diff --git a/[refs] b/[refs]
index ea6155195929..8e8425a8972c 100644
--- a/[refs]
+++ b/[refs]
@@ -1,2 +1,2 @@
---
-refs/heads/master: a418500b42c5c54f3f9d68036950c701740a2765
+refs/heads/master: 9506057fca54464f3291b62156e6cd907c4cbc95
diff --git a/trunk/Documentation/DocBook/kernel-hacking.tmpl b/trunk/Documentation/DocBook/kernel-hacking.tmpl
index 582032eea872..6367bba32d22 100644
--- a/trunk/Documentation/DocBook/kernel-hacking.tmpl
+++ b/trunk/Documentation/DocBook/kernel-hacking.tmpl
@@ -1105,7 +1105,7 @@ static struct block_device_operations opt_fops = {
- Function names as strings (__FUNCTION__).
+ Function names as strings (__func__).
diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS
index ade7415d2467..dc8f3babcabd 100644
--- a/trunk/MAINTAINERS
+++ b/trunk/MAINTAINERS
@@ -2266,12 +2266,6 @@ M: kristen.c.accardi@intel.com
L: pcihpd-discuss@lists.sourceforge.net
S: Maintained
-SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS
-P: Stephen Hemminger
-M: shemminger@osdl.org
-L: netdev@vger.kernel.org
-S: Maintained
-
SPARC (sparc32):
P: William L. Irwin
M: wli@holomorphy.com
diff --git a/trunk/README b/trunk/README
index 2b5844d8cfa0..76dd780d88ed 100644
--- a/trunk/README
+++ b/trunk/README
@@ -149,9 +149,6 @@ CONFIGURING the kernel:
"make gconfig" X windows (Gtk) based configuration tool.
"make oldconfig" Default all questions based on the contents of
your existing ./.config file.
- "make silentoldconfig"
- Like above, but avoids cluttering the screen
- with question already answered.
NOTES on "make config":
- having unnecessary drivers will make the kernel bigger, and can
@@ -172,6 +169,9 @@ CONFIGURING the kernel:
should probably answer 'n' to the questions for
"development", "experimental", or "debugging" features.
+ - Check the top Makefile for further site-dependent configuration
+ (default SVGA mode etc).
+
COMPILING the kernel:
- Make sure you have gcc 2.95.3 available.
@@ -199,9 +199,6 @@ COMPILING the kernel:
are installing a new kernel with the same version number as your
working kernel, make a backup of your modules directory before you
do a "make modules_install".
- In alternative, before compiling, edit your Makefile and change the
- "EXTRAVERSION" line - its content is appended to the regular kernel
- version.
- In order to boot your new kernel, you'll need to copy the kernel
image (e.g. .../linux/arch/i386/boot/bzImage after compilation)
diff --git a/trunk/arch/arm/kernel/vmlinux.lds.S b/trunk/arch/arm/kernel/vmlinux.lds.S
index ad2d66c93a5c..350b53b41e5b 100644
--- a/trunk/arch/arm/kernel/vmlinux.lds.S
+++ b/trunk/arch/arm/kernel/vmlinux.lds.S
@@ -29,7 +29,7 @@ SECTIONS
*(.arch.info)
__arch_info_end = .;
__tagtable_begin = .;
- *(.taglist)
+ *(.taglist.init)
__tagtable_end = .;
. = ALIGN(16);
__setup_start = .;
diff --git a/trunk/arch/ppc64/Makefile b/trunk/arch/ppc64/Makefile
index 521c2a5a2862..17d2c1eac3b8 100644
--- a/trunk/arch/ppc64/Makefile
+++ b/trunk/arch/ppc64/Makefile
@@ -107,7 +107,7 @@ install: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
defaultimage-$(CONFIG_PPC_PSERIES) := zImage
-defaultimage-$(CONFIG_PPC_PMAC) := zImage.vmode
+defaultimage-$(CONFIG_PPC_PMAC) := vmlinux
defaultimage-$(CONFIG_PPC_MAPLE) := zImage
defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux
KBUILD_IMAGE := $(defaultimage-y)
diff --git a/trunk/arch/ppc64/kernel/pSeries_iommu.c b/trunk/arch/ppc64/kernel/pSeries_iommu.c
index 8c6313e7e145..f0fd7fbd6531 100644
--- a/trunk/arch/ppc64/kernel/pSeries_iommu.c
+++ b/trunk/arch/ppc64/kernel/pSeries_iommu.c
@@ -265,10 +265,8 @@ static void iommu_table_setparms(struct pci_controller *phb,
tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT;
/* Test if we are going over 2GB of DMA space */
- if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) {
- udbg_printf("PCI_DMA: Unexpected number of IOAs under this PHB.\n");
+ if (phb->dma_window_base_cur + phb->dma_window_size > (1L << 31))
panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n");
- }
phb->dma_window_base_cur += phb->dma_window_size;
@@ -312,84 +310,92 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb,
static void iommu_bus_setup_pSeries(struct pci_bus *bus)
{
- struct device_node *dn;
- struct iommu_table *tbl;
- struct device_node *isa_dn, *isa_dn_orig;
- struct device_node *tmp;
+ struct device_node *dn, *pdn;
struct pci_dn *pci;
- int children;
+ struct iommu_table *tbl;
DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
- dn = pci_bus_to_OF_node(bus);
- pci = PCI_DN(dn);
-
- if (bus->self) {
- /* This is not a root bus, any setup will be done for the
- * device-side of the bridge in iommu_dev_setup_pSeries().
- */
- return;
- }
-
- /* Check if the ISA bus on the system is under
- * this PHB.
- */
- isa_dn = isa_dn_orig = of_find_node_by_type(NULL, "isa");
-
- while (isa_dn && isa_dn != dn)
- isa_dn = isa_dn->parent;
-
- if (isa_dn_orig)
- of_node_put(isa_dn_orig);
-
- /* Count number of direct PCI children of the PHB.
- * All PCI device nodes have class-code property, so it's
- * an easy way to find them.
- */
- for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling)
- if (get_property(tmp, "class-code", NULL))
- children++;
-
- DBG("Children: %d\n", children);
-
- /* Calculate amount of DMA window per slot. Each window must be
- * a power of two (due to pci_alloc_consistent requirements).
+ /* For each (root) bus, we carve up the available DMA space in 256MB
+ * pieces. Since each piece is used by one (sub) bus/device, that would
+ * give a maximum of 7 devices per PHB. In most cases, this is plenty.
*
- * Keep 256MB aside for PHBs with ISA.
+ * The exception is on Python PHBs (pre-POWER4). Here we don't have EADS
+ * bridges below the PHB to allocate the sectioned tables to, so instead
+ * we allocate a 1GB table at the PHB level.
*/
- if (!isa_dn) {
- /* No ISA/IDE - just set window size and return */
- pci->phb->dma_window_size = 0x80000000ul; /* To be divided */
-
- while (pci->phb->dma_window_size * children > 0x80000000ul)
- pci->phb->dma_window_size >>= 1;
- DBG("No ISA/IDE, window size is %x\n", pci->phb->dma_window_size);
- pci->phb->dma_window_base_cur = 0;
-
- return;
- }
-
- /* If we have ISA, then we probably have an IDE
- * controller too. Allocate a 128MB table but
- * skip the first 128MB to avoid stepping on ISA
- * space.
- */
- pci->phb->dma_window_size = 0x8000000ul;
- pci->phb->dma_window_base_cur = 0x8000000ul;
-
- tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+ dn = pci_bus_to_OF_node(bus);
+ pci = dn->data;
+
+ if (!bus->self) {
+ /* Root bus */
+ if (is_python(dn)) {
+ unsigned int *iohole;
+
+ DBG("Python root bus %s\n", bus->name);
+
+ iohole = (unsigned int *)get_property(dn, "io-hole", 0);
+
+ if (iohole) {
+ /* On first bus we need to leave room for the
+ * ISA address space. Just skip the first 256MB
+ * alltogether. This leaves 768MB for the window.
+ */
+ DBG("PHB has io-hole, reserving 256MB\n");
+ pci->phb->dma_window_size = 3 << 28;
+ pci->phb->dma_window_base_cur = 1 << 28;
+ } else {
+ /* 1GB window by default */
+ pci->phb->dma_window_size = 1 << 30;
+ pci->phb->dma_window_base_cur = 0;
+ }
+
+ tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+
+ iommu_table_setparms(pci->phb, dn, tbl);
+ pci->iommu_table = iommu_init_table(tbl);
+ } else {
+ /* Do a 128MB table at root. This is used for the IDE
+ * controller on some SMP-mode POWER4 machines. It
+ * doesn't hurt to allocate it on other machines
+ * -- it'll just be unused since new tables are
+ * allocated on the EADS level.
+ *
+ * Allocate at offset 128MB to avoid having to deal
+ * with ISA holes; 128MB table for IDE is plenty.
+ */
+ pci->phb->dma_window_size = 1 << 27;
+ pci->phb->dma_window_base_cur = 1 << 27;
+
+ tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
+
+ iommu_table_setparms(pci->phb, dn, tbl);
+ pci->iommu_table = iommu_init_table(tbl);
+
+ /* All child buses have 256MB tables */
+ pci->phb->dma_window_size = 1 << 28;
+ }
+ } else {
+ pdn = pci_bus_to_OF_node(bus->parent);
- iommu_table_setparms(pci->phb, dn, tbl);
- pci->iommu_table = iommu_init_table(tbl);
+ if (!bus->parent->self && !is_python(pdn)) {
+ struct iommu_table *tbl;
+ /* First child and not python means this is the EADS
+ * level. Allocate new table for this slot with 256MB
+ * window.
+ */
- /* Divide the rest (1.75GB) among the children */
- pci->phb->dma_window_size = 0x80000000ul;
- while (pci->phb->dma_window_size * children > 0x70000000ul)
- pci->phb->dma_window_size >>= 1;
+ tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
- DBG("ISA/IDE, window size is %x\n", pci->phb->dma_window_size);
+ iommu_table_setparms(pci->phb, dn, tbl);
+ pci->iommu_table = iommu_init_table(tbl);
+ } else {
+ /* Lower than first child or under python, use parent table */
+ pci->iommu_table = PCI_DN(pdn)->iommu_table;
+ }
+ }
}
@@ -440,28 +446,13 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
static void iommu_dev_setup_pSeries(struct pci_dev *dev)
{
struct device_node *dn, *mydn;
- struct iommu_table *tbl;
DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, dev->pretty_name);
-
- mydn = dn = pci_device_to_OF_node(dev);
-
- /* If we're the direct child of a root bus, then we need to allocate
- * an iommu table ourselves. The bus setup code should have setup
- * the window sizes already.
- */
- if (!dev->bus->self) {
- DBG(" --> first child, no bridge. Allocating iommu table.\n");
- tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
- iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl);
- PCI_DN(mydn)->iommu_table = iommu_init_table(tbl);
-
- return;
- }
-
- /* If this device is further down the bus tree, search upwards until
- * an already allocated iommu table is found and use that.
+ /* Now copy the iommu_table ptr from the bus device down to the
+ * pci device_node. This means get_iommu_table() won't need to search
+ * up the device tree to find it.
*/
+ mydn = dn = pci_device_to_OF_node(dev);
while (dn && dn->data && PCI_DN(dn)->iommu_table == NULL)
dn = dn->parent;
diff --git a/trunk/arch/ppc64/kernel/pci.c b/trunk/arch/ppc64/kernel/pci.c
index ff4be1da69d5..861138ad092c 100644
--- a/trunk/arch/ppc64/kernel/pci.c
+++ b/trunk/arch/ppc64/kernel/pci.c
@@ -246,14 +246,11 @@ static unsigned int pci_parse_of_flags(u32 addr0)
unsigned int flags = 0;
if (addr0 & 0x02000000) {
- flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
- flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
- flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
+ flags |= IORESOURCE_MEM;
if (addr0 & 0x40000000)
- flags |= IORESOURCE_PREFETCH
- | PCI_BASE_ADDRESS_MEM_PREFETCH;
+ flags |= IORESOURCE_PREFETCH;
} else if (addr0 & 0x01000000)
- flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
+ flags |= IORESOURCE_IO;
return flags;
}
diff --git a/trunk/arch/ppc64/kernel/prom_init.c b/trunk/arch/ppc64/kernel/prom_init.c
index f252670874a4..9979919cdf92 100644
--- a/trunk/arch/ppc64/kernel/prom_init.c
+++ b/trunk/arch/ppc64/kernel/prom_init.c
@@ -1711,7 +1711,6 @@ static void __init flatten_device_tree(void)
unsigned long offset = reloc_offset();
unsigned long mem_start, mem_end, room;
struct boot_param_header *hdr;
- struct prom_t *_prom = PTRRELOC(&prom);
char *namep;
u64 *rsvmap;
@@ -1766,7 +1765,6 @@ static void __init flatten_device_tree(void)
RELOC(dt_struct_end) = PAGE_ALIGN(mem_start);
/* Finish header */
- hdr->boot_cpuid_phys = _prom->cpu;
hdr->magic = OF_DT_HEADER;
hdr->totalsize = RELOC(dt_struct_end) - RELOC(dt_header_start);
hdr->off_dt_struct = RELOC(dt_struct_start) - RELOC(dt_header_start);
@@ -1856,6 +1854,7 @@ static void __init prom_find_boot_cpu(void)
cpu_pkg = call_prom("instance-to-package", 1, 1, prom_cpu);
+ prom_setprop(cpu_pkg, "linux,boot-cpu", NULL, 0);
prom_getprop(cpu_pkg, "reg", &getprop_rval, sizeof(getprop_rval));
_prom->cpu = getprop_rval;
diff --git a/trunk/arch/sparc64/kernel/entry.S b/trunk/arch/sparc64/kernel/entry.S
index b48349527853..3e0badb820c5 100644
--- a/trunk/arch/sparc64/kernel/entry.S
+++ b/trunk/arch/sparc64/kernel/entry.S
@@ -42,15 +42,19 @@
* executing (see inherit_locked_prom_mappings() rant).
*/
sparc64_vpte_nucleus:
- /* Note that kvmap below has verified that the address is
- * in the range MODULES_VADDR --> VMALLOC_END already. So
- * here we need only check if it is an OBP address or not.
- */
- sethi %hi(LOW_OBP_ADDRESS), %g5
+ /* Load 0xf0000000, which is LOW_OBP_ADDRESS. */
+ mov 0xf, %g5
+ sllx %g5, 28, %g5
+
+ /* Is addr >= LOW_OBP_ADDRESS? */
cmp %g4, %g5
blu,pn %xcc, sparc64_vpte_patchme1
mov 0x1, %g5
+
+ /* Load 0x100000000, which is HI_OBP_ADDRESS. */
sllx %g5, 32, %g5
+
+ /* Is addr < HI_OBP_ADDRESS? */
cmp %g4, %g5
blu,pn %xcc, obp_iaddr_patch
nop
@@ -152,29 +156,26 @@ obp_daddr_patch:
* rather, use information saved during inherit_prom_mappings() using 8k
* pagesize.
*/
- .align 32
kvmap:
- sethi %hi(MODULES_VADDR), %g5
- cmp %g4, %g5
- blu,pn %xcc, longpath
- mov (VMALLOC_END >> 24), %g5
- sllx %g5, 24, %g5
- cmp %g4, %g5
- bgeu,pn %xcc, longpath
- nop
+ /* Load 0xf0000000, which is LOW_OBP_ADDRESS. */
+ mov 0xf, %g5
+ sllx %g5, 28, %g5
-kvmap_check_obp:
- sethi %hi(LOW_OBP_ADDRESS), %g5
+ /* Is addr >= LOW_OBP_ADDRESS? */
cmp %g4, %g5
- blu,pn %xcc, kvmap_vmalloc_addr
+ blu,pn %xcc, vmalloc_addr
mov 0x1, %g5
+
+ /* Load 0x100000000, which is HI_OBP_ADDRESS. */
sllx %g5, 32, %g5
+
+ /* Is addr < HI_OBP_ADDRESS? */
cmp %g4, %g5
blu,pn %xcc, obp_daddr_patch
nop
-kvmap_vmalloc_addr:
- /* If we get here, a vmalloc addr was accessed, load kernel VPTE. */
+vmalloc_addr:
+ /* If we get here, a vmalloc addr accessed, load kernel VPTE. */
ldxa [%g3 + %g6] ASI_N, %g5
brgez,pn %g5, longpath
nop
diff --git a/trunk/arch/sparc64/kernel/ptrace.c b/trunk/arch/sparc64/kernel/ptrace.c
index 5efbff90d668..23ad839d113f 100644
--- a/trunk/arch/sparc64/kernel/ptrace.c
+++ b/trunk/arch/sparc64/kernel/ptrace.c
@@ -30,7 +30,6 @@
#include
#include
#include
-#include
/* Returning from ptrace is a bit tricky because the syscall return
* low level code assumes any value returned which is negative and
@@ -129,20 +128,20 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
* is mapped to in the user's address space, we can skip the
* D-cache flush.
*/
- if ((uaddr ^ (unsigned long) kaddr) & (1UL << 13)) {
+ if ((uaddr ^ kaddr) & (1UL << 13)) {
unsigned long start = __pa(kaddr);
unsigned long end = start + len;
if (tlb_type == spitfire) {
for (; start < end; start += 32)
- spitfire_put_dcache_tag(start & 0x3fe0, 0x0);
+ spitfire_put_dcache_tag(va & 0x3fe0, 0x0);
} else {
for (; start < end; start += 32)
__asm__ __volatile__(
"stxa %%g0, [%0] %1\n\t"
"membar #Sync"
: /* no outputs */
- : "r" (start),
+ : "r" (va),
"i" (ASI_DCACHE_INVALIDATE));
}
}
diff --git a/trunk/arch/sparc64/kernel/una_asm.S b/trunk/arch/sparc64/kernel/una_asm.S
index da48400bcc95..cbb40585253c 100644
--- a/trunk/arch/sparc64/kernel/una_asm.S
+++ b/trunk/arch/sparc64/kernel/una_asm.S
@@ -17,7 +17,7 @@ kernel_unaligned_trap_fault:
__do_int_store:
rd %asi, %o4
wr %o3, 0, %asi
- mov %o2, %g3
+ ldx [%o2], %g3
cmp %o1, 2
be,pn %icc, 2f
cmp %o1, 4
diff --git a/trunk/arch/sparc64/kernel/unaligned.c b/trunk/arch/sparc64/kernel/unaligned.c
index 42718f6a7d36..da9739f0d437 100644
--- a/trunk/arch/sparc64/kernel/unaligned.c
+++ b/trunk/arch/sparc64/kernel/unaligned.c
@@ -184,14 +184,13 @@ extern void do_int_load(unsigned long *dest_reg, int size,
unsigned long *saddr, int is_signed, int asi);
extern void __do_int_store(unsigned long *dst_addr, int size,
- unsigned long src_val, int asi);
+ unsigned long *src_val, int asi);
static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr,
- struct pt_regs *regs, int asi, int orig_asi)
+ struct pt_regs *regs, int asi)
{
unsigned long zero = 0;
- unsigned long *src_val_p = &zero;
- unsigned long src_val;
+ unsigned long *src_val = &zero;
if (size == 16) {
size = 8;
@@ -199,25 +198,7 @@ static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr,
(unsigned)fetch_reg(reg_num, regs) : 0)) << 32) |
(unsigned)fetch_reg(reg_num + 1, regs);
} else if (reg_num) {
- src_val_p = fetch_reg_addr(reg_num, regs);
- }
- src_val = *src_val_p;
- if (unlikely(asi != orig_asi)) {
- switch (size) {
- case 2:
- src_val = swab16(src_val);
- break;
- case 4:
- src_val = swab32(src_val);
- break;
- case 8:
- src_val = swab64(src_val);
- break;
- case 16:
- default:
- BUG();
- break;
- };
+ src_val = fetch_reg_addr(reg_num, regs);
}
__do_int_store(dst_addr, size, src_val, asi);
}
@@ -295,7 +276,6 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn, u
kernel_mna_trap_fault();
} else {
unsigned long addr;
- int orig_asi, asi;
addr = compute_effective_address(regs, insn,
((insn >> 25) & 0x1f));
@@ -305,48 +285,18 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn, u
regs->tpc, dirstrings[dir], addr, size,
regs->u_regs[UREG_RETPC]);
#endif
- orig_asi = asi = decode_asi(insn, regs);
- switch (asi) {
- case ASI_NL:
- case ASI_AIUPL:
- case ASI_AIUSL:
- case ASI_PL:
- case ASI_SL:
- case ASI_PNFL:
- case ASI_SNFL:
- asi &= ~0x08;
- break;
- };
switch (dir) {
case load:
do_int_load(fetch_reg_addr(((insn>>25)&0x1f), regs),
size, (unsigned long *) addr,
- decode_signedness(insn), asi);
- if (unlikely(asi != orig_asi)) {
- unsigned long val_in = *(unsigned long *) addr;
- switch (size) {
- case 2:
- val_in = swab16(val_in);
- break;
- case 4:
- val_in = swab32(val_in);
- break;
- case 8:
- val_in = swab64(val_in);
- break;
- case 16:
- default:
- BUG();
- break;
- };
- *(unsigned long *) addr = val_in;
- }
+ decode_signedness(insn),
+ decode_asi(insn, regs));
break;
case store:
do_int_store(((insn>>25)&0x1f), size,
(unsigned long *) addr, regs,
- asi, orig_asi);
+ decode_asi(insn, regs));
break;
default:
diff --git a/trunk/arch/x86_64/Kconfig b/trunk/arch/x86_64/Kconfig
index 21afa69a086d..0969d570f3b5 100644
--- a/trunk/arch/x86_64/Kconfig
+++ b/trunk/arch/x86_64/Kconfig
@@ -308,7 +308,7 @@ config HPET_TIMER
present. The HPET provides a stable time base on SMP
systems, unlike the TSC, but it is more expensive to access,
as it is off-chip. You can find the HPET spec at
- .
+ .
config X86_PM_TIMER
bool "PM timer"
diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c
index 486b6e1c7dfb..c56f995aadad 100644
--- a/trunk/drivers/block/cciss.c
+++ b/trunk/drivers/block/cciss.c
@@ -483,6 +483,9 @@ static int cciss_open(struct inode *inode, struct file *filep)
printk(KERN_DEBUG "cciss_open %s\n", inode->i_bdev->bd_disk->disk_name);
#endif /* CCISS_DEBUG */
+ if (host->busy_initializing)
+ return -EBUSY;
+
if (host->busy_initializing || drv->busy_configuring)
return -EBUSY;
/*
@@ -2988,7 +2991,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);
cciss_procinit(i);
- hba[i]->busy_initializing = 0;
for(j=0; j < NWD; j++) { /* mfm */
drive_info_struct *drv = &(hba[i]->drv[j]);
@@ -3031,6 +3033,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
add_disk(disk);
}
+ hba[i]->busy_initializing = 0;
return(1);
clean4:
diff --git a/trunk/drivers/block/ll_rw_blk.c b/trunk/drivers/block/ll_rw_blk.c
index baedac522945..483d71b10cf9 100644
--- a/trunk/drivers/block/ll_rw_blk.c
+++ b/trunk/drivers/block/ll_rw_blk.c
@@ -2373,6 +2373,44 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
EXPORT_SYMBOL(blkdev_issue_flush);
+/**
+ * blkdev_scsi_issue_flush_fn - issue flush for SCSI devices
+ * @q: device queue
+ * @disk: gendisk
+ * @error_sector: error offset
+ *
+ * Description:
+ * Devices understanding the SCSI command set, can use this function as
+ * a helper for issuing a cache flush. Note: driver is required to store
+ * the error offset (in case of error flushing) in ->sector of struct
+ * request.
+ */
+int blkdev_scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
+ sector_t *error_sector)
+{
+ struct request *rq = blk_get_request(q, WRITE, __GFP_WAIT);
+ int ret;
+
+ rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER;
+ rq->sector = 0;
+ memset(rq->cmd, 0, sizeof(rq->cmd));
+ rq->cmd[0] = 0x35;
+ rq->cmd_len = 12;
+ rq->data = NULL;
+ rq->data_len = 0;
+ rq->timeout = 60 * HZ;
+
+ ret = blk_execute_rq(q, disk, rq, 0);
+
+ if (ret && error_sector)
+ *error_sector = rq->sector;
+
+ blk_put_request(rq);
+ return ret;
+}
+
+EXPORT_SYMBOL(blkdev_scsi_issue_flush_fn);
+
static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
{
int rw = rq_data_dir(rq);
diff --git a/trunk/drivers/infiniband/core/mad_rmpp.c b/trunk/drivers/infiniband/core/mad_rmpp.c
index e23836d0e21b..2bd8b1cc57c4 100644
--- a/trunk/drivers/infiniband/core/mad_rmpp.c
+++ b/trunk/drivers/infiniband/core/mad_rmpp.c
@@ -412,8 +412,8 @@ static inline int get_mad_len(struct mad_rmpp_recv *rmpp_recv)
hdr_size = data_offset(rmpp_mad->mad_hdr.mgmt_class);
data_size = sizeof(struct ib_rmpp_mad) - hdr_size;
- pad = IB_MGMT_RMPP_DATA - be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
- if (pad > IB_MGMT_RMPP_DATA || pad < 0)
+ pad = data_size - be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
+ if (pad > data_size || pad < 0)
pad = 0;
return hdr_size + rmpp_recv->seg_num * data_size - pad;
@@ -583,7 +583,6 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
{
struct ib_rmpp_mad *rmpp_mad;
int timeout;
- u32 paylen;
rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr;
ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE);
@@ -591,9 +590,11 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
if (mad_send_wr->seg_num == 1) {
rmpp_mad->rmpp_hdr.rmpp_rtime_flags |= IB_MGMT_RMPP_FLAG_FIRST;
- paylen = mad_send_wr->total_seg * IB_MGMT_RMPP_DATA -
- mad_send_wr->pad;
- rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(paylen);
+ rmpp_mad->rmpp_hdr.paylen_newwin =
+ cpu_to_be32(mad_send_wr->total_seg *
+ (sizeof(struct ib_rmpp_mad) -
+ offsetof(struct ib_rmpp_mad, data)) -
+ mad_send_wr->pad);
mad_send_wr->sg_list[0].length = sizeof(struct ib_rmpp_mad);
} else {
mad_send_wr->send_wr.num_sge = 2;
@@ -607,8 +608,10 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
if (mad_send_wr->seg_num == mad_send_wr->total_seg) {
rmpp_mad->rmpp_hdr.rmpp_rtime_flags |= IB_MGMT_RMPP_FLAG_LAST;
- paylen = IB_MGMT_RMPP_DATA - mad_send_wr->pad;
- rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(paylen);
+ rmpp_mad->rmpp_hdr.paylen_newwin =
+ cpu_to_be32(sizeof(struct ib_rmpp_mad) -
+ offsetof(struct ib_rmpp_mad, data) -
+ mad_send_wr->pad);
}
/* 2 seconds for an ACK until we can find the packet lifetime */
diff --git a/trunk/drivers/infiniband/core/user_mad.c b/trunk/drivers/infiniband/core/user_mad.c
index a64d6b4dcc16..7c2f03057ddb 100644
--- a/trunk/drivers/infiniband/core/user_mad.c
+++ b/trunk/drivers/infiniband/core/user_mad.c
@@ -334,11 +334,10 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
ret = -EINVAL;
goto err_ah;
}
-
- /* Validate that the management class can support RMPP */
+ /* Validate that management class can support RMPP */
if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) {
hdr_len = offsetof(struct ib_sa_mad, data);
- data_len = length - hdr_len;
+ data_len = length;
} else if ((rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
(rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) {
hdr_len = offsetof(struct ib_vendor_mad, data);
diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_eq.c b/trunk/drivers/infiniband/hw/mthca/mthca_eq.c
index 78152a8ad17d..18f0981eb0c1 100644
--- a/trunk/drivers/infiniband/hw/mthca/mthca_eq.c
+++ b/trunk/drivers/infiniband/hw/mthca/mthca_eq.c
@@ -476,8 +476,12 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev,
int i;
u8 status;
- eq->dev = dev;
- eq->nent = roundup_pow_of_two(max(nent, 2));
+ /* Make sure EQ size is aligned to a power of 2 size. */
+ for (i = 1; i < nent; i <<= 1)
+ ; /* nothing */
+ nent = i;
+
+ eq->dev = dev;
eq->page_list = kmalloc(npages * sizeof *eq->page_list,
GFP_KERNEL);
@@ -508,7 +512,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev,
memset(eq->page_list[i].buf, 0, PAGE_SIZE);
}
- for (i = 0; i < eq->nent; ++i)
+ for (i = 0; i < nent; ++i)
set_eqe_hw(get_eqe(eq, i));
eq->eqn = mthca_alloc(&dev->eq_table.alloc);
@@ -524,6 +528,8 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev,
if (err)
goto err_out_free_eq;
+ eq->nent = nent;
+
memset(eq_context, 0, sizeof *eq_context);
eq_context->flags = cpu_to_be32(MTHCA_EQ_STATUS_OK |
MTHCA_EQ_OWNER_HW |
@@ -532,7 +538,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev,
if (mthca_is_memfree(dev))
eq_context->flags |= cpu_to_be32(MTHCA_EQ_STATE_ARBEL);
- eq_context->logsize_usrpage = cpu_to_be32((ffs(eq->nent) - 1) << 24);
+ eq_context->logsize_usrpage = cpu_to_be32((ffs(nent) - 1) << 24);
if (mthca_is_memfree(dev)) {
eq_context->arbel_pd = cpu_to_be32(dev->driver_pd.pd_num);
} else {
@@ -563,7 +569,7 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev,
dev->eq_table.arm_mask |= eq->eqn_mask;
mthca_dbg(dev, "Allocated EQ %d with %d entries\n",
- eq->eqn, eq->nent);
+ eq->eqn, nent);
return err;
diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c
index 5fa00669f9b8..bcef06bf15e7 100644
--- a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -227,6 +227,7 @@ static void mthca_wq_init(struct mthca_wq *wq)
wq->last_comp = wq->max - 1;
wq->head = 0;
wq->tail = 0;
+ wq->last = NULL;
}
void mthca_qp_event(struct mthca_dev *dev, u32 qpn,
@@ -686,7 +687,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask)
}
if (attr_mask & IB_QP_TIMEOUT) {
- qp_context->pri_path.ackto = attr->timeout << 3;
+ qp_context->pri_path.ackto = attr->timeout;
qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ACK_TIMEOUT);
}
@@ -1102,9 +1103,6 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev,
}
}
- qp->sq.last = get_send_wqe(qp, qp->sq.max - 1);
- qp->rq.last = get_recv_wqe(qp, qp->rq.max - 1);
-
return 0;
}
@@ -1585,13 +1583,15 @@ int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
goto out;
}
- ((struct mthca_next_seg *) prev_wqe)->nda_op =
- cpu_to_be32(((ind << qp->sq.wqe_shift) +
- qp->send_wqe_offset) |
- mthca_opcode[wr->opcode]);
- wmb();
- ((struct mthca_next_seg *) prev_wqe)->ee_nds =
- cpu_to_be32((size0 ? 0 : MTHCA_NEXT_DBD) | size);
+ if (prev_wqe) {
+ ((struct mthca_next_seg *) prev_wqe)->nda_op =
+ cpu_to_be32(((ind << qp->sq.wqe_shift) +
+ qp->send_wqe_offset) |
+ mthca_opcode[wr->opcode]);
+ wmb();
+ ((struct mthca_next_seg *) prev_wqe)->ee_nds =
+ cpu_to_be32((size0 ? 0 : MTHCA_NEXT_DBD) | size);
+ }
if (!size0) {
size0 = size;
@@ -1688,11 +1688,13 @@ int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
qp->wrid[ind] = wr->wr_id;
- ((struct mthca_next_seg *) prev_wqe)->nda_op =
- cpu_to_be32((ind << qp->rq.wqe_shift) | 1);
- wmb();
- ((struct mthca_next_seg *) prev_wqe)->ee_nds =
- cpu_to_be32(MTHCA_NEXT_DBD | size);
+ if (likely(prev_wqe)) {
+ ((struct mthca_next_seg *) prev_wqe)->nda_op =
+ cpu_to_be32((ind << qp->rq.wqe_shift) | 1);
+ wmb();
+ ((struct mthca_next_seg *) prev_wqe)->ee_nds =
+ cpu_to_be32(MTHCA_NEXT_DBD | size);
+ }
if (!size0)
size0 = size;
@@ -1903,13 +1905,15 @@ int mthca_arbel_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
goto out;
}
- ((struct mthca_next_seg *) prev_wqe)->nda_op =
- cpu_to_be32(((ind << qp->sq.wqe_shift) +
- qp->send_wqe_offset) |
- mthca_opcode[wr->opcode]);
- wmb();
- ((struct mthca_next_seg *) prev_wqe)->ee_nds =
- cpu_to_be32(MTHCA_NEXT_DBD | size);
+ if (likely(prev_wqe)) {
+ ((struct mthca_next_seg *) prev_wqe)->nda_op =
+ cpu_to_be32(((ind << qp->sq.wqe_shift) +
+ qp->send_wqe_offset) |
+ mthca_opcode[wr->opcode]);
+ wmb();
+ ((struct mthca_next_seg *) prev_wqe)->ee_nds =
+ cpu_to_be32(MTHCA_NEXT_DBD | size);
+ }
if (!size0) {
size0 = size;
@@ -2123,6 +2127,5 @@ void __devexit mthca_cleanup_qp_table(struct mthca_dev *dev)
for (i = 0; i < 2; ++i)
mthca_CONF_SPECIAL_QP(dev, i, 0, &status);
- mthca_array_cleanup(&dev->qp_table.qp, dev->limits.num_qps);
mthca_alloc_cleanup(&dev->qp_table.alloc);
}
diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_srq.c b/trunk/drivers/infiniband/hw/mthca/mthca_srq.c
index 18998d48c53e..75cd2d84ef12 100644
--- a/trunk/drivers/infiniband/hw/mthca/mthca_srq.c
+++ b/trunk/drivers/infiniband/hw/mthca/mthca_srq.c
@@ -172,8 +172,6 @@ static int mthca_alloc_srq_buf(struct mthca_dev *dev, struct mthca_pd *pd,
scatter->lkey = cpu_to_be32(MTHCA_INVAL_LKEY);
}
- srq->last = get_wqe(srq, srq->max - 1);
-
return 0;
}
@@ -191,6 +189,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd,
srq->max = attr->max_wr;
srq->max_gs = attr->max_sge;
+ srq->last = NULL;
srq->counter = 0;
if (mthca_is_memfree(dev))
@@ -410,7 +409,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
mthca_err(dev, "SRQ %06x full\n", srq->srqn);
err = -ENOMEM;
*bad_wr = wr;
- break;
+ return nreq;
}
wqe = get_wqe(srq, ind);
@@ -428,7 +427,7 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
err = -EINVAL;
*bad_wr = wr;
srq->last = prev_wqe;
- break;
+ return nreq;
}
for (i = 0; i < wr->num_sge; ++i) {
@@ -447,16 +446,20 @@ int mthca_tavor_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
((struct mthca_data_seg *) wqe)->addr = 0;
}
- ((struct mthca_next_seg *) prev_wqe)->nda_op =
- cpu_to_be32((ind << srq->wqe_shift) | 1);
- wmb();
- ((struct mthca_next_seg *) prev_wqe)->ee_nds =
- cpu_to_be32(MTHCA_NEXT_DBD);
+ if (likely(prev_wqe)) {
+ ((struct mthca_next_seg *) prev_wqe)->nda_op =
+ cpu_to_be32((ind << srq->wqe_shift) | 1);
+ wmb();
+ ((struct mthca_next_seg *) prev_wqe)->ee_nds =
+ cpu_to_be32(MTHCA_NEXT_DBD);
+ }
srq->wrid[ind] = wr->wr_id;
srq->first_free = next_ind;
}
+ return nreq;
+
if (likely(nreq)) {
__be32 doorbell[2];
@@ -500,7 +503,7 @@ int mthca_arbel_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
mthca_err(dev, "SRQ %06x full\n", srq->srqn);
err = -ENOMEM;
*bad_wr = wr;
- break;
+ return nreq;
}
wqe = get_wqe(srq, ind);
@@ -516,7 +519,7 @@ int mthca_arbel_post_srq_recv(struct ib_srq *ibsrq, struct ib_recv_wr *wr,
if (unlikely(wr->num_sge > srq->max_gs)) {
err = -EINVAL;
*bad_wr = wr;
- break;
+ return nreq;
}
for (i = 0; i < wr->num_sge; ++i) {
diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h
index 4ea1c1ca85bc..bea960b8191f 100644
--- a/trunk/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -257,7 +257,7 @@ void ipoib_mcast_send(struct net_device *dev, union ib_gid *mgid,
void ipoib_mcast_restart_task(void *dev_ptr);
int ipoib_mcast_start_thread(struct net_device *dev);
-int ipoib_mcast_stop_thread(struct net_device *dev, int flush);
+int ipoib_mcast_stop_thread(struct net_device *dev);
void ipoib_mcast_dev_down(struct net_device *dev);
void ipoib_mcast_dev_flush(struct net_device *dev);
diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index f7440096b5ed..ef0e3894863c 100644
--- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -432,7 +432,7 @@ int ipoib_ib_dev_down(struct net_device *dev)
flush_workqueue(ipoib_workqueue);
}
- ipoib_mcast_stop_thread(dev, 1);
+ ipoib_mcast_stop_thread(dev);
/*
* Flush the multicast groups first so we stop any multicast joins. The
@@ -599,7 +599,7 @@ void ipoib_ib_dev_cleanup(struct net_device *dev)
ipoib_dbg(priv, "cleaning up ib_dev\n");
- ipoib_mcast_stop_thread(dev, 1);
+ ipoib_mcast_stop_thread(dev);
/* Delete the broadcast address and the local address */
ipoib_mcast_dev_down(dev);
diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 704f48e0b6a7..49d120d2b92c 100644
--- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -1005,7 +1005,6 @@ static struct net_device *ipoib_add_port(const char *format,
register_failed:
ib_unregister_event_handler(&priv->event_handler);
- flush_scheduled_work();
event_failed:
ipoib_dev_cleanup(priv->dev);
@@ -1058,7 +1057,6 @@ static void ipoib_remove_one(struct ib_device *device)
list_for_each_entry_safe(priv, tmp, dev_list, list) {
ib_unregister_event_handler(&priv->event_handler);
- flush_scheduled_work();
unregister_netdev(priv->dev);
ipoib_dev_cleanup(priv->dev);
diff --git a/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 36ce29836bf2..aca7aea18a69 100644
--- a/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/trunk/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -145,7 +145,7 @@ static struct ipoib_mcast *ipoib_mcast_alloc(struct net_device *dev,
mcast->dev = dev;
mcast->created = jiffies;
- mcast->backoff = 1;
+ mcast->backoff = HZ;
mcast->logcount = 0;
INIT_LIST_HEAD(&mcast->list);
@@ -396,7 +396,7 @@ static void ipoib_mcast_join_complete(int status,
IPOIB_GID_ARG(mcast->mcmember.mgid), status);
if (!status && !ipoib_mcast_join_finish(mcast, mcmember)) {
- mcast->backoff = 1;
+ mcast->backoff = HZ;
down(&mcast_mutex);
if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
queue_work(ipoib_workqueue, &priv->mcast_task);
@@ -496,7 +496,7 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast,
if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
queue_delayed_work(ipoib_workqueue,
&priv->mcast_task,
- mcast->backoff * HZ);
+ mcast->backoff);
up(&mcast_mutex);
} else
mcast->query_id = ret;
@@ -598,7 +598,7 @@ int ipoib_mcast_start_thread(struct net_device *dev)
return 0;
}
-int ipoib_mcast_stop_thread(struct net_device *dev, int flush)
+int ipoib_mcast_stop_thread(struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ipoib_mcast *mcast;
@@ -610,8 +610,7 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush)
cancel_delayed_work(&priv->mcast_task);
up(&mcast_mutex);
- if (flush)
- flush_workqueue(ipoib_workqueue);
+ flush_workqueue(ipoib_workqueue);
if (priv->broadcast && priv->broadcast->query) {
ib_sa_cancel_query(priv->broadcast->query_id, priv->broadcast->query);
@@ -833,7 +832,7 @@ void ipoib_mcast_restart_task(void *dev_ptr)
ipoib_dbg_mcast(priv, "restarting multicast task\n");
- ipoib_mcast_stop_thread(dev, 0);
+ ipoib_mcast_stop_thread(dev);
spin_lock_irqsave(&priv->lock, flags);
diff --git a/trunk/drivers/message/fusion/Kconfig b/trunk/drivers/message/fusion/Kconfig
index 1883d22cffeb..33f209a39cb6 100644
--- a/trunk/drivers/message/fusion/Kconfig
+++ b/trunk/drivers/message/fusion/Kconfig
@@ -35,23 +35,6 @@ config FUSION_FC
LSIFC929X
LSIFC929XL
-config FUSION_SAS
- tristate "Fusion MPT ScsiHost drivers for SAS"
- depends on PCI && SCSI
- select FUSION
- select SCSI_SAS_ATTRS
- ---help---
- SCSI HOST support for a SAS host adapters.
-
- List of supported controllers:
-
- LSISAS1064
- LSISAS1066
- LSISAS1068
- LSISAS1064E
- LSISAS1066E
- LSISAS1068E
-
config FUSION_MAX_SGE
int "Maximum number of scatter gather entries (16 - 128)"
depends on FUSION
diff --git a/trunk/drivers/message/fusion/Makefile b/trunk/drivers/message/fusion/Makefile
index 8a2e2657f4c2..1d2f9db813c1 100644
--- a/trunk/drivers/message/fusion/Makefile
+++ b/trunk/drivers/message/fusion/Makefile
@@ -34,6 +34,5 @@
obj-$(CONFIG_FUSION_SPI) += mptbase.o mptscsih.o mptspi.o
obj-$(CONFIG_FUSION_FC) += mptbase.o mptscsih.o mptfc.o
-obj-$(CONFIG_FUSION_SAS) += mptbase.o mptscsih.o mptsas.o
obj-$(CONFIG_FUSION_CTL) += mptctl.o
obj-$(CONFIG_FUSION_LAN) += mptlan.o
diff --git a/trunk/drivers/message/fusion/mptbase.c b/trunk/drivers/message/fusion/mptbase.c
index 790a2932ded9..f517d0692d5f 100644
--- a/trunk/drivers/message/fusion/mptbase.c
+++ b/trunk/drivers/message/fusion/mptbase.c
@@ -135,12 +135,13 @@ static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
+//static u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
-static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
+static int mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag);
static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
@@ -151,7 +152,6 @@ static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
static int GetLanConfigPages(MPT_ADAPTER *ioc);
static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
static int GetIoUnitPage2(MPT_ADAPTER *ioc);
-int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
@@ -159,8 +159,6 @@ static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
static void mpt_timer_expired(unsigned long data);
static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
-static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
-static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
#ifdef CONFIG_PROC_FS
static int procmpt_summary_read(char *buf, char **start, off_t offset,
@@ -177,7 +175,6 @@ static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *
static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
-static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
/* module entry point */
static int __init fusion_init (void);
@@ -209,144 +206,6 @@ pci_enable_io_access(struct pci_dev *pdev)
pci_write_config_word(pdev, PCI_COMMAND, command_reg);
}
-/*
- * Process turbo (context) reply...
- */
-static void
-mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
-{
- MPT_FRAME_HDR *mf = NULL;
- MPT_FRAME_HDR *mr = NULL;
- int req_idx = 0;
- int cb_idx;
-
- dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n",
- ioc->name, pa));
-
- switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
- case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
- req_idx = pa & 0x0000FFFF;
- cb_idx = (pa & 0x00FF0000) >> 16;
- mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
- break;
- case MPI_CONTEXT_REPLY_TYPE_LAN:
- cb_idx = mpt_lan_index;
- /*
- * Blind set of mf to NULL here was fatal
- * after lan_reply says "freeme"
- * Fix sort of combined with an optimization here;
- * added explicit check for case where lan_reply
- * was just returning 1 and doing nothing else.
- * For this case skip the callback, but set up
- * proper mf value first here:-)
- */
- if ((pa & 0x58000000) == 0x58000000) {
- req_idx = pa & 0x0000FFFF;
- mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
- mpt_free_msg_frame(ioc, mf);
- mb();
- return;
- break;
- }
- mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
- break;
- case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
- cb_idx = mpt_stm_index;
- mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
- break;
- default:
- cb_idx = 0;
- BUG();
- }
-
- /* Check for (valid) IO callback! */
- if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
- MptCallbacks[cb_idx] == NULL) {
- printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
- __FUNCTION__, ioc->name, cb_idx);
- goto out;
- }
-
- if (MptCallbacks[cb_idx](ioc, mf, mr))
- mpt_free_msg_frame(ioc, mf);
- out:
- mb();
-}
-
-static void
-mpt_reply(MPT_ADAPTER *ioc, u32 pa)
-{
- MPT_FRAME_HDR *mf;
- MPT_FRAME_HDR *mr;
- int req_idx;
- int cb_idx;
- int freeme;
-
- u32 reply_dma_low;
- u16 ioc_stat;
-
- /* non-TURBO reply! Hmmm, something may be up...
- * Newest turbo reply mechanism; get address
- * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
- */
-
- /* Map DMA address of reply header to cpu address.
- * pa is 32 bits - but the dma address may be 32 or 64 bits
- * get offset based only only the low addresses
- */
-
- reply_dma_low = (pa <<= 1);
- mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
- (reply_dma_low - ioc->reply_frames_low_dma));
-
- req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
- cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
- mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
-
- dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
- ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
- DBG_DUMP_REPLY_FRAME(mr)
-
- /* Check/log IOC log info
- */
- ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
- if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
- u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
- if (ioc->bus_type == FC)
- mpt_fc_log_info(ioc, log_info);
- else if (ioc->bus_type == SCSI)
- mpt_sp_log_info(ioc, log_info);
- else if (ioc->bus_type == SAS)
- mpt_sas_log_info(ioc, log_info);
- }
- if (ioc_stat & MPI_IOCSTATUS_MASK) {
- if (ioc->bus_type == SCSI &&
- cb_idx != mpt_stm_index &&
- cb_idx != mpt_lan_index)
- mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
- }
-
-
- /* Check for (valid) IO callback! */
- if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
- MptCallbacks[cb_idx] == NULL) {
- printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
- __FUNCTION__, ioc->name, cb_idx);
- freeme = 0;
- goto out;
- }
-
- freeme = MptCallbacks[cb_idx](ioc, mf, mr);
-
- out:
- /* Flush (non-TURBO) reply with a WRITE! */
- CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
-
- if (freeme)
- mpt_free_msg_frame(ioc, mf);
- mb();
-}
-
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
@@ -368,21 +227,164 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa)
static irqreturn_t
mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
{
- MPT_ADAPTER *ioc = bus_id;
- u32 pa;
+ MPT_ADAPTER *ioc;
+ MPT_FRAME_HDR *mf;
+ MPT_FRAME_HDR *mr;
+ u32 pa;
+ int req_idx;
+ int cb_idx;
+ int type;
+ int freeme;
+
+ ioc = (MPT_ADAPTER *)bus_id;
/*
* Drain the reply FIFO!
+ *
+ * NOTES: I've seen up to 10 replies processed in this loop, so far...
+ * Update: I've seen up to 9182 replies processed in this loop! ??
+ * Update: Limit ourselves to processing max of N replies
+ * (bottom of loop).
*/
while (1) {
- pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
- if (pa == 0xFFFFFFFF)
+
+ if ((pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF)
return IRQ_HANDLED;
- else if (pa & MPI_ADDRESS_REPLY_A_BIT)
- mpt_reply(ioc, pa);
- else
- mpt_turbo_reply(ioc, pa);
- }
+
+ cb_idx = 0;
+ freeme = 0;
+
+ /*
+ * Check for non-TURBO reply!
+ */
+ if (pa & MPI_ADDRESS_REPLY_A_BIT) {
+ u32 reply_dma_low;
+ u16 ioc_stat;
+
+ /* non-TURBO reply! Hmmm, something may be up...
+ * Newest turbo reply mechanism; get address
+ * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
+ */
+
+ /* Map DMA address of reply header to cpu address.
+ * pa is 32 bits - but the dma address may be 32 or 64 bits
+ * get offset based only only the low addresses
+ */
+ reply_dma_low = (pa = (pa << 1));
+ mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
+ (reply_dma_low - ioc->reply_frames_low_dma));
+
+ req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
+ cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
+ mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
+
+ dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
+ ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
+ DBG_DUMP_REPLY_FRAME(mr)
+
+ /* Check/log IOC log info
+ */
+ ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
+ if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
+ u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
+ if (ioc->bus_type == FC)
+ mpt_fc_log_info(ioc, log_info);
+ else if (ioc->bus_type == SCSI)
+ mpt_sp_log_info(ioc, log_info);
+ }
+ if (ioc_stat & MPI_IOCSTATUS_MASK) {
+ if (ioc->bus_type == SCSI)
+ mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
+ }
+ } else {
+ /*
+ * Process turbo (context) reply...
+ */
+ dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n", ioc->name, pa));
+ type = (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT);
+ if (type == MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET) {
+ cb_idx = mpt_stm_index;
+ mf = NULL;
+ mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
+ } else if (type == MPI_CONTEXT_REPLY_TYPE_LAN) {
+ cb_idx = mpt_lan_index;
+ /* Blind set of mf to NULL here was fatal
+ * after lan_reply says "freeme"
+ * Fix sort of combined with an optimization here;
+ * added explicit check for case where lan_reply
+ * was just returning 1 and doing nothing else.
+ * For this case skip the callback, but set up
+ * proper mf value first here:-)
+ */
+ if ((pa & 0x58000000) == 0x58000000) {
+ req_idx = pa & 0x0000FFFF;
+ mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
+ freeme = 1;
+ /*
+ * IMPORTANT! Invalidate the callback!
+ */
+ cb_idx = 0;
+ } else {
+ mf = NULL;
+ }
+ mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
+ } else {
+ req_idx = pa & 0x0000FFFF;
+ cb_idx = (pa & 0x00FF0000) >> 16;
+ mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
+ mr = NULL;
+ }
+ pa = 0; /* No reply flush! */
+ }
+
+#ifdef MPT_DEBUG_IRQ
+ if (ioc->bus_type == SCSI) {
+ /* Verify mf, mr are reasonable.
+ */
+ if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))
+ || (mf < ioc->req_frames)) ) {
+ printk(MYIOC_s_WARN_FMT
+ "mpt_interrupt: Invalid mf (%p)!\n", ioc->name, (void *)mf);
+ cb_idx = 0;
+ pa = 0;
+ freeme = 0;
+ }
+ if ((pa) && (mr) && ((mr >= MPT_INDEX_2_RFPTR(ioc, ioc->req_depth))
+ || (mr < ioc->reply_frames)) ) {
+ printk(MYIOC_s_WARN_FMT
+ "mpt_interrupt: Invalid rf (%p)!\n", ioc->name, (void *)mr);
+ cb_idx = 0;
+ pa = 0;
+ freeme = 0;
+ }
+ if (cb_idx > (MPT_MAX_PROTOCOL_DRIVERS-1)) {
+ printk(MYIOC_s_WARN_FMT
+ "mpt_interrupt: Invalid cb_idx (%d)!\n", ioc->name, cb_idx);
+ cb_idx = 0;
+ pa = 0;
+ freeme = 0;
+ }
+ }
+#endif
+
+ /* Check for (valid) IO callback! */
+ if (cb_idx) {
+ /* Do the callback! */
+ freeme = (*(MptCallbacks[cb_idx]))(ioc, mf, mr);
+ }
+
+ if (pa) {
+ /* Flush (non-TURBO) reply with a WRITE! */
+ CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
+ }
+
+ if (freeme) {
+ /* Put Request back on FreeQ! */
+ mpt_free_msg_frame(ioc, mf);
+ }
+
+ mb();
+ } /* drain reply FIFO */
return IRQ_HANDLED;
}
@@ -507,14 +509,6 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
pCfg->wait_done = 1;
wake_up(&mpt_waitq);
}
- } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
- /* we should be always getting a reply frame */
- memcpy(ioc->persist_reply_frame, reply,
- min(MPT_DEFAULT_FRAME_SIZE,
- 4*reply->u.reply.MsgLength));
- del_timer(&ioc->persist_timer);
- ioc->persist_wait_done = 1;
- wake_up(&mpt_waitq);
} else {
printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
ioc->name, func);
@@ -756,7 +750,6 @@ mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
u.frame.linkage.list);
list_del(&mf->u.frame.linkage.list);
- mf->u.frame.linkage.arg1 = 0;
mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
/* u16! */
@@ -852,7 +845,6 @@ mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
/* Put Request back on FreeQ! */
spin_lock_irqsave(&ioc->FreeQlock, flags);
- mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
#ifdef MFCNT
ioc->mfcnt--;
@@ -979,121 +971,10 @@ mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req,
/* Make sure there are no doorbells */
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
-
+
return r;
}
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/**
- * mpt_host_page_access_control - provides mechanism for the host
- * driver to control the IOC's Host Page Buffer access.
- * @ioc: Pointer to MPT adapter structure
- * @access_control_value: define bits below
- *
- * Access Control Value - bits[15:12]
- * 0h Reserved
- * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
- * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
- * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
- *
- * Returns 0 for success, non-zero for failure.
- */
-
-static int
-mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
-{
- int r = 0;
-
- /* return if in use */
- if (CHIPREG_READ32(&ioc->chip->Doorbell)
- & MPI_DOORBELL_ACTIVE)
- return -1;
-
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
-
- CHIPREG_WRITE32(&ioc->chip->Doorbell,
- ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
- <HostPageBuffer) {
-
- host_page_buffer_sz =
- le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
-
- if(!host_page_buffer_sz)
- return 0; /* fw doesn't need any host buffers */
-
- /* spin till we get enough memory */
- while(host_page_buffer_sz > 0) {
-
- if((ioc->HostPageBuffer = pci_alloc_consistent(
- ioc->pcidev,
- host_page_buffer_sz,
- &ioc->HostPageBuffer_dma)) != NULL) {
-
- dinitprintk((MYIOC_s_INFO_FMT
- "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
- ioc->name,
- ioc->HostPageBuffer,
- ioc->HostPageBuffer_dma,
- host_page_buffer_sz));
- ioc->alloc_total += host_page_buffer_sz;
- ioc->HostPageBuffer_sz = host_page_buffer_sz;
- break;
- }
-
- host_page_buffer_sz -= (4*1024);
- }
- }
-
- if(!ioc->HostPageBuffer) {
- printk(MYIOC_s_ERR_FMT
- "Failed to alloc memory for host_page_buffer!\n",
- ioc->name);
- return -999;
- }
-
- psge = (char *)&ioc_init->HostPageBufferSGE;
- flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
- MPI_SGE_FLAGS_SYSTEM_ADDRESS |
- MPI_SGE_FLAGS_32_BIT_ADDRESSING |
- MPI_SGE_FLAGS_HOST_TO_IOC |
- MPI_SGE_FLAGS_END_OF_BUFFER;
- if (sizeof(dma_addr_t) == sizeof(u64)) {
- flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
- }
- flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
- flags_length |= ioc->HostPageBuffer_sz;
- mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
- ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
-
-return 0;
-}
-
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_verify_adapter - Given a unique IOC identifier, set pointer to
@@ -1203,7 +1084,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
/* Initilize SCSI Config Data structure
*/
- memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
+ memset(&ioc->spi_data, 0, sizeof(ScsiCfgData));
/* Initialize the running configQ head.
*/
@@ -1332,33 +1213,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
ioc->prod_name = "LSI53C1035";
ioc->bus_type = SCSI;
}
- else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
- ioc->prod_name = "LSISAS1064";
- ioc->bus_type = SAS;
- ioc->errata_flag_1064 = 1;
- }
- else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066) {
- ioc->prod_name = "LSISAS1066";
- ioc->bus_type = SAS;
- ioc->errata_flag_1064 = 1;
- }
- else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
- ioc->prod_name = "LSISAS1068";
- ioc->bus_type = SAS;
- ioc->errata_flag_1064 = 1;
- }
- else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
- ioc->prod_name = "LSISAS1064E";
- ioc->bus_type = SAS;
- }
- else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066E) {
- ioc->prod_name = "LSISAS1066E";
- ioc->bus_type = SAS;
- }
- else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
- ioc->prod_name = "LSISAS1068E";
- ioc->bus_type = SAS;
- }
if (ioc->errata_flag_1064)
pci_disable_io_access(pdev);
@@ -1750,23 +1604,8 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
*/
if (ret == 0) {
rc = mpt_do_upload(ioc, sleepFlag);
- if (rc == 0) {
- if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
- /*
- * Maintain only one pointer to FW memory
- * so there will not be two attempt to
- * downloadboot onboard dual function
- * 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));
- }
- } else {
+ if (rc != 0)
printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
- ret = -5;
- }
}
}
}
@@ -1801,22 +1640,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
* and we try GetLanConfigPages again...
*/
if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
- if (ioc->bus_type == SAS) {
-
- /* clear persistency table */
- if(ioc->facts.IOCExceptions &
- MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
- ret = mptbase_sas_persist_operation(ioc,
- MPI_SAS_OP_CLEAR_NOT_PRESENT);
- if(ret != 0)
- return -1;
- }
-
- /* Find IM volumes
- */
- mpt_findImVolumes(ioc);
-
- } else if (ioc->bus_type == FC) {
+ if (ioc->bus_type == FC) {
/*
* Pre-fetch FC port WWN and stuff...
* (FCPortPage0_t stuff)
@@ -1959,7 +1783,7 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
if (ioc->cached_fw != NULL) {
ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
- if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
+ if ((ret = mpt_downloadboot(ioc, NO_SLEEP)) < 0) {
printk(KERN_WARNING MYNAM
": firmware downloadboot failure (%d)!\n", ret);
}
@@ -2007,9 +1831,9 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
}
kfree(ioc->spi_data.nvram);
- kfree(ioc->raid_data.pIocPg3);
+ kfree(ioc->spi_data.pIocPg3);
ioc->spi_data.nvram = NULL;
- ioc->raid_data.pIocPg3 = NULL;
+ ioc->spi_data.pIocPg3 = NULL;
if (ioc->spi_data.pIocPg4 != NULL) {
sz = ioc->spi_data.IocPg4Sz;
@@ -2028,23 +1852,6 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
kfree(ioc->ChainToChain);
ioc->ChainToChain = NULL;
-
- if (ioc->HostPageBuffer != NULL) {
- if((ret = mpt_host_page_access_control(ioc,
- MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
- printk(KERN_ERR MYNAM
- ": %s: host page buffers free failed (%d)!\n",
- __FUNCTION__, ret);
- }
- dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
- ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
- pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
- ioc->HostPageBuffer,
- ioc->HostPageBuffer_dma);
- ioc->HostPageBuffer = NULL;
- ioc->HostPageBuffer_sz = 0;
- ioc->alloc_total -= ioc->HostPageBuffer_sz;
- }
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2227,7 +2034,7 @@ MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
* Loop here waiting for IOC to come READY.
*/
ii = 0;
- cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
+ cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
@@ -2405,7 +2212,6 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
le32_to_cpu(facts->CurrentSenseBufferHighAddr);
facts->CurReplyFrameSize =
le16_to_cpu(facts->CurReplyFrameSize);
- facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
/*
* Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
@@ -2577,25 +2383,13 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
ioc->name, ioc->upload_fw, ioc->facts.Flags));
- if(ioc->bus_type == SAS)
- ioc_init.MaxDevices = ioc->facts.MaxDevices;
- else if(ioc->bus_type == FC)
+ if (ioc->bus_type == FC)
ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
else
ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
+
ioc_init.MaxBuses = MPT_MAX_BUS;
- dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
- ioc->name, ioc->facts.MsgVersion));
- if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
- // set MsgVersion and HeaderVersion host driver was built with
- ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
- ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
-
- if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
- ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
- } else if(mpt_host_page_alloc(ioc, &ioc_init))
- return -99;
- }
+
ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
if (sizeof(dma_addr_t) == sizeof(u64)) {
@@ -2609,21 +2403,17 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
ioc_init.HostMfaHighAddr = cpu_to_le32(0);
ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
}
-
+
ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
- ioc->facts.MaxDevices = ioc_init.MaxDevices;
- ioc->facts.MaxBuses = ioc_init.MaxBuses;
dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
ioc->name, &ioc_init));
r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
- if (r != 0) {
- printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
+ if (r != 0)
return r;
- }
/* No need to byte swap the multibyte fields in the reply
* since we don't even look at it's contents.
@@ -2682,7 +2472,7 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
{
PortEnable_t port_enable;
MPIDefaultReply_t reply_buf;
- int rc;
+ int ii;
int req_sz;
int reply_sz;
@@ -2704,15 +2494,22 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
/* RAID FW may take a long time to enable
*/
- if ( (ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
- > MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) {
- rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
- reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
+ if (ioc->bus_type == FC) {
+ ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
+ reply_sz, (u16*)&reply_buf, 65 /*seconds*/, sleepFlag);
} else {
- rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
- reply_sz, (u16*)&reply_buf, 30 /*seconds*/, sleepFlag);
+ ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
+ reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
}
- return rc;
+
+ if (ii != 0)
+ return ii;
+
+ /* We do not even look at the reply, so we need not
+ * swap the multi-byte fields.
+ */
+
+ return 0;
}
/*
@@ -2869,8 +2666,9 @@ mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
* <0 for fw upload failure.
*/
static int
-mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
+mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
{
+ MpiFwHeader_t *pFwHeader;
MpiExtImageHeader_t *pExtImage;
u32 fwSize;
u32 diag0val;
@@ -2881,8 +2679,18 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
u32 load_addr;
u32 ioc_state=0;
- ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
- ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
+ ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x, ioc FW Ptr %p\n",
+ ioc->name, ioc->facts.FWImageSize, ioc->cached_fw));
+
+ if ( ioc->facts.FWImageSize == 0 )
+ return -1;
+
+ if (ioc->cached_fw == NULL)
+ return -2;
+
+ /* prevent a second downloadboot and memory free with alt_ioc */
+ if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
+ ioc->alt_ioc->cached_fw = NULL;
CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
@@ -2910,17 +2718,16 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
ioc->name, count));
break;
}
- /* wait .1 sec */
+ /* wait 1 sec */
if (sleepFlag == CAN_SLEEP) {
- msleep_interruptible (100);
+ msleep_interruptible (1000);
} else {
- mdelay (100);
+ mdelay (1000);
}
}
if ( count == 30 ) {
- ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
- "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
+ ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! Unable to RESET_ADAPTER diag0val=%x\n",
ioc->name, diag0val));
return -3;
}
@@ -2935,6 +2742,7 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
/* Set the DiagRwEn and Disable ARM bits */
CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
+ pFwHeader = (MpiFwHeader_t *) ioc->cached_fw;
fwSize = (pFwHeader->ImageSize + 3)/4;
ptrFw = (u32 *) pFwHeader;
@@ -2984,38 +2792,19 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
/* Clear the internal flash bad bit - autoincrementing register,
* so must do two writes.
*/
- if (ioc->bus_type == SCSI) {
- /*
- * 1030 and 1035 H/W errata, workaround to access
- * the ClearFlashBadSignatureBit
- */
- CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
- diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
- diagRwData |= 0x40000000;
- CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
- CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
-
- } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
- diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
- MPI_DIAG_CLEAR_FLASH_BAD_SIG);
-
- /* wait 1 msec */
- if (sleepFlag == CAN_SLEEP) {
- msleep_interruptible (1);
- } else {
- mdelay (1);
- }
- }
+ CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
+ diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
+ diagRwData |= 0x4000000;
+ CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
+ CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
if (ioc->errata_flag_1064)
pci_disable_io_access(ioc->pcidev);
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
- ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
- "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
+ ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n",
ioc->name, diag0val));
- diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
+ diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM);
ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
ioc->name, diag0val));
CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
@@ -3023,23 +2812,10 @@ mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
/* Write 0xFF to reset the sequencer */
CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
- if (ioc->bus_type == SAS) {
- ioc_state = mpt_GetIocState(ioc, 0);
- if ( (GetIocFacts(ioc, sleepFlag,
- MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
- ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
- ioc->name, ioc_state));
- return -EFAULT;
- }
- }
-
for (count=0; countname, count, ioc_state));
- if (ioc->bus_type == SAS) {
- return 0;
- }
if ((SendIocInit(ioc, sleepFlag)) != 0) {
ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
ioc->name));
@@ -3273,13 +3049,12 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
/* wait 1 sec */
if (sleepFlag == CAN_SLEEP) {
- msleep_interruptible (1000);
+ ssleep(1);
} else {
mdelay (1000);
}
}
- if ((count = mpt_downloadboot(ioc,
- (MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
+ if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) {
printk(KERN_WARNING MYNAM
": firmware downloadboot failure (%d)!\n", count);
}
@@ -3862,7 +3637,7 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
int count = 0;
u32 intstat=0;
- cntdn = 1000 * howlong;
+ cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
if (sleepFlag == CAN_SLEEP) {
while (--cntdn) {
@@ -3912,7 +3687,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
int count = 0;
u32 intstat=0;
- cntdn = 1000 * howlong;
+ cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
if (sleepFlag == CAN_SLEEP) {
while (--cntdn) {
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
@@ -4224,85 +3999,6 @@ GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
return rc;
}
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
- * @ioc: Pointer to MPT_ADAPTER structure
- * @sas_address: 64bit SAS Address for operation.
- * @target_id: specified target for operation
- * @bus: specified bus for operation
- * @persist_opcode: see below
- *
- * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
- * devices not currently present.
- * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
- *
- * NOTE: Don't use not this function during interrupt time.
- *
- * Returns: 0 for success, non-zero error
- */
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-int
-mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
-{
- SasIoUnitControlRequest_t *sasIoUnitCntrReq;
- SasIoUnitControlReply_t *sasIoUnitCntrReply;
- MPT_FRAME_HDR *mf = NULL;
- MPIHeader_t *mpi_hdr;
-
-
- /* insure garbage is not sent to fw */
- switch(persist_opcode) {
-
- case MPI_SAS_OP_CLEAR_NOT_PRESENT:
- case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
- break;
-
- default:
- return -1;
- break;
- }
-
- printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
-
- /* Get a MF for this command.
- */
- if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
- printk("%s: no msg frames!\n",__FUNCTION__);
- return -1;
- }
-
- mpi_hdr = (MPIHeader_t *) mf;
- sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
- memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
- sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
- sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
- sasIoUnitCntrReq->Operation = persist_opcode;
-
- init_timer(&ioc->persist_timer);
- ioc->persist_timer.data = (unsigned long) ioc;
- ioc->persist_timer.function = mpt_timer_expired;
- ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
- ioc->persist_wait_done=0;
- add_timer(&ioc->persist_timer);
- mpt_put_msg_frame(mpt_base_index, ioc, mf);
- wait_event(mpt_waitq, ioc->persist_wait_done);
-
- sasIoUnitCntrReply =
- (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
- if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
- printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
- __FUNCTION__,
- sasIoUnitCntrReply->IOCStatus,
- sasIoUnitCntrReply->IOCLogInfo);
- return -1;
- }
-
- printk("%s: success\n",__FUNCTION__);
- return 0;
-}
-
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* GetIoUnitPage2 - Retrieve BIOS version and boot order information.
@@ -4644,10 +4340,10 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
if (mpt_config(ioc, &cfg) != 0)
goto done_and_free;
- if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
+ if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) {
mem = kmalloc(iocpage2sz, GFP_ATOMIC);
if (mem) {
- ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
+ ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem;
} else {
goto done_and_free;
}
@@ -4664,7 +4360,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
/* At least 1 RAID Volume
*/
pIocRv = pIoc2->RaidVolume;
- ioc->raid_data.isRaid = 0;
+ ioc->spi_data.isRaid = 0;
for (jj = 0; jj < nVols; jj++, pIocRv++) {
vid = pIocRv->VolumeID;
vbus = pIocRv->VolumeBus;
@@ -4673,7 +4369,7 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
/* find the match
*/
if (vbus == 0) {
- ioc->raid_data.isRaid |= (1 << vid);
+ ioc->spi_data.isRaid |= (1 << vid);
} else {
/* Error! Always bus 0
*/
@@ -4708,8 +4404,8 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
/* Free the old page
*/
- kfree(ioc->raid_data.pIocPg3);
- ioc->raid_data.pIocPg3 = NULL;
+ kfree(ioc->spi_data.pIocPg3);
+ ioc->spi_data.pIocPg3 = NULL;
/* There is at least one physical disk.
* Read and save IOC Page 3
@@ -4746,7 +4442,7 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
mem = kmalloc(iocpage3sz, GFP_ATOMIC);
if (mem) {
memcpy(mem, (u8 *)pIoc3, iocpage3sz);
- ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
+ ioc->spi_data.pIocPg3 = (IOCPage3_t *) mem;
}
}
@@ -5670,8 +5366,8 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static void
-EventDescriptionStr(u8 event, u32 evData0, char *evStr)
+static char *
+EventDescriptionStr(u8 event, u32 evData0)
{
char *ds;
@@ -5724,95 +5420,8 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
ds = "Events(OFF) Change";
break;
case MPI_EVENT_INTEGRATED_RAID:
- {
- u8 ReasonCode = (u8)(evData0 >> 16);
- switch (ReasonCode) {
- case MPI_EVENT_RAID_RC_VOLUME_CREATED :
- ds = "Integrated Raid: Volume Created";
- break;
- case MPI_EVENT_RAID_RC_VOLUME_DELETED :
- ds = "Integrated Raid: Volume Deleted";
- break;
- case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
- ds = "Integrated Raid: Volume Settings Changed";
- break;
- case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
- ds = "Integrated Raid: Volume Status Changed";
- break;
- case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
- ds = "Integrated Raid: Volume Physdisk Changed";
- break;
- case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
- ds = "Integrated Raid: Physdisk Created";
- break;
- case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
- ds = "Integrated Raid: Physdisk Deleted";
- break;
- case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
- ds = "Integrated Raid: Physdisk Settings Changed";
- break;
- case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
- ds = "Integrated Raid: Physdisk Status Changed";
- break;
- case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
- ds = "Integrated Raid: Domain Validation Needed";
- break;
- case MPI_EVENT_RAID_RC_SMART_DATA :
- ds = "Integrated Raid; Smart Data";
- break;
- case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
- ds = "Integrated Raid: Replace Action Started";
- break;
- default:
- ds = "Integrated Raid";
- break;
- }
- break;
- }
- case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
- ds = "SCSI Device Status Change";
- break;
- case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
- {
- u8 ReasonCode = (u8)(evData0 >> 16);
- switch (ReasonCode) {
- case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
- ds = "SAS Device Status Change: Added";
- break;
- case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
- ds = "SAS Device Status Change: Deleted";
- break;
- case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
- ds = "SAS Device Status Change: SMART Data";
- break;
- case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
- ds = "SAS Device Status Change: No Persistancy Added";
- break;
- default:
- ds = "SAS Device Status Change: Unknown";
- break;
- }
- break;
- }
- case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
- ds = "Bus Timer Expired";
- break;
- case MPI_EVENT_QUEUE_FULL:
- ds = "Queue Full";
- break;
- case MPI_EVENT_SAS_SES:
- ds = "SAS SES Event";
- break;
- case MPI_EVENT_PERSISTENT_TABLE_FULL:
- ds = "Persistent Table Full";
- break;
- case MPI_EVENT_SAS_PHY_LINK_STATUS:
- ds = "SAS PHY Link Status";
- break;
- case MPI_EVENT_SAS_DISCOVERY_ERROR:
- ds = "SAS Discovery Error";
+ ds = "Integrated Raid";
break;
-
/*
* MPT base "custom" events may be added here...
*/
@@ -5820,7 +5429,7 @@ EventDescriptionStr(u8 event, u32 evData0, char *evStr)
ds = "Unknown";
break;
}
- strcpy(evStr,ds);
+ return ds;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -5842,7 +5451,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
int ii;
int r = 0;
int handlers = 0;
- char evStr[100];
+ char *evStr;
u8 event;
/*
@@ -5855,7 +5464,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
evData0 = le32_to_cpu(pEventReply->Data[0]);
}
- EventDescriptionStr(event, evData0, evStr);
+ evStr = EventDescriptionStr(event, evData0);
devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
ioc->name,
evStr,
@@ -5872,6 +5481,20 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
* Do general / base driver event processing
*/
switch(event) {
+ case MPI_EVENT_NONE: /* 00 */
+ case MPI_EVENT_LOG_DATA: /* 01 */
+ case MPI_EVENT_STATE_CHANGE: /* 02 */
+ case MPI_EVENT_UNIT_ATTENTION: /* 03 */
+ case MPI_EVENT_IOC_BUS_RESET: /* 04 */
+ case MPI_EVENT_EXT_BUS_RESET: /* 05 */
+ case MPI_EVENT_RESCAN: /* 06 */
+ case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
+ case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
+ case MPI_EVENT_LOGOUT: /* 09 */
+ case MPI_EVENT_INTEGRATED_RAID: /* 0B */
+ case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE: /* 0C */
+ default:
+ break;
case MPI_EVENT_EVENT_CHANGE: /* 0A */
if (evDataLen) {
u8 evState = evData0 & 0xFF;
@@ -5884,8 +5507,6 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
}
}
break;
- default:
- break;
}
/*
@@ -6032,111 +5653,6 @@ mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
}
-/* strings for sas loginfo */
- static char *originator_str[] = {
- "IOP", /* 00h */
- "PL", /* 01h */
- "IR" /* 02h */
- };
- static char *iop_code_str[] = {
- NULL, /* 00h */
- "Invalid SAS Address", /* 01h */
- NULL, /* 02h */
- "Invalid Page", /* 03h */
- NULL, /* 04h */
- "Task Terminated" /* 05h */
- };
- static char *pl_code_str[] = {
- NULL, /* 00h */
- "Open Failure", /* 01h */
- "Invalid Scatter Gather List", /* 02h */
- "Wrong Relative Offset or Frame Length", /* 03h */
- "Frame Transfer Error", /* 04h */
- "Transmit Frame Connected Low", /* 05h */
- "SATA Non-NCQ RW Error Bit Set", /* 06h */
- "SATA Read Log Receive Data Error", /* 07h */
- "SATA NCQ Fail All Commands After Error", /* 08h */
- "SATA Error in Receive Set Device Bit FIS", /* 09h */
- "Receive Frame Invalid Message", /* 0Ah */
- "Receive Context Message Valid Error", /* 0Bh */
- "Receive Frame Current Frame Error", /* 0Ch */
- "SATA Link Down", /* 0Dh */
- "Discovery SATA Init W IOS", /* 0Eh */
- "Config Invalid Page", /* 0Fh */
- "Discovery SATA Init Timeout", /* 10h */
- "Reset", /* 11h */
- "Abort", /* 12h */
- "IO Not Yet Executed", /* 13h */
- "IO Executed", /* 14h */
- NULL, /* 15h */
- NULL, /* 16h */
- NULL, /* 17h */
- NULL, /* 18h */
- NULL, /* 19h */
- NULL, /* 1Ah */
- NULL, /* 1Bh */
- NULL, /* 1Ch */
- NULL, /* 1Dh */
- NULL, /* 1Eh */
- NULL, /* 1Fh */
- "Enclosure Management" /* 20h */
- };
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- * mpt_sas_log_info - Log information returned from SAS IOC.
- * @ioc: Pointer to MPT_ADAPTER structure
- * @log_info: U32 LogInfo reply word from the IOC
- *
- * Refer to lsi/mpi_log_sas.h.
- */
-static void
-mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
-{
-union loginfo_type {
- u32 loginfo;
- struct {
- u32 subcode:16;
- u32 code:8;
- u32 originator:4;
- u32 bus_type:4;
- }dw;
-};
- union loginfo_type sas_loginfo;
- char *code_desc = NULL;
-
- sas_loginfo.loginfo = log_info;
- if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
- (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
- return;
- if ((sas_loginfo.dw.originator == 0 /*IOP*/) &&
- (sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) {
- code_desc = iop_code_str[sas_loginfo.dw.code];
- }else if ((sas_loginfo.dw.originator == 1 /*PL*/) &&
- (sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) {
- code_desc = pl_code_str[sas_loginfo.dw.code];
- }
-
- if (code_desc != NULL)
- printk(MYIOC_s_INFO_FMT
- "LogInfo(0x%08x): Originator={%s}, Code={%s},"
- " SubCode(0x%04x)\n",
- ioc->name,
- log_info,
- originator_str[sas_loginfo.dw.originator],
- code_desc,
- sas_loginfo.dw.subcode);
- else
- printk(MYIOC_s_INFO_FMT
- "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
- " SubCode(0x%04x)\n",
- ioc->name,
- log_info,
- originator_str[sas_loginfo.dw.originator],
- sas_loginfo.dw.code,
- sas_loginfo.dw.subcode);
-}
-
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
@@ -6298,7 +5814,6 @@ EXPORT_SYMBOL(mpt_findImVolumes);
EXPORT_SYMBOL(mpt_read_ioc_pg_3);
EXPORT_SYMBOL(mpt_alloc_fw_memory);
EXPORT_SYMBOL(mpt_free_fw_memory);
-EXPORT_SYMBOL(mptbase_sas_persist_operation);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff --git a/trunk/drivers/message/fusion/mptbase.h b/trunk/drivers/message/fusion/mptbase.h
index 75105277e22f..f4827d923731 100644
--- a/trunk/drivers/message/fusion/mptbase.h
+++ b/trunk/drivers/message/fusion/mptbase.h
@@ -65,7 +65,6 @@
#include "lsi/mpi_fc.h" /* Fibre Channel (lowlevel) support */
#include "lsi/mpi_targ.h" /* SCSI/FCP Target protcol support */
#include "lsi/mpi_tool.h" /* Tools support */
-#include "lsi/mpi_sas.h" /* SAS support */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -77,8 +76,8 @@
#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
#endif
-#define MPT_LINUX_VERSION_COMMON "3.03.03"
-#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.03"
+#define MPT_LINUX_VERSION_COMMON "3.03.02"
+#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.02"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
@@ -424,7 +423,7 @@ typedef struct _MPT_IOCTL {
/*
* Event Structure and define
*/
-#define MPTCTL_EVENT_LOG_SIZE (0x000000032)
+#define MPTCTL_EVENT_LOG_SIZE (0x0000000A)
typedef struct _mpt_ioctl_events {
u32 event; /* Specified by define above */
u32 eventContext; /* Index or counter */
@@ -452,13 +451,16 @@ typedef struct _mpt_ioctl_events {
#define MPT_SCSICFG_ALL_IDS 0x02 /* WriteSDP1 to all IDS */
/* #define MPT_SCSICFG_BLK_NEGO 0x10 WriteSDP1 with WDTR and SDTR disabled */
-typedef struct _SpiCfgData {
+typedef struct _ScsiCfgData {
u32 PortFlags;
int *nvram; /* table of device NVRAM values */
+ IOCPage2_t *pIocPg2; /* table of Raid Volumes */
+ IOCPage3_t *pIocPg3; /* table of physical disks */
IOCPage4_t *pIocPg4; /* SEP devices addressing */
dma_addr_t IocPg4_dma; /* Phys Addr of IOCPage4 data */
int IocPg4Sz; /* IOCPage4 size */
u8 dvStatus[MPT_MAX_SCSI_DEVICES];
+ int isRaid; /* bit field, 1 if RAID */
u8 minSyncFactor; /* 0xFF if async */
u8 maxSyncOffset; /* 0 if async */
u8 maxBusWidth; /* 0 if narrow, 1 if wide */
@@ -470,28 +472,10 @@ typedef struct _SpiCfgData {
u8 dvScheduled; /* 1 if scheduled */
u8 forceDv; /* 1 to force DV scheduling */
u8 noQas; /* Disable QAS for this adapter */
- u8 Saf_Te; /* 1 to force all Processors as
- * SAF-TE if Inquiry data length
- * is too short to check for SAF-TE
- */
+ u8 Saf_Te; /* 1 to force all Processors as SAF-TE if Inquiry data length is too short to check for SAF-TE */
u8 mpt_dv; /* command line option: enhanced=1, basic=0 */
- u8 bus_reset; /* 1 to allow bus reset */
u8 rsvd[1];
-}SpiCfgData;
-
-typedef struct _SasCfgData {
- u8 ptClear; /* 1 to automatically clear the
- * persistent table.
- * 0 to disable
- * automatic clearing.
- */
-}SasCfgData;
-
-typedef struct _RaidCfgData {
- IOCPage2_t *pIocPg2; /* table of Raid Volumes */
- IOCPage3_t *pIocPg3; /* table of physical disks */
- int isRaid; /* bit field, 1 if RAID */
-}RaidCfgData;
+} ScsiCfgData;
/*
* Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
@@ -546,16 +530,11 @@ typedef struct _MPT_ADAPTER
u8 *sense_buf_pool;
dma_addr_t sense_buf_pool_dma;
u32 sense_buf_low_dma;
- u8 *HostPageBuffer; /* SAS - host page buffer support */
- u32 HostPageBuffer_sz;
- dma_addr_t HostPageBuffer_dma;
int mtrr_reg;
struct pci_dev *pcidev; /* struct pci_dev pointer */
u8 __iomem *memmap; /* mmap address */
struct Scsi_Host *sh; /* Scsi Host pointer */
- SpiCfgData spi_data; /* Scsi config. data */
- RaidCfgData raid_data; /* Raid config. data */
- SasCfgData sas_data; /* Sas config. data */
+ ScsiCfgData spi_data; /* Scsi config. data */
MPT_IOCTL *ioctl; /* ioctl data pointer */
struct proc_dir_entry *ioc_dentry;
struct _MPT_ADAPTER *alt_ioc; /* ptr to 929 bound adapter port */
@@ -575,35 +554,31 @@ typedef struct _MPT_ADAPTER
#else
u32 mfcnt;
#endif
- u32 NB_for_64_byte_frame;
+ u32 NB_for_64_byte_frame;
u32 hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)];
u16 hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)];
IOCFactsReply_t facts;
PortFactsReply_t pfacts[2];
FCPortPage0_t fc_port_page0[2];
- struct timer_list persist_timer; /* persist table timer */
- int persist_wait_done; /* persist completion flag */
- u8 persist_reply_frame[MPT_DEFAULT_FRAME_SIZE]; /* persist reply */
LANPage0_t lan_cnfg_page0;
LANPage1_t lan_cnfg_page1;
- /*
+ /*
* Description: errata_flag_1064
* If a PCIX read occurs within 1 or 2 cycles after the chip receives
* a split completion for a read data, an internal address pointer incorrectly
* increments by 32 bytes
*/
- int errata_flag_1064;
+ int errata_flag_1064;
u8 FirstWhoInit;
u8 upload_fw; /* If set, do a fw upload */
u8 reload_fw; /* Force a FW Reload on next reset */
- u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */
+ u8 NBShiftFactor; /* NB Shift Factor based on Block Size (Facts) */
u8 pad1[4];
int DoneCtx;
int TaskCtx;
int InternalCtx;
- struct list_head list;
+ struct list_head list;
struct net_device *netdev;
- struct list_head sas_topology;
} MPT_ADAPTER;
/*
@@ -989,7 +964,6 @@ extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
extern int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
-extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
/*
* Public data decl's...
diff --git a/trunk/drivers/message/fusion/mptctl.c b/trunk/drivers/message/fusion/mptctl.c
index cb2d59d5f5af..7577c2417e2e 100644
--- a/trunk/drivers/message/fusion/mptctl.c
+++ b/trunk/drivers/message/fusion/mptctl.c
@@ -1326,7 +1326,7 @@ mptctl_gettargetinfo (unsigned long arg)
*/
if (hd && hd->Targets) {
mpt_findImVolumes(ioc);
- pIoc2 = ioc->raid_data.pIocPg2;
+ pIoc2 = ioc->spi_data.pIocPg2;
for ( id = 0; id <= max_id; ) {
if ( pIoc2 && pIoc2->NumActiveVolumes ) {
if ( id == pIoc2->RaidVolume[0].VolumeID ) {
@@ -1348,7 +1348,7 @@ mptctl_gettargetinfo (unsigned long arg)
--maxWordsLeft;
goto next_id;
} else {
- pIoc3 = ioc->raid_data.pIocPg3;
+ pIoc3 = ioc->spi_data.pIocPg3;
for ( jj = 0; jj < pIoc3->NumPhysDisks; jj++ ) {
if ( pIoc3->PhysDisk[jj].PhysDiskID == id )
goto next_id;
diff --git a/trunk/drivers/message/fusion/mptfc.c b/trunk/drivers/message/fusion/mptfc.c
index a628be9bbbad..13771abea13f 100644
--- a/trunk/drivers/message/fusion/mptfc.c
+++ b/trunk/drivers/message/fusion/mptfc.c
@@ -189,7 +189,7 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT
"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
ioc->name, ioc);
- return 0;
+ return -ENODEV;
}
sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
diff --git a/trunk/drivers/message/fusion/mptlan.c b/trunk/drivers/message/fusion/mptlan.c
index ed3c891e388f..52794be5a95c 100644
--- a/trunk/drivers/message/fusion/mptlan.c
+++ b/trunk/drivers/message/fusion/mptlan.c
@@ -312,12 +312,7 @@ static int
mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
{
struct net_device *dev = ioc->netdev;
- struct mpt_lan_priv *priv;
-
- if (dev == NULL)
- return(1);
- else
- priv = netdev_priv(dev);
+ struct mpt_lan_priv *priv = netdev_priv(dev);
dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n",
reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
diff --git a/trunk/drivers/message/fusion/mptsas.c b/trunk/drivers/message/fusion/mptsas.c
deleted file mode 100644
index 429820e48c69..000000000000
--- a/trunk/drivers/message/fusion/mptsas.c
+++ /dev/null
@@ -1,1235 +0,0 @@
-/*
- * linux/drivers/message/fusion/mptsas.c
- * For use with LSI Logic PCI chip/adapter(s)
- * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
- *
- * Copyright (c) 1999-2005 LSI Logic Corporation
- * (mailto:mpt_linux_developer@lsil.com)
- * Copyright (c) 2005 Dell
- */
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- NO WARRANTY
- THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
- CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
- LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
- MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
- solely responsible for determining the appropriateness of using and
- distributing the Program and assumes all risks associated with its
- exercise of rights under this Agreement, including but not limited to
- the risks and costs of program errors, damage to or loss of data,
- programs or equipment, and unavailability or interruption of operations.
-
- DISCLAIMER OF LIABILITY
- NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
- HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#include "mptbase.h"
-#include "mptscsih.h"
-
-
-#define my_NAME "Fusion MPT SAS Host driver"
-#define my_VERSION MPT_LINUX_VERSION_COMMON
-#define MYNAM "mptsas"
-
-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 "
- "(default=MPTSCSIH_PT_CLEAR=0)");
-
-static int mptsasDoneCtx = -1;
-static int mptsasTaskCtx = -1;
-static int mptsasInternalCtx = -1; /* Used only for internal commands */
-
-
-/*
- * SAS topology structures
- *
- * The MPT Fusion firmware interface spreads information about the
- * SAS topology over many manufacture pages, thus we need some data
- * structure to collect it and process it for the SAS transport class.
- */
-
-struct mptsas_devinfo {
- u16 handle; /* unique id to address this device */
- u8 phy_id; /* phy number of parent device */
- u8 port_id; /* sas physical port this device
- is assoc'd with */
- u8 target; /* logical target id of this device */
- u8 bus; /* logical bus number of this device */
- u64 sas_address; /* WWN of this device,
- SATA is assigned by HBA,expander */
- u32 device_info; /* bitfield detailed info about this device */
-};
-
-struct mptsas_phyinfo {
- u8 phy_id; /* phy index */
- u8 port_id; /* port number this phy is part of */
- u8 negotiated_link_rate; /* nego'd link rate for this phy */
- u8 hw_link_rate; /* hardware max/min phys link rate */
- u8 programmed_link_rate; /* programmed max/min phy link rate */
- struct mptsas_devinfo identify; /* point to phy device info */
- struct mptsas_devinfo attached; /* point to attached device info */
- struct sas_rphy *rphy;
-};
-
-struct mptsas_portinfo {
- struct list_head list;
- u16 handle; /* unique id to address this */
- u8 num_phys; /* number of phys */
- struct mptsas_phyinfo *phy_info;
-};
-
-/*
- * This is pretty ugly. We will be able to seriously clean it up
- * once the DV code in mptscsih goes away and we can properly
- * implement ->target_alloc.
- */
-static int
-mptsas_slave_alloc(struct scsi_device *device)
-{
- struct Scsi_Host *host = device->host;
- MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
- struct sas_rphy *rphy;
- struct mptsas_portinfo *p;
- VirtDevice *vdev;
- uint target = device->id;
- int i;
-
- if ((vdev = hd->Targets[target]) != NULL)
- goto out;
-
- vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
- if (!vdev) {
- printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
- hd->ioc->name, sizeof(VirtDevice));
- return -ENOMEM;
- }
-
- memset(vdev, 0, sizeof(VirtDevice));
- vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY;
- vdev->ioc_id = hd->ioc->id;
-
- rphy = dev_to_rphy(device->sdev_target->dev.parent);
- list_for_each_entry(p, &hd->ioc->sas_topology, list) {
- for (i = 0; i < p->num_phys; i++) {
- if (p->phy_info[i].attached.sas_address ==
- rphy->identify.sas_address) {
- vdev->target_id =
- p->phy_info[i].attached.target;
- vdev->bus_id = p->phy_info[i].attached.bus;
- hd->Targets[device->id] = vdev;
- goto out;
- }
- }
- }
-
- printk("No matching SAS device found!!\n");
- kfree(vdev);
- return -ENODEV;
-
- out:
- vdev->num_luns++;
- device->hostdata = vdev;
- return 0;
-}
-
-static struct scsi_host_template mptsas_driver_template = {
- .proc_name = "mptsas",
- .proc_info = mptscsih_proc_info,
- .name = "MPT SPI Host",
- .info = mptscsih_info,
- .queuecommand = mptscsih_qcmd,
- .slave_alloc = mptsas_slave_alloc,
- .slave_configure = mptscsih_slave_configure,
- .slave_destroy = mptscsih_slave_destroy,
- .change_queue_depth = mptscsih_change_queue_depth,
- .eh_abort_handler = mptscsih_abort,
- .eh_device_reset_handler = mptscsih_dev_reset,
- .eh_bus_reset_handler = mptscsih_bus_reset,
- .eh_host_reset_handler = mptscsih_host_reset,
- .bios_param = mptscsih_bios_param,
- .can_queue = MPT_FC_CAN_QUEUE,
- .this_id = -1,
- .sg_tablesize = MPT_SCSI_SG_DEPTH,
- .max_sectors = 8192,
- .cmd_per_lun = 7,
- .use_clustering = ENABLE_CLUSTERING,
-};
-
-static struct sas_function_template mptsas_transport_functions = {
-};
-
-static struct scsi_transport_template *mptsas_transport_template;
-
-#ifdef SASDEBUG
-static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data)
-{
- printk("---- IO UNIT PAGE 0 ------------\n");
- printk("Handle=0x%X\n",
- le16_to_cpu(phy_data->AttachedDeviceHandle));
- printk("Controller Handle=0x%X\n",
- le16_to_cpu(phy_data->ControllerDevHandle));
- printk("Port=0x%X\n", phy_data->Port);
- printk("Port Flags=0x%X\n", phy_data->PortFlags);
- printk("PHY Flags=0x%X\n", phy_data->PhyFlags);
- printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate);
- printk("Controller PHY Device Info=0x%X\n",
- le32_to_cpu(phy_data->ControllerPhyDeviceInfo));
- printk("DiscoveryStatus=0x%X\n",
- le32_to_cpu(phy_data->DiscoveryStatus));
- printk("\n");
-}
-
-static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0)
-{
- __le64 sas_address;
-
- memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
-
- printk("---- SAS PHY PAGE 0 ------------\n");
- printk("Attached Device Handle=0x%X\n",
- le16_to_cpu(pg0->AttachedDevHandle));
- printk("SAS Address=0x%llX\n",
- (unsigned long long)le64_to_cpu(sas_address));
- printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier);
- printk("Attached Device Info=0x%X\n",
- le32_to_cpu(pg0->AttachedDeviceInfo));
- printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate);
- printk("Change Count=0x%X\n", pg0->ChangeCount);
- printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo));
- printk("\n");
-}
-
-static void mptsas_print_device_pg0(SasDevicePage0_t *pg0)
-{
- __le64 sas_address;
-
- memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64));
-
- printk("---- SAS DEVICE PAGE 0 ---------\n");
- printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle));
- printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle));
- printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot));
- printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address));
- printk("Target ID=0x%X\n", pg0->TargetID);
- printk("Bus=0x%X\n", pg0->Bus);
- printk("PhyNum=0x%X\n", pg0->PhyNum);
- printk("AccessStatus=0x%X\n", le16_to_cpu(pg0->AccessStatus));
- printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo));
- printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags));
- printk("Physical Port=0x%X\n", pg0->PhysicalPort);
- printk("\n");
-}
-
-static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1)
-{
- printk("---- SAS EXPANDER PAGE 1 ------------\n");
-
- printk("Physical Port=0x%X\n", pg1->PhysicalPort);
- printk("PHY Identifier=0x%X\n", pg1->Phy);
- printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate);
- printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate);
- printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate);
- printk("Owner Device Handle=0x%X\n",
- le16_to_cpu(pg1->OwnerDevHandle));
- printk("Attached Device Handle=0x%X\n",
- le16_to_cpu(pg1->AttachedDevHandle));
-}
-#else
-#define mptsas_print_phy_data(phy_data) do { } while (0)
-#define mptsas_print_phy_pg0(pg0) do { } while (0)
-#define mptsas_print_device_pg0(pg0) do { } while (0)
-#define mptsas_print_expander_pg1(pg1) do { } while (0)
-#endif
-
-static int
-mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info)
-{
- ConfigExtendedPageHeader_t hdr;
- CONFIGPARMS cfg;
- SasIOUnitPage0_t *buffer;
- dma_addr_t dma_handle;
- int error, i;
-
- hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
- hdr.ExtPageLength = 0;
- hdr.PageNumber = 0;
- hdr.Reserved1 = 0;
- hdr.Reserved2 = 0;
- hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
- hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
-
- cfg.cfghdr.ehdr = &hdr;
- cfg.physAddr = -1;
- cfg.pageAddr = 0;
- cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
- cfg.dir = 0; /* read */
- cfg.timeout = 10;
-
- error = mpt_config(ioc, &cfg);
- if (error)
- goto out;
- if (!hdr.ExtPageLength) {
- error = -ENXIO;
- goto out;
- }
-
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- &dma_handle);
- if (!buffer) {
- error = -ENOMEM;
- goto out;
- }
-
- cfg.physAddr = dma_handle;
- cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
-
- error = mpt_config(ioc, &cfg);
- if (error)
- goto out_free_consistent;
-
- port_info->num_phys = buffer->NumPhys;
- port_info->phy_info = kcalloc(port_info->num_phys,
- sizeof(struct mptsas_phyinfo),GFP_KERNEL);
- if (!port_info->phy_info) {
- error = -ENOMEM;
- goto out_free_consistent;
- }
-
- for (i = 0; i < port_info->num_phys; i++) {
- mptsas_print_phy_data(&buffer->PhyData[i]);
- port_info->phy_info[i].phy_id = i;
- port_info->phy_info[i].port_id =
- buffer->PhyData[i].Port;
- port_info->phy_info[i].negotiated_link_rate =
- buffer->PhyData[i].NegotiatedLinkRate;
- }
-
- out_free_consistent:
- pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- buffer, dma_handle);
- out:
- return error;
-}
-
-static int
-mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
- u32 form, u32 form_specific)
-{
- ConfigExtendedPageHeader_t hdr;
- CONFIGPARMS cfg;
- SasPhyPage0_t *buffer;
- dma_addr_t dma_handle;
- int error;
-
- hdr.PageVersion = MPI_SASPHY0_PAGEVERSION;
- hdr.ExtPageLength = 0;
- hdr.PageNumber = 0;
- hdr.Reserved1 = 0;
- hdr.Reserved2 = 0;
- hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
- hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY;
-
- cfg.cfghdr.ehdr = &hdr;
- cfg.dir = 0; /* read */
- cfg.timeout = 10;
-
- /* Get Phy Pg 0 for each Phy. */
- cfg.physAddr = -1;
- cfg.pageAddr = form + form_specific;
- cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
-
- error = mpt_config(ioc, &cfg);
- if (error)
- goto out;
-
- if (!hdr.ExtPageLength) {
- error = -ENXIO;
- goto out;
- }
-
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- &dma_handle);
- if (!buffer) {
- error = -ENOMEM;
- goto out;
- }
-
- cfg.physAddr = dma_handle;
- cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
-
- error = mpt_config(ioc, &cfg);
- if (error)
- goto out_free_consistent;
-
- mptsas_print_phy_pg0(buffer);
-
- phy_info->hw_link_rate = buffer->HwLinkRate;
- phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
- phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
- phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
-
- out_free_consistent:
- pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- buffer, dma_handle);
- out:
- return error;
-}
-
-static int
-mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
- u32 form, u32 form_specific)
-{
- ConfigExtendedPageHeader_t hdr;
- CONFIGPARMS cfg;
- SasDevicePage0_t *buffer;
- dma_addr_t dma_handle;
- __le64 sas_address;
- int error;
-
- hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION;
- hdr.ExtPageLength = 0;
- hdr.PageNumber = 0;
- hdr.Reserved1 = 0;
- hdr.Reserved2 = 0;
- hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
- hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE;
-
- cfg.cfghdr.ehdr = &hdr;
- cfg.pageAddr = form + form_specific;
- cfg.physAddr = -1;
- cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
- cfg.dir = 0; /* read */
- cfg.timeout = 10;
-
- error = mpt_config(ioc, &cfg);
- if (error)
- goto out;
- if (!hdr.ExtPageLength) {
- error = -ENXIO;
- goto out;
- }
-
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- &dma_handle);
- if (!buffer) {
- error = -ENOMEM;
- goto out;
- }
-
- cfg.physAddr = dma_handle;
- cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
-
- error = mpt_config(ioc, &cfg);
- if (error)
- goto out_free_consistent;
-
- mptsas_print_device_pg0(buffer);
-
- device_info->handle = le16_to_cpu(buffer->DevHandle);
- device_info->phy_id = buffer->PhyNum;
- device_info->port_id = buffer->PhysicalPort;
- device_info->target = buffer->TargetID;
- device_info->bus = buffer->Bus;
- memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
- device_info->sas_address = le64_to_cpu(sas_address);
- device_info->device_info =
- le32_to_cpu(buffer->DeviceInfo);
-
- out_free_consistent:
- pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- buffer, dma_handle);
- out:
- return error;
-}
-
-static int
-mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info,
- u32 form, u32 form_specific)
-{
- ConfigExtendedPageHeader_t hdr;
- CONFIGPARMS cfg;
- SasExpanderPage0_t *buffer;
- dma_addr_t dma_handle;
- int error;
-
- hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
- hdr.ExtPageLength = 0;
- hdr.PageNumber = 0;
- hdr.Reserved1 = 0;
- hdr.Reserved2 = 0;
- hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
- hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
-
- cfg.cfghdr.ehdr = &hdr;
- cfg.physAddr = -1;
- cfg.pageAddr = form + form_specific;
- cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
- cfg.dir = 0; /* read */
- cfg.timeout = 10;
-
- error = mpt_config(ioc, &cfg);
- if (error)
- goto out;
-
- if (!hdr.ExtPageLength) {
- error = -ENXIO;
- goto out;
- }
-
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- &dma_handle);
- if (!buffer) {
- error = -ENOMEM;
- goto out;
- }
-
- cfg.physAddr = dma_handle;
- cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
-
- error = mpt_config(ioc, &cfg);
- if (error)
- goto out_free_consistent;
-
- /* save config data */
- port_info->num_phys = buffer->NumPhys;
- port_info->handle = le16_to_cpu(buffer->DevHandle);
- port_info->phy_info = kcalloc(port_info->num_phys,
- sizeof(struct mptsas_phyinfo),GFP_KERNEL);
- if (!port_info->phy_info) {
- error = -ENOMEM;
- goto out_free_consistent;
- }
-
- out_free_consistent:
- pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- buffer, dma_handle);
- out:
- return error;
-}
-
-static int
-mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
- u32 form, u32 form_specific)
-{
- ConfigExtendedPageHeader_t hdr;
- CONFIGPARMS cfg;
- SasExpanderPage1_t *buffer;
- dma_addr_t dma_handle;
- int error;
-
- hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION;
- hdr.ExtPageLength = 0;
- hdr.PageNumber = 1;
- hdr.Reserved1 = 0;
- hdr.Reserved2 = 0;
- hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
- hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER;
-
- cfg.cfghdr.ehdr = &hdr;
- cfg.physAddr = -1;
- cfg.pageAddr = form + form_specific;
- cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
- cfg.dir = 0; /* read */
- cfg.timeout = 10;
-
- error = mpt_config(ioc, &cfg);
- if (error)
- goto out;
-
- if (!hdr.ExtPageLength) {
- error = -ENXIO;
- goto out;
- }
-
- buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- &dma_handle);
- if (!buffer) {
- error = -ENOMEM;
- goto out;
- }
-
- cfg.physAddr = dma_handle;
- cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
-
- error = mpt_config(ioc, &cfg);
- if (error)
- goto out_free_consistent;
-
-
- mptsas_print_expander_pg1(buffer);
-
- /* save config data */
- phy_info->phy_id = buffer->Phy;
- phy_info->port_id = buffer->PhysicalPort;
- phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate;
- phy_info->programmed_link_rate = buffer->ProgrammedLinkRate;
- phy_info->hw_link_rate = buffer->HwLinkRate;
- phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle);
- phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle);
-
-
- out_free_consistent:
- pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
- buffer, dma_handle);
- out:
- return error;
-}
-
-static void
-mptsas_parse_device_info(struct sas_identify *identify,
- struct mptsas_devinfo *device_info)
-{
- u16 protocols;
-
- identify->sas_address = device_info->sas_address;
- identify->phy_identifier = device_info->phy_id;
-
- /*
- * Fill in Phy Initiator Port Protocol.
- * Bits 6:3, more than one bit can be set, fall through cases.
- */
- protocols = device_info->device_info & 0x78;
- identify->initiator_port_protocols = 0;
- if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR)
- identify->initiator_port_protocols |= SAS_PROTOCOL_SSP;
- if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR)
- identify->initiator_port_protocols |= SAS_PROTOCOL_STP;
- if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR)
- identify->initiator_port_protocols |= SAS_PROTOCOL_SMP;
- if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST)
- identify->initiator_port_protocols |= SAS_PROTOCOL_SATA;
-
- /*
- * Fill in Phy Target Port Protocol.
- * Bits 10:7, more than one bit can be set, fall through cases.
- */
- protocols = device_info->device_info & 0x780;
- identify->target_port_protocols = 0;
- if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET)
- identify->target_port_protocols |= SAS_PROTOCOL_SSP;
- if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET)
- identify->target_port_protocols |= SAS_PROTOCOL_STP;
- if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET)
- identify->target_port_protocols |= SAS_PROTOCOL_SMP;
- if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE)
- identify->target_port_protocols |= SAS_PROTOCOL_SATA;
-
- /*
- * Fill in Attached device type.
- */
- switch (device_info->device_info &
- MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) {
- case MPI_SAS_DEVICE_INFO_NO_DEVICE:
- identify->device_type = SAS_PHY_UNUSED;
- break;
- case MPI_SAS_DEVICE_INFO_END_DEVICE:
- identify->device_type = SAS_END_DEVICE;
- break;
- case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER:
- identify->device_type = SAS_EDGE_EXPANDER_DEVICE;
- break;
- case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER:
- identify->device_type = SAS_FANOUT_EXPANDER_DEVICE;
- break;
- }
-}
-
-static int mptsas_probe_one_phy(struct device *dev,
- struct mptsas_phyinfo *phy_info, int index)
-{
- struct sas_phy *port;
- int error;
-
- port = sas_phy_alloc(dev, index);
- if (!port)
- return -ENOMEM;
-
- port->port_identifier = phy_info->port_id;
- mptsas_parse_device_info(&port->identify, &phy_info->identify);
-
- /*
- * Set Negotiated link rate.
- */
- switch (phy_info->negotiated_link_rate) {
- case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED:
- port->negotiated_linkrate = SAS_PHY_DISABLED;
- break;
- case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION:
- port->negotiated_linkrate = SAS_LINK_RATE_FAILED;
- break;
- case MPI_SAS_IOUNIT0_RATE_1_5:
- port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS;
- break;
- case MPI_SAS_IOUNIT0_RATE_3_0:
- port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS;
- break;
- case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE:
- case MPI_SAS_IOUNIT0_RATE_UNKNOWN:
- default:
- port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
- break;
- }
-
- /*
- * Set Max hardware link rate.
- */
- switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
- case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5:
- port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
- break;
- case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
- port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
- break;
- default:
- break;
- }
-
- /*
- * Set Max programmed link rate.
- */
- switch (phy_info->programmed_link_rate &
- MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) {
- case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5:
- port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS;
- break;
- case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0:
- port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS;
- break;
- default:
- break;
- }
-
- /*
- * Set Min hardware link rate.
- */
- switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) {
- case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5:
- port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
- break;
- case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
- port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS;
- break;
- default:
- break;
- }
-
- /*
- * Set Min programmed link rate.
- */
- switch (phy_info->programmed_link_rate &
- MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) {
- case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5:
- port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
- break;
- case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0:
- port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS;
- break;
- default:
- break;
- }
-
- error = sas_phy_add(port);
- if (error) {
- sas_phy_free(port);
- return error;
- }
-
- if (phy_info->attached.handle) {
- struct sas_rphy *rphy;
-
- rphy = sas_rphy_alloc(port);
- if (!rphy)
- return 0; /* non-fatal: an rphy can be added later */
-
- mptsas_parse_device_info(&rphy->identify, &phy_info->attached);
- error = sas_rphy_add(rphy);
- if (error) {
- sas_rphy_free(rphy);
- return error;
- }
-
- phy_info->rphy = rphy;
- }
-
- return 0;
-}
-
-static int
-mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index)
-{
- struct mptsas_portinfo *port_info;
- u32 handle = 0xFFFF;
- int error = -ENOMEM, i;
-
- port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
- if (!port_info)
- goto out;
- memset(port_info, 0, sizeof(*port_info));
-
- error = mptsas_sas_io_unit_pg0(ioc, port_info);
- if (error)
- goto out_free_port_info;
-
- list_add_tail(&port_info->list, &ioc->sas_topology);
-
- for (i = 0; i < port_info->num_phys; i++) {
- mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
- (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
- MPI_SAS_PHY_PGAD_FORM_SHIFT), i);
-
- mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify,
- (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE <<
- MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle);
- handle = port_info->phy_info[i].identify.handle;
-
- if (port_info->phy_info[i].attached.handle) {
- mptsas_sas_device_pg0(ioc,
- &port_info->phy_info[i].attached,
- (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
- MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
- port_info->phy_info[i].attached.handle);
- }
-
- mptsas_probe_one_phy(&ioc->sh->shost_gendev,
- &port_info->phy_info[i], *index);
- (*index)++;
- }
-
- return 0;
-
- out_free_port_info:
- kfree(port_info);
- out:
- return error;
-}
-
-static int
-mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index)
-{
- struct mptsas_portinfo *port_info, *p;
- int error = -ENOMEM, i, j;
-
- port_info = kmalloc(sizeof(*port_info), GFP_KERNEL);
- if (!port_info)
- goto out;
- memset(port_info, 0, sizeof(*port_info));
-
- error = mptsas_sas_expander_pg0(ioc, port_info,
- (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE <<
- MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle);
- if (error)
- goto out_free_port_info;
-
- *handle = port_info->handle;
-
- list_add_tail(&port_info->list, &ioc->sas_topology);
- for (i = 0; i < port_info->num_phys; i++) {
- struct device *parent;
-
- mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i],
- (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM <<
- MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle);
-
- if (port_info->phy_info[i].identify.handle) {
- mptsas_sas_device_pg0(ioc,
- &port_info->phy_info[i].identify,
- (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
- MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
- port_info->phy_info[i].identify.handle);
- }
-
- if (port_info->phy_info[i].attached.handle) {
- mptsas_sas_device_pg0(ioc,
- &port_info->phy_info[i].attached,
- (MPI_SAS_DEVICE_PGAD_FORM_HANDLE <<
- MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
- port_info->phy_info[i].attached.handle);
- }
-
- /*
- * If we find a parent port handle this expander is
- * attached to another expander, else it hangs of the
- * HBA phys.
- */
- parent = &ioc->sh->shost_gendev;
- list_for_each_entry(p, &ioc->sas_topology, list) {
- for (j = 0; j < p->num_phys; j++) {
- if (port_info->phy_info[i].identify.handle ==
- p->phy_info[j].attached.handle)
- parent = &p->phy_info[j].rphy->dev;
- }
- }
-
- mptsas_probe_one_phy(parent, &port_info->phy_info[i], *index);
- (*index)++;
- }
-
- return 0;
-
- out_free_port_info:
- kfree(port_info);
- out:
- return error;
-}
-
-static void
-mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
-{
- u32 handle = 0xFFFF;
- int index = 0;
-
- mptsas_probe_hba_phys(ioc, &index);
- while (!mptsas_probe_expander_phys(ioc, &handle, &index))
- ;
-}
-
-static int
-mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
- struct Scsi_Host *sh;
- MPT_SCSI_HOST *hd;
- MPT_ADAPTER *ioc;
- unsigned long flags;
- int sz, ii;
- int numSGE = 0;
- int scale;
- int ioc_cap;
- u8 *mem;
- int error=0;
- int r;
-
- r = mpt_attach(pdev,id);
- if (r)
- return r;
-
- ioc = pci_get_drvdata(pdev);
- ioc->DoneCtx = mptsasDoneCtx;
- ioc->TaskCtx = mptsasTaskCtx;
- ioc->InternalCtx = mptsasInternalCtx;
-
- /* Added sanity check on readiness of the MPT adapter.
- */
- if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
- printk(MYIOC_s_WARN_FMT
- "Skipping because it's not operational!\n",
- ioc->name);
- return -ENODEV;
- }
-
- if (!ioc->active) {
- printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
- ioc->name);
- return -ENODEV;
- }
-
- /* Sanity check - ensure at least 1 port is INITIATOR capable
- */
- ioc_cap = 0;
- for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) {
- if (ioc->pfacts[ii].ProtocolFlags &
- MPI_PORTFACTS_PROTOCOL_INITIATOR)
- ioc_cap++;
- }
-
- if (!ioc_cap) {
- printk(MYIOC_s_WARN_FMT
- "Skipping ioc=%p because SCSI Initiator mode "
- "is NOT enabled!\n", ioc->name, ioc);
- return 0;
- }
-
- sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST));
- if (!sh) {
- printk(MYIOC_s_WARN_FMT
- "Unable to register controller with SCSI subsystem\n",
- ioc->name);
- return -1;
- }
-
- spin_lock_irqsave(&ioc->FreeQlock, flags);
-
- /* Attach the SCSI Host to the IOC structure
- */
- ioc->sh = sh;
-
- sh->io_port = 0;
- sh->n_io_port = 0;
- sh->irq = 0;
-
- /* set 16 byte cdb's */
- sh->max_cmd_len = 16;
-
- sh->max_id = ioc->pfacts->MaxDevices + 1;
-
- sh->transportt = mptsas_transport_template;
-
- sh->max_lun = MPT_LAST_LUN + 1;
- sh->max_channel = 0;
- sh->this_id = ioc->pfacts[0].PortSCSIID;
-
- /* Required entry.
- */
- sh->unique_id = ioc->id;
-
- INIT_LIST_HEAD(&ioc->sas_topology);
-
- /* Verify that we won't exceed the maximum
- * number of chain buffers
- * We can optimize: ZZ = req_sz/sizeof(SGE)
- * For 32bit SGE's:
- * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
- * + (req_sz - 64)/sizeof(SGE)
- * A slightly different algorithm is required for
- * 64bit SGEs.
- */
- scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
- if (sizeof(dma_addr_t) == sizeof(u64)) {
- numSGE = (scale - 1) *
- (ioc->facts.MaxChainDepth-1) + scale +
- (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
- sizeof(u32));
- } else {
- numSGE = 1 + (scale - 1) *
- (ioc->facts.MaxChainDepth-1) + scale +
- (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
- sizeof(u32));
- }
-
- if (numSGE < sh->sg_tablesize) {
- /* Reset this value */
- dprintk((MYIOC_s_INFO_FMT
- "Resetting sg_tablesize to %d from %d\n",
- ioc->name, numSGE, sh->sg_tablesize));
- sh->sg_tablesize = numSGE;
- }
-
- spin_unlock_irqrestore(&ioc->FreeQlock, flags);
-
- hd = (MPT_SCSI_HOST *) sh->hostdata;
- hd->ioc = ioc;
-
- /* SCSI needs scsi_cmnd lookup table!
- * (with size equal to req_depth*PtrSz!)
- */
- sz = ioc->req_depth * sizeof(void *);
- mem = kmalloc(sz, GFP_ATOMIC);
- if (mem == NULL) {
- error = -ENOMEM;
- goto mptsas_probe_failed;
- }
-
- memset(mem, 0, sz);
- hd->ScsiLookup = (struct scsi_cmnd **) mem;
-
- dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
- ioc->name, hd->ScsiLookup, sz));
-
- /* Allocate memory for the device structures.
- * A non-Null pointer at an offset
- * indicates a device exists.
- * max_id = 1 + maximum id (hosts.h)
- */
- sz = sh->max_id * sizeof(void *);
- mem = kmalloc(sz, GFP_ATOMIC);
- if (mem == NULL) {
- error = -ENOMEM;
- goto mptsas_probe_failed;
- }
-
- memset(mem, 0, sz);
- hd->Targets = (VirtDevice **) mem;
-
- dprintk((KERN_INFO
- " Targets @ %p, sz=%d\n", hd->Targets, sz));
-
- /* Clear the TM flags
- */
- hd->tmPending = 0;
- hd->tmState = TM_STATE_NONE;
- hd->resetPending = 0;
- hd->abortSCpnt = NULL;
-
- /* Clear the pointer used to store
- * single-threaded commands, i.e., those
- * issued during a bus scan, dv and
- * configuration pages.
- */
- hd->cmdPtr = NULL;
-
- /* Initialize this SCSI Hosts' timers
- * To use, set the timer expires field
- * and add_timer
- */
- init_timer(&hd->timer);
- 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) {
- mptbase_sas_persist_operation(
- 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;
-
- error = scsi_add_host(sh, &ioc->pcidev->dev);
- if (error) {
- dprintk((KERN_ERR MYNAM
- "scsi_add_host failed\n"));
- goto mptsas_probe_failed;
- }
-
- mptsas_scan_sas_topology(ioc);
-
- return 0;
-
-mptsas_probe_failed:
-
- mptscsih_remove(pdev);
- return error;
-}
-
-static void __devexit mptsas_remove(struct pci_dev *pdev)
-{
- MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
- struct mptsas_portinfo *p, *n;
-
- sas_remove_host(ioc->sh);
-
- list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
- list_del(&p->list);
- kfree(p);
- }
-
- mptscsih_remove(pdev);
-}
-
-static struct pci_device_id mptsas_pci_table[] = {
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064,
- PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066,
- PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068,
- PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E,
- PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E,
- PCI_ANY_ID, PCI_ANY_ID },
- { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E,
- PCI_ANY_ID, PCI_ANY_ID },
- {0} /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(pci, mptsas_pci_table);
-
-
-static struct pci_driver mptsas_driver = {
- .name = "mptsas",
- .id_table = mptsas_pci_table,
- .probe = mptsas_probe,
- .remove = __devexit_p(mptsas_remove),
- .shutdown = mptscsih_shutdown,
-#ifdef CONFIG_PM
- .suspend = mptscsih_suspend,
- .resume = mptscsih_resume,
-#endif
-};
-
-static int __init
-mptsas_init(void)
-{
- show_mptmod_ver(my_NAME, my_VERSION);
-
- mptsas_transport_template =
- sas_attach_transport(&mptsas_transport_functions);
- if (!mptsas_transport_template)
- return -ENODEV;
-
- mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER);
- mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER);
- mptsasInternalCtx =
- mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER);
-
- if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) {
- devtprintk((KERN_INFO MYNAM
- ": Registered for IOC event notifications\n"));
- }
-
- if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) {
- dprintk((KERN_INFO MYNAM
- ": Registered for IOC reset notifications\n"));
- }
-
- return pci_register_driver(&mptsas_driver);
-}
-
-static void __exit
-mptsas_exit(void)
-{
- pci_unregister_driver(&mptsas_driver);
- sas_release_transport(mptsas_transport_template);
-
- mpt_reset_deregister(mptsasDoneCtx);
- mpt_event_deregister(mptsasDoneCtx);
-
- mpt_deregister(mptsasInternalCtx);
- mpt_deregister(mptsasTaskCtx);
- mpt_deregister(mptsasDoneCtx);
-}
-
-module_init(mptsas_init);
-module_exit(mptsas_exit);
diff --git a/trunk/drivers/message/fusion/mptscsih.c b/trunk/drivers/message/fusion/mptscsih.c
index 5cb07eb224d7..4a003dc5fde8 100644
--- a/trunk/drivers/message/fusion/mptscsih.c
+++ b/trunk/drivers/message/fusion/mptscsih.c
@@ -62,7 +62,6 @@
#include
#include
#include
-#include
#include "mptbase.h"
#include "mptscsih.h"
@@ -94,9 +93,8 @@ typedef struct _BIG_SENSE_BUF {
#define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
#define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
-#define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
-#define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
-#define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
+#define MPT_ICFLAG_PHYS_DISK 0x04 /* Any SCSI IO but do Phys Disk Format */
+#define MPT_ICFLAG_TAGGED_CMD 0x08 /* Do tagged IO */
#define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
#define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
@@ -161,8 +159,6 @@ int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR
static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
-static struct work_struct mptscsih_persistTask;
-
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
static void mptscsih_domainValidation(void *hd);
@@ -171,7 +167,6 @@ static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
-static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
#endif
void mptscsih_remove(struct pci_dev *);
@@ -611,24 +606,11 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
sc->resid = sc->request_bufflen - xfer_cnt;
- /*
- * if we get a data underrun indication, yet no data was
- * transferred and the SCSI status indicates that the
- * command was never started, change the data underrun
- * to success
- */
- if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
- (scsi_status == MPI_SCSI_STATUS_BUSY ||
- scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
- scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
- status = MPI_IOCSTATUS_SUCCESS;
- }
-
dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
"IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
"resid=%d bufflen=%d xfer_cnt=%d\n",
ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
- status, scsi_state, scsi_status, sc->resid,
+ status, scsi_state, scsi_status, sc->resid,
sc->request_bufflen, xfer_cnt));
if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
@@ -637,11 +619,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
/*
* Look for + dump FCP ResponseInfo[]!
*/
- if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
- pScsiReply->ResponseInfo) {
- printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
- "FCP_ResponseInfo=%08xh\n",
- ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
+ if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) {
+ printk(KERN_NOTICE " FCP_ResponseInfo=%08xh\n",
le32_to_cpu(pScsiReply->ResponseInfo));
}
@@ -682,13 +661,23 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
break;
case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
- sc->resid = sc->request_bufflen - xfer_cnt;
- if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
- sc->result=DID_SOFT_ERROR << 16;
- else /* Sufficient data transfer occurred */
+ if ( xfer_cnt >= sc->underflow ) {
+ /* Sufficient data transfer occurred */
sc->result = (DID_OK << 16) | scsi_status;
- dreplyprintk((KERN_NOTICE
- "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
+ } else if ( xfer_cnt == 0 ) {
+ /* A CRC Error causes this condition; retry */
+ sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
+ (CHECK_CONDITION << 1);
+ sc->sense_buffer[0] = 0x70;
+ sc->sense_buffer[2] = NO_SENSE;
+ sc->sense_buffer[12] = 0;
+ sc->sense_buffer[13] = 0;
+ } else {
+ sc->result = DID_SOFT_ERROR << 16;
+ }
+ dreplyprintk((KERN_NOTICE
+ "RESIDUAL_MISMATCH: result=%x on id=%d\n",
+ sc->result, sc->device->id));
break;
case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
@@ -703,10 +692,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
;
} else {
if (xfer_cnt < sc->underflow) {
- if (scsi_status == SAM_STAT_BUSY)
- sc->result = SAM_STAT_BUSY;
- else
- sc->result = DID_SOFT_ERROR << 16;
+ sc->result = DID_SOFT_ERROR << 16;
}
if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
/* What to do?
@@ -731,10 +717,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
- if (scsi_status == MPI_SCSI_STATUS_BUSY)
- sc->result = (DID_BUS_BUSY << 16) | scsi_status;
- else
- sc->result = (DID_OK << 16) | scsi_status;
+ scsi_status = pScsiReply->SCSIStatus;
+ sc->result = (DID_OK << 16) | scsi_status;
if (scsi_state == 0) {
;
} else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
@@ -906,13 +890,12 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
SCSIIORequest_t *mf = NULL;
int ii;
int max = hd->ioc->req_depth;
- struct scsi_cmnd *sc;
dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
target, lun, max));
for (ii=0; ii < max; ii++) {
- if ((sc = hd->ScsiLookup[ii]) != NULL) {
+ if (hd->ScsiLookup[ii] != NULL) {
mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
@@ -927,22 +910,9 @@ mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
hd->ScsiLookup[ii] = NULL;
mptscsih_freeChainBuffers(hd->ioc, ii);
mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
- if (sc->use_sg) {
- pci_unmap_sg(hd->ioc->pcidev,
- (struct scatterlist *) sc->request_buffer,
- sc->use_sg,
- sc->sc_data_direction);
- } else if (sc->request_bufflen) {
- pci_unmap_single(hd->ioc->pcidev,
- sc->SCp.dma_handle,
- sc->request_bufflen,
- sc->sc_data_direction);
- }
- sc->host_scribble = NULL;
- sc->result = DID_NO_CONNECT << 16;
- sc->scsi_done(sc);
}
}
+
return;
}
@@ -997,10 +967,8 @@ mptscsih_remove(struct pci_dev *pdev)
unsigned long flags;
int sz1;
- if(!host) {
- mpt_detach(pdev);
+ if(!host)
return;
- }
scsi_remove_host(host);
@@ -1288,7 +1256,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
MPT_SCSI_HOST *hd;
MPT_FRAME_HDR *mf;
SCSIIORequest_t *pScsiReq;
- VirtDevice *pTarget = SCpnt->device->hostdata;
+ VirtDevice *pTarget;
+ int target;
int lun;
u32 datalen;
u32 scsictl;
@@ -1298,9 +1267,12 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
int ii;
hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
+ target = SCpnt->device->id;
lun = SCpnt->device->lun;
SCpnt->scsi_done = done;
+ pTarget = hd->Targets[target];
+
dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
(hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
@@ -1343,7 +1315,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* Default to untagged. Once a target structure has been allocated,
* use the Inquiry data to determine if device supports tagged.
*/
- if (pTarget
+ if ( pTarget
&& (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
&& (SCpnt->device->tagged_supported)) {
scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
@@ -1353,8 +1325,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* Use the above information to set up the message frame
*/
- pScsiReq->TargetID = (u8) pTarget->target_id;
- pScsiReq->Bus = pTarget->bus_id;
+ pScsiReq->TargetID = (u8) target;
+ pScsiReq->Bus = (u8) SCpnt->device->channel;
pScsiReq->ChainOffset = 0;
pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
pScsiReq->CDBLength = SCpnt->cmd_len;
@@ -1406,7 +1378,7 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
if (hd->ioc->bus_type == SCSI) {
- int dvStatus = hd->ioc->spi_data.dvStatus[pTarget->target_id];
+ int dvStatus = hd->ioc->spi_data.dvStatus[target];
int issueCmd = 1;
if (dvStatus || hd->ioc->spi_data.forceDv) {
@@ -1454,7 +1426,6 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
return 0;
fail:
- hd->ScsiLookup[my_idx] = NULL;
mptscsih_freeChainBuffers(hd->ioc, my_idx);
mpt_free_msg_frame(hd->ioc, mf);
return SCSI_MLQUEUE_HOST_BUSY;
@@ -1742,23 +1713,24 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
MPT_FRAME_HDR *mf;
u32 ctx2abort;
int scpnt_idx;
- int retval;
/* If we can't locate our host adapter structure, return FAILED status.
*/
if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
SCpnt->result = DID_RESET << 16;
SCpnt->scsi_done(SCpnt);
- dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
+ dfailprintk((KERN_WARNING MYNAM ": mptscsih_abort: "
"Can't locate host! (sc=%p)\n",
SCpnt));
return FAILED;
}
ioc = hd->ioc;
- if (hd->resetPending) {
+ if (hd->resetPending)
return FAILED;
- }
+
+ printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
+ hd->ioc->name, SCpnt);
if (hd->timeouts < -1)
hd->timeouts++;
@@ -1766,20 +1738,16 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
/* Find this command
*/
if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
- /* Cmd not found in ScsiLookup.
+ /* Cmd not found in ScsiLookup.
* Do OS callback.
*/
SCpnt->result = DID_RESET << 16;
- dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
+ dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
"Command not in the active list! (sc=%p)\n",
hd->ioc->name, SCpnt));
return SUCCESS;
}
- printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
- hd->ioc->name, SCpnt);
- scsi_print_command(SCpnt);
-
/* Most important! Set TaskMsgContext to SCpnt's MsgContext!
* (the IO to be ABORT'd)
*
@@ -1792,22 +1760,38 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
hd->abortSCpnt = SCpnt;
- retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
+ if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
- ctx2abort, 2 /* 2 second timeout */);
+ ctx2abort, 2 /* 2 second timeout */)
+ < 0) {
- printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
- hd->ioc->name,
- ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
-
- if (retval == 0)
- return SUCCESS;
+ /* The TM request failed and the subsequent FW-reload failed!
+ * Fatal error case.
+ */
+ printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
+ hd->ioc->name, SCpnt);
- if(retval != FAILED ) {
+ /* We must clear our pending flag before clearing our state.
+ */
hd->tmPending = 0;
hd->tmState = TM_STATE_NONE;
+
+ /* Unmap the DMA buffers, if any. */
+ if (SCpnt->use_sg) {
+ pci_unmap_sg(ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer,
+ SCpnt->use_sg, SCpnt->sc_data_direction);
+ } else if (SCpnt->request_bufflen) {
+ pci_unmap_single(ioc->pcidev, SCpnt->SCp.dma_handle,
+ SCpnt->request_bufflen, SCpnt->sc_data_direction);
+ }
+ hd->ScsiLookup[scpnt_idx] = NULL;
+ SCpnt->result = DID_RESET << 16;
+ SCpnt->scsi_done(SCpnt); /* Issue the command callback */
+ mptscsih_freeChainBuffers(ioc, scpnt_idx);
+ mpt_free_msg_frame(ioc, mf);
+ return FAILED;
}
- return FAILED;
+ return SUCCESS;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1823,12 +1807,11 @@ int
mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
{
MPT_SCSI_HOST *hd;
- int retval;
/* If we can't locate our host adapter structure, return FAILED status.
*/
if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
- dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
+ dtmprintk((KERN_WARNING MYNAM ": mptscsih_dev_reset: "
"Can't locate host! (sc=%p)\n",
SCpnt));
return FAILED;
@@ -1837,26 +1820,24 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
if (hd->resetPending)
return FAILED;
- printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
+ printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
hd->ioc->name, SCpnt);
- scsi_print_command(SCpnt);
- retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
+ if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
SCpnt->device->channel, SCpnt->device->id,
- 0, 0, 5 /* 5 second timeout */);
-
- printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
- hd->ioc->name,
- ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
-
- if (retval == 0)
- return SUCCESS;
-
- if(retval != FAILED ) {
+ 0, 0, 5 /* 5 second timeout */)
+ < 0){
+ /* The TM request failed and the subsequent FW-reload failed!
+ * Fatal error case.
+ */
+ printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n",
+ hd->ioc->name, SCpnt);
hd->tmPending = 0;
hd->tmState = TM_STATE_NONE;
+ return FAILED;
}
- return FAILED;
+
+ return SUCCESS;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1872,39 +1853,41 @@ int
mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
{
MPT_SCSI_HOST *hd;
- int retval;
+ spinlock_t *host_lock = SCpnt->device->host->host_lock;
/* If we can't locate our host adapter structure, return FAILED status.
*/
if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
- dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
+ dtmprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: "
"Can't locate host! (sc=%p)\n",
SCpnt ) );
return FAILED;
}
- printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
+ printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n",
hd->ioc->name, SCpnt);
- scsi_print_command(SCpnt);
if (hd->timeouts < -1)
hd->timeouts++;
- retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
- SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */);
-
- printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
- hd->ioc->name,
- ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+ /* We are now ready to execute the task management request. */
+ if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
+ SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
+ < 0){
- if (retval == 0)
- return SUCCESS;
-
- if(retval != FAILED ) {
+ /* The TM request failed and the subsequent FW-reload failed!
+ * Fatal error case.
+ */
+ printk(MYIOC_s_WARN_FMT
+ "Error processing TaskMgmt request (sc=%p)\n",
+ hd->ioc->name, SCpnt);
hd->tmPending = 0;
hd->tmState = TM_STATE_NONE;
+ spin_lock_irq(host_lock);
+ return FAILED;
}
- return FAILED;
+
+ return SUCCESS;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -2186,7 +2169,7 @@ mptscsih_slave_alloc(struct scsi_device *device)
vdev->raidVolume = 0;
hd->Targets[device->id] = vdev;
if (hd->ioc->bus_type == SCSI) {
- if (hd->ioc->raid_data.isRaid & (1 << device->id)) {
+ if (hd->ioc->spi_data.isRaid & (1 << device->id)) {
vdev->raidVolume = 1;
ddvtprintk((KERN_INFO
"RAID Volume @ id %d\n", device->id));
@@ -2197,7 +2180,22 @@ mptscsih_slave_alloc(struct scsi_device *device)
out:
vdev->num_luns++;
- device->hostdata = vdev;
+ return 0;
+}
+
+static int
+mptscsih_is_raid_volume(MPT_SCSI_HOST *hd, uint id)
+{
+ int i;
+
+ if (!hd->ioc->spi_data.isRaid || !hd->ioc->spi_data.pIocPg3)
+ return 0;
+
+ for (i = 0; i < hd->ioc->spi_data.pIocPg3->NumPhysDisks; i++) {
+ if (id == hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID)
+ return 1;
+ }
+
return 0;
}
@@ -2228,7 +2226,7 @@ mptscsih_slave_destroy(struct scsi_device *device)
hd->Targets[target] = NULL;
if (hd->ioc->bus_type == SCSI) {
- if (mptscsih_is_phys_disk(hd->ioc, target)) {
+ if (mptscsih_is_raid_volume(hd, target)) {
hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
} else {
hd->ioc->spi_data.dvStatus[target] =
@@ -2441,7 +2439,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
{
MPT_SCSI_HOST *hd;
unsigned long flags;
- int ii;
dtmprintk((KERN_WARNING MYNAM
": IOC %s_reset routed to SCSI host driver!\n",
@@ -2499,8 +2496,11 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
/* ScsiLookup initialization
*/
- for (ii=0; ii < hd->ioc->req_depth; ii++)
- hd->ScsiLookup[ii] = NULL;
+ {
+ int ii;
+ for (ii=0; ii < hd->ioc->req_depth; ii++)
+ hd->ScsiLookup[ii] = NULL;
+ }
/* 2. Chain Buffer initialization
*/
@@ -2548,16 +2548,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
return 1; /* currently means nothing really */
}
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* work queue thread to clear the persitency table */
-static void
-mptscsih_sas_persist_clear_table(void * arg)
-{
- MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
-
- mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
-}
-
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
int
mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
@@ -2568,18 +2558,18 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
ioc->name, event));
- if (ioc->sh == NULL ||
- ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
- return 1;
-
switch (event) {
case MPI_EVENT_UNIT_ATTENTION: /* 03 */
/* FIXME! */
break;
case MPI_EVENT_IOC_BUS_RESET: /* 04 */
case MPI_EVENT_EXT_BUS_RESET: /* 05 */
- if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
- hd->soft_resets++;
+ hd = NULL;
+ if (ioc->sh) {
+ hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
+ if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
+ hd->soft_resets++;
+ }
break;
case MPI_EVENT_LOGOUT: /* 09 */
/* FIXME! */
@@ -2598,24 +2588,69 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
break;
case MPI_EVENT_INTEGRATED_RAID: /* 0B */
- {
- pMpiEventDataRaid_t pRaidEventData =
- (pMpiEventDataRaid_t) pEvReply->Data;
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
- /* Domain Validation Needed */
- if (ioc->bus_type == SCSI &&
- pRaidEventData->ReasonCode ==
- MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
- mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
+ /* negoNvram set to 0 if DV enabled and to USE_NVRAM if
+ * if DV disabled. Need to check for target mode.
+ */
+ hd = NULL;
+ if (ioc->sh)
+ hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
+
+ if (hd && (ioc->bus_type == SCSI) && (hd->negoNvram == 0)) {
+ ScsiCfgData *pSpi;
+ Ioc3PhysDisk_t *pPDisk;
+ int numPDisk;
+ u8 reason;
+ u8 physDiskNum;
+
+ reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
+ if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
+ /* New or replaced disk.
+ * Set DV flag and schedule DV.
+ */
+ pSpi = &ioc->spi_data;
+ physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
+ ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum));
+ if (pSpi->pIocPg3) {
+ pPDisk = pSpi->pIocPg3->PhysDisk;
+ numPDisk =pSpi->pIocPg3->NumPhysDisks;
+
+ while (numPDisk) {
+ if (physDiskNum == pPDisk->PhysDiskNum) {
+ pSpi->dvStatus[pPDisk->PhysDiskID] = (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
+ pSpi->forceDv = MPT_SCSICFG_NEED_DV;
+ ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
+ break;
+ }
+ pPDisk++;
+ numPDisk--;
+ }
+
+ if (numPDisk == 0) {
+ /* The physical disk that needs DV was not found
+ * in the stored IOC Page 3. The driver must reload
+ * this page. DV routine will set the NEED_DV flag for
+ * all phys disks that have DV_NOT_DONE set.
+ */
+ pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
+ ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum));
+ }
+ }
+ }
+ }
#endif
- break;
- }
- /* Persistent table is full. */
- case MPI_EVENT_PERSISTENT_TABLE_FULL:
- INIT_WORK(&mptscsih_persistTask,
- mptscsih_sas_persist_clear_table,(void *)ioc);
- schedule_work(&mptscsih_persistTask);
+#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
+ printk("Raid Event RF: ");
+ {
+ u32 *m = (u32 *)pEvReply;
+ int ii;
+ int n = (int)pEvReply->MsgLength;
+ for (ii=6; ii < n; ii++)
+ printk(" %08x", le32_to_cpu(m[ii]));
+ printk("\n");
+ }
+#endif
break;
case MPI_EVENT_NONE: /* 00 */
@@ -2652,7 +2687,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
{
int indexed_lun, lun_index;
VirtDevice *vdev;
- SpiCfgData *pSpi;
+ ScsiCfgData *pSpi;
char data_56;
dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
@@ -2759,7 +2794,7 @@ mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *
static void
mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
{
- SpiCfgData *pspi_data = &hd->ioc->spi_data;
+ ScsiCfgData *pspi_data = &hd->ioc->spi_data;
int id = (int) target->target_id;
int nvram;
VirtDevice *vdev;
@@ -2938,13 +2973,11 @@ mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
static void
mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
{
- MPT_ADAPTER *ioc = hd->ioc;
u8 cmd;
- SpiCfgData *pSpi;
+ ScsiCfgData *pSpi;
- ddvtprintk((MYIOC_s_NOTE_FMT
- " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
- hd->ioc->name, pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
+ ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
+ pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
return;
@@ -2952,12 +2985,12 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
cmd = pReq->CDB[0];
if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
- pSpi = &ioc->spi_data;
- if ((ioc->raid_data.isRaid & (1 << pReq->TargetID)) && ioc->raid_data.pIocPg3) {
+ pSpi = &hd->ioc->spi_data;
+ if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) {
/* Set NEED_DV for all hidden disks
*/
- Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
- int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
+ Ioc3PhysDisk_t *pPDisk = pSpi->pIocPg3->PhysDisk;
+ int numPDisk = pSpi->pIocPg3->NumPhysDisks;
while (numPDisk) {
pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
@@ -2971,50 +3004,6 @@ mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
}
}
-/* mptscsih_raid_set_dv_flags()
- *
- * New or replaced disk. Set DV flag and schedule DV.
- */
-static void
-mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
-{
- MPT_ADAPTER *ioc = hd->ioc;
- SpiCfgData *pSpi = &ioc->spi_data;
- Ioc3PhysDisk_t *pPDisk;
- int numPDisk;
-
- if (hd->negoNvram != 0)
- return;
-
- ddvtprintk(("DV requested for phys disk id %d\n", id));
- if (ioc->raid_data.pIocPg3) {
- pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
- numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
- while (numPDisk) {
- if (id == pPDisk->PhysDiskNum) {
- pSpi->dvStatus[pPDisk->PhysDiskID] =
- (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
- pSpi->forceDv = MPT_SCSICFG_NEED_DV;
- ddvtprintk(("NEED_DV set for phys disk id %d\n",
- pPDisk->PhysDiskID));
- break;
- }
- pPDisk++;
- numPDisk--;
- }
-
- if (numPDisk == 0) {
- /* The physical disk that needs DV was not found
- * in the stored IOC Page 3. The driver must reload
- * this page. DV routine will set the NEED_DV flag for
- * all phys disks that have DV_NOT_DONE set.
- */
- pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
- ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
- }
- }
-}
-
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* If no Target, bus reset on 1st I/O. Set the flag to
@@ -3102,7 +3091,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
MPT_ADAPTER *ioc = hd->ioc;
Config_t *pReq;
SCSIDevicePage1_t *pData;
- VirtDevice *pTarget=NULL;
+ VirtDevice *pTarget;
MPT_FRAME_HDR *mf;
dma_addr_t dataDma;
u16 req_idx;
@@ -3201,7 +3190,7 @@ mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
#endif
if (flags & MPT_SCSICFG_BLK_NEGO)
- negoFlags |= MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
+ negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
mptscsih_setDevicePage1Flags(width, factor, offset,
&requested, &configuration, negoFlags);
@@ -4022,7 +4011,7 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
/* If target Ptr NULL or if this target is NOT a disk, skip.
*/
- if ((pTarget) && (pTarget->inq_data[0] == TYPE_DISK)){
+ if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){
for (lun=0; lun <= MPT_LAST_LUN; lun++) {
/* If LUN present, issue the command
*/
@@ -4117,9 +4106,9 @@ mptscsih_domainValidation(void *arg)
if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
mpt_read_ioc_pg_3(ioc);
- if (ioc->raid_data.pIocPg3) {
- Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
- int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
+ if (ioc->spi_data.pIocPg3) {
+ Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
+ int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
while (numPDisk) {
if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
@@ -4158,7 +4147,7 @@ mptscsih_domainValidation(void *arg)
isPhysDisk = mptscsih_is_phys_disk(ioc, id);
if (isPhysDisk) {
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
- if (hd->ioc->raid_data.isRaid & (1 << ii)) {
+ if (hd->ioc->spi_data.isRaid & (1 << ii)) {
hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
}
}
@@ -4177,7 +4166,7 @@ mptscsih_domainValidation(void *arg)
if (isPhysDisk) {
for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
- if (hd->ioc->raid_data.isRaid & (1 << ii)) {
+ if (hd->ioc->spi_data.isRaid & (1 << ii)) {
hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
}
}
@@ -4199,21 +4188,21 @@ mptscsih_domainValidation(void *arg)
/* Search IOC page 3 to determine if this is hidden physical disk
*/
-/* Search IOC page 3 to determine if this is hidden physical disk
- */
-static int
+static int
mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
{
- int i;
+ if (ioc->spi_data.pIocPg3) {
+ Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
+ int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
- if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
- return 0;
-
- for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
- if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
- return 1;
+ while (numPDisk) {
+ if (pPDisk->PhysDiskID == id) {
+ return 1;
+ }
+ pPDisk++;
+ numPDisk--;
+ }
}
-
return 0;
}
@@ -4419,7 +4408,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
/* Skip this ID? Set cfg.cfghdr.hdr to force config page write
*/
{
- SpiCfgData *pspi_data = &hd->ioc->spi_data;
+ ScsiCfgData *pspi_data = &hd->ioc->spi_data;
if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
/* Set the factor from nvram */
nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
@@ -4449,11 +4438,11 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
}
/* Finish iocmd inititialization - hidden or visible disk? */
- if (ioc->raid_data.pIocPg3) {
+ if (ioc->spi_data.pIocPg3) {
/* Search IOC page 3 for matching id
*/
- Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
- int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
+ Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
+ int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
while (numPDisk) {
if (pPDisk->PhysDiskID == id) {
@@ -4477,7 +4466,7 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
/* RAID Volume ID's may double for a physical device. If RAID but
* not a physical ID as well, skip DV.
*/
- if ((hd->ioc->raid_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
+ if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
goto target_done;
@@ -4826,8 +4815,6 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
notDone = 0;
if (iocmd.flags & MPT_ICFLAG_ECHO) {
bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
- if (pbuf1[0] & 0x01)
- iocmd.flags |= MPT_ICFLAG_EBOS;
} else {
bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
}
@@ -4924,9 +4911,6 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
}
iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
- if (iocmd.flags & MPT_ICFLAG_EBOS)
- goto skip_Reserve;
-
repeat = 5;
while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
iocmd.cmd = RESERVE;
@@ -4970,7 +4954,6 @@ mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
}
}
-skip_Reserve:
mptscsih_fillbuf(pbuf1, sz, patt, 1);
iocmd.cmd = WRITE_BUFFER;
iocmd.data_dma = buf1_dma;
@@ -5215,12 +5198,11 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
* If not an LVD bus, the adapter minSyncFactor has been
* already throttled back.
*/
- negoFlags = hd->ioc->spi_data.noQas;
if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
width = pTarget->maxWidth;
offset = pTarget->maxOffset;
factor = pTarget->minSyncFactor;
- negoFlags |= pTarget->negoFlags;
+ negoFlags = pTarget->negoFlags;
} else {
if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
data = hd->ioc->spi_data.nvram[id];
@@ -5241,6 +5223,7 @@ mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
}
/* Set the negotiation flags */
+ negoFlags = hd->ioc->spi_data.noQas;
if (!width)
negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
diff --git a/trunk/drivers/message/fusion/mptscsih.h b/trunk/drivers/message/fusion/mptscsih.h
index 971fda4b8b57..51c0255ac16e 100644
--- a/trunk/drivers/message/fusion/mptscsih.h
+++ b/trunk/drivers/message/fusion/mptscsih.h
@@ -1,5 +1,5 @@
/*
- * linux/drivers/message/fusion/mptscsih.h
+ * linux/drivers/message/fusion/mptscsi.h
* High performance SCSI / Fibre Channel SCSI Host device driver.
* For use with PCI chip/adapter(s):
* LSIFC9xx/LSI409xx Fibre Channel
@@ -53,8 +53,8 @@
* SCSI Public stuff...
*/
-#define MPT_SCSI_CMD_PER_DEV_HIGH 64
-#define MPT_SCSI_CMD_PER_DEV_LOW 32
+#define MPT_SCSI_CMD_PER_DEV_HIGH 31
+#define MPT_SCSI_CMD_PER_DEV_LOW 7
#define MPT_SCSI_CMD_PER_LUN 7
@@ -77,7 +77,6 @@
#define MPTSCSIH_MAX_WIDTH 1
#define MPTSCSIH_MIN_SYNC 0x08
#define MPTSCSIH_SAF_TE 0
-#define MPTSCSIH_PT_CLEAR 0
#endif
diff --git a/trunk/drivers/message/fusion/mptspi.c b/trunk/drivers/message/fusion/mptspi.c
index 5c0e307d1d5d..587d1274fd74 100644
--- a/trunk/drivers/message/fusion/mptspi.c
+++ b/trunk/drivers/message/fusion/mptspi.c
@@ -199,7 +199,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
printk(MYIOC_s_WARN_FMT
"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
ioc->name, ioc);
- return 0;
+ return -ENODEV;
}
sh = scsi_host_alloc(&mptspi_driver_template, sizeof(MPT_SCSI_HOST));
diff --git a/trunk/drivers/message/i2o/config-osm.c b/trunk/drivers/message/i2o/config-osm.c
index 10432f665201..af32ab4e90cd 100644
--- a/trunk/drivers/message/i2o/config-osm.c
+++ b/trunk/drivers/message/i2o/config-osm.c
@@ -56,11 +56,8 @@ static int __init i2o_config_init(void)
return -EBUSY;
}
#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL
- if (i2o_config_old_init()) {
- osm_err("old config handler initialization failed\n");
+ if (i2o_config_old_init())
i2o_driver_unregister(&i2o_config_driver);
- return -EBUSY;
- }
#endif
return 0;
diff --git a/trunk/drivers/s390/scsi/Makefile b/trunk/drivers/s390/scsi/Makefile
index d6a78f1a2f16..fc145307a7d4 100644
--- a/trunk/drivers/s390/scsi/Makefile
+++ b/trunk/drivers/s390/scsi/Makefile
@@ -3,7 +3,7 @@
#
zfcp-objs := zfcp_aux.o zfcp_ccw.o zfcp_scsi.o zfcp_erp.o zfcp_qdio.o \
- zfcp_fsf.o zfcp_dbf.o zfcp_sysfs_adapter.o zfcp_sysfs_port.o \
+ zfcp_fsf.o zfcp_sysfs_adapter.o zfcp_sysfs_port.o \
zfcp_sysfs_unit.o zfcp_sysfs_driver.o
obj-$(CONFIG_ZFCP) += zfcp.o
diff --git a/trunk/drivers/s390/scsi/zfcp_aux.c b/trunk/drivers/s390/scsi/zfcp_aux.c
index 0b5087f7cabc..bfe3ba73bc0f 100644
--- a/trunk/drivers/s390/scsi/zfcp_aux.c
+++ b/trunk/drivers/s390/scsi/zfcp_aux.c
@@ -122,6 +122,95 @@ _zfcp_hex_dump(char *addr, int count)
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER
+static inline int
+zfcp_fsf_req_is_scsi_cmnd(struct zfcp_fsf_req *fsf_req)
+{
+ return ((fsf_req->fsf_command == FSF_QTCB_FCP_CMND) &&
+ !(fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT));
+}
+
+void
+zfcp_cmd_dbf_event_fsf(const char *text, struct zfcp_fsf_req *fsf_req,
+ void *add_data, int add_length)
+{
+ struct zfcp_adapter *adapter = fsf_req->adapter;
+ struct scsi_cmnd *scsi_cmnd;
+ int level = 3;
+ int i;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->dbf_lock, flags);
+ if (zfcp_fsf_req_is_scsi_cmnd(fsf_req)) {
+ scsi_cmnd = fsf_req->data.send_fcp_command_task.scsi_cmnd;
+ debug_text_event(adapter->cmd_dbf, level, "fsferror");
+ debug_text_event(adapter->cmd_dbf, level, text);
+ debug_event(adapter->cmd_dbf, level, &fsf_req,
+ sizeof (unsigned long));
+ debug_event(adapter->cmd_dbf, level, &fsf_req->seq_no,
+ sizeof (u32));
+ debug_event(adapter->cmd_dbf, level, &scsi_cmnd,
+ sizeof (unsigned long));
+ debug_event(adapter->cmd_dbf, level, &scsi_cmnd->cmnd,
+ min(ZFCP_CMD_DBF_LENGTH, (int)scsi_cmnd->cmd_len));
+ for (i = 0; i < add_length; i += ZFCP_CMD_DBF_LENGTH)
+ debug_event(adapter->cmd_dbf,
+ level,
+ (char *) add_data + i,
+ min(ZFCP_CMD_DBF_LENGTH, add_length - i));
+ }
+ spin_unlock_irqrestore(&adapter->dbf_lock, flags);
+}
+
+/* XXX additionally log unit if available */
+/* ---> introduce new parameter for unit, see 2.4 code */
+void
+zfcp_cmd_dbf_event_scsi(const char *text, struct scsi_cmnd *scsi_cmnd)
+{
+ struct zfcp_adapter *adapter;
+ union zfcp_req_data *req_data;
+ struct zfcp_fsf_req *fsf_req;
+ int level = ((host_byte(scsi_cmnd->result) != 0) ? 1 : 5);
+ unsigned long flags;
+
+ adapter = (struct zfcp_adapter *) scsi_cmnd->device->host->hostdata[0];
+ req_data = (union zfcp_req_data *) scsi_cmnd->host_scribble;
+ fsf_req = (req_data ? req_data->send_fcp_command_task.fsf_req : NULL);
+ spin_lock_irqsave(&adapter->dbf_lock, flags);
+ debug_text_event(adapter->cmd_dbf, level, "hostbyte");
+ debug_text_event(adapter->cmd_dbf, level, text);
+ debug_event(adapter->cmd_dbf, level, &scsi_cmnd->result, sizeof (u32));
+ debug_event(adapter->cmd_dbf, level, &scsi_cmnd,
+ sizeof (unsigned long));
+ debug_event(adapter->cmd_dbf, level, &scsi_cmnd->cmnd,
+ min(ZFCP_CMD_DBF_LENGTH, (int)scsi_cmnd->cmd_len));
+ if (likely(fsf_req)) {
+ debug_event(adapter->cmd_dbf, level, &fsf_req,
+ sizeof (unsigned long));
+ debug_event(adapter->cmd_dbf, level, &fsf_req->seq_no,
+ sizeof (u32));
+ } else {
+ debug_text_event(adapter->cmd_dbf, level, "");
+ debug_text_event(adapter->cmd_dbf, level, "");
+ }
+ spin_unlock_irqrestore(&adapter->dbf_lock, flags);
+}
+
+void
+zfcp_in_els_dbf_event(struct zfcp_adapter *adapter, const char *text,
+ struct fsf_status_read_buffer *status_buffer, int length)
+{
+ int level = 1;
+ int i;
+
+ debug_text_event(adapter->in_els_dbf, level, text);
+ debug_event(adapter->in_els_dbf, level, &status_buffer->d_id, 8);
+ for (i = 0; i < length; i += ZFCP_IN_ELS_DBF_LENGTH)
+ debug_event(adapter->in_els_dbf,
+ level,
+ (char *) status_buffer->payload + i,
+ min(ZFCP_IN_ELS_DBF_LENGTH, length - i));
+}
+
/**
* zfcp_device_setup - setup function
* @str: pointer to parameter string
@@ -928,6 +1017,81 @@ zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter)
mempool_destroy(adapter->pool.data_gid_pn);
}
+/**
+ * zfcp_adapter_debug_register - registers debug feature for an adapter
+ * @adapter: pointer to adapter for which debug features should be registered
+ * return: -ENOMEM on error, 0 otherwise
+ */
+int
+zfcp_adapter_debug_register(struct zfcp_adapter *adapter)
+{
+ char dbf_name[20];
+
+ /* debug feature area which records SCSI command failures (hostbyte) */
+ spin_lock_init(&adapter->dbf_lock);
+
+ sprintf(dbf_name, ZFCP_CMD_DBF_NAME "%s",
+ zfcp_get_busid_by_adapter(adapter));
+ adapter->cmd_dbf = debug_register(dbf_name, ZFCP_CMD_DBF_INDEX,
+ ZFCP_CMD_DBF_AREAS,
+ ZFCP_CMD_DBF_LENGTH);
+ debug_register_view(adapter->cmd_dbf, &debug_hex_ascii_view);
+ debug_set_level(adapter->cmd_dbf, ZFCP_CMD_DBF_LEVEL);
+
+ /* debug feature area which records SCSI command aborts */
+ sprintf(dbf_name, ZFCP_ABORT_DBF_NAME "%s",
+ zfcp_get_busid_by_adapter(adapter));
+ adapter->abort_dbf = debug_register(dbf_name, ZFCP_ABORT_DBF_INDEX,
+ ZFCP_ABORT_DBF_AREAS,
+ ZFCP_ABORT_DBF_LENGTH);
+ debug_register_view(adapter->abort_dbf, &debug_hex_ascii_view);
+ debug_set_level(adapter->abort_dbf, ZFCP_ABORT_DBF_LEVEL);
+
+ /* debug feature area which records incoming ELS commands */
+ sprintf(dbf_name, ZFCP_IN_ELS_DBF_NAME "%s",
+ zfcp_get_busid_by_adapter(adapter));
+ adapter->in_els_dbf = debug_register(dbf_name, ZFCP_IN_ELS_DBF_INDEX,
+ ZFCP_IN_ELS_DBF_AREAS,
+ ZFCP_IN_ELS_DBF_LENGTH);
+ debug_register_view(adapter->in_els_dbf, &debug_hex_ascii_view);
+ debug_set_level(adapter->in_els_dbf, ZFCP_IN_ELS_DBF_LEVEL);
+
+ /* debug feature area which records erp events */
+ sprintf(dbf_name, ZFCP_ERP_DBF_NAME "%s",
+ zfcp_get_busid_by_adapter(adapter));
+ adapter->erp_dbf = debug_register(dbf_name, ZFCP_ERP_DBF_INDEX,
+ ZFCP_ERP_DBF_AREAS,
+ ZFCP_ERP_DBF_LENGTH);
+ debug_register_view(adapter->erp_dbf, &debug_hex_ascii_view);
+ debug_set_level(adapter->erp_dbf, ZFCP_ERP_DBF_LEVEL);
+
+ if (!(adapter->cmd_dbf && adapter->abort_dbf &&
+ adapter->in_els_dbf && adapter->erp_dbf)) {
+ zfcp_adapter_debug_unregister(adapter);
+ return -ENOMEM;
+ }
+
+ return 0;
+
+}
+
+/**
+ * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter
+ * @adapter: pointer to adapter for which debug features should be unregistered
+ */
+void
+zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter)
+{
+ debug_unregister(adapter->abort_dbf);
+ debug_unregister(adapter->cmd_dbf);
+ debug_unregister(adapter->erp_dbf);
+ debug_unregister(adapter->in_els_dbf);
+ adapter->abort_dbf = NULL;
+ adapter->cmd_dbf = NULL;
+ adapter->erp_dbf = NULL;
+ adapter->in_els_dbf = NULL;
+}
+
void
zfcp_dummy_release(struct device *dev)
{
@@ -1298,6 +1462,10 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,
/* see FC-FS */
no_entries = (fcp_rscn_head->payload_len / 4);
+ zfcp_in_els_dbf_event(adapter, "##rscn", status_buffer,
+ fcp_rscn_head->payload_len);
+
+ debug_text_event(adapter->erp_dbf, 1, "unsol_els_rscn:");
for (i = 1; i < no_entries; i++) {
/* skip head and start with 1st element */
fcp_rscn_element++;
@@ -1329,6 +1497,8 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,
(ZFCP_STATUS_PORT_DID_DID, &port->status)) {
ZFCP_LOG_INFO("incoming RSCN, trying to open "
"port 0x%016Lx\n", port->wwpn);
+ debug_text_event(adapter->erp_dbf, 1,
+ "unsol_els_rscnu:");
zfcp_erp_port_reopen(port,
ZFCP_STATUS_COMMON_ERP_FAILED);
continue;
@@ -1354,6 +1524,8 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,
*/
ZFCP_LOG_INFO("incoming RSCN, trying to open "
"port 0x%016Lx\n", port->wwpn);
+ debug_text_event(adapter->erp_dbf, 1,
+ "unsol_els_rscnk:");
zfcp_test_link(port);
}
}
@@ -1369,6 +1541,8 @@ zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter,
struct zfcp_port *port;
unsigned long flags;
+ zfcp_in_els_dbf_event(adapter, "##plogi", status_buffer, 28);
+
read_lock_irqsave(&zfcp_data.config_lock, flags);
list_for_each_entry(port, &adapter->port_list_head, list) {
if (port->wwpn == (*(wwn_t *) & els_logi->nport_wwn))
@@ -1382,6 +1556,8 @@ zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter,
status_buffer->d_id,
zfcp_get_busid_by_adapter(adapter));
} else {
+ debug_text_event(adapter->erp_dbf, 1, "unsol_els_plogi:");
+ debug_event(adapter->erp_dbf, 1, &els_logi->nport_wwn, 8);
zfcp_erp_port_forced_reopen(port, 0);
}
}
@@ -1394,6 +1570,8 @@ zfcp_fsf_incoming_els_logo(struct zfcp_adapter *adapter,
struct zfcp_port *port;
unsigned long flags;
+ zfcp_in_els_dbf_event(adapter, "##logo", status_buffer, 16);
+
read_lock_irqsave(&zfcp_data.config_lock, flags);
list_for_each_entry(port, &adapter->port_list_head, list) {
if (port->wwpn == els_logo->nport_wwpn)
@@ -1407,6 +1585,8 @@ zfcp_fsf_incoming_els_logo(struct zfcp_adapter *adapter,
status_buffer->d_id,
zfcp_get_busid_by_adapter(adapter));
} else {
+ debug_text_event(adapter->erp_dbf, 1, "unsol_els_logo:");
+ debug_event(adapter->erp_dbf, 1, &els_logo->nport_wwpn, 8);
zfcp_erp_port_forced_reopen(port, 0);
}
}
@@ -1415,6 +1595,7 @@ static void
zfcp_fsf_incoming_els_unknown(struct zfcp_adapter *adapter,
struct fsf_status_read_buffer *status_buffer)
{
+ zfcp_in_els_dbf_event(adapter, "##undef", status_buffer, 24);
ZFCP_LOG_NORMAL("warning: unknown incoming ELS 0x%08x "
"for adapter %s\n", *(u32 *) (status_buffer->payload),
zfcp_get_busid_by_adapter(adapter));
@@ -1428,11 +1609,10 @@ zfcp_fsf_incoming_els(struct zfcp_fsf_req *fsf_req)
u32 els_type;
struct zfcp_adapter *adapter;
- status_buffer = (struct fsf_status_read_buffer *) fsf_req->data;
+ status_buffer = fsf_req->data.status_read.buffer;
els_type = *(u32 *) (status_buffer->payload);
adapter = fsf_req->adapter;
- zfcp_san_dbf_event_incoming_els(fsf_req);
if (els_type == LS_PLOGI)
zfcp_fsf_incoming_els_plogi(adapter, status_buffer);
else if (els_type == LS_LOGO)
diff --git a/trunk/drivers/s390/scsi/zfcp_ccw.c b/trunk/drivers/s390/scsi/zfcp_ccw.c
index 0fc46381fc22..b30abab77da3 100644
--- a/trunk/drivers/s390/scsi/zfcp_ccw.c
+++ b/trunk/drivers/s390/scsi/zfcp_ccw.c
@@ -202,9 +202,19 @@ static int
zfcp_ccw_set_offline(struct ccw_device *ccw_device)
{
struct zfcp_adapter *adapter;
+ struct zfcp_port *port;
+ struct fc_rport *rport;
down(&zfcp_data.config_sema);
adapter = dev_get_drvdata(&ccw_device->dev);
+ /* might be racy, but we cannot take config_lock due to the fact that
+ fc_remote_port_delete might sleep */
+ list_for_each_entry(port, &adapter->port_list_head, list)
+ if (port->rport) {
+ rport = port->rport;
+ port->rport = NULL;
+ fc_remote_port_delete(rport);
+ }
zfcp_erp_adapter_shutdown(adapter, 0);
zfcp_erp_wait(adapter);
zfcp_adapter_scsi_unregister(adapter);
diff --git a/trunk/drivers/s390/scsi/zfcp_dbf.c b/trunk/drivers/s390/scsi/zfcp_dbf.c
deleted file mode 100644
index 826fb3b00605..000000000000
--- a/trunk/drivers/s390/scsi/zfcp_dbf.c
+++ /dev/null
@@ -1,995 +0,0 @@
-/*
- *
- * linux/drivers/s390/scsi/zfcp_dbf.c
- *
- * FCP adapter driver for IBM eServer zSeries
- *
- * Debugging facilities
- *
- * (C) Copyright IBM Corp. 2005
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define ZFCP_DBF_REVISION "$Revision$"
-
-#include
-#include
-#include "zfcp_ext.h"
-
-static u32 dbfsize = 4;
-
-module_param(dbfsize, uint, 0400);
-MODULE_PARM_DESC(dbfsize,
- "number of pages for each debug feature area (default 4)");
-
-#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER
-
-static inline int
-zfcp_dbf_stck(char *out_buf, const char *label, unsigned long long stck)
-{
- unsigned long long sec;
- struct timespec xtime;
- int len = 0;
-
- stck -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);
- sec = stck >> 12;
- do_div(sec, 1000000);
- xtime.tv_sec = sec;
- stck -= (sec * 1000000) << 12;
- xtime.tv_nsec = ((stck * 1000) >> 12);
- len += sprintf(out_buf + len, "%-24s%011lu:%06lu\n",
- label, xtime.tv_sec, xtime.tv_nsec);
-
- return len;
-}
-
-static int zfcp_dbf_tag(char *out_buf, const char *label, const char *tag)
-{
- int len = 0, i;
-
- len += sprintf(out_buf + len, "%-24s", label);
- for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++)
- len += sprintf(out_buf + len, "%c", tag[i]);
- len += sprintf(out_buf + len, "\n");
-
- return len;
-}
-
-static int
-zfcp_dbf_view(char *out_buf, const char *label, const char *format, ...)
-{
- va_list arg;
- int len = 0;
-
- len += sprintf(out_buf + len, "%-24s", label);
- va_start(arg, format);
- len += vsprintf(out_buf + len, format, arg);
- va_end(arg);
- len += sprintf(out_buf + len, "\n");
-
- return len;
-}
-
-static int
-zfcp_dbf_view_dump(char *out_buf, const char *label,
- char *buffer, int buflen, int offset, int total_size)
-{
- int len = 0;
-
- if (offset == 0)
- len += sprintf(out_buf + len, "%-24s ", label);
-
- while (buflen--) {
- if (offset > 0) {
- if ((offset % 32) == 0)
- len += sprintf(out_buf + len, "\n%-24c ", ' ');
- else if ((offset % 4) == 0)
- len += sprintf(out_buf + len, " ");
- }
- len += sprintf(out_buf + len, "%02x", *buffer++);
- if (++offset == total_size) {
- len += sprintf(out_buf + len, "\n");
- break;
- }
- }
-
- if (total_size == 0)
- len += sprintf(out_buf + len, "\n");
-
- return len;
-}
-
-static inline int
-zfcp_dbf_view_header(debug_info_t * id, struct debug_view *view, int area,
- debug_entry_t * entry, char *out_buf)
-{
- struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry);
- int len = 0;
-
- if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) {
- len += zfcp_dbf_stck(out_buf + len, "timestamp",
- entry->id.stck);
- len += zfcp_dbf_view(out_buf + len, "cpu", "%02i",
- entry->id.fields.cpuid);
- } else {
- len += zfcp_dbf_view_dump(out_buf + len, NULL,
- dump->data,
- dump->size,
- dump->offset, dump->total_size);
- if ((dump->offset + dump->size) == dump->total_size)
- len += sprintf(out_buf + len, "\n");
- }
-
- return len;
-}
-
-inline void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
-{
- struct zfcp_adapter *adapter = fsf_req->adapter;
- struct fsf_qtcb *qtcb = fsf_req->qtcb;
- union fsf_prot_status_qual *prot_status_qual =
- &qtcb->prefix.prot_status_qual;
- union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual;
- struct scsi_cmnd *scsi_cmnd;
- struct zfcp_port *port;
- struct zfcp_unit *unit;
- struct zfcp_send_els *send_els;
- struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
- struct zfcp_hba_dbf_record_response *response = &rec->type.response;
- int level;
- unsigned long flags;
-
- spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
- memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));
- strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE);
-
- if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
- (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {
- strncpy(rec->tag2, "perr", ZFCP_DBF_TAG_SIZE);
- level = 1;
- } else if (qtcb->header.fsf_status != FSF_GOOD) {
- strncpy(rec->tag2, "ferr", ZFCP_DBF_TAG_SIZE);
- level = 1;
- } else if ((fsf_req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) ||
- (fsf_req->fsf_command == FSF_QTCB_OPEN_LUN)) {
- strncpy(rec->tag2, "open", ZFCP_DBF_TAG_SIZE);
- level = 4;
- } else if ((prot_status_qual->doubleword[0] != 0) ||
- (prot_status_qual->doubleword[1] != 0) ||
- (fsf_status_qual->doubleword[0] != 0) ||
- (fsf_status_qual->doubleword[1] != 0)) {
- strncpy(rec->tag2, "qual", ZFCP_DBF_TAG_SIZE);
- level = 3;
- } else {
- strncpy(rec->tag2, "norm", ZFCP_DBF_TAG_SIZE);
- level = 6;
- }
-
- response->fsf_command = fsf_req->fsf_command;
- response->fsf_reqid = (unsigned long)fsf_req;
- response->fsf_seqno = fsf_req->seq_no;
- response->fsf_issued = fsf_req->issued;
- response->fsf_prot_status = qtcb->prefix.prot_status;
- response->fsf_status = qtcb->header.fsf_status;
- memcpy(response->fsf_prot_status_qual,
- prot_status_qual, FSF_PROT_STATUS_QUAL_SIZE);
- memcpy(response->fsf_status_qual,
- fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE);
- response->fsf_req_status = fsf_req->status;
- response->sbal_first = fsf_req->sbal_first;
- response->sbal_curr = fsf_req->sbal_curr;
- response->sbal_last = fsf_req->sbal_last;
- response->pool = fsf_req->pool != NULL;
- response->erp_action = (unsigned long)fsf_req->erp_action;
-
- switch (fsf_req->fsf_command) {
- case FSF_QTCB_FCP_CMND:
- if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
- break;
- scsi_cmnd = (struct scsi_cmnd *)fsf_req->data;
- if (scsi_cmnd != NULL) {
- response->data.send_fcp.scsi_cmnd
- = (unsigned long)scsi_cmnd;
- response->data.send_fcp.scsi_serial
- = scsi_cmnd->serial_number;
- }
- break;
-
- case FSF_QTCB_OPEN_PORT_WITH_DID:
- case FSF_QTCB_CLOSE_PORT:
- case FSF_QTCB_CLOSE_PHYSICAL_PORT:
- port = (struct zfcp_port *)fsf_req->data;
- response->data.port.wwpn = port->wwpn;
- response->data.port.d_id = port->d_id;
- response->data.port.port_handle = qtcb->header.port_handle;
- break;
-
- case FSF_QTCB_OPEN_LUN:
- case FSF_QTCB_CLOSE_LUN:
- unit = (struct zfcp_unit *)fsf_req->data;
- port = unit->port;
- response->data.unit.wwpn = port->wwpn;
- response->data.unit.fcp_lun = unit->fcp_lun;
- response->data.unit.port_handle = qtcb->header.port_handle;
- response->data.unit.lun_handle = qtcb->header.lun_handle;
- break;
-
- case FSF_QTCB_SEND_ELS:
- send_els = (struct zfcp_send_els *)fsf_req->data;
- response->data.send_els.d_id = qtcb->bottom.support.d_id;
- response->data.send_els.ls_code = send_els->ls_code >> 24;
- break;
-
- case FSF_QTCB_ABORT_FCP_CMND:
- case FSF_QTCB_SEND_GENERIC:
- case FSF_QTCB_EXCHANGE_CONFIG_DATA:
- case FSF_QTCB_EXCHANGE_PORT_DATA:
- case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
- case FSF_QTCB_UPLOAD_CONTROL_FILE:
- break;
- }
-
- debug_event(adapter->hba_dbf, level,
- rec, sizeof(struct zfcp_hba_dbf_record));
- spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
-}
-
-inline void
-zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter,
- struct fsf_status_read_buffer *status_buffer)
-{
- struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
- unsigned long flags;
-
- spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
- memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));
- strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE);
- strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE);
-
- rec->type.status.failed = adapter->status_read_failed;
- if (status_buffer != NULL) {
- rec->type.status.status_type = status_buffer->status_type;
- rec->type.status.status_subtype = status_buffer->status_subtype;
- memcpy(&rec->type.status.queue_designator,
- &status_buffer->queue_designator,
- sizeof(struct fsf_queue_designator));
-
- switch (status_buffer->status_type) {
- case FSF_STATUS_READ_SENSE_DATA_AVAIL:
- rec->type.status.payload_size =
- ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL;
- break;
-
- case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:
- rec->type.status.payload_size =
- ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD;
- break;
-
- case FSF_STATUS_READ_LINK_DOWN:
- switch (status_buffer->status_subtype) {
- case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
- case FSF_STATUS_READ_SUB_FDISC_FAILED:
- rec->type.status.payload_size =
- sizeof(struct fsf_link_down_info);
- }
- break;
-
- case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:
- rec->type.status.payload_size =
- ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT;
- break;
- }
- memcpy(&rec->type.status.payload,
- &status_buffer->payload, rec->type.status.payload_size);
- }
-
- debug_event(adapter->hba_dbf, 2,
- rec, sizeof(struct zfcp_hba_dbf_record));
- spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
-}
-
-inline void
-zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status,
- unsigned int qdio_error, unsigned int siga_error,
- int sbal_index, int sbal_count)
-{
- struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
- unsigned long flags;
-
- spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
- memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));
- strncpy(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE);
- rec->type.qdio.status = status;
- rec->type.qdio.qdio_error = qdio_error;
- rec->type.qdio.siga_error = siga_error;
- rec->type.qdio.sbal_index = sbal_index;
- rec->type.qdio.sbal_count = sbal_count;
- debug_event(adapter->hba_dbf, 0,
- rec, sizeof(struct zfcp_hba_dbf_record));
- spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
-}
-
-static inline int
-zfcp_hba_dbf_view_response(char *out_buf,
- struct zfcp_hba_dbf_record_response *rec)
-{
- int len = 0;
-
- len += zfcp_dbf_view(out_buf + len, "fsf_command", "0x%08x",
- rec->fsf_command);
- len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",
- rec->fsf_reqid);
- len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",
- rec->fsf_seqno);
- len += zfcp_dbf_stck(out_buf + len, "fsf_issued", rec->fsf_issued);
- len += zfcp_dbf_view(out_buf + len, "fsf_prot_status", "0x%08x",
- rec->fsf_prot_status);
- len += zfcp_dbf_view(out_buf + len, "fsf_status", "0x%08x",
- rec->fsf_status);
- len += zfcp_dbf_view_dump(out_buf + len, "fsf_prot_status_qual",
- rec->fsf_prot_status_qual,
- FSF_PROT_STATUS_QUAL_SIZE,
- 0, FSF_PROT_STATUS_QUAL_SIZE);
- len += zfcp_dbf_view_dump(out_buf + len, "fsf_status_qual",
- rec->fsf_status_qual,
- FSF_STATUS_QUALIFIER_SIZE,
- 0, FSF_STATUS_QUALIFIER_SIZE);
- len += zfcp_dbf_view(out_buf + len, "fsf_req_status", "0x%08x",
- rec->fsf_req_status);
- len += zfcp_dbf_view(out_buf + len, "sbal_first", "0x%02x",
- rec->sbal_first);
- len += zfcp_dbf_view(out_buf + len, "sbal_curr", "0x%02x",
- rec->sbal_curr);
- len += zfcp_dbf_view(out_buf + len, "sbal_last", "0x%02x",
- rec->sbal_last);
- len += zfcp_dbf_view(out_buf + len, "pool", "0x%02x", rec->pool);
-
- switch (rec->fsf_command) {
- case FSF_QTCB_FCP_CMND:
- if (rec->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
- break;
- len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx",
- rec->data.send_fcp.scsi_cmnd);
- len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx",
- rec->data.send_fcp.scsi_serial);
- break;
-
- case FSF_QTCB_OPEN_PORT_WITH_DID:
- case FSF_QTCB_CLOSE_PORT:
- case FSF_QTCB_CLOSE_PHYSICAL_PORT:
- len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx",
- rec->data.port.wwpn);
- len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x",
- rec->data.port.d_id);
- len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x",
- rec->data.port.port_handle);
- break;
-
- case FSF_QTCB_OPEN_LUN:
- case FSF_QTCB_CLOSE_LUN:
- len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx",
- rec->data.unit.wwpn);
- len += zfcp_dbf_view(out_buf + len, "fcp_lun", "0x%016Lx",
- rec->data.unit.fcp_lun);
- len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x",
- rec->data.unit.port_handle);
- len += zfcp_dbf_view(out_buf + len, "lun_handle", "0x%08x",
- rec->data.unit.lun_handle);
- break;
-
- case FSF_QTCB_SEND_ELS:
- len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x",
- rec->data.send_els.d_id);
- len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x",
- rec->data.send_els.ls_code);
- break;
-
- case FSF_QTCB_ABORT_FCP_CMND:
- case FSF_QTCB_SEND_GENERIC:
- case FSF_QTCB_EXCHANGE_CONFIG_DATA:
- case FSF_QTCB_EXCHANGE_PORT_DATA:
- case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
- case FSF_QTCB_UPLOAD_CONTROL_FILE:
- break;
- }
-
- return len;
-}
-
-static inline int
-zfcp_hba_dbf_view_status(char *out_buf, struct zfcp_hba_dbf_record_status *rec)
-{
- int len = 0;
-
- len += zfcp_dbf_view(out_buf + len, "failed", "0x%02x", rec->failed);
- len += zfcp_dbf_view(out_buf + len, "status_type", "0x%08x",
- rec->status_type);
- len += zfcp_dbf_view(out_buf + len, "status_subtype", "0x%08x",
- rec->status_subtype);
- len += zfcp_dbf_view_dump(out_buf + len, "queue_designator",
- (char *)&rec->queue_designator,
- sizeof(struct fsf_queue_designator),
- 0, sizeof(struct fsf_queue_designator));
- len += zfcp_dbf_view_dump(out_buf + len, "payload",
- (char *)&rec->payload,
- rec->payload_size, 0, rec->payload_size);
-
- return len;
-}
-
-static inline int
-zfcp_hba_dbf_view_qdio(char *out_buf, struct zfcp_hba_dbf_record_qdio *rec)
-{
- int len = 0;
-
- len += zfcp_dbf_view(out_buf + len, "status", "0x%08x", rec->status);
- len += zfcp_dbf_view(out_buf + len, "qdio_error", "0x%08x",
- rec->qdio_error);
- len += zfcp_dbf_view(out_buf + len, "siga_error", "0x%08x",
- rec->siga_error);
- len += zfcp_dbf_view(out_buf + len, "sbal_index", "0x%02x",
- rec->sbal_index);
- len += zfcp_dbf_view(out_buf + len, "sbal_count", "0x%02x",
- rec->sbal_count);
-
- return len;
-}
-
-static int
-zfcp_hba_dbf_view_format(debug_info_t * id, struct debug_view *view,
- char *out_buf, const char *in_buf)
-{
- struct zfcp_hba_dbf_record *rec = (struct zfcp_hba_dbf_record *)in_buf;
- int len = 0;
-
- if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
- return 0;
-
- len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag);
- if (isalpha(rec->tag2[0]))
- len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2);
- if (strncmp(rec->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0)
- len += zfcp_hba_dbf_view_response(out_buf + len,
- &rec->type.response);
- else if (strncmp(rec->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0)
- len += zfcp_hba_dbf_view_status(out_buf + len,
- &rec->type.status);
- else if (strncmp(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0)
- len += zfcp_hba_dbf_view_qdio(out_buf + len, &rec->type.qdio);
-
- len += sprintf(out_buf + len, "\n");
-
- return len;
-}
-
-struct debug_view zfcp_hba_dbf_view = {
- "structured",
- NULL,
- &zfcp_dbf_view_header,
- &zfcp_hba_dbf_view_format,
- NULL,
- NULL
-};
-
-inline void
-_zfcp_san_dbf_event_common_ct(const char *tag, struct zfcp_fsf_req *fsf_req,
- u32 s_id, u32 d_id, void *buffer, int buflen)
-{
- struct zfcp_send_ct *send_ct = (struct zfcp_send_ct *)fsf_req->data;
- struct zfcp_port *port = send_ct->port;
- struct zfcp_adapter *adapter = port->adapter;
- struct ct_hdr *header = (struct ct_hdr *)buffer;
- struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf;
- struct zfcp_san_dbf_record_ct *ct = &rec->type.ct;
- unsigned long flags;
-
- spin_lock_irqsave(&adapter->san_dbf_lock, flags);
- memset(rec, 0, sizeof(struct zfcp_san_dbf_record));
- strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
- rec->fsf_reqid = (unsigned long)fsf_req;
- rec->fsf_seqno = fsf_req->seq_no;
- rec->s_id = s_id;
- rec->d_id = d_id;
- if (strncmp(tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {
- ct->type.request.cmd_req_code = header->cmd_rsp_code;
- ct->type.request.revision = header->revision;
- ct->type.request.gs_type = header->gs_type;
- ct->type.request.gs_subtype = header->gs_subtype;
- ct->type.request.options = header->options;
- ct->type.request.max_res_size = header->max_res_size;
- } else if (strncmp(tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {
- ct->type.response.cmd_rsp_code = header->cmd_rsp_code;
- ct->type.response.revision = header->revision;
- ct->type.response.reason_code = header->reason_code;
- ct->type.response.reason_code_expl = header->reason_code_expl;
- ct->type.response.vendor_unique = header->vendor_unique;
- }
- ct->payload_size =
- min(buflen - (int)sizeof(struct ct_hdr), ZFCP_DBF_CT_PAYLOAD);
- memcpy(ct->payload, buffer + sizeof(struct ct_hdr), ct->payload_size);
- debug_event(adapter->san_dbf, 3,
- rec, sizeof(struct zfcp_san_dbf_record));
- spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
-}
-
-inline void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
-{
- struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
- struct zfcp_port *port = ct->port;
- struct zfcp_adapter *adapter = port->adapter;
-
- _zfcp_san_dbf_event_common_ct("octc", fsf_req,
- fc_host_port_id(adapter->scsi_host),
- port->d_id, zfcp_sg_to_address(ct->req),
- ct->req->length);
-}
-
-inline void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
-{
- struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
- struct zfcp_port *port = ct->port;
- struct zfcp_adapter *adapter = port->adapter;
-
- _zfcp_san_dbf_event_common_ct("rctc", fsf_req, port->d_id,
- fc_host_port_id(adapter->scsi_host),
- zfcp_sg_to_address(ct->resp),
- ct->resp->length);
-}
-
-static inline void
-_zfcp_san_dbf_event_common_els(const char *tag, int level,
- struct zfcp_fsf_req *fsf_req, u32 s_id,
- u32 d_id, u8 ls_code, void *buffer, int buflen)
-{
- struct zfcp_adapter *adapter = fsf_req->adapter;
- struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf;
- struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
- unsigned long flags;
- int offset = 0;
-
- spin_lock_irqsave(&adapter->san_dbf_lock, flags);
- do {
- memset(rec, 0, sizeof(struct zfcp_san_dbf_record));
- if (offset == 0) {
- strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
- rec->fsf_reqid = (unsigned long)fsf_req;
- rec->fsf_seqno = fsf_req->seq_no;
- rec->s_id = s_id;
- rec->d_id = d_id;
- rec->type.els.ls_code = ls_code;
- buflen = min(buflen, ZFCP_DBF_ELS_MAX_PAYLOAD);
- rec->type.els.payload_size = buflen;
- memcpy(rec->type.els.payload,
- buffer, min(buflen, ZFCP_DBF_ELS_PAYLOAD));
- offset += min(buflen, ZFCP_DBF_ELS_PAYLOAD);
- } else {
- strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
- dump->total_size = buflen;
- dump->offset = offset;
- dump->size = min(buflen - offset,
- (int)sizeof(struct zfcp_san_dbf_record)
- - (int)sizeof(struct zfcp_dbf_dump));
- memcpy(dump->data, buffer + offset, dump->size);
- offset += dump->size;
- }
- debug_event(adapter->san_dbf, level,
- rec, sizeof(struct zfcp_san_dbf_record));
- } while (offset < buflen);
- spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
-}
-
-inline void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req)
-{
- struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
-
- _zfcp_san_dbf_event_common_els("oels", 2, fsf_req,
- fc_host_port_id(els->adapter->scsi_host),
- els->d_id,
- *(u8 *) zfcp_sg_to_address(els->req),
- zfcp_sg_to_address(els->req),
- els->req->length);
-}
-
-inline void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req)
-{
- struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
-
- _zfcp_san_dbf_event_common_els("rels", 2, fsf_req, els->d_id,
- fc_host_port_id(els->adapter->scsi_host),
- *(u8 *) zfcp_sg_to_address(els->req),
- zfcp_sg_to_address(els->resp),
- els->resp->length);
-}
-
-inline void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req)
-{
- struct zfcp_adapter *adapter = fsf_req->adapter;
- struct fsf_status_read_buffer *status_buffer =
- (struct fsf_status_read_buffer *)fsf_req->data;
- int length = (int)status_buffer->length -
- (int)((void *)&status_buffer->payload - (void *)status_buffer);
-
- _zfcp_san_dbf_event_common_els("iels", 1, fsf_req, status_buffer->d_id,
- fc_host_port_id(adapter->scsi_host),
- *(u8 *) status_buffer->payload,
- (void *)status_buffer->payload, length);
-}
-
-static int
-zfcp_san_dbf_view_format(debug_info_t * id, struct debug_view *view,
- char *out_buf, const char *in_buf)
-{
- struct zfcp_san_dbf_record *rec = (struct zfcp_san_dbf_record *)in_buf;
- char *buffer = NULL;
- int buflen = 0, total = 0;
- int len = 0;
-
- if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
- return 0;
-
- len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag);
- len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",
- rec->fsf_reqid);
- len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",
- rec->fsf_seqno);
- len += zfcp_dbf_view(out_buf + len, "s_id", "0x%06x", rec->s_id);
- len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", rec->d_id);
-
- if (strncmp(rec->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {
- len += zfcp_dbf_view(out_buf + len, "cmd_req_code", "0x%04x",
- rec->type.ct.type.request.cmd_req_code);
- len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x",
- rec->type.ct.type.request.revision);
- len += zfcp_dbf_view(out_buf + len, "gs_type", "0x%02x",
- rec->type.ct.type.request.gs_type);
- len += zfcp_dbf_view(out_buf + len, "gs_subtype", "0x%02x",
- rec->type.ct.type.request.gs_subtype);
- len += zfcp_dbf_view(out_buf + len, "options", "0x%02x",
- rec->type.ct.type.request.options);
- len += zfcp_dbf_view(out_buf + len, "max_res_size", "0x%04x",
- rec->type.ct.type.request.max_res_size);
- total = rec->type.ct.payload_size;
- buffer = rec->type.ct.payload;
- buflen = min(total, ZFCP_DBF_CT_PAYLOAD);
- } else if (strncmp(rec->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {
- len += zfcp_dbf_view(out_buf + len, "cmd_rsp_code", "0x%04x",
- rec->type.ct.type.response.cmd_rsp_code);
- len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x",
- rec->type.ct.type.response.revision);
- len += zfcp_dbf_view(out_buf + len, "reason_code", "0x%02x",
- rec->type.ct.type.response.reason_code);
- len +=
- zfcp_dbf_view(out_buf + len, "reason_code_expl", "0x%02x",
- rec->type.ct.type.response.reason_code_expl);
- len +=
- zfcp_dbf_view(out_buf + len, "vendor_unique", "0x%02x",
- rec->type.ct.type.response.vendor_unique);
- total = rec->type.ct.payload_size;
- buffer = rec->type.ct.payload;
- buflen = min(total, ZFCP_DBF_CT_PAYLOAD);
- } else if (strncmp(rec->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 ||
- strncmp(rec->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||
- strncmp(rec->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {
- len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x",
- rec->type.els.ls_code);
- total = rec->type.els.payload_size;
- buffer = rec->type.els.payload;
- buflen = min(total, ZFCP_DBF_ELS_PAYLOAD);
- }
-
- len += zfcp_dbf_view_dump(out_buf + len, "payload",
- buffer, buflen, 0, total);
-
- if (buflen == total)
- len += sprintf(out_buf + len, "\n");
-
- return len;
-}
-
-struct debug_view zfcp_san_dbf_view = {
- "structured",
- NULL,
- &zfcp_dbf_view_header,
- &zfcp_san_dbf_view_format,
- NULL,
- NULL
-};
-
-static inline void
-_zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
- struct zfcp_adapter *adapter,
- struct scsi_cmnd *scsi_cmnd,
- struct zfcp_fsf_req *new_fsf_req)
-{
- struct zfcp_fsf_req *fsf_req =
- (struct zfcp_fsf_req *)scsi_cmnd->host_scribble;
- struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf;
- struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
- unsigned long flags;
- struct fcp_rsp_iu *fcp_rsp;
- char *fcp_rsp_info = NULL, *fcp_sns_info = NULL;
- int offset = 0, buflen = 0;
-
- spin_lock_irqsave(&adapter->scsi_dbf_lock, flags);
- do {
- memset(rec, 0, sizeof(struct zfcp_scsi_dbf_record));
- if (offset == 0) {
- strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
- strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE);
- if (scsi_cmnd->device) {
- rec->scsi_id = scsi_cmnd->device->id;
- rec->scsi_lun = scsi_cmnd->device->lun;
- }
- rec->scsi_result = scsi_cmnd->result;
- rec->scsi_cmnd = (unsigned long)scsi_cmnd;
- rec->scsi_serial = scsi_cmnd->serial_number;
- memcpy(rec->scsi_opcode,
- &scsi_cmnd->cmnd,
- min((int)scsi_cmnd->cmd_len,
- ZFCP_DBF_SCSI_OPCODE));
- rec->scsi_retries = scsi_cmnd->retries;
- rec->scsi_allowed = scsi_cmnd->allowed;
- if (fsf_req != NULL) {
- fcp_rsp = (struct fcp_rsp_iu *)
- &(fsf_req->qtcb->bottom.io.fcp_rsp);
- fcp_rsp_info =
- zfcp_get_fcp_rsp_info_ptr(fcp_rsp);
- fcp_sns_info =
- zfcp_get_fcp_sns_info_ptr(fcp_rsp);
-
- rec->type.fcp.rsp_validity =
- fcp_rsp->validity.value;
- rec->type.fcp.rsp_scsi_status =
- fcp_rsp->scsi_status;
- rec->type.fcp.rsp_resid = fcp_rsp->fcp_resid;
- if (fcp_rsp->validity.bits.fcp_rsp_len_valid)
- rec->type.fcp.rsp_code =
- *(fcp_rsp_info + 3);
- if (fcp_rsp->validity.bits.fcp_sns_len_valid) {
- buflen = min((int)fcp_rsp->fcp_sns_len,
- ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO);
- rec->type.fcp.sns_info_len = buflen;
- memcpy(rec->type.fcp.sns_info,
- fcp_sns_info,
- min(buflen,
- ZFCP_DBF_SCSI_FCP_SNS_INFO));
- offset += min(buflen,
- ZFCP_DBF_SCSI_FCP_SNS_INFO);
- }
-
- rec->fsf_reqid = (unsigned long)fsf_req;
- rec->fsf_seqno = fsf_req->seq_no;
- rec->fsf_issued = fsf_req->issued;
- }
- if (new_fsf_req != NULL) {
- rec->type.new_fsf_req.fsf_reqid =
- (unsigned long)
- new_fsf_req;
- rec->type.new_fsf_req.fsf_seqno =
- new_fsf_req->seq_no;
- rec->type.new_fsf_req.fsf_issued =
- new_fsf_req->issued;
- }
- } else {
- strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
- dump->total_size = buflen;
- dump->offset = offset;
- dump->size = min(buflen - offset,
- (int)sizeof(struct
- zfcp_scsi_dbf_record) -
- (int)sizeof(struct zfcp_dbf_dump));
- memcpy(dump->data, fcp_sns_info + offset, dump->size);
- offset += dump->size;
- }
- debug_event(adapter->scsi_dbf, level,
- rec, sizeof(struct zfcp_scsi_dbf_record));
- } while (offset < buflen);
- spin_unlock_irqrestore(&adapter->scsi_dbf_lock, flags);
-}
-
-inline void
-zfcp_scsi_dbf_event_result(const char *tag, int level,
- struct zfcp_adapter *adapter,
- struct scsi_cmnd *scsi_cmnd)
-{
- _zfcp_scsi_dbf_event_common("rslt",
- tag, level, adapter, scsi_cmnd, NULL);
-}
-
-inline void
-zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter,
- struct scsi_cmnd *scsi_cmnd,
- struct zfcp_fsf_req *new_fsf_req)
-{
- _zfcp_scsi_dbf_event_common("abrt",
- tag, 1, adapter, scsi_cmnd, new_fsf_req);
-}
-
-inline void
-zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
- struct scsi_cmnd *scsi_cmnd)
-{
- struct zfcp_adapter *adapter = unit->port->adapter;
-
- _zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst",
- tag, 1, adapter, scsi_cmnd, NULL);
-}
-
-static int
-zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view,
- char *out_buf, const char *in_buf)
-{
- struct zfcp_scsi_dbf_record *rec =
- (struct zfcp_scsi_dbf_record *)in_buf;
- int len = 0;
-
- if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
- return 0;
-
- len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag);
- len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2);
- len += zfcp_dbf_view(out_buf + len, "scsi_id", "0x%08x", rec->scsi_id);
- len += zfcp_dbf_view(out_buf + len, "scsi_lun", "0x%08x",
- rec->scsi_lun);
- len += zfcp_dbf_view(out_buf + len, "scsi_result", "0x%08x",
- rec->scsi_result);
- len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx",
- rec->scsi_cmnd);
- len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx",
- rec->scsi_serial);
- len += zfcp_dbf_view_dump(out_buf + len, "scsi_opcode",
- rec->scsi_opcode,
- ZFCP_DBF_SCSI_OPCODE,
- 0, ZFCP_DBF_SCSI_OPCODE);
- len += zfcp_dbf_view(out_buf + len, "scsi_retries", "0x%02x",
- rec->scsi_retries);
- len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x",
- rec->scsi_allowed);
- len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",
- rec->fsf_reqid);
- len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",
- rec->fsf_seqno);
- len += zfcp_dbf_stck(out_buf + len, "fsf_issued", rec->fsf_issued);
- if (strncmp(rec->tag, "rslt", ZFCP_DBF_TAG_SIZE) == 0) {
- len +=
- zfcp_dbf_view(out_buf + len, "fcp_rsp_validity", "0x%02x",
- rec->type.fcp.rsp_validity);
- len +=
- zfcp_dbf_view(out_buf + len, "fcp_rsp_scsi_status",
- "0x%02x", rec->type.fcp.rsp_scsi_status);
- len +=
- zfcp_dbf_view(out_buf + len, "fcp_rsp_resid", "0x%08x",
- rec->type.fcp.rsp_resid);
- len +=
- zfcp_dbf_view(out_buf + len, "fcp_rsp_code", "0x%08x",
- rec->type.fcp.rsp_code);
- len +=
- zfcp_dbf_view(out_buf + len, "fcp_sns_info_len", "0x%08x",
- rec->type.fcp.sns_info_len);
- len +=
- zfcp_dbf_view_dump(out_buf + len, "fcp_sns_info",
- rec->type.fcp.sns_info,
- min((int)rec->type.fcp.sns_info_len,
- ZFCP_DBF_SCSI_FCP_SNS_INFO), 0,
- rec->type.fcp.sns_info_len);
- } else if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) {
- len += zfcp_dbf_view(out_buf + len, "fsf_reqid_abort", "0x%0Lx",
- rec->type.new_fsf_req.fsf_reqid);
- len += zfcp_dbf_view(out_buf + len, "fsf_seqno_abort", "0x%08x",
- rec->type.new_fsf_req.fsf_seqno);
- len += zfcp_dbf_stck(out_buf + len, "fsf_issued",
- rec->type.new_fsf_req.fsf_issued);
- } else if ((strncmp(rec->tag, "trst", ZFCP_DBF_TAG_SIZE) == 0) ||
- (strncmp(rec->tag, "lrst", ZFCP_DBF_TAG_SIZE) == 0)) {
- len += zfcp_dbf_view(out_buf + len, "fsf_reqid_reset", "0x%0Lx",
- rec->type.new_fsf_req.fsf_reqid);
- len += zfcp_dbf_view(out_buf + len, "fsf_seqno_reset", "0x%08x",
- rec->type.new_fsf_req.fsf_seqno);
- len += zfcp_dbf_stck(out_buf + len, "fsf_issued",
- rec->type.new_fsf_req.fsf_issued);
- }
-
- len += sprintf(out_buf + len, "\n");
-
- return len;
-}
-
-struct debug_view zfcp_scsi_dbf_view = {
- "structured",
- NULL,
- &zfcp_dbf_view_header,
- &zfcp_scsi_dbf_view_format,
- NULL,
- NULL
-};
-
-/**
- * zfcp_adapter_debug_register - registers debug feature for an adapter
- * @adapter: pointer to adapter for which debug features should be registered
- * return: -ENOMEM on error, 0 otherwise
- */
-int zfcp_adapter_debug_register(struct zfcp_adapter *adapter)
-{
- char dbf_name[DEBUG_MAX_NAME_LEN];
-
- /* debug feature area which records recovery activity */
- spin_lock_init(&adapter->erp_dbf_lock);
- sprintf(dbf_name, "zfcp_%s_erp", zfcp_get_busid_by_adapter(adapter));
- adapter->erp_dbf = debug_register(dbf_name, dbfsize, 2,
- sizeof(struct zfcp_erp_dbf_record));
- if (!adapter->erp_dbf)
- goto failed;
- debug_register_view(adapter->erp_dbf, &debug_hex_ascii_view);
- debug_set_level(adapter->erp_dbf, 3);
-
- /* debug feature area which records HBA (FSF and QDIO) conditions */
- spin_lock_init(&adapter->hba_dbf_lock);
- sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter));
- adapter->hba_dbf = debug_register(dbf_name, dbfsize, 1,
- sizeof(struct zfcp_hba_dbf_record));
- if (!adapter->hba_dbf)
- goto failed;
- debug_register_view(adapter->hba_dbf, &debug_hex_ascii_view);
- debug_register_view(adapter->hba_dbf, &zfcp_hba_dbf_view);
- debug_set_level(adapter->hba_dbf, 3);
-
- /* debug feature area which records SAN command failures and recovery */
- spin_lock_init(&adapter->san_dbf_lock);
- sprintf(dbf_name, "zfcp_%s_san", zfcp_get_busid_by_adapter(adapter));
- adapter->san_dbf = debug_register(dbf_name, dbfsize, 1,
- sizeof(struct zfcp_san_dbf_record));
- if (!adapter->san_dbf)
- goto failed;
- debug_register_view(adapter->san_dbf, &debug_hex_ascii_view);
- debug_register_view(adapter->san_dbf, &zfcp_san_dbf_view);
- debug_set_level(adapter->san_dbf, 6);
-
- /* debug feature area which records SCSI command failures and recovery */
- spin_lock_init(&adapter->scsi_dbf_lock);
- sprintf(dbf_name, "zfcp_%s_scsi", zfcp_get_busid_by_adapter(adapter));
- adapter->scsi_dbf = debug_register(dbf_name, dbfsize, 1,
- sizeof(struct zfcp_scsi_dbf_record));
- if (!adapter->scsi_dbf)
- goto failed;
- debug_register_view(adapter->scsi_dbf, &debug_hex_ascii_view);
- debug_register_view(adapter->scsi_dbf, &zfcp_scsi_dbf_view);
- debug_set_level(adapter->scsi_dbf, 3);
-
- return 0;
-
- failed:
- zfcp_adapter_debug_unregister(adapter);
-
- return -ENOMEM;
-}
-
-/**
- * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter
- * @adapter: pointer to adapter for which debug features should be unregistered
- */
-void zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter)
-{
- debug_unregister(adapter->scsi_dbf);
- debug_unregister(adapter->san_dbf);
- debug_unregister(adapter->hba_dbf);
- debug_unregister(adapter->erp_dbf);
- adapter->scsi_dbf = NULL;
- adapter->san_dbf = NULL;
- adapter->hba_dbf = NULL;
- adapter->erp_dbf = NULL;
-}
-
-#undef ZFCP_LOG_AREA
diff --git a/trunk/drivers/s390/scsi/zfcp_def.h b/trunk/drivers/s390/scsi/zfcp_def.h
index d81b737d68cc..455e902533a9 100644
--- a/trunk/drivers/s390/scsi/zfcp_def.h
+++ b/trunk/drivers/s390/scsi/zfcp_def.h
@@ -66,7 +66,7 @@
/********************* GENERAL DEFINES *********************************/
/* zfcp version number, it consists of major, minor, and patch-level number */
-#define ZFCP_VERSION "4.5.0"
+#define ZFCP_VERSION "4.3.0"
/**
* zfcp_sg_to_address - determine kernel address from struct scatterlist
@@ -154,17 +154,13 @@ typedef u32 scsi_lun_t;
#define ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP 100
#define ZFCP_EXCHANGE_CONFIG_DATA_RETRIES 7
-/* Retry 5 times every 2 second, then every minute */
-#define ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES 5
-#define ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP 200
-#define ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP 6000
-
/* timeout value for "default timer" for fsf requests */
#define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ);
/*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/
typedef unsigned long long wwn_t;
+typedef unsigned int fc_id_t;
typedef unsigned long long fcp_lun_t;
/* data length field may be at variable position in FCP-2 FCP_CMND IU */
typedef unsigned int fcp_dl_t;
@@ -284,171 +280,6 @@ struct fcp_logo {
wwn_t nport_wwpn;
} __attribute__((packed));
-/*
- * DBF stuff
- */
-#define ZFCP_DBF_TAG_SIZE 4
-
-struct zfcp_dbf_dump {
- u8 tag[ZFCP_DBF_TAG_SIZE];
- u32 total_size; /* size of total dump data */
- u32 offset; /* how much data has being already dumped */
- u32 size; /* how much data comes with this record */
- u8 data[]; /* dump data */
-} __attribute__ ((packed));
-
-/* FIXME: to be inflated when reworking the erp dbf */
-struct zfcp_erp_dbf_record {
- u8 dummy[16];
-} __attribute__ ((packed));
-
-struct zfcp_hba_dbf_record_response {
- u32 fsf_command;
- u64 fsf_reqid;
- u32 fsf_seqno;
- u64 fsf_issued;
- u32 fsf_prot_status;
- u32 fsf_status;
- u8 fsf_prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
- u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
- u32 fsf_req_status;
- u8 sbal_first;
- u8 sbal_curr;
- u8 sbal_last;
- u8 pool;
- u64 erp_action;
- union {
- struct {
- u64 scsi_cmnd;
- u64 scsi_serial;
- } send_fcp;
- struct {
- u64 wwpn;
- u32 d_id;
- u32 port_handle;
- } port;
- struct {
- u64 wwpn;
- u64 fcp_lun;
- u32 port_handle;
- u32 lun_handle;
- } unit;
- struct {
- u32 d_id;
- u8 ls_code;
- } send_els;
- } data;
-} __attribute__ ((packed));
-
-struct zfcp_hba_dbf_record_status {
- u8 failed;
- u32 status_type;
- u32 status_subtype;
- struct fsf_queue_designator
- queue_designator;
- u32 payload_size;
-#define ZFCP_DBF_UNSOL_PAYLOAD 80
-#define ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL 32
-#define ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD 56
-#define ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT 2 * sizeof(u32)
- u8 payload[ZFCP_DBF_UNSOL_PAYLOAD];
-} __attribute__ ((packed));
-
-struct zfcp_hba_dbf_record_qdio {
- u32 status;
- u32 qdio_error;
- u32 siga_error;
- u8 sbal_index;
- u8 sbal_count;
-} __attribute__ ((packed));
-
-struct zfcp_hba_dbf_record {
- u8 tag[ZFCP_DBF_TAG_SIZE];
- u8 tag2[ZFCP_DBF_TAG_SIZE];
- union {
- struct zfcp_hba_dbf_record_response response;
- struct zfcp_hba_dbf_record_status status;
- struct zfcp_hba_dbf_record_qdio qdio;
- } type;
-} __attribute__ ((packed));
-
-struct zfcp_san_dbf_record_ct {
- union {
- struct {
- u16 cmd_req_code;
- u8 revision;
- u8 gs_type;
- u8 gs_subtype;
- u8 options;
- u16 max_res_size;
- } request;
- struct {
- u16 cmd_rsp_code;
- u8 revision;
- u8 reason_code;
- u8 reason_code_expl;
- u8 vendor_unique;
- } response;
- } type;
- u32 payload_size;
-#define ZFCP_DBF_CT_PAYLOAD 24
- u8 payload[ZFCP_DBF_CT_PAYLOAD];
-} __attribute__ ((packed));
-
-struct zfcp_san_dbf_record_els {
- u8 ls_code;
- u32 payload_size;
-#define ZFCP_DBF_ELS_PAYLOAD 32
-#define ZFCP_DBF_ELS_MAX_PAYLOAD 1024
- u8 payload[ZFCP_DBF_ELS_PAYLOAD];
-} __attribute__ ((packed));
-
-struct zfcp_san_dbf_record {
- u8 tag[ZFCP_DBF_TAG_SIZE];
- u64 fsf_reqid;
- u32 fsf_seqno;
- u32 s_id;
- u32 d_id;
- union {
- struct zfcp_san_dbf_record_ct ct;
- struct zfcp_san_dbf_record_els els;
- } type;
-} __attribute__ ((packed));
-
-struct zfcp_scsi_dbf_record {
- u8 tag[ZFCP_DBF_TAG_SIZE];
- u8 tag2[ZFCP_DBF_TAG_SIZE];
- u32 scsi_id;
- u32 scsi_lun;
- u32 scsi_result;
- u64 scsi_cmnd;
- u64 scsi_serial;
-#define ZFCP_DBF_SCSI_OPCODE 16
- u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE];
- u8 scsi_retries;
- u8 scsi_allowed;
- u64 fsf_reqid;
- u32 fsf_seqno;
- u64 fsf_issued;
- union {
- struct {
- u64 fsf_reqid;
- u32 fsf_seqno;
- u64 fsf_issued;
- } new_fsf_req;
- struct {
- u8 rsp_validity;
- u8 rsp_scsi_status;
- u32 rsp_resid;
- u8 rsp_code;
-#define ZFCP_DBF_SCSI_FCP_SNS_INFO 16
-#define ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO 256
- u32 sns_info_len;
- u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO];
- } fcp;
- } type;
-} __attribute__ ((packed));
-
/*
* FC-FS stuff
*/
@@ -508,6 +339,34 @@ struct zfcp_rc_entry {
*/
#define ZFCP_CT_TIMEOUT (3 * R_A_TOV)
+
+/***************** S390 DEBUG FEATURE SPECIFIC DEFINES ***********************/
+
+/* debug feature entries per adapter */
+#define ZFCP_ERP_DBF_INDEX 1
+#define ZFCP_ERP_DBF_AREAS 2
+#define ZFCP_ERP_DBF_LENGTH 16
+#define ZFCP_ERP_DBF_LEVEL 3
+#define ZFCP_ERP_DBF_NAME "zfcperp"
+
+#define ZFCP_CMD_DBF_INDEX 2
+#define ZFCP_CMD_DBF_AREAS 1
+#define ZFCP_CMD_DBF_LENGTH 8
+#define ZFCP_CMD_DBF_LEVEL 3
+#define ZFCP_CMD_DBF_NAME "zfcpcmd"
+
+#define ZFCP_ABORT_DBF_INDEX 2
+#define ZFCP_ABORT_DBF_AREAS 1
+#define ZFCP_ABORT_DBF_LENGTH 8
+#define ZFCP_ABORT_DBF_LEVEL 6
+#define ZFCP_ABORT_DBF_NAME "zfcpabt"
+
+#define ZFCP_IN_ELS_DBF_INDEX 2
+#define ZFCP_IN_ELS_DBF_AREAS 1
+#define ZFCP_IN_ELS_DBF_LENGTH 8
+#define ZFCP_IN_ELS_DBF_LEVEL 6
+#define ZFCP_IN_ELS_DBF_NAME "zfcpels"
+
/******************** LOGGING MACROS AND DEFINES *****************************/
/*
@@ -642,7 +501,6 @@ do { \
#define ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL 0x00000080
#define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100
#define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200
-#define ZFCP_STATUS_ADAPTER_XPORT_OK 0x00000800
#define ZFCP_STATUS_ADAPTER_SCSI_UP \
(ZFCP_STATUS_COMMON_UNBLOCKED | \
@@ -777,6 +635,45 @@ struct zfcp_adapter_mempool {
mempool_t *data_gid_pn;
};
+struct zfcp_exchange_config_data{
+};
+
+struct zfcp_open_port {
+ struct zfcp_port *port;
+};
+
+struct zfcp_close_port {
+ struct zfcp_port *port;
+};
+
+struct zfcp_open_unit {
+ struct zfcp_unit *unit;
+};
+
+struct zfcp_close_unit {
+ struct zfcp_unit *unit;
+};
+
+struct zfcp_close_physical_port {
+ struct zfcp_port *port;
+};
+
+struct zfcp_send_fcp_command_task {
+ struct zfcp_fsf_req *fsf_req;
+ struct zfcp_unit *unit;
+ struct scsi_cmnd *scsi_cmnd;
+ unsigned long start_jiffies;
+};
+
+struct zfcp_send_fcp_command_task_management {
+ struct zfcp_unit *unit;
+};
+
+struct zfcp_abort_fcp_command {
+ struct zfcp_fsf_req *fsf_req;
+ struct zfcp_unit *unit;
+};
+
/*
* header for CT_IU
*/
@@ -805,7 +702,7 @@ struct ct_iu_gid_pn_req {
/* FS_ACC IU and data unit for GID_PN nameserver request */
struct ct_iu_gid_pn_resp {
struct ct_hdr header;
- u32 d_id;
+ fc_id_t d_id;
} __attribute__ ((packed));
typedef void (*zfcp_send_ct_handler_t)(unsigned long);
@@ -871,7 +768,7 @@ typedef void (*zfcp_send_els_handler_t)(unsigned long);
struct zfcp_send_els {
struct zfcp_adapter *adapter;
struct zfcp_port *port;
- u32 d_id;
+ fc_id_t d_id;
struct scatterlist *req;
struct scatterlist *resp;
unsigned int req_count;
@@ -884,6 +781,33 @@ struct zfcp_send_els {
int status;
};
+struct zfcp_status_read {
+ struct fsf_status_read_buffer *buffer;
+};
+
+struct zfcp_fsf_done {
+ struct completion *complete;
+ int status;
+};
+
+/* request specific data */
+union zfcp_req_data {
+ struct zfcp_exchange_config_data exchange_config_data;
+ struct zfcp_open_port open_port;
+ struct zfcp_close_port close_port;
+ struct zfcp_open_unit open_unit;
+ struct zfcp_close_unit close_unit;
+ struct zfcp_close_physical_port close_physical_port;
+ struct zfcp_send_fcp_command_task send_fcp_command_task;
+ struct zfcp_send_fcp_command_task_management
+ send_fcp_command_task_management;
+ struct zfcp_abort_fcp_command abort_fcp_command;
+ struct zfcp_send_ct *send_ct;
+ struct zfcp_send_els *send_els;
+ struct zfcp_status_read status_read;
+ struct fsf_qtcb_bottom_port *port_data;
+};
+
struct zfcp_qdio_queue {
struct qdio_buffer *buffer[QDIO_MAX_BUFFERS_PER_Q]; /* SBALs */
u8 free_index; /* index of next free bfr
@@ -914,19 +838,21 @@ struct zfcp_adapter {
atomic_t refcount; /* reference count */
wait_queue_head_t remove_wq; /* can be used to wait for
refcount drop to zero */
+ wwn_t wwnn; /* WWNN */
+ wwn_t wwpn; /* WWPN */
+ fc_id_t s_id; /* N_Port ID */
wwn_t peer_wwnn; /* P2P peer WWNN */
wwn_t peer_wwpn; /* P2P peer WWPN */
- u32 peer_d_id; /* P2P peer D_ID */
- wwn_t physical_wwpn; /* WWPN of physical port */
- u32 physical_s_id; /* local FC port ID */
+ fc_id_t peer_d_id; /* P2P peer D_ID */
struct ccw_device *ccw_device; /* S/390 ccw device */
u8 fc_service_class;
u32 fc_topology; /* FC topology */
+ u32 fc_link_speed; /* FC interface speed */
u32 hydra_version; /* Hydra version */
u32 fsf_lic_version;
- u32 adapter_features; /* FCP channel features */
- u32 connection_features; /* host connection features */
+ u32 supported_features;/* of FCP channel */
u32 hardware_version; /* of FCP channel */
+ u8 serial_number[32]; /* of hardware */
struct Scsi_Host *scsi_host; /* Pointer to mid-layer */
unsigned short scsi_host_no; /* Assigned host number */
unsigned char name[9];
@@ -963,18 +889,11 @@ struct zfcp_adapter {
u32 erp_low_mem_count; /* nr of erp actions waiting
for memory */
struct zfcp_port *nameserver_port; /* adapter's nameserver */
- debug_info_t *erp_dbf;
- debug_info_t *hba_dbf;
- debug_info_t *san_dbf; /* debug feature areas */
- debug_info_t *scsi_dbf;
- spinlock_t erp_dbf_lock;
- spinlock_t hba_dbf_lock;
- spinlock_t san_dbf_lock;
- spinlock_t scsi_dbf_lock;
- struct zfcp_erp_dbf_record erp_dbf_buf;
- struct zfcp_hba_dbf_record hba_dbf_buf;
- struct zfcp_san_dbf_record san_dbf_buf;
- struct zfcp_scsi_dbf_record scsi_dbf_buf;
+ debug_info_t *erp_dbf; /* S/390 debug features */
+ debug_info_t *abort_dbf;
+ debug_info_t *in_els_dbf;
+ debug_info_t *cmd_dbf;
+ spinlock_t dbf_lock;
struct zfcp_adapter_mempool pool; /* Adapter memory pools */
struct qdio_initialize qdio_init_data; /* for qdio_establish */
struct device generic_services; /* directory for WKA ports */
@@ -1000,7 +919,7 @@ struct zfcp_port {
atomic_t status; /* status of this remote port */
wwn_t wwnn; /* WWNN if known */
wwn_t wwpn; /* WWPN */
- u32 d_id; /* D_ID */
+ fc_id_t d_id; /* D_ID */
u32 handle; /* handle assigned by FSF */
struct zfcp_erp_action erp_action; /* pending error recovery */
atomic_t erp_counter;
@@ -1044,13 +963,11 @@ struct zfcp_fsf_req {
u32 fsf_command; /* FSF Command copy */
struct fsf_qtcb *qtcb; /* address of associated QTCB */
u32 seq_no; /* Sequence number of request */
- unsigned long data; /* private data of request */
+ union zfcp_req_data data; /* Info fields of request */
struct zfcp_erp_action *erp_action; /* used if this request is
issued on behalf of erp */
mempool_t *pool; /* used if request was alloacted
from emergency pool */
- unsigned long long issued; /* request sent time (STCK) */
- struct zfcp_unit *unit;
};
typedef void zfcp_fsf_req_handler_t(struct zfcp_fsf_req*);
diff --git a/trunk/drivers/s390/scsi/zfcp_erp.c b/trunk/drivers/s390/scsi/zfcp_erp.c
index 023f4e558ae4..cb4f612550ba 100644
--- a/trunk/drivers/s390/scsi/zfcp_erp.c
+++ b/trunk/drivers/s390/scsi/zfcp_erp.c
@@ -82,7 +82,6 @@ static int zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *);
static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *);
static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *);
static int zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *);
-static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *);
static int zfcp_erp_adapter_strategy_open_fsf_statusread(
struct zfcp_erp_action *);
@@ -346,13 +345,13 @@ zfcp_erp_adisc(struct zfcp_port *port)
/* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports
without FC-AL-2 capability, so we don't set it */
- adisc->wwpn = fc_host_port_name(adapter->scsi_host);
- adisc->wwnn = fc_host_node_name(adapter->scsi_host);
- adisc->nport_id = fc_host_port_id(adapter->scsi_host);
+ adisc->wwpn = adapter->wwpn;
+ adisc->wwnn = adapter->wwnn;
+ adisc->nport_id = adapter->s_id;
ZFCP_LOG_INFO("ADISC request from s_id 0x%08x to d_id 0x%08x "
"(wwpn=0x%016Lx, wwnn=0x%016Lx, "
"hard_nport_id=0x%08x, nport_id=0x%08x)\n",
- adisc->nport_id, send_els->d_id, (wwn_t) adisc->wwpn,
+ adapter->s_id, send_els->d_id, (wwn_t) adisc->wwpn,
(wwn_t) adisc->wwnn, adisc->hard_nport_id,
adisc->nport_id);
@@ -405,7 +404,7 @@ zfcp_erp_adisc_handler(unsigned long data)
struct zfcp_send_els *send_els;
struct zfcp_port *port;
struct zfcp_adapter *adapter;
- u32 d_id;
+ fc_id_t d_id;
struct zfcp_ls_adisc_acc *adisc;
send_els = (struct zfcp_send_els *) data;
@@ -436,9 +435,9 @@ zfcp_erp_adisc_handler(unsigned long data)
ZFCP_LOG_INFO("ADISC response from d_id 0x%08x to s_id "
"0x%08x (wwpn=0x%016Lx, wwnn=0x%016Lx, "
"hard_nport_id=0x%08x, nport_id=0x%08x)\n",
- d_id, fc_host_port_id(adapter->scsi_host),
- (wwn_t) adisc->wwpn, (wwn_t) adisc->wwnn,
- adisc->hard_nport_id, adisc->nport_id);
+ d_id, adapter->s_id, (wwn_t) adisc->wwpn,
+ (wwn_t) adisc->wwnn, adisc->hard_nport_id,
+ adisc->nport_id);
/* set wwnn for port */
if (port->wwnn == 0)
@@ -887,7 +886,7 @@ static int
zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
{
int retval = 0;
- struct zfcp_fsf_req *fsf_req = NULL;
+ struct zfcp_fsf_req *fsf_req;
struct zfcp_adapter *adapter = erp_action->adapter;
if (erp_action->fsf_req) {
@@ -897,7 +896,7 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
list_for_each_entry(fsf_req, &adapter->fsf_req_list_head, list)
if (fsf_req == erp_action->fsf_req)
break;
- if (fsf_req && (fsf_req->erp_action == erp_action)) {
+ if (fsf_req == erp_action->fsf_req) {
/* fsf_req still exists */
debug_text_event(adapter->erp_dbf, 3, "a_ca_req");
debug_event(adapter->erp_dbf, 3, &fsf_req,
@@ -2259,21 +2258,16 @@ zfcp_erp_adapter_strategy_close_qdio(struct zfcp_erp_action *erp_action)
static int
zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action)
{
- int xconfig, xport;
-
- if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
- &erp_action->adapter->status)) {
- zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);
- atomic_set(&erp_action->adapter->erp_counter, 0);
- return ZFCP_ERP_FAILED;
- }
+ int retval;
- xconfig = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action);
- xport = zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);
- if ((xconfig == ZFCP_ERP_FAILED) || (xport == ZFCP_ERP_FAILED))
- return ZFCP_ERP_FAILED;
+ /* do 'exchange configuration data' */
+ retval = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action);
+ if (retval == ZFCP_ERP_FAILED)
+ return retval;
- return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action);
+ /* start the desired number of Status Reads */
+ retval = zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action);
+ return retval;
}
/*
@@ -2297,9 +2291,7 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
&adapter->status);
ZFCP_LOG_DEBUG("Doing exchange config data\n");
- write_lock(&adapter->erp_lock);
zfcp_erp_action_to_running(erp_action);
- write_unlock(&adapter->erp_lock);
zfcp_erp_timeout_init(erp_action);
if (zfcp_fsf_exchange_config_data(erp_action)) {
retval = ZFCP_ERP_FAILED;
@@ -2356,76 +2348,6 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
return retval;
}
-static int
-zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)
-{
- int retval = ZFCP_ERP_SUCCEEDED;
- int retries;
- int sleep;
- struct zfcp_adapter *adapter = erp_action->adapter;
-
- atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
-
- for (retries = 0; ; retries++) {
- ZFCP_LOG_DEBUG("Doing exchange port data\n");
- zfcp_erp_action_to_running(erp_action);
- zfcp_erp_timeout_init(erp_action);
- if (zfcp_fsf_exchange_port_data(erp_action, adapter, NULL)) {
- retval = ZFCP_ERP_FAILED;
- debug_text_event(adapter->erp_dbf, 5, "a_fstx_xf");
- ZFCP_LOG_INFO("error: initiation of exchange of "
- "port data failed for adapter %s\n",
- zfcp_get_busid_by_adapter(adapter));
- break;
- }
- debug_text_event(adapter->erp_dbf, 6, "a_fstx_xok");
- ZFCP_LOG_DEBUG("Xchange underway\n");
-
- /*
- * Why this works:
- * Both the normal completion handler as well as the timeout
- * handler will do an 'up' when the 'exchange port data'
- * request completes or times out. Thus, the signal to go on
- * won't be lost utilizing this semaphore.
- * Furthermore, this 'adapter_reopen' action is
- * guaranteed to be the only action being there (highest action
- * which prevents other actions from being created).
- * Resulting from that, the wake signal recognized here
- * _must_ be the one belonging to the 'exchange port
- * data' request.
- */
- down(&adapter->erp_ready_sem);
- if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
- ZFCP_LOG_INFO("error: exchange of port data "
- "for adapter %s timed out\n",
- zfcp_get_busid_by_adapter(adapter));
- break;
- }
-
- if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
- &adapter->status))
- break;
-
- ZFCP_LOG_DEBUG("host connection still initialising... "
- "waiting and retrying...\n");
- /* sleep a little bit before retry */
- sleep = retries < ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES ?
- ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP :
- ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP;
- msleep(jiffies_to_msecs(sleep));
- }
-
- if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
- &adapter->status)) {
- ZFCP_LOG_INFO("error: exchange of port data for "
- "adapter %s failed\n",
- zfcp_get_busid_by_adapter(adapter));
- retval = ZFCP_ERP_FAILED;
- }
-
- return retval;
-}
-
/*
* function:
*
@@ -3272,19 +3194,11 @@ zfcp_erp_action_enqueue(int action,
/* fall through !!! */
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
- if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
- &port->status)) {
- if (port->erp_action.action !=
- ZFCP_ERP_ACTION_REOPEN_PORT_FORCED) {
- ZFCP_LOG_INFO("dropped erp action %i (port "
- "0x%016Lx, action in use: %i)\n",
- action, port->wwpn,
- port->erp_action.action);
- debug_text_event(adapter->erp_dbf, 4,
- "pf_actenq_drp");
- } else
- debug_text_event(adapter->erp_dbf, 4,
- "pf_actenq_drpcp");
+ if (atomic_test_mask
+ (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)
+ && port->erp_action.action ==
+ ZFCP_ERP_ACTION_REOPEN_PORT_FORCED) {
+ debug_text_event(adapter->erp_dbf, 4, "pf_actenq_drp");
debug_event(adapter->erp_dbf, 4, &port->wwpn,
sizeof (wwn_t));
goto out;
@@ -3675,9 +3589,6 @@ zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter)
struct zfcp_port *port;
unsigned long flags;
- if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
- return;
-
debug_text_event(adapter->erp_dbf, 3, "a_access_recover");
debug_event(adapter->erp_dbf, 3, &adapter->name, 8);
diff --git a/trunk/drivers/s390/scsi/zfcp_ext.h b/trunk/drivers/s390/scsi/zfcp_ext.h
index c3782261cb5c..cd98a2de9f8f 100644
--- a/trunk/drivers/s390/scsi/zfcp_ext.h
+++ b/trunk/drivers/s390/scsi/zfcp_ext.h
@@ -96,8 +96,7 @@ extern int zfcp_fsf_open_unit(struct zfcp_erp_action *);
extern int zfcp_fsf_close_unit(struct zfcp_erp_action *);
extern int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *);
-extern int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *,
- struct zfcp_adapter *,
+extern int zfcp_fsf_exchange_port_data(struct zfcp_adapter *,
struct fsf_qtcb_bottom_port *);
extern int zfcp_fsf_control_file(struct zfcp_adapter *, struct zfcp_fsf_req **,
u32, u32, struct zfcp_sg_list *);
@@ -110,6 +109,7 @@ extern int zfcp_fsf_req_create(struct zfcp_adapter *, u32, int, mempool_t *,
extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *,
struct zfcp_erp_action *);
extern int zfcp_fsf_send_els(struct zfcp_send_els *);
+extern int zfcp_fsf_req_wait_and_cleanup(struct zfcp_fsf_req *, int, u32 *);
extern int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *,
struct zfcp_unit *,
struct scsi_cmnd *,
@@ -182,25 +182,9 @@ extern void zfcp_erp_port_access_changed(struct zfcp_port *);
extern void zfcp_erp_unit_access_changed(struct zfcp_unit *);
/******************************** AUX ****************************************/
-extern void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *);
-extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *,
- struct fsf_status_read_buffer *);
-extern void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *,
- unsigned int, unsigned int, unsigned int,
- int, int);
-
-extern void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *);
-extern void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *);
-extern void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *);
-extern void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *);
-extern void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *);
-
-extern void zfcp_scsi_dbf_event_result(const char *, int, struct zfcp_adapter *,
- struct scsi_cmnd *);
-extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *,
- struct scsi_cmnd *,
- struct zfcp_fsf_req *);
-extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *,
- struct scsi_cmnd *);
-
+extern void zfcp_cmd_dbf_event_fsf(const char *, struct zfcp_fsf_req *,
+ void *, int);
+extern void zfcp_cmd_dbf_event_scsi(const char *, struct scsi_cmnd *);
+extern void zfcp_in_els_dbf_event(struct zfcp_adapter *, const char *,
+ struct fsf_status_read_buffer *, int);
#endif /* ZFCP_EXT_H */
diff --git a/trunk/drivers/s390/scsi/zfcp_fsf.c b/trunk/drivers/s390/scsi/zfcp_fsf.c
index 3b0fc1163f5f..c007b6424e74 100644
--- a/trunk/drivers/s390/scsi/zfcp_fsf.c
+++ b/trunk/drivers/s390/scsi/zfcp_fsf.c
@@ -59,8 +59,6 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *, struct timer_list *);
static int zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *);
static int zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *);
static int zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *);
-static void zfcp_fsf_link_down_info_eval(struct zfcp_adapter *,
- struct fsf_link_down_info *);
static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *);
static void zfcp_fsf_req_dismiss(struct zfcp_fsf_req *);
@@ -287,51 +285,51 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
{
int retval = 0;
struct zfcp_adapter *adapter = fsf_req->adapter;
- struct fsf_qtcb *qtcb = fsf_req->qtcb;
- union fsf_prot_status_qual *prot_status_qual =
- &qtcb->prefix.prot_status_qual;
- zfcp_hba_dbf_event_fsf_response(fsf_req);
+ ZFCP_LOG_DEBUG("QTCB is at %p\n", fsf_req->qtcb);
if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
ZFCP_LOG_DEBUG("fsf_req 0x%lx has been dismissed\n",
(unsigned long) fsf_req);
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
ZFCP_STATUS_FSFREQ_RETRY; /* only for SCSI cmnds. */
+ zfcp_cmd_dbf_event_fsf("dismiss", fsf_req, NULL, 0);
goto skip_protstatus;
}
/* log additional information provided by FSF (if any) */
- if (unlikely(qtcb->header.log_length)) {
+ if (unlikely(fsf_req->qtcb->header.log_length)) {
/* do not trust them ;-) */
- if (qtcb->header.log_start > sizeof(struct fsf_qtcb)) {
+ if (fsf_req->qtcb->header.log_start > sizeof(struct fsf_qtcb)) {
ZFCP_LOG_NORMAL
("bug: ULP (FSF logging) log data starts "
"beyond end of packet header. Ignored. "
"(start=%i, size=%li)\n",
- qtcb->header.log_start,
+ fsf_req->qtcb->header.log_start,
sizeof(struct fsf_qtcb));
goto forget_log;
}
- if ((size_t) (qtcb->header.log_start + qtcb->header.log_length)
+ if ((size_t) (fsf_req->qtcb->header.log_start +
+ fsf_req->qtcb->header.log_length)
> sizeof(struct fsf_qtcb)) {
ZFCP_LOG_NORMAL("bug: ULP (FSF logging) log data ends "
"beyond end of packet header. Ignored. "
"(start=%i, length=%i, size=%li)\n",
- qtcb->header.log_start,
- qtcb->header.log_length,
+ fsf_req->qtcb->header.log_start,
+ fsf_req->qtcb->header.log_length,
sizeof(struct fsf_qtcb));
goto forget_log;
}
ZFCP_LOG_TRACE("ULP log data: \n");
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE,
- (char *) qtcb + qtcb->header.log_start,
- qtcb->header.log_length);
+ (char *) fsf_req->qtcb +
+ fsf_req->qtcb->header.log_start,
+ fsf_req->qtcb->header.log_length);
}
forget_log:
/* evaluate FSF Protocol Status */
- switch (qtcb->prefix.prot_status) {
+ switch (fsf_req->qtcb->prefix.prot_status) {
case FSF_PROT_GOOD:
case FSF_PROT_FSF_STATUS_PRESENTED:
@@ -342,9 +340,14 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
"microcode of version 0x%x, the device driver "
"only supports 0x%x. Aborting.\n",
zfcp_get_busid_by_adapter(adapter),
- prot_status_qual->version_error.fsf_version,
- ZFCP_QTCB_VERSION);
+ fsf_req->qtcb->prefix.prot_status_qual.
+ version_error.fsf_version, ZFCP_QTCB_VERSION);
+ /* stop operation for this adapter */
+ debug_text_exception(adapter->erp_dbf, 0, "prot_ver_err");
zfcp_erp_adapter_shutdown(adapter, 0);
+ zfcp_cmd_dbf_event_fsf("qverserr", fsf_req,
+ &fsf_req->qtcb->prefix.prot_status_qual,
+ sizeof (union fsf_prot_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -352,10 +355,16 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
ZFCP_LOG_NORMAL("bug: Sequence number mismatch between "
"driver (0x%x) and adapter %s (0x%x). "
"Restarting all operations on this adapter.\n",
- qtcb->prefix.req_seq_no,
+ fsf_req->qtcb->prefix.req_seq_no,
zfcp_get_busid_by_adapter(adapter),
- prot_status_qual->sequence_error.exp_req_seq_no);
+ fsf_req->qtcb->prefix.prot_status_qual.
+ sequence_error.exp_req_seq_no);
+ debug_text_exception(adapter->erp_dbf, 0, "prot_seq_err");
+ /* restart operation on this adapter */
zfcp_erp_adapter_reopen(adapter, 0);
+ zfcp_cmd_dbf_event_fsf("seqnoerr", fsf_req,
+ &fsf_req->qtcb->prefix.prot_status_qual,
+ sizeof (union fsf_prot_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY;
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -366,35 +375,116 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
"that used on adapter %s. "
"Stopping all operations on this adapter.\n",
zfcp_get_busid_by_adapter(adapter));
+ debug_text_exception(adapter->erp_dbf, 0, "prot_unsup_qtcb");
zfcp_erp_adapter_shutdown(adapter, 0);
+ zfcp_cmd_dbf_event_fsf("unsqtcbt", fsf_req,
+ &fsf_req->qtcb->prefix.prot_status_qual,
+ sizeof (union fsf_prot_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_PROT_HOST_CONNECTION_INITIALIZING:
+ zfcp_cmd_dbf_event_fsf("hconinit", fsf_req,
+ &fsf_req->qtcb->prefix.prot_status_qual,
+ sizeof (union fsf_prot_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
atomic_set_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
&(adapter->status));
+ debug_text_event(adapter->erp_dbf, 3, "prot_con_init");
break;
case FSF_PROT_DUPLICATE_REQUEST_ID:
+ if (fsf_req->qtcb) {
ZFCP_LOG_NORMAL("bug: The request identifier 0x%Lx "
"to the adapter %s is ambiguous. "
- "Stopping all operations on this adapter.\n",
- *(unsigned long long*)
- (&qtcb->bottom.support.req_handle),
+ "Stopping all operations on this "
+ "adapter.\n",
+ *(unsigned long long *)
+ (&fsf_req->qtcb->bottom.support.
+ req_handle),
+ zfcp_get_busid_by_adapter(adapter));
+ } else {
+ ZFCP_LOG_NORMAL("bug: The request identifier %p "
+ "to the adapter %s is ambiguous. "
+ "Stopping all operations on this "
+ "adapter. "
+ "(bug: got this for an unsolicited "
+ "status read request)\n",
+ fsf_req,
zfcp_get_busid_by_adapter(adapter));
+ }
+ debug_text_exception(adapter->erp_dbf, 0, "prot_dup_id");
zfcp_erp_adapter_shutdown(adapter, 0);
+ zfcp_cmd_dbf_event_fsf("dupreqid", fsf_req,
+ &fsf_req->qtcb->prefix.prot_status_qual,
+ sizeof (union fsf_prot_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_PROT_LINK_DOWN:
- zfcp_fsf_link_down_info_eval(adapter,
- &prot_status_qual->link_down_info);
+ /*
+ * 'test and set' is not atomic here -
+ * it's ok as long as calls to our response queue handler
+ * (and thus execution of this code here) are serialized
+ * by the qdio module
+ */
+ if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
+ &adapter->status)) {
+ switch (fsf_req->qtcb->prefix.prot_status_qual.
+ locallink_error.code) {
+ case FSF_PSQ_LINK_NOLIGHT:
+ ZFCP_LOG_INFO("The local link to adapter %s "
+ "is down (no light detected).\n",
+ zfcp_get_busid_by_adapter(
+ adapter));
+ break;
+ case FSF_PSQ_LINK_WRAPPLUG:
+ ZFCP_LOG_INFO("The local link to adapter %s "
+ "is down (wrap plug detected).\n",
+ zfcp_get_busid_by_adapter(
+ adapter));
+ break;
+ case FSF_PSQ_LINK_NOFCP:
+ ZFCP_LOG_INFO("The local link to adapter %s "
+ "is down (adjacent node on "
+ "link does not support FCP).\n",
+ zfcp_get_busid_by_adapter(
+ adapter));
+ break;
+ default:
+ ZFCP_LOG_INFO("The local link to adapter %s "
+ "is down "
+ "(warning: unknown reason "
+ "code).\n",
+ zfcp_get_busid_by_adapter(
+ adapter));
+ break;
+
+ }
+ /*
+ * Due to the 'erp failed' flag the adapter won't
+ * be recovered but will be just set to 'blocked'
+ * state. All subordinary devices will have state
+ * 'blocked' and 'erp failed', too.
+ * Thus the adapter is still able to provide
+ * 'link up' status without being flooded with
+ * requests.
+ * (note: even 'close port' is not permitted)
+ */
+ ZFCP_LOG_INFO("Stopping all operations for adapter "
+ "%s.\n",
+ zfcp_get_busid_by_adapter(adapter));
+ atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
+ ZFCP_STATUS_COMMON_ERP_FAILED,
+ &adapter->status);
+ zfcp_erp_adapter_reopen(adapter, 0);
+ }
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_PROT_REEST_QUEUE:
- ZFCP_LOG_NORMAL("The local link to adapter with "
+ debug_text_event(adapter->erp_dbf, 1, "prot_reest_queue");
+ ZFCP_LOG_INFO("The local link to adapter with "
"%s was re-plugged. "
"Re-starting operations on this adapter.\n",
zfcp_get_busid_by_adapter(adapter));
@@ -405,6 +495,9 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
zfcp_erp_adapter_reopen(adapter,
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED
| ZFCP_STATUS_COMMON_ERP_FAILED);
+ zfcp_cmd_dbf_event_fsf("reestque", fsf_req,
+ &fsf_req->qtcb->prefix.prot_status_qual,
+ sizeof (union fsf_prot_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -414,7 +507,12 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
"Restarting all operations on this "
"adapter.\n",
zfcp_get_busid_by_adapter(adapter));
+ debug_text_event(adapter->erp_dbf, 0, "prot_err_sta");
+ /* restart operation on this adapter */
zfcp_erp_adapter_reopen(adapter, 0);
+ zfcp_cmd_dbf_event_fsf("proterrs", fsf_req,
+ &fsf_req->qtcb->prefix.prot_status_qual,
+ sizeof (union fsf_prot_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY;
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -426,7 +524,11 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
"Stopping all operations on this adapter. "
"(debug info 0x%x).\n",
zfcp_get_busid_by_adapter(adapter),
- qtcb->prefix.prot_status);
+ fsf_req->qtcb->prefix.prot_status);
+ debug_text_event(adapter->erp_dbf, 0, "prot_inval:");
+ debug_exception(adapter->erp_dbf, 0,
+ &fsf_req->qtcb->prefix.prot_status,
+ sizeof (u32));
zfcp_erp_adapter_shutdown(adapter, 0);
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
}
@@ -466,18 +568,28 @@ zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *fsf_req)
"(debug info 0x%x).\n",
zfcp_get_busid_by_adapter(fsf_req->adapter),
fsf_req->qtcb->header.fsf_command);
+ debug_text_exception(fsf_req->adapter->erp_dbf, 0,
+ "fsf_s_unknown");
zfcp_erp_adapter_shutdown(fsf_req->adapter, 0);
+ zfcp_cmd_dbf_event_fsf("unknownc", fsf_req,
+ &fsf_req->qtcb->header.fsf_status_qual,
+ sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_FCP_RSP_AVAILABLE:
ZFCP_LOG_DEBUG("FCP Sense data will be presented to the "
"SCSI stack.\n");
+ debug_text_event(fsf_req->adapter->erp_dbf, 3, "fsf_s_rsp");
break;
case FSF_ADAPTER_STATUS_AVAILABLE:
+ debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_s_astatus");
zfcp_fsf_fsfstatus_qual_eval(fsf_req);
break;
+
+ default:
+ break;
}
skip_fsfstatus:
@@ -505,28 +617,44 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req)
switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) {
case FSF_SQ_FCP_RSP_AVAILABLE:
+ debug_text_event(fsf_req->adapter->erp_dbf, 4, "fsf_sq_rsp");
break;
case FSF_SQ_RETRY_IF_POSSIBLE:
/* The SCSI-stack may now issue retries or escalate */
+ debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_sq_retry");
+ zfcp_cmd_dbf_event_fsf("sqretry", fsf_req,
+ &fsf_req->qtcb->header.fsf_status_qual,
+ sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_SQ_COMMAND_ABORTED:
/* Carry the aborted state on to upper layer */
+ debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_sq_abort");
+ zfcp_cmd_dbf_event_fsf("sqabort", fsf_req,
+ &fsf_req->qtcb->header.fsf_status_qual,
+ sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTED;
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_SQ_NO_RECOM:
+ debug_text_exception(fsf_req->adapter->erp_dbf, 0,
+ "fsf_sq_no_rec");
ZFCP_LOG_NORMAL("bug: No recommendation could be given for a"
"problem on the adapter %s "
"Stopping all operations on this adapter. ",
zfcp_get_busid_by_adapter(fsf_req->adapter));
zfcp_erp_adapter_shutdown(fsf_req->adapter, 0);
+ zfcp_cmd_dbf_event_fsf("sqnrecom", fsf_req,
+ &fsf_req->qtcb->header.fsf_status_qual,
+ sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_SQ_ULP_PROGRAMMING_ERROR:
ZFCP_LOG_NORMAL("error: not enough SBALs for data transfer "
"(adapter %s)\n",
zfcp_get_busid_by_adapter(fsf_req->adapter));
+ debug_text_exception(fsf_req->adapter->erp_dbf, 0,
+ "fsf_sq_ulp_err");
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
@@ -540,6 +668,13 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req)
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
(char *) &fsf_req->qtcb->header.fsf_status_qual,
sizeof (union fsf_status_qual));
+ debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf_sq_inval:");
+ debug_exception(fsf_req->adapter->erp_dbf, 0,
+ &fsf_req->qtcb->header.fsf_status_qual.word[0],
+ sizeof (u32));
+ zfcp_cmd_dbf_event_fsf("squndef", fsf_req,
+ &fsf_req->qtcb->header.fsf_status_qual,
+ sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
}
@@ -547,110 +682,6 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req)
return retval;
}
-/**
- * zfcp_fsf_link_down_info_eval - evaluate link down information block
- */
-static void
-zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter,
- struct fsf_link_down_info *link_down)
-{
- switch (link_down->error_code) {
- case FSF_PSQ_LINK_NO_LIGHT:
- ZFCP_LOG_NORMAL("The local link to adapter %s is down "
- "(no light detected)\n",
- zfcp_get_busid_by_adapter(adapter));
- break;
- case FSF_PSQ_LINK_WRAP_PLUG:
- ZFCP_LOG_NORMAL("The local link to adapter %s is down "
- "(wrap plug detected)\n",
- zfcp_get_busid_by_adapter(adapter));
- break;
- case FSF_PSQ_LINK_NO_FCP:
- ZFCP_LOG_NORMAL("The local link to adapter %s is down "
- "(adjacent node on link does not support FCP)\n",
- zfcp_get_busid_by_adapter(adapter));
- break;
- case FSF_PSQ_LINK_FIRMWARE_UPDATE:
- ZFCP_LOG_NORMAL("The local link to adapter %s is down "
- "(firmware update in progress)\n",
- zfcp_get_busid_by_adapter(adapter));
- break;
- case FSF_PSQ_LINK_INVALID_WWPN:
- ZFCP_LOG_NORMAL("The local link to adapter %s is down "
- "(duplicate or invalid WWPN detected)\n",
- zfcp_get_busid_by_adapter(adapter));
- break;
- case FSF_PSQ_LINK_NO_NPIV_SUPPORT:
- ZFCP_LOG_NORMAL("The local link to adapter %s is down "
- "(no support for NPIV by Fabric)\n",
- zfcp_get_busid_by_adapter(adapter));
- break;
- case FSF_PSQ_LINK_NO_FCP_RESOURCES:
- ZFCP_LOG_NORMAL("The local link to adapter %s is down "
- "(out of resource in FCP daughtercard)\n",
- zfcp_get_busid_by_adapter(adapter));
- break;
- case FSF_PSQ_LINK_NO_FABRIC_RESOURCES:
- ZFCP_LOG_NORMAL("The local link to adapter %s is down "
- "(out of resource in Fabric)\n",
- zfcp_get_busid_by_adapter(adapter));
- break;
- case FSF_PSQ_LINK_FABRIC_LOGIN_UNABLE:
- ZFCP_LOG_NORMAL("The local link to adapter %s is down "
- "(unable to Fabric login)\n",
- zfcp_get_busid_by_adapter(adapter));
- break;
- case FSF_PSQ_LINK_WWPN_ASSIGNMENT_CORRUPTED:
- ZFCP_LOG_NORMAL("WWPN assignment file corrupted on adapter %s\n",
- zfcp_get_busid_by_adapter(adapter));
- break;
- case FSF_PSQ_LINK_MODE_TABLE_CURRUPTED:
- ZFCP_LOG_NORMAL("Mode table corrupted on adapter %s\n",
- zfcp_get_busid_by_adapter(adapter));
- break;
- case FSF_PSQ_LINK_NO_WWPN_ASSIGNMENT:
- ZFCP_LOG_NORMAL("No WWPN for assignment table on adapter %s\n",
- zfcp_get_busid_by_adapter(adapter));
- break;
- default:
- ZFCP_LOG_NORMAL("The local link to adapter %s is down "
- "(warning: unknown reason code %d)\n",
- zfcp_get_busid_by_adapter(adapter),
- link_down->error_code);
- }
-
- if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
- ZFCP_LOG_DEBUG("Debug information to link down: "
- "primary_status=0x%02x "
- "ioerr_code=0x%02x "
- "action_code=0x%02x "
- "reason_code=0x%02x "
- "explanation_code=0x%02x "
- "vendor_specific_code=0x%02x\n",
- link_down->primary_status,
- link_down->ioerr_code,
- link_down->action_code,
- link_down->reason_code,
- link_down->explanation_code,
- link_down->vendor_specific_code);
-
- if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
- &adapter->status)) {
- atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
- &adapter->status);
- switch (link_down->error_code) {
- case FSF_PSQ_LINK_NO_LIGHT:
- case FSF_PSQ_LINK_WRAP_PLUG:
- case FSF_PSQ_LINK_NO_FCP:
- case FSF_PSQ_LINK_FIRMWARE_UPDATE:
- zfcp_erp_adapter_reopen(adapter, 0);
- break;
- default:
- zfcp_erp_adapter_failed(adapter);
- }
- }
-}
-
/*
* function: zfcp_fsf_req_dispatch
*
@@ -665,6 +696,11 @@ zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req)
struct zfcp_adapter *adapter = fsf_req->adapter;
int retval = 0;
+ if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
+ ZFCP_LOG_TRACE("fsf_req=%p, QTCB=%p\n", fsf_req, fsf_req->qtcb);
+ ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE,
+ (char *) fsf_req->qtcb, sizeof(struct fsf_qtcb));
+ }
switch (fsf_req->fsf_command) {
@@ -724,13 +760,13 @@ zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req)
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
ZFCP_LOG_NORMAL("bug: Command issued by the device driver is "
"not supported by the adapter %s\n",
- zfcp_get_busid_by_adapter(adapter));
+ zfcp_get_busid_by_adapter(fsf_req->adapter));
if (fsf_req->fsf_command != fsf_req->qtcb->header.fsf_command)
ZFCP_LOG_NORMAL
("bug: Command issued by the device driver differs "
"from the command returned by the adapter %s "
"(debug info 0x%x, 0x%x).\n",
- zfcp_get_busid_by_adapter(adapter),
+ zfcp_get_busid_by_adapter(fsf_req->adapter),
fsf_req->fsf_command,
fsf_req->qtcb->header.fsf_command);
}
@@ -738,6 +774,8 @@ zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req)
if (!erp_action)
return retval;
+ debug_text_event(adapter->erp_dbf, 3, "a_frh");
+ debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int));
zfcp_erp_async_handler(erp_action, 0);
return retval;
@@ -783,7 +821,7 @@ zfcp_fsf_status_read(struct zfcp_adapter *adapter, int req_flags)
goto failed_buf;
}
memset(status_buffer, 0, sizeof (struct fsf_status_read_buffer));
- fsf_req->data = (unsigned long) status_buffer;
+ fsf_req->data.status_read.buffer = status_buffer;
/* insert pointer to respective buffer */
sbale = zfcp_qdio_sbale_curr(fsf_req);
@@ -808,7 +846,6 @@ zfcp_fsf_status_read(struct zfcp_adapter *adapter, int req_flags)
failed_buf:
zfcp_fsf_req_free(fsf_req);
failed_req_create:
- zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL);
out:
write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags);
return retval;
@@ -822,7 +859,7 @@ zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req)
struct zfcp_port *port;
unsigned long flags;
- status_buffer = (struct fsf_status_read_buffer *) fsf_req->data;
+ status_buffer = fsf_req->data.status_read.buffer;
adapter = fsf_req->adapter;
read_lock_irqsave(&zfcp_data.config_lock, flags);
@@ -881,33 +918,38 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
int retval = 0;
struct zfcp_adapter *adapter = fsf_req->adapter;
struct fsf_status_read_buffer *status_buffer =
- (struct fsf_status_read_buffer *) fsf_req->data;
+ fsf_req->data.status_read.buffer;
if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) {
- zfcp_hba_dbf_event_fsf_unsol("dism", adapter, status_buffer);
mempool_free(status_buffer, adapter->pool.data_status_read);
zfcp_fsf_req_free(fsf_req);
goto out;
}
- zfcp_hba_dbf_event_fsf_unsol("read", adapter, status_buffer);
-
switch (status_buffer->status_type) {
case FSF_STATUS_READ_PORT_CLOSED:
+ debug_text_event(adapter->erp_dbf, 3, "unsol_pclosed:");
+ debug_event(adapter->erp_dbf, 3,
+ &status_buffer->d_id, sizeof (u32));
zfcp_fsf_status_read_port_closed(fsf_req);
break;
case FSF_STATUS_READ_INCOMING_ELS:
+ debug_text_event(adapter->erp_dbf, 3, "unsol_els:");
zfcp_fsf_incoming_els(fsf_req);
break;
case FSF_STATUS_READ_SENSE_DATA_AVAIL:
+ debug_text_event(adapter->erp_dbf, 3, "unsol_sense:");
ZFCP_LOG_INFO("unsolicited sense data received (adapter %s)\n",
zfcp_get_busid_by_adapter(adapter));
+ ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, (char *) status_buffer,
+ sizeof(struct fsf_status_read_buffer));
break;
case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:
+ debug_text_event(adapter->erp_dbf, 3, "unsol_bit_err:");
ZFCP_LOG_NORMAL("Bit error threshold data received:\n");
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
(char *) status_buffer,
@@ -915,32 +957,17 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
break;
case FSF_STATUS_READ_LINK_DOWN:
- switch (status_buffer->status_subtype) {
- case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
- ZFCP_LOG_INFO("Physical link to adapter %s is down\n",
- zfcp_get_busid_by_adapter(adapter));
- break;
- case FSF_STATUS_READ_SUB_FDISC_FAILED:
- ZFCP_LOG_INFO("Local link to adapter %s is down "
- "due to failed FDISC login\n",
+ debug_text_event(adapter->erp_dbf, 0, "unsol_link_down:");
+ ZFCP_LOG_INFO("Local link to adapter %s is down\n",
zfcp_get_busid_by_adapter(adapter));
- break;
- case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE:
- ZFCP_LOG_INFO("Local link to adapter %s is down "
- "due to firmware update on adapter\n",
- zfcp_get_busid_by_adapter(adapter));
- break;
- default:
- ZFCP_LOG_INFO("Local link to adapter %s is down "
- "due to unknown reason\n",
- zfcp_get_busid_by_adapter(adapter));
- };
- zfcp_fsf_link_down_info_eval(adapter,
- (struct fsf_link_down_info *) &status_buffer->payload);
+ atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
+ &adapter->status);
+ zfcp_erp_adapter_failed(adapter);
break;
case FSF_STATUS_READ_LINK_UP:
- ZFCP_LOG_NORMAL("Local link to adapter %s was replugged. "
+ debug_text_event(adapter->erp_dbf, 2, "unsol_link_up:");
+ ZFCP_LOG_INFO("Local link to adapter %s was replugged. "
"Restarting operations on this adapter\n",
zfcp_get_busid_by_adapter(adapter));
/* All ports should be marked as ready to run again */
@@ -953,40 +980,35 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
break;
case FSF_STATUS_READ_CFDC_UPDATED:
- ZFCP_LOG_NORMAL("CFDC has been updated on the adapter %s\n",
+ debug_text_event(adapter->erp_dbf, 2, "unsol_cfdc_update:");
+ ZFCP_LOG_INFO("CFDC has been updated on the adapter %s\n",
zfcp_get_busid_by_adapter(adapter));
zfcp_erp_adapter_access_changed(adapter);
break;
case FSF_STATUS_READ_CFDC_HARDENED:
+ debug_text_event(adapter->erp_dbf, 2, "unsol_cfdc_harden:");
switch (status_buffer->status_subtype) {
case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE:
- ZFCP_LOG_NORMAL("CFDC of adapter %s saved on SE\n",
+ ZFCP_LOG_INFO("CFDC of adapter %s saved on SE\n",
zfcp_get_busid_by_adapter(adapter));
break;
case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2:
- ZFCP_LOG_NORMAL("CFDC of adapter %s has been copied "
+ ZFCP_LOG_INFO("CFDC of adapter %s has been copied "
"to the secondary SE\n",
zfcp_get_busid_by_adapter(adapter));
break;
default:
- ZFCP_LOG_NORMAL("CFDC of adapter %s has been hardened\n",
+ ZFCP_LOG_INFO("CFDC of adapter %s has been hardened\n",
zfcp_get_busid_by_adapter(adapter));
}
break;
- case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:
- debug_text_event(adapter->erp_dbf, 2, "unsol_features:");
- ZFCP_LOG_INFO("List of supported features on adapter %s has "
- "been changed from 0x%08X to 0x%08X\n",
- zfcp_get_busid_by_adapter(adapter),
- *(u32*) (status_buffer->payload + 4),
- *(u32*) (status_buffer->payload));
- adapter->adapter_features = *(u32*) status_buffer->payload;
- break;
-
default:
- ZFCP_LOG_NORMAL("warning: An unsolicited status packet of unknown "
+ debug_text_event(adapter->erp_dbf, 0, "unsol_unknown:");
+ debug_exception(adapter->erp_dbf, 0,
+ &status_buffer->status_type, sizeof (u32));
+ ZFCP_LOG_NORMAL("bug: An unsolicited status packet of unknown "
"type was received (debug info 0x%x)\n",
status_buffer->status_type);
ZFCP_LOG_DEBUG("Dump of status_read_buffer %p:\n",
@@ -1071,7 +1093,7 @@ zfcp_fsf_abort_fcp_command(unsigned long old_req_id,
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
- fsf_req->data = (unsigned long) unit;
+ fsf_req->data.abort_fcp_command.unit = unit;
/* set handles of unit and its parent port in QTCB */
fsf_req->qtcb->header.lun_handle = unit->handle;
@@ -1117,7 +1139,7 @@ static int
zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
{
int retval = -EINVAL;
- struct zfcp_unit *unit;
+ struct zfcp_unit *unit = new_fsf_req->data.abort_fcp_command.unit;
unsigned char status_qual =
new_fsf_req->qtcb->header.fsf_status_qual.word[0];
@@ -1128,8 +1150,6 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
goto skip_fsfstatus;
}
- unit = (struct zfcp_unit *) new_fsf_req->data;
-
/* evaluate FSF status in QTCB */
switch (new_fsf_req->qtcb->header.fsf_status) {
@@ -1344,7 +1364,7 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
sbale[3].addr = zfcp_sg_to_address(&ct->resp[0]);
sbale[3].length = ct->resp[0].length;
sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY;
- } else if (adapter->adapter_features &
+ } else if (adapter->supported_features &
FSF_FEATURE_ELS_CT_CHAINED_SBALS) {
/* try to use chained SBALs */
bytes = zfcp_qdio_sbals_from_sg(fsf_req,
@@ -1394,9 +1414,7 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
fsf_req->qtcb->header.port_handle = port->handle;
fsf_req->qtcb->bottom.support.service_class = adapter->fc_service_class;
fsf_req->qtcb->bottom.support.timeout = ct->timeout;
- fsf_req->data = (unsigned long) ct;
-
- zfcp_san_dbf_event_ct_request(fsf_req);
+ fsf_req->data.send_ct = ct;
/* start QDIO request for this FSF request */
ret = zfcp_fsf_req_send(fsf_req, ct->timer);
@@ -1427,10 +1445,10 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
* zfcp_fsf_send_ct_handler - handler for Generic Service requests
* @fsf_req: pointer to struct zfcp_fsf_req
*
- * Data specific for the Generic Service request is passed using
- * fsf_req->data. There we find the pointer to struct zfcp_send_ct.
- * Usually a specific handler for the CT request is called which is
- * found in this structure.
+ * Data specific for the Generic Service request is passed by
+ * fsf_req->data.send_ct
+ * Usually a specific handler for the request is called via
+ * fsf_req->data.send_ct->handler at end of this function.
*/
static int
zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
@@ -1444,7 +1462,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
u16 subtable, rule, counter;
adapter = fsf_req->adapter;
- send_ct = (struct zfcp_send_ct *) fsf_req->data;
+ send_ct = fsf_req->data.send_ct;
port = send_ct->port;
header = &fsf_req->qtcb->header;
bottom = &fsf_req->qtcb->bottom.support;
@@ -1456,7 +1474,6 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
switch (header->fsf_status) {
case FSF_GOOD:
- zfcp_san_dbf_event_ct_response(fsf_req);
retval = 0;
break;
@@ -1617,7 +1634,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els)
{
volatile struct qdio_buffer_element *sbale;
struct zfcp_fsf_req *fsf_req;
- u32 d_id;
+ fc_id_t d_id;
struct zfcp_adapter *adapter;
unsigned long lock_flags;
int bytes;
@@ -1647,7 +1664,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els)
sbale[3].addr = zfcp_sg_to_address(&els->resp[0]);
sbale[3].length = els->resp[0].length;
sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY;
- } else if (adapter->adapter_features &
+ } else if (adapter->supported_features &
FSF_FEATURE_ELS_CT_CHAINED_SBALS) {
/* try to use chained SBALs */
bytes = zfcp_qdio_sbals_from_sg(fsf_req,
@@ -1697,12 +1714,10 @@ zfcp_fsf_send_els(struct zfcp_send_els *els)
fsf_req->qtcb->bottom.support.d_id = d_id;
fsf_req->qtcb->bottom.support.service_class = adapter->fc_service_class;
fsf_req->qtcb->bottom.support.timeout = ZFCP_ELS_TIMEOUT;
- fsf_req->data = (unsigned long) els;
+ fsf_req->data.send_els = els;
sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
- zfcp_san_dbf_event_els_request(fsf_req);
-
/* start QDIO request for this FSF request */
ret = zfcp_fsf_req_send(fsf_req, els->timer);
if (ret) {
@@ -1731,23 +1746,23 @@ zfcp_fsf_send_els(struct zfcp_send_els *els)
* zfcp_fsf_send_els_handler - handler for ELS commands
* @fsf_req: pointer to struct zfcp_fsf_req
*
- * Data specific for the ELS command is passed using
- * fsf_req->data. There we find the pointer to struct zfcp_send_els.
- * Usually a specific handler for the ELS command is called which is
- * found in this structure.
+ * Data specific for the ELS command is passed by
+ * fsf_req->data.send_els
+ * Usually a specific handler for the command is called via
+ * fsf_req->data.send_els->handler at end of this function.
*/
static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req)
{
struct zfcp_adapter *adapter;
struct zfcp_port *port;
- u32 d_id;
+ fc_id_t d_id;
struct fsf_qtcb_header *header;
struct fsf_qtcb_bottom_support *bottom;
struct zfcp_send_els *send_els;
int retval = -EINVAL;
u16 subtable, rule, counter;
- send_els = (struct zfcp_send_els *) fsf_req->data;
+ send_els = fsf_req->data.send_els;
adapter = send_els->adapter;
port = send_els->port;
d_id = send_els->d_id;
@@ -1760,7 +1775,6 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req)
switch (header->fsf_status) {
case FSF_GOOD:
- zfcp_san_dbf_event_els_response(fsf_req);
retval = 0;
break;
@@ -1940,9 +1954,7 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
erp_action->fsf_req->erp_action = erp_action;
erp_action->fsf_req->qtcb->bottom.config.feature_selection =
- FSF_FEATURE_CFDC |
- FSF_FEATURE_LUN_SHARING |
- FSF_FEATURE_UPDATE_ALERT;
+ (FSF_FEATURE_CFDC | FSF_FEATURE_LUN_SHARING);
/* start QDIO request for this FSF request */
retval = zfcp_fsf_req_send(erp_action->fsf_req, &erp_action->timer);
@@ -1978,36 +1990,29 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
{
struct fsf_qtcb_bottom_config *bottom;
struct zfcp_adapter *adapter = fsf_req->adapter;
- struct Scsi_Host *shost = adapter->scsi_host;
bottom = &fsf_req->qtcb->bottom.config;
ZFCP_LOG_DEBUG("low/high QTCB version 0x%x/0x%x of FSF\n",
bottom->low_qtcb_version, bottom->high_qtcb_version);
adapter->fsf_lic_version = bottom->lic_version;
- adapter->adapter_features = bottom->adapter_features;
- adapter->connection_features = bottom->connection_features;
+ adapter->supported_features = bottom->supported_features;
adapter->peer_wwpn = 0;
adapter->peer_wwnn = 0;
adapter->peer_d_id = 0;
if (xchg_ok) {
- fc_host_node_name(shost) = bottom->nport_serv_param.wwnn;
- fc_host_port_name(shost) = bottom->nport_serv_param.wwpn;
- fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK;
- fc_host_speed(shost) = bottom->fc_link_speed;
- fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
+ adapter->wwnn = bottom->nport_serv_param.wwnn;
+ adapter->wwpn = bottom->nport_serv_param.wwpn;
+ adapter->s_id = bottom->s_id & ZFCP_DID_MASK;
adapter->fc_topology = bottom->fc_topology;
+ adapter->fc_link_speed = bottom->fc_link_speed;
adapter->hydra_version = bottom->adapter_type;
- if (adapter->physical_wwpn == 0)
- adapter->physical_wwpn = fc_host_port_name(shost);
- if (adapter->physical_s_id == 0)
- adapter->physical_s_id = fc_host_port_id(shost);
} else {
- fc_host_node_name(shost) = 0;
- fc_host_port_name(shost) = 0;
- fc_host_port_id(shost) = 0;
- fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
+ adapter->wwnn = 0;
+ adapter->wwpn = 0;
+ adapter->s_id = 0;
adapter->fc_topology = 0;
+ adapter->fc_link_speed = 0;
adapter->hydra_version = 0;
}
@@ -2017,28 +2022,26 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
adapter->peer_wwnn = bottom->plogi_payload.wwnn;
}
- if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) {
+ if(adapter->supported_features & FSF_FEATURE_HBAAPI_MANAGEMENT){
adapter->hardware_version = bottom->hardware_version;
- memcpy(fc_host_serial_number(shost), bottom->serial_number,
- min(FC_SERIAL_NUMBER_SIZE, 17));
- EBCASC(fc_host_serial_number(shost),
- min(FC_SERIAL_NUMBER_SIZE, 17));
+ memcpy(adapter->serial_number, bottom->serial_number, 17);
+ EBCASC(adapter->serial_number, sizeof(adapter->serial_number));
}
ZFCP_LOG_NORMAL("The adapter %s reported the following characteristics:\n"
- "WWNN 0x%016Lx, "
- "WWPN 0x%016Lx, "
- "S_ID 0x%08x,\n"
- "adapter version 0x%x, "
- "LIC version 0x%x, "
- "FC link speed %d Gb/s\n",
- zfcp_get_busid_by_adapter(adapter),
- (wwn_t) fc_host_node_name(shost),
- (wwn_t) fc_host_port_name(shost),
- fc_host_port_id(shost),
- adapter->hydra_version,
- adapter->fsf_lic_version,
- fc_host_speed(shost));
+ "WWNN 0x%016Lx, "
+ "WWPN 0x%016Lx, "
+ "S_ID 0x%08x,\n"
+ "adapter version 0x%x, "
+ "LIC version 0x%x, "
+ "FC link speed %d Gb/s\n",
+ zfcp_get_busid_by_adapter(adapter),
+ adapter->wwnn,
+ adapter->wwpn,
+ (unsigned int) adapter->s_id,
+ adapter->hydra_version,
+ adapter->fsf_lic_version,
+ adapter->fc_link_speed);
if (ZFCP_QTCB_VERSION < bottom->low_qtcb_version) {
ZFCP_LOG_NORMAL("error: the adapter %s "
"only supports newer control block "
@@ -2059,6 +2062,7 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
zfcp_erp_adapter_shutdown(adapter, 0);
return -EIO;
}
+ zfcp_set_fc_host_attrs(adapter);
return 0;
}
@@ -2074,12 +2078,11 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
{
struct fsf_qtcb_bottom_config *bottom;
struct zfcp_adapter *adapter = fsf_req->adapter;
- struct fsf_qtcb *qtcb = fsf_req->qtcb;
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
return -EIO;
- switch (qtcb->header.fsf_status) {
+ switch (fsf_req->qtcb->header.fsf_status) {
case FSF_GOOD:
if (zfcp_fsf_exchange_config_evaluate(fsf_req, 1))
@@ -2109,7 +2112,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
zfcp_erp_adapter_shutdown(adapter, 0);
return -EIO;
case FSF_TOPO_FABRIC:
- ZFCP_LOG_NORMAL("Switched fabric fibrechannel "
+ ZFCP_LOG_INFO("Switched fabric fibrechannel "
"network detected at adapter %s.\n",
zfcp_get_busid_by_adapter(adapter));
break;
@@ -2127,7 +2130,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
zfcp_erp_adapter_shutdown(adapter, 0);
return -EIO;
}
- bottom = &qtcb->bottom.config;
+ bottom = &fsf_req->qtcb->bottom.config;
if (bottom->max_qtcb_size < sizeof(struct fsf_qtcb)) {
ZFCP_LOG_NORMAL("bug: Maximum QTCB size (%d bytes) "
"allowed by the adapter %s "
@@ -2152,10 +2155,12 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0))
return -EIO;
- atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status);
-
- zfcp_fsf_link_down_info_eval(adapter,
- &qtcb->header.fsf_status_qual.link_down_info);
+ ZFCP_LOG_INFO("Local link to adapter %s is down\n",
+ zfcp_get_busid_by_adapter(adapter));
+ atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK |
+ ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
+ &adapter->status);
+ zfcp_erp_adapter_failed(adapter);
break;
default:
debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf-stat-ng");
@@ -2169,13 +2174,11 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
/**
* zfcp_fsf_exchange_port_data - request information about local port
- * @erp_action: ERP action for the adapter for which port data is requested
* @adapter: for which port data is requested
* @data: response to exchange port data request
*/
int
-zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
- struct zfcp_adapter *adapter,
+zfcp_fsf_exchange_port_data(struct zfcp_adapter *adapter,
struct fsf_qtcb_bottom_port *data)
{
volatile struct qdio_buffer_element *sbale;
@@ -2184,7 +2187,7 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
struct zfcp_fsf_req *fsf_req;
struct timer_list *timer;
- if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) {
+ if(!(adapter->supported_features & FSF_FEATURE_HBAAPI_MANAGEMENT)){
ZFCP_LOG_INFO("error: exchange port data "
"command not supported by adapter %s\n",
zfcp_get_busid_by_adapter(adapter));
@@ -2208,18 +2211,12 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
goto out;
}
- if (erp_action) {
- erp_action->fsf_req = fsf_req;
- fsf_req->erp_action = erp_action;
- }
-
- if (data)
- fsf_req->data = (unsigned long) data;
-
sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
+ fsf_req->data.port_data = data;
+
init_timer(timer);
timer->function = zfcp_fsf_request_timeout_handler;
timer->data = (unsigned long) adapter;
@@ -2231,8 +2228,6 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
"command on the adapter %s\n",
zfcp_get_busid_by_adapter(adapter));
zfcp_fsf_req_free(fsf_req);
- if (erp_action)
- erp_action->fsf_req = NULL;
write_unlock_irqrestore(&adapter->request_queue.queue_lock,
lock_flags);
goto out;
@@ -2261,42 +2256,21 @@ zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action,
static void
zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req)
{
- struct zfcp_adapter *adapter = fsf_req->adapter;
- struct Scsi_Host *shost = adapter->scsi_host;
- struct fsf_qtcb *qtcb = fsf_req->qtcb;
- struct fsf_qtcb_bottom_port *bottom, *data;
+ struct fsf_qtcb_bottom_port *bottom;
+ struct fsf_qtcb_bottom_port *data = fsf_req->data.port_data;
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
return;
- switch (qtcb->header.fsf_status) {
+ switch (fsf_req->qtcb->header.fsf_status) {
case FSF_GOOD:
- atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
-
- bottom = &qtcb->bottom.port;
- data = (struct fsf_qtcb_bottom_port*) fsf_req->data;
- if (data)
- memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port));
- if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) {
- adapter->physical_wwpn = bottom->wwpn;
- adapter->physical_s_id = bottom->fc_port_id;
- } else {
- adapter->physical_wwpn = fc_host_port_name(shost);
- adapter->physical_s_id = fc_host_port_id(shost);
- }
- fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
- break;
-
- case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
- atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
-
- zfcp_fsf_link_down_info_eval(adapter,
- &qtcb->header.fsf_status_qual.link_down_info);
+ bottom = &fsf_req->qtcb->bottom.port;
+ memcpy(data, bottom, sizeof(*data));
break;
default:
- debug_text_event(adapter->erp_dbf, 0, "xchg-port-ng");
- debug_event(adapter->erp_dbf, 0,
+ debug_text_event(fsf_req->adapter->erp_dbf, 0, "xchg-port-ng");
+ debug_event(fsf_req->adapter->erp_dbf, 0,
&fsf_req->qtcb->header.fsf_status, sizeof(u32));
}
}
@@ -2338,7 +2312,7 @@ zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
erp_action->fsf_req->qtcb->bottom.support.d_id = erp_action->port->d_id;
atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->port->status);
- erp_action->fsf_req->data = (unsigned long) erp_action->port;
+ erp_action->fsf_req->data.open_port.port = erp_action->port;
erp_action->fsf_req->erp_action = erp_action;
/* start QDIO request for this FSF request */
@@ -2379,7 +2353,7 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
struct fsf_qtcb_header *header;
u16 subtable, rule, counter;
- port = (struct zfcp_port *) fsf_req->data;
+ port = fsf_req->data.open_port.port;
header = &fsf_req->qtcb->header;
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
@@ -2592,7 +2566,7 @@ zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->port->status);
- erp_action->fsf_req->data = (unsigned long) erp_action->port;
+ erp_action->fsf_req->data.close_port.port = erp_action->port;
erp_action->fsf_req->erp_action = erp_action;
erp_action->fsf_req->qtcb->header.port_handle =
erp_action->port->handle;
@@ -2632,7 +2606,7 @@ zfcp_fsf_close_port_handler(struct zfcp_fsf_req *fsf_req)
int retval = -EINVAL;
struct zfcp_port *port;
- port = (struct zfcp_port *) fsf_req->data;
+ port = fsf_req->data.close_port.port;
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
/* don't change port status in our bookkeeping */
@@ -2729,8 +2703,8 @@ zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
atomic_set_mask(ZFCP_STATUS_PORT_PHYS_CLOSING,
&erp_action->port->status);
/* save a pointer to this port */
- erp_action->fsf_req->data = (unsigned long) erp_action->port;
- /* port to be closed */
+ erp_action->fsf_req->data.close_physical_port.port = erp_action->port;
+ /* port to be closeed */
erp_action->fsf_req->qtcb->header.port_handle =
erp_action->port->handle;
erp_action->fsf_req->erp_action = erp_action;
@@ -2773,7 +2747,7 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req)
struct fsf_qtcb_header *header;
u16 subtable, rule, counter;
- port = (struct zfcp_port *) fsf_req->data;
+ port = fsf_req->data.close_physical_port.port;
header = &fsf_req->qtcb->header;
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
@@ -2934,11 +2908,10 @@ zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
erp_action->port->handle;
erp_action->fsf_req->qtcb->bottom.support.fcp_lun =
erp_action->unit->fcp_lun;
- if (!(erp_action->adapter->connection_features & FSF_FEATURE_NPIV_MODE))
erp_action->fsf_req->qtcb->bottom.support.option =
FSF_OPEN_LUN_SUPPRESS_BOXING;
atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->unit->status);
- erp_action->fsf_req->data = (unsigned long) erp_action->unit;
+ erp_action->fsf_req->data.open_unit.unit = erp_action->unit;
erp_action->fsf_req->erp_action = erp_action;
/* start QDIO request for this FSF request */
@@ -2982,9 +2955,9 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
struct fsf_qtcb_bottom_support *bottom;
struct fsf_queue_designator *queue_designator;
u16 subtable, rule, counter;
- int exclusive, readwrite;
+ u32 allowed, exclusive, readwrite;
- unit = (struct zfcp_unit *) fsf_req->data;
+ unit = fsf_req->data.open_unit.unit;
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
/* don't change unit status in our bookkeeping */
@@ -2996,6 +2969,10 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
bottom = &fsf_req->qtcb->bottom.support;
queue_designator = &header->fsf_status_qual.fsf_queue_designator;
+ allowed = bottom->lun_access_info & FSF_UNIT_ACCESS_OPEN_LUN_ALLOWED;
+ exclusive = bottom->lun_access_info & FSF_UNIT_ACCESS_EXCLUSIVE;
+ readwrite = bottom->lun_access_info & FSF_UNIT_ACCESS_OUTBOUND_TRANSFER;
+
atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
ZFCP_STATUS_UNIT_SHARED |
ZFCP_STATUS_UNIT_READONLY,
@@ -3169,15 +3146,10 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
unit->handle);
/* mark unit as open */
atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status);
-
- if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE) &&
- (adapter->adapter_features & FSF_FEATURE_LUN_SHARING) &&
- (adapter->ccw_device->id.dev_model != ZFCP_DEVICE_MODEL_PRIV)) {
- exclusive = (bottom->lun_access_info &
- FSF_UNIT_ACCESS_EXCLUSIVE);
- readwrite = (bottom->lun_access_info &
- FSF_UNIT_ACCESS_OUTBOUND_TRANSFER);
-
+ atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
+ ZFCP_STATUS_COMMON_ACCESS_BOXED,
+ &unit->status);
+ if (adapter->supported_features & FSF_FEATURE_LUN_SHARING){
if (!exclusive)
atomic_set_mask(ZFCP_STATUS_UNIT_SHARED,
&unit->status);
@@ -3270,7 +3242,7 @@ zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
erp_action->port->handle;
erp_action->fsf_req->qtcb->header.lun_handle = erp_action->unit->handle;
atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->unit->status);
- erp_action->fsf_req->data = (unsigned long) erp_action->unit;
+ erp_action->fsf_req->data.close_unit.unit = erp_action->unit;
erp_action->fsf_req->erp_action = erp_action;
/* start QDIO request for this FSF request */
@@ -3309,7 +3281,7 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req)
int retval = -EINVAL;
struct zfcp_unit *unit;
- unit = (struct zfcp_unit *) fsf_req->data;
+ unit = fsf_req->data.close_unit.unit; /* restore unit */
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
/* don't change unit status in our bookkeeping */
@@ -3333,6 +3305,9 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req)
debug_text_event(fsf_req->adapter->erp_dbf, 1,
"fsf_s_phand_nv");
zfcp_erp_adapter_reopen(unit->port->adapter, 0);
+ zfcp_cmd_dbf_event_fsf("porthinv", fsf_req,
+ &fsf_req->qtcb->header.fsf_status_qual,
+ sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -3351,6 +3326,9 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req)
debug_text_event(fsf_req->adapter->erp_dbf, 1,
"fsf_s_lhand_nv");
zfcp_erp_port_reopen(unit->port, 0);
+ zfcp_cmd_dbf_event_fsf("lunhinv", fsf_req,
+ &fsf_req->qtcb->header.fsf_status_qual,
+ sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -3458,14 +3436,21 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
goto failed_req_create;
}
- zfcp_unit_get(unit);
- fsf_req->unit = unit;
-
- /* associate FSF request with SCSI request (for look up on abort) */
- scsi_cmnd->host_scribble = (char *) fsf_req;
+ /*
+ * associate FSF request with SCSI request
+ * (need this for look up on abort)
+ */
+ fsf_req->data.send_fcp_command_task.fsf_req = fsf_req;
+ scsi_cmnd->host_scribble = (char *) &(fsf_req->data);
- /* associate SCSI command with FSF request */
- fsf_req->data = (unsigned long) scsi_cmnd;
+ /*
+ * associate SCSI command with FSF request
+ * (need this for look up on normal command completion)
+ */
+ fsf_req->data.send_fcp_command_task.scsi_cmnd = scsi_cmnd;
+ fsf_req->data.send_fcp_command_task.start_jiffies = jiffies;
+ fsf_req->data.send_fcp_command_task.unit = unit;
+ ZFCP_LOG_DEBUG("unit=%p, fcp_lun=0x%016Lx\n", unit, unit->fcp_lun);
/* set handles of unit and its parent port in QTCB */
fsf_req->qtcb->header.lun_handle = unit->handle;
@@ -3599,7 +3584,6 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
send_failed:
no_fit:
failed_scsi_cmnd:
- zfcp_unit_put(unit);
zfcp_fsf_req_free(fsf_req);
fsf_req = NULL;
scsi_cmnd->host_scribble = NULL;
@@ -3656,7 +3640,7 @@ zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter,
* hold a pointer to the unit being target of this
* task management request
*/
- fsf_req->data = (unsigned long) unit;
+ fsf_req->data.send_fcp_command_task_management.unit = unit;
/* set FSF related fields in QTCB */
fsf_req->qtcb->header.lun_handle = unit->handle;
@@ -3722,9 +3706,9 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
header = &fsf_req->qtcb->header;
if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT))
- unit = (struct zfcp_unit *) fsf_req->data;
+ unit = fsf_req->data.send_fcp_command_task_management.unit;
else
- unit = fsf_req->unit;
+ unit = fsf_req->data.send_fcp_command_task.unit;
if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
/* go directly to calls of special handlers */
@@ -3781,6 +3765,10 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
debug_text_event(fsf_req->adapter->erp_dbf, 1,
"fsf_s_hand_mis");
zfcp_erp_adapter_reopen(unit->port->adapter, 0);
+ zfcp_cmd_dbf_event_fsf("handmism",
+ fsf_req,
+ &header->fsf_status_qual,
+ sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -3801,6 +3789,10 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
debug_text_exception(fsf_req->adapter->erp_dbf, 0,
"fsf_s_class_nsup");
zfcp_erp_adapter_shutdown(unit->port->adapter, 0);
+ zfcp_cmd_dbf_event_fsf("unsclass",
+ fsf_req,
+ &header->fsf_status_qual,
+ sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -3819,6 +3811,10 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
debug_text_event(fsf_req->adapter->erp_dbf, 1,
"fsf_s_fcp_lun_nv");
zfcp_erp_port_reopen(unit->port, 0);
+ zfcp_cmd_dbf_event_fsf("fluninv",
+ fsf_req,
+ &header->fsf_status_qual,
+ sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -3857,6 +3853,10 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
debug_text_event(fsf_req->adapter->erp_dbf, 0,
"fsf_s_dir_ind_nv");
zfcp_erp_adapter_shutdown(unit->port->adapter, 0);
+ zfcp_cmd_dbf_event_fsf("dirinv",
+ fsf_req,
+ &header->fsf_status_qual,
+ sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -3872,6 +3872,10 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
debug_text_event(fsf_req->adapter->erp_dbf, 0,
"fsf_s_cmd_len_nv");
zfcp_erp_adapter_shutdown(unit->port->adapter, 0);
+ zfcp_cmd_dbf_event_fsf("cleninv",
+ fsf_req,
+ &header->fsf_status_qual,
+ sizeof (union fsf_status_qual));
fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break;
@@ -3943,8 +3947,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
zfcp_fsf_send_fcp_command_task_management_handler(fsf_req);
} else {
retval = zfcp_fsf_send_fcp_command_task_handler(fsf_req);
- fsf_req->unit = NULL;
- zfcp_unit_put(unit);
}
return retval;
}
@@ -3968,10 +3970,10 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
u32 sns_len;
char *fcp_rsp_info = zfcp_get_fcp_rsp_info_ptr(fcp_rsp_iu);
unsigned long flags;
- struct zfcp_unit *unit = fsf_req->unit;
+ struct zfcp_unit *unit = fsf_req->data.send_fcp_command_task.unit;
read_lock_irqsave(&fsf_req->adapter->abort_lock, flags);
- scpnt = (struct scsi_cmnd *) fsf_req->data;
+ scpnt = fsf_req->data.send_fcp_command_task.scsi_cmnd;
if (unlikely(!scpnt)) {
ZFCP_LOG_DEBUG
("Command with fsf_req %p is not associated to "
@@ -4041,6 +4043,7 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
(char *) &fsf_req->qtcb->
bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE);
+ zfcp_cmd_dbf_event_fsf("clenmis", fsf_req, NULL, 0);
set_host_byte(&scpnt->result, DID_ERROR);
goto skip_fsfstatus;
case RSP_CODE_FIELD_INVALID:
@@ -4059,6 +4062,7 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
(char *) &fsf_req->qtcb->
bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE);
set_host_byte(&scpnt->result, DID_ERROR);
+ zfcp_cmd_dbf_event_fsf("codeinv", fsf_req, NULL, 0);
goto skip_fsfstatus;
case RSP_CODE_RO_MISMATCH:
/* hardware bug */
@@ -4075,6 +4079,7 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
(char *) &fsf_req->qtcb->
bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE);
+ zfcp_cmd_dbf_event_fsf("codemism", fsf_req, NULL, 0);
set_host_byte(&scpnt->result, DID_ERROR);
goto skip_fsfstatus;
default:
@@ -4091,6 +4096,7 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
(char *) &fsf_req->qtcb->
bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE);
+ zfcp_cmd_dbf_event_fsf("undeffcp", fsf_req, NULL, 0);
set_host_byte(&scpnt->result, DID_ERROR);
goto skip_fsfstatus;
}
@@ -4152,17 +4158,19 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
skip_fsfstatus:
ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result);
- if (scpnt->result != 0)
- zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt);
- else if (scpnt->retries > 0)
- zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt);
- else
- zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt);
+ zfcp_cmd_dbf_event_scsi("response", scpnt);
/* cleanup pointer (need this especially for abort) */
scpnt->host_scribble = NULL;
+ /*
+ * NOTE:
+ * according to the outcome of a discussion on linux-scsi we
+ * don't need to grab the io_request_lock here since we use
+ * the new eh
+ */
/* always call back */
+
(scpnt->scsi_done) (scpnt);
/*
@@ -4190,7 +4198,8 @@ zfcp_fsf_send_fcp_command_task_management_handler(struct zfcp_fsf_req *fsf_req)
struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *)
&(fsf_req->qtcb->bottom.io.fcp_rsp);
char *fcp_rsp_info = zfcp_get_fcp_rsp_info_ptr(fcp_rsp_iu);
- struct zfcp_unit *unit = (struct zfcp_unit *) fsf_req->data;
+ struct zfcp_unit *unit =
+ fsf_req->data.send_fcp_command_task_management.unit;
del_timer(&fsf_req->adapter->scsi_er_timer);
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) {
@@ -4267,7 +4276,7 @@ zfcp_fsf_control_file(struct zfcp_adapter *adapter,
int direction;
int retval = 0;
- if (!(adapter->adapter_features & FSF_FEATURE_CFDC)) {
+ if (!(adapter->supported_features & FSF_FEATURE_CFDC)) {
ZFCP_LOG_INFO("cfdc not supported (adapter %s)\n",
zfcp_get_busid_by_adapter(adapter));
retval = -EOPNOTSUPP;
@@ -4540,6 +4549,52 @@ zfcp_fsf_control_file_handler(struct zfcp_fsf_req *fsf_req)
return retval;
}
+
+/*
+ * function: zfcp_fsf_req_wait_and_cleanup
+ *
+ * purpose:
+ *
+ * FIXME(design): signal seems to be <0 !!!
+ * returns: 0 - request completed (*status is valid), cleanup succ.
+ * <0 - request completed (*status is valid), cleanup failed
+ * >0 - signal which interrupted waiting (*status invalid),
+ * request not completed, no cleanup
+ *
+ * *status is a copy of status of completed fsf_req
+ */
+int
+zfcp_fsf_req_wait_and_cleanup(struct zfcp_fsf_req *fsf_req,
+ int interruptible, u32 * status)
+{
+ int retval = 0;
+ int signal = 0;
+
+ if (interruptible) {
+ __wait_event_interruptible(fsf_req->completion_wq,
+ fsf_req->status &
+ ZFCP_STATUS_FSFREQ_COMPLETED,
+ signal);
+ if (signal) {
+ ZFCP_LOG_DEBUG("Caught signal %i while waiting for the "
+ "completion of the request at %p\n",
+ signal, fsf_req);
+ retval = signal;
+ goto out;
+ }
+ } else {
+ __wait_event(fsf_req->completion_wq,
+ fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
+ }
+
+ *status = fsf_req->status;
+
+ /* cleanup request */
+ zfcp_fsf_req_free(fsf_req);
+ out:
+ return retval;
+}
+
static inline int
zfcp_fsf_req_sbal_check(unsigned long *flags,
struct zfcp_qdio_queue *queue, int needed)
@@ -4555,16 +4610,15 @@ zfcp_fsf_req_sbal_check(unsigned long *flags,
* set qtcb pointer in fsf_req and initialize QTCB
*/
static inline void
-zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req)
+zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req, u32 fsf_cmd)
{
if (likely(fsf_req->qtcb != NULL)) {
- fsf_req->qtcb->prefix.req_seq_no = fsf_req->adapter->fsf_req_seq_no;
fsf_req->qtcb->prefix.req_id = (unsigned long)fsf_req;
fsf_req->qtcb->prefix.ulp_info = ZFCP_ULP_INFO_VERSION;
- fsf_req->qtcb->prefix.qtcb_type = fsf_qtcb_type[fsf_req->fsf_command];
+ fsf_req->qtcb->prefix.qtcb_type = fsf_qtcb_type[fsf_cmd];
fsf_req->qtcb->prefix.qtcb_version = ZFCP_QTCB_VERSION;
fsf_req->qtcb->header.req_handle = (unsigned long)fsf_req;
- fsf_req->qtcb->header.fsf_command = fsf_req->fsf_command;
+ fsf_req->qtcb->header.fsf_command = fsf_cmd;
}
}
@@ -4632,10 +4686,7 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags,
goto failed_fsf_req;
}
- fsf_req->adapter = adapter;
- fsf_req->fsf_command = fsf_cmd;
-
- zfcp_fsf_req_qtcb_init(fsf_req);
+ zfcp_fsf_req_qtcb_init(fsf_req, fsf_cmd);
/* initialize waitqueue which may be used to wait on
this request completion */
@@ -4657,10 +4708,8 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags,
goto failed_sbals;
}
- if (fsf_req->qtcb) {
- fsf_req->seq_no = adapter->fsf_req_seq_no;
- fsf_req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no;
- }
+ fsf_req->adapter = adapter; /* pointer to "parent" adapter */
+ fsf_req->fsf_command = fsf_cmd;
fsf_req->sbal_number = 1;
fsf_req->sbal_first = req_queue->free_index;
fsf_req->sbal_curr = req_queue->free_index;
@@ -4711,9 +4760,9 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
struct zfcp_adapter *adapter;
struct zfcp_qdio_queue *req_queue;
volatile struct qdio_buffer_element *sbale;
- int inc_seq_no;
int new_distance_from_int;
unsigned long flags;
+ int inc_seq_no = 1;
int retval = 0;
adapter = fsf_req->adapter;
@@ -4727,13 +4776,23 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, (char *) sbale[1].addr,
sbale[1].length);
+ /* set sequence counter in QTCB */
+ if (likely(fsf_req->qtcb)) {
+ fsf_req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no;
+ fsf_req->seq_no = adapter->fsf_req_seq_no;
+ ZFCP_LOG_TRACE("FSF request %p of adapter %s gets "
+ "FSF sequence counter value of %i\n",
+ fsf_req,
+ zfcp_get_busid_by_adapter(adapter),
+ fsf_req->qtcb->prefix.req_seq_no);
+ } else
+ inc_seq_no = 0;
+
/* put allocated FSF request at list tail */
spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
list_add_tail(&fsf_req->list, &adapter->fsf_req_list_head);
spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
- inc_seq_no = (fsf_req->qtcb != NULL);
-
/* figure out expiration time of timeout and start timeout */
if (unlikely(timer)) {
timer->expires += jiffies;
@@ -4763,8 +4822,6 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap if needed */
new_distance_from_int = zfcp_qdio_determine_pci(req_queue, fsf_req);
- fsf_req->issued = get_clock();
-
retval = do_QDIO(adapter->ccw_device,
QDIO_FLAG_SYNC_OUTPUT,
0, fsf_req->sbal_first, fsf_req->sbal_number, NULL);
@@ -4803,11 +4860,15 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer)
* routines resulting in missing sequence counter values
* otherwise,
*/
-
/* Don't increase for unsolicited status */
- if (inc_seq_no)
+ if (likely(inc_seq_no)) {
adapter->fsf_req_seq_no++;
-
+ ZFCP_LOG_TRACE
+ ("FSF sequence counter value of adapter %s "
+ "increased to %i\n",
+ zfcp_get_busid_by_adapter(adapter),
+ adapter->fsf_req_seq_no);
+ }
/* count FSF requests pending */
atomic_inc(&adapter->fsf_reqs_active);
}
diff --git a/trunk/drivers/s390/scsi/zfcp_fsf.h b/trunk/drivers/s390/scsi/zfcp_fsf.h
index 48719f055952..07140dfda2a7 100644
--- a/trunk/drivers/s390/scsi/zfcp_fsf.h
+++ b/trunk/drivers/s390/scsi/zfcp_fsf.h
@@ -116,7 +116,6 @@
#define FSF_INVALID_COMMAND_OPTION 0x000000E5
/* #define FSF_ERROR 0x000000FF */
-#define FSF_PROT_STATUS_QUAL_SIZE 16
#define FSF_STATUS_QUALIFIER_SIZE 16
/* FSF status qualifier, recommendations */
@@ -140,18 +139,9 @@
#define FSF_SQ_CFDC_SUBTABLE_LUN 0x0004
/* FSF status qualifier (most significant 4 bytes), local link down */
-#define FSF_PSQ_LINK_NO_LIGHT 0x00000004
-#define FSF_PSQ_LINK_WRAP_PLUG 0x00000008
-#define FSF_PSQ_LINK_NO_FCP 0x00000010
-#define FSF_PSQ_LINK_FIRMWARE_UPDATE 0x00000020
-#define FSF_PSQ_LINK_INVALID_WWPN 0x00000100
-#define FSF_PSQ_LINK_NO_NPIV_SUPPORT 0x00000200
-#define FSF_PSQ_LINK_NO_FCP_RESOURCES 0x00000400
-#define FSF_PSQ_LINK_NO_FABRIC_RESOURCES 0x00000800
-#define FSF_PSQ_LINK_FABRIC_LOGIN_UNABLE 0x00001000
-#define FSF_PSQ_LINK_WWPN_ASSIGNMENT_CORRUPTED 0x00002000
-#define FSF_PSQ_LINK_MODE_TABLE_CURRUPTED 0x00004000
-#define FSF_PSQ_LINK_NO_WWPN_ASSIGNMENT 0x00008000
+#define FSF_PSQ_LINK_NOLIGHT 0x00000004
+#define FSF_PSQ_LINK_WRAPPLUG 0x00000008
+#define FSF_PSQ_LINK_NOFCP 0x00000010
/* payload size in status read buffer */
#define FSF_STATUS_READ_PAYLOAD_SIZE 4032
@@ -164,21 +154,15 @@
#define FSF_STATUS_READ_INCOMING_ELS 0x00000002
#define FSF_STATUS_READ_SENSE_DATA_AVAIL 0x00000003
#define FSF_STATUS_READ_BIT_ERROR_THRESHOLD 0x00000004
-#define FSF_STATUS_READ_LINK_DOWN 0x00000005
+#define FSF_STATUS_READ_LINK_DOWN 0x00000005 /* FIXME: really? */
#define FSF_STATUS_READ_LINK_UP 0x00000006
#define FSF_STATUS_READ_CFDC_UPDATED 0x0000000A
#define FSF_STATUS_READ_CFDC_HARDENED 0x0000000B
-#define FSF_STATUS_READ_FEATURE_UPDATE_ALERT 0x0000000C
/* status subtypes in status read buffer */
#define FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT 0x00000001
#define FSF_STATUS_READ_SUB_ERROR_PORT 0x00000002
-/* status subtypes for link down */
-#define FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK 0x00000000
-#define FSF_STATUS_READ_SUB_FDISC_FAILED 0x00000001
-#define FSF_STATUS_READ_SUB_FIRMWARE_UPDATE 0x00000002
-
/* status subtypes for CFDC */
#define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE 0x00000002
#define FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2 0x0000000F
@@ -209,15 +193,11 @@
#define FSF_QTCB_LOG_SIZE 1024
/* channel features */
+#define FSF_FEATURE_QTCB_SUPPRESSION 0x00000001
#define FSF_FEATURE_CFDC 0x00000002
#define FSF_FEATURE_LUN_SHARING 0x00000004
#define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010
#define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020
-#define FSF_FEATURE_UPDATE_ALERT 0x00000100
-
-/* host connection features */
-#define FSF_FEATURE_NPIV_MODE 0x00000001
-#define FSF_FEATURE_VM_ASSIGNED_WWPN 0x00000002
/* option */
#define FSF_OPEN_LUN_SUPPRESS_BOXING 0x00000001
@@ -325,23 +305,15 @@ struct fsf_qual_sequence_error {
u32 res1[3];
} __attribute__ ((packed));
-struct fsf_link_down_info {
- u32 error_code;
- u32 res1;
- u8 res2[2];
- u8 primary_status;
- u8 ioerr_code;
- u8 action_code;
- u8 reason_code;
- u8 explanation_code;
- u8 vendor_specific_code;
+struct fsf_qual_locallink_error {
+ u32 code;
+ u32 res1[3];
} __attribute__ ((packed));
union fsf_prot_status_qual {
- u64 doubleword[FSF_PROT_STATUS_QUAL_SIZE / sizeof(u64)];
struct fsf_qual_version_error version_error;
struct fsf_qual_sequence_error sequence_error;
- struct fsf_link_down_info link_down_info;
+ struct fsf_qual_locallink_error locallink_error;
} __attribute__ ((packed));
struct fsf_qtcb_prefix {
@@ -359,9 +331,7 @@ union fsf_status_qual {
u8 byte[FSF_STATUS_QUALIFIER_SIZE];
u16 halfword[FSF_STATUS_QUALIFIER_SIZE / sizeof (u16)];
u32 word[FSF_STATUS_QUALIFIER_SIZE / sizeof (u32)];
- u64 doubleword[FSF_STATUS_QUALIFIER_SIZE / sizeof(u64)];
struct fsf_queue_designator fsf_queue_designator;
- struct fsf_link_down_info link_down_info;
} __attribute__ ((packed));
struct fsf_qtcb_header {
@@ -436,8 +406,8 @@ struct fsf_qtcb_bottom_config {
u32 low_qtcb_version;
u32 max_qtcb_size;
u32 max_data_transfer_size;
- u32 adapter_features;
- u32 connection_features;
+ u32 supported_features;
+ u8 res1[4];
u32 fc_topology;
u32 fc_link_speed;
u32 adapter_type;
@@ -455,7 +425,7 @@ struct fsf_qtcb_bottom_config {
} __attribute__ ((packed));
struct fsf_qtcb_bottom_port {
- u64 wwpn;
+ u8 res1[8];
u32 fc_port_id;
u32 port_type;
u32 port_state;
diff --git a/trunk/drivers/s390/scsi/zfcp_qdio.c b/trunk/drivers/s390/scsi/zfcp_qdio.c
index d719f66a29a4..24e16ec331d9 100644
--- a/trunk/drivers/s390/scsi/zfcp_qdio.c
+++ b/trunk/drivers/s390/scsi/zfcp_qdio.c
@@ -54,7 +54,8 @@ static inline int zfcp_qdio_sbals_from_buffer
static qdio_handler_t zfcp_qdio_request_handler;
static qdio_handler_t zfcp_qdio_response_handler;
static int zfcp_qdio_handler_error_check(struct zfcp_adapter *,
- unsigned int, unsigned int, unsigned int, int, int);
+ unsigned int,
+ unsigned int, unsigned int);
#define ZFCP_LOG_AREA ZFCP_LOG_AREA_QDIO
@@ -213,12 +214,22 @@ zfcp_qdio_allocate(struct zfcp_adapter *adapter)
*
*/
static inline int
-zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status,
- unsigned int qdio_error, unsigned int siga_error,
- int first_element, int elements_processed)
+zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter,
+ unsigned int status,
+ unsigned int qdio_error, unsigned int siga_error)
{
int retval = 0;
+ if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_TRACE)) {
+ if (status & QDIO_STATUS_INBOUND_INT) {
+ ZFCP_LOG_TRACE("status is"
+ " QDIO_STATUS_INBOUND_INT \n");
+ }
+ if (status & QDIO_STATUS_OUTBOUND_INT) {
+ ZFCP_LOG_TRACE("status is"
+ " QDIO_STATUS_OUTBOUND_INT \n");
+ }
+ }
if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) {
retval = -EIO;
@@ -226,10 +237,9 @@ zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status,
"qdio_error=0x%x, siga_error=0x%x)\n",
status, qdio_error, siga_error);
- zfcp_hba_dbf_event_qdio(adapter, status, qdio_error, siga_error,
- first_element, elements_processed);
+ /* Restarting IO on the failed adapter from scratch */
+ debug_text_event(adapter->erp_dbf, 1, "qdio_err");
/*
- * Restarting IO on the failed adapter from scratch.
* Since we have been using this adapter, it is save to assume
* that it is not failed but recoverable. The card seems to
* report link-up events by self-initiated queue shutdown.
@@ -272,8 +282,7 @@ zfcp_qdio_request_handler(struct ccw_device *ccw_device,
first_element, elements_processed);
if (unlikely(zfcp_qdio_handler_error_check(adapter, status, qdio_error,
- siga_error, first_element,
- elements_processed)))
+ siga_error)))
goto out;
/*
* we stored address of struct zfcp_adapter data structure
@@ -325,8 +334,7 @@ zfcp_qdio_response_handler(struct ccw_device *ccw_device,
queue = &adapter->response_queue;
if (unlikely(zfcp_qdio_handler_error_check(adapter, status, qdio_error,
- siga_error, first_element,
- elements_processed)))
+ siga_error)))
goto out;
/*
diff --git a/trunk/drivers/s390/scsi/zfcp_scsi.c b/trunk/drivers/s390/scsi/zfcp_scsi.c
index 3dcd1bfba3b4..31a76065cf28 100644
--- a/trunk/drivers/s390/scsi/zfcp_scsi.c
+++ b/trunk/drivers/s390/scsi/zfcp_scsi.c
@@ -44,8 +44,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *);
static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *);
static int zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *);
static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *);
-static int zfcp_task_management_function(struct zfcp_unit *, u8,
- struct scsi_cmnd *);
+static int zfcp_task_management_function(struct zfcp_unit *, u8);
static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, scsi_id_t,
scsi_lun_t);
@@ -243,10 +242,7 @@ static void
zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result)
{
set_host_byte(&scpnt->result, result);
- if ((scpnt->device != NULL) && (scpnt->device->host != NULL))
- zfcp_scsi_dbf_event_result("fail", 4,
- (struct zfcp_adapter*) scpnt->device->host->hostdata[0],
- scpnt);
+ zfcp_cmd_dbf_event_scsi("failing", scpnt);
/* return directly */
scpnt->scsi_done(scpnt);
}
@@ -418,38 +414,67 @@ zfcp_port_lookup(struct zfcp_adapter *adapter, int channel, scsi_id_t id)
return (struct zfcp_port *) NULL;
}
-/**
- * zfcp_scsi_eh_abort_handler - abort the specified SCSI command
- * @scpnt: pointer to scsi_cmnd to be aborted
- * Return: SUCCESS - command has been aborted and cleaned up in internal
- * bookkeeping, SCSI stack won't be called for aborted command
- * FAILED - otherwise
+/*
+ * function: zfcp_scsi_eh_abort_handler
+ *
+ * purpose: tries to abort the specified (timed out) SCSI command
*
- * We do not need to care for a SCSI command which completes normally
- * but late during this abort routine runs. We are allowed to return
- * late commands to the SCSI stack. It tracks the state of commands and
- * will handle late commands. (Usually, the normal completion of late
- * commands is ignored with respect to the running abort operation.)
+ * note: We do not need to care for a SCSI command which completes
+ * normally but late during this abort routine runs.
+ * We are allowed to return late commands to the SCSI stack.
+ * It tracks the state of commands and will handle late commands.
+ * (Usually, the normal completion of late commands is ignored with
+ * respect to the running abort operation. Grep for 'done_late'
+ * in the SCSI stacks sources.)
+ *
+ * returns: SUCCESS - command has been aborted and cleaned up in internal
+ * bookkeeping,
+ * SCSI stack won't be called for aborted command
+ * FAILED - otherwise
*/
int
-zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
+__zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
{
- struct Scsi_Host *scsi_host;
- struct zfcp_adapter *adapter;
- struct zfcp_unit *unit;
int retval = SUCCESS;
- struct zfcp_fsf_req *new_fsf_req = NULL;
- struct zfcp_fsf_req *old_fsf_req;
+ struct zfcp_fsf_req *new_fsf_req, *old_fsf_req;
+ struct zfcp_adapter *adapter = (struct zfcp_adapter *) scpnt->device->host->hostdata[0];
+ struct zfcp_unit *unit = (struct zfcp_unit *) scpnt->device->hostdata;
+ struct zfcp_port *port = unit->port;
+ struct Scsi_Host *scsi_host = scpnt->device->host;
+ union zfcp_req_data *req_data = NULL;
unsigned long flags;
-
- scsi_host = scpnt->device->host;
- adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
- unit = (struct zfcp_unit *) scpnt->device->hostdata;
+ u32 status = 0;
+
+ /* the components of a abort_dbf record (fixed size record) */
+ u64 dbf_scsi_cmnd = (unsigned long) scpnt;
+ char dbf_opcode[ZFCP_ABORT_DBF_LENGTH];
+ wwn_t dbf_wwn = port->wwpn;
+ fcp_lun_t dbf_fcp_lun = unit->fcp_lun;
+ u64 dbf_retries = scpnt->retries;
+ u64 dbf_allowed = scpnt->allowed;
+ u64 dbf_timeout = 0;
+ u64 dbf_fsf_req = 0;
+ u64 dbf_fsf_status = 0;
+ u64 dbf_fsf_qual[2] = { 0, 0 };
+ char dbf_result[ZFCP_ABORT_DBF_LENGTH] = "##undef";
+
+ memset(dbf_opcode, 0, ZFCP_ABORT_DBF_LENGTH);
+ memcpy(dbf_opcode,
+ scpnt->cmnd,
+ min(scpnt->cmd_len, (unsigned char) ZFCP_ABORT_DBF_LENGTH));
ZFCP_LOG_INFO("aborting scsi_cmnd=%p on adapter %s\n",
scpnt, zfcp_get_busid_by_adapter(adapter));
- /* avoid race condition between late normal completion and abort */
+ spin_unlock_irq(scsi_host->host_lock);
+
+ /*
+ * Race condition between normal (late) completion and abort has
+ * to be avoided.
+ * The entirity of all accesses to scsi_req have to be atomic.
+ * scsi_req is usually part of the fsf_req and thus we block the
+ * release of fsf_req as long as we need to access scsi_req.
+ */
write_lock_irqsave(&adapter->abort_lock, flags);
/*
@@ -459,47 +484,144 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
* this routine returns. (scpnt is parameter passed to this routine
* and must not disappear during abort even on late completion.)
*/
- old_fsf_req = (struct zfcp_fsf_req *) scpnt->host_scribble;
- if (!old_fsf_req) {
+ req_data = (union zfcp_req_data *) scpnt->host_scribble;
+ /* DEBUG */
+ ZFCP_LOG_DEBUG("req_data=%p\n", req_data);
+ if (!req_data) {
+ ZFCP_LOG_DEBUG("late command completion overtook abort\n");
+ /*
+ * That's it.
+ * Do not initiate abort but return SUCCESS.
+ */
write_unlock_irqrestore(&adapter->abort_lock, flags);
- zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, new_fsf_req);
retval = SUCCESS;
+ strncpy(dbf_result, "##late1", ZFCP_ABORT_DBF_LENGTH);
+ goto out;
+ }
+
+ /* Figure out which fsf_req needs to be aborted. */
+ old_fsf_req = req_data->send_fcp_command_task.fsf_req;
+
+ dbf_fsf_req = (unsigned long) old_fsf_req;
+ dbf_timeout =
+ (jiffies - req_data->send_fcp_command_task.start_jiffies) / HZ;
+
+ ZFCP_LOG_DEBUG("old_fsf_req=%p\n", old_fsf_req);
+ if (!old_fsf_req) {
+ write_unlock_irqrestore(&adapter->abort_lock, flags);
+ ZFCP_LOG_NORMAL("bug: no old fsf request found\n");
+ ZFCP_LOG_NORMAL("req_data:\n");
+ ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
+ (char *) req_data, sizeof (union zfcp_req_data));
+ ZFCP_LOG_NORMAL("scsi_cmnd:\n");
+ ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
+ (char *) scpnt, sizeof (struct scsi_cmnd));
+ retval = FAILED;
+ strncpy(dbf_result, "##bug:r", ZFCP_ABORT_DBF_LENGTH);
goto out;
}
- old_fsf_req->data = 0;
+ old_fsf_req->data.send_fcp_command_task.scsi_cmnd = NULL;
+ /* mark old request as being aborted */
old_fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTING;
+ /*
+ * We have to collect all information (e.g. unit) needed by
+ * zfcp_fsf_abort_fcp_command before calling that routine
+ * since that routine is not allowed to access
+ * fsf_req which it is going to abort.
+ * This is because of we need to release fsf_req_list_lock
+ * before calling zfcp_fsf_abort_fcp_command.
+ * Since this lock will not be held, fsf_req may complete
+ * late and may be released meanwhile.
+ */
+ ZFCP_LOG_DEBUG("unit 0x%016Lx (%p)\n", unit->fcp_lun, unit);
- /* don't access old_fsf_req after releasing the abort_lock */
+ /*
+ * We block (call schedule)
+ * That's why we must release the lock and enable the
+ * interrupts before.
+ * On the other hand we do not need the lock anymore since
+ * all critical accesses to scsi_req are done.
+ */
write_unlock_irqrestore(&adapter->abort_lock, flags);
/* call FSF routine which does the abort */
new_fsf_req = zfcp_fsf_abort_fcp_command((unsigned long) old_fsf_req,
adapter, unit, 0);
+ ZFCP_LOG_DEBUG("new_fsf_req=%p\n", new_fsf_req);
if (!new_fsf_req) {
- ZFCP_LOG_INFO("error: initiation of Abort FCP Cmnd failed\n");
retval = FAILED;
+ ZFCP_LOG_NORMAL("error: initiation of Abort FCP Cmnd "
+ "failed\n");
+ strncpy(dbf_result, "##nores", ZFCP_ABORT_DBF_LENGTH);
goto out;
}
/* wait for completion of abort */
+ ZFCP_LOG_DEBUG("waiting for cleanup...\n");
+#if 1
+ /*
+ * FIXME:
+ * copying zfcp_fsf_req_wait_and_cleanup code is not really nice
+ */
__wait_event(new_fsf_req->completion_wq,
new_fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
-
+ status = new_fsf_req->status;
+ dbf_fsf_status = new_fsf_req->qtcb->header.fsf_status;
+ /*
+ * Ralphs special debug load provides timestamps in the FSF
+ * status qualifier. This might be specified later if being
+ * useful for debugging aborts.
+ */
+ dbf_fsf_qual[0] =
+ *(u64 *) & new_fsf_req->qtcb->header.fsf_status_qual.word[0];
+ dbf_fsf_qual[1] =
+ *(u64 *) & new_fsf_req->qtcb->header.fsf_status_qual.word[2];
+ zfcp_fsf_req_free(new_fsf_req);
+#else
+ retval = zfcp_fsf_req_wait_and_cleanup(new_fsf_req,
+ ZFCP_UNINTERRUPTIBLE, &status);
+#endif
+ ZFCP_LOG_DEBUG("Waiting for cleanup complete, status=0x%x\n", status);
/* status should be valid since signals were not permitted */
- if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) {
- zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, new_fsf_req);
+ if (status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) {
retval = SUCCESS;
- } else if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) {
- zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, new_fsf_req);
+ strncpy(dbf_result, "##succ", ZFCP_ABORT_DBF_LENGTH);
+ } else if (status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) {
retval = SUCCESS;
+ strncpy(dbf_result, "##late2", ZFCP_ABORT_DBF_LENGTH);
} else {
- zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, new_fsf_req);
retval = FAILED;
+ strncpy(dbf_result, "##fail", ZFCP_ABORT_DBF_LENGTH);
}
- zfcp_fsf_req_free(new_fsf_req);
+
out:
+ debug_event(adapter->abort_dbf, 1, &dbf_scsi_cmnd, sizeof (u64));
+ debug_event(adapter->abort_dbf, 1, &dbf_opcode, ZFCP_ABORT_DBF_LENGTH);
+ debug_event(adapter->abort_dbf, 1, &dbf_wwn, sizeof (wwn_t));
+ debug_event(adapter->abort_dbf, 1, &dbf_fcp_lun, sizeof (fcp_lun_t));
+ debug_event(adapter->abort_dbf, 1, &dbf_retries, sizeof (u64));
+ debug_event(adapter->abort_dbf, 1, &dbf_allowed, sizeof (u64));
+ debug_event(adapter->abort_dbf, 1, &dbf_timeout, sizeof (u64));
+ debug_event(adapter->abort_dbf, 1, &dbf_fsf_req, sizeof (u64));
+ debug_event(adapter->abort_dbf, 1, &dbf_fsf_status, sizeof (u64));
+ debug_event(adapter->abort_dbf, 1, &dbf_fsf_qual[0], sizeof (u64));
+ debug_event(adapter->abort_dbf, 1, &dbf_fsf_qual[1], sizeof (u64));
+ debug_text_event(adapter->abort_dbf, 1, dbf_result);
+
+ spin_lock_irq(scsi_host->host_lock);
return retval;
}
+int
+zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
+{
+ int rc;
+ struct Scsi_Host *scsi_host = scpnt->device->host;
+ spin_lock_irq(scsi_host->host_lock);
+ rc = __zfcp_scsi_eh_abort_handler(scpnt);
+ spin_unlock_irq(scsi_host->host_lock);
+ return rc;
+}
+
/*
* function: zfcp_scsi_eh_device_reset_handler
*
@@ -529,9 +651,8 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
*/
if (!atomic_test_mask(ZFCP_STATUS_UNIT_NOTSUPPUNITRESET,
&unit->status)) {
- retval = zfcp_task_management_function(unit,
- FCP_LOGICAL_UNIT_RESET,
- scpnt);
+ retval =
+ zfcp_task_management_function(unit, FCP_LOGICAL_UNIT_RESET);
if (retval) {
ZFCP_LOG_DEBUG("unit reset failed (unit=%p)\n", unit);
if (retval == -ENOTSUPP)
@@ -547,7 +668,7 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
goto out;
}
}
- retval = zfcp_task_management_function(unit, FCP_TARGET_RESET, scpnt);
+ retval = zfcp_task_management_function(unit, FCP_TARGET_RESET);
if (retval) {
ZFCP_LOG_DEBUG("target reset failed (unit=%p)\n", unit);
retval = FAILED;
@@ -560,12 +681,12 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
}
static int
-zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags,
- struct scsi_cmnd *scpnt)
+zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags)
{
struct zfcp_adapter *adapter = unit->port->adapter;
+ int retval;
+ int status;
struct zfcp_fsf_req *fsf_req;
- int retval = 0;
/* issue task management function */
fsf_req = zfcp_fsf_send_fcp_command_task_management
@@ -575,63 +696,70 @@ zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags,
"failed for unit 0x%016Lx on port 0x%016Lx on "
"adapter %s\n", unit->fcp_lun, unit->port->wwpn,
zfcp_get_busid_by_adapter(adapter));
- zfcp_scsi_dbf_event_devreset("nres", tm_flags, unit, scpnt);
retval = -ENOMEM;
goto out;
}
- __wait_event(fsf_req->completion_wq,
- fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
-
+ retval = zfcp_fsf_req_wait_and_cleanup(fsf_req,
+ ZFCP_UNINTERRUPTIBLE, &status);
/*
* check completion status of task management function
+ * (status should always be valid since no signals permitted)
*/
- if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {
- zfcp_scsi_dbf_event_devreset("fail", tm_flags, unit, scpnt);
+ if (status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED)
retval = -EIO;
- } else if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP) {
- zfcp_scsi_dbf_event_devreset("nsup", tm_flags, unit, scpnt);
+ else if (status & ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP)
retval = -ENOTSUPP;
- } else
- zfcp_scsi_dbf_event_devreset("okay", tm_flags, unit, scpnt);
-
- zfcp_fsf_req_free(fsf_req);
+ else
+ retval = 0;
out:
return retval;
}
-/**
- * zfcp_scsi_eh_bus_reset_handler - reset bus (reopen adapter)
+/*
+ * function: zfcp_scsi_eh_bus_reset_handler
+ *
+ * purpose:
+ *
+ * returns:
*/
int
zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *scpnt)
{
- struct zfcp_unit *unit = (struct zfcp_unit*) scpnt->device->hostdata;
- struct zfcp_adapter *adapter = unit->port->adapter;
+ int retval = 0;
+ struct zfcp_unit *unit;
+ unit = (struct zfcp_unit *) scpnt->device->hostdata;
ZFCP_LOG_NORMAL("bus reset because of problems with "
"unit 0x%016Lx\n", unit->fcp_lun);
- zfcp_erp_adapter_reopen(adapter, 0);
- zfcp_erp_wait(adapter);
+ zfcp_erp_adapter_reopen(unit->port->adapter, 0);
+ zfcp_erp_wait(unit->port->adapter);
+ retval = SUCCESS;
- return SUCCESS;
+ return retval;
}
-/**
- * zfcp_scsi_eh_host_reset_handler - reset host (reopen adapter)
+/*
+ * function: zfcp_scsi_eh_host_reset_handler
+ *
+ * purpose:
+ *
+ * returns:
*/
int
zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
{
- struct zfcp_unit *unit = (struct zfcp_unit*) scpnt->device->hostdata;
- struct zfcp_adapter *adapter = unit->port->adapter;
+ int retval = 0;
+ struct zfcp_unit *unit;
+ unit = (struct zfcp_unit *) scpnt->device->hostdata;
ZFCP_LOG_NORMAL("host reset because of problems with "
"unit 0x%016Lx\n", unit->fcp_lun);
- zfcp_erp_adapter_reopen(adapter, 0);
- zfcp_erp_wait(adapter);
+ zfcp_erp_adapter_reopen(unit->port->adapter, 0);
+ zfcp_erp_wait(unit->port->adapter);
+ retval = SUCCESS;
- return SUCCESS;
+ return retval;
}
/*
@@ -698,16 +826,10 @@ void
zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter)
{
struct Scsi_Host *shost;
- struct zfcp_port *port;
shost = adapter->scsi_host;
if (!shost)
return;
- read_lock_irq(&zfcp_data.config_lock);
- list_for_each_entry(port, &adapter->port_list_head, list)
- if (port->rport)
- port->rport = NULL;
- read_unlock_irq(&zfcp_data.config_lock);
fc_remove_host(shost);
scsi_remove_host(shost);
scsi_host_put(shost);
@@ -782,6 +904,18 @@ zfcp_get_node_name(struct scsi_target *starget)
read_unlock_irqrestore(&zfcp_data.config_lock, flags);
}
+void
+zfcp_set_fc_host_attrs(struct zfcp_adapter *adapter)
+{
+ struct Scsi_Host *shost = adapter->scsi_host;
+
+ fc_host_node_name(shost) = adapter->wwnn;
+ fc_host_port_name(shost) = adapter->wwpn;
+ strncpy(fc_host_serial_number(shost), adapter->serial_number,
+ min(FC_SERIAL_NUMBER_SIZE, 32));
+ fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
+}
+
struct fc_function_template zfcp_transport_functions = {
.get_starget_port_id = zfcp_get_port_id,
.get_starget_port_name = zfcp_get_port_name,
@@ -793,10 +927,7 @@ struct fc_function_template zfcp_transport_functions = {
.show_host_node_name = 1,
.show_host_port_name = 1,
.show_host_supported_classes = 1,
- .show_host_maxframe_size = 1,
.show_host_serial_number = 1,
- .show_host_speed = 1,
- .show_host_port_id = 1,
};
/**
diff --git a/trunk/drivers/s390/scsi/zfcp_sysfs_adapter.c b/trunk/drivers/s390/scsi/zfcp_sysfs_adapter.c
index 0cd435280e7d..e7345a74800a 100644
--- a/trunk/drivers/s390/scsi/zfcp_sysfs_adapter.c
+++ b/trunk/drivers/s390/scsi/zfcp_sysfs_adapter.c
@@ -62,18 +62,21 @@ static ssize_t zfcp_sysfs_adapter_##_name##_show(struct device *dev, struct devi
static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_adapter_##_name##_show, NULL);
ZFCP_DEFINE_ADAPTER_ATTR(status, "0x%08x\n", atomic_read(&adapter->status));
+ZFCP_DEFINE_ADAPTER_ATTR(wwnn, "0x%016llx\n", adapter->wwnn);
+ZFCP_DEFINE_ADAPTER_ATTR(wwpn, "0x%016llx\n", adapter->wwpn);
+ZFCP_DEFINE_ADAPTER_ATTR(s_id, "0x%06x\n", adapter->s_id);
ZFCP_DEFINE_ADAPTER_ATTR(peer_wwnn, "0x%016llx\n", adapter->peer_wwnn);
ZFCP_DEFINE_ADAPTER_ATTR(peer_wwpn, "0x%016llx\n", adapter->peer_wwpn);
ZFCP_DEFINE_ADAPTER_ATTR(peer_d_id, "0x%06x\n", adapter->peer_d_id);
-ZFCP_DEFINE_ADAPTER_ATTR(physical_wwpn, "0x%016llx\n", adapter->physical_wwpn);
-ZFCP_DEFINE_ADAPTER_ATTR(physical_s_id, "0x%06x\n", adapter->physical_s_id);
ZFCP_DEFINE_ADAPTER_ATTR(card_version, "0x%04x\n", adapter->hydra_version);
ZFCP_DEFINE_ADAPTER_ATTR(lic_version, "0x%08x\n", adapter->fsf_lic_version);
+ZFCP_DEFINE_ADAPTER_ATTR(fc_link_speed, "%d Gb/s\n", adapter->fc_link_speed);
ZFCP_DEFINE_ADAPTER_ATTR(fc_service_class, "%d\n", adapter->fc_service_class);
ZFCP_DEFINE_ADAPTER_ATTR(fc_topology, "%s\n",
fc_topologies[adapter->fc_topology]);
ZFCP_DEFINE_ADAPTER_ATTR(hardware_version, "0x%08x\n",
adapter->hardware_version);
+ZFCP_DEFINE_ADAPTER_ATTR(serial_number, "%17s\n", adapter->serial_number);
ZFCP_DEFINE_ADAPTER_ATTR(scsi_host_no, "0x%x\n", adapter->scsi_host_no);
ZFCP_DEFINE_ADAPTER_ATTR(in_recovery, "%d\n", atomic_test_mask
(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status));
@@ -252,18 +255,21 @@ static struct attribute *zfcp_adapter_attrs[] = {
&dev_attr_in_recovery.attr,
&dev_attr_port_remove.attr,
&dev_attr_port_add.attr,
+ &dev_attr_wwnn.attr,
+ &dev_attr_wwpn.attr,
+ &dev_attr_s_id.attr,
&dev_attr_peer_wwnn.attr,
&dev_attr_peer_wwpn.attr,
&dev_attr_peer_d_id.attr,
- &dev_attr_physical_wwpn.attr,
- &dev_attr_physical_s_id.attr,
&dev_attr_card_version.attr,
&dev_attr_lic_version.attr,
+ &dev_attr_fc_link_speed.attr,
&dev_attr_fc_service_class.attr,
&dev_attr_fc_topology.attr,
&dev_attr_scsi_host_no.attr,
&dev_attr_status.attr,
&dev_attr_hardware_version.attr,
+ &dev_attr_serial_number.attr,
NULL
};
diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 876d1de8480d..c932b3b94490 100644
--- a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -1109,6 +1109,15 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa
return (0);
}
+uint64_t
+ahc_linux_get_memsize(void)
+{
+ struct sysinfo si;
+
+ si_meminfo(&si);
+ return ((uint64_t)si.totalram << PAGE_SHIFT);
+}
+
/*
* Place the SCSI bus into a known state by either resetting it,
* or forcing transfer negotiations on the next command to any
diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.h b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.h
index be9edbe26dbe..c52996269240 100644
--- a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -494,6 +494,8 @@ ahc_insb(struct ahc_softc * ahc, long port, uint8_t *array, int count)
int ahc_linux_register_host(struct ahc_softc *,
struct scsi_host_template *);
+uint64_t ahc_linux_get_memsize(void);
+
/*************************** Pretty Printing **********************************/
struct info_str {
char *buffer;
diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
index 3ce77ddc889e..0d44a6907dd2 100644
--- a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
+++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c
@@ -180,7 +180,6 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct ahc_pci_identity *entry;
char *name;
int error;
- struct device *dev = &pdev->dev;
pci = pdev;
entry = ahc_find_pci_device(pci);
@@ -210,12 +209,11 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
if (sizeof(dma_addr_t) > 4
- && ahc->features & AHC_LARGE_SCBS
- && dma_set_mask(dev, mask_39bit) == 0
- && dma_get_required_mask(dev) > DMA_32BIT_MASK) {
+ && ahc_linux_get_memsize() > 0x80000000
+ && pci_set_dma_mask(pdev, mask_39bit) == 0) {
ahc->flags |= AHC_39BIT_ADDRESSING;
} else {
- if (dma_set_mask(dev, DMA_32BIT_MASK)) {
+ if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n");
return (-ENODEV);
}
diff --git a/trunk/drivers/scsi/atp870u.c b/trunk/drivers/scsi/atp870u.c
index a8cfbef304b5..e6153fe5842a 100644
--- a/trunk/drivers/scsi/atp870u.c
+++ b/trunk/drivers/scsi/atp870u.c
@@ -996,7 +996,6 @@ static void send_s870(struct atp_unit *dev,unsigned char c)
#ifdef ED_DBGP
printk("send_s870: prdaddr_2 0x%8x tmpcip %x target_id %d\n", dev->id[c][target_id].prdaddr,tmpcip,target_id);
#endif
- dev->id[c][target_id].prdaddr = dev->id[c][target_id].prd_bus;
outl(dev->id[c][target_id].prdaddr, tmpcip);
tmpcip = tmpcip - 2;
outb(0x06, tmpcip);
@@ -2573,7 +2572,7 @@ static void atp870u_free_tables(struct Scsi_Host *host)
for (k = 0; k < 16; k++) {
if (!atp_dev->id[j][k].prd_table)
continue;
- pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prd_bus);
+ pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prdaddr);
atp_dev->id[j][k].prd_table = NULL;
}
}
@@ -2585,13 +2584,12 @@ static int atp870u_init_tables(struct Scsi_Host *host)
int c,k;
for(c=0;c < 2;c++) {
for(k=0;k<16;k++) {
- atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prd_bus));
+ atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prdaddr));
if (!atp_dev->id[c][k].prd_table) {
printk("atp870u_init_tables fail\n");
atp870u_free_tables(host);
return -ENOMEM;
}
- atp_dev->id[c][k].prdaddr = atp_dev->id[c][k].prd_bus;
atp_dev->id[c][k].devsp=0x20;
atp_dev->id[c][k].devtype = 0x7f;
atp_dev->id[c][k].curr_req = NULL;
diff --git a/trunk/drivers/scsi/atp870u.h b/trunk/drivers/scsi/atp870u.h
index 62bae64a01c1..89f43af39cf2 100644
--- a/trunk/drivers/scsi/atp870u.h
+++ b/trunk/drivers/scsi/atp870u.h
@@ -54,9 +54,8 @@ struct atp_unit
unsigned long tran_len;
unsigned long last_len;
unsigned char *prd_pos;
- unsigned char *prd_table; /* Kernel address of PRD table */
- dma_addr_t prd_bus; /* Bus address of PRD */
- dma_addr_t prdaddr; /* Dynamically updated in driver */
+ unsigned char *prd_table;
+ dma_addr_t prdaddr;
struct scsi_cmnd *curr_req;
} id[2][16];
struct Scsi_Host *host;
diff --git a/trunk/drivers/scsi/fd_mcs.c b/trunk/drivers/scsi/fd_mcs.c
index d59d449a9e4d..fa652f8aa643 100644
--- a/trunk/drivers/scsi/fd_mcs.c
+++ b/trunk/drivers/scsi/fd_mcs.c
@@ -1360,5 +1360,3 @@ static Scsi_Host_Template driver_template = {
.use_clustering = DISABLE_CLUSTERING,
};
#include "scsi_module.c"
-
-MODULE_LICENSE("GPL");
diff --git a/trunk/drivers/scsi/hosts.c b/trunk/drivers/scsi/hosts.c
index f2a72d33132c..85503fad789a 100644
--- a/trunk/drivers/scsi/hosts.c
+++ b/trunk/drivers/scsi/hosts.c
@@ -98,7 +98,6 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
switch (oldstate) {
case SHOST_CREATED:
case SHOST_RUNNING:
- case SHOST_CANCEL_RECOVERY:
break;
default:
goto illegal;
@@ -108,31 +107,12 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state)
case SHOST_DEL:
switch (oldstate) {
case SHOST_CANCEL:
- case SHOST_DEL_RECOVERY:
break;
default:
goto illegal;
}
break;
- case SHOST_CANCEL_RECOVERY:
- switch (oldstate) {
- case SHOST_CANCEL:
- case SHOST_RECOVERY:
- break;
- default:
- goto illegal;
- }
- break;
-
- case SHOST_DEL_RECOVERY:
- switch (oldstate) {
- case SHOST_CANCEL_RECOVERY:
- break;
- default:
- goto illegal;
- }
- break;
}
shost->shost_state = state;
return 0;
@@ -154,24 +134,13 @@ EXPORT_SYMBOL(scsi_host_set_state);
**/
void scsi_remove_host(struct Scsi_Host *shost)
{
- unsigned long flags;
down(&shost->scan_mutex);
- spin_lock_irqsave(shost->host_lock, flags);
- if (scsi_host_set_state(shost, SHOST_CANCEL))
- if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY)) {
- spin_unlock_irqrestore(shost->host_lock, flags);
- up(&shost->scan_mutex);
- return;
- }
- spin_unlock_irqrestore(shost->host_lock, flags);
+ scsi_host_set_state(shost, SHOST_CANCEL);
up(&shost->scan_mutex);
scsi_forget_host(shost);
scsi_proc_host_rm(shost);
- spin_lock_irqsave(shost->host_lock, flags);
- if (scsi_host_set_state(shost, SHOST_DEL))
- BUG_ON(scsi_host_set_state(shost, SHOST_DEL_RECOVERY));
- spin_unlock_irqrestore(shost->host_lock, flags);
+ scsi_host_set_state(shost, SHOST_DEL);
transport_unregister_device(&shost->shost_gendev);
class_device_unregister(&shost->shost_classdev);
diff --git a/trunk/drivers/scsi/ibmmca.c b/trunk/drivers/scsi/ibmmca.c
index 19392f651272..6e54c7d9b33c 100644
--- a/trunk/drivers/scsi/ibmmca.c
+++ b/trunk/drivers/scsi/ibmmca.c
@@ -460,8 +460,6 @@ MODULE_PARM(adisplay, "1i");
MODULE_PARM(normal, "1i");
MODULE_PARM(ansi, "1i");
#endif
-
-MODULE_LICENSE("GPL");
#endif
/*counter of concurrent disk read/writes, to turn on/off disk led */
static int disk_rw_in_progress = 0;
diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c
index ff25210b00ba..5b14934ba861 100644
--- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -727,16 +727,6 @@ static void adapter_info_rsp(struct srp_event_struct *evt_struct)
if (hostdata->madapter_info.port_max_txu[0])
hostdata->host->max_sectors =
hostdata->madapter_info.port_max_txu[0] >> 9;
-
- if (hostdata->madapter_info.os_type == 3 &&
- strcmp(hostdata->madapter_info.srp_version, "1.6a") <= 0) {
- printk("ibmvscsi: host (Ver. %s) doesn't support large"
- "transfers\n",
- hostdata->madapter_info.srp_version);
- printk("ibmvscsi: limiting scatterlists to %d\n",
- MAX_INDIRECT_BUFS);
- hostdata->host->sg_tablesize = MAX_INDIRECT_BUFS;
- }
}
}
diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c
index 1f0ebabf6d47..a780546eda9c 100644
--- a/trunk/drivers/scsi/scsi.c
+++ b/trunk/drivers/scsi/scsi.c
@@ -1265,8 +1265,9 @@ int scsi_device_cancel(struct scsi_device *sdev, int recovery)
list_for_each_safe(lh, lh_sf, &active_list) {
scmd = list_entry(lh, struct scsi_cmnd, eh_entry);
list_del_init(lh);
- if (recovery &&
- !scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD)) {
+ if (recovery) {
+ scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD);
+ } else {
scmd->result = (DID_ABORT << 16);
scsi_finish_command(scmd);
}
diff --git a/trunk/drivers/scsi/scsi_devinfo.c b/trunk/drivers/scsi/scsi_devinfo.c
index 64fc9e21f35b..07b554affcf2 100644
--- a/trunk/drivers/scsi/scsi_devinfo.c
+++ b/trunk/drivers/scsi/scsi_devinfo.c
@@ -110,7 +110,6 @@ static struct {
{"RELISYS", "Scorpio", NULL, BLIST_NOLUN}, /* responds to all lun */
{"SANKYO", "CP525", "6.64", BLIST_NOLUN}, /* causes failed REQ SENSE, extra reset */
{"TEXEL", "CD-ROM", "1.06", BLIST_NOLUN},
- {"transtec", "T5008", "0001", BLIST_NOREPORTLUN },
{"YAMAHA", "CDR100", "1.00", BLIST_NOLUN}, /* locks up */
{"YAMAHA", "CDR102", "1.00", BLIST_NOLUN}, /* locks up */
{"YAMAHA", "CRW8424S", "1.0", BLIST_NOLUN}, /* locks up */
diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c
index ad5342165079..895c9452be4c 100644
--- a/trunk/drivers/scsi/scsi_error.c
+++ b/trunk/drivers/scsi/scsi_error.c
@@ -50,7 +50,7 @@
void scsi_eh_wakeup(struct Scsi_Host *shost)
{
if (shost->host_busy == shost->host_failed) {
- wake_up_process(shost->ehandler);
+ up(shost->eh_wait);
SCSI_LOG_ERROR_RECOVERY(5,
printk("Waking error handler thread\n"));
}
@@ -68,24 +68,19 @@ int scsi_eh_scmd_add(struct scsi_cmnd *scmd, int eh_flag)
{
struct Scsi_Host *shost = scmd->device->host;
unsigned long flags;
- int ret = 0;
- if (!shost->ehandler)
+ if (shost->eh_wait == NULL)
return 0;
spin_lock_irqsave(shost->host_lock, flags);
- if (scsi_host_set_state(shost, SHOST_RECOVERY))
- if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY))
- goto out_unlock;
- ret = 1;
scmd->eh_eflags |= eh_flag;
list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q);
+ scsi_host_set_state(shost, SHOST_RECOVERY);
shost->host_failed++;
scsi_eh_wakeup(shost);
- out_unlock:
spin_unlock_irqrestore(shost->host_lock, flags);
- return ret;
+ return 1;
}
/**
@@ -181,8 +176,8 @@ void scsi_times_out(struct scsi_cmnd *scmd)
}
if (unlikely(!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) {
- scmd->result |= DID_TIME_OUT << 16;
- __scsi_done(scmd);
+ panic("Error handler thread not present at %p %p %s %d",
+ scmd, scmd->device->host, __FILE__, __LINE__);
}
}
@@ -201,7 +196,8 @@ int scsi_block_when_processing_errors(struct scsi_device *sdev)
{
int online;
- wait_event(sdev->host->host_wait, !scsi_host_in_recovery(sdev->host));
+ wait_event(sdev->host->host_wait, (sdev->host->shost_state !=
+ SHOST_RECOVERY));
online = scsi_device_online(sdev);
@@ -1445,7 +1441,6 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
static void scsi_restart_operations(struct Scsi_Host *shost)
{
struct scsi_device *sdev;
- unsigned long flags;
/*
* If the door was locked, we need to insert a door lock request
@@ -1465,11 +1460,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
SCSI_LOG_ERROR_RECOVERY(3, printk("%s: waking up host to restart\n",
__FUNCTION__));
- spin_lock_irqsave(shost->host_lock, flags);
- if (scsi_host_set_state(shost, SHOST_RUNNING))
- if (scsi_host_set_state(shost, SHOST_CANCEL))
- BUG_ON(scsi_host_set_state(shost, SHOST_DEL));
- spin_unlock_irqrestore(shost->host_lock, flags);
+ scsi_host_set_state(shost, SHOST_RUNNING);
wake_up(&shost->host_wait);
@@ -1591,31 +1582,40 @@ int scsi_error_handler(void *data)
{
struct Scsi_Host *shost = (struct Scsi_Host *) data;
int rtn;
+ DECLARE_MUTEX_LOCKED(sem);
current->flags |= PF_NOFREEZE;
+ shost->eh_wait = &sem;
-
/*
- * Note - we always use TASK_INTERRUPTIBLE even if the module
- * was loaded as part of the kernel. The reason is that
- * UNINTERRUPTIBLE would cause this thread to be counted in
- * the load average as a running process, and an interruptible
- * wait doesn't.
+ * Wake up the thread that created us.
*/
- set_current_state(TASK_INTERRUPTIBLE);
- while (!kthread_should_stop()) {
- if (shost->host_failed == 0 ||
- shost->host_failed != shost->host_busy) {
- SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
- " scsi_eh_%d"
- " sleeping\n",
- shost->host_no));
- schedule();
- set_current_state(TASK_INTERRUPTIBLE);
- continue;
- }
+ SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of"
+ " scsi_eh_%d\n",shost->host_no));
+
+ while (1) {
+ /*
+ * If we get a signal, it means we are supposed to go
+ * away and die. This typically happens if the user is
+ * trying to unload a module.
+ */
+ SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
+ " scsi_eh_%d"
+ " sleeping\n",shost->host_no));
+
+ /*
+ * Note - we always use down_interruptible with the semaphore
+ * even if the module was loaded as part of the kernel. The
+ * reason is that down() will cause this thread to be counted
+ * in the load average as a running process, and down
+ * interruptible doesn't. Given that we need to allow this
+ * thread to die if the driver was loaded as a module, using
+ * semaphores isn't unreasonable.
+ */
+ down_interruptible(&sem);
+ if (kthread_should_stop())
+ break;
- __set_current_state(TASK_RUNNING);
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"
" scsi_eh_%d waking"
" up\n",shost->host_no));
@@ -1642,7 +1642,7 @@ int scsi_error_handler(void *data)
* which are still online.
*/
scsi_restart_operations(shost);
- set_current_state(TASK_INTERRUPTIBLE);
+
}
SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d"
@@ -1651,7 +1651,7 @@ int scsi_error_handler(void *data)
/*
* Make sure that nobody tries to wake us up again.
*/
- shost->ehandler = NULL;
+ shost->eh_wait = NULL;
return 0;
}
diff --git a/trunk/drivers/scsi/scsi_ioctl.c b/trunk/drivers/scsi/scsi_ioctl.c
index de7f98cc38fe..b7fddac81347 100644
--- a/trunk/drivers/scsi/scsi_ioctl.c
+++ b/trunk/drivers/scsi/scsi_ioctl.c
@@ -458,7 +458,7 @@ int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd,
* error processing, as long as the device was opened
* non-blocking */
if (filp && filp->f_flags & O_NONBLOCK) {
- if (scsi_host_in_recovery(sdev->host))
+ if (sdev->host->shost_state == SHOST_RECOVERY)
return -ENODEV;
} else if (!scsi_block_when_processing_errors(sdev))
return -ENODEV;
diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c
index dc9c772bc874..863bb6495daa 100644
--- a/trunk/drivers/scsi/scsi_lib.c
+++ b/trunk/drivers/scsi/scsi_lib.c
@@ -118,6 +118,7 @@ static void scsi_unprep_request(struct request *req)
req->flags &= ~REQ_DONTPREP;
req->special = (req->flags & REQ_SPECIAL) ? cmd->sc_request : NULL;
+ scsi_release_buffers(cmd);
scsi_put_command(cmd);
}
@@ -139,12 +140,14 @@ static void scsi_unprep_request(struct request *req)
* commands.
* Notes: This could be called either from an interrupt context or a
* normal process context.
+ * Notes: Upon return, cmd is a stale pointer.
*/
int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
{
struct Scsi_Host *host = cmd->device->host;
struct scsi_device *device = cmd->device;
struct request_queue *q = device->request_queue;
+ struct request *req = cmd->request;
unsigned long flags;
SCSI_LOG_MLQUEUE(1,
@@ -185,8 +188,9 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
* function. The SCSI request function detects the blocked condition
* and plugs the queue appropriately.
*/
+ scsi_unprep_request(req);
spin_lock_irqsave(q->queue_lock, flags);
- blk_requeue_request(q, cmd->request);
+ blk_requeue_request(q, req);
spin_unlock_irqrestore(q->queue_lock, flags);
scsi_run_queue(q);
@@ -447,7 +451,7 @@ void scsi_device_unbusy(struct scsi_device *sdev)
spin_lock_irqsave(shost->host_lock, flags);
shost->host_busy--;
- if (unlikely(scsi_host_in_recovery(shost) &&
+ if (unlikely((shost->shost_state == SHOST_RECOVERY) &&
shost->host_failed))
scsi_eh_wakeup(shost);
spin_unlock(shost->host_lock);
@@ -1264,7 +1268,6 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
}
} else {
memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));
- cmd->cmd_len = req->cmd_len;
if (rq_data_dir(req) == WRITE)
cmd->sc_data_direction = DMA_TO_DEVICE;
else if (req->data_len)
@@ -1339,7 +1342,7 @@ static inline int scsi_host_queue_ready(struct request_queue *q,
struct Scsi_Host *shost,
struct scsi_device *sdev)
{
- if (scsi_host_in_recovery(shost))
+ if (shost->shost_state == SHOST_RECOVERY)
return 0;
if (shost->host_busy == 0 && shost->host_blocked) {
/*
@@ -1511,6 +1514,7 @@ static void scsi_request_fn(struct request_queue *q)
* cases (host limits or settings) should run the queue at some
* later time.
*/
+ scsi_unprep_request(req);
spin_lock_irq(q->queue_lock);
blk_requeue_request(q, req);
sdev->device_busy--;
diff --git a/trunk/drivers/scsi/scsi_scan.c b/trunk/drivers/scsi/scsi_scan.c
index fcf9f6cbb142..b86f170fa8ed 100644
--- a/trunk/drivers/scsi/scsi_scan.c
+++ b/trunk/drivers/scsi/scsi_scan.c
@@ -1466,17 +1466,23 @@ EXPORT_SYMBOL(scsi_scan_single_target);
void scsi_forget_host(struct Scsi_Host *shost)
{
- struct scsi_device *sdev;
+ struct scsi_target *starget, *tmp;
unsigned long flags;
- restart:
+ /*
+ * Ok, this look a bit strange. We always look for the first device
+ * on the list as scsi_remove_device removes them from it - thus we
+ * also have to release the lock.
+ * We don't need to get another reference to the device before
+ * releasing the lock as we already own the reference from
+ * scsi_register_device that's release in scsi_remove_device. And
+ * after that we don't look at sdev anymore.
+ */
spin_lock_irqsave(shost->host_lock, flags);
- list_for_each_entry(sdev, &shost->__devices, siblings) {
- if (sdev->sdev_state == SDEV_DEL)
- continue;
+ list_for_each_entry_safe(starget, tmp, &shost->__targets, siblings) {
spin_unlock_irqrestore(shost->host_lock, flags);
- __scsi_remove_device(sdev);
- goto restart;
+ scsi_remove_target(&starget->dev);
+ spin_lock_irqsave(shost->host_lock, flags);
}
spin_unlock_irqrestore(shost->host_lock, flags);
}
diff --git a/trunk/drivers/scsi/scsi_sysfs.c b/trunk/drivers/scsi/scsi_sysfs.c
index 72a6550a056c..b8052d5206cc 100644
--- a/trunk/drivers/scsi/scsi_sysfs.c
+++ b/trunk/drivers/scsi/scsi_sysfs.c
@@ -57,8 +57,6 @@ static struct {
{ SHOST_CANCEL, "cancel" },
{ SHOST_DEL, "deleted" },
{ SHOST_RECOVERY, "recovery" },
- { SHOST_CANCEL_RECOVERY, "cancel/recovery" },
- { SHOST_DEL_RECOVERY, "deleted/recovery", },
};
const char *scsi_host_state_name(enum scsi_host_state state)
{
@@ -709,11 +707,9 @@ void __scsi_remove_device(struct scsi_device *sdev)
**/
void scsi_remove_device(struct scsi_device *sdev)
{
- struct Scsi_Host *shost = sdev->host;
-
- down(&shost->scan_mutex);
+ down(&sdev->host->scan_mutex);
__scsi_remove_device(sdev);
- up(&shost->scan_mutex);
+ up(&sdev->host->scan_mutex);
}
EXPORT_SYMBOL(scsi_remove_device);
@@ -721,20 +717,17 @@ void __scsi_remove_target(struct scsi_target *starget)
{
struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
unsigned long flags;
- struct scsi_device *sdev;
+ struct scsi_device *sdev, *tmp;
spin_lock_irqsave(shost->host_lock, flags);
starget->reap_ref++;
- restart:
- list_for_each_entry(sdev, &shost->__devices, siblings) {
+ list_for_each_entry_safe(sdev, tmp, &shost->__devices, siblings) {
if (sdev->channel != starget->channel ||
- sdev->id != starget->id ||
- sdev->sdev_state == SDEV_DEL)
+ sdev->id != starget->id)
continue;
spin_unlock_irqrestore(shost->host_lock, flags);
scsi_remove_device(sdev);
spin_lock_irqsave(shost->host_lock, flags);
- goto restart;
}
spin_unlock_irqrestore(shost->host_lock, flags);
scsi_target_reap(starget);
diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c
index 9a1dc0cea03c..de564b386052 100644
--- a/trunk/drivers/scsi/sd.c
+++ b/trunk/drivers/scsi/sd.c
@@ -235,7 +235,6 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
return 0;
memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
- SCpnt->cmd_len = rq->cmd_len;
if (rq_data_dir(rq) == WRITE)
SCpnt->sc_data_direction = DMA_TO_DEVICE;
else if (rq->data_len)
diff --git a/trunk/drivers/scsi/sg.c b/trunk/drivers/scsi/sg.c
index 4d09a6e4dd2e..9ea4765d1d12 100644
--- a/trunk/drivers/scsi/sg.c
+++ b/trunk/drivers/scsi/sg.c
@@ -1027,7 +1027,7 @@ sg_ioctl(struct inode *inode, struct file *filp,
if (sdp->detached)
return -ENODEV;
if (filp->f_flags & O_NONBLOCK) {
- if (scsi_host_in_recovery(sdp->device->host))
+ if (sdp->device->host->shost_state == SHOST_RECOVERY)
return -EBUSY;
} else if (!scsi_block_when_processing_errors(sdp->device))
return -EBUSY;
diff --git a/trunk/drivers/scsi/sr.c b/trunk/drivers/scsi/sr.c
index 561901b1cf11..ce63fc8312dc 100644
--- a/trunk/drivers/scsi/sr.c
+++ b/trunk/drivers/scsi/sr.c
@@ -326,7 +326,6 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
return 0;
memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
- SCpnt->cmd_len = rq->cmd_len;
if (!rq->data_len)
SCpnt->sc_data_direction = DMA_NONE;
else if (rq_data_dir(rq) == WRITE)
diff --git a/trunk/drivers/scsi/st.c b/trunk/drivers/scsi/st.c
index d001c046551b..a93308ae9736 100644
--- a/trunk/drivers/scsi/st.c
+++ b/trunk/drivers/scsi/st.c
@@ -4206,7 +4206,6 @@ static int st_init_command(struct scsi_cmnd *SCpnt)
return 0;
memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
- SCpnt->cmd_len = rq->cmd_len;
if (rq_data_dir(rq) == WRITE)
SCpnt->sc_data_direction = DMA_TO_DEVICE;
diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig
index 773ae11b4a19..31ee13eef7af 100644
--- a/trunk/drivers/video/Kconfig
+++ b/trunk/drivers/video/Kconfig
@@ -650,7 +650,6 @@ config FB_NVIDIA
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
- select FB_SOFT_CURSOR
help
This driver supports graphics boards with the nVidia chips, TNT
and newer. For very old chipsets, such as the RIVA128, then use
diff --git a/trunk/drivers/video/aty/xlinit.c b/trunk/drivers/video/aty/xlinit.c
index 0bea0d8d7821..92643af12581 100644
--- a/trunk/drivers/video/aty/xlinit.c
+++ b/trunk/drivers/video/aty/xlinit.c
@@ -174,7 +174,7 @@ int atyfb_xl_init(struct fb_info *info)
const struct xl_card_cfg_t * card = &card_cfg[xl_card];
struct atyfb_par *par = (struct atyfb_par *) info->par;
union aty_pll pll;
- int err;
+ int i, err;
u32 temp;
aty_st_8(CONFIG_STAT0, 0x85, par);
@@ -252,12 +252,9 @@ int atyfb_xl_init(struct fb_info *info)
aty_st_le32(0xEC, 0x00000000, par);
aty_st_le32(0xFC, 0x00000000, par);
-#if defined (CONFIG_FB_ATY_GENERIC_LCD)
- int i;
for (i=0; irefresh = cvt->f_refresh;
mode->pixclock = KHZ2PICOS(cvt->pixclock/1000);
- mode->left_margin = cvt->h_back_porch;
- mode->right_margin = cvt->h_front_porch;
+ mode->left_margin = cvt->h_front_porch;
+ mode->right_margin = cvt->h_back_porch;
mode->hsync_len = cvt->hsync;
- mode->upper_margin = cvt->v_back_porch;
- mode->lower_margin = cvt->v_front_porch;
+ mode->upper_margin = cvt->v_front_porch;
+ mode->lower_margin = cvt->v_back_porch;
mode->vsync_len = cvt->vsync;
mode->sync &= ~(FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT);
diff --git a/trunk/drivers/video/nvidia/nvidia.c b/trunk/drivers/video/nvidia/nvidia.c
index a7f020ada630..3620de0f252e 100644
--- a/trunk/drivers/video/nvidia/nvidia.c
+++ b/trunk/drivers/video/nvidia/nvidia.c
@@ -893,7 +893,7 @@ static int nvidiafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
int i, set = cursor->set;
u16 fg, bg;
- if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
+ if (!hwcur || cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
return -ENXIO;
NVShowHideCursor(par, 0);
@@ -1356,9 +1356,6 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
info->pixmap.size = 8 * 1024;
info->pixmap.flags = FB_PIXMAP_SYSTEM;
- if (!hwcur)
- info->fbops->fb_cursor = soft_cursor;
-
info->var.accel_flags = (!noaccel);
switch (par->Architecture) {
diff --git a/trunk/fs/fat/inode.c b/trunk/fs/fat/inode.c
index e2effe2dc9b2..51b1d15d9d5c 100644
--- a/trunk/fs/fat/inode.c
+++ b/trunk/fs/fat/inode.c
@@ -300,9 +300,9 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
inode->i_blksize = sbi->cluster_size;
inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
& ~((loff_t)sbi->cluster_size - 1)) >> 9;
- inode->i_mtime.tv_sec =
+ inode->i_mtime.tv_sec = inode->i_atime.tv_sec =
date_dos2unix(le16_to_cpu(de->time), le16_to_cpu(de->date));
- inode->i_mtime.tv_nsec = 0;
+ inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec = 0;
if (sbi->options.isvfat) {
int secs = de->ctime_cs / 100;
int csecs = de->ctime_cs % 100;
@@ -310,11 +310,8 @@ static int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
date_dos2unix(le16_to_cpu(de->ctime),
le16_to_cpu(de->cdate)) + secs;
inode->i_ctime.tv_nsec = csecs * 10000000;
- inode->i_atime.tv_sec =
- date_dos2unix(le16_to_cpu(0), le16_to_cpu(de->adate));
- inode->i_atime.tv_nsec = 0;
} else
- inode->i_ctime = inode->i_atime = inode->i_mtime;
+ inode->i_ctime = inode->i_mtime;
return 0;
}
@@ -516,9 +513,7 @@ static int fat_write_inode(struct inode *inode, int wait)
raw_entry->starthi = cpu_to_le16(MSDOS_I(inode)->i_logstart >> 16);
fat_date_unix2dos(inode->i_mtime.tv_sec, &raw_entry->time, &raw_entry->date);
if (sbi->options.isvfat) {
- __le16 atime;
fat_date_unix2dos(inode->i_ctime.tv_sec,&raw_entry->ctime,&raw_entry->cdate);
- fat_date_unix2dos(inode->i_atime.tv_sec,&atime,&raw_entry->adate);
raw_entry->ctime_cs = (inode->i_ctime.tv_sec & 1) * 100 +
inode->i_ctime.tv_nsec / 10000000;
}
diff --git a/trunk/fs/ntfs/runlist.c b/trunk/fs/ntfs/runlist.c
index 061b5ff6b73c..e2665d011d72 100644
--- a/trunk/fs/ntfs/runlist.c
+++ b/trunk/fs/ntfs/runlist.c
@@ -158,21 +158,17 @@ static inline BOOL ntfs_are_rl_mergeable(runlist_element *dst,
BUG_ON(!dst);
BUG_ON(!src);
- /* We can merge unmapped regions even if they are misaligned. */
- if ((dst->lcn == LCN_RL_NOT_MAPPED) && (src->lcn == LCN_RL_NOT_MAPPED))
- return TRUE;
- /* If the runs are misaligned, we cannot merge them. */
- if ((dst->vcn + dst->length) != src->vcn)
+ if ((dst->lcn < 0) || (src->lcn < 0)) { /* Are we merging holes? */
+ if (dst->lcn == LCN_HOLE && src->lcn == LCN_HOLE)
+ return TRUE;
return FALSE;
- /* If both runs are non-sparse and contiguous, we can merge them. */
- if ((dst->lcn >= 0) && (src->lcn >= 0) &&
- ((dst->lcn + dst->length) == src->lcn))
- return TRUE;
- /* If we are merging two holes, we can merge them. */
- if ((dst->lcn == LCN_HOLE) && (src->lcn == LCN_HOLE))
- return TRUE;
- /* Cannot merge. */
- return FALSE;
+ }
+ if ((dst->lcn + dst->length) != src->lcn) /* Are the runs contiguous? */
+ return FALSE;
+ if ((dst->vcn + dst->length) != src->vcn) /* Are the runs misaligned? */
+ return FALSE;
+
+ return TRUE;
}
/**
@@ -218,15 +214,14 @@ static inline void __ntfs_rl_merge(runlist_element *dst, runlist_element *src)
static inline runlist_element *ntfs_rl_append(runlist_element *dst,
int dsize, runlist_element *src, int ssize, int loc)
{
- BOOL right = FALSE; /* Right end of @src needs merging. */
- int marker; /* End of the inserted runs. */
+ BOOL right; /* Right end of @src needs merging. */
+ int marker; /* End of the inserted runs. */
BUG_ON(!dst);
BUG_ON(!src);
/* First, check if the right hand end needs merging. */
- if ((loc + 1) < dsize)
- right = ntfs_are_rl_mergeable(src + ssize - 1, dst + loc + 1);
+ right = ntfs_are_rl_mergeable(src + ssize - 1, dst + loc + 1);
/* Space required: @dst size + @src size, less one if we merged. */
dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - right);
@@ -382,21 +377,20 @@ static inline runlist_element *ntfs_rl_replace(runlist_element *dst,
int dsize, runlist_element *src, int ssize, int loc)
{
BOOL left = FALSE; /* Left end of @src needs merging. */
- BOOL right = FALSE; /* Right end of @src needs merging. */
+ BOOL right; /* Right end of @src needs merging. */
int tail; /* Start of tail of @dst. */
int marker; /* End of the inserted runs. */
BUG_ON(!dst);
BUG_ON(!src);
- /* First, see if the left and right ends need merging. */
- if ((loc + 1) < dsize)
- right = ntfs_are_rl_mergeable(src + ssize - 1, dst + loc + 1);
+ /* First, merge the left and right ends, if necessary. */
+ right = ntfs_are_rl_mergeable(src + ssize - 1, dst + loc + 1);
if (loc > 0)
left = ntfs_are_rl_mergeable(dst + loc - 1, src);
/*
* Allocate some space. We will need less if the left, right, or both
- * ends get merged.
+ * ends were merged.
*/
dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - left - right);
if (IS_ERR(dst))
@@ -405,26 +399,21 @@ static inline runlist_element *ntfs_rl_replace(runlist_element *dst,
* We are guaranteed to succeed from here so can start modifying the
* original runlists.
*/
-
- /* First, merge the left and right ends, if necessary. */
if (right)
__ntfs_rl_merge(src + ssize - 1, dst + loc + 1);
if (left)
__ntfs_rl_merge(dst + loc - 1, src);
/*
- * Offset of the tail of @dst. This needs to be moved out of the way
- * to make space for the runs to be copied from @src, i.e. the first
- * run of the tail of @dst.
- * Nominally, @tail equals @loc + 1, i.e. location, skipping the
- * replaced run. However, if @right, then one of @dst's runs is
- * already merged into @src.
+ * First run of @dst that needs to be moved out of the way to make
+ * space for the runs to be copied from @src, i.e. the first run of the
+ * tail of @dst.
*/
tail = loc + right + 1;
/*
* First run after the @src runs that have been inserted, i.e. where
* the tail of @dst needs to be moved to.
- * Nominally, @marker equals @loc + @ssize, i.e. location + number of
- * runs in @src. However, if @left, then the first run in @src has
+ * Nominally, marker equals @loc + @ssize, i.e. location + number of
+ * runs in @src). However, if @left, then the first run in @src has
* been merged with one in @dst.
*/
marker = loc + ssize - left;
diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c
index fb34f88a4a74..23db452ab428 100644
--- a/trunk/fs/proc/base.c
+++ b/trunk/fs/proc/base.c
@@ -340,52 +340,6 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf
return result;
}
-
-/* Same as proc_root_link, but this addionally tries to get fs from other
- * threads in the group */
-static int proc_task_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
-{
- struct fs_struct *fs;
- int result = -ENOENT;
- struct task_struct *leader = proc_task(inode);
-
- task_lock(leader);
- fs = leader->fs;
- if (fs) {
- atomic_inc(&fs->count);
- task_unlock(leader);
- } else {
- /* Try to get fs from other threads */
- task_unlock(leader);
- struct task_struct *task = leader;
- read_lock(&tasklist_lock);
- if (pid_alive(task)) {
- while ((task = next_thread(task)) != leader) {
- task_lock(task);
- fs = task->fs;
- if (fs) {
- atomic_inc(&fs->count);
- task_unlock(task);
- break;
- }
- task_unlock(task);
- }
- }
- read_unlock(&tasklist_lock);
- }
-
- if (fs) {
- read_lock(&fs->lock);
- *mnt = mntget(fs->rootmnt);
- *dentry = dget(fs->root);
- read_unlock(&fs->lock);
- result = 0;
- put_fs_struct(fs);
- }
- return result;
-}
-
-
#define MAY_PTRACE(task) \
(task == current || \
(task->parent == current && \
@@ -517,14 +471,14 @@ static int proc_oom_score(struct task_struct *task, char *buffer)
/* permission checks */
-/* If the process being read is separated by chroot from the reading process,
- * don't let the reader access the threads.
- */
-static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt)
+static int proc_check_root(struct inode *inode)
{
- struct dentry *de, *base;
- struct vfsmount *our_vfsmnt, *mnt;
+ struct dentry *de, *base, *root;
+ struct vfsmount *our_vfsmnt, *vfsmnt, *mnt;
int res = 0;
+
+ if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */
+ return -ENOENT;
read_lock(¤t->fs->lock);
our_vfsmnt = mntget(current->fs->rootmnt);
base = dget(current->fs->root);
@@ -557,16 +511,6 @@ static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt)
goto exit;
}
-static int proc_check_root(struct inode *inode)
-{
- struct dentry *root;
- struct vfsmount *vfsmnt;
-
- if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */
- return -ENOENT;
- return proc_check_chroot(root, vfsmnt);
-}
-
static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
{
if (generic_permission(inode, mask, NULL) != 0)
@@ -574,20 +518,6 @@ static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
return proc_check_root(inode);
}
-static int proc_task_permission(struct inode *inode, int mask, struct nameidata *nd)
-{
- struct dentry *root;
- struct vfsmount *vfsmnt;
-
- if (generic_permission(inode, mask, NULL) != 0)
- return -EACCES;
-
- if (proc_task_root_link(inode, &root, &vfsmnt))
- return -ENOENT;
-
- return proc_check_chroot(root, vfsmnt);
-}
-
extern struct seq_operations proc_pid_maps_op;
static int maps_open(struct inode *inode, struct file *file)
{
@@ -1489,7 +1419,7 @@ static struct inode_operations proc_fd_inode_operations = {
static struct inode_operations proc_task_inode_operations = {
.lookup = proc_task_lookup,
- .permission = proc_task_permission,
+ .permission = proc_permission,
};
#ifdef CONFIG_SECURITY
diff --git a/trunk/include/asm-arm/setup.h b/trunk/include/asm-arm/setup.h
index adcbd79762bf..a4b3ebf9bdd1 100644
--- a/trunk/include/asm-arm/setup.h
+++ b/trunk/include/asm-arm/setup.h
@@ -171,7 +171,7 @@ struct tagtable {
int (*parse)(const struct tag *);
};
-#define __tag __attribute_used__ __attribute__((__section__(".taglist")))
+#define __tag __attribute_used__ __attribute__((__section__(".taglist.init")))
#define __tagtable(tag, fn) \
static struct tagtable __tagtable_##fn __tag = { tag, fn }
diff --git a/trunk/include/asm-sparc64/cacheflush.h b/trunk/include/asm-sparc64/cacheflush.h
index ededd2659eab..51b26e81d828 100644
--- a/trunk/include/asm-sparc64/cacheflush.h
+++ b/trunk/include/asm-sparc64/cacheflush.h
@@ -4,6 +4,13 @@
#include
#include
+/* Flushing for D-cache alias handling is only needed if
+ * the page size is smaller than 16K.
+ */
+#if PAGE_SHIFT < 14
+#define DCACHE_ALIASING_POSSIBLE
+#endif
+
#ifndef __ASSEMBLY__
#include
diff --git a/trunk/include/asm-sparc64/ide.h b/trunk/include/asm-sparc64/ide.h
index c393f815b0be..4c1098474c73 100644
--- a/trunk/include/asm-sparc64/ide.h
+++ b/trunk/include/asm-sparc64/ide.h
@@ -15,7 +15,6 @@
#include
#include
#include
-#include
#ifndef MAX_HWIFS
# ifdef CONFIG_BLK_DEV_IDEPCI
diff --git a/trunk/include/asm-sparc64/page.h b/trunk/include/asm-sparc64/page.h
index 7f8d764abc47..c9f8ef208ea5 100644
--- a/trunk/include/asm-sparc64/page.h
+++ b/trunk/include/asm-sparc64/page.h
@@ -21,13 +21,6 @@
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
-/* Flushing for D-cache alias handling is only needed if
- * the page size is smaller than 16K.
- */
-#if PAGE_SHIFT < 14
-#define DCACHE_ALIASING_POSSIBLE
-#endif
-
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
diff --git a/trunk/include/asm-sparc64/pgalloc.h b/trunk/include/asm-sparc64/pgalloc.h
index a96067cca963..b9b1914aae63 100644
--- a/trunk/include/asm-sparc64/pgalloc.h
+++ b/trunk/include/asm-sparc64/pgalloc.h
@@ -10,7 +10,6 @@
#include
#include
#include
-#include
/* Page table allocation/freeing. */
#ifdef CONFIG_SMP
diff --git a/trunk/include/asm-sparc64/pgtable.h b/trunk/include/asm-sparc64/pgtable.h
index a297f6144f0f..a2b4f5ed4625 100644
--- a/trunk/include/asm-sparc64/pgtable.h
+++ b/trunk/include/asm-sparc64/pgtable.h
@@ -24,23 +24,21 @@
#include
#include
-/* The kernel image occupies 0x4000000 to 0x1000000 (4MB --> 32MB).
- * The page copy blockops can use 0x2000000 to 0x10000000.
+/* The kernel image occupies 0x4000000 to 0x1000000 (4MB --> 16MB).
+ * The page copy blockops use 0x1000000 to 0x18000000 (16MB --> 24MB).
* The PROM resides in an area spanning 0xf0000000 to 0x100000000.
- * The vmalloc area spans 0x100000000 to 0x200000000.
- * Since modules need to be in the lowest 32-bits of the address space,
- * we place them right before the OBP area from 0x10000000 to 0xf0000000.
+ * The vmalloc area spans 0x140000000 to 0x200000000.
* There is a single static kernel PMD which maps from 0x0 to address
* 0x400000000.
*/
-#define TLBTEMP_BASE _AC(0x0000000002000000,UL)
-#define MODULES_VADDR _AC(0x0000000010000000,UL)
-#define MODULES_LEN _AC(0x00000000e0000000,UL)
-#define MODULES_END _AC(0x00000000f0000000,UL)
+#define TLBTEMP_BASE _AC(0x0000000001000000,UL)
+#define MODULES_VADDR _AC(0x0000000002000000,UL)
+#define MODULES_LEN _AC(0x000000007e000000,UL)
+#define MODULES_END _AC(0x0000000080000000,UL)
+#define VMALLOC_START _AC(0x0000000140000000,UL)
+#define VMALLOC_END _AC(0x0000000200000000,UL)
#define LOW_OBP_ADDRESS _AC(0x00000000f0000000,UL)
#define HI_OBP_ADDRESS _AC(0x0000000100000000,UL)
-#define VMALLOC_START _AC(0x0000000100000000,UL)
-#define VMALLOC_END _AC(0x0000000200000000,UL)
/* XXX All of this needs to be rethought so we can take advantage
* XXX cheetah's full 64-bit virtual address space, ie. no more hole
diff --git a/trunk/include/linux/byteorder/generic.h b/trunk/include/linux/byteorder/generic.h
index 04bd756efc67..5fde6f4d6c1e 100644
--- a/trunk/include/linux/byteorder/generic.h
+++ b/trunk/include/linux/byteorder/generic.h
@@ -5,10 +5,6 @@
* linux/byteorder_generic.h
* Generic Byte-reordering support
*
- * The "... p" macros, like le64_to_cpup, can be used with pointers
- * to unaligned data, but there will be a performance penalty on
- * some architectures. Use get_unaligned for unaligned data.
- *
* Francois-Rene Rideau 19970707
* gathered all the good ideas from all asm-foo/byteorder.h into one file,
* cleaned them up.
diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h
index 097b3a3c693d..82d7024f0765 100644
--- a/trunk/include/linux/mm.h
+++ b/trunk/include/linux/mm.h
@@ -136,7 +136,6 @@ extern unsigned int kobjsize(const void *objp);
#define VM_EXEC 0x00000004
#define VM_SHARED 0x00000008
-/* mprotect() hardcodes VM_MAYREAD >> 4 == VM_READ, and so for r/w/x bits. */
#define VM_MAYREAD 0x00000010 /* limits for mprotect() etc */
#define VM_MAYWRITE 0x00000020
#define VM_MAYEXEC 0x00000040
@@ -351,8 +350,7 @@ static inline void put_page(struct page *page)
* only one copy in memory, at most, normally.
*
* For the non-reserved pages, page_count(page) denotes a reference count.
- * page_count() == 0 means the page is free. page->lru is then used for
- * freelist management in the buddy allocator.
+ * page_count() == 0 means the page is free.
* page_count() == 1 means the page is used for exactly one purpose
* (e.g. a private data page of one process).
*
@@ -378,8 +376,10 @@ static inline void put_page(struct page *page)
* attaches, plus 1 if `private' contains something, plus one for
* the page cache itself.
*
- * Instead of keeping dirty/clean pages in per address-space lists, we instead
- * now tag pages as dirty/under writeback in the radix tree.
+ * All pages belonging to an inode are in these doubly linked lists:
+ * mapping->clean_pages, mapping->dirty_pages and mapping->locked_pages;
+ * using the page->list list_head. These fields are also used for
+ * freelist managemet (when page_count()==0).
*
* There is also a per-mapping radix tree mapping index to the page
* in memory if present. The tree is rooted at mapping->root.
diff --git a/trunk/include/linux/syscalls.h b/trunk/include/linux/syscalls.h
index a6f03e473737..425f58c8ea4a 100644
--- a/trunk/include/linux/syscalls.h
+++ b/trunk/include/linux/syscalls.h
@@ -508,7 +508,5 @@ asmlinkage long sys_keyctl(int cmd, unsigned long arg2, unsigned long arg3,
asmlinkage long sys_ioprio_set(int which, int who, int ioprio);
asmlinkage long sys_ioprio_get(int which, int who);
-asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask,
- unsigned long maxnode);
#endif
diff --git a/trunk/include/rdma/ib_mad.h b/trunk/include/rdma/ib_mad.h
index 0e293fe733b0..53184a38fdf6 100644
--- a/trunk/include/rdma/ib_mad.h
+++ b/trunk/include/rdma/ib_mad.h
@@ -108,13 +108,6 @@
#define IB_QP1_QKEY 0x80010000
#define IB_QP_SET_QKEY 0x80000000
-enum {
- IB_MGMT_MAD_DATA = 232,
- IB_MGMT_RMPP_DATA = 220,
- IB_MGMT_VENDOR_DATA = 216,
- IB_MGMT_SA_DATA = 200
-};
-
struct ib_mad_hdr {
u8 base_version;
u8 mgmt_class;
@@ -156,20 +149,20 @@ struct ib_sa_hdr {
struct ib_mad {
struct ib_mad_hdr mad_hdr;
- u8 data[IB_MGMT_MAD_DATA];
+ u8 data[232];
};
struct ib_rmpp_mad {
struct ib_mad_hdr mad_hdr;
struct ib_rmpp_hdr rmpp_hdr;
- u8 data[IB_MGMT_RMPP_DATA];
+ u8 data[220];
};
struct ib_sa_mad {
struct ib_mad_hdr mad_hdr;
struct ib_rmpp_hdr rmpp_hdr;
struct ib_sa_hdr sa_hdr;
- u8 data[IB_MGMT_SA_DATA];
+ u8 data[200];
} __attribute__ ((packed));
struct ib_vendor_mad {
@@ -177,7 +170,7 @@ struct ib_vendor_mad {
struct ib_rmpp_hdr rmpp_hdr;
u8 reserved;
u8 oui[3];
- u8 data[IB_MGMT_VENDOR_DATA];
+ u8 data[216];
};
struct ib_class_port_info
diff --git a/trunk/include/scsi/scsi_host.h b/trunk/include/scsi/scsi_host.h
index 69313ba7505b..916144be208b 100644
--- a/trunk/include/scsi/scsi_host.h
+++ b/trunk/include/scsi/scsi_host.h
@@ -439,8 +439,6 @@ enum scsi_host_state {
SHOST_CANCEL,
SHOST_DEL,
SHOST_RECOVERY,
- SHOST_CANCEL_RECOVERY,
- SHOST_DEL_RECOVERY,
};
struct Scsi_Host {
@@ -467,6 +465,8 @@ struct Scsi_Host {
struct list_head eh_cmd_q;
struct task_struct * ehandler; /* Error recovery thread. */
+ struct semaphore * eh_wait; /* The error recovery thread waits
+ on this. */
struct semaphore * eh_action; /* Wait for specific actions on the
host. */
unsigned int eh_active:1; /* Indicates the eh thread is awake and active if
@@ -621,13 +621,6 @@ static inline struct Scsi_Host *dev_to_shost(struct device *dev)
return container_of(dev, struct Scsi_Host, shost_gendev);
}
-static inline int scsi_host_in_recovery(struct Scsi_Host *shost)
-{
- return shost->shost_state == SHOST_RECOVERY ||
- shost->shost_state == SHOST_CANCEL_RECOVERY ||
- shost->shost_state == SHOST_DEL_RECOVERY;
-}
-
extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *);
extern void scsi_flush_work(struct Scsi_Host *);
diff --git a/trunk/include/scsi/scsi_transport_fc.h b/trunk/include/scsi/scsi_transport_fc.h
index b0d445437372..115db056dc6b 100644
--- a/trunk/include/scsi/scsi_transport_fc.h
+++ b/trunk/include/scsi/scsi_transport_fc.h
@@ -103,8 +103,8 @@ enum fc_port_state {
incapable of reporting */
#define FC_PORTSPEED_1GBIT 1
#define FC_PORTSPEED_2GBIT 2
-#define FC_PORTSPEED_4GBIT 4
-#define FC_PORTSPEED_10GBIT 8
+#define FC_PORTSPEED_10GBIT 4
+#define FC_PORTSPEED_4GBIT 8
#define FC_PORTSPEED_NOT_NEGOTIATED (1 << 15) /* Speed not established */
/*
diff --git a/trunk/kernel/printk.c b/trunk/kernel/printk.c
index 4b8f0f9230a4..a967605bc2e3 100644
--- a/trunk/kernel/printk.c
+++ b/trunk/kernel/printk.c
@@ -488,11 +488,6 @@ static int __init printk_time_setup(char *str)
__setup("time", printk_time_setup);
-__attribute__((weak)) unsigned long long printk_clock(void)
-{
- return sched_clock();
-}
-
/*
* This is printk. It can be called from any context. We want it to work.
*
@@ -570,7 +565,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
loglev_char = default_message_loglevel
+ '0';
}
- t = printk_clock();
+ t = sched_clock();
nanosec_rem = do_div(t, 1000000000);
tlen = sprintf(tbuf,
"<%c>[%5lu.%06lu] ",
diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c
index fa11d91242e8..8b8e05f07cdb 100644
--- a/trunk/mm/mmap.c
+++ b/trunk/mm/mmap.c
@@ -1640,7 +1640,7 @@ static void unmap_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
/*
* Get rid of page table information in the indicated region.
*
- * Called with the mm semaphore held.
+ * Called with the page table lock held.
*/
static void unmap_region(struct mm_struct *mm,
struct vm_area_struct *vma, struct vm_area_struct *prev,
diff --git a/trunk/mm/mprotect.c b/trunk/mm/mprotect.c
index 57577f63b305..e9fbd013ad9a 100644
--- a/trunk/mm/mprotect.c
+++ b/trunk/mm/mprotect.c
@@ -248,8 +248,7 @@ sys_mprotect(unsigned long start, size_t len, unsigned long prot)
newflags = vm_flags | (vma->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC));
- /* newflags >> 4 shift VM_MAY% in place of VM_% */
- if ((newflags & ~(newflags >> 4)) & (VM_READ | VM_WRITE | VM_EXEC)) {
+ if ((newflags & ~(newflags >> 4)) & 0xf) {
error = -EACCES;
goto out;
}
diff --git a/trunk/net/ipv4/fib_trie.c b/trunk/net/ipv4/fib_trie.c
index 50c0519cd70d..90ae70870a10 100644
--- a/trunk/net/ipv4/fib_trie.c
+++ b/trunk/net/ipv4/fib_trie.c
@@ -1086,7 +1086,7 @@ fib_insert_node(struct trie *t, int *err, u32 key, int plen)
}
if (tp && tp->pos + tp->bits > 32)
- printk(KERN_WARNING "fib_trie tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",
+ printk("ERROR tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",
tp, tp->pos, tp->bits, key, plen);
/* Rebalance the trie */
@@ -1832,7 +1832,16 @@ static int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah, struct fi
i++;
continue;
}
- BUG_ON(!fa->fa_info);
+ if (fa->fa_info->fib_nh == NULL) {
+ printk("Trie error _fib_nh=NULL in fa[%d] k=%08x plen=%d\n", i, key, plen);
+ i++;
+ continue;
+ }
+ if (fa->fa_info == NULL) {
+ printk("Trie error fa_info=NULL in fa[%d] k=%08x plen=%d\n", i, key, plen);
+ i++;
+ continue;
+ }
if (fib_dump_info(skb, NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq,
@@ -1955,7 +1964,7 @@ struct fib_table * __init fib_hash_init(int id)
trie_main = t;
if (id == RT_TABLE_LOCAL)
- printk(KERN_INFO "IPv4 FIB: Using LC-trie version %s\n", VERSION);
+ printk("IPv4 FIB: Using LC-trie version %s\n", VERSION);
return tb;
}
diff --git a/trunk/net/ipv4/tcp_minisocks.c b/trunk/net/ipv4/tcp_minisocks.c
index b1a63b2c6b4a..a88db28b0af7 100644
--- a/trunk/net/ipv4/tcp_minisocks.c
+++ b/trunk/net/ipv4/tcp_minisocks.c
@@ -384,7 +384,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
newtp->frto_counter = 0;
newtp->frto_highmark = 0;
- newicsk->icsk_ca_ops = &tcp_init_congestion_ops;
+ newicsk->icsk_ca_ops = &tcp_reno;
tcp_set_ca_state(newsk, TCP_CA_Open);
tcp_init_xmit_timers(newsk);
diff --git a/trunk/net/packet/af_packet.c b/trunk/net/packet/af_packet.c
index ee865d88183b..8690f171c1ef 100644
--- a/trunk/net/packet/af_packet.c
+++ b/trunk/net/packet/af_packet.c
@@ -36,11 +36,6 @@
* Michal Ostrowski : Module initialization cleanup.
* Ulises Alonso : Frame number limit removal and
* packet_set_ring memory leak.
- * Eric Biederman : Allow for > 8 byte hardware addresses.
- * The convention is that longer addresses
- * will simply extend the hardware address
- * byte arrays at the end of sockaddr_ll
- * and packet_mreq.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -166,17 +161,7 @@ struct packet_mclist
int count;
unsigned short type;
unsigned short alen;
- unsigned char addr[MAX_ADDR_LEN];
-};
-/* identical to struct packet_mreq except it has
- * a longer address field.
- */
-struct packet_mreq_max
-{
- int mr_ifindex;
- unsigned short mr_type;
- unsigned short mr_alen;
- unsigned char mr_address[MAX_ADDR_LEN];
+ unsigned char addr[8];
};
#endif
#ifdef CONFIG_PACKET_MMAP
@@ -731,8 +716,6 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
err = -EINVAL;
if (msg->msg_namelen < sizeof(struct sockaddr_ll))
goto out;
- if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr)))
- goto out;
ifindex = saddr->sll_ifindex;
proto = saddr->sll_protocol;
addr = saddr->sll_addr;
@@ -761,12 +744,6 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
if (dev->hard_header) {
int res;
err = -EINVAL;
- if (saddr) {
- if (saddr->sll_halen != dev->addr_len)
- goto out_free;
- if (saddr->sll_hatype != dev->type)
- goto out_free;
- }
res = dev->hard_header(skb, dev, ntohs(proto), addr, NULL, len);
if (sock->type != SOCK_DGRAM) {
skb->tail = skb->data;
@@ -1068,7 +1045,6 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
struct sock *sk = sock->sk;
struct sk_buff *skb;
int copied, err;
- struct sockaddr_ll *sll;
err = -EINVAL;
if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
@@ -1080,6 +1056,16 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
return -ENODEV;
#endif
+ /*
+ * If the address length field is there to be filled in, we fill
+ * it in now.
+ */
+
+ if (sock->type == SOCK_PACKET)
+ msg->msg_namelen = sizeof(struct sockaddr_pkt);
+ else
+ msg->msg_namelen = sizeof(struct sockaddr_ll);
+
/*
* Call the generic datagram receiver. This handles all sorts
* of horrible races and re-entrancy so we can forget about it
@@ -1100,17 +1086,6 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
if(skb==NULL)
goto out;
- /*
- * If the address length field is there to be filled in, we fill
- * it in now.
- */
-
- sll = (struct sockaddr_ll*)skb->cb;
- if (sock->type == SOCK_PACKET)
- msg->msg_namelen = sizeof(struct sockaddr_pkt);
- else
- msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr);
-
/*
* You lose any data beyond the buffer you gave. If it worries a
* user program they can ask the device for its MTU anyway.
@@ -1191,7 +1166,7 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr,
sll->sll_hatype = 0; /* Bad: we have no ARPHRD_UNSPEC */
sll->sll_halen = 0;
}
- *uaddr_len = offsetof(struct sockaddr_ll, sll_addr) + sll->sll_halen;
+ *uaddr_len = sizeof(*sll);
return 0;
}
@@ -1224,7 +1199,7 @@ static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, i
}
}
-static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq)
+static int packet_mc_add(struct sock *sk, struct packet_mreq *mreq)
{
struct packet_sock *po = pkt_sk(sk);
struct packet_mclist *ml, *i;
@@ -1274,7 +1249,7 @@ static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq)
return err;
}
-static int packet_mc_drop(struct sock *sk, struct packet_mreq_max *mreq)
+static int packet_mc_drop(struct sock *sk, struct packet_mreq *mreq)
{
struct packet_mclist *ml, **mlp;
@@ -1340,17 +1315,11 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
case PACKET_ADD_MEMBERSHIP:
case PACKET_DROP_MEMBERSHIP:
{
- struct packet_mreq_max mreq;
- int len = optlen;
- memset(&mreq, 0, sizeof(mreq));
- if (len < sizeof(struct packet_mreq))
+ struct packet_mreq mreq;
+ if (optlen sizeof(mreq))
- len = sizeof(mreq);
- if (copy_from_user(&mreq,optval,len))
+ if (copy_from_user(&mreq,optval,sizeof(mreq)))
return -EFAULT;
- if (len < (mreq.mr_alen + offsetof(struct packet_mreq, mr_address)))
- return -EINVAL;
if (optname == PACKET_ADD_MEMBERSHIP)
ret = packet_mc_add(sk, &mreq);
else
diff --git a/trunk/sound/sparc/cs4231.c b/trunk/sound/sparc/cs4231.c
index f4361c518e46..2fb27c4e951f 100644
--- a/trunk/sound/sparc/cs4231.c
+++ b/trunk/sound/sparc/cs4231.c
@@ -173,7 +173,7 @@ static cs4231_t *cs4231_list;
#define CS4231_GLOBALIRQ 0x01 /* IRQ is active */
-/* definitions for codec irq status - CS4231_IRQ_STATUS */
+/* definitions for codec irq status */
#define CS4231_PLAYBACK_IRQ 0x10
#define CS4231_RECORD_IRQ 0x20
@@ -402,7 +402,7 @@ static void snd_cs4231_outm(cs4231_t *chip, unsigned char reg,
udelay(100);
#ifdef CONFIG_SND_DEBUG
if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- snd_printdd("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
+ snd_printk("outm: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
#endif
if (chip->calibrate_mute) {
chip->image[reg] &= mask;
@@ -425,10 +425,6 @@ static void snd_cs4231_dout(cs4231_t *chip, unsigned char reg, unsigned char val
timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT);
timeout--)
udelay(100);
-#ifdef CONFIG_SND_DEBUG
- if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- snd_printdd("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
-#endif
__cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL));
__cs4231_writeb(chip, value, CS4231P(chip, REG));
mb();
@@ -444,12 +440,15 @@ static void snd_cs4231_out(cs4231_t *chip, unsigned char reg, unsigned char valu
udelay(100);
#ifdef CONFIG_SND_DEBUG
if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- snd_printdd("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
+ snd_printk("out: auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
#endif
__cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL));
__cs4231_writeb(chip, value, CS4231P(chip, REG));
chip->image[reg] = value;
mb();
+#if 0
+ printk("codec out - reg 0x%x = 0x%x\n", chip->mce_bit | reg, value);
+#endif
}
static unsigned char snd_cs4231_in(cs4231_t *chip, unsigned char reg)
@@ -463,14 +462,61 @@ static unsigned char snd_cs4231_in(cs4231_t *chip, unsigned char reg)
udelay(100);
#ifdef CONFIG_SND_DEBUG
if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- snd_printdd("in: auto calibration time out - reg = 0x%x\n", reg);
+ snd_printk("in: auto calibration time out - reg = 0x%x\n", reg);
#endif
__cs4231_writeb(chip, chip->mce_bit | reg, CS4231P(chip, REGSEL));
mb();
ret = __cs4231_readb(chip, CS4231P(chip, REG));
+#if 0
+ printk("codec in - reg 0x%x = 0x%x\n", chip->mce_bit | reg, ret);
+#endif
return ret;
}
+#if 0
+
+static void snd_cs4231_debug(cs4231_t *chip)
+{
+ printk("CS4231 REGS: INDEX = 0x%02x ",
+ __cs4231_readb(chip, CS4231P(chip, REGSEL)));
+ printk(" STATUS = 0x%02x\n",
+ __cs4231_readb(chip, CS4231P(chip, STATUS)));
+ printk(" 0x00: left input = 0x%02x ", snd_cs4231_in(chip, 0x00));
+ printk(" 0x10: alt 1 (CFIG 2) = 0x%02x\n", snd_cs4231_in(chip, 0x10));
+ printk(" 0x01: right input = 0x%02x ", snd_cs4231_in(chip, 0x01));
+ printk(" 0x11: alt 2 (CFIG 3) = 0x%02x\n", snd_cs4231_in(chip, 0x11));
+ printk(" 0x02: GF1 left input = 0x%02x ", snd_cs4231_in(chip, 0x02));
+ printk(" 0x12: left line in = 0x%02x\n", snd_cs4231_in(chip, 0x12));
+ printk(" 0x03: GF1 right input = 0x%02x ", snd_cs4231_in(chip, 0x03));
+ printk(" 0x13: right line in = 0x%02x\n", snd_cs4231_in(chip, 0x13));
+ printk(" 0x04: CD left input = 0x%02x ", snd_cs4231_in(chip, 0x04));
+ printk(" 0x14: timer low = 0x%02x\n", snd_cs4231_in(chip, 0x14));
+ printk(" 0x05: CD right input = 0x%02x ", snd_cs4231_in(chip, 0x05));
+ printk(" 0x15: timer high = 0x%02x\n", snd_cs4231_in(chip, 0x15));
+ printk(" 0x06: left output = 0x%02x ", snd_cs4231_in(chip, 0x06));
+ printk(" 0x16: left MIC (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x16));
+ printk(" 0x07: right output = 0x%02x ", snd_cs4231_in(chip, 0x07));
+ printk(" 0x17: right MIC (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x17));
+ printk(" 0x08: playback format = 0x%02x ", snd_cs4231_in(chip, 0x08));
+ printk(" 0x18: IRQ status = 0x%02x\n", snd_cs4231_in(chip, 0x18));
+ printk(" 0x09: iface (CFIG 1) = 0x%02x ", snd_cs4231_in(chip, 0x09));
+ printk(" 0x19: left line out = 0x%02x\n", snd_cs4231_in(chip, 0x19));
+ printk(" 0x0a: pin control = 0x%02x ", snd_cs4231_in(chip, 0x0a));
+ printk(" 0x1a: mono control = 0x%02x\n", snd_cs4231_in(chip, 0x1a));
+ printk(" 0x0b: init & status = 0x%02x ", snd_cs4231_in(chip, 0x0b));
+ printk(" 0x1b: right line out = 0x%02x\n", snd_cs4231_in(chip, 0x1b));
+ printk(" 0x0c: revision & mode = 0x%02x ", snd_cs4231_in(chip, 0x0c));
+ printk(" 0x1c: record format = 0x%02x\n", snd_cs4231_in(chip, 0x1c));
+ printk(" 0x0d: loopback = 0x%02x ", snd_cs4231_in(chip, 0x0d));
+ printk(" 0x1d: var freq (PnP) = 0x%02x\n", snd_cs4231_in(chip, 0x1d));
+ printk(" 0x0e: ply upr count = 0x%02x ", snd_cs4231_in(chip, 0x0e));
+ printk(" 0x1e: rec upr count = 0x%02x\n", snd_cs4231_in(chip, 0x1e));
+ printk(" 0x0f: ply lwr count = 0x%02x ", snd_cs4231_in(chip, 0x0f));
+ printk(" 0x1f: rec lwr count = 0x%02x\n", snd_cs4231_in(chip, 0x1f));
+}
+
+#endif
+
/*
* CS4231 detection / MCE routines
*/
@@ -482,12 +528,11 @@ static void snd_cs4231_busy_wait(cs4231_t *chip)
/* huh.. looks like this sequence is proper for CS4231A chip (GUS MAX) */
for (timeout = 5; timeout > 0; timeout--)
__cs4231_readb(chip, CS4231P(chip, REGSEL));
-
/* end of cleanup sequence */
- for (timeout = 500;
+ for (timeout = 250;
timeout > 0 && (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT);
timeout--)
- udelay(1000);
+ udelay(100);
}
static void snd_cs4231_mce_up(cs4231_t *chip)
@@ -500,12 +545,12 @@ static void snd_cs4231_mce_up(cs4231_t *chip)
udelay(100);
#ifdef CONFIG_SND_DEBUG
if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- snd_printdd("mce_up - auto calibration time out (0)\n");
+ snd_printk("mce_up - auto calibration time out (0)\n");
#endif
chip->mce_bit |= CS4231_MCE;
timeout = __cs4231_readb(chip, CS4231P(chip, REGSEL));
if (timeout == 0x80)
- snd_printdd("mce_up [%p]: serious init problem - codec still busy\n", chip->port);
+ snd_printk("mce_up [%p]: serious init problem - codec still busy\n", chip->port);
if (!(timeout & CS4231_MCE))
__cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL));
spin_unlock_irqrestore(&chip->lock, flags);
@@ -518,15 +563,18 @@ static void snd_cs4231_mce_down(cs4231_t *chip)
spin_lock_irqsave(&chip->lock, flags);
snd_cs4231_busy_wait(chip);
+#if 0
+ printk("(1) timeout = %i\n", timeout);
+#endif
#ifdef CONFIG_SND_DEBUG
if (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT)
- snd_printdd("mce_down [%p] - auto calibration time out (0)\n", CS4231P(chip, REGSEL));
+ snd_printk("mce_down [%p] - auto calibration time out (0)\n", CS4231P(chip, REGSEL));
#endif
chip->mce_bit &= ~CS4231_MCE;
timeout = __cs4231_readb(chip, CS4231P(chip, REGSEL));
__cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), CS4231P(chip, REGSEL));
if (timeout == 0x80)
- snd_printdd("mce_down [%p]: serious init problem - codec still busy\n", chip->port);
+ snd_printk("mce_down [%p]: serious init problem - codec still busy\n", chip->port);
if ((timeout & CS4231_MCE) == 0) {
spin_unlock_irqrestore(&chip->lock, flags);
return;
@@ -542,7 +590,9 @@ static void snd_cs4231_mce_down(cs4231_t *chip)
spin_unlock_irqrestore(&chip->lock, flags);
return;
}
-
+#if 0
+ printk("(2) timeout = %i, jiffies = %li\n", timeout, jiffies);
+#endif
/* in 10ms increments, check condition, up to 250ms */
timeout = 25;
while (snd_cs4231_in(chip, CS4231_TEST_INIT) & CS4231_CALIB_IN_PROGRESS) {
@@ -554,7 +604,9 @@ static void snd_cs4231_mce_down(cs4231_t *chip)
msleep(10);
spin_lock_irqsave(&chip->lock, flags);
}
-
+#if 0
+ printk("(3) jiffies = %li\n", jiffies);
+#endif
/* in 10ms increments, check condition, up to 100ms */
timeout = 10;
while (__cs4231_readb(chip, CS4231P(chip, REGSEL)) & CS4231_INIT) {
@@ -567,58 +619,54 @@ static void snd_cs4231_mce_down(cs4231_t *chip)
spin_lock_irqsave(&chip->lock, flags);
}
spin_unlock_irqrestore(&chip->lock, flags);
+#if 0
+ printk("(4) jiffies = %li\n", jiffies);
+ snd_printk("mce_down - exit = 0x%x\n", __cs4231_readb(chip, CS4231P(chip, REGSEL)));
+#endif
}
+#if 0 /* Unused for now... */
+static unsigned int snd_cs4231_get_count(unsigned char format, unsigned int size)
+{
+ switch (format & 0xe0) {
+ case CS4231_LINEAR_16:
+ case CS4231_LINEAR_16_BIG:
+ size >>= 1;
+ break;
+ case CS4231_ADPCM_16:
+ return size >> 2;
+ }
+ if (format & CS4231_STEREO)
+ size >>= 1;
+ return size;
+}
+#endif
+
#ifdef EBUS_SUPPORT
static void snd_cs4231_ebus_advance_dma(struct ebus_dma_info *p, snd_pcm_substream_t *substream, unsigned int *periods_sent)
{
snd_pcm_runtime_t *runtime = substream->runtime;
while (1) {
- unsigned int period_size = snd_pcm_lib_period_bytes(substream);
- unsigned int offset = period_size * (*periods_sent);
+ unsigned int dma_size = snd_pcm_lib_period_bytes(substream);
+ unsigned int offset = dma_size * (*periods_sent);
- if (period_size >= (1 << 24))
+ if (dma_size >= (1 << 24))
BUG();
- if (ebus_dma_request(p, runtime->dma_addr + offset, period_size))
+ if (ebus_dma_request(p, runtime->dma_addr + offset, dma_size))
return;
- (*periods_sent) = ((*periods_sent) + 1) % runtime->periods;
- }
-}
+#if 0
+ printk("ebus_advance: Sent period %u (size[%x] offset[%x])\n",
+ (*periods_sent), dma_size, offset);
#endif
-
-#ifdef SBUS_SUPPORT
-static void snd_cs4231_sbus_advance_dma(snd_pcm_substream_t *substream, unsigned int *periods_sent)
-{
- cs4231_t *chip = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
-
- unsigned int period_size = snd_pcm_lib_period_bytes(substream);
- unsigned int offset = period_size * (*periods_sent % runtime->periods);
-
- if (runtime->period_size > 0xffff + 1)
- BUG();
-
- switch (substream->stream) {
- case SNDRV_PCM_STREAM_PLAYBACK:
- sbus_writel(runtime->dma_addr + offset, chip->port + APCPNVA);
- sbus_writel(period_size, chip->port + APCPNC);
- break;
- case SNDRV_PCM_STREAM_CAPTURE:
- sbus_writel(runtime->dma_addr + offset, chip->port + APCCNVA);
- sbus_writel(period_size, chip->port + APCCNC);
- break;
+ (*periods_sent) = ((*periods_sent) + 1) % runtime->periods;
}
-
- (*periods_sent) = (*periods_sent + 1) % runtime->periods;
}
#endif
-static void cs4231_dma_trigger(snd_pcm_substream_t *substream, unsigned int what, int on)
+static void cs4231_dma_trigger(cs4231_t *chip, unsigned int what, int on)
{
- cs4231_t *chip = snd_pcm_substream_chip(substream);
-
#ifdef EBUS_SUPPORT
if (chip->flags & CS4231_FLAG_EBUS) {
if (what & CS4231_PLAYBACK_ENABLE) {
@@ -646,60 +694,6 @@ static void cs4231_dma_trigger(snd_pcm_substream_t *substream, unsigned int what
} else {
#endif
#ifdef SBUS_SUPPORT
- u32 csr = sbus_readl(chip->port + APCCSR);
- /* I don't know why, but on sbus the period counter must
- * only start counting after the first period is sent.
- * Therefore this dummy thing.
- */
- unsigned int dummy = 0;
-
- switch (what) {
- case CS4231_PLAYBACK_ENABLE:
- if (on) {
- csr &= ~APC_XINT_PLAY;
- sbus_writel(csr, chip->port + APCCSR);
-
- csr &= ~APC_PPAUSE;
- sbus_writel(csr, chip->port + APCCSR);
-
- snd_cs4231_sbus_advance_dma(substream, &dummy);
-
- csr |= APC_GENL_INT | APC_PLAY_INT | APC_XINT_ENA |
- APC_XINT_PLAY | APC_XINT_EMPT | APC_XINT_GENL |
- APC_XINT_PENA | APC_PDMA_READY;
- sbus_writel(csr, chip->port + APCCSR);
- } else {
- csr |= APC_PPAUSE;
- sbus_writel(csr, chip->port + APCCSR);
-
- csr &= ~APC_PDMA_READY;
- sbus_writel(csr, chip->port + APCCSR);
- }
- break;
- case CS4231_RECORD_ENABLE:
- if (on) {
- csr &= ~APC_XINT_CAPT;
- sbus_writel(csr, chip->port + APCCSR);
-
- csr &= ~APC_CPAUSE;
- sbus_writel(csr, chip->port + APCCSR);
-
- snd_cs4231_sbus_advance_dma(substream, &dummy);
-
- csr |= APC_GENL_INT | APC_CAPT_INT | APC_XINT_ENA |
- APC_XINT_CAPT | APC_XINT_CEMP | APC_XINT_GENL |
- APC_CDMA_READY;
-
- sbus_writel(csr, chip->port + APCCSR);
- } else {
- csr |= APC_CPAUSE;
- sbus_writel(csr, chip->port + APCCSR);
-
- csr &= ~APC_CDMA_READY;
- sbus_writel(csr, chip->port + APCCSR);
- }
- break;
- }
#endif
#ifdef EBUS_SUPPORT
}
@@ -731,12 +725,25 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd)
}
}
+#if 0
+ printk("TRIGGER: what[%x] on(%d)\n",
+ what, (cmd == SNDRV_PCM_TRIGGER_START));
+#endif
+
spin_lock_irqsave(&chip->lock, flags);
if (cmd == SNDRV_PCM_TRIGGER_START) {
- cs4231_dma_trigger(substream, what, 1);
+ cs4231_dma_trigger(chip, what, 1);
chip->image[CS4231_IFACE_CTRL] |= what;
+ if (what & CS4231_PLAYBACK_ENABLE) {
+ snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, 0xff);
+ snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, 0xff);
+ }
+ if (what & CS4231_RECORD_ENABLE) {
+ snd_cs4231_out(chip, CS4231_REC_LWR_CNT, 0xff);
+ snd_cs4231_out(chip, CS4231_REC_UPR_CNT, 0xff);
+ }
} else {
- cs4231_dma_trigger(substream, what, 0);
+ cs4231_dma_trigger(chip, what, 0);
chip->image[CS4231_IFACE_CTRL] &= ~what;
}
snd_cs4231_out(chip, CS4231_IFACE_CTRL,
@@ -748,7 +755,9 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd)
result = -EINVAL;
break;
}
-
+#if 0
+ snd_cs4231_debug(chip);
+#endif
return result;
}
@@ -781,6 +790,9 @@ static unsigned char snd_cs4231_get_format(cs4231_t *chip, int format, int chann
}
if (channels > 1)
rformat |= CS4231_STEREO;
+#if 0
+ snd_printk("get_format: 0x%x (mode=0x%x)\n", format, mode);
+#endif
return rformat;
}
@@ -932,7 +944,7 @@ static void snd_cs4231_init(cs4231_t *chip)
snd_cs4231_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
- snd_printdd("init: (1)\n");
+ snd_printk("init: (1)\n");
#endif
snd_cs4231_mce_up(chip);
spin_lock_irqsave(&chip->lock, flags);
@@ -945,7 +957,7 @@ static void snd_cs4231_init(cs4231_t *chip)
snd_cs4231_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
- snd_printdd("init: (2)\n");
+ snd_printk("init: (2)\n");
#endif
snd_cs4231_mce_up(chip);
@@ -955,7 +967,7 @@ static void snd_cs4231_init(cs4231_t *chip)
snd_cs4231_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
- snd_printdd("init: (3) - afei = 0x%x\n", chip->image[CS4231_ALT_FEATURE_1]);
+ snd_printk("init: (3) - afei = 0x%x\n", chip->image[CS4231_ALT_FEATURE_1]);
#endif
spin_lock_irqsave(&chip->lock, flags);
@@ -969,7 +981,7 @@ static void snd_cs4231_init(cs4231_t *chip)
snd_cs4231_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
- snd_printdd("init: (4)\n");
+ snd_printk("init: (4)\n");
#endif
snd_cs4231_mce_up(chip);
@@ -979,7 +991,7 @@ static void snd_cs4231_init(cs4231_t *chip)
snd_cs4231_mce_down(chip);
#ifdef SNDRV_DEBUG_MCE
- snd_printdd("init: (5)\n");
+ snd_printk("init: (5)\n");
#endif
}
@@ -1010,7 +1022,6 @@ static int snd_cs4231_open(cs4231_t *chip, unsigned int mode)
CS4231_RECORD_IRQ |
CS4231_TIMER_IRQ);
snd_cs4231_out(chip, CS4231_IRQ_STATUS, 0);
-
spin_unlock_irqrestore(&chip->lock, flags);
chip->mode = mode;
@@ -1125,21 +1136,11 @@ static int snd_cs4231_playback_hw_free(snd_pcm_substream_t *substream)
static int snd_cs4231_playback_prepare(snd_pcm_substream_t *substream)
{
cs4231_t *chip = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
-
chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_PLAYBACK_ENABLE |
CS4231_PLAYBACK_PIO);
-
- if (runtime->period_size > 0xffff + 1)
- BUG();
-
- snd_cs4231_out(chip, CS4231_PLY_LWR_CNT, (runtime->period_size - 1) & 0x00ff);
- snd_cs4231_out(chip, CS4231_PLY_UPR_CNT, (runtime->period_size - 1) >> 8 & 0x00ff);
- chip->p_periods_sent = 0;
-
spin_unlock_irqrestore(&chip->lock, flags);
return 0;
@@ -1171,16 +1172,12 @@ static int snd_cs4231_capture_hw_free(snd_pcm_substream_t *substream)
static int snd_cs4231_capture_prepare(snd_pcm_substream_t *substream)
{
cs4231_t *chip = snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
unsigned long flags;
spin_lock_irqsave(&chip->lock, flags);
chip->image[CS4231_IFACE_CTRL] &= ~(CS4231_RECORD_ENABLE |
CS4231_RECORD_PIO);
- snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (runtime->period_size - 1) & 0x00ff);
- snd_cs4231_out(chip, CS4231_REC_LWR_CNT, (runtime->period_size - 1) >> 8 & 0x00ff);
-
spin_unlock_irqrestore(&chip->lock, flags);
return 0;
@@ -1199,61 +1196,53 @@ static void snd_cs4231_overrange(cs4231_t *chip)
chip->capture_substream->runtime->overrange++;
}
-static irqreturn_t snd_cs4231_generic_interrupt(cs4231_t *chip)
+static void snd_cs4231_generic_interrupt(cs4231_t *chip)
{
unsigned long flags;
unsigned char status;
- /*This is IRQ is not raised by the cs4231*/
- if (!(__cs4231_readb(chip, CS4231P(chip, STATUS)) & CS4231_GLOBALIRQ))
- return IRQ_NONE;
-
status = snd_cs4231_in(chip, CS4231_IRQ_STATUS);
+ if (!status)
+ return;
if (status & CS4231_TIMER_IRQ) {
if (chip->timer)
snd_timer_interrupt(chip->timer, chip->timer->sticks);
}
-
- if (status & CS4231_RECORD_IRQ)
+ if (status & CS4231_PLAYBACK_IRQ)
+ snd_pcm_period_elapsed(chip->playback_substream);
+ if (status & CS4231_RECORD_IRQ) {
snd_cs4231_overrange(chip);
+ snd_pcm_period_elapsed(chip->capture_substream);
+ }
/* ACK the CS4231 interrupt. */
spin_lock_irqsave(&chip->lock, flags);
snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0);
spin_unlock_irqrestore(&chip->lock, flags);
-
- return 0;
}
#ifdef SBUS_SUPPORT
static irqreturn_t snd_cs4231_sbus_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
cs4231_t *chip = dev_id;
+ u32 csr;
+
+ csr = sbus_readl(chip->port + APCCSR);
+ if (!(csr & (APC_INT_PENDING |
+ APC_PLAY_INT |
+ APC_CAPT_INT |
+ APC_GENL_INT |
+ APC_XINT_PEMP |
+ APC_XINT_CEMP)))
+ return IRQ_NONE;
/* ACK the APC interrupt. */
- u32 csr = sbus_readl(chip->port + APCCSR);
-
sbus_writel(csr, chip->port + APCCSR);
- if ((chip->image[CS4231_IFACE_CTRL] & CS4231_PLAYBACK_ENABLE) &&
- (csr & APC_PLAY_INT) &&
- (csr & APC_XINT_PNVA) &&
- !(csr & APC_XINT_EMPT)) {
- snd_cs4231_sbus_advance_dma(chip->playback_substream,
- &chip->p_periods_sent);
- snd_pcm_period_elapsed(chip->playback_substream);
- }
+ snd_cs4231_generic_interrupt(chip);
- if ((chip->image[CS4231_IFACE_CTRL] & CS4231_RECORD_ENABLE) &&
- (csr & APC_CAPT_INT) &&
- (csr & APC_XINT_CNVA)) {
- snd_cs4231_sbus_advance_dma(chip->capture_substream,
- &chip->c_periods_sent);
- snd_pcm_period_elapsed(chip->capture_substream);
- }
-
- return snd_cs4231_generic_interrupt(chip);
+ return IRQ_HANDLED;
}
#endif
@@ -1301,8 +1290,7 @@ static snd_pcm_uframes_t snd_cs4231_playback_pointer(snd_pcm_substream_t *substr
#ifdef EBUS_SUPPORT
}
#endif
- ptr += period_bytes - residue;
-
+ ptr += (period_bytes - residue);
return bytes_to_frames(substream->runtime, ptr);
}
@@ -1326,7 +1314,7 @@ static snd_pcm_uframes_t snd_cs4231_capture_pointer(snd_pcm_substream_t * substr
#ifdef EBUS_SUPPORT
}
#endif
- ptr += period_bytes - residue;
+ ptr += (period_bytes - residue);
return bytes_to_frames(substream->runtime, ptr);
}
@@ -1340,6 +1328,9 @@ static int snd_cs4231_probe(cs4231_t *chip)
int i, id, vers;
unsigned char *ptr;
+#if 0
+ snd_cs4231_debug(chip);
+#endif
id = vers = 0;
for (i = 0; i < 50; i++) {
mb();
@@ -1994,13 +1985,13 @@ static int __init snd_cs4231_sbus_create(snd_card_t *card,
chip->port = sbus_ioremap(&sdev->resource[0], 0,
chip->regs_size, "cs4231");
if (!chip->port) {
- snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev);
+ snd_printk("cs4231-%d: Unable to map chip registers.\n", dev);
return -EIO;
}
if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt,
SA_SHIRQ, "cs4231", chip)) {
- snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %s\n",
+ snd_printk("cs4231-%d: Unable to grab SBUS IRQ %s\n",
dev,
__irq_itoa(sdev->irqs[0]));
snd_cs4231_sbus_free(chip);
@@ -2122,29 +2113,29 @@ static int __init snd_cs4231_ebus_create(snd_card_t *card,
chip->eb2c.regs = ioremap(edev->resource[2].start, 0x10);
if (!chip->port || !chip->eb2p.regs || !chip->eb2c.regs) {
snd_cs4231_ebus_free(chip);
- snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev);
+ snd_printk("cs4231-%d: Unable to map chip registers.\n", dev);
return -EIO;
}
if (ebus_dma_register(&chip->eb2c)) {
snd_cs4231_ebus_free(chip);
- snd_printdd("cs4231-%d: Unable to register EBUS capture DMA\n", dev);
+ snd_printk("cs4231-%d: Unable to register EBUS capture DMA\n", dev);
return -EBUSY;
}
if (ebus_dma_irq_enable(&chip->eb2c, 1)) {
snd_cs4231_ebus_free(chip);
- snd_printdd("cs4231-%d: Unable to enable EBUS capture IRQ\n", dev);
+ snd_printk("cs4231-%d: Unable to enable EBUS capture IRQ\n", dev);
return -EBUSY;
}
if (ebus_dma_register(&chip->eb2p)) {
snd_cs4231_ebus_free(chip);
- snd_printdd("cs4231-%d: Unable to register EBUS play DMA\n", dev);
+ snd_printk("cs4231-%d: Unable to register EBUS play DMA\n", dev);
return -EBUSY;
}
if (ebus_dma_irq_enable(&chip->eb2p, 1)) {
snd_cs4231_ebus_free(chip);
- snd_printdd("cs4231-%d: Unable to enable EBUS play IRQ\n", dev);
+ snd_printk("cs4231-%d: Unable to enable EBUS play IRQ\n", dev);
return -EBUSY;
}