diff --git a/[refs] b/[refs] index f19ad8254ffb..9900b7089cfd 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: dbbffe6898fd0d7bac66ded5d3c58835b13ddefc +refs/heads/master: 416821d3d68164909b2cbcf398e4ba0797f5f8a2 diff --git a/trunk/Makefile b/trunk/Makefile index cd11e8857604..a3a834b11a97 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 -PATCHLEVEL = 10 +PATCHLEVEL = 9 SUBLEVEL = 0 -EXTRAVERSION = -rc1 +EXTRAVERSION = NAME = Unicycling Gorilla # *DOCUMENTATION* diff --git a/trunk/arch/parisc/Kconfig b/trunk/arch/parisc/Kconfig index cad060f288cf..6507dabdd5dd 100644 --- a/trunk/arch/parisc/Kconfig +++ b/trunk/arch/parisc/Kconfig @@ -245,7 +245,7 @@ config SMP config IRQSTACKS bool "Use separate kernel stacks when processing interrupts" - default n + default y help If you say Y here the kernel will use separate kernel stacks for handling hard and soft interrupts. This can help avoid diff --git a/trunk/arch/parisc/include/asm/hardirq.h b/trunk/arch/parisc/include/asm/hardirq.h index 12373c4dabab..c19f7138ba48 100644 --- a/trunk/arch/parisc/include/asm/hardirq.h +++ b/trunk/arch/parisc/include/asm/hardirq.h @@ -11,10 +11,18 @@ #include #include +#ifdef CONFIG_IRQSTACKS +#define __ARCH_HAS_DO_SOFTIRQ +#endif + typedef struct { unsigned int __softirq_pending; #ifdef CONFIG_DEBUG_STACKOVERFLOW unsigned int kernel_stack_usage; +#ifdef CONFIG_IRQSTACKS + unsigned int irq_stack_usage; + unsigned int irq_stack_counter; +#endif #endif #ifdef CONFIG_SMP unsigned int irq_resched_count; @@ -28,6 +36,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); #define __ARCH_IRQ_STAT #define __IRQ_STAT(cpu, member) (irq_stat[cpu].member) #define inc_irq_stat(member) this_cpu_inc(irq_stat.member) +#define __inc_irq_stat(member) __this_cpu_inc(irq_stat.member) #define local_softirq_pending() this_cpu_read(irq_stat.__softirq_pending) #define __ARCH_SET_SOFTIRQ_PENDING diff --git a/trunk/arch/parisc/include/asm/processor.h b/trunk/arch/parisc/include/asm/processor.h index 064015547d1e..cfbc43929cf6 100644 --- a/trunk/arch/parisc/include/asm/processor.h +++ b/trunk/arch/parisc/include/asm/processor.h @@ -63,10 +63,13 @@ */ #ifdef __KERNEL__ +#include + #define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */ union irq_stack_union { unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)]; + raw_spinlock_t lock; }; DECLARE_PER_CPU(union irq_stack_union, irq_stack_union); diff --git a/trunk/arch/parisc/kernel/irq.c b/trunk/arch/parisc/kernel/irq.c index e255db0bb761..55237a70e197 100644 --- a/trunk/arch/parisc/kernel/irq.c +++ b/trunk/arch/parisc/kernel/irq.c @@ -166,22 +166,32 @@ int arch_show_interrupts(struct seq_file *p, int prec) seq_printf(p, "%*s: ", prec, "STK"); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->kernel_stack_usage); - seq_printf(p, " Kernel stack usage\n"); + seq_puts(p, " Kernel stack usage\n"); +# ifdef CONFIG_IRQSTACKS + seq_printf(p, "%*s: ", prec, "IST"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", irq_stats(j)->irq_stack_usage); + seq_puts(p, " Interrupt stack usage\n"); + seq_printf(p, "%*s: ", prec, "ISC"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", irq_stats(j)->irq_stack_counter); + seq_puts(p, " Interrupt stack usage counter\n"); +# endif #endif #ifdef CONFIG_SMP seq_printf(p, "%*s: ", prec, "RES"); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count); - seq_printf(p, " Rescheduling interrupts\n"); + seq_puts(p, " Rescheduling interrupts\n"); seq_printf(p, "%*s: ", prec, "CAL"); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_call_count); - seq_printf(p, " Function call interrupts\n"); + seq_puts(p, " Function call interrupts\n"); #endif seq_printf(p, "%*s: ", prec, "TLB"); for_each_online_cpu(j) seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count); - seq_printf(p, " TLB shootdowns\n"); + seq_puts(p, " TLB shootdowns\n"); return 0; } @@ -378,6 +388,7 @@ static inline void stack_overflow_check(struct pt_regs *regs) unsigned long sp = regs->gr[30]; unsigned long stack_usage; unsigned int *last_usage; + int cpu = smp_processor_id(); /* if sr7 != 0, we interrupted a userspace process which we do not want * to check for stack overflow. We will only check the kernel stack. */ @@ -386,7 +397,31 @@ static inline void stack_overflow_check(struct pt_regs *regs) /* calculate kernel stack usage */ stack_usage = sp - stack_start; - last_usage = &per_cpu(irq_stat.kernel_stack_usage, smp_processor_id()); +#ifdef CONFIG_IRQSTACKS + if (likely(stack_usage <= THREAD_SIZE)) + goto check_kernel_stack; /* found kernel stack */ + + /* check irq stack usage */ + stack_start = (unsigned long) &per_cpu(irq_stack_union, cpu).stack; + stack_usage = sp - stack_start; + + last_usage = &per_cpu(irq_stat.irq_stack_usage, cpu); + if (unlikely(stack_usage > *last_usage)) + *last_usage = stack_usage; + + if (likely(stack_usage < (IRQ_STACK_SIZE - STACK_MARGIN))) + return; + + pr_emerg("stackcheck: %s will most likely overflow irq stack " + "(sp:%lx, stk bottom-top:%lx-%lx)\n", + current->comm, sp, stack_start, stack_start + IRQ_STACK_SIZE); + goto panic_check; + +check_kernel_stack: +#endif + + /* check kernel stack usage */ + last_usage = &per_cpu(irq_stat.kernel_stack_usage, cpu); if (unlikely(stack_usage > *last_usage)) *last_usage = stack_usage; @@ -398,31 +433,69 @@ static inline void stack_overflow_check(struct pt_regs *regs) "(sp:%lx, stk bottom-top:%lx-%lx)\n", current->comm, sp, stack_start, stack_start + THREAD_SIZE); +#ifdef CONFIG_IRQSTACKS +panic_check: +#endif if (sysctl_panic_on_stackoverflow) panic("low stack detected by irq handler - check messages\n"); #endif } #ifdef CONFIG_IRQSTACKS -DEFINE_PER_CPU(union irq_stack_union, irq_stack_union); +DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { + .lock = __RAW_SPIN_LOCK_UNLOCKED((irq_stack_union).lock) + }; static void execute_on_irq_stack(void *func, unsigned long param1) { - unsigned long *irq_stack_start; + union irq_stack_union *union_ptr; unsigned long irq_stack; - int cpu = smp_processor_id(); + raw_spinlock_t *irq_stack_in_use; - irq_stack_start = &per_cpu(irq_stack_union, cpu).stack[0]; - irq_stack = (unsigned long) irq_stack_start; - irq_stack = ALIGN(irq_stack, 16); /* align for stack frame usage */ + union_ptr = &per_cpu(irq_stack_union, smp_processor_id()); + irq_stack = (unsigned long) &union_ptr->stack; + irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.lock), + 64); /* align for stack frame usage */ - BUG_ON(*irq_stack_start); /* report bug if we were called recursive. */ - *irq_stack_start = 1; + /* We may be called recursive. If we are already using the irq stack, + * just continue to use it. Use spinlocks to serialize + * the irq stack usage. + */ + irq_stack_in_use = &union_ptr->lock; + if (!raw_spin_trylock(irq_stack_in_use)) { + void (*direct_call)(unsigned long p1) = func; + + /* We are using the IRQ stack already. + * Do direct call on current stack. */ + direct_call(param1); + return; + } /* This is where we switch to the IRQ stack. */ call_on_stack(param1, func, irq_stack); - *irq_stack_start = 0; + __inc_irq_stat(irq_stack_counter); + + /* free up irq stack usage. */ + do_raw_spin_unlock(irq_stack_in_use); +} + +asmlinkage void do_softirq(void) +{ + __u32 pending; + unsigned long flags; + + if (in_interrupt()) + return; + + local_irq_save(flags); + + pending = local_softirq_pending(); + + if (pending) + execute_on_irq_stack(__do_softirq, 0); + + local_irq_restore(flags); } #endif /* CONFIG_IRQSTACKS */ diff --git a/trunk/arch/parisc/mm/init.c b/trunk/arch/parisc/mm/init.c index ce939ac8622b..1c965642068b 100644 --- a/trunk/arch/parisc/mm/init.c +++ b/trunk/arch/parisc/mm/init.c @@ -1069,7 +1069,7 @@ void flush_tlb_all(void) { int do_recycle; - inc_irq_stat(irq_tlb_count); + __inc_irq_stat(irq_tlb_count); do_recycle = 0; spin_lock(&sid_lock); if (dirty_space_ids > RECYCLE_THRESHOLD) { @@ -1090,7 +1090,7 @@ void flush_tlb_all(void) #else void flush_tlb_all(void) { - inc_irq_stat(irq_tlb_count); + __inc_irq_stat(irq_tlb_count); spin_lock(&sid_lock); flush_tlb_all_local(NULL); recycle_sids(); diff --git a/trunk/arch/powerpc/kernel/entry_64.S b/trunk/arch/powerpc/kernel/entry_64.S index 915fbb4fc2fe..3fe5259e2fea 100644 --- a/trunk/arch/powerpc/kernel/entry_64.S +++ b/trunk/arch/powerpc/kernel/entry_64.S @@ -150,7 +150,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) CURRENT_THREAD_INFO(r11, r1) ld r10,TI_FLAGS(r11) andi. r11,r10,_TIF_SYSCALL_T_OR_A - bne syscall_dotrace + bne- syscall_dotrace .Lsyscall_dotrace_cont: cmpldi 0,r0,NR_syscalls bge- syscall_enosys diff --git a/trunk/arch/x86/include/uapi/asm/msr-index.h b/trunk/arch/x86/include/uapi/asm/msr-index.h index 2af848dfa754..b3a4866661c5 100644 --- a/trunk/arch/x86/include/uapi/asm/msr-index.h +++ b/trunk/arch/x86/include/uapi/asm/msr-index.h @@ -120,9 +120,6 @@ #define MSR_CORE_C6_RESIDENCY 0x000003fd #define MSR_CORE_C7_RESIDENCY 0x000003fe #define MSR_PKG_C2_RESIDENCY 0x0000060d -#define MSR_PKG_C8_RESIDENCY 0x00000630 -#define MSR_PKG_C9_RESIDENCY 0x00000631 -#define MSR_PKG_C10_RESIDENCY 0x00000632 /* Run Time Average Power Limiting (RAPL) Interface */ diff --git a/trunk/arch/x86/pci/xen.c b/trunk/arch/x86/pci/xen.c index 48e8461057ba..4a9be6ddf054 100644 --- a/trunk/arch/x86/pci/xen.c +++ b/trunk/arch/x86/pci/xen.c @@ -295,10 +295,11 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) int pos; u32 table_offset, bir; - pos = dev->msix_cap; + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); + pci_read_config_dword(dev, pos + PCI_MSIX_TABLE, &table_offset); - bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR); + bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); map_irq.table_base = pci_resource_start(dev, bir); map_irq.entry_nr = msidesc->msi_attrib.entry_nr; diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c index a492be2635ac..53d4f680c9b5 100644 --- a/trunk/arch/x86/xen/enlighten.c +++ b/trunk/arch/x86/xen/enlighten.c @@ -85,29 +85,7 @@ EXPORT_SYMBOL_GPL(hypercall_page); -/* - * Pointer to the xen_vcpu_info structure or - * &HYPERVISOR_shared_info->vcpu_info[cpu]. See xen_hvm_init_shared_info - * and xen_vcpu_setup for details. By default it points to share_info->vcpu_info - * but if the hypervisor supports VCPUOP_register_vcpu_info then it can point - * to xen_vcpu_info. The pointer is used in __xen_evtchn_do_upcall to - * acknowledge pending events. - * Also more subtly it is used by the patched version of irq enable/disable - * e.g. xen_irq_enable_direct and xen_iret in PV mode. - * - * The desire to be able to do those mask/unmask operations as a single - * instruction by using the per-cpu offset held in %gs is the real reason - * vcpu info is in a per-cpu pointer and the original reason for this - * hypercall. - * - */ DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); - -/* - * Per CPU pages used if hypervisor supports VCPUOP_register_vcpu_info - * hypercall. This can be used both in PV and PVHVM mode. The structure - * overrides the default per_cpu(xen_vcpu, cpu) value. - */ DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info); enum xen_domain_type xen_domain_type = XEN_NATIVE; @@ -179,21 +157,6 @@ static void xen_vcpu_setup(int cpu) BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info); - /* - * This path is called twice on PVHVM - first during bootup via - * smp_init -> xen_hvm_cpu_notify, and then if the VCPU is being - * hotplugged: cpu_up -> xen_hvm_cpu_notify. - * As we can only do the VCPUOP_register_vcpu_info once lets - * not over-write its result. - * - * For PV it is called during restore (xen_vcpu_restore) and bootup - * (xen_setup_vcpu_info_placement). The hotplug mechanism does not - * use this function. - */ - if (xen_hvm_domain()) { - if (per_cpu(xen_vcpu, cpu) == &per_cpu(xen_vcpu_info, cpu)) - return; - } if (cpu < MAX_VIRT_CPUS) per_cpu(xen_vcpu,cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; @@ -209,12 +172,7 @@ static void xen_vcpu_setup(int cpu) /* Check to see if the hypervisor will put the vcpu_info structure where we want it, which allows direct access via - a percpu-variable. - N.B. This hypercall can _only_ be called once per CPU. Subsequent - calls will error out with -EINVAL. This is due to the fact that - hypervisor has no unregister variant and this hypercall does not - allow to over-write info.mfn and info.offset. - */ + a percpu-variable. */ err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info); if (err) { @@ -429,9 +387,6 @@ static void __init xen_init_cpuid_mask(void) cpuid_leaf1_edx_mask &= ~((1 << X86_FEATURE_APIC) | /* disable local APIC */ (1 << X86_FEATURE_ACPI)); /* disable ACPI */ - - cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_X2APIC % 32)); - ax = 1; cx = 0; xen_cpuid(&ax, &bx, &cx, &dx); @@ -1648,9 +1603,6 @@ void __ref xen_hvm_init_shared_info(void) * online but xen_hvm_init_shared_info is run at resume time too and * in that case multiple vcpus might be online. */ for_each_online_cpu(cpu) { - /* Leave it to be NULL. */ - if (cpu >= MAX_VIRT_CPUS) - continue; per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; } } diff --git a/trunk/arch/x86/xen/spinlock.c b/trunk/arch/x86/xen/spinlock.c index 3002ec1bb71a..8b54603ce816 100644 --- a/trunk/arch/x86/xen/spinlock.c +++ b/trunk/arch/x86/xen/spinlock.c @@ -364,7 +364,7 @@ void __cpuinit xen_init_lock_cpu(int cpu) int irq; const char *name; - WARN(per_cpu(lock_kicker_irq, cpu) >= 0, "spinlock on CPU%d exists on IRQ%d!\n", + WARN(per_cpu(lock_kicker_irq, cpu) > 0, "spinlock on CPU%d exists on IRQ%d!\n", cpu, per_cpu(lock_kicker_irq, cpu)); /* diff --git a/trunk/drivers/gpu/drm/drm_crtc.c b/trunk/drivers/gpu/drm/drm_crtc.c index e7e92429d10f..3a8f7e6db295 100644 --- a/trunk/drivers/gpu/drm/drm_crtc.c +++ b/trunk/drivers/gpu/drm/drm_crtc.c @@ -78,10 +78,6 @@ void drm_warn_on_modeset_not_all_locked(struct drm_device *dev) { struct drm_crtc *crtc; - /* Locking is currently fubar in the panic handler. */ - if (oops_in_progress) - return; - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) WARN_ON(!mutex_is_locked(&crtc->mutex)); @@ -250,7 +246,6 @@ char *drm_get_connector_status_name(enum drm_connector_status status) else return "unknown"; } -EXPORT_SYMBOL(drm_get_connector_status_name); /** * drm_mode_object_get - allocate a new modeset identifier diff --git a/trunk/drivers/gpu/drm/drm_crtc_helper.c b/trunk/drivers/gpu/drm/drm_crtc_helper.c index ed1334e27c33..e974f9309b72 100644 --- a/trunk/drivers/gpu/drm/drm_crtc_helper.c +++ b/trunk/drivers/gpu/drm/drm_crtc_helper.c @@ -121,7 +121,6 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, connector->helper_private; int count = 0; int mode_flags = 0; - bool verbose_prune = true; DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, drm_get_connector_name(connector)); @@ -150,7 +149,6 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", connector->base.id, drm_get_connector_name(connector)); drm_mode_connector_update_edid_property(connector, NULL); - verbose_prune = false; goto prune; } @@ -184,7 +182,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, } prune: - drm_mode_prune_invalid(dev, &connector->modes, verbose_prune); + drm_mode_prune_invalid(dev, &connector->modes, true); if (list_empty(&connector->modes)) return 0; @@ -1007,20 +1005,12 @@ static void output_poll_execute(struct work_struct *work) continue; connector->status = connector->funcs->detect(connector, false); - if (old_status != connector->status) { - const char *old, *new; - - old = drm_get_connector_status_name(old_status); - new = drm_get_connector_status_name(connector->status); - - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] " - "status updated from %s to %s\n", - connector->base.id, - drm_get_connector_name(connector), - old, new); - + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n", + connector->base.id, + drm_get_connector_name(connector), + old_status, connector->status); + if (old_status != connector->status) changed = true; - } } mutex_unlock(&dev->mode_config.mutex); @@ -1093,11 +1083,10 @@ void drm_helper_hpd_irq_event(struct drm_device *dev) old_status = connector->status; connector->status = connector->funcs->detect(connector, false); - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n", + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n", connector->base.id, drm_get_connector_name(connector), - drm_get_connector_status_name(old_status), - drm_get_connector_status_name(connector->status)); + old_status, connector->status); if (old_status != connector->status) changed = true; } diff --git a/trunk/drivers/gpu/drm/drm_drv.c b/trunk/drivers/gpu/drm/drm_drv.c index 9cc247f55502..8d4f29075af5 100644 --- a/trunk/drivers/gpu/drm/drm_drv.c +++ b/trunk/drivers/gpu/drm/drm_drv.c @@ -57,7 +57,7 @@ static int drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv); #define DRM_IOCTL_DEF(ioctl, _func, _flags) \ - [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl} + [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0} /** Ioctl table */ static const struct drm_ioctl_desc drm_ioctls[] = { @@ -375,7 +375,7 @@ long drm_ioctl(struct file *filp, { struct drm_file *file_priv = filp->private_data; struct drm_device *dev; - const struct drm_ioctl_desc *ioctl = NULL; + const struct drm_ioctl_desc *ioctl; drm_ioctl_t *func; unsigned int nr = DRM_IOCTL_NR(cmd); int retcode = -EINVAL; @@ -392,6 +392,11 @@ long drm_ioctl(struct file *filp, atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]); ++file_priv->ioctl_count; + DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", + task_pid_nr(current), cmd, nr, + (long)old_encode_dev(file_priv->minor->device), + file_priv->authenticated); + if ((nr >= DRM_CORE_IOCTL_COUNT) && ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) goto err_i1; @@ -412,11 +417,6 @@ long drm_ioctl(struct file *filp, } else goto err_i1; - DRM_DEBUG("pid=%d, dev=0x%lx, auth=%d, %s\n", - task_pid_nr(current), - (long)old_encode_dev(file_priv->minor->device), - file_priv->authenticated, ioctl->name); - /* Do not trust userspace, use our own definition */ func = ioctl->func; /* is there a local override? */ @@ -471,12 +471,6 @@ long drm_ioctl(struct file *filp, } err_i1: - if (!ioctl) - DRM_DEBUG("invalid iotcl: pid=%d, dev=0x%lx, auth=%d, cmd=0x%02x, nr=0x%02x\n", - task_pid_nr(current), - (long)old_encode_dev(file_priv->minor->device), - file_priv->authenticated, cmd, nr); - if (kdata != stack_kdata) kfree(kdata); atomic_dec(&dev->ioctl_count); diff --git a/trunk/drivers/gpu/drm/drm_encoder_slave.c b/trunk/drivers/gpu/drm/drm_encoder_slave.c index 0cfb60f54766..48c52f7df4e6 100644 --- a/trunk/drivers/gpu/drm/drm_encoder_slave.c +++ b/trunk/drivers/gpu/drm/drm_encoder_slave.c @@ -54,12 +54,16 @@ int drm_i2c_encoder_init(struct drm_device *dev, struct i2c_adapter *adap, const struct i2c_board_info *info) { + char modalias[sizeof(I2C_MODULE_PREFIX) + + I2C_NAME_SIZE]; struct module *module = NULL; struct i2c_client *client; struct drm_i2c_encoder_driver *encoder_drv; int err = 0; - request_module("%s%s", I2C_MODULE_PREFIX, info->type); + snprintf(modalias, sizeof(modalias), + "%s%s", I2C_MODULE_PREFIX, info->type); + request_module(modalias); client = i2c_new_device(adap, info); if (!client) { diff --git a/trunk/drivers/gpu/drm/drm_mm.c b/trunk/drivers/gpu/drm/drm_mm.c index 07cf99cc8862..db1e2d6f90d7 100644 --- a/trunk/drivers/gpu/drm/drm_mm.c +++ b/trunk/drivers/gpu/drm/drm_mm.c @@ -755,35 +755,33 @@ void drm_mm_debug_table(struct drm_mm *mm, const char *prefix) EXPORT_SYMBOL(drm_mm_debug_table); #if defined(CONFIG_DEBUG_FS) -static unsigned long drm_mm_dump_hole(struct seq_file *m, struct drm_mm_node *entry) -{ - unsigned long hole_start, hole_end, hole_size; - - if (entry->hole_follows) { - hole_start = drm_mm_hole_node_start(entry); - hole_end = drm_mm_hole_node_end(entry); - hole_size = hole_end - hole_start; - seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", - hole_start, hole_end, hole_size); - return hole_size; - } - - return 0; -} - int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) { struct drm_mm_node *entry; unsigned long total_used = 0, total_free = 0, total = 0; + unsigned long hole_start, hole_end, hole_size; - total_free += drm_mm_dump_hole(m, &mm->head_node); + hole_start = drm_mm_hole_node_start(&mm->head_node); + hole_end = drm_mm_hole_node_end(&mm->head_node); + hole_size = hole_end - hole_start; + if (hole_size) + seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", + hole_start, hole_end, hole_size); + total_free += hole_size; drm_mm_for_each_node(entry, mm) { seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: used\n", entry->start, entry->start + entry->size, entry->size); total_used += entry->size; - total_free += drm_mm_dump_hole(m, entry); + if (entry->hole_follows) { + hole_start = drm_mm_hole_node_start(entry); + hole_end = drm_mm_hole_node_end(entry); + hole_size = hole_end - hole_start; + seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", + hole_start, hole_end, hole_size); + total_free += hole_size; + } } total = total_free + total_used; diff --git a/trunk/drivers/gpu/drm/drm_modes.c b/trunk/drivers/gpu/drm/drm_modes.c index a371ff865a88..faa79df02648 100644 --- a/trunk/drivers/gpu/drm/drm_modes.c +++ b/trunk/drivers/gpu/drm/drm_modes.c @@ -1143,7 +1143,6 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, was_digit = false; } else goto done; - break; case '0' ... '9': was_digit = true; break; diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 6165535d15f0..6be940effefd 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -1045,8 +1045,6 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, if (timeout) { struct timespec sleep_time = timespec_sub(now, before); *timeout = timespec_sub(*timeout, sleep_time); - if (!timespec_valid(timeout)) /* i.e. negative time remains */ - set_normalized_timespec(timeout, 0, 0); } switch (end) { @@ -1055,6 +1053,8 @@ static int __wait_seqno(struct intel_ring_buffer *ring, u32 seqno, case -ERESTARTSYS: /* Signal */ return (int)end; case 0: /* Timeout */ + if (timeout) + set_normalized_timespec(timeout, 0, 0); return -ETIME; default: /* Completed */ WARN_ON(end < 0); /* We're not aware of other errors */ @@ -2377,8 +2377,10 @@ i915_gem_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *file) mutex_unlock(&dev->struct_mutex); ret = __wait_seqno(ring, seqno, reset_counter, true, timeout); - if (timeout) + if (timeout) { + WARN_ON(!timespec_valid(timeout)); args->timeout_ns = timespec_to_ns(timeout); + } return ret; out: diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c b/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c index bdb0d7717bc7..dca614de71b6 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -709,6 +709,15 @@ static inline size_t gen6_get_stolen_size(u16 snb_gmch_ctl) return snb_gmch_ctl << 25; /* 32 MB units */ } +static inline size_t gen7_get_stolen_size(u16 snb_gmch_ctl) +{ + static const int stolen_decoder[] = { + 0, 0, 0, 0, 0, 32, 48, 64, 128, 256, 96, 160, 224, 352}; + snb_gmch_ctl >>= IVB_GMCH_GMS_SHIFT; + snb_gmch_ctl &= IVB_GMCH_GMS_MASK; + return stolen_decoder[snb_gmch_ctl] << 20; +} + static int gen6_gmch_probe(struct drm_device *dev, size_t *gtt_total, size_t *stolen, @@ -738,7 +747,11 @@ static int gen6_gmch_probe(struct drm_device *dev, pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl); gtt_size = gen6_get_total_gtt_size(snb_gmch_ctl); - *stolen = gen6_get_stolen_size(snb_gmch_ctl); + if (IS_GEN7(dev) && !IS_VALLEYVIEW(dev)) + *stolen = gen7_get_stolen_size(snb_gmch_ctl); + else + *stolen = gen6_get_stolen_size(snb_gmch_ctl); + *gtt_total = (gtt_size / sizeof(gen6_gtt_pte_t)) << PAGE_SHIFT; /* For Modern GENs the PTEs and register space are split in the BAR */ diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index 2d6b62e42daf..83f9c26e1adb 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -46,6 +46,8 @@ #define SNB_GMCH_GGMS_MASK 0x3 #define SNB_GMCH_GMS_SHIFT 3 /* Graphics Mode Select */ #define SNB_GMCH_GMS_MASK 0x1f +#define IVB_GMCH_GMS_SHIFT 4 +#define IVB_GMCH_GMS_MASK 0xf /* PCI config space */ diff --git a/trunk/drivers/gpu/drm/i915/intel_ddi.c b/trunk/drivers/gpu/drm/i915/intel_ddi.c index fb961bb81903..26a0a570f92e 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ddi.c +++ b/trunk/drivers/gpu/drm/i915/intel_ddi.c @@ -1265,8 +1265,6 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_start_link_train(intel_dp); intel_dp_complete_link_train(intel_dp); - if (port != PORT_A) - intel_dp_stop_link_train(intel_dp); } } @@ -1328,9 +1326,6 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder) } else if (type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - if (port == PORT_A) - intel_dp_stop_link_train(intel_dp); - ironlake_edp_backlight_on(intel_dp); } diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index 3d704b706a8d..fb2fbc1e08b9 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -702,9 +702,6 @@ intel_dp_compute_config(struct intel_encoder *encoder, /* Walk through all bpp values. Luckily they're all nicely spaced with 2 * bpc in between. */ bpp = min_t(int, 8*3, pipe_config->pipe_bpp); - if (is_edp(intel_dp) && dev_priv->edp.bpp) - bpp = min_t(int, bpp, dev_priv->edp.bpp); - for (; bpp >= 6*3; bpp -= 2*3) { mode_rate = intel_dp_link_required(target_clock, bpp); @@ -742,7 +739,6 @@ intel_dp_compute_config(struct intel_encoder *encoder, intel_dp->link_bw = bws[clock]; intel_dp->lane_count = lane_count; adjusted_mode->clock = drm_dp_bw_code_to_link_rate(intel_dp->link_bw); - pipe_config->pipe_bpp = bpp; pipe_config->pixel_target_clock = target_clock; DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n", @@ -755,6 +751,20 @@ intel_dp_compute_config(struct intel_encoder *encoder, target_clock, adjusted_mode->clock, &pipe_config->dp_m_n); + /* + * XXX: We have a strange regression where using the vbt edp bpp value + * for the link bw computation results in black screens, the panel only + * works when we do the computation at the usual 24bpp (but still + * requires us to use 18bpp). Until that's fully debugged, stay + * bug-for-bug compatible with the old code. + */ + if (is_edp(intel_dp) && dev_priv->edp.bpp) { + DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", + bpp, dev_priv->edp.bpp); + bpp = min_t(int, bpp, dev_priv->edp.bpp); + } + pipe_config->pipe_bpp = bpp; + return true; } @@ -1379,7 +1389,6 @@ static void intel_enable_dp(struct intel_encoder *encoder) ironlake_edp_panel_on(intel_dp); ironlake_edp_panel_vdd_off(intel_dp, true); intel_dp_complete_link_train(intel_dp); - intel_dp_stop_link_train(intel_dp); ironlake_edp_backlight_on(intel_dp); } @@ -1702,9 +1711,10 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, struct drm_i915_private *dev_priv = dev->dev_private; enum port port = intel_dig_port->port; int ret; + uint32_t temp; if (HAS_DDI(dev)) { - uint32_t temp = I915_READ(DP_TP_CTL(port)); + temp = I915_READ(DP_TP_CTL(port)); if (dp_train_pat & DP_LINK_SCRAMBLING_DISABLE) temp |= DP_TP_CTL_SCRAMBLE_DISABLE; @@ -1714,6 +1724,18 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, temp &= ~DP_TP_CTL_LINK_TRAIN_MASK; switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) { case DP_TRAINING_PATTERN_DISABLE: + + if (port != PORT_A) { + temp |= DP_TP_CTL_LINK_TRAIN_IDLE; + I915_WRITE(DP_TP_CTL(port), temp); + + if (wait_for((I915_READ(DP_TP_STATUS(port)) & + DP_TP_STATUS_IDLE_DONE), 1)) + DRM_ERROR("Timed out waiting for DP idle patterns\n"); + + temp &= ~DP_TP_CTL_LINK_TRAIN_MASK; + } + temp |= DP_TP_CTL_LINK_TRAIN_NORMAL; break; @@ -1789,37 +1811,6 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, return true; } -static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp) -{ - struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - enum port port = intel_dig_port->port; - uint32_t val; - - if (!HAS_DDI(dev)) - return; - - val = I915_READ(DP_TP_CTL(port)); - val &= ~DP_TP_CTL_LINK_TRAIN_MASK; - val |= DP_TP_CTL_LINK_TRAIN_IDLE; - I915_WRITE(DP_TP_CTL(port), val); - - /* - * On PORT_A we can have only eDP in SST mode. There the only reason - * we need to set idle transmission mode is to work around a HW issue - * where we enable the pipe while not in idle link-training mode. - * In this case there is requirement to wait for a minimum number of - * idle patterns to be sent. - */ - if (port == PORT_A) - return; - - if (wait_for((I915_READ(DP_TP_STATUS(port)) & DP_TP_STATUS_IDLE_DONE), - 1)) - DRM_ERROR("Timed out waiting for DP idle patterns\n"); -} - /* Enable corresponding port and start training pattern 1 */ void intel_dp_start_link_train(struct intel_dp *intel_dp) @@ -1962,19 +1953,10 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) ++tries; } - intel_dp_set_idle_link_train(intel_dp); - - intel_dp->DP = DP; - if (channel_eq) DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n"); -} - -void intel_dp_stop_link_train(struct intel_dp *intel_dp) -{ - intel_dp_set_link_train(intel_dp, intel_dp->DP, - DP_TRAINING_PATTERN_DISABLE); + intel_dp_set_link_train(intel_dp, DP, DP_TRAINING_PATTERN_DISABLE); } static void @@ -2182,7 +2164,6 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) drm_get_encoder_name(&intel_encoder->base)); intel_dp_start_link_train(intel_dp); intel_dp_complete_link_train(intel_dp); - intel_dp_stop_link_train(intel_dp); } } diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index 624a9e6b8d71..b5b6d19e6dd3 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -499,7 +499,6 @@ extern void intel_dp_init_connector(struct intel_digital_port *intel_dig_port, extern void intel_dp_init_link_config(struct intel_dp *intel_dp); extern void intel_dp_start_link_train(struct intel_dp *intel_dp); extern void intel_dp_complete_link_train(struct intel_dp *intel_dp); -extern void intel_dp_stop_link_train(struct intel_dp *intel_dp); extern void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode); extern void intel_dp_encoder_destroy(struct drm_encoder *encoder); extern void intel_dp_check_link_status(struct intel_dp *intel_dp); diff --git a/trunk/drivers/gpu/drm/i915/intel_fb.c b/trunk/drivers/gpu/drm/i915/intel_fb.c index 6b7c3ca2c035..0e19e575a1b4 100644 --- a/trunk/drivers/gpu/drm/i915/intel_fb.c +++ b/trunk/drivers/gpu/drm/i915/intel_fb.c @@ -262,22 +262,10 @@ void intel_fbdev_fini(struct drm_device *dev) void intel_fbdev_set_suspend(struct drm_device *dev, int state) { drm_i915_private_t *dev_priv = dev->dev_private; - struct intel_fbdev *ifbdev = dev_priv->fbdev; - struct fb_info *info; - - if (!ifbdev) + if (!dev_priv->fbdev) return; - info = ifbdev->helper.fbdev; - - /* On resume from hibernation: If the object is shmemfs backed, it has - * been restored from swap. If the object is stolen however, it will be - * full of whatever garbage was left in there. - */ - if (!state && ifbdev->ifb.obj->stolen) - memset_io(info->screen_base, 0, info->screen_size); - - fb_set_suspend(info, state); + fb_set_suspend(dev_priv->fbdev->helper.fbdev, state); } MODULE_LICENSE("GPL and additional rights"); diff --git a/trunk/drivers/gpu/drm/i915/intel_pm.c b/trunk/drivers/gpu/drm/i915/intel_pm.c index aa01128ff192..de3b0dc5658b 100644 --- a/trunk/drivers/gpu/drm/i915/intel_pm.c +++ b/trunk/drivers/gpu/drm/i915/intel_pm.c @@ -1301,17 +1301,17 @@ static void valleyview_update_wm(struct drm_device *dev) vlv_update_drain_latency(dev); - if (g4x_compute_wm0(dev, PIPE_A, + if (g4x_compute_wm0(dev, 0, &valleyview_wm_info, latency_ns, &valleyview_cursor_wm_info, latency_ns, &planea_wm, &cursora_wm)) - enabled |= 1 << PIPE_A; + enabled |= 1; - if (g4x_compute_wm0(dev, PIPE_B, + if (g4x_compute_wm0(dev, 1, &valleyview_wm_info, latency_ns, &valleyview_cursor_wm_info, latency_ns, &planeb_wm, &cursorb_wm)) - enabled |= 1 << PIPE_B; + enabled |= 2; if (single_plane_enabled(enabled) && g4x_compute_srwm(dev, ffs(enabled) - 1, @@ -1357,17 +1357,17 @@ static void g4x_update_wm(struct drm_device *dev) int plane_sr, cursor_sr; unsigned int enabled = 0; - if (g4x_compute_wm0(dev, PIPE_A, + if (g4x_compute_wm0(dev, 0, &g4x_wm_info, latency_ns, &g4x_cursor_wm_info, latency_ns, &planea_wm, &cursora_wm)) - enabled |= 1 << PIPE_A; + enabled |= 1; - if (g4x_compute_wm0(dev, PIPE_B, + if (g4x_compute_wm0(dev, 1, &g4x_wm_info, latency_ns, &g4x_cursor_wm_info, latency_ns, &planeb_wm, &cursorb_wm)) - enabled |= 1 << PIPE_B; + enabled |= 2; if (single_plane_enabled(enabled) && g4x_compute_srwm(dev, ffs(enabled) - 1, @@ -1716,7 +1716,7 @@ static void ironlake_update_wm(struct drm_device *dev) unsigned int enabled; enabled = 0; - if (g4x_compute_wm0(dev, PIPE_A, + if (g4x_compute_wm0(dev, 0, &ironlake_display_wm_info, ILK_LP0_PLANE_LATENCY, &ironlake_cursor_wm_info, @@ -1727,10 +1727,10 @@ static void ironlake_update_wm(struct drm_device *dev) DRM_DEBUG_KMS("FIFO watermarks For pipe A -" " plane %d, " "cursor: %d\n", plane_wm, cursor_wm); - enabled |= 1 << PIPE_A; + enabled |= 1; } - if (g4x_compute_wm0(dev, PIPE_B, + if (g4x_compute_wm0(dev, 1, &ironlake_display_wm_info, ILK_LP0_PLANE_LATENCY, &ironlake_cursor_wm_info, @@ -1741,7 +1741,7 @@ static void ironlake_update_wm(struct drm_device *dev) DRM_DEBUG_KMS("FIFO watermarks For pipe B -" " plane %d, cursor: %d\n", plane_wm, cursor_wm); - enabled |= 1 << PIPE_B; + enabled |= 2; } /* @@ -1801,7 +1801,7 @@ static void sandybridge_update_wm(struct drm_device *dev) unsigned int enabled; enabled = 0; - if (g4x_compute_wm0(dev, PIPE_A, + if (g4x_compute_wm0(dev, 0, &sandybridge_display_wm_info, latency, &sandybridge_cursor_wm_info, latency, &plane_wm, &cursor_wm)) { @@ -1812,10 +1812,10 @@ static void sandybridge_update_wm(struct drm_device *dev) DRM_DEBUG_KMS("FIFO watermarks For pipe A -" " plane %d, " "cursor: %d\n", plane_wm, cursor_wm); - enabled |= 1 << PIPE_A; + enabled |= 1; } - if (g4x_compute_wm0(dev, PIPE_B, + if (g4x_compute_wm0(dev, 1, &sandybridge_display_wm_info, latency, &sandybridge_cursor_wm_info, latency, &plane_wm, &cursor_wm)) { @@ -1826,7 +1826,7 @@ static void sandybridge_update_wm(struct drm_device *dev) DRM_DEBUG_KMS("FIFO watermarks For pipe B -" " plane %d, cursor: %d\n", plane_wm, cursor_wm); - enabled |= 1 << PIPE_B; + enabled |= 2; } /* @@ -1904,7 +1904,7 @@ static void ivybridge_update_wm(struct drm_device *dev) unsigned int enabled; enabled = 0; - if (g4x_compute_wm0(dev, PIPE_A, + if (g4x_compute_wm0(dev, 0, &sandybridge_display_wm_info, latency, &sandybridge_cursor_wm_info, latency, &plane_wm, &cursor_wm)) { @@ -1915,10 +1915,10 @@ static void ivybridge_update_wm(struct drm_device *dev) DRM_DEBUG_KMS("FIFO watermarks For pipe A -" " plane %d, " "cursor: %d\n", plane_wm, cursor_wm); - enabled |= 1 << PIPE_A; + enabled |= 1; } - if (g4x_compute_wm0(dev, PIPE_B, + if (g4x_compute_wm0(dev, 1, &sandybridge_display_wm_info, latency, &sandybridge_cursor_wm_info, latency, &plane_wm, &cursor_wm)) { @@ -1929,10 +1929,10 @@ static void ivybridge_update_wm(struct drm_device *dev) DRM_DEBUG_KMS("FIFO watermarks For pipe B -" " plane %d, cursor: %d\n", plane_wm, cursor_wm); - enabled |= 1 << PIPE_B; + enabled |= 2; } - if (g4x_compute_wm0(dev, PIPE_C, + if (g4x_compute_wm0(dev, 2, &sandybridge_display_wm_info, latency, &sandybridge_cursor_wm_info, latency, &plane_wm, &cursor_wm)) { @@ -1943,7 +1943,7 @@ static void ivybridge_update_wm(struct drm_device *dev) DRM_DEBUG_KMS("FIFO watermarks For pipe C -" " plane %d, cursor: %d\n", plane_wm, cursor_wm); - enabled |= 1 << PIPE_C; + enabled |= 3; } /* diff --git a/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c b/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c index 77b8a45fb10a..f9889658329b 100644 --- a/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/trunk/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -46,26 +46,29 @@ static void mga_crtc_load_lut(struct drm_crtc *crtc) static inline void mga_wait_vsync(struct mga_device *mdev) { - unsigned long timeout = jiffies + HZ/10; + unsigned int count = 0; unsigned int status = 0; do { status = RREG32(MGAREG_Status); - } while ((status & 0x08) && time_before(jiffies, timeout)); - timeout = jiffies + HZ/10; + count++; + } while ((status & 0x08) && (count < 250000)); + count = 0; status = 0; do { status = RREG32(MGAREG_Status); - } while (!(status & 0x08) && time_before(jiffies, timeout)); + count++; + } while (!(status & 0x08) && (count < 250000)); } static inline void mga_wait_busy(struct mga_device *mdev) { - unsigned long timeout = jiffies + HZ; + unsigned int count = 0; unsigned int status = 0; do { status = RREG8(MGAREG_Status + 2); - } while ((status & 0x01) && time_before(jiffies, timeout)); + count++; + } while ((status & 0x01) && (count < 500000)); } /* @@ -186,12 +189,12 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock) WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); tmp = RREG8(DAC_DATA); tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp); WREG8(DAC_INDEX, MGA1064_REMHEADCTL); tmp = RREG8(DAC_DATA); tmp |= MGA1064_REMHEADCTL_CLKDIS; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_REMHEADCTL, tmp); /* select PLL Set C */ tmp = RREG8(MGAREG_MEM_MISC_READ); @@ -201,7 +204,7 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock) WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); tmp = RREG8(DAC_DATA); tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN | 0x80; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); udelay(500); @@ -209,7 +212,7 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock) WREG8(DAC_INDEX, MGA1064_VREF_CTL); tmp = RREG8(DAC_DATA); tmp &= ~0x04; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_VREF_CTL, tmp); udelay(50); @@ -233,13 +236,13 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock) tmp = RREG8(DAC_DATA); tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK; tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); WREG8(DAC_INDEX, MGA1064_REMHEADCTL); tmp = RREG8(DAC_DATA); tmp &= ~MGA1064_REMHEADCTL_CLKSL_MSK; tmp |= MGA1064_REMHEADCTL_CLKSL_PLL; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_REMHEADCTL, tmp); /* reset dotclock rate bit */ WREG8(MGAREG_SEQ_INDEX, 1); @@ -250,7 +253,7 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock) WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); tmp = RREG8(DAC_DATA); tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); vcount = RREG8(MGAREG_VCOUNT); @@ -315,7 +318,7 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock) WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); tmp = RREG8(DAC_DATA); tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp); tmp = RREG8(MGAREG_MEM_MISC_READ); tmp |= 0x3 << 2; @@ -323,12 +326,12 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock) WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT); tmp = RREG8(DAC_DATA); - WREG8(DAC_DATA, tmp & ~0x40); + WREG_DAC(MGA1064_PIX_PLL_STAT, tmp & ~0x40); WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); tmp = RREG8(DAC_DATA); tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); WREG_DAC(MGA1064_EV_PIX_PLLC_M, m); WREG_DAC(MGA1064_EV_PIX_PLLC_N, n); @@ -339,7 +342,7 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock) WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); tmp = RREG8(DAC_DATA); tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); udelay(500); @@ -347,11 +350,11 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock) tmp = RREG8(DAC_DATA); tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK; tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); WREG8(DAC_INDEX, MGA1064_PIX_PLL_STAT); tmp = RREG8(DAC_DATA); - WREG8(DAC_DATA, tmp | 0x40); + WREG_DAC(MGA1064_PIX_PLL_STAT, tmp | 0x40); tmp = RREG8(MGAREG_MEM_MISC_READ); tmp |= (0x3 << 2); @@ -360,7 +363,7 @@ static int mga_g200ev_set_plls(struct mga_device *mdev, long clock) WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); tmp = RREG8(DAC_DATA); tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); return 0; } @@ -413,7 +416,7 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock) WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); tmp = RREG8(DAC_DATA); tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp); tmp = RREG8(MGAREG_MEM_MISC_READ); tmp |= 0x3 << 2; @@ -422,7 +425,7 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock) WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); tmp = RREG8(DAC_DATA); tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); udelay(500); @@ -436,13 +439,13 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock) tmp = RREG8(DAC_DATA); tmp &= ~MGA1064_PIX_CLK_CTL_SEL_MSK; tmp |= MGA1064_PIX_CLK_CTL_SEL_PLL; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); tmp = RREG8(DAC_DATA); tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS; tmp &= ~MGA1064_PIX_CLK_CTL_CLK_POW_DOWN; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); vcount = RREG8(MGAREG_VCOUNT); @@ -512,12 +515,12 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) WREG8(DAC_INDEX, MGA1064_PIX_CLK_CTL); tmp = RREG8(DAC_DATA); tmp |= MGA1064_PIX_CLK_CTL_CLK_DIS; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_PIX_CLK_CTL_CLK_DIS, tmp); WREG8(DAC_INDEX, MGA1064_REMHEADCTL); tmp = RREG8(DAC_DATA); tmp |= MGA1064_REMHEADCTL_CLKDIS; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_REMHEADCTL, tmp); tmp = RREG8(MGAREG_MEM_MISC_READ); tmp |= (0x3<<2) | 0xc0; @@ -527,7 +530,7 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) tmp = RREG8(DAC_DATA); tmp &= ~MGA1064_PIX_CLK_CTL_CLK_DIS; tmp |= MGA1064_PIX_CLK_CTL_CLK_POW_DOWN; - WREG8(DAC_DATA, tmp); + WREG_DAC(MGA1064_PIX_CLK_CTL, tmp); udelay(500); @@ -654,26 +657,12 @@ static void mga_g200wb_commit(struct drm_crtc *crtc) WREG_DAC(MGA1064_GEN_IO_DATA, tmp); } -/* - This is how the framebuffer base address is stored in g200 cards: - * Assume @offset is the gpu_addr variable of the framebuffer object - * Then addr is the number of _pixels_ (not bytes) from the start of - VRAM to the first pixel we want to display. (divided by 2 for 32bit - framebuffers) - * addr is stored in the CRTCEXT0, CRTCC and CRTCD registers - addr<20> -> CRTCEXT0<6> - addr<19-16> -> CRTCEXT0<3-0> - addr<15-8> -> CRTCC<7-0> - addr<7-0> -> CRTCD<7-0> - CRTCEXT0 has to be programmed last to trigger an update and make the - new addr variable take effect. - */ + void mga_set_start_address(struct drm_crtc *crtc, unsigned offset) { struct mga_device *mdev = crtc->dev->dev_private; u32 addr; int count; - u8 crtcext0; while (RREG8(0x1fda) & 0x08); while (!(RREG8(0x1fda) & 0x08)); @@ -681,17 +670,10 @@ void mga_set_start_address(struct drm_crtc *crtc, unsigned offset) count = RREG8(MGAREG_VCOUNT) + 2; while (RREG8(MGAREG_VCOUNT) < count); - WREG8(MGAREG_CRTCEXT_INDEX, 0); - crtcext0 = RREG8(MGAREG_CRTCEXT_DATA); - crtcext0 &= 0xB0; - addr = offset / 8; - /* Can't store addresses any higher than that... - but we also don't have more than 16MB of memory, so it should be fine. */ - WARN_ON(addr > 0x1fffff); - crtcext0 |= (!!(addr & (1<<20)))<<6; + addr = offset >> 2; WREG_CRT(0x0d, (u8)(addr & 0xff)); WREG_CRT(0x0c, (u8)(addr >> 8) & 0xff); - WREG_ECRT(0x0, ((u8)(addr >> 16) & 0xf) | crtcext0); + WREG_CRT(0xaf, (u8)(addr >> 16) & 0xf); } @@ -847,7 +829,11 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, for (i = 0; i < sizeof(dacvalue); i++) { - if ((i <= 0x17) || + if ((i <= 0x03) || + (i == 0x07) || + (i == 0x0b) || + (i == 0x0f) || + ((i >= 0x13) && (i <= 0x17)) || (i == 0x1b) || (i == 0x1c) || ((i >= 0x1f) && (i <= 0x29)) || diff --git a/trunk/drivers/idle/intel_idle.c b/trunk/drivers/idle/intel_idle.c index fa6964d8681a..0e8fab1913df 100644 --- a/trunk/drivers/idle/intel_idle.c +++ b/trunk/drivers/idle/intel_idle.c @@ -272,27 +272,6 @@ static struct cpuidle_state hsw_cstates[CPUIDLE_STATE_MAX] = { .exit_latency = 166, .target_residency = 500, .enter = &intel_idle }, - { - .name = "C8-HSW", - .desc = "MWAIT 0x40", - .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, - .exit_latency = 300, - .target_residency = 900, - .enter = &intel_idle }, - { - .name = "C9-HSW", - .desc = "MWAIT 0x50", - .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, - .exit_latency = 600, - .target_residency = 1800, - .enter = &intel_idle }, - { - .name = "C10-HSW", - .desc = "MWAIT 0x60", - .flags = MWAIT2flg(0x60) | CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_TLB_FLUSHED, - .exit_latency = 2600, - .target_residency = 7700, - .enter = &intel_idle }, { .enter = NULL } }; diff --git a/trunk/drivers/lguest/page_tables.c b/trunk/drivers/lguest/page_tables.c index 5b9ac32801c7..699187ab3800 100644 --- a/trunk/drivers/lguest/page_tables.c +++ b/trunk/drivers/lguest/page_tables.c @@ -1002,7 +1002,6 @@ void guest_set_pgd(struct lguest *lg, unsigned long gpgdir, u32 idx) kill_guest(&lg->cpus[0], "Cannot populate switcher mapping"); } - lg->pgdirs[pgdir].last_host_cpu = -1; } } diff --git a/trunk/drivers/net/caif/Kconfig b/trunk/drivers/net/caif/Kconfig index 547098086773..7ffc756131a2 100644 --- a/trunk/drivers/net/caif/Kconfig +++ b/trunk/drivers/net/caif/Kconfig @@ -43,7 +43,7 @@ config CAIF_HSI config CAIF_VIRTIO tristate "CAIF virtio transport driver" - depends on CAIF && HAS_DMA + depends on CAIF select VHOST_RING select VIRTIO select GENERIC_ALLOCATOR diff --git a/trunk/drivers/net/ethernet/3com/3c59x.c b/trunk/drivers/net/ethernet/3com/3c59x.c index 072c6f14e8fc..de570a8f8967 100644 --- a/trunk/drivers/net/ethernet/3com/3c59x.c +++ b/trunk/drivers/net/ethernet/3com/3c59x.c @@ -632,6 +632,7 @@ struct vortex_private { pm_state_valid:1, /* pci_dev->saved_config_space has sane contents */ open:1, medialock:1, + must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */ large_frames:1, /* accept large frames */ handling_irq:1; /* private in_irq indicator */ /* {get|set}_wol operations are already serialized by rtnl. @@ -1011,12 +1012,6 @@ static int vortex_init_one(struct pci_dev *pdev, if (rc < 0) goto out; - rc = pci_request_regions(pdev, DRV_NAME); - if (rc < 0) { - pci_disable_device(pdev); - goto out; - } - unit = vortex_cards_found; if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) { @@ -1032,7 +1027,6 @@ static int vortex_init_one(struct pci_dev *pdev, if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */ ioaddr = pci_iomap(pdev, 0, 0); if (!ioaddr) { - pci_release_regions(pdev); pci_disable_device(pdev); rc = -ENOMEM; goto out; @@ -1042,7 +1036,6 @@ static int vortex_init_one(struct pci_dev *pdev, ent->driver_data, unit); if (rc < 0) { pci_iounmap(pdev, ioaddr); - pci_release_regions(pdev); pci_disable_device(pdev); goto out; } @@ -1185,6 +1178,11 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq, /* PCI-only startup logic */ if (pdev) { + /* EISA resources already marked, so only PCI needs to do this here */ + /* Ignore return value, because Cardbus drivers already allocate for us */ + if (request_region(dev->base_addr, vci->io_size, print_name) != NULL) + vp->must_free_region = 1; + /* enable bus-mastering if necessary */ if (vci->flags & PCI_USES_MASTER) pci_set_master(pdev); @@ -1222,7 +1220,7 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq, &vp->rx_ring_dma); retval = -ENOMEM; if (!vp->rx_ring) - goto free_device; + goto free_region; vp->tx_ring = (struct boom_tx_desc *)(vp->rx_ring + RX_RING_SIZE); vp->tx_ring_dma = vp->rx_ring_dma + sizeof(struct boom_rx_desc) * RX_RING_SIZE; @@ -1486,7 +1484,9 @@ static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq, + sizeof(struct boom_tx_desc) * TX_RING_SIZE, vp->rx_ring, vp->rx_ring_dma); -free_device: +free_region: + if (vp->must_free_region) + release_region(dev->base_addr, vci->io_size); free_netdev(dev); pr_err(PFX "vortex_probe1 fails. Returns %d\n", retval); out: @@ -3254,9 +3254,8 @@ static void vortex_remove_one(struct pci_dev *pdev) + sizeof(struct boom_tx_desc) * TX_RING_SIZE, vp->rx_ring, vp->rx_ring_dma); - - pci_release_regions(pdev); - + if (vp->must_free_region) + release_region(dev->base_addr, vp->io_size); free_netdev(dev); } diff --git a/trunk/drivers/net/ethernet/brocade/bna/bnad.c b/trunk/drivers/net/ethernet/brocade/bna/bnad.c index 07f7ef05c3f2..ce4a030d3d0c 100644 --- a/trunk/drivers/net/ethernet/brocade/bna/bnad.c +++ b/trunk/drivers/net/ethernet/brocade/bna/bnad.c @@ -3236,10 +3236,9 @@ bnad_init(struct bnad *bnad, sprintf(bnad->wq_name, "%s_wq_%d", BNAD_NAME, bnad->id); bnad->work_q = create_singlethread_workqueue(bnad->wq_name); - if (!bnad->work_q) { - iounmap(bnad->bar0); + + if (!bnad->work_q) return -ENOMEM; - } return 0; } diff --git a/trunk/drivers/net/ethernet/cadence/Kconfig b/trunk/drivers/net/ethernet/cadence/Kconfig index 768285ec10f4..1194446f859a 100644 --- a/trunk/drivers/net/ethernet/cadence/Kconfig +++ b/trunk/drivers/net/ethernet/cadence/Kconfig @@ -22,7 +22,7 @@ if NET_CADENCE config ARM_AT91_ETHER tristate "AT91RM9200 Ethernet support" - depends on GENERIC_HARDIRQS && HAS_DMA + depends on GENERIC_HARDIRQS select NET_CORE select MACB ---help--- @@ -31,7 +31,6 @@ config ARM_AT91_ETHER config MACB tristate "Cadence MACB/GEM support" - depends on HAS_DMA select PHYLIB ---help--- The Cadence MACB ethernet interface is found on many Atmel AT32 and diff --git a/trunk/drivers/net/ethernet/calxeda/Kconfig b/trunk/drivers/net/ethernet/calxeda/Kconfig index 184a063bed5f..aba435c3d4ae 100644 --- a/trunk/drivers/net/ethernet/calxeda/Kconfig +++ b/trunk/drivers/net/ethernet/calxeda/Kconfig @@ -1,6 +1,6 @@ config NET_CALXEDA_XGMAC tristate "Calxeda 1G/10G XGMAC Ethernet driver" - depends on HAS_IOMEM && HAS_DMA + depends on HAS_IOMEM select CRC32 help This is the driver for the XGMAC Ethernet IP block found on Calxeda diff --git a/trunk/drivers/net/ethernet/freescale/fec_main.c b/trunk/drivers/net/ethernet/freescale/fec_main.c index ca9825ca88c9..aff0310a778b 100644 --- a/trunk/drivers/net/ethernet/freescale/fec_main.c +++ b/trunk/drivers/net/ethernet/freescale/fec_main.c @@ -87,8 +87,6 @@ #define FEC_QUIRK_HAS_GBIT (1 << 3) /* Controller has extend desc buffer */ #define FEC_QUIRK_HAS_BUFDESC_EX (1 << 4) -/* Controller has hardware checksum support */ -#define FEC_QUIRK_HAS_CSUM (1 << 5) static struct platform_device_id fec_devtype[] = { { @@ -107,7 +105,7 @@ static struct platform_device_id fec_devtype[] = { }, { .name = "imx6q-fec", .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | - FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM, + FEC_QUIRK_HAS_BUFDESC_EX, }, { .name = "mvf-fec", .driver_data = FEC_QUIRK_ENET_MAC, @@ -1746,8 +1744,6 @@ static const struct net_device_ops fec_netdev_ops = { static int fec_enet_init(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); struct bufdesc *cbd_base; /* Allocate memory for buffer descriptors. */ @@ -1779,14 +1775,12 @@ static int fec_enet_init(struct net_device *ndev) writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK); netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, FEC_NAPI_WEIGHT); - if (id_entry->driver_data & FEC_QUIRK_HAS_CSUM) { - /* enable hw accelerator */ - ndev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM - | NETIF_F_RXCSUM); - ndev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM - | NETIF_F_RXCSUM); - fep->csum_flags |= FLAG_RX_CSUM_ENABLED; - } + /* enable hw accelerator */ + ndev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM + | NETIF_F_RXCSUM); + ndev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM + | NETIF_F_RXCSUM); + fep->csum_flags |= FLAG_RX_CSUM_ENABLED; fec_restart(ndev, 0); diff --git a/trunk/drivers/net/ethernet/ibm/emac/core.c b/trunk/drivers/net/ethernet/ibm/emac/core.c index d300a0c0eafc..4989481c19f0 100644 --- a/trunk/drivers/net/ethernet/ibm/emac/core.c +++ b/trunk/drivers/net/ethernet/ibm/emac/core.c @@ -359,26 +359,10 @@ static int emac_reset(struct emac_instance *dev) } #ifdef CONFIG_PPC_DCR_NATIVE - /* - * PPC460EX/GT Embedded Processor Advanced User's Manual - * section 28.10.1 Mode Register 0 (EMACx_MR0) states: - * Note: The PHY must provide a TX Clk in order to perform a soft reset - * of the EMAC. If none is present, select the internal clock - * (SDR0_ETH_CFG[EMACx_PHY_CLK] = 1). - * After a soft reset, select the external clock. - */ - if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) { - if (dev->phy_address == 0xffffffff && - dev->phy_map == 0xffffffff) { - /* No PHY: select internal loop clock before reset */ - dcri_clrset(SDR0, SDR0_ETH_CFG, - 0, SDR0_ETH_CFG_ECS << dev->cell_index); - } else { - /* PHY present: select external clock before reset */ - dcri_clrset(SDR0, SDR0_ETH_CFG, - SDR0_ETH_CFG_ECS << dev->cell_index, 0); - } - } + /* Enable internal clock source */ + if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) + dcri_clrset(SDR0, SDR0_ETH_CFG, + 0, SDR0_ETH_CFG_ECS << dev->cell_index); #endif out_be32(&p->mr0, EMAC_MR0_SRST); @@ -386,14 +370,10 @@ static int emac_reset(struct emac_instance *dev) --n; #ifdef CONFIG_PPC_DCR_NATIVE - if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) { - if (dev->phy_address == 0xffffffff && - dev->phy_map == 0xffffffff) { - /* No PHY: restore external clock source after reset */ - dcri_clrset(SDR0, SDR0_ETH_CFG, - SDR0_ETH_CFG_ECS << dev->cell_index, 0); - } - } + /* Enable external clock source */ + if (emac_has_feature(dev, EMAC_FTR_460EX_PHY_CLK_FIX)) + dcri_clrset(SDR0, SDR0_ETH_CFG, + SDR0_ETH_CFG_ECS << dev->cell_index, 0); #endif if (n) { diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/en_resources.c b/trunk/drivers/net/ethernet/mellanox/mlx4/en_resources.c index d3f508697a3d..91f2b2c43c12 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/en_resources.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/en_resources.c @@ -60,7 +60,7 @@ void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride, context->pri_path.sched_queue = 0x83 | (priv->port - 1) << 6; if (user_prio >= 0) { context->pri_path.sched_queue |= user_prio << 3; - context->pri_path.feup = MLX4_FEUP_FORCE_ETH_UP; + context->pri_path.feup = 1 << 6; } context->pri_path.counter_index = 0xff; context->cqn_send = cpu_to_be32(cqn); diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/fw.c b/trunk/drivers/net/ethernet/mellanox/mlx4/fw.c index 58a8e535d698..b147bdd40768 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -131,9 +131,7 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) [2] = "RSS XOR Hash Function support", [3] = "Device manage flow steering support", [4] = "Automatic MAC reassignment support", - [5] = "Time stamping support", - [6] = "VST (control vlan insertion/stripping) support", - [7] = "FSM (MAC anti-spoofing) support" + [5] = "Time stamping support" }; int i; diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 1157f028a90f..e12e0d2e0ee0 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -372,29 +372,24 @@ static int update_vport_qp_param(struct mlx4_dev *dev, if (MLX4_QP_ST_RC == qp_type) return -EINVAL; - /* force strip vlan by clear vsd */ - qpc->param3 &= ~cpu_to_be32(MLX4_STRIP_VLAN); - if (0 != vp_oper->state.default_vlan) { - qpc->pri_path.vlan_control = - MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED | - MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED | - MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED; - } else { /* priority tagged */ - qpc->pri_path.vlan_control = - MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED | - MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED; - } - - qpc->pri_path.fvl_rx |= MLX4_FVL_RX_FORCE_ETH_VLAN; qpc->pri_path.vlan_index = vp_oper->vlan_idx; - qpc->pri_path.fl |= MLX4_FL_CV | MLX4_FL_ETH_HIDE_CQE_VLAN; - qpc->pri_path.feup |= MLX4_FEUP_FORCE_ETH_UP | MLX4_FVL_FORCE_ETH_VLAN; + qpc->pri_path.fl = (1 << 6) | (1 << 2); /* set cv bit and hide_cqe_vlan bit*/ + qpc->pri_path.feup |= 1 << 3; /* set fvl bit */ qpc->pri_path.sched_queue &= 0xC7; qpc->pri_path.sched_queue |= (vp_oper->state.default_qos) << 3; + mlx4_dbg(dev, "qp %d port %d Q 0x%x set vlan to %d vidx %d feup %x fl %x\n", + be32_to_cpu(qpc->local_qpn) & 0xffffff, port, + (int)(qpc->pri_path.sched_queue), vp_oper->state.default_vlan, + vp_oper->vlan_idx, (int)(qpc->pri_path.feup), + (int)(qpc->pri_path.fl)); } if (vp_oper->state.spoofchk) { - qpc->pri_path.feup |= MLX4_FSM_FORCE_ETH_SRC_MAC; + qpc->pri_path.feup |= 1 << 5; /* set fsm bit */; qpc->pri_path.grh_mylmc = (0x80 & qpc->pri_path.grh_mylmc) + vp_oper->mac_idx; + mlx4_dbg(dev, "spoof qp %d port %d feup 0x%x, myLmc 0x%x mindx %d\n", + be32_to_cpu(qpc->local_qpn) & 0xffffff, port, + (int)qpc->pri_path.feup, (int)qpc->pri_path.grh_mylmc, + vp_oper->mac_idx); } return 0; } diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 019c5f78732e..90c253b145ef 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -429,7 +429,6 @@ struct qlcnic_hardware_context { u16 port_type; u16 board_type; - u16 supported_type; u16 link_speed; u16 link_duplex; @@ -1515,7 +1514,6 @@ void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter); void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter); void qlcnic_82xx_add_sysfs(struct qlcnic_adapter *adapter); void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter); -int qlcnic_82xx_get_settings(struct qlcnic_adapter *, struct ethtool_cmd *); int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32); int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32); diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index b4ff1e35a11d..ea790a93ee7c 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -696,14 +696,15 @@ u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *adapter) return 1; } -u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter, u32 *wait_time) +u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter) { u32 data; + unsigned long wait_time = 0; struct qlcnic_hardware_context *ahw = adapter->ahw; /* wait for mailbox completion */ do { data = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL); - if (++(*wait_time) > QLCNIC_MBX_TIMEOUT) { + if (++wait_time > QLCNIC_MBX_TIMEOUT) { data = QLCNIC_RCODE_TIMEOUT; break; } @@ -719,8 +720,8 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter, u16 opcode; u8 mbx_err_code; unsigned long flags; + u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd; struct qlcnic_hardware_context *ahw = adapter->ahw; - u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, wait_time = 0; opcode = LSW(cmd->req.arg[0]); if (!test_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status)) { @@ -753,13 +754,15 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter, /* Signal FW about the impending command */ QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER); poll: - rsp = qlcnic_83xx_mbx_poll(adapter, &wait_time); + rsp = qlcnic_83xx_mbx_poll(adapter); if (rsp != QLCNIC_RCODE_TIMEOUT) { /* Get the FW response data */ fw_data = readl(QLCNIC_MBX_FW(ahw, 0)); if (fw_data & QLCNIC_MBX_ASYNC_EVENT) { __qlcnic_83xx_process_aen(adapter); - goto poll; + mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL); + if (mbx_val) + goto poll; } mbx_err_code = QLCNIC_MBX_STATUS(fw_data); rsp_num = QLCNIC_MBX_NUM_REGS(fw_data); @@ -1273,13 +1276,11 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter, return err; } -static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test, - int num_sds_ring) +static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test) { struct qlcnic_adapter *adapter = netdev_priv(netdev); struct qlcnic_host_sds_ring *sds_ring; struct qlcnic_host_rds_ring *rds_ring; - u16 adapter_state = adapter->is_up; u8 ring; int ret; @@ -1303,10 +1304,6 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test, ret = qlcnic_fw_create_ctx(adapter); if (ret) { qlcnic_detach(adapter); - if (adapter_state == QLCNIC_ADAPTER_UP_MAGIC) { - adapter->max_sds_rings = num_sds_ring; - qlcnic_attach(adapter); - } netif_device_attach(netdev); return ret; } @@ -1599,8 +1596,7 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode) if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) return -EBUSY; - ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST, - max_sds_rings); + ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST); if (ret) goto fail_diag_alloc; @@ -2834,23 +2830,6 @@ int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter) break; } config = cmd.rsp.arg[3]; - if (QLC_83XX_SFP_PRESENT(config)) { - switch (ahw->module_type) { - case LINKEVENT_MODULE_OPTICAL_UNKNOWN: - case LINKEVENT_MODULE_OPTICAL_SRLR: - case LINKEVENT_MODULE_OPTICAL_LRM: - case LINKEVENT_MODULE_OPTICAL_SFP_1G: - ahw->supported_type = PORT_FIBRE; - break; - case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE: - case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN: - case LINKEVENT_MODULE_TWINAX: - ahw->supported_type = PORT_TP; - break; - default: - ahw->supported_type = PORT_OTHER; - } - } if (config & 1) err = 1; } @@ -2859,8 +2838,7 @@ int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter) return config; } -int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter, - struct ethtool_cmd *ecmd) +int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter) { u32 config = 0; int status = 0; @@ -2873,54 +2851,6 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter, ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config); /* hard code until there is a way to get it from flash */ ahw->board_type = QLCNIC_BRDTYPE_83XX_10G; - - if (netif_running(adapter->netdev) && ahw->has_link_events) { - ethtool_cmd_speed_set(ecmd, ahw->link_speed); - ecmd->duplex = ahw->link_duplex; - ecmd->autoneg = ahw->link_autoneg; - } else { - ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN); - ecmd->duplex = DUPLEX_UNKNOWN; - ecmd->autoneg = AUTONEG_DISABLE; - } - - if (ahw->port_type == QLCNIC_XGBE) { - ecmd->supported = SUPPORTED_1000baseT_Full; - ecmd->advertising = ADVERTISED_1000baseT_Full; - } else { - ecmd->supported = (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full); - ecmd->advertising = (ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full | - ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full); - } - - switch (ahw->supported_type) { - case PORT_FIBRE: - ecmd->supported |= SUPPORTED_FIBRE; - ecmd->advertising |= ADVERTISED_FIBRE; - ecmd->port = PORT_FIBRE; - ecmd->transceiver = XCVR_EXTERNAL; - break; - case PORT_TP: - ecmd->supported |= SUPPORTED_TP; - ecmd->advertising |= ADVERTISED_TP; - ecmd->port = PORT_TP; - ecmd->transceiver = XCVR_INTERNAL; - break; - default: - ecmd->supported |= SUPPORTED_FIBRE; - ecmd->advertising |= ADVERTISED_FIBRE; - ecmd->port = PORT_OTHER; - ecmd->transceiver = XCVR_EXTERNAL; - break; - } - ecmd->phy_address = ahw->physical_port; return status; } @@ -3116,8 +3046,7 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev) if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) return -EIO; - ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST, - max_sds_rings); + ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST); if (ret) goto fail_diag_irq; diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index f5db67fc9f55..1f1d85e6f2af 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h @@ -603,7 +603,7 @@ int qlcnic_83xx_get_vnic_pf_info(struct qlcnic_adapter *, struct qlcnic_info *); void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *); void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data); -int qlcnic_83xx_get_settings(struct qlcnic_adapter *, struct ethtool_cmd *); +int qlcnic_83xx_get_settings(struct qlcnic_adapter *); int qlcnic_83xx_set_settings(struct qlcnic_adapter *, struct ethtool_cmd *); void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *, struct ethtool_pauseparam *); @@ -620,7 +620,7 @@ int qlcnic_83xx_flash_test(struct qlcnic_adapter *); int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *); int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *); u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *); -u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *, u32 *); +u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *); void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *); void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *); #endif diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index c67d1eb35e8f..ab1d8d99cbd5 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c @@ -435,6 +435,10 @@ static void qlcnic_83xx_idc_attach_driver(struct qlcnic_adapter *adapter) } done: netif_device_attach(netdev); + if (netif_running(netdev)) { + netif_carrier_on(netdev); + netif_wake_queue(netdev); + } } static int qlcnic_83xx_idc_enter_failed_state(struct qlcnic_adapter *adapter, @@ -638,21 +642,15 @@ static int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter) static void qlcnic_83xx_idc_update_idc_params(struct qlcnic_adapter *adapter) { - struct qlcnic_hardware_context *ahw = adapter->ahw; - qlcnic_83xx_idc_update_drv_presence_reg(adapter, 1, 1); + clear_bit(__QLCNIC_RESETTING, &adapter->state); set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status); qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1); set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status); - - ahw->idc.quiesce_req = 0; - ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY; - ahw->idc.err_code = 0; - ahw->idc.collect_dump = 0; - ahw->reset_context = 0; - adapter->tx_timeo_cnt = 0; - - clear_bit(__QLCNIC_RESETTING, &adapter->state); + adapter->ahw->idc.quiesce_req = 0; + adapter->ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY; + adapter->ahw->idc.err_code = 0; + adapter->ahw->idc.collect_dump = 0; } /** @@ -853,7 +851,6 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter) /* Check for soft reset request */ if (ahw->reset_context && !(val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY)) { - adapter->ahw->reset_context = 0; qlcnic_83xx_idc_tx_soft_reset(adapter); return ret; } @@ -917,7 +914,6 @@ static int qlcnic_83xx_idc_need_quiesce_state(struct qlcnic_adapter *adapter) static int qlcnic_83xx_idc_failed_state(struct qlcnic_adapter *adapter) { dev_err(&adapter->pdev->dev, "%s: please restart!!\n", __func__); - clear_bit(__QLCNIC_RESETTING, &adapter->state); adapter->ahw->idc.err_code = -EIO; return 0; diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index f67652de5a63..08efb4635007 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -131,13 +131,12 @@ static const char qlcnic_83xx_rx_stats_strings[][ETH_GSTRING_LEN] = { "ctx_lro_pkt_cnt", "ctx_ip_csum_error", "ctx_rx_pkts_wo_ctx", - "ctx_rx_pkts_drop_wo_sds_on_card", - "ctx_rx_pkts_drop_wo_sds_on_host", + "ctx_rx_pkts_dropped_wo_sts", "ctx_rx_osized_pkts", "ctx_rx_pkts_dropped_wo_rds", "ctx_rx_unexpected_mcast_pkts", "ctx_invalid_mac_address", - "ctx_rx_rds_ring_prim_attempted", + "ctx_rx_rds_ring_prim_attemoted", "ctx_rx_rds_ring_prim_success", "ctx_num_lro_flows_added", "ctx_num_lro_flows_removed", @@ -252,18 +251,6 @@ static int qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { struct qlcnic_adapter *adapter = netdev_priv(dev); - - if (qlcnic_82xx_check(adapter)) - return qlcnic_82xx_get_settings(adapter, ecmd); - else if (qlcnic_83xx_check(adapter)) - return qlcnic_83xx_get_settings(adapter, ecmd); - - return -EIO; -} - -int qlcnic_82xx_get_settings(struct qlcnic_adapter *adapter, - struct ethtool_cmd *ecmd) -{ struct qlcnic_hardware_context *ahw = adapter->ahw; u32 speed, reg; int check_sfp_module = 0; @@ -289,7 +276,10 @@ int qlcnic_82xx_get_settings(struct qlcnic_adapter *adapter, } else if (adapter->ahw->port_type == QLCNIC_XGBE) { u32 val = 0; - val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR); + if (qlcnic_83xx_check(adapter)) + qlcnic_83xx_get_settings(adapter); + else + val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR); if (val == QLCNIC_PORT_MODE_802_3_AP) { ecmd->supported = SUPPORTED_1000baseT_Full; @@ -299,13 +289,16 @@ int qlcnic_82xx_get_settings(struct qlcnic_adapter *adapter, ecmd->advertising = ADVERTISED_10000baseT_Full; } - if (netif_running(adapter->netdev) && ahw->has_link_events) { - reg = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn)); - speed = P3P_LINK_SPEED_VAL(pcifn, reg); - ahw->link_speed = speed * P3P_LINK_SPEED_MHZ; - ethtool_cmd_speed_set(ecmd, ahw->link_speed); - ecmd->autoneg = ahw->link_autoneg; - ecmd->duplex = ahw->link_duplex; + if (netif_running(dev) && adapter->ahw->has_link_events) { + if (qlcnic_82xx_check(adapter)) { + reg = QLCRD32(adapter, + P3P_LINK_SPEED_REG(pcifn)); + speed = P3P_LINK_SPEED_VAL(pcifn, reg); + ahw->link_speed = speed * P3P_LINK_SPEED_MHZ; + } + ethtool_cmd_speed_set(ecmd, adapter->ahw->link_speed); + ecmd->autoneg = adapter->ahw->link_autoneg; + ecmd->duplex = adapter->ahw->link_duplex; goto skip; } @@ -347,8 +340,8 @@ int qlcnic_82xx_get_settings(struct qlcnic_adapter *adapter, case QLCNIC_BRDTYPE_P3P_10G_SFP_QT: ecmd->advertising |= ADVERTISED_TP; ecmd->supported |= SUPPORTED_TP; - check_sfp_module = netif_running(adapter->netdev) && - ahw->has_link_events; + check_sfp_module = netif_running(dev) && + adapter->ahw->has_link_events; case QLCNIC_BRDTYPE_P3P_10G_XFP: ecmd->supported |= SUPPORTED_FIBRE; ecmd->advertising |= ADVERTISED_FIBRE; @@ -362,8 +355,8 @@ int qlcnic_82xx_get_settings(struct qlcnic_adapter *adapter, ecmd->advertising |= (ADVERTISED_FIBRE | ADVERTISED_TP); ecmd->port = PORT_FIBRE; - check_sfp_module = netif_running(adapter->netdev) && - ahw->has_link_events; + check_sfp_module = netif_running(dev) && + adapter->ahw->has_link_events; } else { ecmd->autoneg = AUTONEG_ENABLE; ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg); @@ -372,6 +365,13 @@ int qlcnic_82xx_get_settings(struct qlcnic_adapter *adapter, ecmd->port = PORT_TP; } break; + case QLCNIC_BRDTYPE_83XX_10G: + ecmd->autoneg = AUTONEG_DISABLE; + ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP); + ecmd->advertising |= (ADVERTISED_FIBRE | ADVERTISED_TP); + ecmd->port = PORT_FIBRE; + check_sfp_module = netif_running(dev) && ahw->has_link_events; + break; default: dev_err(&adapter->pdev->dev, "Unsupported board model %d\n", adapter->ahw->board_type); diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h index b6818f4356b9..95b1b5732838 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h @@ -134,7 +134,7 @@ struct qlcnic_mailbox_metadata { #define QLCNIC_SET_OWNER 1 #define QLCNIC_CLR_OWNER 0 -#define QLCNIC_MBX_TIMEOUT 5000 +#define QLCNIC_MBX_TIMEOUT 10000 #define QLCNIC_MBX_RSP_OK 1 #define QLCNIC_MBX_PORT_RSP_OK 0x1a diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 8fb836d4129f..264d5a4f8153 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -37,24 +37,24 @@ MODULE_PARM_DESC(qlcnic_mac_learn, "Mac Filter (0=learning is disabled, 1=Driver learning is enabled, 2=FDB learning is enabled)"); int qlcnic_use_msi = 1; -MODULE_PARM_DESC(use_msi, "MSI interrupt (0=disabled, 1=enabled)"); +MODULE_PARM_DESC(use_msi, "MSI interrupt (0=disabled, 1=enabled"); module_param_named(use_msi, qlcnic_use_msi, int, 0444); int qlcnic_use_msi_x = 1; -MODULE_PARM_DESC(use_msi_x, "MSI-X interrupt (0=disabled, 1=enabled)"); +MODULE_PARM_DESC(use_msi_x, "MSI-X interrupt (0=disabled, 1=enabled"); module_param_named(use_msi_x, qlcnic_use_msi_x, int, 0444); int qlcnic_auto_fw_reset = 1; -MODULE_PARM_DESC(auto_fw_reset, "Auto firmware reset (0=disabled, 1=enabled)"); +MODULE_PARM_DESC(auto_fw_reset, "Auto firmware reset (0=disabled, 1=enabled"); module_param_named(auto_fw_reset, qlcnic_auto_fw_reset, int, 0644); int qlcnic_load_fw_file; -MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file)"); +MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file"); module_param_named(load_fw_file, qlcnic_load_fw_file, int, 0444); int qlcnic_config_npars; module_param(qlcnic_config_npars, int, 0444); -MODULE_PARM_DESC(qlcnic_config_npars, "Configure NPARs (0=disabled, 1=enabled)"); +MODULE_PARM_DESC(qlcnic_config_npars, "Configure NPARs (0=disabled, 1=enabled"); static int qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent); static void qlcnic_remove(struct pci_dev *pdev); @@ -308,23 +308,6 @@ int qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) return 0; } -static void qlcnic_delete_adapter_mac(struct qlcnic_adapter *adapter) -{ - struct qlcnic_mac_list_s *cur; - struct list_head *head; - - list_for_each(head, &adapter->mac_list) { - cur = list_entry(head, struct qlcnic_mac_list_s, list); - if (!memcmp(adapter->mac_addr, cur->mac_addr, ETH_ALEN)) { - qlcnic_sre_macaddr_change(adapter, cur->mac_addr, - 0, QLCNIC_MAC_DEL); - list_del(&cur->list); - kfree(cur); - return; - } - } -} - static int qlcnic_set_mac(struct net_device *netdev, void *p) { struct qlcnic_adapter *adapter = netdev_priv(netdev); @@ -339,15 +322,11 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p) if (!is_valid_ether_addr(addr->sa_data)) return -EINVAL; - if (!memcmp(adapter->mac_addr, addr->sa_data, ETH_ALEN)) - return 0; - if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) { netif_device_detach(netdev); qlcnic_napi_disable(adapter); } - qlcnic_delete_adapter_mac(adapter); memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len); memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); qlcnic_set_multi(adapter->netdev); @@ -2502,17 +2481,12 @@ static void qlcnic_tx_timeout(struct net_device *netdev) if (test_bit(__QLCNIC_RESETTING, &adapter->state)) return; - if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS) { - netdev_info(netdev, "Tx timeout, reset the adapter.\n"); - if (qlcnic_82xx_check(adapter)) - adapter->need_fw_reset = 1; - else if (qlcnic_83xx_check(adapter)) - qlcnic_83xx_idc_request_reset(adapter, - QLCNIC_FORCE_FW_DUMP_KEY); - } else { - netdev_info(netdev, "Tx timeout, reset adapter context.\n"); + dev_err(&netdev->dev, "transmit timeout, resetting.\n"); + + if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS) + adapter->need_fw_reset = 1; + else adapter->ahw->reset_context = 1; - } } static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev) diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index 3869c3864deb..44d547d78b84 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c @@ -280,9 +280,9 @@ void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter) static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr, u32 *pay, u8 pci_func, u8 size) { - u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, val, wait_time = 0; struct qlcnic_hardware_context *ahw = adapter->ahw; unsigned long flags; + u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, val; u16 opcode; u8 mbx_err_code; int i, j; @@ -330,13 +330,15 @@ static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr, * assume something is wrong. */ poll: - rsp = qlcnic_83xx_mbx_poll(adapter, &wait_time); + rsp = qlcnic_83xx_mbx_poll(adapter); if (rsp != QLCNIC_RCODE_TIMEOUT) { /* Get the FW response data */ fw_data = readl(QLCNIC_MBX_FW(ahw, 0)); if (fw_data & QLCNIC_MBX_ASYNC_EVENT) { __qlcnic_83xx_process_aen(adapter); - goto poll; + mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL); + if (mbx_val) + goto poll; } mbx_err_code = QLCNIC_MBX_STATUS(fw_data); rsp_num = QLCNIC_MBX_NUM_REGS(fw_data); diff --git a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index 1a66ccded235..c81be2da119b 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/trunk/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c @@ -1133,6 +1133,9 @@ static int qlcnic_sriov_validate_linkevent(struct qlcnic_vf_info *vf, if ((cmd->req.arg[1] >> 16) != vf->rx_ctx_id) return -EINVAL; + if (!(cmd->req.arg[1] & BIT_8)) + return -EINVAL; + return 0; } diff --git a/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c index 50235d201592..87463bc701a6 100644 --- a/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/trunk/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -1106,7 +1106,6 @@ static int ql_get_next_chunk(struct ql_adapter *qdev, struct rx_ring *rx_ring, if (pci_dma_mapping_error(qdev->pdev, map)) { __free_pages(rx_ring->pg_chunk.page, qdev->lbq_buf_order); - rx_ring->pg_chunk.page = NULL; netif_err(qdev, drv, qdev->ndev, "PCI mapping failed.\n"); return -ENOMEM; @@ -2778,12 +2777,6 @@ static void ql_free_lbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring curr_idx = 0; } - if (rx_ring->pg_chunk.page) { - pci_unmap_page(qdev->pdev, rx_ring->pg_chunk.map, - ql_lbq_block_size(qdev), PCI_DMA_FROMDEVICE); - put_page(rx_ring->pg_chunk.page); - rx_ring->pg_chunk.page = NULL; - } } static void ql_free_sbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring) diff --git a/trunk/drivers/net/ethernet/stmicro/stmmac/Kconfig b/trunk/drivers/net/ethernet/stmicro/stmmac/Kconfig index 43c1f3223322..f695a50bac47 100644 --- a/trunk/drivers/net/ethernet/stmicro/stmmac/Kconfig +++ b/trunk/drivers/net/ethernet/stmicro/stmmac/Kconfig @@ -1,6 +1,6 @@ config STMMAC_ETH tristate "STMicroelectronics 10/100/1000 Ethernet driver" - depends on HAS_IOMEM && HAS_DMA + depends on HAS_IOMEM select NET_CORE select MII select PHYLIB diff --git a/trunk/drivers/net/macvlan.c b/trunk/drivers/net/macvlan.c index 1c502bb0c916..d5a141c7c4e7 100644 --- a/trunk/drivers/net/macvlan.c +++ b/trunk/drivers/net/macvlan.c @@ -229,8 +229,7 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb) } if (port->passthru) - vlan = list_first_or_null_rcu(&port->vlans, - struct macvlan_dev, list); + vlan = list_first_entry(&port->vlans, struct macvlan_dev, list); else vlan = macvlan_hash_lookup(port, eth->h_dest); if (vlan == NULL) @@ -815,7 +814,7 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, if (err < 0) goto upper_dev_unlink; - list_add_tail_rcu(&vlan->list, &port->vlans); + list_add_tail(&vlan->list, &port->vlans); netif_stacked_transfer_operstate(lowerdev, dev); return 0; @@ -843,7 +842,7 @@ void macvlan_dellink(struct net_device *dev, struct list_head *head) { struct macvlan_dev *vlan = netdev_priv(dev); - list_del_rcu(&vlan->list); + list_del(&vlan->list); unregister_netdevice_queue(dev, head); netdev_upper_dev_unlink(vlan->lowerdev, dev); } diff --git a/trunk/drivers/net/virtio_net.c b/trunk/drivers/net/virtio_net.c index 655bb25eed2b..3c23fdc27bf0 100644 --- a/trunk/drivers/net/virtio_net.c +++ b/trunk/drivers/net/virtio_net.c @@ -28,7 +28,7 @@ #include #include -static int napi_weight = NAPI_POLL_WEIGHT; +static int napi_weight = 128; module_param(napi_weight, int, 0444); static bool csum = true, gso = true; diff --git a/trunk/drivers/net/wireless/ath/ath5k/base.c b/trunk/drivers/net/wireless/ath/ath5k/base.c index 7f702fe3ecc2..9b20d9ee2719 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/base.c +++ b/trunk/drivers/net/wireless/ath/ath5k/base.c @@ -2369,9 +2369,6 @@ ath5k_tx_complete_poll_work(struct work_struct *work) int i; bool needreset = false; - if (!test_bit(ATH_STAT_STARTED, ah->status)) - return; - mutex_lock(&ah->lock); for (i = 0; i < ARRAY_SIZE(ah->txqs); i++) { @@ -2679,7 +2676,6 @@ int ath5k_start(struct ieee80211_hw *hw) mmiowb(); mutex_unlock(&ah->lock); - set_bit(ATH_STAT_STARTED, ah->status); ieee80211_queue_delayed_work(ah->hw, &ah->tx_complete_work, msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT)); @@ -2741,7 +2737,6 @@ void ath5k_stop(struct ieee80211_hw *hw) ath5k_stop_tasklets(ah); - clear_bit(ATH_STAT_STARTED, ah->status); cancel_delayed_work_sync(&ah->tx_complete_work); if (!ath5k_modparam_no_hw_rfkill_switch) diff --git a/trunk/drivers/net/wireless/ath/ath9k/Kconfig b/trunk/drivers/net/wireless/ath/ath9k/Kconfig index f3dc124c60c7..17507dc8a1e7 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/Kconfig +++ b/trunk/drivers/net/wireless/ath/ath9k/Kconfig @@ -17,7 +17,7 @@ config ATH9K_BTCOEX_SUPPORT config ATH9K tristate "Atheros 802.11n wireless cards support" - depends on MAC80211 && HAS_DMA + depends on MAC80211 select ATH9K_HW select MAC80211_LEDS select LEDS_CLASS diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h index e85a8b076c22..0c2ac0c6dc89 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h @@ -233,9 +233,9 @@ static const u32 ar9565_1p0_baseband_core[][2] = { {0x00009d10, 0x01834061}, {0x00009d14, 0x00c00400}, {0x00009d18, 0x00000000}, - {0x00009e08, 0x0038230c}, - {0x00009e24, 0x9907b515}, - {0x00009e28, 0x126f0600}, + {0x00009e08, 0x0078230c}, + {0x00009e24, 0x990bb515}, + {0x00009e28, 0x126f0000}, {0x00009e30, 0x06336f77}, {0x00009e34, 0x6af6532f}, {0x00009e38, 0x0cc80c00}, @@ -337,7 +337,7 @@ static const u32 ar9565_1p0_baseband_core[][2] = { static const u32 ar9565_1p0_baseband_postamble[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8009}, + {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a800d}, {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a01ae}, {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x63c640da}, {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x09143c81}, @@ -345,9 +345,9 @@ static const u32 ar9565_1p0_baseband_postamble[][5] = { {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, - {0x00009e04, 0x00802020, 0x00802020, 0x00142020, 0x00142020}, - {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, - {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e}, + {0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, + {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8}, + {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e}, {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e}, {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, @@ -450,8 +450,6 @@ static const u32 ar9565_1p0_soc_postamble[][5] = { static const u32 ar9565_1p0_Common_rx_gain_table[][2] = { /* Addr allmodes */ - {0x00004050, 0x00300300}, - {0x0000406c, 0x00100000}, {0x0000a000, 0x00010000}, {0x0000a004, 0x00030002}, {0x0000a008, 0x00050004}, @@ -500,27 +498,27 @@ static const u32 ar9565_1p0_Common_rx_gain_table[][2] = { {0x0000a0b4, 0x00000000}, {0x0000a0b8, 0x00000000}, {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x00bf00a0}, - {0x0000a0c4, 0x11a011a1}, - {0x0000a0c8, 0x11be11bf}, - {0x0000a0cc, 0x11bc11bd}, - {0x0000a0d0, 0x22632264}, - {0x0000a0d4, 0x22612262}, - {0x0000a0d8, 0x227f2260}, - {0x0000a0dc, 0x4322227e}, - {0x0000a0e0, 0x43204321}, - {0x0000a0e4, 0x433e433f}, - {0x0000a0e8, 0x4462433d}, - {0x0000a0ec, 0x44604461}, - {0x0000a0f0, 0x447e447f}, - {0x0000a0f4, 0x5582447d}, - {0x0000a0f8, 0x55805581}, - {0x0000a0fc, 0x559e559f}, - {0x0000a100, 0x66816682}, - {0x0000a104, 0x669f6680}, - {0x0000a108, 0x669d669e}, - {0x0000a10c, 0x77627763}, - {0x0000a110, 0x77607761}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x01000101}, + {0x0000a0c8, 0x011e011f}, + {0x0000a0cc, 0x011c011d}, + {0x0000a0d0, 0x02030204}, + {0x0000a0d4, 0x02010202}, + {0x0000a0d8, 0x021f0200}, + {0x0000a0dc, 0x0302021e}, + {0x0000a0e0, 0x03000301}, + {0x0000a0e4, 0x031e031f}, + {0x0000a0e8, 0x0402031d}, + {0x0000a0ec, 0x04000401}, + {0x0000a0f0, 0x041e041f}, + {0x0000a0f4, 0x0502041d}, + {0x0000a0f8, 0x05000501}, + {0x0000a0fc, 0x051e051f}, + {0x0000a100, 0x06010602}, + {0x0000a104, 0x061f0600}, + {0x0000a108, 0x061d061e}, + {0x0000a10c, 0x07020703}, + {0x0000a110, 0x07000701}, {0x0000a114, 0x00000000}, {0x0000a118, 0x00000000}, {0x0000a11c, 0x00000000}, @@ -532,27 +530,27 @@ static const u32 ar9565_1p0_Common_rx_gain_table[][2] = { {0x0000a134, 0x00000000}, {0x0000a138, 0x00000000}, {0x0000a13c, 0x00000000}, - {0x0000a140, 0x00bf00a0}, - {0x0000a144, 0x11a011a1}, - {0x0000a148, 0x11be11bf}, - {0x0000a14c, 0x11bc11bd}, - {0x0000a150, 0x22632264}, - {0x0000a154, 0x22612262}, - {0x0000a158, 0x227f2260}, - {0x0000a15c, 0x4322227e}, - {0x0000a160, 0x43204321}, - {0x0000a164, 0x433e433f}, - {0x0000a168, 0x4462433d}, - {0x0000a16c, 0x44604461}, - {0x0000a170, 0x447e447f}, - {0x0000a174, 0x5582447d}, - {0x0000a178, 0x55805581}, - {0x0000a17c, 0x559e559f}, - {0x0000a180, 0x66816682}, - {0x0000a184, 0x669f6680}, - {0x0000a188, 0x669d669e}, - {0x0000a18c, 0x77e677e7}, - {0x0000a190, 0x77e477e5}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x01000101}, + {0x0000a148, 0x011e011f}, + {0x0000a14c, 0x011c011d}, + {0x0000a150, 0x02030204}, + {0x0000a154, 0x02010202}, + {0x0000a158, 0x021f0200}, + {0x0000a15c, 0x0302021e}, + {0x0000a160, 0x03000301}, + {0x0000a164, 0x031e031f}, + {0x0000a168, 0x0402031d}, + {0x0000a16c, 0x04000401}, + {0x0000a170, 0x041e041f}, + {0x0000a174, 0x0502041d}, + {0x0000a178, 0x05000501}, + {0x0000a17c, 0x051e051f}, + {0x0000a180, 0x06010602}, + {0x0000a184, 0x061f0600}, + {0x0000a188, 0x061d061e}, + {0x0000a18c, 0x07020703}, + {0x0000a190, 0x07000701}, {0x0000a194, 0x00000000}, {0x0000a198, 0x00000000}, {0x0000a19c, 0x00000000}, @@ -772,7 +770,7 @@ static const u32 ar9565_1p0_Modes_lowest_ob_db_tx_gain_table[][5] = { static const u32 ar9565_1p0_pciephy_clkreq_disable_L1[][2] = { /* Addr allmodes */ - {0x00018c00, 0x18212ede}, + {0x00018c00, 0x18213ede}, {0x00018c04, 0x000801d8}, {0x00018c08, 0x0003780c}, }; @@ -891,8 +889,8 @@ static const u32 ar9565_1p0_common_wo_xlna_rx_gain_table[][2] = { {0x0000a180, 0x66816682}, {0x0000a184, 0x669f6680}, {0x0000a188, 0x669d669e}, - {0x0000a18c, 0x77e677e7}, - {0x0000a190, 0x77e477e5}, + {0x0000a18c, 0x77627763}, + {0x0000a190, 0x77607761}, {0x0000a194, 0x00000000}, {0x0000a198, 0x00000000}, {0x0000a19c, 0x00000000}, @@ -1116,7 +1114,7 @@ static const u32 ar9565_1p0_modes_high_ob_db_tx_gain_table[][5] = { {0x0000a2e0, 0xffecec00, 0xffecec00, 0xfd339c84, 0xfd339c84}, {0x0000a2e4, 0xfc0f0000, 0xfc0f0000, 0xfec3e000, 0xfec3e000}, {0x0000a2e8, 0xfc100000, 0xfc100000, 0xfffc0000, 0xfffc0000}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050df, 0x000050df}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, {0x0000a508, 0x0b022220, 0x0b022220, 0x08000004, 0x08000004}, @@ -1142,13 +1140,13 @@ static const u32 ar9565_1p0_modes_high_ob_db_tx_gain_table[][5] = { {0x0000a558, 0x69027f56, 0x69027f56, 0x53001ce5, 0x53001ce5}, {0x0000a55c, 0x6d029f56, 0x6d029f56, 0x57001ce9, 0x57001ce9}, {0x0000a560, 0x73049f56, 0x73049f56, 0x5b001ceb, 0x5b001ceb}, - {0x0000a564, 0x7804ff56, 0x7804ff56, 0x60001cf0, 0x60001cf0}, - {0x0000a568, 0x7804ff56, 0x7804ff56, 0x61001cf1, 0x61001cf1}, - {0x0000a56c, 0x7804ff56, 0x7804ff56, 0x62001cf2, 0x62001cf2}, - {0x0000a570, 0x7804ff56, 0x7804ff56, 0x63001cf3, 0x63001cf3}, - {0x0000a574, 0x7804ff56, 0x7804ff56, 0x64001cf4, 0x64001cf4}, - {0x0000a578, 0x7804ff56, 0x7804ff56, 0x66001ff6, 0x66001ff6}, - {0x0000a57c, 0x7804ff56, 0x7804ff56, 0x66001ff6, 0x66001ff6}, + {0x0000a564, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, + {0x0000a568, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, + {0x0000a56c, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, + {0x0000a570, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, + {0x0000a574, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, + {0x0000a578, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, + {0x0000a57c, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, @@ -1176,7 +1174,7 @@ static const u32 ar9565_1p0_modes_high_power_tx_gain_table[][5] = { {0x0000a2e0, 0xffecec00, 0xffecec00, 0xfd339c84, 0xfd339c84}, {0x0000a2e4, 0xfc0f0000, 0xfc0f0000, 0xfec3e000, 0xfec3e000}, {0x0000a2e8, 0xfc100000, 0xfc100000, 0xfffc0000, 0xfffc0000}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050df, 0x000050df}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, @@ -1202,13 +1200,13 @@ static const u32 ar9565_1p0_modes_high_power_tx_gain_table[][5] = { {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x7504ff56, 0x7504ff56, 0x59001cf0, 0x59001cf0}, - {0x0000a568, 0x7504ff56, 0x7504ff56, 0x5a001cf1, 0x5a001cf1}, - {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x5b001cf2, 0x5b001cf2}, - {0x0000a570, 0x7504ff56, 0x7504ff56, 0x5c001cf3, 0x5c001cf3}, - {0x0000a574, 0x7504ff56, 0x7504ff56, 0x5d001cf4, 0x5d001cf4}, - {0x0000a578, 0x7504ff56, 0x7504ff56, 0x5f001ff6, 0x5f001ff6}, - {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x5f001ff6, 0x5f001ff6}, + {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index a18414b5948b..6963862a1872 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -227,13 +227,13 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) goto work; + ath9k_set_beacon(sc); + if (ah->opmode == NL80211_IFTYPE_STATION && test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { spin_lock_irqsave(&sc->sc_pm_lock, flags); sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; spin_unlock_irqrestore(&sc->sc_pm_lock, flags); - } else { - ath9k_set_beacon(sc); } work: ath_restart_work(sc); @@ -1332,7 +1332,6 @@ static int ath9k_sta_add(struct ieee80211_hw *hw, struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_node *an = (struct ath_node *) sta->drv_priv; struct ieee80211_key_conf ps_key = { }; - int key; ath_node_attach(sc, sta, vif); @@ -1340,9 +1339,7 @@ static int ath9k_sta_add(struct ieee80211_hw *hw, vif->type != NL80211_IFTYPE_AP_VLAN) return 0; - key = ath_key_config(common, vif, sta, &ps_key); - if (key > 0) - an->ps_key = key; + an->ps_key = ath_key_config(common, vif, sta, &ps_key); return 0; } @@ -1359,7 +1356,6 @@ static void ath9k_del_ps_key(struct ath_softc *sc, return; ath_key_delete(common, &ps_key); - an->ps_key = 0; } static int ath9k_sta_remove(struct ieee80211_hw *hw, diff --git a/trunk/drivers/net/wireless/b43/dma.c b/trunk/drivers/net/wireless/b43/dma.c index f7c70b3a6ea9..523355b87659 100644 --- a/trunk/drivers/net/wireless/b43/dma.c +++ b/trunk/drivers/net/wireless/b43/dma.c @@ -1728,25 +1728,6 @@ static void dma_rx(struct b43_dmaring *ring, int *slot) sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); } -void b43_dma_handle_rx_overflow(struct b43_dmaring *ring) -{ - int current_slot, previous_slot; - - B43_WARN_ON(ring->tx); - - /* Device has filled all buffers, drop all packets and let TCP - * decrease speed. - * Decrement RX index by one will let the device to see all slots - * as free again - */ - /* - *TODO: How to increase rx_drop in mac80211? - */ - current_slot = ring->ops->get_current_rxslot(ring); - previous_slot = prev_slot(ring, current_slot); - ring->ops->set_current_rxslot(ring, previous_slot); -} - void b43_dma_rx(struct b43_dmaring *ring) { const struct b43_dma_ops *ops = ring->ops; diff --git a/trunk/drivers/net/wireless/b43/dma.h b/trunk/drivers/net/wireless/b43/dma.h index df8c8cdcbdb5..9fdd1983079c 100644 --- a/trunk/drivers/net/wireless/b43/dma.h +++ b/trunk/drivers/net/wireless/b43/dma.h @@ -9,7 +9,7 @@ /* DMA-Interrupt reasons. */ #define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ | (1 << 14) | (1 << 15)) -#define B43_DMAIRQ_RDESC_UFLOW (1 << 13) +#define B43_DMAIRQ_NONFATALMASK (1 << 13) #define B43_DMAIRQ_RX_DONE (1 << 16) /*** 32-bit DMA Engine. ***/ @@ -295,8 +295,6 @@ int b43_dma_tx(struct b43_wldev *dev, void b43_dma_handle_txstatus(struct b43_wldev *dev, const struct b43_txstatus *status); -void b43_dma_handle_rx_overflow(struct b43_dmaring *ring); - void b43_dma_rx(struct b43_dmaring *ring); void b43_dma_direct_fifo_rx(struct b43_wldev *dev, diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index 6dd07e2ec595..d377f77d30b5 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -1902,18 +1902,30 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) } } - if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK))) { - b43err(dev->wl, - "Fatal DMA error: 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X\n", - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3], - dma_reason[4], dma_reason[5]); - b43err(dev->wl, "This device does not support DMA " + if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK | + B43_DMAIRQ_NONFATALMASK))) { + if (merged_dma_reason & B43_DMAIRQ_FATALMASK) { + b43err(dev->wl, "Fatal DMA error: " + "0x%08X, 0x%08X, 0x%08X, " + "0x%08X, 0x%08X, 0x%08X\n", + dma_reason[0], dma_reason[1], + dma_reason[2], dma_reason[3], + dma_reason[4], dma_reason[5]); + b43err(dev->wl, "This device does not support DMA " "on your system. It will now be switched to PIO.\n"); - /* Fall back to PIO transfers if we get fatal DMA errors! */ - dev->use_pio = true; - b43_controller_restart(dev, "DMA error"); - return; + /* Fall back to PIO transfers if we get fatal DMA errors! */ + dev->use_pio = true; + b43_controller_restart(dev, "DMA error"); + return; + } + if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { + b43err(dev->wl, "DMA error: " + "0x%08X, 0x%08X, 0x%08X, " + "0x%08X, 0x%08X, 0x%08X\n", + dma_reason[0], dma_reason[1], + dma_reason[2], dma_reason[3], + dma_reason[4], dma_reason[5]); + } } if (unlikely(reason & B43_IRQ_UCODE_DEBUG)) @@ -1932,11 +1944,6 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) handle_irq_noise(dev); /* Check the DMA reason registers for received data. */ - if (dma_reason[0] & B43_DMAIRQ_RDESC_UFLOW) { - if (B43_DEBUG) - b43warn(dev->wl, "RX descriptor underrun\n"); - b43_dma_handle_rx_overflow(dev->dma.rx_ring); - } if (dma_reason[0] & B43_DMAIRQ_RX_DONE) { if (b43_using_pio_transfers(dev)) b43_pio_rx(dev->pio.rx_queue); @@ -1994,7 +2001,7 @@ static irqreturn_t b43_do_interrupt(struct b43_wldev *dev) return IRQ_NONE; dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) - & 0x0001FC00; + & 0x0001DC00; dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON) & 0x0000DC00; dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON) @@ -3123,7 +3130,7 @@ static int b43_chip_init(struct b43_wldev *dev) b43_write32(dev, 0x018C, 0x02000000); } b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000); - b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001FC00); + b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001DC00); b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00); b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00); b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00); diff --git a/trunk/drivers/net/wireless/iwlegacy/4965-mac.c b/trunk/drivers/net/wireless/iwlegacy/4965-mac.c index 9a95045c97b6..b8f82e688c72 100644 --- a/trunk/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/trunk/drivers/net/wireless/iwlegacy/4965-mac.c @@ -5741,7 +5741,8 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length) hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_AMPDU_AGGREGATION | IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC | IEEE80211_HW_SPECTRUM_MGMT | - IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; + IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_PS | + IEEE80211_HW_SUPPORTS_DYNAMIC_PS; if (il->cfg->sku & IL_SKU_N) hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | diff --git a/trunk/drivers/net/wireless/mwifiex/cfg80211.c b/trunk/drivers/net/wireless/mwifiex/cfg80211.c index e42b266a023a..d3c8ece980d8 100644 --- a/trunk/drivers/net/wireless/mwifiex/cfg80211.c +++ b/trunk/drivers/net/wireless/mwifiex/cfg80211.c @@ -2234,6 +2234,9 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) if (wdev->netdev->reg_state == NETREG_REGISTERED) unregister_netdevice(wdev->netdev); + if (wdev->netdev->reg_state == NETREG_UNREGISTERED) + free_netdev(wdev->netdev); + /* Clear the priv in adapter */ priv->netdev = NULL; diff --git a/trunk/drivers/net/wireless/mwifiex/cmdevt.c b/trunk/drivers/net/wireless/mwifiex/cmdevt.c index 26755d9acb55..74db0d24a579 100644 --- a/trunk/drivers/net/wireless/mwifiex/cmdevt.c +++ b/trunk/drivers/net/wireless/mwifiex/cmdevt.c @@ -1191,7 +1191,6 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter) adapter->if_ops.wakeup(adapter); adapter->hs_activated = false; adapter->is_hs_configured = false; - adapter->is_suspended = false; mwifiex_hs_activated_event(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY), false); diff --git a/trunk/drivers/net/wireless/mwifiex/main.c b/trunk/drivers/net/wireless/mwifiex/main.c index 2eb88ea9acf7..121443a0f2a1 100644 --- a/trunk/drivers/net/wireless/mwifiex/main.c +++ b/trunk/drivers/net/wireless/mwifiex/main.c @@ -655,7 +655,6 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev) { dev->netdev_ops = &mwifiex_netdev_ops; - dev->destructor = free_netdev; /* Initialize private structure */ priv->current_key_index = 0; priv->media_connected = false; diff --git a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c index 1a8a19dbd635..311d0b26b81c 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -96,7 +96,7 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, } else { /* Multicast */ priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE; - if (mcast_list->mode == MWIFIEX_ALL_MULTI_MODE) { + if (mcast_list->mode == MWIFIEX_MULTICAST_MODE) { dev_dbg(priv->adapter->dev, "info: Enabling All Multicast!\n"); priv->curr_pkt_filter |= @@ -108,11 +108,20 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: Set multicast list=%d\n", mcast_list->num_multicast_addr); - /* Send multicast addresses to firmware */ - ret = mwifiex_send_cmd_async(priv, - HostCmd_CMD_MAC_MULTICAST_ADR, - HostCmd_ACT_GEN_SET, 0, - mcast_list); + /* Set multicast addresses to firmware */ + if (old_pkt_filter == priv->curr_pkt_filter) { + /* Send request to firmware */ + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_MAC_MULTICAST_ADR, + HostCmd_ACT_GEN_SET, 0, + mcast_list); + } else { + /* Send request to firmware */ + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_MAC_MULTICAST_ADR, + HostCmd_ACT_GEN_SET, 0, + mcast_list); + } } } } diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index 86af29f53bbe..db95c547c09d 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -1353,8 +1353,6 @@ config SCSI_LPFC tristate "Emulex LightPulse Fibre Channel Support" depends on PCI && SCSI select SCSI_FC_ATTRS - select GENERIC_CSUM - select CRC_T10DIF help This lpfc driver supports the Emulex LightPulse Family of Fibre Channel PCI host adapters. diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_dev.c b/trunk/drivers/scsi/aic94xx/aic94xx_dev.c index 33072388ea16..64136c56e706 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_dev.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_dev.c @@ -84,7 +84,7 @@ static void asd_set_ddb_type(struct domain_device *dev) struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; int ddb = (int) (unsigned long) dev->lldd_dev; - if (dev->dev_type == SAS_SATA_PM_PORT) + if (dev->dev_type == SATA_PM_PORT) asd_ddbsite_write_byte(asd_ha,ddb, DDB_TYPE, DDB_TYPE_PM_PORT); else if (dev->tproto) asd_ddbsite_write_byte(asd_ha,ddb, DDB_TYPE, DDB_TYPE_TARGET); @@ -116,7 +116,7 @@ void asd_set_dmamode(struct domain_device *dev) int ddb = (int) (unsigned long) dev->lldd_dev; u32 qdepth = 0; - if (dev->dev_type == SAS_SATA_DEV || dev->dev_type == SAS_SATA_PM_PORT) { + if (dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM_PORT) { if (ata_id_has_ncq(ata_dev->id)) qdepth = ata_id_queue_depth(ata_dev->id); asd_ddbsite_write_dword(asd_ha, ddb, SATA_TAG_ALLOC_MASK, @@ -140,8 +140,8 @@ static int asd_init_sata(struct domain_device *dev) int ddb = (int) (unsigned long) dev->lldd_dev; asd_ddbsite_write_word(asd_ha, ddb, ATA_CMD_SCBPTR, 0xFFFF); - if (dev->dev_type == SAS_SATA_DEV || dev->dev_type == SAS_SATA_PM || - dev->dev_type == SAS_SATA_PM_PORT) { + if (dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM || + dev->dev_type == SATA_PM_PORT) { struct dev_to_host_fis *fis = (struct dev_to_host_fis *) dev->frame_rcvd; asd_ddbsite_write_byte(asd_ha, ddb, SATA_STATUS, fis->status); @@ -174,7 +174,7 @@ static int asd_init_target_ddb(struct domain_device *dev) asd_ddbsite_write_byte(asd_ha, ddb, CONN_MASK, dev->port->phy_mask); if (dev->port->oob_mode != SATA_OOB_MODE) { flags |= OPEN_REQUIRED; - if ((dev->dev_type == SAS_SATA_DEV) || + if ((dev->dev_type == SATA_DEV) || (dev->tproto & SAS_PROTOCOL_STP)) { struct smp_resp *rps_resp = &dev->sata_dev.rps_resp; if (rps_resp->frame_type == SMP_RESPONSE && @@ -188,8 +188,8 @@ static int asd_init_target_ddb(struct domain_device *dev) } else { flags |= CONCURRENT_CONN_SUPP; if (!dev->parent && - (dev->dev_type == SAS_EDGE_EXPANDER_DEVICE || - dev->dev_type == SAS_FANOUT_EXPANDER_DEVICE)) + (dev->dev_type == EDGE_DEV || + dev->dev_type == FANOUT_DEV)) asd_ddbsite_write_byte(asd_ha, ddb, MAX_CCONN, 4); else @@ -198,7 +198,7 @@ static int asd_init_target_ddb(struct domain_device *dev) asd_ddbsite_write_byte(asd_ha, ddb, NUM_CTX, 1); } } - if (dev->dev_type == SAS_SATA_PM) + if (dev->dev_type == SATA_PM) flags |= SATA_MULTIPORT; asd_ddbsite_write_byte(asd_ha, ddb, DDB_TARG_FLAGS, flags); @@ -211,7 +211,7 @@ static int asd_init_target_ddb(struct domain_device *dev) asd_ddbsite_write_word(asd_ha, ddb, SEND_QUEUE_TAIL, 0xFFFF); asd_ddbsite_write_word(asd_ha, ddb, SISTER_DDB, 0xFFFF); - if (dev->dev_type == SAS_SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) { + if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) { i = asd_init_sata(dev); if (i < 0) { asd_free_ddb(asd_ha, ddb); @@ -219,7 +219,7 @@ static int asd_init_target_ddb(struct domain_device *dev) } } - if (dev->dev_type == SAS_END_DEVICE) { + if (dev->dev_type == SAS_END_DEV) { struct sas_end_device *rdev = rphy_to_end_device(dev->rphy); if (rdev->I_T_nexus_loss_timeout > 0) asd_ddbsite_write_word(asd_ha, ddb, ITNL_TIMEOUT, @@ -328,10 +328,10 @@ int asd_dev_found(struct domain_device *dev) spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags); switch (dev->dev_type) { - case SAS_SATA_PM: + case SATA_PM: res = asd_init_sata_pm_ddb(dev); break; - case SAS_SATA_PM_PORT: + case SATA_PM_PORT: res = asd_init_sata_pm_port_ddb(dev); break; default: diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_hwi.c b/trunk/drivers/scsi/aic94xx/aic94xx_hwi.c index 4df867e07b20..81b736c76fff 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_hwi.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_hwi.c @@ -74,7 +74,7 @@ static void asd_init_phy_identify(struct asd_phy *phy) memset(phy->identify_frame, 0, sizeof(*phy->identify_frame)); - phy->identify_frame->dev_type = SAS_END_DEVICE; + phy->identify_frame->dev_type = SAS_END_DEV; if (phy->sas_phy.role & PHY_ROLE_INITIATOR) phy->identify_frame->initiator_bits = phy->sas_phy.iproto; if (phy->sas_phy.role & PHY_ROLE_TARGET) diff --git a/trunk/drivers/scsi/aic94xx/aic94xx_tmf.c b/trunk/drivers/scsi/aic94xx/aic94xx_tmf.c index d4c35df3d4ae..cf9040933da6 100644 --- a/trunk/drivers/scsi/aic94xx/aic94xx_tmf.c +++ b/trunk/drivers/scsi/aic94xx/aic94xx_tmf.c @@ -184,7 +184,7 @@ int asd_I_T_nexus_reset(struct domain_device *dev) struct sas_phy *phy = sas_get_local_phy(dev); /* Standard mandates link reset for ATA (type 0) and * hard reset for SSP (type 1) */ - int reset_type = (dev->dev_type == SAS_SATA_DEV || + int reset_type = (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) ? 0 : 1; asd_clear_nexus_I_T(dev, NEXUS_PHASE_PRE); diff --git a/trunk/drivers/scsi/be2iscsi/be.h b/trunk/drivers/scsi/be2iscsi/be.h index 777e7c0bbb4b..f1733dfa3ae2 100644 --- a/trunk/drivers/scsi/be2iscsi/be.h +++ b/trunk/drivers/scsi/be2iscsi/be.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2013 Emulex + * Copyright (C) 2005 - 2012 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or diff --git a/trunk/drivers/scsi/be2iscsi/be_cmds.c b/trunk/drivers/scsi/be2iscsi/be_cmds.c index e66aa7c11a8a..5c87768c109c 100644 --- a/trunk/drivers/scsi/be2iscsi/be_cmds.c +++ b/trunk/drivers/scsi/be2iscsi/be_cmds.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2013 Emulex + * Copyright (C) 2005 - 2012 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -155,7 +155,6 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba, uint16_t status = 0, addl_status = 0, wrb_num = 0; struct be_mcc_wrb *temp_wrb; struct be_cmd_req_hdr *ioctl_hdr; - struct be_cmd_resp_hdr *ioctl_resp_hdr; struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; if (beiscsi_error(phba)) @@ -205,12 +204,6 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba, ioctl_hdr->subsystem, ioctl_hdr->opcode, status, addl_status); - - if (status == MCC_STATUS_INSUFFICIENT_BUFFER) { - ioctl_resp_hdr = (struct be_cmd_resp_hdr *) ioctl_hdr; - if (ioctl_resp_hdr->response_length) - goto release_mcc_tag; - } rc = -EAGAIN; } @@ -274,7 +267,6 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl, struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev); struct be_cmd_req_hdr *hdr = embedded_payload(wrb); - struct be_cmd_resp_hdr *resp_hdr; be_dws_le_to_cpu(compl, 4); @@ -292,11 +284,6 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl, hdr->subsystem, hdr->opcode, compl_status, extd_status); - if (compl_status == MCC_STATUS_INSUFFICIENT_BUFFER) { - resp_hdr = (struct be_cmd_resp_hdr *) hdr; - if (resp_hdr->response_length) - return 0; - } return -EBUSY; } return 0; @@ -348,26 +335,30 @@ static void be2iscsi_fail_session(struct iscsi_cls_session *cls_session) void beiscsi_async_link_state_process(struct beiscsi_hba *phba, struct be_async_event_link_state *evt) { - if ((evt->port_link_status == ASYNC_EVENT_LINK_DOWN) || - ((evt->port_link_status & ASYNC_EVENT_LOGICAL) && - (evt->port_fault != BEISCSI_PHY_LINK_FAULT_NONE))) { - phba->state = BE_ADAPTER_LINK_DOWN; - + switch (evt->port_link_status) { + case ASYNC_EVENT_LINK_DOWN: beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT, - "BC_%d : Link Down on Port %d\n", + "BC_%d : Link Down on Physical Port %d\n", evt->physical_port); + phba->state |= BE_ADAPTER_LINK_DOWN; iscsi_host_for_each_session(phba->shost, be2iscsi_fail_session); - } else if ((evt->port_link_status & ASYNC_EVENT_LINK_UP) || - ((evt->port_link_status & ASYNC_EVENT_LOGICAL) && - (evt->port_fault == BEISCSI_PHY_LINK_FAULT_NONE))) { + break; + case ASYNC_EVENT_LINK_UP: phba->state = BE_ADAPTER_UP; - beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT, - "BC_%d : Link UP on Port %d\n", + "BC_%d : Link UP on Physical Port %d\n", + evt->physical_port); + break; + default: + beiscsi_log(phba, KERN_ERR, + BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT, + "BC_%d : Unexpected Async Notification %d on" + "Physical Port %d\n", + evt->port_link_status, evt->physical_port); } } @@ -488,7 +479,7 @@ static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl) { void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET; struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev); - uint32_t wait = 0; + int wait = 0; u32 ready; do { @@ -536,10 +527,6 @@ int be_mbox_notify(struct be_ctrl_info *ctrl) struct be_mcc_compl *compl = &mbox->compl; struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev); - status = be_mbox_db_ready_wait(ctrl); - if (status) - return status; - val &= ~MPU_MAILBOX_DB_RDY_MASK; val |= MPU_MAILBOX_DB_HI_MASK; val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2; @@ -593,10 +580,6 @@ static int be_mbox_notify_wait(struct beiscsi_hba *phba) struct be_mcc_compl *compl = &mbox->compl; struct be_ctrl_info *ctrl = &phba->ctrl; - status = be_mbox_db_ready_wait(ctrl); - if (status) - return status; - val |= MPU_MAILBOX_DB_HI_MASK; /* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */ val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2; @@ -749,16 +732,6 @@ int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl, return status; } -/** - * be_cmd_fw_initialize()- Initialize FW - * @ctrl: Pointer to function control structure - * - * Send FW initialize pattern for the function. - * - * return - * Success: 0 - * Failure: Non-Zero value - **/ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl) { struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); @@ -789,47 +762,6 @@ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl) return status; } -/** - * be_cmd_fw_uninit()- Uinitialize FW - * @ctrl: Pointer to function control structure - * - * Send FW uninitialize pattern for the function - * - * return - * Success: 0 - * Failure: Non-Zero value - **/ -int be_cmd_fw_uninit(struct be_ctrl_info *ctrl) -{ - struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); - struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev); - int status; - u8 *endian_check; - - spin_lock(&ctrl->mbox_lock); - memset(wrb, 0, sizeof(*wrb)); - - endian_check = (u8 *) wrb; - *endian_check++ = 0xFF; - *endian_check++ = 0xAA; - *endian_check++ = 0xBB; - *endian_check++ = 0xFF; - *endian_check++ = 0xFF; - *endian_check++ = 0xCC; - *endian_check++ = 0xDD; - *endian_check = 0xFF; - - be_dws_cpu_to_le(wrb, sizeof(*wrb)); - - status = be_mbox_notify(ctrl); - if (status) - beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, - "BC_%d : be_cmd_fw_uninit Failed\n"); - - spin_unlock(&ctrl->mbox_lock); - return status; -} - int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl, struct be_queue_info *cq, struct be_queue_info *eq, bool sol_evts, bool no_delay, int coalesce_wm) @@ -851,20 +783,7 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl, OPCODE_COMMON_CQ_CREATE, sizeof(*req)); req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); - if (is_chip_be2_be3r(phba)) { - AMAP_SET_BITS(struct amap_cq_context, coalescwm, - ctxt, coalesce_wm); - AMAP_SET_BITS(struct amap_cq_context, nodelay, ctxt, no_delay); - AMAP_SET_BITS(struct amap_cq_context, count, ctxt, - __ilog2_u32(cq->len / 256)); - AMAP_SET_BITS(struct amap_cq_context, valid, ctxt, 1); - AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts); - AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1); - AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id); - AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1); - AMAP_SET_BITS(struct amap_cq_context, func, ctxt, - PCI_FUNC(ctrl->pdev->devfn)); - } else { + if (chip_skh_r(ctrl->pdev)) { req->hdr.version = MBX_CMD_VER2; req->page_size = 1; AMAP_SET_BITS(struct amap_cq_context_v2, coalescwm, @@ -877,6 +796,19 @@ int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl, AMAP_SET_BITS(struct amap_cq_context_v2, eventable, ctxt, 1); AMAP_SET_BITS(struct amap_cq_context_v2, eqid, ctxt, eq->id); AMAP_SET_BITS(struct amap_cq_context_v2, armed, ctxt, 1); + } else { + AMAP_SET_BITS(struct amap_cq_context, coalescwm, + ctxt, coalesce_wm); + AMAP_SET_BITS(struct amap_cq_context, nodelay, ctxt, no_delay); + AMAP_SET_BITS(struct amap_cq_context, count, ctxt, + __ilog2_u32(cq->len / 256)); + AMAP_SET_BITS(struct amap_cq_context, valid, ctxt, 1); + AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts); + AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1); + AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id); + AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1); + AMAP_SET_BITS(struct amap_cq_context, func, ctxt, + PCI_FUNC(ctrl->pdev->devfn)); } be_dws_cpu_to_le(ctxt, sizeof(req->context)); @@ -1017,7 +949,6 @@ int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl, struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem); struct be_defq_create_req *req = embedded_payload(wrb); struct be_dma_mem *q_mem = &dq->dma_mem; - struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev); void *ctxt = &req->context; int status; @@ -1030,36 +961,17 @@ int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl, OPCODE_COMMON_ISCSI_DEFQ_CREATE, sizeof(*req)); req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size); - - if (is_chip_be2_be3r(phba)) { - AMAP_SET_BITS(struct amap_be_default_pdu_context, - rx_pdid, ctxt, 0); - AMAP_SET_BITS(struct amap_be_default_pdu_context, - rx_pdid_valid, ctxt, 1); - AMAP_SET_BITS(struct amap_be_default_pdu_context, - pci_func_id, ctxt, PCI_FUNC(ctrl->pdev->devfn)); - AMAP_SET_BITS(struct amap_be_default_pdu_context, - ring_size, ctxt, - be_encoded_q_len(length / - sizeof(struct phys_addr))); - AMAP_SET_BITS(struct amap_be_default_pdu_context, - default_buffer_size, ctxt, entry_size); - AMAP_SET_BITS(struct amap_be_default_pdu_context, - cq_id_recv, ctxt, cq->id); - } else { - AMAP_SET_BITS(struct amap_default_pdu_context_ext, - rx_pdid, ctxt, 0); - AMAP_SET_BITS(struct amap_default_pdu_context_ext, - rx_pdid_valid, ctxt, 1); - AMAP_SET_BITS(struct amap_default_pdu_context_ext, - ring_size, ctxt, - be_encoded_q_len(length / - sizeof(struct phys_addr))); - AMAP_SET_BITS(struct amap_default_pdu_context_ext, - default_buffer_size, ctxt, entry_size); - AMAP_SET_BITS(struct amap_default_pdu_context_ext, - cq_id_recv, ctxt, cq->id); - } + AMAP_SET_BITS(struct amap_be_default_pdu_context, rx_pdid, ctxt, 0); + AMAP_SET_BITS(struct amap_be_default_pdu_context, rx_pdid_valid, ctxt, + 1); + AMAP_SET_BITS(struct amap_be_default_pdu_context, pci_func_id, ctxt, + PCI_FUNC(ctrl->pdev->devfn)); + AMAP_SET_BITS(struct amap_be_default_pdu_context, ring_size, ctxt, + be_encoded_q_len(length / sizeof(struct phys_addr))); + AMAP_SET_BITS(struct amap_be_default_pdu_context, default_buffer_size, + ctxt, entry_size); + AMAP_SET_BITS(struct amap_be_default_pdu_context, cq_id_recv, ctxt, + cq->id); be_dws_cpu_to_le(ctxt, sizeof(req->context)); diff --git a/trunk/drivers/scsi/be2iscsi/be_cmds.h b/trunk/drivers/scsi/be2iscsi/be_cmds.h index 99073086dfe0..23397d51ac54 100644 --- a/trunk/drivers/scsi/be2iscsi/be_cmds.h +++ b/trunk/drivers/scsi/be2iscsi/be_cmds.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2013 Emulex + * Copyright (C) 2005 - 2012 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -52,10 +52,6 @@ struct be_mcc_wrb { /* Completion Status */ #define MCC_STATUS_SUCCESS 0x0 -#define MCC_STATUS_FAILED 0x1 -#define MCC_STATUS_ILLEGAL_REQUEST 0x2 -#define MCC_STATUS_ILLEGAL_FIELD 0x3 -#define MCC_STATUS_INSUFFICIENT_BUFFER 0x4 #define CQE_STATUS_COMPL_MASK 0xFFFF #define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */ @@ -122,8 +118,7 @@ struct be_async_event_trailer { enum { ASYNC_EVENT_LINK_DOWN = 0x0, - ASYNC_EVENT_LINK_UP = 0x1, - ASYNC_EVENT_LOGICAL = 0x2 + ASYNC_EVENT_LINK_UP = 0x1 }; /** @@ -135,9 +130,6 @@ struct be_async_event_link_state { u8 port_link_status; u8 port_duplex; u8 port_speed; -#define BEISCSI_PHY_LINK_FAULT_NONE 0x00 -#define BEISCSI_PHY_LINK_FAULT_LOCAL 0x01 -#define BEISCSI_PHY_LINK_FAULT_REMOTE 0x02 u8 port_fault; u8 rsvd0[7]; struct be_async_event_trailer trailer; @@ -705,7 +697,6 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba, uint32_t tag, struct be_mcc_wrb **wrb, void *cmd_va); /*ISCSI Functuions */ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl); -int be_cmd_fw_uninit(struct be_ctrl_info *ctrl); struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem); struct be_mcc_wrb *wrb_from_mccq(struct beiscsi_hba *phba); @@ -760,18 +751,6 @@ struct amap_be_default_pdu_context { u8 rsvd4[32]; /* dword 3 */ } __packed; -struct amap_default_pdu_context_ext { - u8 rsvd0[16]; /* dword 0 */ - u8 ring_size[4]; /* dword 0 */ - u8 rsvd1[12]; /* dword 0 */ - u8 rsvd2[22]; /* dword 1 */ - u8 rx_pdid[9]; /* dword 1 */ - u8 rx_pdid_valid; /* dword 1 */ - u8 default_buffer_size[16]; /* dword 2 */ - u8 cq_id_recv[16]; /* dword 2 */ - u8 rsvd3[32]; /* dword 3 */ -} __packed; - struct be_defq_create_req { struct be_cmd_req_hdr hdr; u16 num_pages; @@ -917,7 +896,7 @@ struct amap_it_dmsg_cqe_v2 { * stack to notify the * controller of a posted Work Request Block */ -#define DB_WRB_POST_CID_MASK 0xFFFF /* bits 0 - 16 */ +#define DB_WRB_POST_CID_MASK 0x3FF /* bits 0 - 9 */ #define DB_DEF_PDU_WRB_INDEX_MASK 0xFF /* bits 0 - 9 */ #define DB_DEF_PDU_WRB_INDEX_SHIFT 16 diff --git a/trunk/drivers/scsi/be2iscsi/be_iscsi.c b/trunk/drivers/scsi/be2iscsi/be_iscsi.c index ef36be003f67..9014690fe841 100644 --- a/trunk/drivers/scsi/be2iscsi/be_iscsi.c +++ b/trunk/drivers/scsi/be2iscsi/be_iscsi.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2013 Emulex + * Copyright (C) 2005 - 2012 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -161,9 +161,7 @@ static int beiscsi_bindconn_cid(struct beiscsi_hba *phba, struct beiscsi_conn *beiscsi_conn, unsigned int cid) { - uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); - - if (phba->conn_table[cri_index]) { + if (phba->conn_table[cid]) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, "BS_%d : Connection table already occupied. Detected clash\n"); @@ -171,9 +169,9 @@ static int beiscsi_bindconn_cid(struct beiscsi_hba *phba, } else { beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, "BS_%d : phba->conn_table[%d]=%p(beiscsi_conn)\n", - cri_index, beiscsi_conn); + cid, beiscsi_conn); - phba->conn_table[cri_index] = beiscsi_conn; + phba->conn_table[cid] = beiscsi_conn; } return 0; } @@ -992,27 +990,9 @@ static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid) static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep) { struct beiscsi_hba *phba = beiscsi_ep->phba; - struct beiscsi_conn *beiscsi_conn; beiscsi_put_cid(phba, beiscsi_ep->ep_cid); beiscsi_ep->phba = NULL; - phba->ep_array[BE_GET_CRI_FROM_CID - (beiscsi_ep->ep_cid)] = NULL; - - /** - * Check if any connection resource allocated by driver - * is to be freed.This case occurs when target redirection - * or connection retry is done. - **/ - if (!beiscsi_ep->conn) - return; - - beiscsi_conn = beiscsi_ep->conn; - if (beiscsi_conn->login_in_progress) { - beiscsi_free_mgmt_task_handles(beiscsi_conn, - beiscsi_conn->task); - beiscsi_conn->login_in_progress = 0; - } } /** @@ -1029,6 +1009,7 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, { struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; struct beiscsi_hba *phba = beiscsi_ep->phba; + struct be_mcc_wrb *wrb; struct tcp_connect_and_offload_out *ptcpcnct_out; struct be_dma_mem nonemb_cmd; unsigned int tag; @@ -1048,8 +1029,15 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, "BS_%d : In beiscsi_open_conn, ep_cid=%d\n", beiscsi_ep->ep_cid); - phba->ep_array[BE_GET_CRI_FROM_CID - (beiscsi_ep->ep_cid)] = ep; + phba->ep_array[beiscsi_ep->ep_cid - + phba->fw_config.iscsi_cid_start] = ep; + if (beiscsi_ep->ep_cid > (phba->fw_config.iscsi_cid_start + + phba->params.cxns_per_ctrl * 2)) { + + beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, + "BS_%d : Failed in allocate iscsi cid\n"); + goto free_ep; + } beiscsi_ep->cid_vld = 0; nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, @@ -1061,24 +1049,24 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, "BS_%d : Failed to allocate memory for" " mgmt_open_connection\n"); - beiscsi_free_ep(beiscsi_ep); + beiscsi_put_cid(phba, beiscsi_ep->ep_cid); return -ENOMEM; } nonemb_cmd.size = sizeof(struct tcp_connect_and_offload_in); memset(nonemb_cmd.va, 0, nonemb_cmd.size); tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd); - if (tag <= 0) { + if (!tag) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, "BS_%d : mgmt_open_connection Failed for cid=%d\n", beiscsi_ep->ep_cid); + beiscsi_put_cid(phba, beiscsi_ep->ep_cid); pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, nonemb_cmd.va, nonemb_cmd.dma); - beiscsi_free_ep(beiscsi_ep); return -EAGAIN; } - ret = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd.va); + ret = beiscsi_mccq_compl(phba, tag, &wrb, NULL); if (ret) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, @@ -1086,11 +1074,10 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, nonemb_cmd.va, nonemb_cmd.dma); - beiscsi_free_ep(beiscsi_ep); - return -EBUSY; + goto free_ep; } - ptcpcnct_out = (struct tcp_connect_and_offload_out *)nonemb_cmd.va; + ptcpcnct_out = embedded_payload(wrb); beiscsi_ep = ep->dd_data; beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle; beiscsi_ep->cid_vld = 1; @@ -1100,6 +1087,10 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep, pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, nonemb_cmd.va, nonemb_cmd.dma); return 0; + +free_ep: + beiscsi_free_ep(beiscsi_ep); + return -EBUSY; } /** @@ -1128,13 +1119,6 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, return ERR_PTR(ret); } - if (beiscsi_error(phba)) { - ret = -EIO; - beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, - "BS_%d : The FW state Not Stable!!!\n"); - return ERR_PTR(ret); - } - if (phba->state != BE_ADAPTER_UP) { ret = -EBUSY; beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, @@ -1217,10 +1201,8 @@ static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag) static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba, unsigned int cid) { - uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); - - if (phba->conn_table[cri_index]) - phba->conn_table[cri_index] = NULL; + if (phba->conn_table[cid]) + phba->conn_table[cid] = NULL; else { beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, "BS_%d : Connection table Not occupied.\n"); diff --git a/trunk/drivers/scsi/be2iscsi/be_iscsi.h b/trunk/drivers/scsi/be2iscsi/be_iscsi.h index 31ddc8494398..38eab7232159 100644 --- a/trunk/drivers/scsi/be2iscsi/be_iscsi.h +++ b/trunk/drivers/scsi/be2iscsi/be_iscsi.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2013 Emulex + * Copyright (C) 2005 - 2012 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or diff --git a/trunk/drivers/scsi/be2iscsi/be_main.c b/trunk/drivers/scsi/be2iscsi/be_main.c index d24a2867bc21..4e2733d23003 100644 --- a/trunk/drivers/scsi/be2iscsi/be_main.c +++ b/trunk/drivers/scsi/be2iscsi/be_main.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2013 Emulex + * Copyright (C) 2005 - 2012 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -153,14 +153,10 @@ BEISCSI_RW_ATTR(log_enable, 0x00, DEVICE_ATTR(beiscsi_drvr_ver, S_IRUGO, beiscsi_drvr_ver_disp, NULL); DEVICE_ATTR(beiscsi_adapter_family, S_IRUGO, beiscsi_adap_family_disp, NULL); -DEVICE_ATTR(beiscsi_fw_ver, S_IRUGO, beiscsi_fw_ver_disp, NULL); -DEVICE_ATTR(beiscsi_active_cid_count, S_IRUGO, beiscsi_active_cid_disp, NULL); struct device_attribute *beiscsi_attrs[] = { &dev_attr_beiscsi_log_enable, &dev_attr_beiscsi_drvr_ver, &dev_attr_beiscsi_adapter_family, - &dev_attr_beiscsi_fw_ver, - &dev_attr_beiscsi_active_cid_count, NULL, }; @@ -706,7 +702,7 @@ static void beiscsi_get_params(struct beiscsi_hba *phba) + BE2_TMFS + BE2_NOPOUT_REQ)); phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count; - phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count; + phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count * 2; phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count; phba->params.num_sge_per_io = BE2_SGE; phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ; @@ -1036,6 +1032,7 @@ static void hwi_ring_cq_db(struct beiscsi_hba *phba, static unsigned int beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn, struct beiscsi_hba *phba, + unsigned short cid, struct pdu_base *ppdu, unsigned long pdu_len, void *pbuffer, unsigned long buf_len) @@ -1147,10 +1144,9 @@ struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid) struct hwi_wrb_context *pwrb_context; struct hwi_controller *phwi_ctrlr; struct wrb_handle *pwrb_handle, *pwrb_handle_tmp; - uint16_t cri_index = BE_GET_CRI_FROM_CID(cid); phwi_ctrlr = phba->phwi_ctrlr; - pwrb_context = &phwi_ctrlr->wrb_context[cri_index]; + pwrb_context = &phwi_ctrlr->wrb_context[cid]; if (pwrb_context->wrb_handles_available >= 2) { pwrb_handle = pwrb_context->pwrb_handle_base[ pwrb_context->alloc_index]; @@ -1326,9 +1322,8 @@ be_complete_logout(struct beiscsi_conn *beiscsi_conn, hdr->t2retain = 0; hdr->flags = csol_cqe->i_flags; hdr->response = csol_cqe->i_resp; - hdr->exp_cmdsn = cpu_to_be32(csol_cqe->exp_cmdsn); - hdr->max_cmdsn = cpu_to_be32(csol_cqe->exp_cmdsn + - csol_cqe->cmd_wnd - 1); + hdr->exp_cmdsn = csol_cqe->exp_cmdsn; + hdr->max_cmdsn = (csol_cqe->exp_cmdsn + csol_cqe->cmd_wnd - 1); hdr->dlength[0] = 0; hdr->dlength[1] = 0; @@ -1351,9 +1346,9 @@ be_complete_tmf(struct beiscsi_conn *beiscsi_conn, hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP; hdr->flags = csol_cqe->i_flags; hdr->response = csol_cqe->i_resp; - hdr->exp_cmdsn = cpu_to_be32(csol_cqe->exp_cmdsn); - hdr->max_cmdsn = cpu_to_be32(csol_cqe->exp_cmdsn + - csol_cqe->cmd_wnd - 1); + hdr->exp_cmdsn = csol_cqe->exp_cmdsn; + hdr->max_cmdsn = (csol_cqe->exp_cmdsn + + csol_cqe->cmd_wnd - 1); hdr->itt = io_task->libiscsi_itt; __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); @@ -1368,29 +1363,35 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn, struct hwi_controller *phwi_ctrlr; struct iscsi_task *task; struct beiscsi_io_task *io_task; - uint16_t wrb_index, cid, cri_index; + struct iscsi_conn *conn = beiscsi_conn->conn; + struct iscsi_session *session = conn->session; + uint16_t wrb_index, cid; phwi_ctrlr = phba->phwi_ctrlr; - if (is_chip_be2_be3r(phba)) { - wrb_index = AMAP_GET_BITS(struct amap_it_dmsg_cqe, + if (chip_skh_r(phba->pcidev)) { + wrb_index = AMAP_GET_BITS(struct amap_it_dmsg_cqe_v2, wrb_idx, psol); - cid = AMAP_GET_BITS(struct amap_it_dmsg_cqe, + cid = AMAP_GET_BITS(struct amap_it_dmsg_cqe_v2, cid, psol); } else { - wrb_index = AMAP_GET_BITS(struct amap_it_dmsg_cqe_v2, + wrb_index = AMAP_GET_BITS(struct amap_it_dmsg_cqe, wrb_idx, psol); - cid = AMAP_GET_BITS(struct amap_it_dmsg_cqe_v2, + cid = AMAP_GET_BITS(struct amap_it_dmsg_cqe, cid, psol); } - cri_index = BE_GET_CRI_FROM_CID(cid); - pwrb_context = &phwi_ctrlr->wrb_context[cri_index]; + pwrb_context = &phwi_ctrlr->wrb_context[ + cid - phba->fw_config.iscsi_cid_start]; pwrb_handle = pwrb_context->pwrb_handle_basestd[wrb_index]; task = pwrb_handle->pio_handle; io_task = task->dd_data; - memset(io_task->pwrb_handle->pwrb, 0, sizeof(struct iscsi_wrb)); - iscsi_put_task(task); + spin_lock_bh(&phba->mgmt_sgl_lock); + free_mgmt_sgl_handle(phba, io_task->psgl_handle); + spin_unlock_bh(&phba->mgmt_sgl_lock); + spin_lock_bh(&session->lock); + free_wrb_handle(phba, pwrb_context, pwrb_handle); + spin_unlock_bh(&session->lock); } static void @@ -1405,8 +1406,8 @@ be_complete_nopin_resp(struct beiscsi_conn *beiscsi_conn, hdr = (struct iscsi_nopin *)task->hdr; hdr->flags = csol_cqe->i_flags; hdr->exp_cmdsn = cpu_to_be32(csol_cqe->exp_cmdsn); - hdr->max_cmdsn = cpu_to_be32(csol_cqe->exp_cmdsn + - csol_cqe->cmd_wnd - 1); + hdr->max_cmdsn = be32_to_cpu(hdr->exp_cmdsn + + csol_cqe->cmd_wnd - 1); hdr->opcode = ISCSI_OP_NOOP_IN; hdr->itt = io_task->libiscsi_itt; @@ -1417,26 +1418,7 @@ static void adapter_get_sol_cqe(struct beiscsi_hba *phba, struct sol_cqe *psol, struct common_sol_cqe *csol_cqe) { - if (is_chip_be2_be3r(phba)) { - csol_cqe->exp_cmdsn = AMAP_GET_BITS(struct amap_sol_cqe, - i_exp_cmd_sn, psol); - csol_cqe->res_cnt = AMAP_GET_BITS(struct amap_sol_cqe, - i_res_cnt, psol); - csol_cqe->cmd_wnd = AMAP_GET_BITS(struct amap_sol_cqe, - i_cmd_wnd, psol); - csol_cqe->wrb_index = AMAP_GET_BITS(struct amap_sol_cqe, - wrb_index, psol); - csol_cqe->cid = AMAP_GET_BITS(struct amap_sol_cqe, - cid, psol); - csol_cqe->hw_sts = AMAP_GET_BITS(struct amap_sol_cqe, - hw_sts, psol); - csol_cqe->i_resp = AMAP_GET_BITS(struct amap_sol_cqe, - i_resp, psol); - csol_cqe->i_sts = AMAP_GET_BITS(struct amap_sol_cqe, - i_sts, psol); - csol_cqe->i_flags = AMAP_GET_BITS(struct amap_sol_cqe, - i_flags, psol); - } else { + if (chip_skh_r(phba->pcidev)) { csol_cqe->exp_cmdsn = AMAP_GET_BITS(struct amap_sol_cqe_v2, i_exp_cmd_sn, psol); csol_cqe->res_cnt = AMAP_GET_BITS(struct amap_sol_cqe_v2, @@ -1447,7 +1429,7 @@ static void adapter_get_sol_cqe(struct beiscsi_hba *phba, cid, psol); csol_cqe->hw_sts = AMAP_GET_BITS(struct amap_sol_cqe_v2, hw_sts, psol); - csol_cqe->cmd_wnd = AMAP_GET_BITS(struct amap_sol_cqe_v2, + csol_cqe->cmd_wnd = AMAP_GET_BITS(struct amap_sol_cqe, i_cmd_wnd, psol); if (AMAP_GET_BITS(struct amap_sol_cqe_v2, cmd_cmpl, psol)) @@ -1463,6 +1445,25 @@ static void adapter_get_sol_cqe(struct beiscsi_hba *phba, if (AMAP_GET_BITS(struct amap_sol_cqe_v2, o, psol)) csol_cqe->i_flags |= ISCSI_FLAG_CMD_OVERFLOW; + } else { + csol_cqe->exp_cmdsn = AMAP_GET_BITS(struct amap_sol_cqe, + i_exp_cmd_sn, psol); + csol_cqe->res_cnt = AMAP_GET_BITS(struct amap_sol_cqe, + i_res_cnt, psol); + csol_cqe->cmd_wnd = AMAP_GET_BITS(struct amap_sol_cqe, + i_cmd_wnd, psol); + csol_cqe->wrb_index = AMAP_GET_BITS(struct amap_sol_cqe, + wrb_index, psol); + csol_cqe->cid = AMAP_GET_BITS(struct amap_sol_cqe, + cid, psol); + csol_cqe->hw_sts = AMAP_GET_BITS(struct amap_sol_cqe, + hw_sts, psol); + csol_cqe->i_resp = AMAP_GET_BITS(struct amap_sol_cqe, + i_resp, psol); + csol_cqe->i_sts = AMAP_GET_BITS(struct amap_sol_cqe, + i_sts, psol); + csol_cqe->i_flags = AMAP_GET_BITS(struct amap_sol_cqe, + i_flags, psol); } } @@ -1479,15 +1480,14 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, struct iscsi_conn *conn = beiscsi_conn->conn; struct iscsi_session *session = conn->session; struct common_sol_cqe csol_cqe = {0}; - uint16_t cri_index = 0; phwi_ctrlr = phba->phwi_ctrlr; /* Copy the elements to a common structure */ adapter_get_sol_cqe(phba, psol, &csol_cqe); - cri_index = BE_GET_CRI_FROM_CID(csol_cqe.cid); - pwrb_context = &phwi_ctrlr->wrb_context[cri_index]; + pwrb_context = &phwi_ctrlr->wrb_context[ + csol_cqe.cid - phba->fw_config.iscsi_cid_start]; pwrb_handle = pwrb_context->pwrb_handle_basestd[ csol_cqe.wrb_index]; @@ -1561,15 +1561,15 @@ hwi_get_async_handle(struct beiscsi_hba *phba, unsigned char is_header = 0; unsigned int index, dpl; - if (is_chip_be2_be3r(phba)) { - dpl = AMAP_GET_BITS(struct amap_i_t_dpdu_cqe, + if (chip_skh_r(phba->pcidev)) { + dpl = AMAP_GET_BITS(struct amap_i_t_dpdu_cqe_v2, dpl, pdpdu_cqe); - index = AMAP_GET_BITS(struct amap_i_t_dpdu_cqe, + index = AMAP_GET_BITS(struct amap_i_t_dpdu_cqe_v2, index, pdpdu_cqe); } else { - dpl = AMAP_GET_BITS(struct amap_i_t_dpdu_cqe_v2, + dpl = AMAP_GET_BITS(struct amap_i_t_dpdu_cqe, dpl, pdpdu_cqe); - index = AMAP_GET_BITS(struct amap_i_t_dpdu_cqe_v2, + index = AMAP_GET_BITS(struct amap_i_t_dpdu_cqe, index, pdpdu_cqe); } @@ -1613,8 +1613,8 @@ hwi_get_async_handle(struct beiscsi_hba *phba, WARN_ON(!pasync_handle); - pasync_handle->cri = - BE_GET_CRI_FROM_CID(beiscsi_conn->beiscsi_conn_cid); + pasync_handle->cri = (unsigned short)beiscsi_conn->beiscsi_conn_cid - + phba->fw_config.iscsi_cid_start; pasync_handle->is_header = is_header; pasync_handle->buffer_len = dpl; *pcq_index = index; @@ -1856,6 +1856,8 @@ hwi_fwd_async_msg(struct beiscsi_conn *beiscsi_conn, } status = beiscsi_process_async_pdu(beiscsi_conn, phba, + (beiscsi_conn->beiscsi_conn_cid - + phba->fw_config.iscsi_cid_start), phdr, hdr_len, pfirst_buffer, offset); @@ -2009,7 +2011,6 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) unsigned int num_processed = 0; unsigned int tot_nump = 0; unsigned short code = 0, cid = 0; - uint16_t cri_index = 0; struct beiscsi_conn *beiscsi_conn; struct beiscsi_endpoint *beiscsi_ep; struct iscsi_endpoint *ep; @@ -2027,9 +2028,7 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) 32] & CQE_CODE_MASK); /* Get the CID */ - if (is_chip_be2_be3r(phba)) { - cid = AMAP_GET_BITS(struct amap_sol_cqe, cid, sol); - } else { + if (chip_skh_r(phba->pcidev)) { if ((code == DRIVERMSG_NOTIFY) || (code == UNSOL_HDR_NOTIFY) || (code == UNSOL_DATA_NOTIFY)) @@ -2039,10 +2038,10 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) else cid = AMAP_GET_BITS(struct amap_sol_cqe_v2, cid, sol); - } + } else + cid = AMAP_GET_BITS(struct amap_sol_cqe, cid, sol); - cri_index = BE_GET_CRI_FROM_CID(cid); - ep = phba->ep_array[cri_index]; + ep = phba->ep_array[cid - phba->fw_config.iscsi_cid_start]; beiscsi_ep = ep->dd_data; beiscsi_conn = beiscsi_ep->conn; @@ -2192,7 +2191,7 @@ void beiscsi_process_all_cqs(struct work_struct *work) static int be_iopoll(struct blk_iopoll *iop, int budget) { - unsigned int ret; + static unsigned int ret; struct beiscsi_hba *phba; struct be_eq_obj *pbe_eq; @@ -2417,11 +2416,11 @@ static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task) /* Check for the data_count */ dsp_value = (task->data_count) ? 1 : 0; - if (is_chip_be2_be3r(phba)) - AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, + if (chip_skh_r(phba->pcidev)) + AMAP_SET_BITS(struct amap_iscsi_wrb_v2, dsp, pwrb, dsp_value); else - AMAP_SET_BITS(struct amap_iscsi_wrb_v2, dsp, + AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, dsp_value); /* Map addr only if there is data_count */ @@ -2539,9 +2538,8 @@ static void beiscsi_find_mem_req(struct beiscsi_hba *phba) static int beiscsi_alloc_mem(struct beiscsi_hba *phba) { - dma_addr_t bus_add; - struct hwi_controller *phwi_ctrlr; struct be_mem_descriptor *mem_descr; + dma_addr_t bus_add; struct mem_array *mem_arr, *mem_arr_orig; unsigned int i, j, alloc_size, curr_alloc_size; @@ -2549,18 +2547,9 @@ static int beiscsi_alloc_mem(struct beiscsi_hba *phba) if (!phba->phwi_ctrlr) return -ENOMEM; - /* Allocate memory for wrb_context */ - phwi_ctrlr = phba->phwi_ctrlr; - phwi_ctrlr->wrb_context = kzalloc(sizeof(struct hwi_wrb_context) * - phba->params.cxns_per_ctrl, - GFP_KERNEL); - if (!phwi_ctrlr->wrb_context) - return -ENOMEM; - phba->init_mem = kcalloc(SE_MEM_MAX, sizeof(*mem_descr), GFP_KERNEL); if (!phba->init_mem) { - kfree(phwi_ctrlr->wrb_context); kfree(phba->phwi_ctrlr); return -ENOMEM; } @@ -2569,7 +2558,6 @@ static int beiscsi_alloc_mem(struct beiscsi_hba *phba) GFP_KERNEL); if (!mem_arr_orig) { kfree(phba->init_mem); - kfree(phwi_ctrlr->wrb_context); kfree(phba->phwi_ctrlr); return -ENOMEM; } @@ -2640,7 +2628,6 @@ static int beiscsi_alloc_mem(struct beiscsi_hba *phba) } kfree(mem_arr_orig); kfree(phba->init_mem); - kfree(phba->phwi_ctrlr->wrb_context); kfree(phba->phwi_ctrlr); return -ENOMEM; } @@ -2679,7 +2666,6 @@ static void iscsi_init_global_templates(struct beiscsi_hba *phba) static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba) { struct be_mem_descriptor *mem_descr_wrbh, *mem_descr_wrb; - struct hwi_context_memory *phwi_ctxt; struct wrb_handle *pwrb_handle = NULL; struct hwi_controller *phwi_ctrlr; struct hwi_wrb_context *pwrb_context; @@ -2694,18 +2680,7 @@ static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba) mem_descr_wrb += HWI_MEM_WRB; phwi_ctrlr = phba->phwi_ctrlr; - /* Allocate memory for WRBQ */ - phwi_ctxt = phwi_ctrlr->phwi_ctxt; - phwi_ctxt->be_wrbq = kzalloc(sizeof(struct be_queue_info) * - phba->fw_config.iscsi_cid_count, - GFP_KERNEL); - if (!phwi_ctxt->be_wrbq) { - beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, - "BM_%d : WRBQ Mem Alloc Failed\n"); - return -ENOMEM; - } - - for (index = 0; index < phba->params.cxns_per_ctrl; index++) { + for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) { pwrb_context = &phwi_ctrlr->wrb_context[index]; pwrb_context->pwrb_handle_base = kzalloc(sizeof(struct wrb_handle *) * @@ -2748,7 +2723,7 @@ static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba) } } idx = 0; - for (index = 0; index < phba->params.cxns_per_ctrl; index++) { + for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) { pwrb_context = &phwi_ctrlr->wrb_context[index]; if (!num_cxn_wrb) { pwrb = mem_descr_wrb->mem_array[idx].virtual_address; @@ -2777,7 +2752,7 @@ static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba) return -ENOMEM; } -static int hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) +static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) { struct hwi_controller *phwi_ctrlr; struct hba_parameters *p = &phba->params; @@ -2795,15 +2770,6 @@ static int hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) pasync_ctx = phwi_ctrlr->phwi_ctxt->pasync_ctx; memset(pasync_ctx, 0, sizeof(*pasync_ctx)); - pasync_ctx->async_entry = kzalloc(sizeof(struct hwi_async_entry) * - phba->fw_config.iscsi_cid_count, - GFP_KERNEL); - if (!pasync_ctx->async_entry) { - beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, - "BM_%d : hwi_init_async_pdu_ctx Mem Alloc Failed\n"); - return -ENOMEM; - } - pasync_ctx->num_entries = p->asyncpdus_per_ctrl; pasync_ctx->buffer_size = p->defpdu_hdr_sz; @@ -2968,8 +2934,6 @@ static int hwi_init_async_pdu_ctx(struct beiscsi_hba *phba) pasync_ctx->async_header.ep_read_ptr = -1; pasync_ctx->async_data.host_write_ptr = 0; pasync_ctx->async_data.ep_read_ptr = -1; - - return 0; } static int @@ -3329,7 +3293,6 @@ beiscsi_create_wrb_rings(struct beiscsi_hba *phba, void *wrb_vaddr; struct be_dma_mem sgl; struct be_mem_descriptor *mem_descr; - struct hwi_wrb_context *pwrb_context; int status; idx = 0; @@ -3388,9 +3351,8 @@ beiscsi_create_wrb_rings(struct beiscsi_hba *phba, kfree(pwrb_arr); return status; } - pwrb_context = &phwi_ctrlr->wrb_context[i]; - pwrb_context->cid = phwi_context->be_wrbq[i].id; - BE_SET_CID_TO_CRI(i, pwrb_context->cid); + phwi_ctrlr->wrb_context[i * 2].cid = phwi_context->be_wrbq[i]. + id; } kfree(pwrb_arr); return 0; @@ -3403,7 +3365,7 @@ static void free_wrb_handles(struct beiscsi_hba *phba) struct hwi_wrb_context *pwrb_context; phwi_ctrlr = phba->phwi_ctrlr; - for (index = 0; index < phba->params.cxns_per_ctrl; index++) { + for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) { pwrb_context = &phwi_ctrlr->wrb_context[index]; kfree(pwrb_context->pwrb_handle_base); kfree(pwrb_context->pwrb_handle_basestd); @@ -3432,7 +3394,6 @@ static void hwi_cleanup(struct beiscsi_hba *phba) struct be_ctrl_info *ctrl = &phba->ctrl; struct hwi_controller *phwi_ctrlr; struct hwi_context_memory *phwi_context; - struct hwi_async_pdu_context *pasync_ctx; int i, eq_num; phwi_ctrlr = phba->phwi_ctrlr; @@ -3442,7 +3403,6 @@ static void hwi_cleanup(struct beiscsi_hba *phba) if (q->created) beiscsi_cmd_q_destroy(ctrl, q, QTYPE_WRBQ); } - kfree(phwi_context->be_wrbq); free_wrb_handles(phba); q = &phwi_context->be_def_hdrq; @@ -3470,10 +3430,6 @@ static void hwi_cleanup(struct beiscsi_hba *phba) beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ); } be_mcc_queues_destroy(phba); - - pasync_ctx = phwi_ctrlr->phwi_ctxt->pasync_ctx; - kfree(pasync_ctx->async_entry); - be_cmd_fw_uninit(ctrl); } static int be_mcc_queues_create(struct beiscsi_hba *phba, @@ -3651,12 +3607,7 @@ static int hwi_init_controller(struct beiscsi_hba *phba) if (beiscsi_init_wrb_handle(phba)) return -ENOMEM; - if (hwi_init_async_pdu_ctx(phba)) { - beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, - "BM_%d : hwi_init_async_pdu_ctx failed\n"); - return -ENOMEM; - } - + hwi_init_async_pdu_ctx(phba); if (hwi_init_port(phba) != 0) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, "BM_%d : hwi_init_controller failed\n"); @@ -3686,7 +3637,6 @@ static void beiscsi_free_mem(struct beiscsi_hba *phba) mem_descr++; } kfree(phba->init_mem); - kfree(phba->phwi_ctrlr->wrb_context); kfree(phba->phwi_ctrlr); } @@ -3819,7 +3769,7 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba) static int hba_setup_cid_tbls(struct beiscsi_hba *phba) { - int i; + int i, new_cid; phba->cid_array = kzalloc(sizeof(void *) * phba->params.cxns_per_ctrl, GFP_KERNEL); @@ -3830,33 +3780,19 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) return -ENOMEM; } phba->ep_array = kzalloc(sizeof(struct iscsi_endpoint *) * - phba->params.cxns_per_ctrl, GFP_KERNEL); + phba->params.cxns_per_ctrl * 2, GFP_KERNEL); if (!phba->ep_array) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, "BM_%d : Failed to allocate memory in " "hba_setup_cid_tbls\n"); kfree(phba->cid_array); - phba->cid_array = NULL; return -ENOMEM; } - - phba->conn_table = kzalloc(sizeof(struct beiscsi_conn *) * - phba->params.cxns_per_ctrl, GFP_KERNEL); - if (!phba->conn_table) { - beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, - "BM_%d : Failed to allocate memory in" - "hba_setup_cid_tbls\n"); - - kfree(phba->cid_array); - kfree(phba->ep_array); - phba->cid_array = NULL; - phba->ep_array = NULL; - return -ENOMEM; + new_cid = phba->fw_config.iscsi_cid_start; + for (i = 0; i < phba->params.cxns_per_ctrl; i++) { + phba->cid_array[i] = new_cid; + new_cid += 2; } - - for (i = 0; i < phba->params.cxns_per_ctrl; i++) - phba->cid_array[i] = phba->phwi_ctrlr->wrb_context[i].cid; - phba->avlbl_cids = phba->params.cxns_per_ctrl; return 0; } @@ -4126,53 +4062,6 @@ static void beiscsi_clean_port(struct beiscsi_hba *phba) kfree(phba->eh_sgl_hndl_base); kfree(phba->cid_array); kfree(phba->ep_array); - kfree(phba->conn_table); -} - -/** - * beiscsi_free_mgmt_task_handles()- Free driver CXN resources - * @beiscsi_conn: ptr to the conn to be cleaned up - * @task: ptr to iscsi_task resource to be freed. - * - * Free driver mgmt resources binded to CXN. - **/ -void -beiscsi_free_mgmt_task_handles(struct beiscsi_conn *beiscsi_conn, - struct iscsi_task *task) -{ - struct beiscsi_io_task *io_task; - struct beiscsi_hba *phba = beiscsi_conn->phba; - struct hwi_wrb_context *pwrb_context; - struct hwi_controller *phwi_ctrlr; - uint16_t cri_index = BE_GET_CRI_FROM_CID( - beiscsi_conn->beiscsi_conn_cid); - - phwi_ctrlr = phba->phwi_ctrlr; - pwrb_context = &phwi_ctrlr->wrb_context[cri_index]; - - io_task = task->dd_data; - - if (io_task->pwrb_handle) { - memset(io_task->pwrb_handle->pwrb, 0, - sizeof(struct iscsi_wrb)); - free_wrb_handle(phba, pwrb_context, - io_task->pwrb_handle); - io_task->pwrb_handle = NULL; - } - - if (io_task->psgl_handle) { - spin_lock_bh(&phba->mgmt_sgl_lock); - free_mgmt_sgl_handle(phba, - io_task->psgl_handle); - io_task->psgl_handle = NULL; - spin_unlock_bh(&phba->mgmt_sgl_lock); - } - - if (io_task->mtask_addr) - pci_unmap_single(phba->pcidev, - io_task->mtask_addr, - io_task->mtask_data_count, - PCI_DMA_TODEVICE); } /** @@ -4189,11 +4078,10 @@ static void beiscsi_cleanup_task(struct iscsi_task *task) struct beiscsi_session *beiscsi_sess = beiscsi_conn->beiscsi_sess; struct hwi_wrb_context *pwrb_context; struct hwi_controller *phwi_ctrlr; - uint16_t cri_index = BE_GET_CRI_FROM_CID( - beiscsi_conn->beiscsi_conn_cid); phwi_ctrlr = phba->phwi_ctrlr; - pwrb_context = &phwi_ctrlr->wrb_context[cri_index]; + pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid + - phba->fw_config.iscsi_cid_start]; if (io_task->cmd_bhs) { pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs, @@ -4215,8 +4103,27 @@ static void beiscsi_cleanup_task(struct iscsi_task *task) io_task->psgl_handle = NULL; } } else { - if (!beiscsi_conn->login_in_progress) - beiscsi_free_mgmt_task_handles(beiscsi_conn, task); + if (!beiscsi_conn->login_in_progress) { + if (io_task->pwrb_handle) { + free_wrb_handle(phba, pwrb_context, + io_task->pwrb_handle); + io_task->pwrb_handle = NULL; + } + if (io_task->psgl_handle) { + spin_lock(&phba->mgmt_sgl_lock); + free_mgmt_sgl_handle(phba, + io_task->psgl_handle); + spin_unlock(&phba->mgmt_sgl_lock); + io_task->psgl_handle = NULL; + } + if (io_task->mtask_addr) { + pci_unmap_single(phba->pcidev, + io_task->mtask_addr, + io_task->mtask_data_count, + PCI_DMA_TODEVICE); + io_task->mtask_addr = 0; + } + } } } @@ -4239,14 +4146,15 @@ beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn, beiscsi_cleanup_task(task); spin_unlock_bh(&session->lock); - pwrb_handle = alloc_wrb_handle(phba, beiscsi_conn->beiscsi_conn_cid); + pwrb_handle = alloc_wrb_handle(phba, (beiscsi_conn->beiscsi_conn_cid - + phba->fw_config.iscsi_cid_start)); /* Check for the adapter family */ - if (is_chip_be2_be3r(phba)) + if (chip_skh_r(phba->pcidev)) + beiscsi_offload_cxn_v2(params, pwrb_handle); + else beiscsi_offload_cxn_v0(params, pwrb_handle, phba->init_mem); - else - beiscsi_offload_cxn_v2(params, pwrb_handle); be_dws_le_to_cpu(pwrb_handle->pwrb, sizeof(struct iscsi_target_context_update_wrb)); @@ -4286,7 +4194,6 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) struct hwi_wrb_context *pwrb_context; struct hwi_controller *phwi_ctrlr; itt_t itt; - uint16_t cri_index = 0; struct beiscsi_session *beiscsi_sess = beiscsi_conn->beiscsi_sess; dma_addr_t paddr; @@ -4316,7 +4223,8 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) goto free_hndls; } io_task->pwrb_handle = alloc_wrb_handle(phba, - beiscsi_conn->beiscsi_conn_cid); + beiscsi_conn->beiscsi_conn_cid - + phba->fw_config.iscsi_cid_start); if (!io_task->pwrb_handle) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG, @@ -4328,7 +4236,6 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) } else { io_task->scsi_cmnd = NULL; if ((opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) { - beiscsi_conn->task = task; if (!beiscsi_conn->login_in_progress) { spin_lock(&phba->mgmt_sgl_lock); io_task->psgl_handle = (struct sgl_handle *) @@ -4350,7 +4257,8 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) io_task->psgl_handle; io_task->pwrb_handle = alloc_wrb_handle(phba, - beiscsi_conn->beiscsi_conn_cid); + beiscsi_conn->beiscsi_conn_cid - + phba->fw_config.iscsi_cid_start); if (!io_task->pwrb_handle) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_IO | @@ -4370,6 +4278,7 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) io_task->pwrb_handle = beiscsi_conn->plogin_wrb_handle; } + beiscsi_conn->task = task; } else { spin_lock(&phba->mgmt_sgl_lock); io_task->psgl_handle = alloc_mgmt_sgl_handle(phba); @@ -4386,7 +4295,8 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) } io_task->pwrb_handle = alloc_wrb_handle(phba, - beiscsi_conn->beiscsi_conn_cid); + beiscsi_conn->beiscsi_conn_cid - + phba->fw_config.iscsi_cid_start); if (!io_task->pwrb_handle) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG, @@ -4414,13 +4324,12 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode) free_mgmt_hndls: spin_lock(&phba->mgmt_sgl_lock); free_mgmt_sgl_handle(phba, io_task->psgl_handle); - io_task->psgl_handle = NULL; spin_unlock(&phba->mgmt_sgl_lock); free_hndls: phwi_ctrlr = phba->phwi_ctrlr; - cri_index = BE_GET_CRI_FROM_CID( - beiscsi_conn->beiscsi_conn_cid); - pwrb_context = &phwi_ctrlr->wrb_context[cri_index]; + pwrb_context = &phwi_ctrlr->wrb_context[ + beiscsi_conn->beiscsi_conn_cid - + phba->fw_config.iscsi_cid_start]; if (io_task->pwrb_handle) free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle); io_task->pwrb_handle = NULL; @@ -4442,6 +4351,7 @@ int beiscsi_iotask_v2(struct iscsi_task *task, struct scatterlist *sg, unsigned int doorbell = 0; pwrb = io_task->pwrb_handle->pwrb; + memset(pwrb, 0, sizeof(*pwrb)); io_task->cmd_bhs->iscsi_hdr.exp_statsn = 0; io_task->bhs_len = sizeof(struct be_cmd_bhs); @@ -4555,19 +4465,7 @@ static int beiscsi_mtask(struct iscsi_task *task) pwrb = io_task->pwrb_handle->pwrb; memset(pwrb, 0, sizeof(*pwrb)); - if (is_chip_be2_be3r(phba)) { - AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, - be32_to_cpu(task->cmdsn)); - AMAP_SET_BITS(struct amap_iscsi_wrb, wrb_idx, pwrb, - io_task->pwrb_handle->wrb_index); - AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb, - io_task->psgl_handle->sgl_index); - AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb, - task->data_count); - AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb, - io_task->pwrb_handle->nxt_wrb_index); - pwrb_typeoffset = BE_WRB_TYPE_OFFSET; - } else { + if (chip_skh_r(phba->pcidev)) { AMAP_SET_BITS(struct amap_iscsi_wrb_v2, cmdsn_itt, pwrb, be32_to_cpu(task->cmdsn)); AMAP_SET_BITS(struct amap_iscsi_wrb_v2, wrb_idx, pwrb, @@ -4579,6 +4477,18 @@ static int beiscsi_mtask(struct iscsi_task *task) AMAP_SET_BITS(struct amap_iscsi_wrb_v2, ptr2nextwrb, pwrb, io_task->pwrb_handle->nxt_wrb_index); pwrb_typeoffset = SKH_WRB_TYPE_OFFSET; + } else { + AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, + be32_to_cpu(task->cmdsn)); + AMAP_SET_BITS(struct amap_iscsi_wrb, wrb_idx, pwrb, + io_task->pwrb_handle->wrb_index); + AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb, + io_task->psgl_handle->sgl_index); + AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb, + task->data_count); + AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb, + io_task->pwrb_handle->nxt_wrb_index); + pwrb_typeoffset = BE_WRB_TYPE_OFFSET; } @@ -4591,19 +4501,19 @@ static int beiscsi_mtask(struct iscsi_task *task) case ISCSI_OP_NOOP_OUT: if (task->hdr->ttt != ISCSI_RESERVED_TAG) { ADAPTER_SET_WRB_TYPE(pwrb, TGT_DM_CMD, pwrb_typeoffset); - if (is_chip_be2_be3r(phba)) - AMAP_SET_BITS(struct amap_iscsi_wrb, + if (chip_skh_r(phba->pcidev)) + AMAP_SET_BITS(struct amap_iscsi_wrb_v2, dmsg, pwrb, 1); else - AMAP_SET_BITS(struct amap_iscsi_wrb_v2, + AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 1); } else { ADAPTER_SET_WRB_TYPE(pwrb, INI_RD_CMD, pwrb_typeoffset); - if (is_chip_be2_be3r(phba)) - AMAP_SET_BITS(struct amap_iscsi_wrb, + if (chip_skh_r(phba->pcidev)) + AMAP_SET_BITS(struct amap_iscsi_wrb_v2, dmsg, pwrb, 0); else - AMAP_SET_BITS(struct amap_iscsi_wrb_v2, + AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); } hwi_write_buffer(pwrb, task); @@ -4630,9 +4540,9 @@ static int beiscsi_mtask(struct iscsi_task *task) } /* Set the task type */ - io_task->wrb_type = (is_chip_be2_be3r(phba)) ? - AMAP_GET_BITS(struct amap_iscsi_wrb, type, pwrb) : - AMAP_GET_BITS(struct amap_iscsi_wrb_v2, type, pwrb); + io_task->wrb_type = (chip_skh_r(phba->pcidev)) ? + AMAP_GET_BITS(struct amap_iscsi_wrb_v2, type, pwrb) : + AMAP_GET_BITS(struct amap_iscsi_wrb, type, pwrb); doorbell |= cid & DB_WRB_POST_CID_MASK; doorbell |= (io_task->pwrb_handle->wrb_index & @@ -4924,7 +4834,6 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, case OC_SKH_ID1: phba->generation = BE_GEN4; phba->iotask_fn = beiscsi_iotask_v2; - break; default: phba->generation = 0; } diff --git a/trunk/drivers/scsi/be2iscsi/be_main.h b/trunk/drivers/scsi/be2iscsi/be_main.h index 2c06ef3c02ac..5946577d79d6 100644 --- a/trunk/drivers/scsi/be2iscsi/be_main.h +++ b/trunk/drivers/scsi/be2iscsi/be_main.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2013 Emulex + * Copyright (C) 2005 - 2012 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -36,7 +36,7 @@ #include "be.h" #define DRV_NAME "be2iscsi" -#define BUILD_STR "10.0.467.0" +#define BUILD_STR "10.0.272.0" #define BE_NAME "Emulex OneConnect" \ "Open-iSCSI Driver version" BUILD_STR #define DRV_DESC BE_NAME " " "Driver" @@ -66,9 +66,8 @@ #define MAX_CPUS 64 #define BEISCSI_MAX_NUM_CPUS 7 -#define OC_SKH_MAX_NUM_CPUS 31 +#define OC_SKH_MAX_NUM_CPUS 63 -#define BEISCSI_VER_STRLEN 32 #define BEISCSI_SGLIST_ELEMENTS 30 @@ -266,9 +265,7 @@ struct invalidate_command_table { unsigned short cid; } __packed; -#define chip_be2(phba) (phba->generation == BE_GEN2) -#define chip_be3_r(phba) (phba->generation == BE_GEN3) -#define is_chip_be2_be3r(phba) (chip_be3_r(phba) || (chip_be2(phba))) +#define chip_skh_r(pdev) (pdev->device == OC_SKH_ID1) struct beiscsi_hba { struct hba_parameters params; struct hwi_controller *phwi_ctrlr; @@ -307,15 +304,10 @@ struct beiscsi_hba { unsigned short avlbl_cids; unsigned short cid_alloc; unsigned short cid_free; + struct beiscsi_conn *conn_table[BE2_MAX_SESSIONS * 2]; struct list_head hba_queue; -#define BE_MAX_SESSION 2048 -#define BE_SET_CID_TO_CRI(cri_index, cid) \ - (phba->cid_to_cri_map[cid] = cri_index) -#define BE_GET_CRI_FROM_CID(cid) (phba->cid_to_cri_map[cid]) - unsigned short cid_to_cri_map[BE_MAX_SESSION]; unsigned short *cid_array; struct iscsi_endpoint **ep_array; - struct beiscsi_conn **conn_table; struct iscsi_boot_kset *boot_kset; struct Scsi_Host *shost; struct iscsi_iface *ipv4_iface; @@ -347,7 +339,6 @@ struct beiscsi_hba { struct delayed_work beiscsi_hw_check_task; u8 mac_address[ETH_ALEN]; - char fw_ver_str[BEISCSI_VER_STRLEN]; char wq_name[20]; struct workqueue_struct *wq; /* The actuak work queue */ struct be_ctrl_info ctrl; @@ -572,7 +563,7 @@ struct hwi_async_pdu_context { * This is a varying size list! Do not add anything * after this entry!! */ - struct hwi_async_entry *async_entry; + struct hwi_async_entry async_entry[BE2_MAX_SESSIONS * 2]; }; #define PDUCQE_CODE_MASK 0x0000003F @@ -758,8 +749,6 @@ void free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle); void beiscsi_process_all_cqs(struct work_struct *work); -void beiscsi_free_mgmt_task_handles(struct beiscsi_conn *beiscsi_conn, - struct iscsi_task *task); static inline bool beiscsi_error(struct beiscsi_hba *phba) { @@ -944,7 +933,7 @@ struct hwi_controller { struct sgl_handle *psgl_handle_base; unsigned int wrb_mem_index; - struct hwi_wrb_context *wrb_context; + struct hwi_wrb_context wrb_context[BE2_MAX_SESSIONS * 2]; struct mcc_wrb *pmcc_wrb_base; struct be_ring default_pdu_hdr; struct be_ring default_pdu_data; @@ -981,7 +970,9 @@ struct hwi_context_memory { struct be_queue_info be_def_hdrq; struct be_queue_info be_def_dataq; - struct be_queue_info *be_wrbq; + struct be_queue_info be_wrbq[BE2_MAX_SESSIONS]; + struct be_mcc_wrb_context *pbe_mcc_context; + struct hwi_async_pdu_context *pasync_ctx; }; diff --git a/trunk/drivers/scsi/be2iscsi/be_mgmt.c b/trunk/drivers/scsi/be2iscsi/be_mgmt.c index 245a9595a93a..55cc9902263d 100644 --- a/trunk/drivers/scsi/be2iscsi/be_mgmt.c +++ b/trunk/drivers/scsi/be2iscsi/be_mgmt.c @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2013 Emulex + * Copyright (C) 2005 - 2012 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -368,8 +368,6 @@ int mgmt_check_supported_fw(struct be_ctrl_info *ctrl, beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT, "BM_%d : phba->fw_config.iscsi_features = %d\n", phba->fw_config.iscsi_features); - memcpy(phba->fw_ver_str, resp->params.hba_attribs. - firmware_version_string, BEISCSI_VER_STRLEN); } else beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, "BG_%d : Failed in mgmt_check_supported_fw\n"); @@ -1261,45 +1259,6 @@ beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr, return snprintf(buf, PAGE_SIZE, BE_NAME "\n"); } -/** - * beiscsi_fw_ver_disp()- Display Firmware Version - * @dev: ptr to device not used. - * @attr: device attribute, not used. - * @buf: contains formatted text Firmware version - * - * return - * size of the formatted string - **/ -ssize_t -beiscsi_fw_ver_disp(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct beiscsi_hba *phba = iscsi_host_priv(shost); - - return snprintf(buf, PAGE_SIZE, "%s\n", phba->fw_ver_str); -} - -/** - * beiscsi_active_cid_disp()- Display Sessions Active - * @dev: ptr to device not used. - * @attr: device attribute, not used. - * @buf: contains formatted text Session Count - * - * return - * size of the formatted string - **/ -ssize_t -beiscsi_active_cid_disp(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct beiscsi_hba *phba = iscsi_host_priv(shost); - - return snprintf(buf, PAGE_SIZE, "%d\n", - (phba->params.cxns_per_ctrl - phba->avlbl_cids)); -} - /** * beiscsi_adap_family_disp()- Display adapter family. * @dev: ptr to device to get priv structure diff --git a/trunk/drivers/scsi/be2iscsi/be_mgmt.h b/trunk/drivers/scsi/be2iscsi/be_mgmt.h index 04af7e74fe48..2e4968add799 100644 --- a/trunk/drivers/scsi/be2iscsi/be_mgmt.h +++ b/trunk/drivers/scsi/be2iscsi/be_mgmt.h @@ -1,5 +1,5 @@ /** - * Copyright (C) 2005 - 2013 Emulex + * Copyright (C) 2005 - 2012 Emulex * All rights reserved. * * This program is free software; you can redistribute it and/or @@ -156,25 +156,25 @@ union invalidate_commands_params { } __packed; struct mgmt_hba_attributes { - u8 flashrom_version_string[BEISCSI_VER_STRLEN]; - u8 manufacturer_name[BEISCSI_VER_STRLEN]; + u8 flashrom_version_string[32]; + u8 manufacturer_name[32]; u32 supported_modes; u8 seeprom_version_lo; u8 seeprom_version_hi; u8 rsvd0[2]; u32 fw_cmd_data_struct_version; u32 ep_fw_data_struct_version; - u8 ncsi_version_string[12]; + u32 future_reserved[12]; u32 default_extended_timeout; - u8 controller_model_number[BEISCSI_VER_STRLEN]; + u8 controller_model_number[32]; u8 controller_description[64]; - u8 controller_serial_number[BEISCSI_VER_STRLEN]; - u8 ip_version_string[BEISCSI_VER_STRLEN]; - u8 firmware_version_string[BEISCSI_VER_STRLEN]; - u8 bios_version_string[BEISCSI_VER_STRLEN]; - u8 redboot_version_string[BEISCSI_VER_STRLEN]; - u8 driver_version_string[BEISCSI_VER_STRLEN]; - u8 fw_on_flash_version_string[BEISCSI_VER_STRLEN]; + u8 controller_serial_number[32]; + u8 ip_version_string[32]; + u8 firmware_version_string[32]; + u8 bios_version_string[32]; + u8 redboot_version_string[32]; + u8 driver_version_string[32]; + u8 fw_on_flash_version_string[32]; u32 functionalities_supported; u16 max_cdblength; u8 asic_revision; @@ -190,8 +190,7 @@ struct mgmt_hba_attributes { u32 firmware_post_status; u32 hba_mtu[8]; u8 iscsi_features; - u8 asic_generation; - u8 future_u8[2]; + u8 future_u8[3]; u32 future_u32[3]; } __packed; @@ -208,7 +207,7 @@ struct mgmt_controller_attributes { u64 unique_identifier; u8 netfilters; u8 rsvd0[3]; - u32 future_u32[4]; + u8 future_u32[4]; } __packed; struct be_mgmt_controller_attributes { @@ -312,12 +311,6 @@ int mgmt_set_vlan(struct beiscsi_hba *phba, uint16_t vlan_tag); ssize_t beiscsi_drvr_ver_disp(struct device *dev, struct device_attribute *attr, char *buf); -ssize_t beiscsi_fw_ver_disp(struct device *dev, - struct device_attribute *attr, char *buf); - -ssize_t beiscsi_active_cid_disp(struct device *dev, - struct device_attribute *attr, char *buf); - ssize_t beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr, char *buf); diff --git a/trunk/drivers/scsi/bnx2fc/bnx2fc.h b/trunk/drivers/scsi/bnx2fc/bnx2fc.h index 08b22a901c25..11596b2c4702 100644 --- a/trunk/drivers/scsi/bnx2fc/bnx2fc.h +++ b/trunk/drivers/scsi/bnx2fc/bnx2fc.h @@ -2,7 +2,7 @@ #define _BNX2FC_H_ /* bnx2fc.h: Broadcom NetXtreme II Linux FCoE offload driver. * - * Copyright (c) 2008 - 2013 Broadcom Corporation + * Copyright (c) 2008 - 2011 Broadcom Corporation * * 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 @@ -64,12 +64,10 @@ #include "bnx2fc_constants.h" #define BNX2FC_NAME "bnx2fc" -#define BNX2FC_VERSION "1.0.14" +#define BNX2FC_VERSION "1.0.13" #define PFX "bnx2fc: " -#define BCM_CHIP_LEN 16 - #define BNX2X_DOORBELL_PCI_BAR 2 #define BNX2FC_MAX_BD_LEN 0xffff @@ -243,8 +241,6 @@ struct bnx2fc_hba { int wait_for_link_down; int num_ofld_sess; struct list_head vports; - - char chip_num[BCM_CHIP_LEN]; }; struct bnx2fc_interface { diff --git a/trunk/drivers/scsi/bnx2fc/bnx2fc_els.c b/trunk/drivers/scsi/bnx2fc/bnx2fc_els.c index b1c9a4f8caee..bdbbb13b8534 100644 --- a/trunk/drivers/scsi/bnx2fc/bnx2fc_els.c +++ b/trunk/drivers/scsi/bnx2fc/bnx2fc_els.c @@ -3,7 +3,7 @@ * This file contains helper routines that handle ELS requests * and responses. * - * Copyright (c) 2008 - 2013 Broadcom Corporation + * Copyright (c) 2008 - 2011 Broadcom Corporation * * 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 diff --git a/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 69ac55495c1d..7dffec1e5715 100644 --- a/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -3,7 +3,7 @@ * cnic modules to create FCoE instances, send/receive non-offloaded * FIP/FCoE packets, listen to link events etc. * - * Copyright (c) 2008 - 2013 Broadcom Corporation + * Copyright (c) 2008 - 2011 Broadcom Corporation * * 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 @@ -22,7 +22,7 @@ DEFINE_PER_CPU(struct bnx2fc_percpu_s, bnx2fc_percpu); #define DRV_MODULE_NAME "bnx2fc" #define DRV_MODULE_VERSION BNX2FC_VERSION -#define DRV_MODULE_RELDATE "Mar 08, 2013" +#define DRV_MODULE_RELDATE "Dec 21, 2012" static char version[] = @@ -679,7 +679,6 @@ static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev) { struct fcoe_port *port = lport_priv(lport); struct bnx2fc_interface *interface = port->priv; - struct bnx2fc_hba *hba = interface->hba; struct Scsi_Host *shost = lport->host; int rc = 0; @@ -700,9 +699,8 @@ static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev) } if (!lport->vport) fc_host_max_npiv_vports(lport->host) = USHRT_MAX; - snprintf(fc_host_symbolic_name(lport->host), 256, - "%s (Broadcom %s) v%s over %s", - BNX2FC_NAME, hba->chip_num, BNX2FC_VERSION, + sprintf(fc_host_symbolic_name(lport->host), "%s v%s over %s", + BNX2FC_NAME, BNX2FC_VERSION, interface->netdev->name); return 0; @@ -1658,60 +1656,23 @@ static int bnx2fc_bind_adapter_devices(struct bnx2fc_hba *hba) static int bnx2fc_bind_pcidev(struct bnx2fc_hba *hba) { struct cnic_dev *cnic; - struct pci_dev *pdev; if (!hba->cnic) { printk(KERN_ERR PFX "cnic is NULL\n"); return -ENODEV; } cnic = hba->cnic; - pdev = hba->pcidev = cnic->pcidev; - if (!hba->pcidev) - return -ENODEV; + hba->pcidev = cnic->pcidev; + if (hba->pcidev) + pci_dev_get(hba->pcidev); - switch (pdev->device) { - case PCI_DEVICE_ID_NX2_57710: - strncpy(hba->chip_num, "BCM57710", BCM_CHIP_LEN); - break; - case PCI_DEVICE_ID_NX2_57711: - strncpy(hba->chip_num, "BCM57711", BCM_CHIP_LEN); - break; - case PCI_DEVICE_ID_NX2_57712: - case PCI_DEVICE_ID_NX2_57712_MF: - case PCI_DEVICE_ID_NX2_57712_VF: - strncpy(hba->chip_num, "BCM57712", BCM_CHIP_LEN); - break; - case PCI_DEVICE_ID_NX2_57800: - case PCI_DEVICE_ID_NX2_57800_MF: - case PCI_DEVICE_ID_NX2_57800_VF: - strncpy(hba->chip_num, "BCM57800", BCM_CHIP_LEN); - break; - case PCI_DEVICE_ID_NX2_57810: - case PCI_DEVICE_ID_NX2_57810_MF: - case PCI_DEVICE_ID_NX2_57810_VF: - strncpy(hba->chip_num, "BCM57810", BCM_CHIP_LEN); - break; - case PCI_DEVICE_ID_NX2_57840: - case PCI_DEVICE_ID_NX2_57840_MF: - case PCI_DEVICE_ID_NX2_57840_VF: - case PCI_DEVICE_ID_NX2_57840_2_20: - case PCI_DEVICE_ID_NX2_57840_4_10: - strncpy(hba->chip_num, "BCM57840", BCM_CHIP_LEN); - break; - default: - pr_err(PFX "Unknown device id 0x%x\n", pdev->device); - break; - } - pci_dev_get(hba->pcidev); return 0; } static void bnx2fc_unbind_pcidev(struct bnx2fc_hba *hba) { - if (hba->pcidev) { - hba->chip_num[0] = '\0'; + if (hba->pcidev) pci_dev_put(hba->pcidev); - } hba->pcidev = NULL; } diff --git a/trunk/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/trunk/drivers/scsi/bnx2fc/bnx2fc_hwi.c index c0d035a8f8f9..50510ffe1bf5 100644 --- a/trunk/drivers/scsi/bnx2fc/bnx2fc_hwi.c +++ b/trunk/drivers/scsi/bnx2fc/bnx2fc_hwi.c @@ -2,7 +2,7 @@ * This file contains the code that low level functions that interact * with 57712 FCoE firmware. * - * Copyright (c) 2008 - 2013 Broadcom Corporation + * Copyright (c) 2008 - 2011 Broadcom Corporation * * 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 @@ -126,11 +126,7 @@ int bnx2fc_send_fw_fcoe_init_msg(struct bnx2fc_hba *hba) fcoe_init3.error_bit_map_lo = 0xffffffff; fcoe_init3.error_bit_map_hi = 0xffffffff; - /* - * enable both cached connection and cached tasks - * 0 = none, 1 = cached connection, 2 = cached tasks, 3 = both - */ - fcoe_init3.perf_config = 3; + fcoe_init3.perf_config = 1; kwqe_arr[0] = (struct kwqe *) &fcoe_init1; kwqe_arr[1] = (struct kwqe *) &fcoe_init2; diff --git a/trunk/drivers/scsi/bnx2fc/bnx2fc_io.c b/trunk/drivers/scsi/bnx2fc/bnx2fc_io.c index 575142e92d9c..723a9a8ba5ee 100644 --- a/trunk/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/trunk/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -1,7 +1,7 @@ /* bnx2fc_io.c: Broadcom NetXtreme II Linux FCoE offload driver. * IO manager and SCSI IO processing. * - * Copyright (c) 2008 - 2013 Broadcom Corporation + * Copyright (c) 2008 - 2011 Broadcom Corporation * * 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 @@ -1270,11 +1270,8 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd) spin_lock_bh(&tgt->tgt_lock); io_req->wait_for_comp = 0; - if (test_bit(BNX2FC_FLAG_IO_COMPL, &io_req->req_flags)) { - BNX2FC_IO_DBG(io_req, "IO completed in a different context\n"); - rc = SUCCESS; - } else if (!(test_and_set_bit(BNX2FC_FLAG_ABTS_DONE, - &io_req->req_flags))) { + if (!(test_and_set_bit(BNX2FC_FLAG_ABTS_DONE, + &io_req->req_flags))) { /* Let the scsi-ml try to recover this command */ printk(KERN_ERR PFX "abort failed, xid = 0x%x\n", io_req->xid); diff --git a/trunk/drivers/scsi/bnx2fc/bnx2fc_tgt.c b/trunk/drivers/scsi/bnx2fc/bnx2fc_tgt.c index 4d93177dfb53..c57a3bb8a9fb 100644 --- a/trunk/drivers/scsi/bnx2fc/bnx2fc_tgt.c +++ b/trunk/drivers/scsi/bnx2fc/bnx2fc_tgt.c @@ -2,7 +2,7 @@ * Handles operations such as session offload/upload etc, and manages * session resources such as connection id and qp resources. * - * Copyright (c) 2008 - 2013 Broadcom Corporation + * Copyright (c) 2008 - 2011 Broadcom Corporation * * 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 diff --git a/trunk/drivers/scsi/csiostor/csio_lnode.h b/trunk/drivers/scsi/csiostor/csio_lnode.h index 372a67d122d3..0f9c04175b11 100644 --- a/trunk/drivers/scsi/csiostor/csio_lnode.h +++ b/trunk/drivers/scsi/csiostor/csio_lnode.h @@ -114,7 +114,7 @@ struct csio_lnode_stats { uint32_t n_rnode_match; /* matched rnode */ uint32_t n_dev_loss_tmo; /* Device loss timeout */ uint32_t n_fdmi_err; /* fdmi err */ - uint32_t n_evt_fw[PROTO_ERR_IMPL_LOGO + 1]; /* fw events */ + uint32_t n_evt_fw[PROTO_ERR_IMPL_LOGO]; /* fw events */ enum csio_ln_ev n_evt_sm[CSIO_LNE_MAX_EVENT]; /* State m/c events */ uint32_t n_rnode_alloc; /* rnode allocated */ uint32_t n_rnode_free; /* rnode freed */ diff --git a/trunk/drivers/scsi/csiostor/csio_rnode.h b/trunk/drivers/scsi/csiostor/csio_rnode.h index 433434221222..65940096a80d 100644 --- a/trunk/drivers/scsi/csiostor/csio_rnode.h +++ b/trunk/drivers/scsi/csiostor/csio_rnode.h @@ -63,7 +63,7 @@ struct csio_rnode_stats { uint32_t n_err_nomem; /* error nomem */ uint32_t n_evt_unexp; /* unexpected event */ uint32_t n_evt_drop; /* unexpected event */ - uint32_t n_evt_fw[PROTO_ERR_IMPL_LOGO + 1]; /* fw events */ + uint32_t n_evt_fw[PROTO_ERR_IMPL_LOGO]; /* fw events */ enum csio_rn_ev n_evt_sm[CSIO_RNFE_MAX_EVENT]; /* State m/c events */ uint32_t n_lun_rst; /* Number of resets of * of LUNs under this diff --git a/trunk/drivers/scsi/fnic/fnic.h b/trunk/drivers/scsi/fnic/fnic.h index b6d1f92ed33c..98436c363035 100644 --- a/trunk/drivers/scsi/fnic/fnic.h +++ b/trunk/drivers/scsi/fnic/fnic.h @@ -38,7 +38,7 @@ #define DRV_NAME "fnic" #define DRV_DESCRIPTION "Cisco FCoE HBA Driver" -#define DRV_VERSION "1.5.0.22" +#define DRV_VERSION "1.5.0.2" #define PFX DRV_NAME ": " #define DFX DRV_NAME "%d: " @@ -192,18 +192,6 @@ enum fnic_state { struct mempool; -enum fnic_evt { - FNIC_EVT_START_VLAN_DISC = 1, - FNIC_EVT_START_FCF_DISC = 2, - FNIC_EVT_MAX, -}; - -struct fnic_event { - struct list_head list; - struct fnic *fnic; - enum fnic_evt event; -}; - /* Per-instance private data structure */ struct fnic { struct fc_lport *lport; @@ -266,18 +254,6 @@ struct fnic { struct sk_buff_head frame_queue; struct sk_buff_head tx_queue; - /*** FIP related data members -- start ***/ - void (*set_vlan)(struct fnic *, u16 vlan); - struct work_struct fip_frame_work; - struct sk_buff_head fip_frame_queue; - struct timer_list fip_timer; - struct list_head vlans; - spinlock_t vlans_lock; - - struct work_struct event_work; - struct list_head evlist; - /*** FIP related data members -- end ***/ - /* copy work queue cache line section */ ____cacheline_aligned struct vnic_wq_copy wq_copy[FNIC_WQ_COPY_MAX]; /* completion queue cache line section */ @@ -302,7 +278,6 @@ static inline struct fnic *fnic_from_ctlr(struct fcoe_ctlr *fip) } extern struct workqueue_struct *fnic_event_queue; -extern struct workqueue_struct *fnic_fip_queue; extern struct device_attribute *fnic_attrs[]; void fnic_clear_intr_mode(struct fnic *fnic); @@ -314,7 +289,6 @@ int fnic_send(struct fc_lport *, struct fc_frame *); void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf); void fnic_handle_frame(struct work_struct *work); void fnic_handle_link(struct work_struct *work); -void fnic_handle_event(struct work_struct *work); int fnic_rq_cmpl_handler(struct fnic *fnic, int); int fnic_alloc_rq_frame(struct vnic_rq *rq); void fnic_free_rq_buf(struct vnic_rq *rq, struct vnic_rq_buf *buf); @@ -347,12 +321,6 @@ void fnic_handle_link_event(struct fnic *fnic); int fnic_is_abts_pending(struct fnic *, struct scsi_cmnd *); -void fnic_handle_fip_frame(struct work_struct *work); -void fnic_handle_fip_event(struct fnic *fnic); -void fnic_fcoe_reset_vlans(struct fnic *fnic); -void fnic_fcoe_evlist_free(struct fnic *fnic); -extern void fnic_handle_fip_timer(struct fnic *fnic); - static inline int fnic_chk_state_flags_locked(struct fnic *fnic, unsigned long st_flags) { diff --git a/trunk/drivers/scsi/fnic/fnic_fcs.c b/trunk/drivers/scsi/fnic/fnic_fcs.c index 006fa92a02df..483eb9dbe663 100644 --- a/trunk/drivers/scsi/fnic/fnic_fcs.c +++ b/trunk/drivers/scsi/fnic/fnic_fcs.c @@ -31,20 +31,12 @@ #include #include "fnic_io.h" #include "fnic.h" -#include "fnic_fip.h" #include "cq_enet_desc.h" #include "cq_exch_desc.h" -static u8 fcoe_all_fcfs[ETH_ALEN]; -struct workqueue_struct *fnic_fip_queue; struct workqueue_struct *fnic_event_queue; static void fnic_set_eth_mode(struct fnic *); -static void fnic_fcoe_send_vlan_req(struct fnic *fnic); -static void fnic_fcoe_start_fcf_disc(struct fnic *fnic); -static void fnic_fcoe_process_vlan_resp(struct fnic *fnic, struct sk_buff *); -static int fnic_fcoe_vlan_check(struct fnic *fnic, u16 flag); -static int fnic_fcoe_handle_fip_frame(struct fnic *fnic, struct sk_buff *skb); void fnic_handle_link(struct work_struct *work) { @@ -77,11 +69,6 @@ void fnic_handle_link(struct work_struct *work) FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link down\n"); fcoe_ctlr_link_down(&fnic->ctlr); - if (fnic->config.flags & VFCF_FIP_CAPABLE) { - /* start FCoE VLAN discovery */ - fnic_fcoe_send_vlan_req(fnic); - return; - } FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n"); fcoe_ctlr_link_up(&fnic->ctlr); @@ -92,11 +79,6 @@ void fnic_handle_link(struct work_struct *work) } else if (fnic->link_status) { /* DOWN -> UP */ spin_unlock_irqrestore(&fnic->fnic_lock, flags); - if (fnic->config.flags & VFCF_FIP_CAPABLE) { - /* start FCoE VLAN discovery */ - fnic_fcoe_send_vlan_req(fnic); - return; - } FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n"); fcoe_ctlr_link_up(&fnic->ctlr); } else { @@ -146,441 +128,6 @@ void fnic_handle_frame(struct work_struct *work) } } -void fnic_fcoe_evlist_free(struct fnic *fnic) -{ - struct fnic_event *fevt = NULL; - struct fnic_event *next = NULL; - unsigned long flags; - - spin_lock_irqsave(&fnic->fnic_lock, flags); - if (list_empty(&fnic->evlist)) { - spin_unlock_irqrestore(&fnic->fnic_lock, flags); - return; - } - - list_for_each_entry_safe(fevt, next, &fnic->evlist, list) { - list_del(&fevt->list); - kfree(fevt); - } - spin_unlock_irqrestore(&fnic->fnic_lock, flags); -} - -void fnic_handle_event(struct work_struct *work) -{ - struct fnic *fnic = container_of(work, struct fnic, event_work); - struct fnic_event *fevt = NULL; - struct fnic_event *next = NULL; - unsigned long flags; - - spin_lock_irqsave(&fnic->fnic_lock, flags); - if (list_empty(&fnic->evlist)) { - spin_unlock_irqrestore(&fnic->fnic_lock, flags); - return; - } - - list_for_each_entry_safe(fevt, next, &fnic->evlist, list) { - if (fnic->stop_rx_link_events) { - list_del(&fevt->list); - kfree(fevt); - spin_unlock_irqrestore(&fnic->fnic_lock, flags); - return; - } - /* - * If we're in a transitional state, just re-queue and return. - * The queue will be serviced when we get to a stable state. - */ - if (fnic->state != FNIC_IN_FC_MODE && - fnic->state != FNIC_IN_ETH_MODE) { - spin_unlock_irqrestore(&fnic->fnic_lock, flags); - return; - } - - list_del(&fevt->list); - switch (fevt->event) { - case FNIC_EVT_START_VLAN_DISC: - spin_unlock_irqrestore(&fnic->fnic_lock, flags); - fnic_fcoe_send_vlan_req(fnic); - spin_lock_irqsave(&fnic->fnic_lock, flags); - break; - case FNIC_EVT_START_FCF_DISC: - FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, - "Start FCF Discovery\n"); - fnic_fcoe_start_fcf_disc(fnic); - break; - default: - FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, - "Unknown event 0x%x\n", fevt->event); - break; - } - kfree(fevt); - } - spin_unlock_irqrestore(&fnic->fnic_lock, flags); -} - -/** - * Check if the Received FIP FLOGI frame is rejected - * @fip: The FCoE controller that received the frame - * @skb: The received FIP frame - * - * Returns non-zero if the frame is rejected with unsupported cmd with - * insufficient resource els explanation. - */ -static inline int is_fnic_fip_flogi_reject(struct fcoe_ctlr *fip, - struct sk_buff *skb) -{ - struct fc_lport *lport = fip->lp; - struct fip_header *fiph; - struct fc_frame_header *fh = NULL; - struct fip_desc *desc; - struct fip_encaps *els; - enum fip_desc_type els_dtype = 0; - u16 op; - u8 els_op; - u8 sub; - - size_t els_len = 0; - size_t rlen; - size_t dlen = 0; - - if (skb_linearize(skb)) - return 0; - - if (skb->len < sizeof(*fiph)) - return 0; - - fiph = (struct fip_header *)skb->data; - op = ntohs(fiph->fip_op); - sub = fiph->fip_subcode; - - if (op != FIP_OP_LS) - return 0; - - if (sub != FIP_SC_REP) - return 0; - - rlen = ntohs(fiph->fip_dl_len) * 4; - if (rlen + sizeof(*fiph) > skb->len) - return 0; - - desc = (struct fip_desc *)(fiph + 1); - dlen = desc->fip_dlen * FIP_BPW; - - if (desc->fip_dtype == FIP_DT_FLOGI) { - - shost_printk(KERN_DEBUG, lport->host, - " FIP TYPE FLOGI: fab name:%llx " - "vfid:%d map:%x\n", - fip->sel_fcf->fabric_name, fip->sel_fcf->vfid, - fip->sel_fcf->fc_map); - if (dlen < sizeof(*els) + sizeof(*fh) + 1) - return 0; - - els_len = dlen - sizeof(*els); - els = (struct fip_encaps *)desc; - fh = (struct fc_frame_header *)(els + 1); - els_dtype = desc->fip_dtype; - - if (!fh) - return 0; - - /* - * ELS command code, reason and explanation should be = Reject, - * unsupported command and insufficient resource - */ - els_op = *(u8 *)(fh + 1); - if (els_op == ELS_LS_RJT) { - shost_printk(KERN_INFO, lport->host, - "Flogi Request Rejected by Switch\n"); - return 1; - } - shost_printk(KERN_INFO, lport->host, - "Flogi Request Accepted by Switch\n"); - } - return 0; -} - -static void fnic_fcoe_send_vlan_req(struct fnic *fnic) -{ - struct fcoe_ctlr *fip = &fnic->ctlr; - struct sk_buff *skb; - char *eth_fr; - int fr_len; - struct fip_vlan *vlan; - u64 vlan_tov; - - fnic_fcoe_reset_vlans(fnic); - fnic->set_vlan(fnic, 0); - FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, - "Sending VLAN request...\n"); - skb = dev_alloc_skb(sizeof(struct fip_vlan)); - if (!skb) - return; - - fr_len = sizeof(*vlan); - eth_fr = (char *)skb->data; - vlan = (struct fip_vlan *)eth_fr; - - memset(vlan, 0, sizeof(*vlan)); - memcpy(vlan->eth.h_source, fip->ctl_src_addr, ETH_ALEN); - memcpy(vlan->eth.h_dest, fcoe_all_fcfs, ETH_ALEN); - vlan->eth.h_proto = htons(ETH_P_FIP); - - vlan->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER); - vlan->fip.fip_op = htons(FIP_OP_VLAN); - vlan->fip.fip_subcode = FIP_SC_VL_REQ; - vlan->fip.fip_dl_len = htons(sizeof(vlan->desc) / FIP_BPW); - - vlan->desc.mac.fd_desc.fip_dtype = FIP_DT_MAC; - vlan->desc.mac.fd_desc.fip_dlen = sizeof(vlan->desc.mac) / FIP_BPW; - memcpy(&vlan->desc.mac.fd_mac, fip->ctl_src_addr, ETH_ALEN); - - vlan->desc.wwnn.fd_desc.fip_dtype = FIP_DT_NAME; - vlan->desc.wwnn.fd_desc.fip_dlen = sizeof(vlan->desc.wwnn) / FIP_BPW; - put_unaligned_be64(fip->lp->wwnn, &vlan->desc.wwnn.fd_wwn); - - skb_put(skb, sizeof(*vlan)); - skb->protocol = htons(ETH_P_FIP); - skb_reset_mac_header(skb); - skb_reset_network_header(skb); - fip->send(fip, skb); - - /* set a timer so that we can retry if there no response */ - vlan_tov = jiffies + msecs_to_jiffies(FCOE_CTLR_FIPVLAN_TOV); - mod_timer(&fnic->fip_timer, round_jiffies(vlan_tov)); -} - -static void fnic_fcoe_process_vlan_resp(struct fnic *fnic, struct sk_buff *skb) -{ - struct fcoe_ctlr *fip = &fnic->ctlr; - struct fip_header *fiph; - struct fip_desc *desc; - u16 vid; - size_t rlen; - size_t dlen; - struct fcoe_vlan *vlan; - u64 sol_time; - unsigned long flags; - - FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, - "Received VLAN response...\n"); - - fiph = (struct fip_header *) skb->data; - - FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, - "Received VLAN response... OP 0x%x SUB_OP 0x%x\n", - ntohs(fiph->fip_op), fiph->fip_subcode); - - rlen = ntohs(fiph->fip_dl_len) * 4; - fnic_fcoe_reset_vlans(fnic); - spin_lock_irqsave(&fnic->vlans_lock, flags); - desc = (struct fip_desc *)(fiph + 1); - while (rlen > 0) { - dlen = desc->fip_dlen * FIP_BPW; - switch (desc->fip_dtype) { - case FIP_DT_VLAN: - vid = ntohs(((struct fip_vlan_desc *)desc)->fd_vlan); - shost_printk(KERN_INFO, fnic->lport->host, - "process_vlan_resp: FIP VLAN %d\n", vid); - vlan = kmalloc(sizeof(*vlan), - GFP_ATOMIC); - if (!vlan) { - /* retry from timer */ - spin_unlock_irqrestore(&fnic->vlans_lock, - flags); - goto out; - } - memset(vlan, 0, sizeof(struct fcoe_vlan)); - vlan->vid = vid & 0x0fff; - vlan->state = FIP_VLAN_AVAIL; - list_add_tail(&vlan->list, &fnic->vlans); - break; - } - desc = (struct fip_desc *)((char *)desc + dlen); - rlen -= dlen; - } - - /* any VLAN descriptors present ? */ - if (list_empty(&fnic->vlans)) { - /* retry from timer */ - FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, - "No VLAN descriptors in FIP VLAN response\n"); - spin_unlock_irqrestore(&fnic->vlans_lock, flags); - goto out; - } - - vlan = list_first_entry(&fnic->vlans, struct fcoe_vlan, list); - fnic->set_vlan(fnic, vlan->vid); - vlan->state = FIP_VLAN_SENT; /* sent now */ - vlan->sol_count++; - spin_unlock_irqrestore(&fnic->vlans_lock, flags); - - /* start the solicitation */ - fcoe_ctlr_link_up(fip); - - sol_time = jiffies + msecs_to_jiffies(FCOE_CTLR_START_DELAY); - mod_timer(&fnic->fip_timer, round_jiffies(sol_time)); -out: - return; -} - -static void fnic_fcoe_start_fcf_disc(struct fnic *fnic) -{ - unsigned long flags; - struct fcoe_vlan *vlan; - u64 sol_time; - - spin_lock_irqsave(&fnic->vlans_lock, flags); - vlan = list_first_entry(&fnic->vlans, struct fcoe_vlan, list); - fnic->set_vlan(fnic, vlan->vid); - vlan->state = FIP_VLAN_SENT; /* sent now */ - vlan->sol_count = 1; - spin_unlock_irqrestore(&fnic->vlans_lock, flags); - - /* start the solicitation */ - fcoe_ctlr_link_up(&fnic->ctlr); - - sol_time = jiffies + msecs_to_jiffies(FCOE_CTLR_START_DELAY); - mod_timer(&fnic->fip_timer, round_jiffies(sol_time)); -} - -static int fnic_fcoe_vlan_check(struct fnic *fnic, u16 flag) -{ - unsigned long flags; - struct fcoe_vlan *fvlan; - - spin_lock_irqsave(&fnic->vlans_lock, flags); - if (list_empty(&fnic->vlans)) { - spin_unlock_irqrestore(&fnic->vlans_lock, flags); - return -EINVAL; - } - - fvlan = list_first_entry(&fnic->vlans, struct fcoe_vlan, list); - if (fvlan->state == FIP_VLAN_USED) { - spin_unlock_irqrestore(&fnic->vlans_lock, flags); - return 0; - } - - if (fvlan->state == FIP_VLAN_SENT) { - fvlan->state = FIP_VLAN_USED; - spin_unlock_irqrestore(&fnic->vlans_lock, flags); - return 0; - } - spin_unlock_irqrestore(&fnic->vlans_lock, flags); - return -EINVAL; -} - -static void fnic_event_enq(struct fnic *fnic, enum fnic_evt ev) -{ - struct fnic_event *fevt; - unsigned long flags; - - fevt = kmalloc(sizeof(*fevt), GFP_ATOMIC); - if (!fevt) - return; - - fevt->fnic = fnic; - fevt->event = ev; - - spin_lock_irqsave(&fnic->fnic_lock, flags); - list_add_tail(&fevt->list, &fnic->evlist); - spin_unlock_irqrestore(&fnic->fnic_lock, flags); - - schedule_work(&fnic->event_work); -} - -static int fnic_fcoe_handle_fip_frame(struct fnic *fnic, struct sk_buff *skb) -{ - struct fip_header *fiph; - int ret = 1; - u16 op; - u8 sub; - - if (!skb || !(skb->data)) - return -1; - - if (skb_linearize(skb)) - goto drop; - - fiph = (struct fip_header *)skb->data; - op = ntohs(fiph->fip_op); - sub = fiph->fip_subcode; - - if (FIP_VER_DECAPS(fiph->fip_ver) != FIP_VER) - goto drop; - - if (ntohs(fiph->fip_dl_len) * FIP_BPW + sizeof(*fiph) > skb->len) - goto drop; - - if (op == FIP_OP_DISC && sub == FIP_SC_ADV) { - if (fnic_fcoe_vlan_check(fnic, ntohs(fiph->fip_flags))) - goto drop; - /* pass it on to fcoe */ - ret = 1; - } else if (op == FIP_OP_VLAN && sub == FIP_SC_VL_REP) { - /* set the vlan as used */ - fnic_fcoe_process_vlan_resp(fnic, skb); - ret = 0; - } else if (op == FIP_OP_CTRL && sub == FIP_SC_CLR_VLINK) { - /* received CVL request, restart vlan disc */ - fnic_event_enq(fnic, FNIC_EVT_START_VLAN_DISC); - /* pass it on to fcoe */ - ret = 1; - } -drop: - return ret; -} - -void fnic_handle_fip_frame(struct work_struct *work) -{ - struct fnic *fnic = container_of(work, struct fnic, fip_frame_work); - unsigned long flags; - struct sk_buff *skb; - struct ethhdr *eh; - - while ((skb = skb_dequeue(&fnic->fip_frame_queue))) { - spin_lock_irqsave(&fnic->fnic_lock, flags); - if (fnic->stop_rx_link_events) { - spin_unlock_irqrestore(&fnic->fnic_lock, flags); - dev_kfree_skb(skb); - return; - } - /* - * If we're in a transitional state, just re-queue and return. - * The queue will be serviced when we get to a stable state. - */ - if (fnic->state != FNIC_IN_FC_MODE && - fnic->state != FNIC_IN_ETH_MODE) { - skb_queue_head(&fnic->fip_frame_queue, skb); - spin_unlock_irqrestore(&fnic->fnic_lock, flags); - return; - } - spin_unlock_irqrestore(&fnic->fnic_lock, flags); - eh = (struct ethhdr *)skb->data; - if (eh->h_proto == htons(ETH_P_FIP)) { - skb_pull(skb, sizeof(*eh)); - if (fnic_fcoe_handle_fip_frame(fnic, skb) <= 0) { - dev_kfree_skb(skb); - continue; - } - /* - * If there's FLOGI rejects - clear all - * fcf's & restart from scratch - */ - if (is_fnic_fip_flogi_reject(&fnic->ctlr, skb)) { - shost_printk(KERN_INFO, fnic->lport->host, - "Trigger a Link down - VLAN Disc\n"); - fcoe_ctlr_link_down(&fnic->ctlr); - /* start FCoE VLAN discovery */ - fnic_fcoe_send_vlan_req(fnic); - dev_kfree_skb(skb); - continue; - } - fcoe_ctlr_recv(&fnic->ctlr, skb); - continue; - } - } -} - /** * fnic_import_rq_eth_pkt() - handle received FCoE or FIP frame. * @fnic: fnic instance. @@ -603,14 +150,8 @@ static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb) skb_reset_mac_header(skb); } if (eh->h_proto == htons(ETH_P_FIP)) { - if (!(fnic->config.flags & VFCF_FIP_CAPABLE)) { - printk(KERN_ERR "Dropped FIP frame, as firmware " - "uses non-FIP mode, Enable FIP " - "using UCSM\n"); - goto drop; - } - skb_queue_tail(&fnic->fip_frame_queue, skb); - queue_work(fnic_fip_queue, &fnic->fip_frame_work); + skb_pull(skb, sizeof(*eh)); + fcoe_ctlr_recv(&fnic->ctlr, skb); return 1; /* let caller know packet was used */ } if (eh->h_proto != htons(ETH_P_FCOE)) @@ -1179,104 +720,3 @@ void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf) dev_kfree_skb(fp_skb(fp)); buf->os_buf = NULL; } - -void fnic_fcoe_reset_vlans(struct fnic *fnic) -{ - unsigned long flags; - struct fcoe_vlan *vlan; - struct fcoe_vlan *next; - - /* - * indicate a link down to fcoe so that all fcf's are free'd - * might not be required since we did this before sending vlan - * discovery request - */ - spin_lock_irqsave(&fnic->vlans_lock, flags); - if (!list_empty(&fnic->vlans)) { - list_for_each_entry_safe(vlan, next, &fnic->vlans, list) { - list_del(&vlan->list); - kfree(vlan); - } - } - spin_unlock_irqrestore(&fnic->vlans_lock, flags); -} - -void fnic_handle_fip_timer(struct fnic *fnic) -{ - unsigned long flags; - struct fcoe_vlan *vlan; - u64 sol_time; - - spin_lock_irqsave(&fnic->fnic_lock, flags); - if (fnic->stop_rx_link_events) { - spin_unlock_irqrestore(&fnic->fnic_lock, flags); - return; - } - spin_unlock_irqrestore(&fnic->fnic_lock, flags); - - if (fnic->ctlr.mode == FIP_ST_NON_FIP) - return; - - spin_lock_irqsave(&fnic->vlans_lock, flags); - if (list_empty(&fnic->vlans)) { - /* no vlans available, try again */ - FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, - "Start VLAN Discovery\n"); - spin_unlock_irqrestore(&fnic->vlans_lock, flags); - fnic_event_enq(fnic, FNIC_EVT_START_VLAN_DISC); - return; - } - - vlan = list_first_entry(&fnic->vlans, struct fcoe_vlan, list); - shost_printk(KERN_DEBUG, fnic->lport->host, - "fip_timer: vlan %d state %d sol_count %d\n", - vlan->vid, vlan->state, vlan->sol_count); - switch (vlan->state) { - case FIP_VLAN_USED: - FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, - "FIP VLAN is selected for FC transaction\n"); - spin_unlock_irqrestore(&fnic->vlans_lock, flags); - break; - case FIP_VLAN_FAILED: - /* if all vlans are in failed state, restart vlan disc */ - FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, - "Start VLAN Discovery\n"); - spin_unlock_irqrestore(&fnic->vlans_lock, flags); - fnic_event_enq(fnic, FNIC_EVT_START_VLAN_DISC); - break; - case FIP_VLAN_SENT: - if (vlan->sol_count >= FCOE_CTLR_MAX_SOL) { - /* - * no response on this vlan, remove from the list. - * Try the next vlan - */ - shost_printk(KERN_INFO, fnic->lport->host, - "Dequeue this VLAN ID %d from list\n", - vlan->vid); - list_del(&vlan->list); - kfree(vlan); - vlan = NULL; - if (list_empty(&fnic->vlans)) { - /* we exhausted all vlans, restart vlan disc */ - spin_unlock_irqrestore(&fnic->vlans_lock, - flags); - shost_printk(KERN_INFO, fnic->lport->host, - "fip_timer: vlan list empty, " - "trigger vlan disc\n"); - fnic_event_enq(fnic, FNIC_EVT_START_VLAN_DISC); - return; - } - /* check the next vlan */ - vlan = list_first_entry(&fnic->vlans, struct fcoe_vlan, - list); - fnic->set_vlan(fnic, vlan->vid); - vlan->state = FIP_VLAN_SENT; /* sent now */ - } - spin_unlock_irqrestore(&fnic->vlans_lock, flags); - vlan->sol_count++; - sol_time = jiffies + msecs_to_jiffies - (FCOE_CTLR_START_DELAY); - mod_timer(&fnic->fip_timer, round_jiffies(sol_time)); - break; - } -} diff --git a/trunk/drivers/scsi/fnic/fnic_fip.h b/trunk/drivers/scsi/fnic/fnic_fip.h deleted file mode 100644 index 87e74c2ab971..000000000000 --- a/trunk/drivers/scsi/fnic/fnic_fip.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2008 Cisco Systems, Inc. All rights reserved. - * Copyright 2007 Nuova Systems, Inc. All rights reserved. - * - * This program is free software; you may 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. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _FNIC_FIP_H_ -#define _FNIC_FIP_H_ - - -#define FCOE_CTLR_START_DELAY 2000 /* ms after first adv. to choose FCF */ -#define FCOE_CTLR_FIPVLAN_TOV 2000 /* ms after FIP VLAN disc */ -#define FCOE_CTLR_MAX_SOL 8 - -#define FINC_MAX_FLOGI_REJECTS 8 - -/* - * FIP_DT_VLAN descriptor. - */ -struct fip_vlan_desc { - struct fip_desc fd_desc; - __be16 fd_vlan; -} __attribute__((packed)); - -struct vlan { - __be16 vid; - __be16 type; -}; - -/* - * VLAN entry. - */ -struct fcoe_vlan { - struct list_head list; - u16 vid; /* vlan ID */ - u16 sol_count; /* no. of sols sent */ - u16 state; /* state */ -}; - -enum fip_vlan_state { - FIP_VLAN_AVAIL = 0, /* don't do anything */ - FIP_VLAN_SENT = 1, /* sent */ - FIP_VLAN_USED = 2, /* succeed */ - FIP_VLAN_FAILED = 3, /* failed to response */ -}; - -struct fip_vlan { - struct ethhdr eth; - struct fip_header fip; - struct { - struct fip_mac_desc mac; - struct fip_wwn_desc wwnn; - } desc; -}; - -#endif /* __FINC_FIP_H_ */ diff --git a/trunk/drivers/scsi/fnic/fnic_main.c b/trunk/drivers/scsi/fnic/fnic_main.c index 5f09d1814d26..d601ac543c52 100644 --- a/trunk/drivers/scsi/fnic/fnic_main.c +++ b/trunk/drivers/scsi/fnic/fnic_main.c @@ -39,7 +39,6 @@ #include "vnic_intr.h" #include "vnic_stats.h" #include "fnic_io.h" -#include "fnic_fip.h" #include "fnic.h" #define PCI_DEVICE_ID_CISCO_FNIC 0x0045 @@ -293,13 +292,6 @@ static void fnic_notify_timer(unsigned long data) round_jiffies(jiffies + FNIC_NOTIFY_TIMER_PERIOD)); } -static void fnic_fip_notify_timer(unsigned long data) -{ - struct fnic *fnic = (struct fnic *)data; - - fnic_handle_fip_timer(fnic); -} - static void fnic_notify_timer_start(struct fnic *fnic) { switch (vnic_dev_get_intr_mode(fnic->vdev)) { @@ -411,12 +403,6 @@ static u8 *fnic_get_mac(struct fc_lport *lport) return fnic->data_src_addr; } -static void fnic_set_vlan(struct fnic *fnic, u16 vlan_id) -{ - u16 old_vlan; - old_vlan = vnic_dev_set_default_vlan(fnic->vdev, vlan_id); -} - static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct Scsi_Host *host; @@ -634,29 +620,7 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) vnic_dev_packet_filter(fnic->vdev, 1, 1, 0, 0, 0); vnic_dev_add_addr(fnic->vdev, FIP_ALL_ENODE_MACS); vnic_dev_add_addr(fnic->vdev, fnic->ctlr.ctl_src_addr); - fnic->set_vlan = fnic_set_vlan; fcoe_ctlr_init(&fnic->ctlr, FIP_MODE_AUTO); - setup_timer(&fnic->fip_timer, fnic_fip_notify_timer, - (unsigned long)fnic); - spin_lock_init(&fnic->vlans_lock); - INIT_WORK(&fnic->fip_frame_work, fnic_handle_fip_frame); - INIT_WORK(&fnic->event_work, fnic_handle_event); - skb_queue_head_init(&fnic->fip_frame_queue); - spin_lock_irqsave(&fnic_list_lock, flags); - if (!fnic_fip_queue) { - fnic_fip_queue = - create_singlethread_workqueue("fnic_fip_q"); - if (!fnic_fip_queue) { - spin_unlock_irqrestore(&fnic_list_lock, flags); - printk(KERN_ERR PFX "fnic FIP work queue " - "create failed\n"); - err = -ENOMEM; - goto err_out_free_max_pool; - } - } - spin_unlock_irqrestore(&fnic_list_lock, flags); - INIT_LIST_HEAD(&fnic->evlist); - INIT_LIST_HEAD(&fnic->vlans); } else { shost_printk(KERN_INFO, fnic->lport->host, "firmware uses non-FIP mode\n"); @@ -843,13 +807,6 @@ static void fnic_remove(struct pci_dev *pdev) skb_queue_purge(&fnic->frame_queue); skb_queue_purge(&fnic->tx_queue); - if (fnic->config.flags & VFCF_FIP_CAPABLE) { - del_timer_sync(&fnic->fip_timer); - skb_queue_purge(&fnic->fip_frame_queue); - fnic_fcoe_reset_vlans(fnic); - fnic_fcoe_evlist_free(fnic); - } - /* * Log off the fabric. This stops all remote ports, dns port, * logs off the fabric. This flushes all rport, disc, lport work @@ -932,8 +889,8 @@ static int __init fnic_init_module(void) len = sizeof(struct fnic_sgl_list); fnic_sgl_cache[FNIC_SGL_CACHE_MAX] = kmem_cache_create ("fnic_sgl_max", len + FNIC_SG_DESC_ALIGN, FNIC_SG_DESC_ALIGN, - SLAB_HWCACHE_ALIGN, - NULL); + SLAB_HWCACHE_ALIGN, + NULL); if (!fnic_sgl_cache[FNIC_SGL_CACHE_MAX]) { printk(KERN_ERR PFX "failed to create fnic max sgl slab\n"); err = -ENOMEM; @@ -994,10 +951,6 @@ static void __exit fnic_cleanup_module(void) { pci_unregister_driver(&fnic_driver); destroy_workqueue(fnic_event_queue); - if (fnic_fip_queue) { - flush_workqueue(fnic_fip_queue); - destroy_workqueue(fnic_fip_queue); - } kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_MAX]); kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]); kmem_cache_destroy(fnic_io_req_cache); diff --git a/trunk/drivers/scsi/fnic/vnic_dev.c b/trunk/drivers/scsi/fnic/vnic_dev.c index 9795d6f3e197..b576be734e2e 100644 --- a/trunk/drivers/scsi/fnic/vnic_dev.c +++ b/trunk/drivers/scsi/fnic/vnic_dev.c @@ -584,16 +584,6 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg) return vnic_dev_cmd(vdev, CMD_INIT, &a0, &a1, wait); } -u16 vnic_dev_set_default_vlan(struct vnic_dev *vdev, u16 new_default_vlan) -{ - u64 a0 = new_default_vlan, a1 = 0; - int wait = 1000; - int old_vlan = 0; - - old_vlan = vnic_dev_cmd(vdev, CMD_SET_DEFAULT_VLAN, &a0, &a1, wait); - return (u16)old_vlan; -} - int vnic_dev_link_status(struct vnic_dev *vdev) { if (vdev->linkstatus) diff --git a/trunk/drivers/scsi/fnic/vnic_dev.h b/trunk/drivers/scsi/fnic/vnic_dev.h index 40d4195f562b..f9935a8a5a09 100644 --- a/trunk/drivers/scsi/fnic/vnic_dev.h +++ b/trunk/drivers/scsi/fnic/vnic_dev.h @@ -148,8 +148,6 @@ int vnic_dev_disable(struct vnic_dev *vdev); int vnic_dev_open(struct vnic_dev *vdev, int arg); int vnic_dev_open_done(struct vnic_dev *vdev, int *done); int vnic_dev_init(struct vnic_dev *vdev, int arg); -u16 vnic_dev_set_default_vlan(struct vnic_dev *vdev, - u16 new_default_vlan); int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg); int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done); void vnic_dev_set_intr_mode(struct vnic_dev *vdev, diff --git a/trunk/drivers/scsi/fnic/vnic_devcmd.h b/trunk/drivers/scsi/fnic/vnic_devcmd.h index 3e2fcbda6aed..7c9ccbd4134b 100644 --- a/trunk/drivers/scsi/fnic/vnic_devcmd.h +++ b/trunk/drivers/scsi/fnic/vnic_devcmd.h @@ -196,73 +196,6 @@ enum vnic_devcmd_cmd { /* undo initialize of virtual link */ CMD_DEINIT = _CMDCNW(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 34), - - /* check fw capability of a cmd: - * in: (u32)a0=cmd - * out: (u32)a0=errno, 0:valid cmd, a1=supported VNIC_STF_* bits */ - CMD_CAPABILITY = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 36), - - /* persistent binding info - * in: (u64)a0=paddr of arg - * (u32)a1=CMD_PERBI_XXX */ - CMD_PERBI = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_FC, 37), - - /* Interrupt Assert Register functionality - * in: (u16)a0=interrupt number to assert - */ - CMD_IAR = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 38), - - /* initiate hangreset, like softreset after hang detected */ - CMD_HANG_RESET = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 39), - - /* hangreset status: - * out: a0=0 reset complete, a0=1 reset in progress */ - CMD_HANG_RESET_STATUS = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 40), - - /* - * Set hw ingress packet vlan rewrite mode: - * in: (u32)a0=new vlan rewrite mode - * out: (u32)a0=old vlan rewrite mode */ - CMD_IG_VLAN_REWRITE_MODE = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ENET, 41), - - /* - * in: (u16)a0=bdf of target vnic - * (u32)a1=cmd to proxy - * a2-a15=args to cmd in a1 - * out: (u32)a0=status of proxied cmd - * a1-a15=out args of proxied cmd */ - CMD_PROXY_BY_BDF = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 42), - - /* - * As for BY_BDF except a0 is index of hvnlink subordinate vnic - * or SR-IOV virtual vnic - */ - CMD_PROXY_BY_INDEX = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 43), - - /* - * For HPP toggle: - * adapter-info-get - * in: (u64)a0=phsical address of buffer passed in from caller. - * (u16)a1=size of buffer specified in a0. - * out: (u64)a0=phsical address of buffer passed in from caller. - * (u16)a1=actual bytes from VIF-CONFIG-INFO TLV, or - * 0 if no VIF-CONFIG-INFO TLV was ever received. */ - CMD_CONFIG_INFO_GET = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 44), - - /* - * INT13 API: (u64)a0=paddr to vnic_int13_params struct - * (u32)a1=INT13_CMD_xxx - */ - CMD_INT13_ALL = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 45), - - /* - * Set default vlan: - * in: (u16)a0=new default vlan - * (u16)a1=zero for overriding vlan with param a0, - * non-zero for resetting vlan to the default - * out: (u16)a0=old default vlan - */ - CMD_SET_DEFAULT_VLAN = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 46) }; /* flags for CMD_OPEN */ diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvfc.c b/trunk/drivers/scsi/ibmvscsi/ibmvfc.c index 4e31caa21ddf..cc82d0f322b6 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvfc.c @@ -2179,7 +2179,7 @@ static int ibmvfc_cancel_all(struct scsi_device *sdev, int type) return 0; } - if (vhost->logged_in) { + if (vhost->state == IBMVFC_ACTIVE) { evt = ibmvfc_get_event(vhost); ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT); @@ -2190,12 +2190,7 @@ static int ibmvfc_cancel_all(struct scsi_device *sdev, int type) tmf->common.length = sizeof(*tmf); tmf->scsi_id = rport->port_id; int_to_scsilun(sdev->lun, &tmf->lun); - if (!(vhost->login_buf->resp.capabilities & IBMVFC_CAN_SUPPRESS_ABTS)) - type &= ~IBMVFC_TMF_SUPPRESS_ABTS; - if (vhost->state == IBMVFC_ACTIVE) - tmf->flags = (type | IBMVFC_TMF_LUA_VALID); - else - tmf->flags = ((type & IBMVFC_TMF_SUPPRESS_ABTS) | IBMVFC_TMF_LUA_VALID); + tmf->flags = (type | IBMVFC_TMF_LUA_VALID); tmf->cancel_key = (unsigned long)sdev->hostdata; tmf->my_cancel_key = (unsigned long)starget->hostdata; @@ -2332,7 +2327,7 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev) timeout = wait_for_completion_timeout(&evt->comp, timeout); if (!timeout) { - rc = ibmvfc_cancel_all(sdev, 0); + rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET); if (!rc) { rc = ibmvfc_wait_for_ops(vhost, sdev->hostdata, ibmvfc_match_key); if (rc == SUCCESS) @@ -2388,30 +2383,24 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev) * @cmd: scsi command to abort * * Returns: - * SUCCESS / FAST_IO_FAIL / FAILED + * SUCCESS / FAILED **/ static int ibmvfc_eh_abort_handler(struct scsi_cmnd *cmd) { struct scsi_device *sdev = cmd->device; struct ibmvfc_host *vhost = shost_priv(sdev->host); - int cancel_rc, block_rc; + int cancel_rc, abort_rc; int rc = FAILED; ENTER; - block_rc = fc_block_scsi_eh(cmd); + fc_block_scsi_eh(cmd); ibmvfc_wait_while_resetting(vhost); - if (block_rc != FAST_IO_FAIL) { - cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET); - ibmvfc_abort_task_set(sdev); - } else - cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_SUPPRESS_ABTS); + cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET); + abort_rc = ibmvfc_abort_task_set(sdev); - if (!cancel_rc) + if (!cancel_rc && !abort_rc) rc = ibmvfc_wait_for_ops(vhost, sdev, ibmvfc_match_lun); - if (block_rc == FAST_IO_FAIL && rc != FAILED) - rc = FAST_IO_FAIL; - LEAVE; return rc; } @@ -2421,46 +2410,28 @@ static int ibmvfc_eh_abort_handler(struct scsi_cmnd *cmd) * @cmd: scsi command struct * * Returns: - * SUCCESS / FAST_IO_FAIL / FAILED + * SUCCESS / FAILED **/ static int ibmvfc_eh_device_reset_handler(struct scsi_cmnd *cmd) { struct scsi_device *sdev = cmd->device; struct ibmvfc_host *vhost = shost_priv(sdev->host); - int cancel_rc, block_rc, reset_rc = 0; + int cancel_rc, reset_rc; int rc = FAILED; ENTER; - block_rc = fc_block_scsi_eh(cmd); + fc_block_scsi_eh(cmd); ibmvfc_wait_while_resetting(vhost); - if (block_rc != FAST_IO_FAIL) { - cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_LUN_RESET); - reset_rc = ibmvfc_reset_device(sdev, IBMVFC_LUN_RESET, "LUN"); - } else - cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_SUPPRESS_ABTS); + cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_LUN_RESET); + reset_rc = ibmvfc_reset_device(sdev, IBMVFC_LUN_RESET, "LUN"); if (!cancel_rc && !reset_rc) rc = ibmvfc_wait_for_ops(vhost, sdev, ibmvfc_match_lun); - if (block_rc == FAST_IO_FAIL && rc != FAILED) - rc = FAST_IO_FAIL; - LEAVE; return rc; } -/** - * ibmvfc_dev_cancel_all_noreset - Device iterated cancel all function - * @sdev: scsi device struct - * @data: return code - * - **/ -static void ibmvfc_dev_cancel_all_noreset(struct scsi_device *sdev, void *data) -{ - unsigned long *rc = data; - *rc |= ibmvfc_cancel_all(sdev, IBMVFC_TMF_SUPPRESS_ABTS); -} - /** * ibmvfc_dev_cancel_all_reset - Device iterated cancel all function * @sdev: scsi device struct @@ -2478,33 +2449,26 @@ static void ibmvfc_dev_cancel_all_reset(struct scsi_device *sdev, void *data) * @cmd: scsi command struct * * Returns: - * SUCCESS / FAST_IO_FAIL / FAILED + * SUCCESS / FAILED **/ static int ibmvfc_eh_target_reset_handler(struct scsi_cmnd *cmd) { struct scsi_device *sdev = cmd->device; struct ibmvfc_host *vhost = shost_priv(sdev->host); struct scsi_target *starget = scsi_target(sdev); - int block_rc; - int reset_rc = 0; + int reset_rc; int rc = FAILED; unsigned long cancel_rc = 0; ENTER; - block_rc = fc_block_scsi_eh(cmd); + fc_block_scsi_eh(cmd); ibmvfc_wait_while_resetting(vhost); - if (block_rc != FAST_IO_FAIL) { - starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all_reset); - reset_rc = ibmvfc_reset_device(sdev, IBMVFC_TARGET_RESET, "target"); - } else - starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all_noreset); + starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all_reset); + reset_rc = ibmvfc_reset_device(sdev, IBMVFC_TARGET_RESET, "target"); if (!cancel_rc && !reset_rc) rc = ibmvfc_wait_for_ops(vhost, starget, ibmvfc_match_target); - if (block_rc == FAST_IO_FAIL && rc != FAILED) - rc = FAST_IO_FAIL; - LEAVE; return rc; } @@ -2516,16 +2480,12 @@ static int ibmvfc_eh_target_reset_handler(struct scsi_cmnd *cmd) **/ static int ibmvfc_eh_host_reset_handler(struct scsi_cmnd *cmd) { - int rc, block_rc; + int rc; struct ibmvfc_host *vhost = shost_priv(cmd->device->host); - block_rc = fc_block_scsi_eh(cmd); + fc_block_scsi_eh(cmd); dev_err(vhost->dev, "Resetting connection due to error recovery\n"); rc = ibmvfc_issue_fc_host_lip(vhost->host); - - if (block_rc == FAST_IO_FAIL) - return FAST_IO_FAIL; - return rc ? FAILED : SUCCESS; } @@ -2549,7 +2509,8 @@ static void ibmvfc_terminate_rport_io(struct fc_rport *rport) dev_rport = starget_to_rport(scsi_target(sdev)); if (dev_rport != rport) continue; - ibmvfc_cancel_all(sdev, IBMVFC_TMF_SUPPRESS_ABTS); + ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET); + ibmvfc_abort_task_set(sdev); } rc = ibmvfc_wait_for_ops(vhost, rport, ibmvfc_match_rport); diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvfc.h b/trunk/drivers/scsi/ibmvscsi/ibmvfc.h index 017a5290e8c1..3be8af624e6f 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/trunk/drivers/scsi/ibmvscsi/ibmvfc.h @@ -29,8 +29,8 @@ #include "viosrp.h" #define IBMVFC_NAME "ibmvfc" -#define IBMVFC_DRIVER_VERSION "1.0.11" -#define IBMVFC_DRIVER_DATE "(April 12, 2013)" +#define IBMVFC_DRIVER_VERSION "1.0.10" +#define IBMVFC_DRIVER_DATE "(August 24, 2012)" #define IBMVFC_DEFAULT_TIMEOUT 60 #define IBMVFC_ADISC_CANCEL_TIMEOUT 45 @@ -208,10 +208,10 @@ struct ibmvfc_npiv_login_resp { u16 error; u32 flags; #define IBMVFC_NATIVE_FC 0x01 +#define IBMVFC_CAN_FLUSH_ON_HALT 0x08 u32 reserved; u64 capabilities; #define IBMVFC_CAN_FLUSH_ON_HALT 0x08 -#define IBMVFC_CAN_SUPPRESS_ABTS 0x10 u32 max_cmds; u32 scsi_id_sz; u64 max_dma_len; @@ -351,7 +351,6 @@ struct ibmvfc_tmf { #define IBMVFC_TMF_LUN_RESET 0x10 #define IBMVFC_TMF_TGT_RESET 0x20 #define IBMVFC_TMF_LUA_VALID 0x40 -#define IBMVFC_TMF_SUPPRESS_ABTS 0x80 u32 cancel_key; u32 my_cancel_key; u32 pad; diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index 82a3c1ec8706..2197b57fb225 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -4777,7 +4777,7 @@ static int ipr_eh_host_reset(struct scsi_cmnd *cmd) ioa_cfg = (struct ipr_ioa_cfg *) cmd->device->host->hostdata; spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - if (!ioa_cfg->in_reset_reload && !ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead) { + if (!ioa_cfg->in_reset_reload) { ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_ABBREV); dev_err(&ioa_cfg->pdev->dev, "Adapter being reset as a result of error recovery.\n"); @@ -6421,7 +6421,7 @@ static void ipr_build_ata_ioadl64(struct ipr_cmnd *ipr_cmd, { u32 ioadl_flags = 0; struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; - struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ata_ioadl.ioadl64; + struct ipr_ioadl64_desc *ioadl64 = ipr_cmd->i.ioadl64; struct ipr_ioadl64_desc *last_ioadl64 = NULL; int len = qc->nbytes; struct scatterlist *sg; @@ -6441,7 +6441,7 @@ static void ipr_build_ata_ioadl64(struct ipr_cmnd *ipr_cmd, ioarcb->ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl64_desc) * ipr_cmd->dma_use_sg); ioarcb->u.sis64_addr_data.data_ioadl_addr = - cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ata_ioadl.ioadl64)); + cpu_to_be64(dma_addr + offsetof(struct ipr_cmnd, i.ata_ioadl)); for_each_sg(qc->sg, sg, qc->n_elem, si) { ioadl64->flags = cpu_to_be32(ioadl_flags); @@ -6739,7 +6739,6 @@ static int ipr_invalid_adapter(struct ipr_ioa_cfg *ioa_cfg) static int ipr_ioa_bringdown_done(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; - int i; ENTER; if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].removing_ioa) { @@ -6751,13 +6750,6 @@ static int ipr_ioa_bringdown_done(struct ipr_cmnd *ipr_cmd) ioa_cfg->in_reset_reload = 0; ioa_cfg->reset_retries = 0; - for (i = 0; i < ioa_cfg->hrrq_num; i++) { - spin_lock(&ioa_cfg->hrrq[i]._lock); - ioa_cfg->hrrq[i].ioa_is_dead = 1; - spin_unlock(&ioa_cfg->hrrq[i]._lock); - } - wmb(); - list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); wake_up_all(&ioa_cfg->reset_wait_q); LEAVE; @@ -8659,7 +8651,7 @@ static void ipr_pci_perm_failure(struct pci_dev *pdev) spin_lock_irqsave(ioa_cfg->host->host_lock, flags); if (ioa_cfg->sdt_state == WAIT_FOR_DUMP) ioa_cfg->sdt_state = ABORT_DUMP; - ioa_cfg->reset_retries = IPR_NUM_RESET_RELOAD_RETRIES - 1; + ioa_cfg->reset_retries = IPR_NUM_RESET_RELOAD_RETRIES; ioa_cfg->in_ioa_bringdown = 1; for (i = 0; i < ioa_cfg->hrrq_num; i++) { spin_lock(&ioa_cfg->hrrq[i]._lock); diff --git a/trunk/drivers/scsi/ipr.h b/trunk/drivers/scsi/ipr.h index a1fb840596ef..21a6ff1ed5c6 100644 --- a/trunk/drivers/scsi/ipr.h +++ b/trunk/drivers/scsi/ipr.h @@ -552,7 +552,7 @@ struct ipr_ioarcb_ata_regs { /* 22 bytes */ u8 hob_lbam; u8 hob_lbah; u8 ctl; -}__attribute__ ((packed, aligned(2))); +}__attribute__ ((packed, aligned(4))); struct ipr_ioadl_desc { __be32 flags_and_data_len; diff --git a/trunk/drivers/scsi/isci/remote_device.c b/trunk/drivers/scsi/isci/remote_device.c index 96a26f454673..c3aa6c5457b9 100644 --- a/trunk/drivers/scsi/isci/remote_device.c +++ b/trunk/drivers/scsi/isci/remote_device.c @@ -1085,7 +1085,7 @@ static void sci_remote_device_ready_state_enter(struct sci_base_state_machine *s struct isci_host *ihost = idev->owning_port->owning_controller; struct domain_device *dev = idev->domain_dev; - if (dev->dev_type == SAS_SATA_DEV || (dev->tproto & SAS_PROTOCOL_SATA)) { + if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_SATA)) { sci_change_state(&idev->sm, SCI_STP_DEV_IDLE); } else if (dev_is_expander(dev)) { sci_change_state(&idev->sm, SCI_SMP_DEV_IDLE); @@ -1098,7 +1098,7 @@ static void sci_remote_device_ready_state_exit(struct sci_base_state_machine *sm struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm); struct domain_device *dev = idev->domain_dev; - if (dev->dev_type == SAS_END_DEVICE) { + if (dev->dev_type == SAS_END_DEV) { struct isci_host *ihost = idev->owning_port->owning_controller; isci_remote_device_not_ready(ihost, idev, diff --git a/trunk/drivers/scsi/isci/remote_device.h b/trunk/drivers/scsi/isci/remote_device.h index 47a013fffae7..7674caae1d88 100644 --- a/trunk/drivers/scsi/isci/remote_device.h +++ b/trunk/drivers/scsi/isci/remote_device.h @@ -297,7 +297,7 @@ static inline struct isci_remote_device *rnc_to_dev(struct sci_remote_node_conte static inline bool dev_is_expander(struct domain_device *dev) { - return dev->dev_type == SAS_EDGE_EXPANDER_DEVICE || dev->dev_type == SAS_FANOUT_EXPANDER_DEVICE; + return dev->dev_type == EDGE_DEV || dev->dev_type == FANOUT_DEV; } static inline void sci_remote_device_decrement_request_count(struct isci_remote_device *idev) diff --git a/trunk/drivers/scsi/isci/request.c b/trunk/drivers/scsi/isci/request.c index e3e3bcbd5a9f..9594ab62702b 100644 --- a/trunk/drivers/scsi/isci/request.c +++ b/trunk/drivers/scsi/isci/request.c @@ -2978,7 +2978,7 @@ static void sci_request_started_state_enter(struct sci_base_state_machine *sm) /* all unaccelerated request types (non ssp or ncq) handled with * substates */ - if (!task && dev->dev_type == SAS_END_DEVICE) { + if (!task && dev->dev_type == SAS_END_DEV) { state = SCI_REQ_TASK_WAIT_TC_COMP; } else if (task && task->task_proto == SAS_PROTOCOL_SMP) { state = SCI_REQ_SMP_WAIT_RESP; @@ -3101,7 +3101,7 @@ sci_io_request_construct(struct isci_host *ihost, if (idev->rnc.remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) return SCI_FAILURE_INVALID_REMOTE_DEVICE; - if (dev->dev_type == SAS_END_DEVICE) + if (dev->dev_type == SAS_END_DEV) /* pass */; else if (dev_is_sata(dev)) memset(&ireq->stp.cmd, 0, sizeof(ireq->stp.cmd)); @@ -3125,7 +3125,7 @@ enum sci_status sci_task_request_construct(struct isci_host *ihost, /* Build the common part of the request */ sci_general_request_construct(ihost, idev, ireq); - if (dev->dev_type == SAS_END_DEVICE || dev_is_sata(dev)) { + if (dev->dev_type == SAS_END_DEV || dev_is_sata(dev)) { set_bit(IREQ_TMF, &ireq->flags); memset(ireq->tc, 0, sizeof(struct scu_task_context)); diff --git a/trunk/drivers/scsi/isci/task.c b/trunk/drivers/scsi/isci/task.c index 9bb020ac089c..b6f19a1db780 100644 --- a/trunk/drivers/scsi/isci/task.c +++ b/trunk/drivers/scsi/isci/task.c @@ -250,7 +250,7 @@ static struct isci_request *isci_task_request_build(struct isci_host *ihost, } /* XXX convert to get this from task->tproto like other drivers */ - if (dev->dev_type == SAS_END_DEVICE) { + if (dev->dev_type == SAS_END_DEV) { isci_tmf->proto = SAS_PROTOCOL_SSP; status = sci_task_request_construct_ssp(ireq); if (status != SCI_SUCCESS) diff --git a/trunk/drivers/scsi/libsas/sas_ata.c b/trunk/drivers/scsi/libsas/sas_ata.c index 161c98efade9..bdb81cda8401 100644 --- a/trunk/drivers/scsi/libsas/sas_ata.c +++ b/trunk/drivers/scsi/libsas/sas_ata.c @@ -285,14 +285,14 @@ int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy) if (phy->attached_tproto & SAS_PROTOCOL_STP) dev->tproto = phy->attached_tproto; if (phy->attached_sata_dev) - dev->tproto |= SAS_SATA_DEV; + dev->tproto |= SATA_DEV; - if (phy->attached_dev_type == SAS_SATA_PENDING) - dev->dev_type = SAS_SATA_PENDING; + if (phy->attached_dev_type == SATA_PENDING) + dev->dev_type = SATA_PENDING; else { int res; - dev->dev_type = SAS_SATA_DEV; + dev->dev_type = SATA_DEV; res = sas_get_report_phy_sata(dev->parent, phy->phy_id, &dev->sata_dev.rps_resp); if (res) { @@ -314,7 +314,7 @@ static int sas_ata_clear_pending(struct domain_device *dev, struct ex_phy *phy) int res; /* we weren't pending, so successfully end the reset sequence now */ - if (dev->dev_type != SAS_SATA_PENDING) + if (dev->dev_type != SATA_PENDING) return 1; /* hmmm, if this succeeds do we need to repost the domain_device to the @@ -348,9 +348,9 @@ static int smp_ata_check_ready(struct ata_link *link) return 0; switch (ex_phy->attached_dev_type) { - case SAS_SATA_PENDING: + case SATA_PENDING: return 0; - case SAS_END_DEVICE: + case SAS_END_DEV: if (ex_phy->attached_sata_dev) return sas_ata_clear_pending(dev, ex_phy); default: @@ -631,7 +631,7 @@ static void sas_get_ata_command_set(struct domain_device *dev) struct dev_to_host_fis *fis = (struct dev_to_host_fis *) dev->frame_rcvd; - if (dev->dev_type == SAS_SATA_PENDING) + if (dev->dev_type == SATA_PENDING) return; if ((fis->sector_count == 1 && /* ATA */ @@ -797,7 +797,7 @@ int sas_discover_sata(struct domain_device *dev) { int res; - if (dev->dev_type == SAS_SATA_PM) + if (dev->dev_type == SATA_PM) return -ENODEV; sas_get_ata_command_set(dev); diff --git a/trunk/drivers/scsi/libsas/sas_discover.c b/trunk/drivers/scsi/libsas/sas_discover.c index 62b58d38ce2e..a0c3003e0c7d 100644 --- a/trunk/drivers/scsi/libsas/sas_discover.c +++ b/trunk/drivers/scsi/libsas/sas_discover.c @@ -39,11 +39,11 @@ void sas_init_dev(struct domain_device *dev) { switch (dev->dev_type) { - case SAS_END_DEVICE: + case SAS_END_DEV: INIT_LIST_HEAD(&dev->ssp_dev.eh_list_node); break; - case SAS_EDGE_EXPANDER_DEVICE: - case SAS_FANOUT_EXPANDER_DEVICE: + case EDGE_DEV: + case FANOUT_DEV: INIT_LIST_HEAD(&dev->ex_dev.children); mutex_init(&dev->ex_dev.cmd_mutex); break; @@ -93,9 +93,9 @@ static int sas_get_port_device(struct asd_sas_port *port) if (fis->interrupt_reason == 1 && fis->lbal == 1 && fis->byte_count_low==0x69 && fis->byte_count_high == 0x96 && (fis->device & ~0x10) == 0) - dev->dev_type = SAS_SATA_PM; + dev->dev_type = SATA_PM; else - dev->dev_type = SAS_SATA_DEV; + dev->dev_type = SATA_DEV; dev->tproto = SAS_PROTOCOL_SATA; } else { struct sas_identify_frame *id = @@ -109,21 +109,21 @@ static int sas_get_port_device(struct asd_sas_port *port) dev->port = port; switch (dev->dev_type) { - case SAS_SATA_DEV: + case SATA_DEV: rc = sas_ata_init(dev); if (rc) { rphy = NULL; break; } /* fall through */ - case SAS_END_DEVICE: + case SAS_END_DEV: rphy = sas_end_device_alloc(port->port); break; - case SAS_EDGE_EXPANDER_DEVICE: + case EDGE_DEV: rphy = sas_expander_alloc(port->port, SAS_EDGE_EXPANDER_DEVICE); break; - case SAS_FANOUT_EXPANDER_DEVICE: + case FANOUT_DEV: rphy = sas_expander_alloc(port->port, SAS_FANOUT_EXPANDER_DEVICE); break; @@ -156,7 +156,7 @@ static int sas_get_port_device(struct asd_sas_port *port) dev->rphy = rphy; get_device(&dev->rphy->dev); - if (dev_is_sata(dev) || dev->dev_type == SAS_END_DEVICE) + if (dev_is_sata(dev) || dev->dev_type == SAS_END_DEV) list_add_tail(&dev->disco_list_node, &port->disco_list); else { spin_lock_irq(&port->dev_list_lock); @@ -315,7 +315,7 @@ void sas_free_device(struct kref *kref) dev->phy = NULL; /* remove the phys and ports, everything else should be gone */ - if (dev->dev_type == SAS_EDGE_EXPANDER_DEVICE || dev->dev_type == SAS_FANOUT_EXPANDER_DEVICE) + if (dev->dev_type == EDGE_DEV || dev->dev_type == FANOUT_DEV) kfree(dev->ex_dev.ex_phy); if (dev_is_sata(dev) && dev->sata_dev.ap) { @@ -343,7 +343,7 @@ static void sas_unregister_common_dev(struct asd_sas_port *port, struct domain_d spin_unlock_irq(&port->dev_list_lock); spin_lock_irq(&ha->lock); - if (dev->dev_type == SAS_END_DEVICE && + if (dev->dev_type == SAS_END_DEV && !list_empty(&dev->ssp_dev.eh_list_node)) { list_del_init(&dev->ssp_dev.eh_list_node); ha->eh_active--; @@ -457,15 +457,15 @@ static void sas_discover_domain(struct work_struct *work) task_pid_nr(current)); switch (dev->dev_type) { - case SAS_END_DEVICE: + case SAS_END_DEV: error = sas_discover_end_dev(dev); break; - case SAS_EDGE_EXPANDER_DEVICE: - case SAS_FANOUT_EXPANDER_DEVICE: + case EDGE_DEV: + case FANOUT_DEV: error = sas_discover_root_expander(dev); break; - case SAS_SATA_DEV: - case SAS_SATA_PM: + case SATA_DEV: + case SATA_PM: #ifdef CONFIG_SCSI_SAS_ATA error = sas_discover_sata(dev); break; diff --git a/trunk/drivers/scsi/libsas/sas_expander.c b/trunk/drivers/scsi/libsas/sas_expander.c index 446b85110a1f..f42b0e15410f 100644 --- a/trunk/drivers/scsi/libsas/sas_expander.c +++ b/trunk/drivers/scsi/libsas/sas_expander.c @@ -183,21 +183,21 @@ static char sas_route_char(struct domain_device *dev, struct ex_phy *phy) } } -static enum sas_device_type to_dev_type(struct discover_resp *dr) +static enum sas_dev_type to_dev_type(struct discover_resp *dr) { /* This is detecting a failure to transmit initial dev to host * FIS as described in section J.5 of sas-2 r16 */ - if (dr->attached_dev_type == SAS_PHY_UNUSED && dr->attached_sata_dev && + if (dr->attached_dev_type == NO_DEVICE && dr->attached_sata_dev && dr->linkrate >= SAS_LINK_RATE_1_5_GBPS) - return SAS_SATA_PENDING; + return SATA_PENDING; else return dr->attached_dev_type; } static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) { - enum sas_device_type dev_type; + enum sas_dev_type dev_type; enum sas_linkrate linkrate; u8 sas_addr[SAS_ADDR_SIZE]; struct smp_resp *resp = rsp; @@ -238,7 +238,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) /* Handle vacant phy - rest of dr data is not valid so skip it */ if (phy->phy_state == PHY_VACANT) { memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); - phy->attached_dev_type = SAS_PHY_UNUSED; + phy->attached_dev_type = NO_DEVICE; if (!test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) { phy->phy_id = phy_id; goto skip; @@ -259,7 +259,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) /* help some expanders that fail to zero sas_address in the 'no * device' case */ - if (phy->attached_dev_type == SAS_PHY_UNUSED || + if (phy->attached_dev_type == NO_DEVICE || phy->linkrate < SAS_LINK_RATE_1_5_GBPS) memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); else @@ -292,13 +292,13 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) out: switch (phy->attached_dev_type) { - case SAS_SATA_PENDING: + case SATA_PENDING: type = "stp pending"; break; - case SAS_PHY_UNUSED: + case NO_DEVICE: type = "no device"; break; - case SAS_END_DEVICE: + case SAS_END_DEV: if (phy->attached_iproto) { if (phy->attached_tproto) type = "host+target"; @@ -311,8 +311,8 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) type = "ssp"; } break; - case SAS_EDGE_EXPANDER_DEVICE: - case SAS_FANOUT_EXPANDER_DEVICE: + case EDGE_DEV: + case FANOUT_DEV: type = "smp"; break; default: @@ -833,7 +833,7 @@ static struct domain_device *sas_ex_discover_end_dev( } else #endif if (phy->attached_tproto & SAS_PROTOCOL_SSP) { - child->dev_type = SAS_END_DEVICE; + child->dev_type = SAS_END_DEV; rphy = sas_end_device_alloc(phy->port); /* FIXME: error handling */ if (unlikely(!rphy)) @@ -932,11 +932,11 @@ static struct domain_device *sas_ex_discover_expander( switch (phy->attached_dev_type) { - case SAS_EDGE_EXPANDER_DEVICE: + case EDGE_DEV: rphy = sas_expander_alloc(phy->port, SAS_EDGE_EXPANDER_DEVICE); break; - case SAS_FANOUT_EXPANDER_DEVICE: + case FANOUT_DEV: rphy = sas_expander_alloc(phy->port, SAS_FANOUT_EXPANDER_DEVICE); break; @@ -1013,7 +1013,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) if (sas_dev_present_in_domain(dev->port, ex_phy->attached_sas_addr)) sas_ex_disable_port(dev, ex_phy->attached_sas_addr); - if (ex_phy->attached_dev_type == SAS_PHY_UNUSED) { + if (ex_phy->attached_dev_type == NO_DEVICE) { if (ex_phy->routing_attr == DIRECT_ROUTING) { memset(ex_phy->attached_sas_addr, 0, SAS_ADDR_SIZE); sas_configure_routing(dev, ex_phy->attached_sas_addr); @@ -1022,10 +1022,10 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) } else if (ex_phy->linkrate == SAS_LINK_RATE_UNKNOWN) return 0; - if (ex_phy->attached_dev_type != SAS_END_DEVICE && - ex_phy->attached_dev_type != SAS_FANOUT_EXPANDER_DEVICE && - ex_phy->attached_dev_type != SAS_EDGE_EXPANDER_DEVICE && - ex_phy->attached_dev_type != SAS_SATA_PENDING) { + if (ex_phy->attached_dev_type != SAS_END_DEV && + ex_phy->attached_dev_type != FANOUT_DEV && + ex_phy->attached_dev_type != EDGE_DEV && + ex_phy->attached_dev_type != SATA_PENDING) { SAS_DPRINTK("unknown device type(0x%x) attached to ex %016llx " "phy 0x%x\n", ex_phy->attached_dev_type, SAS_ADDR(dev->sas_addr), @@ -1049,11 +1049,11 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) } switch (ex_phy->attached_dev_type) { - case SAS_END_DEVICE: - case SAS_SATA_PENDING: + case SAS_END_DEV: + case SATA_PENDING: child = sas_ex_discover_end_dev(dev, phy_id); break; - case SAS_FANOUT_EXPANDER_DEVICE: + case FANOUT_DEV: if (SAS_ADDR(dev->port->disc.fanout_sas_addr)) { SAS_DPRINTK("second fanout expander %016llx phy 0x%x " "attached to ex %016llx phy 0x%x\n", @@ -1067,7 +1067,7 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id) memcpy(dev->port->disc.fanout_sas_addr, ex_phy->attached_sas_addr, SAS_ADDR_SIZE); /* fallthrough */ - case SAS_EDGE_EXPANDER_DEVICE: + case EDGE_DEV: child = sas_ex_discover_expander(dev, phy_id); break; default: @@ -1111,8 +1111,8 @@ static int sas_find_sub_addr(struct domain_device *dev, u8 *sub_addr) phy->phy_state == PHY_NOT_PRESENT) continue; - if ((phy->attached_dev_type == SAS_EDGE_EXPANDER_DEVICE || - phy->attached_dev_type == SAS_FANOUT_EXPANDER_DEVICE) && + if ((phy->attached_dev_type == EDGE_DEV || + phy->attached_dev_type == FANOUT_DEV) && phy->routing_attr == SUBTRACTIVE_ROUTING) { memcpy(sub_addr, phy->attached_sas_addr,SAS_ADDR_SIZE); @@ -1130,8 +1130,8 @@ static int sas_check_level_subtractive_boundary(struct domain_device *dev) u8 sub_addr[8] = {0, }; list_for_each_entry(child, &ex->children, siblings) { - if (child->dev_type != SAS_EDGE_EXPANDER_DEVICE && - child->dev_type != SAS_FANOUT_EXPANDER_DEVICE) + if (child->dev_type != EDGE_DEV && + child->dev_type != FANOUT_DEV) continue; if (sub_addr[0] == 0) { sas_find_sub_addr(child, sub_addr); @@ -1208,7 +1208,7 @@ static int sas_check_ex_subtractive_boundary(struct domain_device *dev) int i; u8 *sub_sas_addr = NULL; - if (dev->dev_type != SAS_EDGE_EXPANDER_DEVICE) + if (dev->dev_type != EDGE_DEV) return 0; for (i = 0; i < ex->num_phys; i++) { @@ -1218,8 +1218,8 @@ static int sas_check_ex_subtractive_boundary(struct domain_device *dev) phy->phy_state == PHY_NOT_PRESENT) continue; - if ((phy->attached_dev_type == SAS_FANOUT_EXPANDER_DEVICE || - phy->attached_dev_type == SAS_EDGE_EXPANDER_DEVICE) && + if ((phy->attached_dev_type == FANOUT_DEV || + phy->attached_dev_type == EDGE_DEV) && phy->routing_attr == SUBTRACTIVE_ROUTING) { if (!sub_sas_addr) @@ -1245,8 +1245,8 @@ static void sas_print_parent_topology_bug(struct domain_device *child, struct ex_phy *child_phy) { static const char *ex_type[] = { - [SAS_EDGE_EXPANDER_DEVICE] = "edge", - [SAS_FANOUT_EXPANDER_DEVICE] = "fanout", + [EDGE_DEV] = "edge", + [FANOUT_DEV] = "fanout", }; struct domain_device *parent = child->parent; @@ -1321,8 +1321,8 @@ static int sas_check_parent_topology(struct domain_device *child) if (!child->parent) return 0; - if (child->parent->dev_type != SAS_EDGE_EXPANDER_DEVICE && - child->parent->dev_type != SAS_FANOUT_EXPANDER_DEVICE) + if (child->parent->dev_type != EDGE_DEV && + child->parent->dev_type != FANOUT_DEV) return 0; parent_ex = &child->parent->ex_dev; @@ -1341,8 +1341,8 @@ static int sas_check_parent_topology(struct domain_device *child) child_phy = &child_ex->ex_phy[parent_phy->attached_phy_id]; switch (child->parent->dev_type) { - case SAS_EDGE_EXPANDER_DEVICE: - if (child->dev_type == SAS_FANOUT_EXPANDER_DEVICE) { + case EDGE_DEV: + if (child->dev_type == FANOUT_DEV) { if (parent_phy->routing_attr != SUBTRACTIVE_ROUTING || child_phy->routing_attr != TABLE_ROUTING) { sas_print_parent_topology_bug(child, parent_phy, child_phy); @@ -1366,7 +1366,7 @@ static int sas_check_parent_topology(struct domain_device *child) } } break; - case SAS_FANOUT_EXPANDER_DEVICE: + case FANOUT_DEV: if (parent_phy->routing_attr != TABLE_ROUTING || child_phy->routing_attr != SUBTRACTIVE_ROUTING) { sas_print_parent_topology_bug(child, parent_phy, child_phy); @@ -1619,8 +1619,8 @@ static int sas_ex_level_discovery(struct asd_sas_port *port, const int level) struct domain_device *dev; list_for_each_entry(dev, &port->dev_list, dev_list_node) { - if (dev->dev_type == SAS_EDGE_EXPANDER_DEVICE || - dev->dev_type == SAS_FANOUT_EXPANDER_DEVICE) { + if (dev->dev_type == EDGE_DEV || + dev->dev_type == FANOUT_DEV) { struct sas_expander_device *ex = rphy_to_expander_device(dev->rphy); @@ -1720,7 +1720,7 @@ static int sas_get_phy_change_count(struct domain_device *dev, } static int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id, - u8 *sas_addr, enum sas_device_type *type) + u8 *sas_addr, enum sas_dev_type *type) { int res; struct smp_resp *disc_resp; @@ -1849,7 +1849,7 @@ static int sas_find_bcast_dev(struct domain_device *dev, SAS_DPRINTK("Expander phys DID NOT change\n"); } list_for_each_entry(ch, &ex->children, siblings) { - if (ch->dev_type == SAS_EDGE_EXPANDER_DEVICE || ch->dev_type == SAS_FANOUT_EXPANDER_DEVICE) { + if (ch->dev_type == EDGE_DEV || ch->dev_type == FANOUT_DEV) { res = sas_find_bcast_dev(ch, src_dev); if (*src_dev) return res; @@ -1866,8 +1866,8 @@ static void sas_unregister_ex_tree(struct asd_sas_port *port, struct domain_devi list_for_each_entry_safe(child, n, &ex->children, siblings) { set_bit(SAS_DEV_GONE, &child->state); - if (child->dev_type == SAS_EDGE_EXPANDER_DEVICE || - child->dev_type == SAS_FANOUT_EXPANDER_DEVICE) + if (child->dev_type == EDGE_DEV || + child->dev_type == FANOUT_DEV) sas_unregister_ex_tree(port, child); else sas_unregister_dev(port, child); @@ -1887,8 +1887,8 @@ static void sas_unregister_devs_sas_addr(struct domain_device *parent, if (SAS_ADDR(child->sas_addr) == SAS_ADDR(phy->attached_sas_addr)) { set_bit(SAS_DEV_GONE, &child->state); - if (child->dev_type == SAS_EDGE_EXPANDER_DEVICE || - child->dev_type == SAS_FANOUT_EXPANDER_DEVICE) + if (child->dev_type == EDGE_DEV || + child->dev_type == FANOUT_DEV) sas_unregister_ex_tree(parent->port, child); else sas_unregister_dev(parent->port, child); @@ -1916,8 +1916,8 @@ static int sas_discover_bfs_by_root_level(struct domain_device *root, int res = 0; list_for_each_entry(child, &ex_root->children, siblings) { - if (child->dev_type == SAS_EDGE_EXPANDER_DEVICE || - child->dev_type == SAS_FANOUT_EXPANDER_DEVICE) { + if (child->dev_type == EDGE_DEV || + child->dev_type == FANOUT_DEV) { struct sas_expander_device *ex = rphy_to_expander_device(child->rphy); @@ -1970,8 +1970,8 @@ static int sas_discover_new(struct domain_device *dev, int phy_id) list_for_each_entry(child, &dev->ex_dev.children, siblings) { if (SAS_ADDR(child->sas_addr) == SAS_ADDR(ex_phy->attached_sas_addr)) { - if (child->dev_type == SAS_EDGE_EXPANDER_DEVICE || - child->dev_type == SAS_FANOUT_EXPANDER_DEVICE) + if (child->dev_type == EDGE_DEV || + child->dev_type == FANOUT_DEV) res = sas_discover_bfs_by_root(child); break; } @@ -1979,16 +1979,16 @@ static int sas_discover_new(struct domain_device *dev, int phy_id) return res; } -static bool dev_type_flutter(enum sas_device_type new, enum sas_device_type old) +static bool dev_type_flutter(enum sas_dev_type new, enum sas_dev_type old) { if (old == new) return true; /* treat device directed resets as flutter, if we went - * SAS_END_DEVICE to SAS_SATA_PENDING the link needs recovery + * SAS_END_DEV to SATA_PENDING the link needs recovery */ - if ((old == SAS_SATA_PENDING && new == SAS_END_DEVICE) || - (old == SAS_END_DEVICE && new == SAS_SATA_PENDING)) + if ((old == SATA_PENDING && new == SAS_END_DEV) || + (old == SAS_END_DEV && new == SATA_PENDING)) return true; return false; @@ -1998,7 +1998,7 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last) { struct expander_device *ex = &dev->ex_dev; struct ex_phy *phy = &ex->ex_phy[phy_id]; - enum sas_device_type type = SAS_PHY_UNUSED; + enum sas_dev_type type = NO_DEVICE; u8 sas_addr[8]; int res; @@ -2032,7 +2032,7 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last) sas_ex_phy_discover(dev, phy_id); - if (ata_dev && phy->attached_dev_type == SAS_SATA_PENDING) + if (ata_dev && phy->attached_dev_type == SATA_PENDING) action = ", needs recovery"; SAS_DPRINTK("ex %016llx phy 0x%x broadcast flutter%s\n", SAS_ADDR(dev->sas_addr), phy_id, action); diff --git a/trunk/drivers/scsi/libsas/sas_internal.h b/trunk/drivers/scsi/libsas/sas_internal.h index 7e7ba83f0a21..1de67964e5a1 100644 --- a/trunk/drivers/scsi/libsas/sas_internal.h +++ b/trunk/drivers/scsi/libsas/sas_internal.h @@ -131,16 +131,16 @@ static inline void sas_fill_in_rphy(struct domain_device *dev, rphy->identify.initiator_port_protocols = dev->iproto; rphy->identify.target_port_protocols = dev->tproto; switch (dev->dev_type) { - case SAS_SATA_DEV: + case SATA_DEV: /* FIXME: need sata device type */ - case SAS_END_DEVICE: - case SAS_SATA_PENDING: + case SAS_END_DEV: + case SATA_PENDING: rphy->identify.device_type = SAS_END_DEVICE; break; - case SAS_EDGE_EXPANDER_DEVICE: + case EDGE_DEV: rphy->identify.device_type = SAS_EDGE_EXPANDER_DEVICE; break; - case SAS_FANOUT_EXPANDER_DEVICE: + case FANOUT_DEV: rphy->identify.device_type = SAS_FANOUT_EXPANDER_DEVICE; break; default: diff --git a/trunk/drivers/scsi/libsas/sas_port.c b/trunk/drivers/scsi/libsas/sas_port.c index d3c5297c6c89..1398b714c018 100644 --- a/trunk/drivers/scsi/libsas/sas_port.c +++ b/trunk/drivers/scsi/libsas/sas_port.c @@ -69,7 +69,7 @@ static void sas_resume_port(struct asd_sas_phy *phy) continue; } - if (dev->dev_type == SAS_EDGE_EXPANDER_DEVICE || dev->dev_type == SAS_FANOUT_EXPANDER_DEVICE) { + if (dev->dev_type == EDGE_DEV || dev->dev_type == FANOUT_DEV) { dev->ex_dev.ex_change_count = -1; for (i = 0; i < dev->ex_dev.num_phys; i++) { struct ex_phy *phy = &dev->ex_dev.ex_phy[i]; diff --git a/trunk/drivers/scsi/lpfc/lpfc.h b/trunk/drivers/scsi/lpfc/lpfc.h index bcc56cac4fd8..7706c99ec8bb 100644 --- a/trunk/drivers/scsi/lpfc/lpfc.h +++ b/trunk/drivers/scsi/lpfc/lpfc.h @@ -46,15 +46,10 @@ struct lpfc_sli2_slim; #define LPFC_DEFAULT_MENLO_SG_SEG_CNT 128 /* sg element count per scsi cmnd for menlo needs nearly twice as for firmware downloads using bsg */ - -#define LPFC_MIN_SG_SLI4_BUF_SZ 0x800 /* based on LPFC_DEFAULT_SG_SEG_CNT */ -#define LPFC_MAX_SG_SLI4_SEG_CNT_DIF 128 /* sg element count per scsi cmnd */ -#define LPFC_MAX_SG_SEG_CNT_DIF 512 /* sg element count per scsi cmnd */ +#define LPFC_DEFAULT_PROT_SG_SEG_CNT 4096 /* sg protection elements count */ #define LPFC_MAX_SG_SEG_CNT 4096 /* sg element count per scsi cmnd */ -#define LPFC_MAX_SGL_SEG_CNT 512 /* SGL element count per scsi cmnd */ -#define LPFC_MAX_BPL_SEG_CNT 4096 /* BPL element count per scsi cmnd */ - #define LPFC_MAX_SGE_SIZE 0x80000000 /* Maximum data allowed in a SGE */ +#define LPFC_MAX_PROT_SG_SEG_CNT 4096 /* prot sg element count per scsi cmd*/ #define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */ #define LPFC_Q_RAMP_UP_INTERVAL 120 /* lun q_depth ramp up interval */ #define LPFC_VNAME_LEN 100 /* vport symbolic name length */ @@ -71,10 +66,8 @@ struct lpfc_sli2_slim; * queue depths when there are driver resource error or Firmware * resource error. */ -/* 1 Second */ -#define QUEUE_RAMP_DOWN_INTERVAL (msecs_to_jiffies(1000 * 1)) -/* 5 minutes */ -#define QUEUE_RAMP_UP_INTERVAL (msecs_to_jiffies(1000 * 300)) +#define QUEUE_RAMP_DOWN_INTERVAL (1 * HZ) /* 1 Second */ +#define QUEUE_RAMP_UP_INTERVAL (300 * HZ) /* 5 minutes */ /* Number of exchanges reserved for discovery to complete */ #define LPFC_DISC_IOCB_BUFF_COUNT 20 @@ -678,7 +671,6 @@ struct lpfc_hba { uint32_t lmt; uint32_t fc_topology; /* link topology, from LINK INIT */ - uint32_t fc_topology_changed; /* link topology, from LINK INIT */ struct lpfc_stats fc_stat; @@ -709,11 +701,9 @@ struct lpfc_hba { uint32_t cfg_poll_tmo; uint32_t cfg_use_msi; uint32_t cfg_fcp_imax; - uint32_t cfg_fcp_cpu_map; uint32_t cfg_fcp_wq_count; uint32_t cfg_fcp_eq_count; uint32_t cfg_fcp_io_channel; - uint32_t cfg_total_seg_cnt; uint32_t cfg_sg_seg_cnt; uint32_t cfg_prot_sg_seg_cnt; uint32_t cfg_sg_dma_buf_size; @@ -814,10 +804,8 @@ struct lpfc_hba { uint64_t bg_reftag_err_cnt; /* fastpath list. */ - spinlock_t scsi_buf_list_get_lock; /* SCSI buf alloc list lock */ - spinlock_t scsi_buf_list_put_lock; /* SCSI buf free list lock */ - struct list_head lpfc_scsi_buf_list_get; - struct list_head lpfc_scsi_buf_list_put; + spinlock_t scsi_buf_list_lock; + struct list_head lpfc_scsi_buf_list; uint32_t total_scsi_bufs; struct list_head lpfc_iocb_list; uint32_t total_iocbq_bufs; diff --git a/trunk/drivers/scsi/lpfc/lpfc_attr.c b/trunk/drivers/scsi/lpfc/lpfc_attr.c index 3c5625b8b1f4..9290713af253 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_attr.c +++ b/trunk/drivers/scsi/lpfc/lpfc_attr.c @@ -674,9 +674,6 @@ lpfc_do_offline(struct lpfc_hba *phba, uint32_t type) int i; int rc; - if (phba->pport->fc_flag & FC_OFFLINE_MODE) - return 0; - init_completion(&online_compl); rc = lpfc_workq_post_event(phba, &status, &online_compl, LPFC_EVT_OFFLINE_PREP); @@ -744,8 +741,7 @@ lpfc_selective_reset(struct lpfc_hba *phba) int status = 0; int rc; - if ((!phba->cfg_enable_hba_reset) || - (phba->pport->fc_flag & FC_OFFLINE_MODE)) + if (!phba->cfg_enable_hba_reset) return -EACCES; status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); @@ -899,7 +895,6 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode) pci_disable_sriov(pdev); phba->cfg_sriov_nr_virtfn = 0; } - status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); if (status != 0) @@ -2806,8 +2801,6 @@ lpfc_topology_store(struct device *dev, struct device_attribute *attr, lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "3054 lpfc_topology changed from %d to %d\n", prev_val, val); - if (prev_val != val && phba->sli_rev == LPFC_SLI_REV4) - phba->fc_topology_changed = 1; err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport)); if (err) { phba->cfg_topology = prev_val; @@ -3799,141 +3792,6 @@ lpfc_fcp_imax_init(struct lpfc_hba *phba, int val) static DEVICE_ATTR(lpfc_fcp_imax, S_IRUGO | S_IWUSR, lpfc_fcp_imax_show, lpfc_fcp_imax_store); -/** - * lpfc_state_show - Display current driver CPU affinity - * @dev: class converted to a Scsi_host structure. - * @attr: device attribute, not used. - * @buf: on return contains text describing the state of the link. - * - * Returns: size of formatted string. - **/ -static ssize_t -lpfc_fcp_cpu_map_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct Scsi_Host *shost = class_to_shost(dev); - struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; - struct lpfc_hba *phba = vport->phba; - struct lpfc_vector_map_info *cpup; - int idx, len = 0; - - if ((phba->sli_rev != LPFC_SLI_REV4) || - (phba->intr_type != MSIX)) - return len; - - switch (phba->cfg_fcp_cpu_map) { - case 0: - len += snprintf(buf + len, PAGE_SIZE-len, - "fcp_cpu_map: No mapping (%d)\n", - phba->cfg_fcp_cpu_map); - return len; - case 1: - len += snprintf(buf + len, PAGE_SIZE-len, - "fcp_cpu_map: HBA centric mapping (%d): " - "%d online CPUs\n", - phba->cfg_fcp_cpu_map, - phba->sli4_hba.num_online_cpu); - break; - case 2: - len += snprintf(buf + len, PAGE_SIZE-len, - "fcp_cpu_map: Driver centric mapping (%d): " - "%d online CPUs\n", - phba->cfg_fcp_cpu_map, - phba->sli4_hba.num_online_cpu); - break; - } - - cpup = phba->sli4_hba.cpu_map; - for (idx = 0; idx < phba->sli4_hba.num_present_cpu; idx++) { - if (cpup->irq == LPFC_VECTOR_MAP_EMPTY) - len += snprintf(buf + len, PAGE_SIZE-len, - "CPU %02d io_chan %02d " - "physid %d coreid %d\n", - idx, cpup->channel_id, cpup->phys_id, - cpup->core_id); - else - len += snprintf(buf + len, PAGE_SIZE-len, - "CPU %02d io_chan %02d " - "physid %d coreid %d IRQ %d\n", - idx, cpup->channel_id, cpup->phys_id, - cpup->core_id, cpup->irq); - - cpup++; - } - return len; -} - -/** - * lpfc_fcp_cpu_map_store - Change CPU affinity of driver vectors - * @dev: class device that is converted into a Scsi_host. - * @attr: device attribute, not used. - * @buf: one or more lpfc_polling_flags values. - * @count: not used. - * - * Returns: - * -EINVAL - Not implemented yet. - **/ -static ssize_t -lpfc_fcp_cpu_map_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int status = -EINVAL; - return status; -} - -/* -# lpfc_fcp_cpu_map: Defines how to map CPUs to IRQ vectors -# for the HBA. -# -# Value range is [0 to 2]. Default value is LPFC_DRIVER_CPU_MAP (2). -# 0 - Do not affinitze IRQ vectors -# 1 - Affintize HBA vectors with respect to each HBA -# (start with CPU0 for each HBA) -# 2 - Affintize HBA vectors with respect to the entire driver -# (round robin thru all CPUs across all HBAs) -*/ -static int lpfc_fcp_cpu_map = LPFC_DRIVER_CPU_MAP; -module_param(lpfc_fcp_cpu_map, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(lpfc_fcp_cpu_map, - "Defines how to map CPUs to IRQ vectors per HBA"); - -/** - * lpfc_fcp_cpu_map_init - Set the initial sr-iov virtual function enable - * @phba: lpfc_hba pointer. - * @val: link speed value. - * - * Description: - * If val is in a valid range [0-2], then affinitze the adapter's - * MSIX vectors. - * - * Returns: - * zero if val saved. - * -EINVAL val out of range - **/ -static int -lpfc_fcp_cpu_map_init(struct lpfc_hba *phba, int val) -{ - if (phba->sli_rev != LPFC_SLI_REV4) { - phba->cfg_fcp_cpu_map = 0; - return 0; - } - - if (val >= LPFC_MIN_CPU_MAP && val <= LPFC_MAX_CPU_MAP) { - phba->cfg_fcp_cpu_map = val; - return 0; - } - - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "3326 fcp_cpu_map: %d out of range, using default\n", - val); - phba->cfg_fcp_cpu_map = LPFC_DRIVER_CPU_MAP; - - return 0; -} - -static DEVICE_ATTR(lpfc_fcp_cpu_map, S_IRUGO | S_IWUSR, - lpfc_fcp_cpu_map_show, lpfc_fcp_cpu_map_store); - /* # lpfc_fcp_class: Determines FC class to use for the FCP protocol. # Value range is [2,3]. Default value is 3. @@ -4151,11 +4009,12 @@ LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support"); # 0 = disabled (default) # 1 = enabled # Value range is [0,1]. Default value is 0. -# -# This feature in under investigation and may be supported in the future. */ unsigned int lpfc_fcp_look_ahead = LPFC_LOOK_AHEAD_OFF; +module_param(lpfc_fcp_look_ahead, uint, S_IRUGO); +MODULE_PARM_DESC(lpfc_fcp_look_ahead, "Look ahead for completions"); + /* # lpfc_prot_mask: i # - Bit mask of host protection capabilities used to register with the @@ -4212,23 +4071,16 @@ MODULE_PARM_DESC(lpfc_delay_discovery, /* * lpfc_sg_seg_cnt - Initial Maximum DMA Segment Count - * This value can be set to values between 64 and 4096. The default value is + * This value can be set to values between 64 and 256. The default value is * 64, but may be increased to allow for larger Max I/O sizes. The scsi layer * will be allowed to request I/Os of sizes up to (MAX_SEG_COUNT * SEG_SIZE). - * Because of the additional overhead involved in setting up T10-DIF, - * this parameter will be limited to 128 if BlockGuard is enabled under SLI4 - * and will be limited to 512 if BlockGuard is enabled under SLI3. */ LPFC_ATTR_R(sg_seg_cnt, LPFC_DEFAULT_SG_SEG_CNT, LPFC_DEFAULT_SG_SEG_CNT, LPFC_MAX_SG_SEG_CNT, "Max Scatter Gather Segment Count"); -/* - * This parameter will be depricated, the driver cannot limit the - * protection data s/g list. - */ -LPFC_ATTR_R(prot_sg_seg_cnt, LPFC_DEFAULT_SG_SEG_CNT, - LPFC_DEFAULT_SG_SEG_CNT, LPFC_MAX_SG_SEG_CNT, - "Max Protection Scatter Gather Segment Count"); +LPFC_ATTR_R(prot_sg_seg_cnt, LPFC_DEFAULT_PROT_SG_SEG_CNT, + LPFC_DEFAULT_PROT_SG_SEG_CNT, LPFC_MAX_PROT_SG_SEG_CNT, + "Max Protection Scatter Gather Segment Count"); struct device_attribute *lpfc_hba_attrs[] = { &dev_attr_bg_info, @@ -4289,7 +4141,6 @@ struct device_attribute *lpfc_hba_attrs[] = { &dev_attr_lpfc_poll_tmo, &dev_attr_lpfc_use_msi, &dev_attr_lpfc_fcp_imax, - &dev_attr_lpfc_fcp_cpu_map, &dev_attr_lpfc_fcp_wq_count, &dev_attr_lpfc_fcp_eq_count, &dev_attr_lpfc_fcp_io_channel, @@ -5272,7 +5123,6 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) lpfc_enable_rrq_init(phba, lpfc_enable_rrq); lpfc_use_msi_init(phba, lpfc_use_msi); lpfc_fcp_imax_init(phba, lpfc_fcp_imax); - lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map); lpfc_fcp_wq_count_init(phba, lpfc_fcp_wq_count); lpfc_fcp_eq_count_init(phba, lpfc_fcp_eq_count); lpfc_fcp_io_channel_init(phba, lpfc_fcp_io_channel); diff --git a/trunk/drivers/scsi/lpfc/lpfc_bsg.c b/trunk/drivers/scsi/lpfc/lpfc_bsg.c index 094be2cad65b..888666892004 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_bsg.c +++ b/trunk/drivers/scsi/lpfc/lpfc_bsg.c @@ -219,35 +219,26 @@ lpfc_bsg_copy_data(struct lpfc_dmabuf *dma_buffers, unsigned int transfer_bytes, bytes_copied = 0; unsigned int sg_offset, dma_offset; unsigned char *dma_address, *sg_address; + struct scatterlist *sgel; LIST_HEAD(temp_list); - struct sg_mapping_iter miter; - unsigned long flags; - unsigned int sg_flags = SG_MITER_ATOMIC; - bool sg_valid; + list_splice_init(&dma_buffers->list, &temp_list); list_add(&dma_buffers->list, &temp_list); sg_offset = 0; - if (to_buffers) - sg_flags |= SG_MITER_FROM_SG; - else - sg_flags |= SG_MITER_TO_SG; - sg_miter_start(&miter, bsg_buffers->sg_list, bsg_buffers->sg_cnt, - sg_flags); - local_irq_save(flags); - sg_valid = sg_miter_next(&miter); + sgel = bsg_buffers->sg_list; list_for_each_entry(mp, &temp_list, list) { dma_offset = 0; - while (bytes_to_transfer && sg_valid && + while (bytes_to_transfer && sgel && (dma_offset < LPFC_BPL_SIZE)) { dma_address = mp->virt + dma_offset; if (sg_offset) { /* Continue previous partial transfer of sg */ - sg_address = miter.addr + sg_offset; - transfer_bytes = miter.length - sg_offset; + sg_address = sg_virt(sgel) + sg_offset; + transfer_bytes = sgel->length - sg_offset; } else { - sg_address = miter.addr; - transfer_bytes = miter.length; + sg_address = sg_virt(sgel); + transfer_bytes = sgel->length; } if (bytes_to_transfer < transfer_bytes) transfer_bytes = bytes_to_transfer; @@ -261,14 +252,12 @@ lpfc_bsg_copy_data(struct lpfc_dmabuf *dma_buffers, sg_offset += transfer_bytes; bytes_to_transfer -= transfer_bytes; bytes_copied += transfer_bytes; - if (sg_offset >= miter.length) { + if (sg_offset >= sgel->length) { sg_offset = 0; - sg_valid = sg_miter_next(&miter); + sgel = sg_next(sgel); } } } - sg_miter_stop(&miter); - local_irq_restore(flags); list_del_init(&dma_buffers->list); list_splice(&temp_list, &dma_buffers->list); return bytes_copied; @@ -482,7 +471,6 @@ lpfc_bsg_send_mgmt_cmd(struct fc_bsg_job *job) cmdiocbq->context1 = dd_data; cmdiocbq->context2 = cmp; cmdiocbq->context3 = bmp; - cmdiocbq->context_un.ndlp = ndlp; dd_data->type = TYPE_IOCB; dd_data->set_job = job; dd_data->context_un.iocb.cmdiocbq = cmdiocbq; @@ -1520,7 +1508,6 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct fc_bsg_job *job, uint32_t tag, ctiocb->context1 = dd_data; ctiocb->context2 = cmp; ctiocb->context3 = bmp; - ctiocb->context_un.ndlp = ndlp; ctiocb->iocb_cmpl = lpfc_issue_ct_rsp_cmp; dd_data->type = TYPE_IOCB; @@ -2589,8 +2576,7 @@ static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi, evt->wait_time_stamp = jiffies; time_left = wait_event_interruptible_timeout( evt->wq, !list_empty(&evt->events_to_see), - msecs_to_jiffies(1000 * - ((phba->fc_ratov * 2) + LPFC_DRVR_TIMEOUT))); + ((phba->fc_ratov * 2) + LPFC_DRVR_TIMEOUT) * HZ); if (list_empty(&evt->events_to_see)) ret_val = (time_left) ? -EINTR : -ETIMEDOUT; else { @@ -3165,8 +3151,7 @@ lpfc_bsg_diag_loopback_run(struct fc_bsg_job *job) evt->waiting = 1; time_left = wait_event_interruptible_timeout( evt->wq, !list_empty(&evt->events_to_see), - msecs_to_jiffies(1000 * - ((phba->fc_ratov * 2) + LPFC_DRVR_TIMEOUT))); + ((phba->fc_ratov * 2) + LPFC_DRVR_TIMEOUT) * HZ); evt->waiting = 0; if (list_empty(&evt->events_to_see)) { rc = (time_left) ? -EINTR : -ETIMEDOUT; diff --git a/trunk/drivers/scsi/lpfc/lpfc_crtn.h b/trunk/drivers/scsi/lpfc/lpfc_crtn.h index d41456e5f814..7631893ae005 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_crtn.h +++ b/trunk/drivers/scsi/lpfc/lpfc_crtn.h @@ -470,4 +470,3 @@ int lpfc_sli4_xri_sgl_update(struct lpfc_hba *); void lpfc_free_sgl_list(struct lpfc_hba *, struct list_head *); uint32_t lpfc_sli_port_speed_get(struct lpfc_hba *); int lpfc_sli4_request_firmware_update(struct lpfc_hba *, uint8_t); -void lpfc_sli4_offline_eratt(struct lpfc_hba *); diff --git a/trunk/drivers/scsi/lpfc/lpfc_ct.c b/trunk/drivers/scsi/lpfc/lpfc_ct.c index ae1a07c57cae..7bff3a19af56 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_ct.c +++ b/trunk/drivers/scsi/lpfc/lpfc_ct.c @@ -1811,8 +1811,7 @@ lpfc_fdmi_timeout_handler(struct lpfc_vport *vport) if (init_utsname()->nodename[0] != '\0') lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); else - mod_timer(&vport->fc_fdmitmo, jiffies + - msecs_to_jiffies(1000 * 60)); + mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60); } return; } diff --git a/trunk/drivers/scsi/lpfc/lpfc_els.c b/trunk/drivers/scsi/lpfc/lpfc_els.c index 3cae0a92e8bd..bbed8471bf0b 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_els.c +++ b/trunk/drivers/scsi/lpfc/lpfc_els.c @@ -29,7 +29,6 @@ #include #include - #include "lpfc_hw4.h" #include "lpfc_hw.h" #include "lpfc_sli.h" @@ -239,10 +238,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, icmd->un.elsreq64.remoteID = did; /* DID */ icmd->ulpCommand = CMD_ELS_REQUEST64_CR; - if (elscmd == ELS_CMD_FLOGI) - icmd->ulpTimeout = FF_DEF_RATOV * 2; - else - icmd->ulpTimeout = phba->fc_ratov * 2; + icmd->ulpTimeout = phba->fc_ratov * 2; } else { icmd->un.xseq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys); icmd->un.xseq64.bdl.addrLow = putPaddrLow(pbuflist->phys); @@ -312,20 +308,16 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, /* Xmit ELS command to remote NPORT */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0116 Xmit ELS command x%x to remote " - "NPORT x%x I/O tag: x%x, port state:x%x" - " fc_flag:x%x\n", + "NPORT x%x I/O tag: x%x, port state: x%x\n", elscmd, did, elsiocb->iotag, - vport->port_state, - vport->fc_flag); + vport->port_state); } else { /* Xmit ELS response to remote NPORT */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0117 Xmit ELS response x%x to remote " - "NPORT x%x I/O tag: x%x, size: x%x " - "port_state x%x fc_flag x%x\n", + "NPORT x%x I/O tag: x%x, size: x%x\n", elscmd, ndlp->nlp_DID, elsiocb->iotag, - cmdSize, vport->port_state, - vport->fc_flag); + cmdSize); } return elsiocb; @@ -917,23 +909,6 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_PT2PT; spin_unlock_irq(shost->host_lock); - /* If physical FC port changed, unreg VFI and ALL VPIs / RPIs */ - if ((phba->sli_rev == LPFC_SLI_REV4) && phba->fc_topology_changed) { - lpfc_unregister_fcf_prep(phba); - - /* The FC_VFI_REGISTERED flag will get clear in the cmpl - * handler for unreg_vfi, but if we don't force the - * FC_VFI_REGISTERED flag then the reg_vfi mailbox could be - * built with the update bit set instead of just the vp bit to - * change the Nport ID. We need to have the vp set and the - * Upd cleared on topology changes. - */ - spin_lock_irq(shost->host_lock); - vport->fc_flag &= ~FC_VFI_REGISTERED; - spin_unlock_irq(shost->host_lock); - phba->fc_topology_changed = 0; - lpfc_issue_reg_vfi(vport); - } /* Start discovery - this should just do CLEAR_LA */ lpfc_disc_start(vport); @@ -1055,19 +1030,9 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, vport->cfg_discovery_threads = LPFC_MAX_DISC_THREADS; if ((phba->sli_rev == LPFC_SLI_REV4) && (!(vport->fc_flag & FC_VFI_REGISTERED) || - (vport->fc_prevDID != vport->fc_myDID) || - phba->fc_topology_changed)) { - if (vport->fc_flag & FC_VFI_REGISTERED) { - if (phba->fc_topology_changed) { - lpfc_unregister_fcf_prep(phba); - spin_lock_irq(shost->host_lock); - vport->fc_flag &= ~FC_VFI_REGISTERED; - spin_unlock_irq(shost->host_lock); - phba->fc_topology_changed = 0; - } else { - lpfc_sli4_unreg_all_rpis(vport); - } - } + (vport->fc_prevDID != vport->fc_myDID))) { + if (vport->fc_flag & FC_VFI_REGISTERED) + lpfc_sli4_unreg_all_rpis(vport); lpfc_issue_reg_vfi(vport); lpfc_nlp_put(ndlp); goto out; @@ -1089,11 +1054,10 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, /* FLOGI completes successfully */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, - "0101 FLOGI completes successfully, I/O tag:x%x, " - "Data: x%x x%x x%x x%x x%x x%x\n", cmdiocb->iotag, + "0101 FLOGI completes successfully " + "Data: x%x x%x x%x x%x\n", irsp->un.ulpWord[4], sp->cmn.e_d_tov, - sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution, - vport->port_state, vport->fc_flag); + sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution); if (vport->port_state == LPFC_FLOGI) { /* @@ -5083,8 +5047,6 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, struct ls_rjt stat; uint32_t cmd, did; int rc; - uint32_t fc_flag = 0; - uint32_t port_state = 0; cmd = *lp++; sp = (struct serv_parm *) lp; @@ -5151,25 +5113,16 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, * will be. */ vport->fc_myDID = PT2PT_LocalID; - } else - vport->fc_myDID = PT2PT_RemoteID; + } /* * The vport state should go to LPFC_FLOGI only * AFTER we issue a FLOGI, not receive one. */ spin_lock_irq(shost->host_lock); - fc_flag = vport->fc_flag; - port_state = vport->port_state; vport->fc_flag |= FC_PT2PT; vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); - vport->port_state = LPFC_FLOGI; spin_unlock_irq(shost->host_lock); - lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, - "3311 Rcv Flogi PS x%x new PS x%x " - "fc_flag x%x new fc_flag x%x\n", - port_state, vport->port_state, - fc_flag, vport->fc_flag); /* * We temporarily set fc_myDID to make it look like we are @@ -6288,8 +6241,7 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) } if (!list_empty(&phba->sli.ring[LPFC_ELS_RING].txcmplq)) - mod_timer(&vport->els_tmofunc, - jiffies + msecs_to_jiffies(1000 * timeout)); + mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout); } /** @@ -6660,9 +6612,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, /* ELS command received from NPORT */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0112 ELS command x%x received from NPORT x%x " - "Data: x%x x%x x%x x%x\n", - cmd, did, vport->port_state, vport->fc_flag, - vport->fc_myDID, vport->fc_prevDID); + "Data: x%x\n", cmd, did, vport->port_state); switch (cmd) { case ELS_CMD_PLOGI: lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, @@ -6671,19 +6621,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, phba->fc_stat.elsRcvPLOGI++; ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp); - if (phba->sli_rev == LPFC_SLI_REV4 && - (phba->pport->fc_flag & FC_PT2PT)) { - vport->fc_prevDID = vport->fc_myDID; - /* Our DID needs to be updated before registering - * the vfi. This is done in lpfc_rcv_plogi but - * that is called after the reg_vfi. - */ - vport->fc_myDID = elsiocb->iocb.un.rcvels.parmRo; - lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, - "3312 Remote port assigned DID x%x " - "%x\n", vport->fc_myDID, - vport->fc_prevDID); - } lpfc_send_els_event(vport, ndlp, payload); @@ -6693,7 +6630,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, rjt_exp = LSEXP_NOTHING_MORE; break; } - shost = lpfc_shost_from_vport(vport); if (vport->port_state < LPFC_DISC_AUTH) { if (!(phba->pport->fc_flag & FC_PT2PT) || (phba->pport->fc_flag & FC_PT2PT_PLOGI)) { @@ -6705,18 +6641,9 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, * another NPort and the other side has initiated * the PLOGI before responding to our FLOGI. */ - if (phba->sli_rev == LPFC_SLI_REV4 && - (phba->fc_topology_changed || - vport->fc_myDID != vport->fc_prevDID)) { - lpfc_unregister_fcf_prep(phba); - spin_lock_irq(shost->host_lock); - vport->fc_flag &= ~FC_VFI_REGISTERED; - spin_unlock_irq(shost->host_lock); - phba->fc_topology_changed = 0; - lpfc_issue_reg_vfi(vport); - } } + shost = lpfc_shost_from_vport(vport); spin_lock_irq(shost->host_lock); ndlp->nlp_flag &= ~NLP_TARGET_REMOVE; spin_unlock_irq(shost->host_lock); @@ -7075,11 +7002,8 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) spin_lock_irq(shost->host_lock); if (vport->fc_flag & FC_DISC_DELAYED) { spin_unlock_irq(shost->host_lock); - lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, - "3334 Delay fc port discovery for %d seconds\n", - phba->fc_ratov); mod_timer(&vport->delayed_disc_tmo, - jiffies + msecs_to_jiffies(1000 * phba->fc_ratov)); + jiffies + HZ * phba->fc_ratov); return; } spin_unlock_irq(shost->host_lock); @@ -7363,7 +7287,7 @@ lpfc_retry_pport_discovery(struct lpfc_hba *phba) return; shost = lpfc_shost_from_vport(phba->pport); - mod_timer(&ndlp->nlp_delayfunc, jiffies + msecs_to_jiffies(1000)); + mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_DELAY_TMO; spin_unlock_irq(shost->host_lock); @@ -7867,8 +7791,7 @@ lpfc_block_fabric_iocbs(struct lpfc_hba *phba) blocked = test_and_set_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags); /* Start a timer to unblock fabric iocbs after 100ms */ if (!blocked) - mod_timer(&phba->fabric_block_timer, - jiffies + msecs_to_jiffies(100)); + mod_timer(&phba->fabric_block_timer, jiffies + HZ/10 ); return; } diff --git a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c index 0f6e2548f35d..326e05a65a73 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -160,12 +160,11 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) if (!list_empty(&evtp->evt_listp)) return; - evtp->evt_arg1 = lpfc_nlp_get(ndlp); - spin_lock_irq(&phba->hbalock); /* We need to hold the node by incrementing the reference * count until this queued work is done */ + evtp->evt_arg1 = lpfc_nlp_get(ndlp); if (evtp->evt_arg1) { evtp->evt = LPFC_EVT_DEV_LOSS; list_add_tail(&evtp->evt_listp, &phba->work_list); @@ -1009,6 +1008,9 @@ lpfc_linkup(struct lpfc_hba *phba) for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) lpfc_linkup_port(vports[i]); lpfc_destroy_vport_work_array(phba, vports); + if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && + (phba->sli_rev < LPFC_SLI_REV4)) + lpfc_issue_clear_la(phba, phba->pport); return 0; } @@ -1434,8 +1436,7 @@ lpfc_register_fcf(struct lpfc_hba *phba) if (phba->fcf.fcf_flag & FCF_REGISTERED) { phba->fcf.fcf_flag |= (FCF_SCAN_DONE | FCF_IN_USE); phba->hba_flag &= ~FCF_TS_INPROG; - if (phba->pport->port_state != LPFC_FLOGI && - phba->pport->fc_flag & FC_FABRIC) { + if (phba->pport->port_state != LPFC_FLOGI) { phba->hba_flag |= FCF_RR_INPROG; spin_unlock_irq(&phba->hbalock); lpfc_initial_flogi(phba->pport); @@ -2269,11 +2270,8 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) spin_unlock_irq(&phba->hbalock); lpfc_printf_log(phba, KERN_INFO, LOG_FIP, "2836 New FCF matches in-use " - "FCF (x%x), port_state:x%x, " - "fc_flag:x%x\n", - phba->fcf.current_rec.fcf_indx, - phba->pport->port_state, - phba->pport->fc_flag); + "FCF (x%x)\n", + phba->fcf.current_rec.fcf_indx); goto out; } else lpfc_printf_log(phba, KERN_ERR, LOG_FIP, @@ -2798,19 +2796,7 @@ void lpfc_issue_init_vpi(struct lpfc_vport *vport) { LPFC_MBOXQ_t *mboxq; - int rc, vpi; - - if ((vport->port_type != LPFC_PHYSICAL_PORT) && (!vport->vpi)) { - vpi = lpfc_alloc_vpi(vport->phba); - if (!vpi) { - lpfc_printf_vlog(vport, KERN_ERR, - LOG_MBOX, - "3303 Failed to obtain vport vpi\n"); - lpfc_vport_set_state(vport, FC_VPORT_FAILED); - return; - } - vport->vpi = vpi; - } + int rc; mboxq = mempool_alloc(vport->phba->mbox_mem_pool, GFP_KERNEL); if (!mboxq) { @@ -2908,14 +2894,9 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) goto out_free_mem; } - /* If the VFI is already registered, there is nothing else to do - * Unless this was a VFI update and we are in PT2PT mode, then - * we should drop through to set the port state to ready. - */ + /* If the VFI is already registered, there is nothing else to do */ if (vport->fc_flag & FC_VFI_REGISTERED) - if (!(phba->sli_rev == LPFC_SLI_REV4 && - vport->fc_flag & FC_PT2PT)) - goto out_free_mem; + goto out_free_mem; /* The VPI is implicitly registered when the VFI is registered */ spin_lock_irq(shost->host_lock); @@ -2932,13 +2913,6 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) goto out_free_mem; } - lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, - "3313 cmpl reg vfi port_state:%x fc_flag:%x myDid:%x " - "alpacnt:%d LinkState:%x topology:%x\n", - vport->port_state, vport->fc_flag, vport->fc_myDID, - vport->phba->alpa_map[0], - phba->link_state, phba->fc_topology); - if (vport->port_state == LPFC_FABRIC_CFG_LINK) { /* * For private loop or for NPort pt2pt, @@ -2951,10 +2925,7 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) /* Use loop map to make discovery list */ lpfc_disc_list_loopmap(vport); /* Start discovery */ - if (vport->fc_flag & FC_PT2PT) - vport->port_state = LPFC_VPORT_READY; - else - lpfc_disc_start(vport); + lpfc_disc_start(vport); } else { lpfc_start_fdiscs(phba); lpfc_do_scr_ns_plogi(phba, vport); @@ -3036,15 +3007,6 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) break; } - if (phba->fc_topology && - phba->fc_topology != bf_get(lpfc_mbx_read_top_topology, la)) { - lpfc_printf_log(phba, KERN_WARNING, LOG_SLI, - "3314 Toplogy changed was 0x%x is 0x%x\n", - phba->fc_topology, - bf_get(lpfc_mbx_read_top_topology, la)); - phba->fc_topology_changed = 1; - } - phba->fc_topology = bf_get(lpfc_mbx_read_top_topology, la); phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED; @@ -4273,7 +4235,7 @@ lpfc_set_disctmo(struct lpfc_vport *vport) tmo, vport->port_state, vport->fc_flag); } - mod_timer(&vport->fc_disctmo, jiffies + msecs_to_jiffies(1000 * tmo)); + mod_timer(&vport->fc_disctmo, jiffies + HZ * tmo); spin_lock_irq(shost->host_lock); vport->fc_flag |= FC_DISC_TMO; spin_unlock_irq(shost->host_lock); @@ -4987,12 +4949,8 @@ lpfc_disc_start(struct lpfc_vport *vport) uint32_t clear_la_pending; int did_changed; - if (!lpfc_is_link_up(phba)) { - lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, - "3315 Link is not up %x\n", - phba->link_state); + if (!lpfc_is_link_up(phba)) return; - } if (phba->link_state == LPFC_CLEAR_LA) clear_la_pending = 1; @@ -5025,13 +4983,11 @@ lpfc_disc_start(struct lpfc_vport *vport) if (num_sent) return; - /* Register the VPI for SLI3, NPIV only. */ + /* Register the VPI for SLI3, NON-NPIV only. */ if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) && !(vport->fc_flag & FC_PT2PT) && !(vport->fc_flag & FC_RSCN_MODE) && (phba->sli_rev < LPFC_SLI_REV4)) { - if (vport->port_type == LPFC_PHYSICAL_PORT) - lpfc_issue_clear_la(phba, vport); lpfc_issue_reg_vpi(phba, vport); return; } @@ -5454,8 +5410,7 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) if (vport->cfg_fdmi_on == 1) lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); else - mod_timer(&vport->fc_fdmitmo, - jiffies + msecs_to_jiffies(1000 * 60)); + mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60); /* decrement the node reference count held for this callback * function. @@ -5900,7 +5855,7 @@ lpfc_unregister_fcf_prep(struct lpfc_hba *phba) struct lpfc_vport **vports; struct lpfc_nodelist *ndlp; struct Scsi_Host *shost; - int i = 0, rc; + int i, rc; /* Unregister RPIs */ if (lpfc_fcf_inuse(phba)) @@ -5928,20 +5883,6 @@ lpfc_unregister_fcf_prep(struct lpfc_hba *phba) spin_unlock_irq(shost->host_lock); } lpfc_destroy_vport_work_array(phba, vports); - if (i == 0 && (!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED))) { - ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); - if (ndlp) - lpfc_cancel_retry_delay_tmo(phba->pport, ndlp); - lpfc_cleanup_pending_mbox(phba->pport); - if (phba->sli_rev == LPFC_SLI_REV4) - lpfc_sli4_unreg_all_rpis(phba->pport); - lpfc_mbx_unreg_vpi(phba->pport); - shost = lpfc_shost_from_vport(phba->pport); - spin_lock_irq(shost->host_lock); - phba->pport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; - phba->pport->vpi_state &= ~LPFC_VPI_REGISTERED; - spin_unlock_irq(shost->host_lock); - } /* Cleanup any outstanding ELS commands */ lpfc_els_flush_all_cmd(phba); diff --git a/trunk/drivers/scsi/lpfc/lpfc_hw.h b/trunk/drivers/scsi/lpfc/lpfc_hw.h index 83700c18f468..e8c476031703 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hw.h +++ b/trunk/drivers/scsi/lpfc/lpfc_hw.h @@ -1667,7 +1667,6 @@ enum lpfc_protgrp_type { #define BG_OP_IN_CSUM_OUT_CSUM 0x5 #define BG_OP_IN_CRC_OUT_CSUM 0x6 #define BG_OP_IN_CSUM_OUT_CRC 0x7 -#define BG_OP_RAW_MODE 0x8 struct lpfc_pde5 { uint32_t word0; diff --git a/trunk/drivers/scsi/lpfc/lpfc_hw4.h b/trunk/drivers/scsi/lpfc/lpfc_hw4.h index 713a4613ec3a..1dd2f6f0a127 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hw4.h +++ b/trunk/drivers/scsi/lpfc/lpfc_hw4.h @@ -200,11 +200,6 @@ struct lpfc_sli_intf { #define LPFC_MAX_IMAX 5000000 #define LPFC_DEF_IMAX 50000 -#define LPFC_MIN_CPU_MAP 0 -#define LPFC_MAX_CPU_MAP 2 -#define LPFC_HBA_CPU_MAP 1 -#define LPFC_DRIVER_CPU_MAP 2 /* Default */ - /* PORT_CAPABILITIES constants. */ #define LPFC_MAX_SUPPORTED_PAGES 8 @@ -626,7 +621,7 @@ struct lpfc_register { #define lpfc_sliport_status_rdy_SHIFT 23 #define lpfc_sliport_status_rdy_MASK 0x1 #define lpfc_sliport_status_rdy_WORD word0 -#define MAX_IF_TYPE_2_RESETS 6 +#define MAX_IF_TYPE_2_RESETS 1000 #define LPFC_CTL_PORT_CTL_OFFSET 0x408 #define lpfc_sliport_ctrl_end_SHIFT 30 diff --git a/trunk/drivers/scsi/lpfc/lpfc_init.c b/trunk/drivers/scsi/lpfc/lpfc_init.c index cb465b253910..90b8b0515e23 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_init.c +++ b/trunk/drivers/scsi/lpfc/lpfc_init.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -59,9 +58,6 @@ char *_dump_buf_dif; unsigned long _dump_buf_dif_order; spinlock_t _dump_buf_lock; -/* Used when mapping IRQ vectors in a driver centric manner */ -uint16_t lpfc_used_cpu[LPFC_MAX_CPU]; - static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *); static int lpfc_post_rcv_buf(struct lpfc_hba *); static int lpfc_sli4_queue_verify(struct lpfc_hba *); @@ -545,16 +541,13 @@ lpfc_config_port_post(struct lpfc_hba *phba) /* Set up ring-0 (ELS) timer */ timeout = phba->fc_ratov * 2; - mod_timer(&vport->els_tmofunc, - jiffies + msecs_to_jiffies(1000 * timeout)); + mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout); /* Set up heart beat (HB) timer */ - mod_timer(&phba->hb_tmofunc, - jiffies + msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL)); + mod_timer(&phba->hb_tmofunc, jiffies + HZ * LPFC_HB_MBOX_INTERVAL); phba->hb_outstanding = 0; phba->last_completion_time = jiffies; /* Set up error attention (ERATT) polling timer */ - mod_timer(&phba->eratt_poll, - jiffies + msecs_to_jiffies(1000 * LPFC_ERATT_POLL_INTERVAL)); + mod_timer(&phba->eratt_poll, jiffies + HZ * LPFC_ERATT_POLL_INTERVAL); if (phba->hba_flag & LINK_DISABLED) { lpfc_printf_log(phba, @@ -915,9 +908,9 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) psb->pCmd = NULL; psb->status = IOSTAT_SUCCESS; } - spin_lock_irqsave(&phba->scsi_buf_list_put_lock, iflag); - list_splice(&aborts, &phba->lpfc_scsi_buf_list_put); - spin_unlock_irqrestore(&phba->scsi_buf_list_put_lock, iflag); + spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); + list_splice(&aborts, &phba->lpfc_scsi_buf_list); + spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag); return 0; } @@ -1028,8 +1021,7 @@ lpfc_hb_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq) !(phba->link_state == LPFC_HBA_ERROR) && !(phba->pport->load_flag & FC_UNLOADING)) mod_timer(&phba->hb_tmofunc, - jiffies + - msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL)); + jiffies + HZ * LPFC_HB_MBOX_INTERVAL); return; } @@ -1072,18 +1064,15 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) spin_lock_irq(&phba->pport->work_port_lock); - if (time_after(phba->last_completion_time + - msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL), - jiffies)) { + if (time_after(phba->last_completion_time + LPFC_HB_MBOX_INTERVAL * HZ, + jiffies)) { spin_unlock_irq(&phba->pport->work_port_lock); if (!phba->hb_outstanding) mod_timer(&phba->hb_tmofunc, - jiffies + - msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL)); + jiffies + HZ * LPFC_HB_MBOX_INTERVAL); else mod_timer(&phba->hb_tmofunc, - jiffies + - msecs_to_jiffies(1000 * LPFC_HB_MBOX_TIMEOUT)); + jiffies + HZ * LPFC_HB_MBOX_TIMEOUT); return; } spin_unlock_irq(&phba->pport->work_port_lock); @@ -1115,8 +1104,7 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) if (!pmboxq) { mod_timer(&phba->hb_tmofunc, jiffies + - msecs_to_jiffies(1000 * - LPFC_HB_MBOX_INTERVAL)); + HZ * LPFC_HB_MBOX_INTERVAL); return; } @@ -1132,8 +1120,7 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) phba->mbox_mem_pool); mod_timer(&phba->hb_tmofunc, jiffies + - msecs_to_jiffies(1000 * - LPFC_HB_MBOX_INTERVAL)); + HZ * LPFC_HB_MBOX_INTERVAL); return; } phba->skipped_hb = 0; @@ -1149,8 +1136,7 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) phba->skipped_hb = jiffies; mod_timer(&phba->hb_tmofunc, - jiffies + - msecs_to_jiffies(1000 * LPFC_HB_MBOX_TIMEOUT)); + jiffies + HZ * LPFC_HB_MBOX_TIMEOUT); return; } else { /* @@ -1164,8 +1150,7 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) jiffies_to_msecs(jiffies - phba->last_completion_time)); mod_timer(&phba->hb_tmofunc, - jiffies + - msecs_to_jiffies(1000 * LPFC_HB_MBOX_TIMEOUT)); + jiffies + HZ * LPFC_HB_MBOX_TIMEOUT); } } } @@ -1206,7 +1191,7 @@ lpfc_offline_eratt(struct lpfc_hba *phba) * This routine is called to bring a SLI4 HBA offline when HBA hardware error * other than Port Error 6 has been detected. **/ -void +static void lpfc_sli4_offline_eratt(struct lpfc_hba *phba) { lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT); @@ -2648,7 +2633,6 @@ lpfc_online(struct lpfc_hba *phba) struct lpfc_vport *vport; struct lpfc_vport **vports; int i; - bool vpis_cleared = false; if (!phba) return 0; @@ -2672,10 +2656,6 @@ lpfc_online(struct lpfc_hba *phba) lpfc_unblock_mgmt_io(phba); return 1; } - spin_lock_irq(&phba->hbalock); - if (!phba->sli4_hba.max_cfg_param.vpi_used) - vpis_cleared = true; - spin_unlock_irq(&phba->hbalock); } else { if (lpfc_sli_hba_setup(phba)) { /* Initialize SLI2/SLI3 HBA */ lpfc_unblock_mgmt_io(phba); @@ -2692,13 +2672,8 @@ lpfc_online(struct lpfc_hba *phba) vports[i]->fc_flag &= ~FC_OFFLINE_MODE; if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI; - if (phba->sli_rev == LPFC_SLI_REV4) { + if (phba->sli_rev == LPFC_SLI_REV4) vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; - if ((vpis_cleared) && - (vports[i]->port_type != - LPFC_PHYSICAL_PORT)) - vports[i]->vpi = 0; - } spin_unlock_irq(shost->host_lock); } lpfc_destroy_vport_work_array(phba, vports); @@ -2858,30 +2833,16 @@ lpfc_scsi_free(struct lpfc_hba *phba) struct lpfc_iocbq *io, *io_next; spin_lock_irq(&phba->hbalock); - /* Release all the lpfc_scsi_bufs maintained by this host. */ - - spin_lock(&phba->scsi_buf_list_put_lock); - list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list_put, - list) { + spin_lock(&phba->scsi_buf_list_lock); + list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list, list) { list_del(&sb->list); pci_pool_free(phba->lpfc_scsi_dma_buf_pool, sb->data, sb->dma_handle); kfree(sb); phba->total_scsi_bufs--; } - spin_unlock(&phba->scsi_buf_list_put_lock); - - spin_lock(&phba->scsi_buf_list_get_lock); - list_for_each_entry_safe(sb, sb_next, &phba->lpfc_scsi_buf_list_get, - list) { - list_del(&sb->list); - pci_pool_free(phba->lpfc_scsi_dma_buf_pool, sb->data, - sb->dma_handle); - kfree(sb); - phba->total_scsi_bufs--; - } - spin_unlock(&phba->scsi_buf_list_get_lock); + spin_unlock(&phba->scsi_buf_list_lock); /* Release all the lpfc_iocbq entries maintained by this host. */ list_for_each_entry_safe(io, io_next, &phba->lpfc_iocb_list, list) { @@ -3017,12 +2978,9 @@ lpfc_sli4_xri_sgl_update(struct lpfc_hba *phba) phba->sli4_hba.scsi_xri_cnt, phba->sli4_hba.scsi_xri_max); - spin_lock_irq(&phba->scsi_buf_list_get_lock); - spin_lock_irq(&phba->scsi_buf_list_put_lock); - list_splice_init(&phba->lpfc_scsi_buf_list_get, &scsi_sgl_list); - list_splice(&phba->lpfc_scsi_buf_list_put, &scsi_sgl_list); - spin_unlock_irq(&phba->scsi_buf_list_put_lock); - spin_unlock_irq(&phba->scsi_buf_list_get_lock); + spin_lock_irq(&phba->scsi_buf_list_lock); + list_splice_init(&phba->lpfc_scsi_buf_list, &scsi_sgl_list); + spin_unlock_irq(&phba->scsi_buf_list_lock); if (phba->sli4_hba.scsi_xri_cnt > phba->sli4_hba.scsi_xri_max) { /* max scsi xri shrinked below the allocated scsi buffers */ @@ -3036,9 +2994,9 @@ lpfc_sli4_xri_sgl_update(struct lpfc_hba *phba) psb->dma_handle); kfree(psb); } - spin_lock_irq(&phba->scsi_buf_list_get_lock); + spin_lock_irq(&phba->scsi_buf_list_lock); phba->sli4_hba.scsi_xri_cnt -= scsi_xri_cnt; - spin_unlock_irq(&phba->scsi_buf_list_get_lock); + spin_unlock_irq(&phba->scsi_buf_list_lock); } /* update xris associated to remaining allocated scsi buffers */ @@ -3056,12 +3014,9 @@ lpfc_sli4_xri_sgl_update(struct lpfc_hba *phba) psb->cur_iocbq.sli4_lxritag = lxri; psb->cur_iocbq.sli4_xritag = phba->sli4_hba.xri_ids[lxri]; } - spin_lock_irq(&phba->scsi_buf_list_get_lock); - spin_lock_irq(&phba->scsi_buf_list_put_lock); - list_splice_init(&scsi_sgl_list, &phba->lpfc_scsi_buf_list_get); - INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list_put); - spin_unlock_irq(&phba->scsi_buf_list_put_lock); - spin_unlock_irq(&phba->scsi_buf_list_get_lock); + spin_lock_irq(&phba->scsi_buf_list_lock); + list_splice_init(&scsi_sgl_list, &phba->lpfc_scsi_buf_list); + spin_unlock_irq(&phba->scsi_buf_list_lock); return 0; @@ -3242,15 +3197,14 @@ int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time) stat = 1; goto finished; } - if (time >= msecs_to_jiffies(30 * 1000)) { + if (time >= 30 * HZ) { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0461 Scanning longer than 30 " "seconds. Continuing initialization\n"); stat = 1; goto finished; } - if (time >= msecs_to_jiffies(15 * 1000) && - phba->link_state <= LPFC_LINK_DOWN) { + if (time >= 15 * HZ && phba->link_state <= LPFC_LINK_DOWN) { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "0465 Link down longer than 15 " "seconds. Continuing initialization\n"); @@ -3262,7 +3216,7 @@ int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time) goto finished; if (vport->num_disc_nodes || vport->fc_prli_sent) goto finished; - if (vport->fc_map_cnt == 0 && time < msecs_to_jiffies(2 * 1000)) + if (vport->fc_map_cnt == 0 && time < 2 * HZ) goto finished; if ((phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) != 0) goto finished; @@ -4261,8 +4215,7 @@ lpfc_sli4_async_fip_evt(struct lpfc_hba *phba, * If there are other active VLinks present, * re-instantiate the Vlink using FDISC. */ - mod_timer(&ndlp->nlp_delayfunc, - jiffies + msecs_to_jiffies(1000)); + mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); shost = lpfc_shost_from_vport(vport); spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_DELAY_TMO; @@ -4754,52 +4707,23 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba) return -ENOMEM; /* - * Since lpfc_sg_seg_cnt is module parameter, the sg_dma_buf_size + * Since the sg_tablesize is module parameter, the sg_dma_buf_size * used to create the sg_dma_buf_pool must be dynamically calculated. + * 2 segments are added since the IOCB needs a command and response bde. */ - - /* Initialize the host templates the configured values. */ - lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt; - lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt; - - /* There are going to be 2 reserved BDEs: 1 FCP cmnd + 1 FCP rsp */ - if (phba->cfg_enable_bg) { - /* - * The scsi_buf for a T10-DIF I/O will hold the FCP cmnd, - * the FCP rsp, and a BDE for each. Sice we have no control - * over how many protection data segments the SCSI Layer - * will hand us (ie: there could be one for every block - * in the IO), we just allocate enough BDEs to accomidate - * our max amount and we need to limit lpfc_sg_seg_cnt to - * minimize the risk of running out. - */ - phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + - sizeof(struct fcp_rsp) + - (LPFC_MAX_SG_SEG_CNT * sizeof(struct ulp_bde64)); - - if (phba->cfg_sg_seg_cnt > LPFC_MAX_SG_SEG_CNT_DIF) - phba->cfg_sg_seg_cnt = LPFC_MAX_SG_SEG_CNT_DIF; - - /* Total BDEs in BPL for scsi_sg_list and scsi_sg_prot_list */ - phba->cfg_total_seg_cnt = LPFC_MAX_SG_SEG_CNT; - } else { - /* - * The scsi_buf for a regular I/O will hold the FCP cmnd, - * the FCP rsp, a BDE for each, and a BDE for up to - * cfg_sg_seg_cnt data segments. - */ - phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + - sizeof(struct fcp_rsp) + + phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + + sizeof(struct fcp_rsp) + ((phba->cfg_sg_seg_cnt + 2) * sizeof(struct ulp_bde64)); - /* Total BDEs in BPL for scsi_sg_list */ - phba->cfg_total_seg_cnt = phba->cfg_sg_seg_cnt + 2; + if (phba->cfg_enable_bg) { + phba->cfg_sg_seg_cnt = LPFC_MAX_SG_SEG_CNT; + phba->cfg_sg_dma_buf_size += + phba->cfg_prot_sg_seg_cnt * sizeof(struct ulp_bde64); } - lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_FCP, - "9088 sg_tablesize:%d dmabuf_size:%d total_bde:%d\n", - phba->cfg_sg_seg_cnt, phba->cfg_sg_dma_buf_size, - phba->cfg_total_seg_cnt); + /* Also reinitialize the host templates with new values. */ + lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt; + lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt; phba->max_vpi = LPFC_MAX_VPI; /* This will be set to correct value after config_port mbox */ @@ -4865,13 +4789,13 @@ lpfc_sli_driver_resource_unset(struct lpfc_hba *phba) static int lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) { - struct lpfc_vector_map_info *cpup; struct lpfc_sli *psli; LPFC_MBOXQ_t *mboxq; - int rc, i, hbq_count, max_buf_size; + int rc, i, hbq_count, buf_size, dma_buf_size, max_buf_size; uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0}; struct lpfc_mqe *mqe; - int longs; + int longs, sli_family; + int sges_per_segment; /* Before proceed, wait for POST done and device ready */ rc = lpfc_sli4_post_status_check(phba); @@ -4939,6 +4863,11 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) phba->fc_map[1] = LPFC_FCOE_FCF_MAP1; phba->fc_map[2] = LPFC_FCOE_FCF_MAP2; + /* With BlockGuard we can have multiple SGEs per Data Segemnt */ + sges_per_segment = 1; + if (phba->cfg_enable_bg) + sges_per_segment = 2; + /* * For SLI4, instead of using ring 0 (LPFC_FCP_RING) for FCP commands * we will associate a new ring, for each FCP fastpath EQ/CQ/WQ tuple. @@ -4949,71 +4878,43 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) sizeof(struct lpfc_sli_ring), GFP_KERNEL); if (!phba->sli.ring) return -ENOMEM; - /* - * It doesn't matter what family our adapter is in, we are - * limited to 2 Pages, 512 SGEs, for our SGL. - * There are going to be 2 reserved SGEs: 1 FCP cmnd + 1 FCP rsp - */ - max_buf_size = (2 * SLI4_PAGE_SIZE); - if (phba->cfg_sg_seg_cnt > LPFC_MAX_SGL_SEG_CNT - 2) - phba->cfg_sg_seg_cnt = LPFC_MAX_SGL_SEG_CNT - 2; - - /* - * Since lpfc_sg_seg_cnt is module parameter, the sg_dma_buf_size + * Since the sg_tablesize is module parameter, the sg_dma_buf_size * used to create the sg_dma_buf_pool must be dynamically calculated. + * 2 segments are added since the IOCB needs a command and response bde. + * To insure that the scsi sgl does not cross a 4k page boundary only + * sgl sizes of must be a power of 2. */ - - if (phba->cfg_enable_bg) { - /* - * The scsi_buf for a T10-DIF I/O will hold the FCP cmnd, - * the FCP rsp, and a SGE for each. Sice we have no control - * over how many protection data segments the SCSI Layer - * will hand us (ie: there could be one for every block - * in the IO), we just allocate enough SGEs to accomidate - * our max amount and we need to limit lpfc_sg_seg_cnt to - * minimize the risk of running out. - */ - phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + - sizeof(struct fcp_rsp) + max_buf_size; - - /* Total SGEs for scsi_sg_list and scsi_sg_prot_list */ - phba->cfg_total_seg_cnt = LPFC_MAX_SGL_SEG_CNT; - - if (phba->cfg_sg_seg_cnt > LPFC_MAX_SG_SLI4_SEG_CNT_DIF) - phba->cfg_sg_seg_cnt = LPFC_MAX_SG_SLI4_SEG_CNT_DIF; - } else { - /* - * The scsi_buf for a regular I/O will hold the FCP cmnd, - * the FCP rsp, a SGE for each, and a SGE for up to - * cfg_sg_seg_cnt data segments. - */ - phba->cfg_sg_dma_buf_size = sizeof(struct fcp_cmnd) + - sizeof(struct fcp_rsp) + - ((phba->cfg_sg_seg_cnt + 2) * sizeof(struct sli4_sge)); - - /* Total SGEs for scsi_sg_list */ - phba->cfg_total_seg_cnt = phba->cfg_sg_seg_cnt + 2; - /* - * NOTE: if (phba->cfg_sg_seg_cnt + 2) <= 256 we only need - * to post 1 page for the SGL. - */ + buf_size = (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp) + + (((phba->cfg_sg_seg_cnt * sges_per_segment) + 2) * + sizeof(struct sli4_sge))); + + sli_family = bf_get(lpfc_sli_intf_sli_family, &phba->sli4_hba.sli_intf); + max_buf_size = LPFC_SLI4_MAX_BUF_SIZE; + switch (sli_family) { + case LPFC_SLI_INTF_FAMILY_BE2: + case LPFC_SLI_INTF_FAMILY_BE3: + /* There is a single hint for BE - 2 pages per BPL. */ + if (bf_get(lpfc_sli_intf_sli_hint1, &phba->sli4_hba.sli_intf) == + LPFC_SLI_INTF_SLI_HINT1_1) + max_buf_size = LPFC_SLI4_FL1_MAX_BUF_SIZE; + break; + case LPFC_SLI_INTF_FAMILY_LNCR_A0: + case LPFC_SLI_INTF_FAMILY_LNCR_B0: + default: + break; } - /* Initialize the host templates with the updated values. */ - lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt; - lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt; - - if (phba->cfg_sg_dma_buf_size <= LPFC_MIN_SG_SLI4_BUF_SZ) - phba->cfg_sg_dma_buf_size = LPFC_MIN_SG_SLI4_BUF_SZ; - else - phba->cfg_sg_dma_buf_size = - SLI4_PAGE_ALIGN(phba->cfg_sg_dma_buf_size); - - lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_FCP, - "9087 sg_tablesize:%d dmabuf_size:%d total_sge:%d\n", - phba->cfg_sg_seg_cnt, phba->cfg_sg_dma_buf_size, - phba->cfg_total_seg_cnt); + for (dma_buf_size = LPFC_SLI4_MIN_BUF_SIZE; + dma_buf_size < max_buf_size && buf_size > dma_buf_size; + dma_buf_size = dma_buf_size << 1) + ; + if (dma_buf_size == max_buf_size) + phba->cfg_sg_seg_cnt = (dma_buf_size - + sizeof(struct fcp_cmnd) - sizeof(struct fcp_rsp) - + (2 * sizeof(struct sli4_sge))) / + sizeof(struct sli4_sge); + phba->cfg_sg_dma_buf_size = dma_buf_size; /* Initialize buffer queue management fields */ hbq_count = lpfc_sli_hbq_count(); @@ -5203,26 +5104,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) goto out_free_fcp_eq_hdl; } - phba->sli4_hba.cpu_map = kzalloc((sizeof(struct lpfc_vector_map_info) * - phba->sli4_hba.num_present_cpu), - GFP_KERNEL); - if (!phba->sli4_hba.cpu_map) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "3327 Failed allocate memory for msi-x " - "interrupt vector mapping\n"); - rc = -ENOMEM; - goto out_free_msix; - } - /* Initialize io channels for round robin */ - cpup = phba->sli4_hba.cpu_map; - rc = 0; - for (i = 0; i < phba->sli4_hba.num_present_cpu; i++) { - cpup->channel_id = rc; - rc++; - if (rc >= phba->cfg_fcp_io_channel) - rc = 0; - } - /* * Enable sr-iov virtual functions if supported and configured * through the module parameter. @@ -5242,8 +5123,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) return 0; -out_free_msix: - kfree(phba->sli4_hba.msix_entries); out_free_fcp_eq_hdl: kfree(phba->sli4_hba.fcp_eq_hdl); out_free_fcf_rr_bmask: @@ -5273,11 +5152,6 @@ lpfc_sli4_driver_resource_unset(struct lpfc_hba *phba) { struct lpfc_fcf_conn_entry *conn_entry, *next_conn_entry; - /* Free memory allocated for msi-x interrupt vector to CPU mapping */ - kfree(phba->sli4_hba.cpu_map); - phba->sli4_hba.num_present_cpu = 0; - phba->sli4_hba.num_online_cpu = 0; - /* Free memory allocated for msi-x interrupt vector entries */ kfree(phba->sli4_hba.msix_entries); @@ -5386,10 +5260,8 @@ lpfc_setup_driver_resource_phase1(struct lpfc_hba *phba) init_waitqueue_head(&phba->work_waitq); /* Initialize the scsi buffer list used by driver for scsi IO */ - spin_lock_init(&phba->scsi_buf_list_get_lock); - INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list_get); - spin_lock_init(&phba->scsi_buf_list_put_lock); - INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list_put); + spin_lock_init(&phba->scsi_buf_list_lock); + INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list); /* Initialize the fabric iocb list */ INIT_LIST_HEAD(&phba->fabric_iocb_list); @@ -6824,7 +6696,6 @@ lpfc_sli4_queue_verify(struct lpfc_hba *phba) int cfg_fcp_io_channel; uint32_t cpu; uint32_t i = 0; - uint32_t j = 0; /* @@ -6835,21 +6706,15 @@ lpfc_sli4_queue_verify(struct lpfc_hba *phba) /* Sanity check on HBA EQ parameters */ cfg_fcp_io_channel = phba->cfg_fcp_io_channel; - /* It doesn't make sense to have more io channels then online CPUs */ - for_each_present_cpu(cpu) { - if (cpu_online(cpu)) - i++; - j++; + /* It doesn't make sense to have more io channels then CPUs */ + for_each_online_cpu(cpu) { + i++; } - phba->sli4_hba.num_online_cpu = i; - phba->sli4_hba.num_present_cpu = j; - if (i < cfg_fcp_io_channel) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "3188 Reducing IO channels to match number of " - "online CPUs: from %d to %d\n", - cfg_fcp_io_channel, i); + "CPUs: from %d to %d\n", cfg_fcp_io_channel, i); cfg_fcp_io_channel = i; } @@ -7878,13 +7743,8 @@ lpfc_pci_function_reset(struct lpfc_hba *phba) out: /* Catch the not-ready port failure after a port reset. */ - if (num_resets >= MAX_IF_TYPE_2_RESETS) { - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "3317 HBA not functional: IP Reset Failed " - "after (%d) retries, try: " - "echo fw_reset > board_mode\n", num_resets); + if (num_resets >= MAX_IF_TYPE_2_RESETS) rc = -ENODEV; - } return rc; } @@ -8348,269 +8208,6 @@ lpfc_sli_disable_intr(struct lpfc_hba *phba) return; } -/** - * lpfc_find_next_cpu - Find next available CPU that matches the phys_id - * @phba: pointer to lpfc hba data structure. - * - * Find next available CPU to use for IRQ to CPU affinity. - */ -static int -lpfc_find_next_cpu(struct lpfc_hba *phba, uint32_t phys_id) -{ - struct lpfc_vector_map_info *cpup; - int cpu; - - cpup = phba->sli4_hba.cpu_map; - for (cpu = 0; cpu < phba->sli4_hba.num_present_cpu; cpu++) { - /* CPU must be online */ - if (cpu_online(cpu)) { - if ((cpup->irq == LPFC_VECTOR_MAP_EMPTY) && - (lpfc_used_cpu[cpu] == LPFC_VECTOR_MAP_EMPTY) && - (cpup->phys_id == phys_id)) { - return cpu; - } - } - cpup++; - } - - /* - * If we get here, we have used ALL CPUs for the specific - * phys_id. Now we need to clear out lpfc_used_cpu and start - * reusing CPUs. - */ - - for (cpu = 0; cpu < phba->sli4_hba.num_present_cpu; cpu++) { - if (lpfc_used_cpu[cpu] == phys_id) - lpfc_used_cpu[cpu] = LPFC_VECTOR_MAP_EMPTY; - } - - cpup = phba->sli4_hba.cpu_map; - for (cpu = 0; cpu < phba->sli4_hba.num_present_cpu; cpu++) { - /* CPU must be online */ - if (cpu_online(cpu)) { - if ((cpup->irq == LPFC_VECTOR_MAP_EMPTY) && - (cpup->phys_id == phys_id)) { - return cpu; - } - } - cpup++; - } - return LPFC_VECTOR_MAP_EMPTY; -} - -/** - * lpfc_sli4_set_affinity - Set affinity for HBA IRQ vectors - * @phba: pointer to lpfc hba data structure. - * @vectors: number of HBA vectors - * - * Affinitize MSIX IRQ vectors to CPUs. Try to equally spread vector - * affinization across multple physical CPUs (numa nodes). - * In addition, this routine will assign an IO channel for each CPU - * to use when issuing I/Os. - */ -static int -lpfc_sli4_set_affinity(struct lpfc_hba *phba, int vectors) -{ - int i, idx, saved_chann, used_chann, cpu, phys_id; - int max_phys_id, num_io_channel, first_cpu; - struct lpfc_vector_map_info *cpup; -#ifdef CONFIG_X86 - struct cpuinfo_x86 *cpuinfo; -#endif - struct cpumask *mask; - uint8_t chann[LPFC_FCP_IO_CHAN_MAX+1]; - - /* If there is no mapping, just return */ - if (!phba->cfg_fcp_cpu_map) - return 1; - - /* Init cpu_map array */ - memset(phba->sli4_hba.cpu_map, 0xff, - (sizeof(struct lpfc_vector_map_info) * - phba->sli4_hba.num_present_cpu)); - - max_phys_id = 0; - phys_id = 0; - num_io_channel = 0; - first_cpu = LPFC_VECTOR_MAP_EMPTY; - - /* Update CPU map with physical id and core id of each CPU */ - cpup = phba->sli4_hba.cpu_map; - for (cpu = 0; cpu < phba->sli4_hba.num_present_cpu; cpu++) { -#ifdef CONFIG_X86 - cpuinfo = &cpu_data(cpu); - cpup->phys_id = cpuinfo->phys_proc_id; - cpup->core_id = cpuinfo->cpu_core_id; -#else - /* No distinction between CPUs for other platforms */ - cpup->phys_id = 0; - cpup->core_id = 0; -#endif - - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "3328 CPU physid %d coreid %d\n", - cpup->phys_id, cpup->core_id); - - if (cpup->phys_id > max_phys_id) - max_phys_id = cpup->phys_id; - cpup++; - } - - /* Now associate the HBA vectors with specific CPUs */ - for (idx = 0; idx < vectors; idx++) { - cpup = phba->sli4_hba.cpu_map; - cpu = lpfc_find_next_cpu(phba, phys_id); - if (cpu == LPFC_VECTOR_MAP_EMPTY) { - - /* Try for all phys_id's */ - for (i = 1; i < max_phys_id; i++) { - phys_id++; - if (phys_id > max_phys_id) - phys_id = 0; - cpu = lpfc_find_next_cpu(phba, phys_id); - if (cpu == LPFC_VECTOR_MAP_EMPTY) - continue; - goto found; - } - - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "3329 Cannot set affinity:" - "Error mapping vector %d (%d)\n", - idx, vectors); - return 0; - } -found: - cpup += cpu; - if (phba->cfg_fcp_cpu_map == LPFC_DRIVER_CPU_MAP) - lpfc_used_cpu[cpu] = phys_id; - - /* Associate vector with selected CPU */ - cpup->irq = phba->sli4_hba.msix_entries[idx].vector; - - /* Associate IO channel with selected CPU */ - cpup->channel_id = idx; - num_io_channel++; - - if (first_cpu == LPFC_VECTOR_MAP_EMPTY) - first_cpu = cpu; - - /* Now affinitize to the selected CPU */ - mask = &cpup->maskbits; - cpumask_clear(mask); - cpumask_set_cpu(cpu, mask); - i = irq_set_affinity_hint(phba->sli4_hba.msix_entries[idx]. - vector, mask); - - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "3330 Set Affinity: CPU %d channel %d " - "irq %d (%x)\n", - cpu, cpup->channel_id, - phba->sli4_hba.msix_entries[idx].vector, i); - - /* Spread vector mapping across multple physical CPU nodes */ - phys_id++; - if (phys_id > max_phys_id) - phys_id = 0; - } - - /* - * Finally fill in the IO channel for any remaining CPUs. - * At this point, all IO channels have been assigned to a specific - * MSIx vector, mapped to a specific CPU. - * Base the remaining IO channel assigned, to IO channels already - * assigned to other CPUs on the same phys_id. - */ - for (i = 0; i <= max_phys_id; i++) { - /* - * If there are no io channels already mapped to - * this phys_id, just round robin thru the io_channels. - * Setup chann[] for round robin. - */ - for (idx = 0; idx < phba->cfg_fcp_io_channel; idx++) - chann[idx] = idx; - - saved_chann = 0; - used_chann = 0; - - /* - * First build a list of IO channels already assigned - * to this phys_id before reassigning the same IO - * channels to the remaining CPUs. - */ - cpup = phba->sli4_hba.cpu_map; - cpu = first_cpu; - cpup += cpu; - for (idx = 0; idx < phba->sli4_hba.num_present_cpu; - idx++) { - if (cpup->phys_id == i) { - /* - * Save any IO channels that are - * already mapped to this phys_id. - */ - if (cpup->irq != LPFC_VECTOR_MAP_EMPTY) { - chann[saved_chann] = - cpup->channel_id; - saved_chann++; - goto out; - } - - /* See if we are using round-robin */ - if (saved_chann == 0) - saved_chann = - phba->cfg_fcp_io_channel; - - /* Associate next IO channel with CPU */ - cpup->channel_id = chann[used_chann]; - num_io_channel++; - used_chann++; - if (used_chann == saved_chann) - used_chann = 0; - - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "3331 Set IO_CHANN " - "CPU %d channel %d\n", - idx, cpup->channel_id); - } -out: - cpu++; - if (cpu >= phba->sli4_hba.num_present_cpu) { - cpup = phba->sli4_hba.cpu_map; - cpu = 0; - } else { - cpup++; - } - } - } - - if (phba->sli4_hba.num_online_cpu != phba->sli4_hba.num_present_cpu) { - cpup = phba->sli4_hba.cpu_map; - for (idx = 0; idx < phba->sli4_hba.num_present_cpu; idx++) { - if (cpup->channel_id == LPFC_VECTOR_MAP_EMPTY) { - cpup->channel_id = 0; - num_io_channel++; - - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "3332 Assign IO_CHANN " - "CPU %d channel %d\n", - idx, cpup->channel_id); - } - cpup++; - } - } - - /* Sanity check */ - if (num_io_channel != phba->sli4_hba.num_present_cpu) - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "3333 Set affinity mismatch:" - "%d chann != %d cpus: %d vactors\n", - num_io_channel, phba->sli4_hba.num_present_cpu, - vectors); - - phba->cfg_fcp_io_sched = LPFC_FCP_SCHED_BY_CPU; - return 1; -} - - /** * lpfc_sli4_enable_msix - Enable MSI-X interrupt mode to SLI-4 device * @phba: pointer to lpfc hba data structure. @@ -8662,7 +8259,9 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba) phba->sli4_hba.msix_entries[index].vector, phba->sli4_hba.msix_entries[index].entry); - /* Assign MSI-X vectors to interrupt handlers */ + /* + * Assign MSI-X vectors to interrupt handlers + */ for (index = 0; index < vectors; index++) { memset(&phba->sli4_hba.handler_name[index], 0, 16); sprintf((char *)&phba->sli4_hba.handler_name[index], @@ -8690,8 +8289,6 @@ lpfc_sli4_enable_msix(struct lpfc_hba *phba) phba->cfg_fcp_io_channel, vectors); phba->cfg_fcp_io_channel = vectors; } - - lpfc_sli4_set_affinity(phba, vectors); return rc; cfg_fail_out: @@ -9616,15 +9213,15 @@ lpfc_sli_prep_dev_for_reset(struct lpfc_hba *phba) /* Block all SCSI devices' I/Os on the host */ lpfc_scsi_dev_block(phba); - /* Flush all driver's outstanding SCSI I/Os as we are to reset */ - lpfc_sli_flush_fcp_rings(phba); - /* stop all timers */ lpfc_stop_hba_timers(phba); /* Disable interrupt and pci device */ lpfc_sli_disable_intr(phba); pci_disable_device(phba->pcidev); + + /* Flush all driver's outstanding SCSI I/Os as we are to reset */ + lpfc_sli_flush_fcp_rings(phba); } /** @@ -10369,9 +9966,6 @@ lpfc_sli4_prep_dev_for_reset(struct lpfc_hba *phba) /* Block all SCSI devices' I/Os on the host */ lpfc_scsi_dev_block(phba); - /* Flush all driver's outstanding SCSI I/Os as we are to reset */ - lpfc_sli_flush_fcp_rings(phba); - /* stop all timers */ lpfc_stop_hba_timers(phba); @@ -10379,6 +9973,9 @@ lpfc_sli4_prep_dev_for_reset(struct lpfc_hba *phba) lpfc_sli4_disable_intr(phba); lpfc_sli4_queue_destroy(phba); pci_disable_device(phba->pcidev); + + /* Flush all driver's outstanding SCSI I/Os as we are to reset */ + lpfc_sli_flush_fcp_rings(phba); } /** @@ -10938,7 +10535,6 @@ static struct miscdevice lpfc_mgmt_dev = { static int __init lpfc_init(void) { - int cpu; int error = 0; printk(LPFC_MODULE_DESC "\n"); @@ -10965,11 +10561,6 @@ lpfc_init(void) return -ENOMEM; } } - - /* Initialize in case vector mapping is needed */ - for (cpu = 0; cpu < LPFC_MAX_CPU; cpu++) - lpfc_used_cpu[cpu] = LPFC_VECTOR_MAP_EMPTY; - error = pci_register_driver(&lpfc_driver); if (error) { fc_release_transport(lpfc_transport_template); diff --git a/trunk/drivers/scsi/lpfc/lpfc_logmsg.h b/trunk/drivers/scsi/lpfc/lpfc_logmsg.h index 2a4e5d21eab2..baf53e6c2bd1 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_logmsg.h +++ b/trunk/drivers/scsi/lpfc/lpfc_logmsg.h @@ -37,7 +37,6 @@ #define LOG_EVENT 0x00010000 /* CT,TEMP,DUMP, logging */ #define LOG_FIP 0x00020000 /* FIP events */ #define LOG_FCP_UNDER 0x00040000 /* FCP underruns errors */ -#define LOG_SCSI_CMD 0x00080000 /* ALL SCSI commands */ #define LOG_ALL_MSG 0xffffffff /* LOG all messages */ #define lpfc_printf_vlog(vport, level, mask, fmt, arg...) \ diff --git a/trunk/drivers/scsi/lpfc/lpfc_mbox.c b/trunk/drivers/scsi/lpfc/lpfc_mbox.c index 41363db7d426..a7a9fa468308 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_mbox.c +++ b/trunk/drivers/scsi/lpfc/lpfc_mbox.c @@ -2149,21 +2149,18 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys) /* Only FC supports upd bit */ if ((phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC) && - (vport->fc_flag & FC_VFI_REGISTERED) && - (!phba->fc_topology_changed)) { + (vport->fc_flag & FC_VFI_REGISTERED)) { bf_set(lpfc_reg_vfi_vp, reg_vfi, 0); bf_set(lpfc_reg_vfi_upd, reg_vfi, 1); } lpfc_printf_vlog(vport, KERN_INFO, LOG_MBOX, "3134 Register VFI, mydid:x%x, fcfi:%d, " - " vfi:%d, vpi:%d, fc_pname:%x%x fc_flag:x%x" - " port_state:x%x topology chg:%d\n", + " vfi:%d, vpi:%d, fc_pname:%x%x\n", vport->fc_myDID, phba->fcf.fcfi, phba->sli4_hba.vfi_ids[vport->vfi], phba->vpi_ids[vport->vpi], - reg_vfi->wwn[0], reg_vfi->wwn[1], vport->fc_flag, - vport->port_state, phba->fc_topology_changed); + reg_vfi->wwn[0], reg_vfi->wwn[1]); } /** diff --git a/trunk/drivers/scsi/lpfc/lpfc_mem.c b/trunk/drivers/scsi/lpfc/lpfc_mem.c index 812d0cd7c86d..cd86069a0ba8 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_mem.c +++ b/trunk/drivers/scsi/lpfc/lpfc_mem.c @@ -64,26 +64,18 @@ lpfc_mem_alloc(struct lpfc_hba *phba, int align) struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool; int i; - if (phba->sli_rev == LPFC_SLI_REV4) { - /* Calculate alignment */ - if (phba->cfg_sg_dma_buf_size < SLI4_PAGE_SIZE) - i = phba->cfg_sg_dma_buf_size; - else - i = SLI4_PAGE_SIZE; - + if (phba->sli_rev == LPFC_SLI_REV4) phba->lpfc_scsi_dma_buf_pool = pci_pool_create("lpfc_scsi_dma_buf_pool", phba->pcidev, phba->cfg_sg_dma_buf_size, - i, + phba->cfg_sg_dma_buf_size, 0); - } else { + else phba->lpfc_scsi_dma_buf_pool = pci_pool_create("lpfc_scsi_dma_buf_pool", phba->pcidev, phba->cfg_sg_dma_buf_size, align, 0); - } - if (!phba->lpfc_scsi_dma_buf_pool) goto fail; diff --git a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c index 31e9b92f5a9b..82f4d3542289 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -332,11 +332,9 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, /* PLOGI chkparm OK */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, - "0114 PLOGI chkparm OK Data: x%x x%x x%x " - "x%x x%x x%x\n", + "0114 PLOGI chkparm OK Data: x%x x%x x%x x%x\n", ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag, - ndlp->nlp_rpi, vport->port_state, - vport->fc_flag); + ndlp->nlp_rpi); if (vport->cfg_fcp_class == 2 && sp->cls2.classValid) ndlp->nlp_fcp_info |= CLASS2; @@ -576,7 +574,7 @@ lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL); /* 1 sec timeout */ - mod_timer(&ndlp->nlp_delayfunc, jiffies + msecs_to_jiffies(1000)); + mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_DELAY_TMO; @@ -633,8 +631,7 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, * If there are other active VLinks present, * re-instantiate the Vlink using FDISC. */ - mod_timer(&ndlp->nlp_delayfunc, - jiffies + msecs_to_jiffies(1000)); + mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_DELAY_TMO; spin_unlock_irq(shost->host_lock); @@ -651,8 +648,7 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, !(ndlp->nlp_type & NLP_FCP_INITIATOR))) || (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { /* Only try to re-login if this is NOT a Fabric Node */ - mod_timer(&ndlp->nlp_delayfunc, - jiffies + msecs_to_jiffies(1000 * 1)); + mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_DELAY_TMO; spin_unlock_irq(shost->host_lock); @@ -973,7 +969,7 @@ lpfc_rcv_els_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, } /* Put ndlp in npr state set plogi timer for 1 sec */ - mod_timer(&ndlp->nlp_delayfunc, jiffies + msecs_to_jiffies(1000 * 1)); + mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_DELAY_TMO; spin_unlock_irq(shost->host_lock); @@ -1307,8 +1303,7 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport, if ((irsp->ulpStatus) || (!lpfc_check_adisc(vport, ndlp, &ap->nodeName, &ap->portName))) { /* 1 sec timeout */ - mod_timer(&ndlp->nlp_delayfunc, - jiffies + msecs_to_jiffies(1000)); + mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_DELAY_TMO; spin_unlock_irq(shost->host_lock); @@ -1514,8 +1509,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, } /* Put ndlp in npr state set plogi timer for 1 sec */ - mod_timer(&ndlp->nlp_delayfunc, - jiffies + msecs_to_jiffies(1000 * 1)); + mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_DELAY_TMO; spin_unlock_irq(shost->host_lock); @@ -2151,8 +2145,7 @@ lpfc_rcv_prlo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); if ((ndlp->nlp_flag & NLP_DELAY_TMO) == 0) { - mod_timer(&ndlp->nlp_delayfunc, - jiffies + msecs_to_jiffies(1000 * 1)); + mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_DELAY_TMO; ndlp->nlp_flag &= ~NLP_NPR_ADISC; diff --git a/trunk/drivers/scsi/lpfc/lpfc_scsi.c b/trunk/drivers/scsi/lpfc/lpfc_scsi.c index 8523b278ec9d..74b8710e1e90 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_scsi.c +++ b/trunk/drivers/scsi/lpfc/lpfc_scsi.c @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include #include @@ -50,7 +48,7 @@ #define LPFC_RESET_WAIT 2 #define LPFC_ABORT_WAIT 2 -int _dump_buf_done = 1; +int _dump_buf_done; static char *dif_op_str[] = { "PROT_NORMAL", @@ -68,10 +66,6 @@ struct scsi_dif_tuple { __be32 ref_tag; /* Target LBA or indirect LBA */ }; -#if !defined(SCSI_PROT_GUARD_CHECK) || !defined(SCSI_PROT_REF_CHECK) -#define scsi_prot_flagged(sc, flg) sc -#endif - static void lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb); static void @@ -540,16 +534,7 @@ lpfc_new_scsi_buf_s3(struct lpfc_vport *vport, int num_to_alloc) dma_addr_t pdma_phys_fcp_rsp; dma_addr_t pdma_phys_bpl; uint16_t iotag; - int bcnt, bpl_size; - - bpl_size = phba->cfg_sg_dma_buf_size - - (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp)); - - lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, - "9067 ALLOC %d scsi_bufs: %d (%d + %d + %d)\n", - num_to_alloc, phba->cfg_sg_dma_buf_size, - (int)sizeof(struct fcp_cmnd), - (int)sizeof(struct fcp_rsp), bpl_size); + int bcnt; for (bcnt = 0; bcnt < num_to_alloc; bcnt++) { psb = kzalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); @@ -774,7 +759,7 @@ lpfc_sli4_post_scsi_sgl_list(struct lpfc_hba *phba, struct list_head *post_sblist, int sb_count) { struct lpfc_scsi_buf *psb, *psb_next; - int status, sgl_size; + int status; int post_cnt = 0, block_cnt = 0, num_posting = 0, num_posted = 0; dma_addr_t pdma_phys_bpl1; int last_xritag = NO_XRI; @@ -786,9 +771,6 @@ lpfc_sli4_post_scsi_sgl_list(struct lpfc_hba *phba, if (sb_count <= 0) return -EINVAL; - sgl_size = phba->cfg_sg_dma_buf_size - - (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp)); - list_for_each_entry_safe(psb, psb_next, post_sblist, list) { list_del_init(&psb->list); block_cnt++; @@ -821,7 +803,7 @@ lpfc_sli4_post_scsi_sgl_list(struct lpfc_hba *phba, post_cnt = block_cnt; } else if (block_cnt == 1) { /* last single sgl with non-contiguous xri */ - if (sgl_size > SGL_PAGE_SIZE) + if (phba->cfg_sg_dma_buf_size > SGL_PAGE_SIZE) pdma_phys_bpl1 = psb->dma_phys_bpl + SGL_PAGE_SIZE; else @@ -903,12 +885,9 @@ lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *phba) int num_posted, rc = 0; /* get all SCSI buffers need to repost to a local list */ - spin_lock_irq(&phba->scsi_buf_list_get_lock); - spin_lock_irq(&phba->scsi_buf_list_put_lock); - list_splice_init(&phba->lpfc_scsi_buf_list_get, &post_sblist); - list_splice(&phba->lpfc_scsi_buf_list_put, &post_sblist); - spin_unlock_irq(&phba->scsi_buf_list_put_lock); - spin_unlock_irq(&phba->scsi_buf_list_get_lock); + spin_lock_irq(&phba->scsi_buf_list_lock); + list_splice_init(&phba->lpfc_scsi_buf_list, &post_sblist); + spin_unlock_irq(&phba->scsi_buf_list_lock); /* post the list of scsi buffer sgls to port if available */ if (!list_empty(&post_sblist)) { @@ -944,22 +923,13 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) IOCB_t *iocb; dma_addr_t pdma_phys_fcp_cmd; dma_addr_t pdma_phys_fcp_rsp; - dma_addr_t pdma_phys_bpl; + dma_addr_t pdma_phys_bpl, pdma_phys_bpl1; uint16_t iotag, lxri = 0; - int bcnt, num_posted, sgl_size; + int bcnt, num_posted; LIST_HEAD(prep_sblist); LIST_HEAD(post_sblist); LIST_HEAD(scsi_sblist); - sgl_size = phba->cfg_sg_dma_buf_size - - (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp)); - - lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, - "9068 ALLOC %d scsi_bufs: %d (%d + %d + %d)\n", - num_to_alloc, phba->cfg_sg_dma_buf_size, sgl_size, - (int)sizeof(struct fcp_cmnd), - (int)sizeof(struct fcp_rsp)); - for (bcnt = 0; bcnt < num_to_alloc; bcnt++) { psb = kzalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); if (!psb) @@ -978,15 +948,6 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) } memset(psb->data, 0, phba->cfg_sg_dma_buf_size); - /* Page alignment is CRITICAL, double check to be sure */ - if (((unsigned long)(psb->data) & - (unsigned long)(SLI4_PAGE_SIZE - 1)) != 0) { - pci_pool_free(phba->lpfc_scsi_dma_buf_pool, - psb->data, psb->dma_handle); - kfree(psb); - break; - } - /* Allocate iotag for psb->cur_iocbq. */ iotag = lpfc_sli_next_iotag(phba, &psb->cur_iocbq); if (iotag == 0) { @@ -1007,14 +968,17 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) psb->cur_iocbq.sli4_xritag = phba->sli4_hba.xri_ids[lxri]; psb->cur_iocbq.iocb_flag |= LPFC_IO_FCP; psb->fcp_bpl = psb->data; - psb->fcp_cmnd = (psb->data + sgl_size); + psb->fcp_cmnd = (psb->data + phba->cfg_sg_dma_buf_size) + - (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp)); psb->fcp_rsp = (struct fcp_rsp *)((uint8_t *)psb->fcp_cmnd + sizeof(struct fcp_cmnd)); /* Initialize local short-hand pointers. */ sgl = (struct sli4_sge *)psb->fcp_bpl; pdma_phys_bpl = psb->dma_handle; - pdma_phys_fcp_cmd = (psb->dma_handle + sgl_size); + pdma_phys_fcp_cmd = + (psb->dma_handle + phba->cfg_sg_dma_buf_size) + - (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp)); pdma_phys_fcp_rsp = pdma_phys_fcp_cmd + sizeof(struct fcp_cmnd); /* @@ -1056,13 +1020,17 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) iocb->ulpLe = 1; iocb->ulpClass = CLASS3; psb->cur_iocbq.context1 = psb; + if (phba->cfg_sg_dma_buf_size > SGL_PAGE_SIZE) + pdma_phys_bpl1 = pdma_phys_bpl + SGL_PAGE_SIZE; + else + pdma_phys_bpl1 = 0; psb->dma_phys_bpl = pdma_phys_bpl; /* add the scsi buffer to a post list */ list_add_tail(&psb->list, &post_sblist); - spin_lock_irq(&phba->scsi_buf_list_get_lock); + spin_lock_irq(&phba->scsi_buf_list_lock); phba->sli4_hba.scsi_xri_cnt++; - spin_unlock_irq(&phba->scsi_buf_list_get_lock); + spin_unlock_irq(&phba->scsi_buf_list_lock); } lpfc_printf_log(phba, KERN_INFO, LOG_BG, "3021 Allocate %d out of %d requested new SCSI " @@ -1111,23 +1079,17 @@ static struct lpfc_scsi_buf* lpfc_get_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) { struct lpfc_scsi_buf * lpfc_cmd = NULL; - struct list_head *scsi_buf_list_get = &phba->lpfc_scsi_buf_list_get; - unsigned long gflag = 0; - unsigned long pflag = 0; - - spin_lock_irqsave(&phba->scsi_buf_list_get_lock, gflag); - list_remove_head(scsi_buf_list_get, lpfc_cmd, struct lpfc_scsi_buf, - list); - if (!lpfc_cmd) { - spin_lock_irqsave(&phba->scsi_buf_list_put_lock, pflag); - list_splice(&phba->lpfc_scsi_buf_list_put, - &phba->lpfc_scsi_buf_list_get); - INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list_put); - list_remove_head(scsi_buf_list_get, lpfc_cmd, - struct lpfc_scsi_buf, list); - spin_unlock_irqrestore(&phba->scsi_buf_list_put_lock, pflag); + struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list; + unsigned long iflag = 0; + + spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); + list_remove_head(scsi_buf_list, lpfc_cmd, struct lpfc_scsi_buf, list); + if (lpfc_cmd) { + lpfc_cmd->seg_cnt = 0; + lpfc_cmd->nonsg_phys = 0; + lpfc_cmd->prot_seg_cnt = 0; } - spin_unlock_irqrestore(&phba->scsi_buf_list_get_lock, gflag); + spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag); return lpfc_cmd; } /** @@ -1145,39 +1107,28 @@ static struct lpfc_scsi_buf* lpfc_get_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) { struct lpfc_scsi_buf *lpfc_cmd ; - unsigned long gflag = 0; - unsigned long pflag = 0; + unsigned long iflag = 0; int found = 0; - spin_lock_irqsave(&phba->scsi_buf_list_get_lock, gflag); - list_for_each_entry(lpfc_cmd, &phba->lpfc_scsi_buf_list_get, list) { + spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); + list_for_each_entry(lpfc_cmd, &phba->lpfc_scsi_buf_list, + list) { if (lpfc_test_rrq_active(phba, ndlp, lpfc_cmd->cur_iocbq.sli4_lxritag)) continue; list_del(&lpfc_cmd->list); found = 1; + lpfc_cmd->seg_cnt = 0; + lpfc_cmd->nonsg_phys = 0; + lpfc_cmd->prot_seg_cnt = 0; break; } - if (!found) { - spin_lock_irqsave(&phba->scsi_buf_list_put_lock, pflag); - list_splice(&phba->lpfc_scsi_buf_list_put, - &phba->lpfc_scsi_buf_list_get); - INIT_LIST_HEAD(&phba->lpfc_scsi_buf_list_put); - spin_unlock_irqrestore(&phba->scsi_buf_list_put_lock, pflag); - list_for_each_entry(lpfc_cmd, &phba->lpfc_scsi_buf_list_get, - list) { - if (lpfc_test_rrq_active( - phba, ndlp, lpfc_cmd->cur_iocbq.sli4_lxritag)) - continue; - list_del(&lpfc_cmd->list); - found = 1; - break; - } - } - spin_unlock_irqrestore(&phba->scsi_buf_list_get_lock, gflag); + spin_unlock_irqrestore(&phba->scsi_buf_list_lock, + iflag); if (!found) return NULL; - return lpfc_cmd; + else + return lpfc_cmd; } /** * lpfc_get_scsi_buf - Get a scsi buffer from lpfc_scsi_buf_list of the HBA @@ -1209,15 +1160,10 @@ lpfc_release_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb) { unsigned long iflag = 0; - psb->seg_cnt = 0; - psb->nonsg_phys = 0; - psb->prot_seg_cnt = 0; - - spin_lock_irqsave(&phba->scsi_buf_list_put_lock, iflag); + spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); psb->pCmd = NULL; - psb->cur_iocbq.iocb_flag = LPFC_IO_FCP; - list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list_put); - spin_unlock_irqrestore(&phba->scsi_buf_list_put_lock, iflag); + list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list); + spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag); } /** @@ -1235,10 +1181,6 @@ lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb) { unsigned long iflag = 0; - psb->seg_cnt = 0; - psb->nonsg_phys = 0; - psb->prot_seg_cnt = 0; - if (psb->exch_busy) { spin_lock_irqsave(&phba->sli4_hba.abts_scsi_buf_list_lock, iflag); @@ -1248,11 +1190,11 @@ lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb) spin_unlock_irqrestore(&phba->sli4_hba.abts_scsi_buf_list_lock, iflag); } else { + + spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); psb->pCmd = NULL; - psb->cur_iocbq.iocb_flag = LPFC_IO_FCP; - spin_lock_irqsave(&phba->scsi_buf_list_put_lock, iflag); - list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list_put); - spin_unlock_irqrestore(&phba->scsi_buf_list_put_lock, iflag); + list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list); + spin_unlock_irqrestore(&phba->scsi_buf_list_lock, iflag); } } @@ -1326,7 +1268,6 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) "dma_map_sg. Config %d, seg_cnt %d\n", __func__, phba->cfg_sg_seg_cnt, lpfc_cmd->seg_cnt); - lpfc_cmd->seg_cnt = 0; scsi_dma_unmap(scsi_cmnd); return 1; } @@ -2072,21 +2013,9 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, bf_set(pde6_type, pde6, LPFC_PDE6_DESCRIPTOR); bf_set(pde6_optx, pde6, txop); bf_set(pde6_oprx, pde6, rxop); - - /* - * We only need to check the data on READs, for WRITEs - * protection data is automatically generated, not checked. - */ if (datadir == DMA_FROM_DEVICE) { - if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK)) - bf_set(pde6_ce, pde6, checking); - else - bf_set(pde6_ce, pde6, 0); - - if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK)) - bf_set(pde6_re, pde6, checking); - else - bf_set(pde6_re, pde6, 0); + bf_set(pde6_ce, pde6, checking); + bf_set(pde6_re, pde6, checking); } bf_set(pde6_ai, pde6, 1); bf_set(pde6_ae, pde6, 0); @@ -2216,10 +2145,6 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, split_offset = 0; do { - /* Check to see if we ran out of space */ - if (num_bde >= (phba->cfg_total_seg_cnt - 2)) - return num_bde + 3; - /* setup PDE5 with what we have */ pde5 = (struct lpfc_pde5 *) bpl; memset(pde5, 0, sizeof(struct lpfc_pde5)); @@ -2239,17 +2164,8 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, bf_set(pde6_type, pde6, LPFC_PDE6_DESCRIPTOR); bf_set(pde6_optx, pde6, txop); bf_set(pde6_oprx, pde6, rxop); - - if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK)) - bf_set(pde6_ce, pde6, checking); - else - bf_set(pde6_ce, pde6, 0); - - if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK)) - bf_set(pde6_re, pde6, checking); - else - bf_set(pde6_re, pde6, 0); - + bf_set(pde6_ce, pde6, checking); + bf_set(pde6_re, pde6, checking); bf_set(pde6_ai, pde6, 1); bf_set(pde6_ae, pde6, 0); bf_set(pde6_apptagval, pde6, 0); @@ -2297,10 +2213,6 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, pgdone = 0; subtotal = 0; /* total bytes processed for current prot grp */ while (!pgdone) { - /* Check to see if we ran out of space */ - if (num_bde >= phba->cfg_total_seg_cnt) - return num_bde + 1; - if (!sgde) { lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9065 BLKGRD:%s Invalid data segment\n", @@ -2412,6 +2324,7 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, struct sli4_sge_diseed *diseed = NULL; dma_addr_t physaddr; int i = 0, num_sge = 0, status; + int datadir = sc->sc_data_direction; uint32_t reftag; unsigned blksize; uint8_t txop, rxop; @@ -2449,26 +2362,13 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, diseed->ref_tag = cpu_to_le32(reftag); diseed->ref_tag_tran = diseed->ref_tag; - /* - * We only need to check the data on READs, for WRITEs - * protection data is automatically generated, not checked. - */ - if (sc->sc_data_direction == DMA_FROM_DEVICE) { - if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK)) - bf_set(lpfc_sli4_sge_dif_ce, diseed, checking); - else - bf_set(lpfc_sli4_sge_dif_ce, diseed, 0); - - if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK)) - bf_set(lpfc_sli4_sge_dif_re, diseed, checking); - else - bf_set(lpfc_sli4_sge_dif_re, diseed, 0); - } - /* setup DISEED with the rest of the info */ bf_set(lpfc_sli4_sge_dif_optx, diseed, txop); bf_set(lpfc_sli4_sge_dif_oprx, diseed, rxop); - + if (datadir == DMA_FROM_DEVICE) { + bf_set(lpfc_sli4_sge_dif_ce, diseed, checking); + bf_set(lpfc_sli4_sge_dif_re, diseed, checking); + } bf_set(lpfc_sli4_sge_dif_ai, diseed, 1); bf_set(lpfc_sli4_sge_dif_me, diseed, 0); @@ -2597,10 +2497,6 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, split_offset = 0; do { - /* Check to see if we ran out of space */ - if (num_sge >= (phba->cfg_total_seg_cnt - 2)) - return num_sge + 3; - /* setup DISEED with what we have */ diseed = (struct sli4_sge_diseed *) sgl; memset(diseed, 0, sizeof(struct sli4_sge_diseed)); @@ -2610,34 +2506,11 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, diseed->ref_tag = cpu_to_le32(reftag); diseed->ref_tag_tran = diseed->ref_tag; - if (scsi_prot_flagged(sc, SCSI_PROT_GUARD_CHECK)) { - bf_set(lpfc_sli4_sge_dif_ce, diseed, checking); - - } else { - bf_set(lpfc_sli4_sge_dif_ce, diseed, 0); - /* - * When in this mode, the hardware will replace - * the guard tag from the host with a - * newly generated good CRC for the wire. - * Switch to raw mode here to avoid this - * behavior. What the host sends gets put on the wire. - */ - if (txop == BG_OP_IN_CRC_OUT_CRC) { - txop = BG_OP_RAW_MODE; - rxop = BG_OP_RAW_MODE; - } - } - - - if (scsi_prot_flagged(sc, SCSI_PROT_REF_CHECK)) - bf_set(lpfc_sli4_sge_dif_re, diseed, checking); - else - bf_set(lpfc_sli4_sge_dif_re, diseed, 0); - /* setup DISEED with the rest of the info */ bf_set(lpfc_sli4_sge_dif_optx, diseed, txop); bf_set(lpfc_sli4_sge_dif_oprx, diseed, rxop); - + bf_set(lpfc_sli4_sge_dif_ce, diseed, checking); + bf_set(lpfc_sli4_sge_dif_re, diseed, checking); bf_set(lpfc_sli4_sge_dif_ai, diseed, 1); bf_set(lpfc_sli4_sge_dif_me, diseed, 0); @@ -2683,10 +2556,6 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, pgdone = 0; subtotal = 0; /* total bytes processed for current prot grp */ while (!pgdone) { - /* Check to see if we ran out of space */ - if (num_sge >= phba->cfg_total_seg_cnt) - return num_sge + 1; - if (!sgde) { lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9086 BLKGRD:%s Invalid data segment\n", @@ -2800,47 +2669,6 @@ lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc) return ret; } -/** - * lpfc_bg_scsi_adjust_dl - Adjust SCSI data length for BlockGuard - * @phba: The Hba for which this call is being executed. - * @lpfc_cmd: The scsi buffer which is going to be adjusted. - * - * Adjust the data length to account for how much data - * is actually on the wire. - * - * returns the adjusted data length - **/ -static int -lpfc_bg_scsi_adjust_dl(struct lpfc_hba *phba, - struct lpfc_scsi_buf *lpfc_cmd) -{ - struct scsi_cmnd *sc = lpfc_cmd->pCmd; - int fcpdl; - - fcpdl = scsi_bufflen(sc); - - /* Check if there is protection data on the wire */ - if (sc->sc_data_direction == DMA_FROM_DEVICE) { - /* Read */ - if (scsi_get_prot_op(sc) == SCSI_PROT_READ_INSERT) - return fcpdl; - - } else { - /* Write */ - if (scsi_get_prot_op(sc) == SCSI_PROT_WRITE_STRIP) - return fcpdl; - } - - /* - * If we are in DIF Type 1 mode every data block has a 8 byte - * DIF (trailer) attached to it. Must ajust FCP data length. - */ - if (scsi_prot_flagged(sc, SCSI_PROT_TRANSFER_PI)) - fcpdl += (fcpdl / lpfc_cmd_blksize(sc)) * 8; - - return fcpdl; -} - /** * lpfc_bg_scsi_prep_dma_buf_s3 - DMA mapping for scsi buffer to SLI3 IF spec * @phba: The Hba for which this call is being executed. @@ -2861,7 +2689,8 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, uint32_t num_bde = 0; int datasegcnt, protsegcnt, datadir = scsi_cmnd->sc_data_direction; int prot_group_type = 0; - int fcpdl; + int diflen, fcpdl; + unsigned blksize; /* * Start the lpfc command prep by bumping the bpl beyond fcp_cmnd @@ -2882,28 +2711,28 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, return 1; lpfc_cmd->seg_cnt = datasegcnt; - - /* First check if data segment count from SCSI Layer is good */ - if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) - goto err; + if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) { + lpfc_printf_log(phba, KERN_ERR, LOG_BG, + "9067 BLKGRD: %s: Too many sg segments" + " from dma_map_sg. Config %d, seg_cnt" + " %d\n", + __func__, phba->cfg_sg_seg_cnt, + lpfc_cmd->seg_cnt); + scsi_dma_unmap(scsi_cmnd); + return 1; + } prot_group_type = lpfc_prot_group_type(phba, scsi_cmnd); switch (prot_group_type) { case LPFC_PG_TYPE_NO_DIF: - - /* Here we need to add a PDE5 and PDE6 to the count */ - if ((lpfc_cmd->seg_cnt + 2) > phba->cfg_total_seg_cnt) - goto err; - num_bde = lpfc_bg_setup_bpl(phba, scsi_cmnd, bpl, datasegcnt); /* we should have 2 or more entries in buffer list */ if (num_bde < 2) goto err; break; - - case LPFC_PG_TYPE_DIF_BUF: + case LPFC_PG_TYPE_DIF_BUF:{ /* * This type indicates that protection buffers are * passed to the driver, so that needs to be prepared @@ -2918,28 +2747,31 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, } lpfc_cmd->prot_seg_cnt = protsegcnt; - - /* - * There is a minimun of 4 BPLs used for every - * protection data segment. - */ - if ((lpfc_cmd->prot_seg_cnt * 4) > - (phba->cfg_total_seg_cnt - 2)) - goto err; + if (lpfc_cmd->prot_seg_cnt + > phba->cfg_prot_sg_seg_cnt) { + lpfc_printf_log(phba, KERN_ERR, LOG_BG, + "9068 BLKGRD: %s: Too many prot sg " + "segments from dma_map_sg. Config %d," + "prot_seg_cnt %d\n", __func__, + phba->cfg_prot_sg_seg_cnt, + lpfc_cmd->prot_seg_cnt); + dma_unmap_sg(&phba->pcidev->dev, + scsi_prot_sglist(scsi_cmnd), + scsi_prot_sg_count(scsi_cmnd), + datadir); + scsi_dma_unmap(scsi_cmnd); + return 1; + } num_bde = lpfc_bg_setup_bpl_prot(phba, scsi_cmnd, bpl, datasegcnt, protsegcnt); /* we should have 3 or more entries in buffer list */ - if ((num_bde < 3) || - (num_bde > phba->cfg_total_seg_cnt)) + if (num_bde < 3) goto err; break; - + } case LPFC_PG_TYPE_INVALID: default: - scsi_dma_unmap(scsi_cmnd); - lpfc_cmd->seg_cnt = 0; - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, "9022 Unexpected protection group %i\n", prot_group_type); @@ -2958,7 +2790,18 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, iocb_cmd->ulpBdeCount = 1; iocb_cmd->ulpLe = 1; - fcpdl = lpfc_bg_scsi_adjust_dl(phba, lpfc_cmd); + fcpdl = scsi_bufflen(scsi_cmnd); + + if (scsi_get_prot_type(scsi_cmnd) == SCSI_PROT_DIF_TYPE1) { + /* + * We are in DIF Type 1 mode + * Every data block has a 8 byte DIF (trailer) + * attached to it. Must ajust FCP data length + */ + blksize = lpfc_cmd_blksize(scsi_cmnd); + diflen = (fcpdl / blksize) * 8; + fcpdl += diflen; + } fcp_cmnd->fcpDl = be32_to_cpu(fcpdl); /* @@ -2969,233 +2812,13 @@ lpfc_bg_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, return 0; err: - if (lpfc_cmd->seg_cnt) - scsi_dma_unmap(scsi_cmnd); - if (lpfc_cmd->prot_seg_cnt) - dma_unmap_sg(&phba->pcidev->dev, scsi_prot_sglist(scsi_cmnd), - scsi_prot_sg_count(scsi_cmnd), - scsi_cmnd->sc_data_direction); - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "9023 Cannot setup S/G List for HBA" - "IO segs %d/%d BPL %d SCSI %d: %d %d\n", - lpfc_cmd->seg_cnt, lpfc_cmd->prot_seg_cnt, - phba->cfg_total_seg_cnt, phba->cfg_sg_seg_cnt, + "9023 Could not setup all needed BDE's" + "prot_group_type=%d, num_bde=%d\n", prot_group_type, num_bde); - - lpfc_cmd->seg_cnt = 0; - lpfc_cmd->prot_seg_cnt = 0; return 1; } -/* - * This function calcuates the T10 DIF guard tag - * on the specified data using a CRC algorithmn - * using crc_t10dif. - */ -uint16_t -lpfc_bg_crc(uint8_t *data, int count) -{ - uint16_t crc = 0; - uint16_t x; - - crc = crc_t10dif(data, count); - x = cpu_to_be16(crc); - return x; -} - -/* - * This function calcuates the T10 DIF guard tag - * on the specified data using a CSUM algorithmn - * using ip_compute_csum. - */ -uint16_t -lpfc_bg_csum(uint8_t *data, int count) -{ - uint16_t ret; - - ret = ip_compute_csum(data, count); - return ret; -} - -/* - * This function examines the protection data to try to determine - * what type of T10-DIF error occurred. - */ -void -lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) -{ - struct scatterlist *sgpe; /* s/g prot entry */ - struct scatterlist *sgde; /* s/g data entry */ - struct scsi_cmnd *cmd = lpfc_cmd->pCmd; - struct scsi_dif_tuple *src = NULL; - uint8_t *data_src = NULL; - uint16_t guard_tag, guard_type; - uint16_t start_app_tag, app_tag; - uint32_t start_ref_tag, ref_tag; - int prot, protsegcnt; - int err_type, len, data_len; - int chk_ref, chk_app, chk_guard; - uint16_t sum; - unsigned blksize; - - err_type = BGS_GUARD_ERR_MASK; - sum = 0; - guard_tag = 0; - - /* First check to see if there is protection data to examine */ - prot = scsi_get_prot_op(cmd); - if ((prot == SCSI_PROT_READ_STRIP) || - (prot == SCSI_PROT_WRITE_INSERT) || - (prot == SCSI_PROT_NORMAL)) - goto out; - - /* Currently the driver just supports ref_tag and guard_tag checking */ - chk_ref = 1; - chk_app = 0; - chk_guard = 0; - - /* Setup a ptr to the protection data provided by the SCSI host */ - sgpe = scsi_prot_sglist(cmd); - protsegcnt = lpfc_cmd->prot_seg_cnt; - - if (sgpe && protsegcnt) { - - /* - * We will only try to verify guard tag if the segment - * data length is a multiple of the blksize. - */ - sgde = scsi_sglist(cmd); - blksize = lpfc_cmd_blksize(cmd); - data_src = (uint8_t *)sg_virt(sgde); - data_len = sgde->length; - if ((data_len & (blksize - 1)) == 0) - chk_guard = 1; - guard_type = scsi_host_get_guard(cmd->device->host); - - start_ref_tag = (uint32_t)scsi_get_lba(cmd); /* Truncate LBA */ - start_app_tag = src->app_tag; - src = (struct scsi_dif_tuple *)sg_virt(sgpe); - len = sgpe->length; - while (src && protsegcnt) { - while (len) { - - /* - * First check to see if a protection data - * check is valid - */ - if ((src->ref_tag == 0xffffffff) || - (src->app_tag == 0xffff)) { - start_ref_tag++; - goto skipit; - } - - /* App Tag checking */ - app_tag = src->app_tag; - if (chk_app && (app_tag != start_app_tag)) { - err_type = BGS_APPTAG_ERR_MASK; - goto out; - } - - /* Reference Tag checking */ - ref_tag = be32_to_cpu(src->ref_tag); - if (chk_ref && (ref_tag != start_ref_tag)) { - err_type = BGS_REFTAG_ERR_MASK; - goto out; - } - start_ref_tag++; - - /* Guard Tag checking */ - if (chk_guard) { - guard_tag = src->guard_tag; - if (guard_type == SHOST_DIX_GUARD_IP) - sum = lpfc_bg_csum(data_src, - blksize); - else - sum = lpfc_bg_crc(data_src, - blksize); - if ((guard_tag != sum)) { - err_type = BGS_GUARD_ERR_MASK; - goto out; - } - } -skipit: - len -= sizeof(struct scsi_dif_tuple); - if (len < 0) - len = 0; - src++; - - data_src += blksize; - data_len -= blksize; - - /* - * Are we at the end of the Data segment? - * The data segment is only used for Guard - * tag checking. - */ - if (chk_guard && (data_len == 0)) { - chk_guard = 0; - sgde = sg_next(sgde); - if (!sgde) - goto out; - - data_src = (uint8_t *)sg_virt(sgde); - data_len = sgde->length; - if ((data_len & (blksize - 1)) == 0) - chk_guard = 1; - } - } - - /* Goto the next Protection data segment */ - sgpe = sg_next(sgpe); - if (sgpe) { - src = (struct scsi_dif_tuple *)sg_virt(sgpe); - len = sgpe->length; - } else { - src = NULL; - } - protsegcnt--; - } - } -out: - if (err_type == BGS_GUARD_ERR_MASK) { - scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, - 0x10, 0x1); - cmd->result = DRIVER_SENSE << 24 - | ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION); - phba->bg_guard_err_cnt++; - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9069 BLKGRD: LBA %lx grd_tag error %x != %x\n", - (unsigned long)scsi_get_lba(cmd), - sum, guard_tag); - - } else if (err_type == BGS_REFTAG_ERR_MASK) { - scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, - 0x10, 0x3); - cmd->result = DRIVER_SENSE << 24 - | ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION); - - phba->bg_reftag_err_cnt++; - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9066 BLKGRD: LBA %lx ref_tag error %x != %x\n", - (unsigned long)scsi_get_lba(cmd), - ref_tag, start_ref_tag); - - } else if (err_type == BGS_APPTAG_ERR_MASK) { - scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, - 0x10, 0x2); - cmd->result = DRIVER_SENSE << 24 - | ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION); - - phba->bg_apptag_err_cnt++; - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9041 BLKGRD: LBA %lx app_tag error %x != %x\n", - (unsigned long)scsi_get_lba(cmd), - app_tag, start_app_tag); - } -} - - /* * This function checks for BlockGuard errors detected by * the HBA. In case of errors, the ASC/ASCQ fields in the @@ -3219,6 +2842,12 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd, uint32_t bgstat = bgf->bgstat; uint64_t failing_sector = 0; + lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9069 BLKGRD: BG ERROR in cmd" + " 0x%x lba 0x%llx blk cnt 0x%x " + "bgstat=0x%x bghm=0x%x\n", + cmd->cmnd[0], (unsigned long long)scsi_get_lba(cmd), + blk_rq_sectors(cmd->request), bgstat, bghm); + spin_lock(&_dump_buf_lock); if (!_dump_buf_done) { lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9070 BLKGRD: Saving" @@ -3241,24 +2870,18 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd, if (lpfc_bgs_get_invalid_prof(bgstat)) { cmd->result = ScsiResult(DID_ERROR, 0); - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9072 BLKGRD: Invalid BG Profile in cmd" - " 0x%x lba 0x%llx blk cnt 0x%x " - "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - (unsigned long long)scsi_get_lba(cmd), - blk_rq_sectors(cmd->request), bgstat, bghm); + lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9072 BLKGRD: Invalid" + " BlockGuard profile. bgstat:0x%x\n", + bgstat); ret = (-1); goto out; } if (lpfc_bgs_get_uninit_dif_block(bgstat)) { cmd->result = ScsiResult(DID_ERROR, 0); - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9073 BLKGRD: Invalid BG PDIF Block in cmd" - " 0x%x lba 0x%llx blk cnt 0x%x " - "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - (unsigned long long)scsi_get_lba(cmd), - blk_rq_sectors(cmd->request), bgstat, bghm); + lpfc_printf_log(phba, KERN_ERR, LOG_BG, "9073 BLKGRD: " + "Invalid BlockGuard DIF Block. bgstat:0x%x\n", + bgstat); ret = (-1); goto out; } @@ -3271,12 +2894,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd, cmd->result = DRIVER_SENSE << 24 | ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION); phba->bg_guard_err_cnt++; - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9055 BLKGRD: Guard Tag error in cmd" - " 0x%x lba 0x%llx blk cnt 0x%x " - "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - (unsigned long long)scsi_get_lba(cmd), - blk_rq_sectors(cmd->request), bgstat, bghm); + lpfc_printf_log(phba, KERN_ERR, LOG_BG, + "9055 BLKGRD: guard_tag error\n"); } if (lpfc_bgs_get_reftag_err(bgstat)) { @@ -3288,12 +2907,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd, | ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION); phba->bg_reftag_err_cnt++; - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9056 BLKGRD: Ref Tag error in cmd" - " 0x%x lba 0x%llx blk cnt 0x%x " - "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - (unsigned long long)scsi_get_lba(cmd), - blk_rq_sectors(cmd->request), bgstat, bghm); + lpfc_printf_log(phba, KERN_ERR, LOG_BG, + "9056 BLKGRD: ref_tag error\n"); } if (lpfc_bgs_get_apptag_err(bgstat)) { @@ -3305,12 +2920,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd, | ScsiResult(DID_ABORT, SAM_STAT_CHECK_CONDITION); phba->bg_apptag_err_cnt++; - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9061 BLKGRD: App Tag error in cmd" - " 0x%x lba 0x%llx blk cnt 0x%x " - "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - (unsigned long long)scsi_get_lba(cmd), - blk_rq_sectors(cmd->request), bgstat, bghm); + lpfc_printf_log(phba, KERN_ERR, LOG_BG, + "9061 BLKGRD: app_tag error\n"); } if (lpfc_bgs_get_hi_water_mark_present(bgstat)) { @@ -3349,16 +2960,11 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd, if (!ret) { /* No error was reported - problem in FW? */ - lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9057 BLKGRD: Unknown error in cmd" - " 0x%x lba 0x%llx blk cnt 0x%x " - "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - (unsigned long long)scsi_get_lba(cmd), - blk_rq_sectors(cmd->request), bgstat, bghm); - - /* Calcuate what type of error it was */ - lpfc_calc_bg_err(phba, lpfc_cmd); + cmd->result = ScsiResult(DID_ERROR, 0); + lpfc_printf_log(phba, KERN_ERR, LOG_BG, + "9057 BLKGRD: Unknown error reported!\n"); } + out: return ret; } @@ -3422,7 +3028,6 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) "dma_map_sg. Config %d, seg_cnt %d\n", __func__, phba->cfg_sg_seg_cnt, lpfc_cmd->seg_cnt); - lpfc_cmd->seg_cnt = 0; scsi_dma_unmap(scsi_cmnd); return 1; } @@ -3488,6 +3093,45 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) return 0; } +/** + * lpfc_bg_scsi_adjust_dl - Adjust SCSI data length for BlockGuard + * @phba: The Hba for which this call is being executed. + * @lpfc_cmd: The scsi buffer which is going to be adjusted. + * + * Adjust the data length to account for how much data + * is actually on the wire. + * + * returns the adjusted data length + **/ +static int +lpfc_bg_scsi_adjust_dl(struct lpfc_hba *phba, + struct lpfc_scsi_buf *lpfc_cmd) +{ + struct scsi_cmnd *sc = lpfc_cmd->pCmd; + int diflen, fcpdl; + unsigned blksize; + + fcpdl = scsi_bufflen(sc); + + /* Check if there is protection data on the wire */ + if (sc->sc_data_direction == DMA_FROM_DEVICE) { + /* Read */ + if (scsi_get_prot_op(sc) == SCSI_PROT_READ_INSERT) + return fcpdl; + + } else { + /* Write */ + if (scsi_get_prot_op(sc) == SCSI_PROT_WRITE_STRIP) + return fcpdl; + } + + /* If protection data on the wire, adjust the count accordingly */ + blksize = lpfc_cmd_blksize(sc); + diflen = (fcpdl / blksize) * 8; + fcpdl += diflen; + return fcpdl; +} + /** * lpfc_bg_scsi_prep_dma_buf_s4 - DMA mapping for scsi buffer to SLI4 IF spec * @phba: The Hba for which this call is being executed. @@ -3505,14 +3149,14 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd; struct sli4_sge *sgl = (struct sli4_sge *)(lpfc_cmd->fcp_bpl); IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb; - uint32_t num_sge = 0; + uint32_t num_bde = 0; int datasegcnt, protsegcnt, datadir = scsi_cmnd->sc_data_direction; int prot_group_type = 0; int fcpdl; /* * Start the lpfc command prep by bumping the sgl beyond fcp_cmnd - * fcp_rsp regions to the first data sge entry + * fcp_rsp regions to the first data bde entry */ if (scsi_sg_count(scsi_cmnd)) { /* @@ -3535,28 +3179,28 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, sgl += 1; lpfc_cmd->seg_cnt = datasegcnt; - - /* First check if data segment count from SCSI Layer is good */ - if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) - goto err; + if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) { + lpfc_printf_log(phba, KERN_ERR, LOG_BG, + "9087 BLKGRD: %s: Too many sg segments" + " from dma_map_sg. Config %d, seg_cnt" + " %d\n", + __func__, phba->cfg_sg_seg_cnt, + lpfc_cmd->seg_cnt); + scsi_dma_unmap(scsi_cmnd); + return 1; + } prot_group_type = lpfc_prot_group_type(phba, scsi_cmnd); switch (prot_group_type) { case LPFC_PG_TYPE_NO_DIF: - /* Here we need to add a DISEED to the count */ - if ((lpfc_cmd->seg_cnt + 1) > phba->cfg_total_seg_cnt) - goto err; - - num_sge = lpfc_bg_setup_sgl(phba, scsi_cmnd, sgl, + num_bde = lpfc_bg_setup_sgl(phba, scsi_cmnd, sgl, datasegcnt); - /* we should have 2 or more entries in buffer list */ - if (num_sge < 2) + if (num_bde < 2) goto err; break; - - case LPFC_PG_TYPE_DIF_BUF: + case LPFC_PG_TYPE_DIF_BUF:{ /* * This type indicates that protection buffers are * passed to the driver, so that needs to be prepared @@ -3571,28 +3215,31 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, } lpfc_cmd->prot_seg_cnt = protsegcnt; - /* - * There is a minimun of 3 SGEs used for every - * protection data segment. - */ - if ((lpfc_cmd->prot_seg_cnt * 3) > - (phba->cfg_total_seg_cnt - 2)) - goto err; + if (lpfc_cmd->prot_seg_cnt + > phba->cfg_prot_sg_seg_cnt) { + lpfc_printf_log(phba, KERN_ERR, LOG_BG, + "9088 BLKGRD: %s: Too many prot sg " + "segments from dma_map_sg. Config %d," + "prot_seg_cnt %d\n", __func__, + phba->cfg_prot_sg_seg_cnt, + lpfc_cmd->prot_seg_cnt); + dma_unmap_sg(&phba->pcidev->dev, + scsi_prot_sglist(scsi_cmnd), + scsi_prot_sg_count(scsi_cmnd), + datadir); + scsi_dma_unmap(scsi_cmnd); + return 1; + } - num_sge = lpfc_bg_setup_sgl_prot(phba, scsi_cmnd, sgl, + num_bde = lpfc_bg_setup_sgl_prot(phba, scsi_cmnd, sgl, datasegcnt, protsegcnt); - /* we should have 3 or more entries in buffer list */ - if ((num_sge < 3) || - (num_sge > phba->cfg_total_seg_cnt)) + if (num_bde < 3) goto err; break; - + } case LPFC_PG_TYPE_INVALID: default: - scsi_dma_unmap(scsi_cmnd); - lpfc_cmd->seg_cnt = 0; - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, "9083 Unexpected protection group %i\n", prot_group_type); @@ -3616,6 +3263,7 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, } fcpdl = lpfc_bg_scsi_adjust_dl(phba, lpfc_cmd); + fcp_cmnd->fcpDl = be32_to_cpu(fcpdl); /* @@ -3626,22 +3274,10 @@ lpfc_bg_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, return 0; err: - if (lpfc_cmd->seg_cnt) - scsi_dma_unmap(scsi_cmnd); - if (lpfc_cmd->prot_seg_cnt) - dma_unmap_sg(&phba->pcidev->dev, scsi_prot_sglist(scsi_cmnd), - scsi_prot_sg_count(scsi_cmnd), - scsi_cmnd->sc_data_direction); - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, - "9084 Cannot setup S/G List for HBA" - "IO segs %d/%d SGL %d SCSI %d: %d %d\n", - lpfc_cmd->seg_cnt, lpfc_cmd->prot_seg_cnt, - phba->cfg_total_seg_cnt, phba->cfg_sg_seg_cnt, - prot_group_type, num_sge); - - lpfc_cmd->seg_cnt = 0; - lpfc_cmd->prot_seg_cnt = 0; + "9084 Could not setup all needed BDE's" + "prot_group_type=%d, num_bde=%d\n", + prot_group_type, num_bde); return 1; } @@ -4721,8 +4357,7 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) if (scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) { if (vport->phba->cfg_enable_bg) { - lpfc_printf_vlog(vport, - KERN_INFO, LOG_SCSI_CMD, + lpfc_printf_vlog(vport, KERN_INFO, LOG_BG, "9033 BLKGRD: rcvd %s cmd:x%x " "sector x%llx cnt %u pt %x\n", dif_op_str[scsi_get_prot_op(cmnd)], @@ -4734,8 +4369,7 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) err = lpfc_bg_scsi_prep_dma_buf(phba, lpfc_cmd); } else { if (vport->phba->cfg_enable_bg) { - lpfc_printf_vlog(vport, - KERN_INFO, LOG_SCSI_CMD, + lpfc_printf_vlog(vport, KERN_INFO, LOG_BG, "9038 BLKGRD: rcvd PROT_NORMAL cmd: " "x%x sector x%llx cnt %u pt %x\n", cmnd->cmnd[0], @@ -4908,7 +4542,7 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) /* Wait for abort to complete */ wait_event_timeout(waitq, (lpfc_cmd->pCmd != cmnd), - msecs_to_jiffies(2*vport->cfg_devloss_tmo*1000)); + (2*vport->cfg_devloss_tmo*HZ)); lpfc_cmd->waitq = NULL; if (lpfc_cmd->pCmd == cmnd) { @@ -5378,24 +5012,16 @@ lpfc_host_reset_handler(struct scsi_cmnd *cmnd) struct lpfc_hba *phba = vport->phba; int rc, ret = SUCCESS; - lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, - "3172 SCSI layer issued Host Reset Data:\n"); - lpfc_offline_prep(phba, LPFC_MBX_WAIT); lpfc_offline(phba); rc = lpfc_sli_brdrestart(phba); if (rc) ret = FAILED; - rc = lpfc_online(phba); - if (rc) - ret = FAILED; + lpfc_online(phba); lpfc_unblock_mgmt_io(phba); - if (ret == FAILED) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, - "3323 Failed host reset, bring it offline\n"); - lpfc_sli4_offline_eratt(phba); - } + lpfc_printf_log(phba, KERN_ERR, LOG_FCP, + "3172 SCSI layer issued Host Reset Data: x%x\n", ret); return ret; } @@ -5462,11 +5088,11 @@ lpfc_slave_alloc(struct scsi_device *sdev) } num_allocated = lpfc_new_scsi_buf(vport, num_to_alloc); if (num_to_alloc != num_allocated) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP, - "0708 Allocation request of %d " - "command buffers did not succeed. " - "Allocated %d buffers.\n", - num_to_alloc, num_allocated); + lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP, + "0708 Allocation request of %d " + "command buffers did not succeed. " + "Allocated %d buffers.\n", + num_to_alloc, num_allocated); } if (num_allocated > 0) phba->total_scsi_bufs += num_allocated; diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.c b/trunk/drivers/scsi/lpfc/lpfc_sli.c index 572579f87de4..35dd17eb0f27 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.c +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.c @@ -667,7 +667,7 @@ lpfc_handle_rrq_active(struct lpfc_hba *phba) spin_lock_irqsave(&phba->hbalock, iflags); phba->hba_flag &= ~HBA_RRQ_ACTIVE; - next_time = jiffies + msecs_to_jiffies(1000 * (phba->fc_ratov + 1)); + next_time = jiffies + HZ * (phba->fc_ratov + 1); list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) { if (time_after(jiffies, rrq->rrq_stop_time)) @@ -782,7 +782,7 @@ lpfc_cleanup_wt_rrqs(struct lpfc_hba *phba) return; spin_lock_irqsave(&phba->hbalock, iflags); phba->hba_flag &= ~HBA_RRQ_ACTIVE; - next_time = jiffies + msecs_to_jiffies(1000 * (phba->fc_ratov * 2)); + next_time = jiffies + HZ * (phba->fc_ratov * 2); list_splice_init(&phba->active_rrq_list, &rrq_list); spin_unlock_irqrestore(&phba->hbalock, iflags); @@ -878,8 +878,7 @@ lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, else rrq->send_rrq = 0; rrq->xritag = xritag; - rrq->rrq_stop_time = jiffies + - msecs_to_jiffies(1000 * (phba->fc_ratov + 1)); + rrq->rrq_stop_time = jiffies + HZ * (phba->fc_ratov + 1); rrq->ndlp = ndlp; rrq->nlp_DID = ndlp->nlp_DID; rrq->vport = ndlp->vport; @@ -927,7 +926,8 @@ __lpfc_sli_get_sglq(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq) } else if ((piocbq->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) && !(piocbq->iocb_flag & LPFC_IO_LIBDFC)) ndlp = piocbq->context_un.ndlp; - else if (piocbq->iocb_flag & LPFC_IO_LIBDFC) + else if ((piocbq->iocb.ulpCommand == CMD_ELS_REQUEST64_CR) && + (piocbq->iocb_flag & LPFC_IO_LIBDFC)) ndlp = piocbq->context_un.ndlp; else ndlp = piocbq->context1; @@ -1339,8 +1339,7 @@ lpfc_sli_ringtxcmpl_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, BUG(); else mod_timer(&piocb->vport->els_tmofunc, - jiffies + - msecs_to_jiffies(1000 * (phba->fc_ratov << 1))); + jiffies + HZ * (phba->fc_ratov << 1)); } @@ -2341,8 +2340,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba) /* Mailbox cmd Cmpl */ lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, "(%d):0307 Mailbox cmd x%x (x%x/x%x) Cmpl x%p " - "Data: x%x x%x x%x x%x x%x x%x x%x x%x x%x " - "x%x x%x x%x\n", + "Data: x%x x%x x%x x%x x%x x%x x%x x%x x%x\n", pmb->vport ? pmb->vport->vpi : 0, pmbox->mbxCommand, lpfc_sli_config_mbox_subsys_get(phba, pmb), @@ -2356,10 +2354,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba) pmbox->un.varWords[4], pmbox->un.varWords[5], pmbox->un.varWords[6], - pmbox->un.varWords[7], - pmbox->un.varWords[8], - pmbox->un.varWords[9], - pmbox->un.varWords[10]); + pmbox->un.varWords[7]); if (pmb->mbox_cmpl) pmb->mbox_cmpl(phba,pmb); @@ -2913,9 +2908,8 @@ void lpfc_poll_eratt(unsigned long ptr) lpfc_worker_wake_up(phba); else /* Restart the timer for next eratt poll */ - mod_timer(&phba->eratt_poll, - jiffies + - msecs_to_jiffies(1000 * LPFC_ERATT_POLL_INTERVAL)); + mod_timer(&phba->eratt_poll, jiffies + + HZ * LPFC_ERATT_POLL_INTERVAL); return; } @@ -5517,7 +5511,6 @@ lpfc_sli4_dealloc_extent(struct lpfc_hba *phba, uint16_t type) list_del_init(&rsrc_blk->list); kfree(rsrc_blk); } - phba->sli4_hba.max_cfg_param.vpi_used = 0; break; case LPFC_RSC_TYPE_FCOE_XRI: kfree(phba->sli4_hba.xri_bmask); @@ -5818,7 +5811,6 @@ lpfc_sli4_dealloc_resource_identifiers(struct lpfc_hba *phba) lpfc_sli4_dealloc_extent(phba, LPFC_RSC_TYPE_FCOE_VFI); } else { kfree(phba->vpi_bmask); - phba->sli4_hba.max_cfg_param.vpi_used = 0; kfree(phba->vpi_ids); bf_set(lpfc_vpi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0); kfree(phba->sli4_hba.xri_bmask); @@ -6000,7 +5992,7 @@ lpfc_sli4_repost_els_sgl_list(struct lpfc_hba *phba) struct lpfc_sglq *sglq_entry = NULL; struct lpfc_sglq *sglq_entry_next = NULL; struct lpfc_sglq *sglq_entry_first = NULL; - int status, total_cnt, post_cnt = 0, num_posted = 0, block_cnt = 0; + int status, post_cnt = 0, num_posted = 0, block_cnt = 0; int last_xritag = NO_XRI; LIST_HEAD(prep_sgl_list); LIST_HEAD(blck_sgl_list); @@ -6012,7 +6004,6 @@ lpfc_sli4_repost_els_sgl_list(struct lpfc_hba *phba) list_splice_init(&phba->sli4_hba.lpfc_sgl_list, &allc_sgl_list); spin_unlock_irq(&phba->hbalock); - total_cnt = phba->sli4_hba.els_xri_cnt; list_for_each_entry_safe(sglq_entry, sglq_entry_next, &allc_sgl_list, list) { list_del_init(&sglq_entry->list); @@ -6064,7 +6055,9 @@ lpfc_sli4_repost_els_sgl_list(struct lpfc_hba *phba) sglq_entry->sli4_xritag); list_add_tail(&sglq_entry->list, &free_sgl_list); - total_cnt--; + spin_lock_irq(&phba->hbalock); + phba->sli4_hba.els_xri_cnt--; + spin_unlock_irq(&phba->hbalock); } } } @@ -6092,7 +6085,9 @@ lpfc_sli4_repost_els_sgl_list(struct lpfc_hba *phba) (sglq_entry_first->sli4_xritag + post_cnt - 1)); list_splice_init(&blck_sgl_list, &free_sgl_list); - total_cnt -= post_cnt; + spin_lock_irq(&phba->hbalock); + phba->sli4_hba.els_xri_cnt -= post_cnt; + spin_unlock_irq(&phba->hbalock); } /* don't reset xirtag due to hole in xri block */ @@ -6102,8 +6097,6 @@ lpfc_sli4_repost_els_sgl_list(struct lpfc_hba *phba) /* reset els sgl post count for next round of posting */ post_cnt = 0; } - /* update the number of XRIs posted for ELS */ - phba->sli4_hba.els_xri_cnt = total_cnt; /* free the els sgls failed to post */ lpfc_free_sgl_list(phba, &free_sgl_list); @@ -6453,17 +6446,16 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) /* Start the ELS watchdog timer */ mod_timer(&vport->els_tmofunc, - jiffies + msecs_to_jiffies(1000 * (phba->fc_ratov * 2))); + jiffies + HZ * (phba->fc_ratov * 2)); /* Start heart beat timer */ mod_timer(&phba->hb_tmofunc, - jiffies + msecs_to_jiffies(1000 * LPFC_HB_MBOX_INTERVAL)); + jiffies + HZ * LPFC_HB_MBOX_INTERVAL); phba->hb_outstanding = 0; phba->last_completion_time = jiffies; /* Start error attention (ERATT) polling timer */ - mod_timer(&phba->eratt_poll, - jiffies + msecs_to_jiffies(1000 * LPFC_ERATT_POLL_INTERVAL)); + mod_timer(&phba->eratt_poll, jiffies + HZ * LPFC_ERATT_POLL_INTERVAL); /* Enable PCIe device Advanced Error Reporting (AER) if configured */ if (phba->cfg_aer_support == 1 && !(phba->hba_flag & HBA_AER_ENABLED)) { @@ -6830,9 +6822,8 @@ lpfc_sli_issue_mbox_s3(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, goto out_not_finished; } /* timeout active mbox command */ - timeout = msecs_to_jiffies(lpfc_mbox_tmo_val(phba, pmbox) * - 1000); - mod_timer(&psli->mbox_tmo, jiffies + timeout); + mod_timer(&psli->mbox_tmo, (jiffies + + (HZ * lpfc_mbox_tmo_val(phba, pmbox)))); } /* Mailbox cmd issue */ @@ -7505,7 +7496,7 @@ lpfc_sli4_post_async_mbox(struct lpfc_hba *phba) /* Start timer for the mbox_tmo and log some mailbox post messages */ mod_timer(&psli->mbox_tmo, (jiffies + - msecs_to_jiffies(1000 * lpfc_mbox_tmo_val(phba, mboxq)))); + (HZ * lpfc_mbox_tmo_val(phba, mboxq)))); lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_SLI, "(%d):0355 Mailbox cmd x%x (x%x/x%x) issue Data: " @@ -7923,21 +7914,15 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, static inline uint32_t lpfc_sli4_scmd_to_wqidx_distr(struct lpfc_hba *phba) { - struct lpfc_vector_map_info *cpup; - int chann, cpu; + int i; - if (phba->cfg_fcp_io_sched == LPFC_FCP_SCHED_BY_CPU) { - cpu = smp_processor_id(); - if (cpu < phba->sli4_hba.num_present_cpu) { - cpup = phba->sli4_hba.cpu_map; - cpup += cpu; - return cpup->channel_id; - } - chann = cpu; - } - chann = atomic_add_return(1, &phba->fcp_qidx); - chann = (chann % phba->cfg_fcp_io_channel); - return chann; + if (phba->cfg_fcp_io_sched == LPFC_FCP_SCHED_BY_CPU) + i = smp_processor_id(); + else + i = atomic_add_return(1, &phba->fcp_qidx); + + i = (i % phba->cfg_fcp_io_channel); + return i; } /** @@ -8459,14 +8444,10 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, if ((piocb->iocb_flag & LPFC_IO_FCP) || (piocb->iocb_flag & LPFC_USE_FCPWQIDX)) { - if (unlikely(!phba->sli4_hba.fcp_wq)) - return IOCB_ERROR; if (lpfc_sli4_wq_put(phba->sli4_hba.fcp_wq[piocb->fcp_wqidx], &wqe)) return IOCB_ERROR; } else { - if (unlikely(!phba->sli4_hba.els_wq)) - return IOCB_ERROR; if (lpfc_sli4_wq_put(phba->sli4_hba.els_wq, &wqe)) return IOCB_ERROR; } @@ -10022,7 +10003,7 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba, retval = lpfc_sli_issue_iocb(phba, ring_number, piocb, SLI_IOCB_RET_IOCB); if (retval == IOCB_SUCCESS) { - timeout_req = msecs_to_jiffies(timeout * 1000); + timeout_req = timeout * HZ; timeleft = wait_event_timeout(done_q, lpfc_chk_iocb_flg(phba, piocb, LPFC_IO_WAKE), timeout_req); @@ -10127,7 +10108,7 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, if (retval == MBX_BUSY || retval == MBX_SUCCESS) { wait_event_interruptible_timeout(done_q, pmboxq->mbox_flag & LPFC_MBX_WAKE, - msecs_to_jiffies(timeout * 1000)); + timeout * HZ); spin_lock_irqsave(&phba->hbalock, flag); pmboxq->context1 = NULL; @@ -12918,9 +12899,8 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, } wq->db_regaddr = bar_memmap_p + db_offset; lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "3264 WQ[%d]: barset:x%x, offset:x%x, " - "format:x%x\n", wq->queue_id, pci_barset, - db_offset, wq->db_format); + "3264 WQ[%d]: barset:x%x, offset:x%x\n", + wq->queue_id, pci_barset, db_offset); } else { wq->db_format = LPFC_DB_LIST_FORMAT; wq->db_regaddr = phba->sli4_hba.WQDBregaddr; @@ -13140,9 +13120,8 @@ lpfc_rq_create(struct lpfc_hba *phba, struct lpfc_queue *hrq, } hrq->db_regaddr = bar_memmap_p + db_offset; lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "3266 RQ[qid:%d]: barset:x%x, offset:x%x, " - "format:x%x\n", hrq->queue_id, pci_barset, - db_offset, hrq->db_format); + "3266 RQ[qid:%d]: barset:x%x, offset:x%x\n", + hrq->queue_id, pci_barset, db_offset); } else { hrq->db_format = LPFC_DB_RING_FORMAT; hrq->db_regaddr = phba->sli4_hba.RQDBregaddr; @@ -13992,14 +13971,13 @@ lpfc_fc_frame_check(struct lpfc_hba *phba, struct fc_frame_header *fc_hdr) } lpfc_printf_log(phba, KERN_INFO, LOG_ELS, - "2538 Received frame rctl:%s (x%x), type:%s (x%x), " - "frame Data:%08x %08x %08x %08x %08x %08x %08x\n", - rctl_names[fc_hdr->fh_r_ctl], fc_hdr->fh_r_ctl, - type_names[fc_hdr->fh_type], fc_hdr->fh_type, + "2538 Received frame rctl:%s type:%s " + "Frame Data:%08x %08x %08x %08x %08x %08x\n", + rctl_names[fc_hdr->fh_r_ctl], + type_names[fc_hdr->fh_type], be32_to_cpu(header[0]), be32_to_cpu(header[1]), be32_to_cpu(header[2]), be32_to_cpu(header[3]), - be32_to_cpu(header[4]), be32_to_cpu(header[5]), - be32_to_cpu(header[6])); + be32_to_cpu(header[4]), be32_to_cpu(header[5])); return 0; drop: lpfc_printf_log(phba, KERN_WARNING, LOG_ELS, diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli4.h b/trunk/drivers/scsi/lpfc/lpfc_sli4.h index 67af460184ba..be02b59ea279 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli4.h +++ b/trunk/drivers/scsi/lpfc/lpfc_sli4.h @@ -346,6 +346,11 @@ struct lpfc_bmbx { #define SLI4_CT_VFI 2 #define SLI4_CT_FCFI 3 +#define LPFC_SLI4_FL1_MAX_SEGMENT_SIZE 0x10000 +#define LPFC_SLI4_FL1_MAX_BUF_SIZE 0X2000 +#define LPFC_SLI4_MIN_BUF_SIZE 0x400 +#define LPFC_SLI4_MAX_BUF_SIZE 0x20000 + /* * SLI4 specific data structures */ @@ -435,17 +440,6 @@ struct lpfc_sli4_lnk_info { #define LPFC_SLI4_HANDLER_NAME_SZ 16 -/* Used for IRQ vector to CPU mapping */ -struct lpfc_vector_map_info { - uint16_t phys_id; - uint16_t core_id; - uint16_t irq; - uint16_t channel_id; - struct cpumask maskbits; -}; -#define LPFC_VECTOR_MAP_EMPTY 0xffff -#define LPFC_MAX_CPU 256 - /* SLI4 HBA data structure entries */ struct lpfc_sli4_hba { void __iomem *conf_regs_memmap_p; /* Kernel memory mapped address for @@ -579,11 +573,6 @@ struct lpfc_sli4_hba { struct lpfc_iov iov; spinlock_t abts_scsi_buf_list_lock; /* list of aborted SCSI IOs */ spinlock_t abts_sgl_list_lock; /* list of aborted els IOs */ - - /* CPU to vector mapping information */ - struct lpfc_vector_map_info *cpu_map; - uint16_t num_online_cpu; - uint16_t num_present_cpu; }; enum lpfc_sge_type { diff --git a/trunk/drivers/scsi/lpfc/lpfc_version.h b/trunk/drivers/scsi/lpfc/lpfc_version.h index a38dc3b16969..664cd04f7cd8 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_version.h +++ b/trunk/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.3.39" +#define LPFC_DRIVER_VERSION "8.3.38" #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_vport.c b/trunk/drivers/scsi/lpfc/lpfc_vport.c index e28e431564b0..0fe188e66000 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_vport.c +++ b/trunk/drivers/scsi/lpfc/lpfc_vport.c @@ -80,7 +80,7 @@ inline void lpfc_vport_set_state(struct lpfc_vport *vport, } } -int +static int lpfc_alloc_vpi(struct lpfc_hba *phba) { unsigned long vpi; @@ -568,7 +568,6 @@ lpfc_vport_delete(struct fc_vport *fc_vport) struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data; struct lpfc_hba *phba = vport->phba; long timeout; - bool ns_ndlp_referenced = false; if (vport->port_type == LPFC_PHYSICAL_PORT) { lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, @@ -629,18 +628,6 @@ lpfc_vport_delete(struct fc_vport *fc_vport) lpfc_debugfs_terminate(vport); - /* - * The call to fc_remove_host might release the NameServer ndlp. Since - * we might need to use the ndlp to send the DA_ID CT command, - * increment the reference for the NameServer ndlp to prevent it from - * being released. - */ - ndlp = lpfc_findnode_did(vport, NameServer_DID); - if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { - lpfc_nlp_get(ndlp); - ns_ndlp_referenced = true; - } - /* Remove FC host and then SCSI host with the vport */ fc_remove_host(lpfc_shost_from_vport(vport)); scsi_remove_host(lpfc_shost_from_vport(vport)); @@ -747,16 +734,6 @@ lpfc_vport_delete(struct fc_vport *fc_vport) lpfc_discovery_wait(vport); skip_logo: - - /* - * If the NameServer ndlp has been incremented to allow the DA_ID CT - * command to be sent, decrement the ndlp now. - */ - if (ns_ndlp_referenced) { - ndlp = lpfc_findnode_did(vport, NameServer_DID); - lpfc_nlp_put(ndlp); - } - lpfc_cleanup(vport); lpfc_sli_host_down(vport); diff --git a/trunk/drivers/scsi/lpfc/lpfc_vport.h b/trunk/drivers/scsi/lpfc/lpfc_vport.h index 6b2c94eb8134..90828340acea 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_vport.h +++ b/trunk/drivers/scsi/lpfc/lpfc_vport.h @@ -90,7 +90,6 @@ int lpfc_vport_getinfo(struct Scsi_Host *, struct vport_info *); int lpfc_vport_tgt_remove(struct Scsi_Host *, uint, uint); struct lpfc_vport **lpfc_create_vport_work_array(struct lpfc_hba *); void lpfc_destroy_vport_work_array(struct lpfc_hba *, struct lpfc_vport **); -int lpfc_alloc_vpi(struct lpfc_hba *phba); /* * queuecommand VPORT-specific return codes. Specified in the host byte code. diff --git a/trunk/drivers/scsi/megaraid/megaraid_sas_base.c b/trunk/drivers/scsi/megaraid/megaraid_sas_base.c index 3a9ddae86f1f..7c90d57b867e 100644 --- a/trunk/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/trunk/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4931,12 +4931,11 @@ static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg) printk(KERN_ERR "megaraid_sas: timed out while" "waiting for HBA to recover\n"); error = -ENODEV; - goto out_up; + goto out_kfree_ioc; } spin_unlock_irqrestore(&instance->hba_lock, flags); error = megasas_mgmt_fw_ioctl(instance, user_ioc, ioc); - out_up: up(&instance->ioctl_sem); out_kfree_ioc: diff --git a/trunk/drivers/scsi/mvsas/mv_init.c b/trunk/drivers/scsi/mvsas/mv_init.c index 7b7381d7671f..74550922ad55 100644 --- a/trunk/drivers/scsi/mvsas/mv_init.c +++ b/trunk/drivers/scsi/mvsas/mv_init.c @@ -254,7 +254,7 @@ static int mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost) } for (i = 0; i < MVS_MAX_DEVICES; i++) { mvi->devices[i].taskfileset = MVS_ID_NOT_MAPPED; - mvi->devices[i].dev_type = SAS_PHY_UNUSED; + mvi->devices[i].dev_type = NO_DEVICE; mvi->devices[i].device_id = i; mvi->devices[i].dev_status = MVS_DEV_NORMAL; init_timer(&mvi->devices[i].timer); diff --git a/trunk/drivers/scsi/mvsas/mv_sas.c b/trunk/drivers/scsi/mvsas/mv_sas.c index c9e244984e30..532110f4562a 100644 --- a/trunk/drivers/scsi/mvsas/mv_sas.c +++ b/trunk/drivers/scsi/mvsas/mv_sas.c @@ -706,7 +706,7 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, return 0; } -#define DEV_IS_GONE(mvi_dev) ((!mvi_dev || (mvi_dev->dev_type == SAS_PHY_UNUSED))) +#define DEV_IS_GONE(mvi_dev) ((!mvi_dev || (mvi_dev->dev_type == NO_DEVICE))) static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf, struct mvs_tmf_task *tmf, int *pass) { @@ -726,7 +726,7 @@ static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf * libsas will use dev->port, should * not call task_done for sata */ - if (dev->dev_type != SAS_SATA_DEV) + if (dev->dev_type != SATA_DEV) task->task_done(task); return rc; } @@ -1159,10 +1159,10 @@ void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st) phy->identify.device_type = phy->att_dev_info & PORT_DEV_TYPE_MASK; - if (phy->identify.device_type == SAS_END_DEVICE) + if (phy->identify.device_type == SAS_END_DEV) phy->identify.target_port_protocols = SAS_PROTOCOL_SSP; - else if (phy->identify.device_type != SAS_PHY_UNUSED) + else if (phy->identify.device_type != NO_DEVICE) phy->identify.target_port_protocols = SAS_PROTOCOL_SMP; if (oob_done) @@ -1260,7 +1260,7 @@ struct mvs_device *mvs_alloc_dev(struct mvs_info *mvi) { u32 dev; for (dev = 0; dev < MVS_MAX_DEVICES; dev++) { - if (mvi->devices[dev].dev_type == SAS_PHY_UNUSED) { + if (mvi->devices[dev].dev_type == NO_DEVICE) { mvi->devices[dev].device_id = dev; return &mvi->devices[dev]; } @@ -1278,7 +1278,7 @@ void mvs_free_dev(struct mvs_device *mvi_dev) u32 id = mvi_dev->device_id; memset(mvi_dev, 0, sizeof(*mvi_dev)); mvi_dev->device_id = id; - mvi_dev->dev_type = SAS_PHY_UNUSED; + mvi_dev->dev_type = NO_DEVICE; mvi_dev->dev_status = MVS_DEV_NORMAL; mvi_dev->taskfileset = MVS_ID_NOT_MAPPED; } @@ -1480,7 +1480,7 @@ static int mvs_debug_I_T_nexus_reset(struct domain_device *dev) { int rc; struct sas_phy *phy = sas_get_local_phy(dev); - int reset_type = (dev->dev_type == SAS_SATA_DEV || + int reset_type = (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) ? 0 : 1; rc = sas_phy_reset(phy, reset_type); sas_put_local_phy(phy); @@ -1629,7 +1629,7 @@ int mvs_abort_task(struct sas_task *task) } else if (task->task_proto & SAS_PROTOCOL_SATA || task->task_proto & SAS_PROTOCOL_STP) { - if (SAS_SATA_DEV == dev->dev_type) { + if (SATA_DEV == dev->dev_type) { struct mvs_slot_info *slot = task->lldd_task; u32 slot_idx = (u32)(slot - mvi->slot_info); mv_dprintk("mvs_abort_task() mvi=%p task=%p " diff --git a/trunk/drivers/scsi/mvsas/mv_sas.h b/trunk/drivers/scsi/mvsas/mv_sas.h index 60e2fb7f2dca..9f3cc13a5ce7 100644 --- a/trunk/drivers/scsi/mvsas/mv_sas.h +++ b/trunk/drivers/scsi/mvsas/mv_sas.h @@ -67,7 +67,7 @@ extern const struct mvs_dispatch mvs_94xx_dispatch; extern struct kmem_cache *mvs_task_list_cache; #define DEV_IS_EXPANDER(type) \ - ((type == SAS_EDGE_EXPANDER_DEVICE) || (type == SAS_FANOUT_EXPANDER_DEVICE)) + ((type == EDGE_DEV) || (type == FANOUT_DEV)) #define bit(n) ((u64)1 << n) @@ -241,7 +241,7 @@ struct mvs_phy { struct mvs_device { struct list_head dev_entry; - enum sas_device_type dev_type; + enum sas_dev_type dev_type; struct mvs_info *mvi_info; struct domain_device *sas_device; struct timer_list timer; diff --git a/trunk/drivers/scsi/pm8001/Makefile b/trunk/drivers/scsi/pm8001/Makefile index ce4cd87c7c66..52f04296171c 100644 --- a/trunk/drivers/scsi/pm8001/Makefile +++ b/trunk/drivers/scsi/pm8001/Makefile @@ -4,10 +4,9 @@ # Copyright (C) 2008-2009 USI Co., Ltd. -obj-$(CONFIG_SCSI_PM8001) += pm80xx.o -pm80xx-y += pm8001_init.o \ +obj-$(CONFIG_SCSI_PM8001) += pm8001.o +pm8001-y += pm8001_init.o \ pm8001_sas.o \ pm8001_ctl.o \ - pm8001_hwi.o \ - pm80xx_hwi.o + pm8001_hwi.o diff --git a/trunk/drivers/scsi/pm8001/pm8001_ctl.c b/trunk/drivers/scsi/pm8001/pm8001_ctl.c index d99f41c2ca13..45bc197bc22f 100644 --- a/trunk/drivers/scsi/pm8001/pm8001_ctl.c +++ b/trunk/drivers/scsi/pm8001/pm8001_ctl.c @@ -1,5 +1,5 @@ /* - * PMC-Sierra 8001/8081/8088/8089 SAS/SATA based host adapters driver + * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver * * Copyright (c) 2008-2009 USI Co., Ltd. * All rights reserved. @@ -58,13 +58,8 @@ static ssize_t pm8001_ctl_mpi_interface_rev_show(struct device *cdev, struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; - if (pm8001_ha->chip_id == chip_8001) { - return snprintf(buf, PAGE_SIZE, "%d\n", - pm8001_ha->main_cfg_tbl.pm8001_tbl.interface_rev); - } else { - return snprintf(buf, PAGE_SIZE, "%d\n", - pm8001_ha->main_cfg_tbl.pm80xx_tbl.interface_rev); - } + return snprintf(buf, PAGE_SIZE, "%d\n", + pm8001_ha->main_cfg_tbl.interface_rev); } static DEVICE_ATTR(interface_rev, S_IRUGO, pm8001_ctl_mpi_interface_rev_show, NULL); @@ -83,19 +78,11 @@ static ssize_t pm8001_ctl_fw_version_show(struct device *cdev, struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; - if (pm8001_ha->chip_id == chip_8001) { - return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n", - (u8)(pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev >> 24), - (u8)(pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev >> 16), - (u8)(pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev >> 8), - (u8)(pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev)); - } else { - return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n", - (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev >> 24), - (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev >> 16), - (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev >> 8), - (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev)); - } + return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n", + (u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 24), + (u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 16), + (u8)(pm8001_ha->main_cfg_tbl.firmware_rev >> 8), + (u8)(pm8001_ha->main_cfg_tbl.firmware_rev)); } static DEVICE_ATTR(fw_version, S_IRUGO, pm8001_ctl_fw_version_show, NULL); /** @@ -112,13 +99,8 @@ static ssize_t pm8001_ctl_max_out_io_show(struct device *cdev, struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; - if (pm8001_ha->chip_id == chip_8001) { - return snprintf(buf, PAGE_SIZE, "%d\n", - pm8001_ha->main_cfg_tbl.pm8001_tbl.max_out_io); - } else { - return snprintf(buf, PAGE_SIZE, "%d\n", - pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_out_io); - } + return snprintf(buf, PAGE_SIZE, "%d\n", + pm8001_ha->main_cfg_tbl.max_out_io); } static DEVICE_ATTR(max_out_io, S_IRUGO, pm8001_ctl_max_out_io_show, NULL); /** @@ -135,15 +117,8 @@ static ssize_t pm8001_ctl_max_devices_show(struct device *cdev, struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; - if (pm8001_ha->chip_id == chip_8001) { - return snprintf(buf, PAGE_SIZE, "%04d\n", - (u16)(pm8001_ha->main_cfg_tbl.pm8001_tbl.max_sgl >> 16) - ); - } else { - return snprintf(buf, PAGE_SIZE, "%04d\n", - (u16)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_sgl >> 16) - ); - } + return snprintf(buf, PAGE_SIZE, "%04d\n", + (u16)(pm8001_ha->main_cfg_tbl.max_sgl >> 16)); } static DEVICE_ATTR(max_devices, S_IRUGO, pm8001_ctl_max_devices_show, NULL); /** @@ -161,15 +136,8 @@ static ssize_t pm8001_ctl_max_sg_list_show(struct device *cdev, struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; - if (pm8001_ha->chip_id == chip_8001) { - return snprintf(buf, PAGE_SIZE, "%04d\n", - pm8001_ha->main_cfg_tbl.pm8001_tbl.max_sgl & 0x0000FFFF - ); - } else { - return snprintf(buf, PAGE_SIZE, "%04d\n", - pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_sgl & 0x0000FFFF - ); - } + return snprintf(buf, PAGE_SIZE, "%04d\n", + pm8001_ha->main_cfg_tbl.max_sgl & 0x0000FFFF); } static DEVICE_ATTR(max_sg_list, S_IRUGO, pm8001_ctl_max_sg_list_show, NULL); @@ -205,14 +173,7 @@ static ssize_t pm8001_ctl_sas_spec_support_show(struct device *cdev, struct Scsi_Host *shost = class_to_shost(cdev); struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; - /* fe000000 means supports SAS2.1 */ - if (pm8001_ha->chip_id == chip_8001) - mode = (pm8001_ha->main_cfg_tbl.pm8001_tbl.ctrl_cap_flag & - 0xfe000000)>>25; - else - /* fe000000 means supports SAS2.1 */ - mode = (pm8001_ha->main_cfg_tbl.pm80xx_tbl.ctrl_cap_flag & - 0xfe000000)>>25; + mode = (pm8001_ha->main_cfg_tbl.ctrl_cap_flag & 0xfe000000)>>25; return show_sas_spec_support_status(mode, buf); } static DEVICE_ATTR(sas_spec_support, S_IRUGO, @@ -400,11 +361,10 @@ static int pm8001_set_nvmd(struct pm8001_hba_info *pm8001_ha) goto out; } payload = (struct pm8001_ioctl_payload *)ioctlbuffer; - memcpy((u8 *)&payload->func_specific, (u8 *)pm8001_ha->fw_image->data, + memcpy((u8 *)payload->func_specific, (u8 *)pm8001_ha->fw_image->data, pm8001_ha->fw_image->size); payload->length = pm8001_ha->fw_image->size; payload->id = 0; - payload->minor_function = 0x1; pm8001_ha->nvmd_completion = &completion; ret = PM8001_CHIP_DISP->set_nvmd_req(pm8001_ha, payload); wait_for_completion(&completion); @@ -451,7 +411,7 @@ static int pm8001_update_flash(struct pm8001_hba_info *pm8001_ha) payload->length = 1024*16; payload->id = 0; fwControl = - (struct fw_control_info *)&payload->func_specific; + (struct fw_control_info *)payload->func_specific; fwControl->len = IOCTL_BUF_SIZE; /* IN */ fwControl->size = partitionSize + HEADER_LEN;/* IN */ fwControl->retcode = 0;/* OUT */ diff --git a/trunk/drivers/scsi/pm8001/pm8001_defs.h b/trunk/drivers/scsi/pm8001/pm8001_defs.h index 479c5a7a863a..c3d20c8d4abe 100644 --- a/trunk/drivers/scsi/pm8001/pm8001_defs.h +++ b/trunk/drivers/scsi/pm8001/pm8001_defs.h @@ -1,5 +1,5 @@ /* - * PMC-Sierra 8001/8081/8088/8089 SAS/SATA based host adapters driver + * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver * * Copyright (c) 2008-2009 USI Co., Ltd. * All rights reserved. @@ -43,12 +43,9 @@ enum chip_flavors { chip_8001, - chip_8008, - chip_8009, - chip_8018, - chip_8019 }; - +#define USI_MAX_MEMCNT 9 +#define PM8001_MAX_DMA_SG SG_ALL enum phy_speed { PHY_SPEED_15 = 0x01, PHY_SPEED_30 = 0x02, @@ -72,34 +69,23 @@ enum port_type { #define PM8001_MPI_QUEUE 1024 /* maximum mpi queue entries */ #define PM8001_MAX_INB_NUM 1 #define PM8001_MAX_OUTB_NUM 1 -#define PM8001_MAX_SPCV_INB_NUM 1 -#define PM8001_MAX_SPCV_OUTB_NUM 4 #define PM8001_CAN_QUEUE 508 /* SCSI Queue depth */ -/* Inbound/Outbound queue size */ -#define IOMB_SIZE_SPC 64 -#define IOMB_SIZE_SPCV 128 - /* unchangeable hardware details */ -#define PM8001_MAX_PHYS 16 /* max. possible phys */ -#define PM8001_MAX_PORTS 16 /* max. possible ports */ -#define PM8001_MAX_DEVICES 2048 /* max supported device */ -#define PM8001_MAX_MSIX_VEC 64 /* max msi-x int for spcv/ve */ +#define PM8001_MAX_PHYS 8 /* max. possible phys */ +#define PM8001_MAX_PORTS 8 /* max. possible ports */ +#define PM8001_MAX_DEVICES 1024 /* max supported device */ -#define USI_MAX_MEMCNT_BASE 5 -#define IB (USI_MAX_MEMCNT_BASE + 1) -#define CI (IB + PM8001_MAX_SPCV_INB_NUM) -#define OB (CI + PM8001_MAX_SPCV_INB_NUM) -#define PI (OB + PM8001_MAX_SPCV_OUTB_NUM) -#define USI_MAX_MEMCNT (PI + PM8001_MAX_SPCV_OUTB_NUM) -#define PM8001_MAX_DMA_SG SG_ALL enum memory_region_num { AAP1 = 0x0, /* application acceleration processor */ IOP, /* IO processor */ + CI, /* consumer index */ + PI, /* producer index */ + IB, /* inbound queue */ + OB, /* outbound queue */ NVMD, /* NVM device */ DEV_MEM, /* memory for devices */ CCB_MEM, /* memory for command control block */ - FW_FLASH /* memory for fw flash update */ }; #define PM8001_EVENT_LOG_SIZE (128 * 1024) diff --git a/trunk/drivers/scsi/pm8001/pm8001_hwi.c b/trunk/drivers/scsi/pm8001/pm8001_hwi.c index 69dd49c05f1e..b8dd05074abb 100644 --- a/trunk/drivers/scsi/pm8001/pm8001_hwi.c +++ b/trunk/drivers/scsi/pm8001/pm8001_hwi.c @@ -50,39 +50,32 @@ static void read_main_config_table(struct pm8001_hba_info *pm8001_ha) { void __iomem *address = pm8001_ha->main_cfg_tbl_addr; - pm8001_ha->main_cfg_tbl.pm8001_tbl.signature = - pm8001_mr32(address, 0x00); - pm8001_ha->main_cfg_tbl.pm8001_tbl.interface_rev = - pm8001_mr32(address, 0x04); - pm8001_ha->main_cfg_tbl.pm8001_tbl.firmware_rev = - pm8001_mr32(address, 0x08); - pm8001_ha->main_cfg_tbl.pm8001_tbl.max_out_io = - pm8001_mr32(address, 0x0C); - pm8001_ha->main_cfg_tbl.pm8001_tbl.max_sgl = - pm8001_mr32(address, 0x10); - pm8001_ha->main_cfg_tbl.pm8001_tbl.ctrl_cap_flag = - pm8001_mr32(address, 0x14); - pm8001_ha->main_cfg_tbl.pm8001_tbl.gst_offset = - pm8001_mr32(address, 0x18); - pm8001_ha->main_cfg_tbl.pm8001_tbl.inbound_queue_offset = + pm8001_ha->main_cfg_tbl.signature = pm8001_mr32(address, 0x00); + pm8001_ha->main_cfg_tbl.interface_rev = pm8001_mr32(address, 0x04); + pm8001_ha->main_cfg_tbl.firmware_rev = pm8001_mr32(address, 0x08); + pm8001_ha->main_cfg_tbl.max_out_io = pm8001_mr32(address, 0x0C); + pm8001_ha->main_cfg_tbl.max_sgl = pm8001_mr32(address, 0x10); + pm8001_ha->main_cfg_tbl.ctrl_cap_flag = pm8001_mr32(address, 0x14); + pm8001_ha->main_cfg_tbl.gst_offset = pm8001_mr32(address, 0x18); + pm8001_ha->main_cfg_tbl.inbound_queue_offset = pm8001_mr32(address, MAIN_IBQ_OFFSET); - pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_queue_offset = + pm8001_ha->main_cfg_tbl.outbound_queue_offset = pm8001_mr32(address, MAIN_OBQ_OFFSET); - pm8001_ha->main_cfg_tbl.pm8001_tbl.hda_mode_flag = + pm8001_ha->main_cfg_tbl.hda_mode_flag = pm8001_mr32(address, MAIN_HDA_FLAGS_OFFSET); /* read analog Setting offset from the configuration table */ - pm8001_ha->main_cfg_tbl.pm8001_tbl.anolog_setup_table_offset = + pm8001_ha->main_cfg_tbl.anolog_setup_table_offset = pm8001_mr32(address, MAIN_ANALOG_SETUP_OFFSET); /* read Error Dump Offset and Length */ - pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_dump_offset0 = + pm8001_ha->main_cfg_tbl.fatal_err_dump_offset0 = pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP0_OFFSET); - pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_dump_length0 = + pm8001_ha->main_cfg_tbl.fatal_err_dump_length0 = pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP0_LENGTH); - pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_dump_offset1 = + pm8001_ha->main_cfg_tbl.fatal_err_dump_offset1 = pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP1_OFFSET); - pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_dump_length1 = + pm8001_ha->main_cfg_tbl.fatal_err_dump_length1 = pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP1_LENGTH); } @@ -93,56 +86,31 @@ static void read_main_config_table(struct pm8001_hba_info *pm8001_ha) static void read_general_status_table(struct pm8001_hba_info *pm8001_ha) { void __iomem *address = pm8001_ha->general_stat_tbl_addr; - pm8001_ha->gs_tbl.pm8001_tbl.gst_len_mpistate = - pm8001_mr32(address, 0x00); - pm8001_ha->gs_tbl.pm8001_tbl.iq_freeze_state0 = - pm8001_mr32(address, 0x04); - pm8001_ha->gs_tbl.pm8001_tbl.iq_freeze_state1 = - pm8001_mr32(address, 0x08); - pm8001_ha->gs_tbl.pm8001_tbl.msgu_tcnt = - pm8001_mr32(address, 0x0C); - pm8001_ha->gs_tbl.pm8001_tbl.iop_tcnt = - pm8001_mr32(address, 0x10); - pm8001_ha->gs_tbl.pm8001_tbl.rsvd = - pm8001_mr32(address, 0x14); - pm8001_ha->gs_tbl.pm8001_tbl.phy_state[0] = - pm8001_mr32(address, 0x18); - pm8001_ha->gs_tbl.pm8001_tbl.phy_state[1] = - pm8001_mr32(address, 0x1C); - pm8001_ha->gs_tbl.pm8001_tbl.phy_state[2] = - pm8001_mr32(address, 0x20); - pm8001_ha->gs_tbl.pm8001_tbl.phy_state[3] = - pm8001_mr32(address, 0x24); - pm8001_ha->gs_tbl.pm8001_tbl.phy_state[4] = - pm8001_mr32(address, 0x28); - pm8001_ha->gs_tbl.pm8001_tbl.phy_state[5] = - pm8001_mr32(address, 0x2C); - pm8001_ha->gs_tbl.pm8001_tbl.phy_state[6] = - pm8001_mr32(address, 0x30); - pm8001_ha->gs_tbl.pm8001_tbl.phy_state[7] = - pm8001_mr32(address, 0x34); - pm8001_ha->gs_tbl.pm8001_tbl.gpio_input_val = - pm8001_mr32(address, 0x38); - pm8001_ha->gs_tbl.pm8001_tbl.rsvd1[0] = - pm8001_mr32(address, 0x3C); - pm8001_ha->gs_tbl.pm8001_tbl.rsvd1[1] = - pm8001_mr32(address, 0x40); - pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[0] = - pm8001_mr32(address, 0x44); - pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[1] = - pm8001_mr32(address, 0x48); - pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[2] = - pm8001_mr32(address, 0x4C); - pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[3] = - pm8001_mr32(address, 0x50); - pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[4] = - pm8001_mr32(address, 0x54); - pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[5] = - pm8001_mr32(address, 0x58); - pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[6] = - pm8001_mr32(address, 0x5C); - pm8001_ha->gs_tbl.pm8001_tbl.recover_err_info[7] = - pm8001_mr32(address, 0x60); + pm8001_ha->gs_tbl.gst_len_mpistate = pm8001_mr32(address, 0x00); + pm8001_ha->gs_tbl.iq_freeze_state0 = pm8001_mr32(address, 0x04); + pm8001_ha->gs_tbl.iq_freeze_state1 = pm8001_mr32(address, 0x08); + pm8001_ha->gs_tbl.msgu_tcnt = pm8001_mr32(address, 0x0C); + pm8001_ha->gs_tbl.iop_tcnt = pm8001_mr32(address, 0x10); + pm8001_ha->gs_tbl.reserved = pm8001_mr32(address, 0x14); + pm8001_ha->gs_tbl.phy_state[0] = pm8001_mr32(address, 0x18); + pm8001_ha->gs_tbl.phy_state[1] = pm8001_mr32(address, 0x1C); + pm8001_ha->gs_tbl.phy_state[2] = pm8001_mr32(address, 0x20); + pm8001_ha->gs_tbl.phy_state[3] = pm8001_mr32(address, 0x24); + pm8001_ha->gs_tbl.phy_state[4] = pm8001_mr32(address, 0x28); + pm8001_ha->gs_tbl.phy_state[5] = pm8001_mr32(address, 0x2C); + pm8001_ha->gs_tbl.phy_state[6] = pm8001_mr32(address, 0x30); + pm8001_ha->gs_tbl.phy_state[7] = pm8001_mr32(address, 0x34); + pm8001_ha->gs_tbl.reserved1 = pm8001_mr32(address, 0x38); + pm8001_ha->gs_tbl.reserved2 = pm8001_mr32(address, 0x3C); + pm8001_ha->gs_tbl.reserved3 = pm8001_mr32(address, 0x40); + pm8001_ha->gs_tbl.recover_err_info[0] = pm8001_mr32(address, 0x44); + pm8001_ha->gs_tbl.recover_err_info[1] = pm8001_mr32(address, 0x48); + pm8001_ha->gs_tbl.recover_err_info[2] = pm8001_mr32(address, 0x4C); + pm8001_ha->gs_tbl.recover_err_info[3] = pm8001_mr32(address, 0x50); + pm8001_ha->gs_tbl.recover_err_info[4] = pm8001_mr32(address, 0x54); + pm8001_ha->gs_tbl.recover_err_info[5] = pm8001_mr32(address, 0x58); + pm8001_ha->gs_tbl.recover_err_info[6] = pm8001_mr32(address, 0x5C); + pm8001_ha->gs_tbl.recover_err_info[7] = pm8001_mr32(address, 0x60); } /** @@ -151,9 +119,10 @@ static void read_general_status_table(struct pm8001_hba_info *pm8001_ha) */ static void read_inbnd_queue_table(struct pm8001_hba_info *pm8001_ha) { + int inbQ_num = 1; int i; void __iomem *address = pm8001_ha->inbnd_q_tbl_addr; - for (i = 0; i < PM8001_MAX_INB_NUM; i++) { + for (i = 0; i < inbQ_num; i++) { u32 offset = i * 0x20; pm8001_ha->inbnd_q_tbl[i].pi_pci_bar = get_pci_bar_index(pm8001_mr32(address, (offset + 0x14))); @@ -168,9 +137,10 @@ static void read_inbnd_queue_table(struct pm8001_hba_info *pm8001_ha) */ static void read_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha) { + int outbQ_num = 1; int i; void __iomem *address = pm8001_ha->outbnd_q_tbl_addr; - for (i = 0; i < PM8001_MAX_OUTB_NUM; i++) { + for (i = 0; i < outbQ_num; i++) { u32 offset = i * 0x24; pm8001_ha->outbnd_q_tbl[i].ci_pci_bar = get_pci_bar_index(pm8001_mr32(address, (offset + 0x14))); @@ -185,57 +155,54 @@ static void read_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha) */ static void init_default_table_values(struct pm8001_hba_info *pm8001_ha) { + int qn = 1; int i; u32 offsetib, offsetob; void __iomem *addressib = pm8001_ha->inbnd_q_tbl_addr; void __iomem *addressob = pm8001_ha->outbnd_q_tbl_addr; - pm8001_ha->main_cfg_tbl.pm8001_tbl.inbound_q_nppd_hppd = 0; - pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_hw_event_pid0_3 = 0; - pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_hw_event_pid4_7 = 0; - pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_ncq_event_pid0_3 = 0; - pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_ncq_event_pid4_7 = 0; - pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_ITNexus_event_pid0_3 = - 0; - pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_ITNexus_event_pid4_7 = - 0; - pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_ssp_event_pid0_3 = 0; - pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_ssp_event_pid4_7 = 0; - pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_smp_event_pid0_3 = 0; - pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_tgt_smp_event_pid4_7 = 0; - - pm8001_ha->main_cfg_tbl.pm8001_tbl.upper_event_log_addr = + pm8001_ha->main_cfg_tbl.inbound_q_nppd_hppd = 0; + pm8001_ha->main_cfg_tbl.outbound_hw_event_pid0_3 = 0; + pm8001_ha->main_cfg_tbl.outbound_hw_event_pid4_7 = 0; + pm8001_ha->main_cfg_tbl.outbound_ncq_event_pid0_3 = 0; + pm8001_ha->main_cfg_tbl.outbound_ncq_event_pid4_7 = 0; + pm8001_ha->main_cfg_tbl.outbound_tgt_ITNexus_event_pid0_3 = 0; + pm8001_ha->main_cfg_tbl.outbound_tgt_ITNexus_event_pid4_7 = 0; + pm8001_ha->main_cfg_tbl.outbound_tgt_ssp_event_pid0_3 = 0; + pm8001_ha->main_cfg_tbl.outbound_tgt_ssp_event_pid4_7 = 0; + pm8001_ha->main_cfg_tbl.outbound_tgt_smp_event_pid0_3 = 0; + pm8001_ha->main_cfg_tbl.outbound_tgt_smp_event_pid4_7 = 0; + + pm8001_ha->main_cfg_tbl.upper_event_log_addr = pm8001_ha->memoryMap.region[AAP1].phys_addr_hi; - pm8001_ha->main_cfg_tbl.pm8001_tbl.lower_event_log_addr = + pm8001_ha->main_cfg_tbl.lower_event_log_addr = pm8001_ha->memoryMap.region[AAP1].phys_addr_lo; - pm8001_ha->main_cfg_tbl.pm8001_tbl.event_log_size = - PM8001_EVENT_LOG_SIZE; - pm8001_ha->main_cfg_tbl.pm8001_tbl.event_log_option = 0x01; - pm8001_ha->main_cfg_tbl.pm8001_tbl.upper_iop_event_log_addr = + pm8001_ha->main_cfg_tbl.event_log_size = PM8001_EVENT_LOG_SIZE; + pm8001_ha->main_cfg_tbl.event_log_option = 0x01; + pm8001_ha->main_cfg_tbl.upper_iop_event_log_addr = pm8001_ha->memoryMap.region[IOP].phys_addr_hi; - pm8001_ha->main_cfg_tbl.pm8001_tbl.lower_iop_event_log_addr = + pm8001_ha->main_cfg_tbl.lower_iop_event_log_addr = pm8001_ha->memoryMap.region[IOP].phys_addr_lo; - pm8001_ha->main_cfg_tbl.pm8001_tbl.iop_event_log_size = - PM8001_EVENT_LOG_SIZE; - pm8001_ha->main_cfg_tbl.pm8001_tbl.iop_event_log_option = 0x01; - pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_interrupt = 0x01; - for (i = 0; i < PM8001_MAX_INB_NUM; i++) { + pm8001_ha->main_cfg_tbl.iop_event_log_size = PM8001_EVENT_LOG_SIZE; + pm8001_ha->main_cfg_tbl.iop_event_log_option = 0x01; + pm8001_ha->main_cfg_tbl.fatal_err_interrupt = 0x01; + for (i = 0; i < qn; i++) { pm8001_ha->inbnd_q_tbl[i].element_pri_size_cnt = PM8001_MPI_QUEUE | (64 << 16) | (0x00<<30); pm8001_ha->inbnd_q_tbl[i].upper_base_addr = - pm8001_ha->memoryMap.region[IB + i].phys_addr_hi; + pm8001_ha->memoryMap.region[IB].phys_addr_hi; pm8001_ha->inbnd_q_tbl[i].lower_base_addr = - pm8001_ha->memoryMap.region[IB + i].phys_addr_lo; + pm8001_ha->memoryMap.region[IB].phys_addr_lo; pm8001_ha->inbnd_q_tbl[i].base_virt = - (u8 *)pm8001_ha->memoryMap.region[IB + i].virt_ptr; + (u8 *)pm8001_ha->memoryMap.region[IB].virt_ptr; pm8001_ha->inbnd_q_tbl[i].total_length = - pm8001_ha->memoryMap.region[IB + i].total_len; + pm8001_ha->memoryMap.region[IB].total_len; pm8001_ha->inbnd_q_tbl[i].ci_upper_base_addr = - pm8001_ha->memoryMap.region[CI + i].phys_addr_hi; + pm8001_ha->memoryMap.region[CI].phys_addr_hi; pm8001_ha->inbnd_q_tbl[i].ci_lower_base_addr = - pm8001_ha->memoryMap.region[CI + i].phys_addr_lo; + pm8001_ha->memoryMap.region[CI].phys_addr_lo; pm8001_ha->inbnd_q_tbl[i].ci_virt = - pm8001_ha->memoryMap.region[CI + i].virt_ptr; + pm8001_ha->memoryMap.region[CI].virt_ptr; offsetib = i * 0x20; pm8001_ha->inbnd_q_tbl[i].pi_pci_bar = get_pci_bar_index(pm8001_mr32(addressib, @@ -245,25 +212,25 @@ static void init_default_table_values(struct pm8001_hba_info *pm8001_ha) pm8001_ha->inbnd_q_tbl[i].producer_idx = 0; pm8001_ha->inbnd_q_tbl[i].consumer_index = 0; } - for (i = 0; i < PM8001_MAX_OUTB_NUM; i++) { + for (i = 0; i < qn; i++) { pm8001_ha->outbnd_q_tbl[i].element_size_cnt = PM8001_MPI_QUEUE | (64 << 16) | (0x01<<30); pm8001_ha->outbnd_q_tbl[i].upper_base_addr = - pm8001_ha->memoryMap.region[OB + i].phys_addr_hi; + pm8001_ha->memoryMap.region[OB].phys_addr_hi; pm8001_ha->outbnd_q_tbl[i].lower_base_addr = - pm8001_ha->memoryMap.region[OB + i].phys_addr_lo; + pm8001_ha->memoryMap.region[OB].phys_addr_lo; pm8001_ha->outbnd_q_tbl[i].base_virt = - (u8 *)pm8001_ha->memoryMap.region[OB + i].virt_ptr; + (u8 *)pm8001_ha->memoryMap.region[OB].virt_ptr; pm8001_ha->outbnd_q_tbl[i].total_length = - pm8001_ha->memoryMap.region[OB + i].total_len; + pm8001_ha->memoryMap.region[OB].total_len; pm8001_ha->outbnd_q_tbl[i].pi_upper_base_addr = - pm8001_ha->memoryMap.region[PI + i].phys_addr_hi; + pm8001_ha->memoryMap.region[PI].phys_addr_hi; pm8001_ha->outbnd_q_tbl[i].pi_lower_base_addr = - pm8001_ha->memoryMap.region[PI + i].phys_addr_lo; + pm8001_ha->memoryMap.region[PI].phys_addr_lo; pm8001_ha->outbnd_q_tbl[i].interrup_vec_cnt_delay = - 0 | (10 << 16) | (i << 24); + 0 | (10 << 16) | (0 << 24); pm8001_ha->outbnd_q_tbl[i].pi_virt = - pm8001_ha->memoryMap.region[PI + i].virt_ptr; + pm8001_ha->memoryMap.region[PI].virt_ptr; offsetob = i * 0x24; pm8001_ha->outbnd_q_tbl[i].ci_pci_bar = get_pci_bar_index(pm8001_mr32(addressob, @@ -283,51 +250,42 @@ static void update_main_config_table(struct pm8001_hba_info *pm8001_ha) { void __iomem *address = pm8001_ha->main_cfg_tbl_addr; pm8001_mw32(address, 0x24, - pm8001_ha->main_cfg_tbl.pm8001_tbl.inbound_q_nppd_hppd); + pm8001_ha->main_cfg_tbl.inbound_q_nppd_hppd); pm8001_mw32(address, 0x28, - pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_hw_event_pid0_3); + pm8001_ha->main_cfg_tbl.outbound_hw_event_pid0_3); pm8001_mw32(address, 0x2C, - pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_hw_event_pid4_7); + pm8001_ha->main_cfg_tbl.outbound_hw_event_pid4_7); pm8001_mw32(address, 0x30, - pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_ncq_event_pid0_3); + pm8001_ha->main_cfg_tbl.outbound_ncq_event_pid0_3); pm8001_mw32(address, 0x34, - pm8001_ha->main_cfg_tbl.pm8001_tbl.outbound_ncq_event_pid4_7); + pm8001_ha->main_cfg_tbl.outbound_ncq_event_pid4_7); pm8001_mw32(address, 0x38, - pm8001_ha->main_cfg_tbl.pm8001_tbl. - outbound_tgt_ITNexus_event_pid0_3); + pm8001_ha->main_cfg_tbl.outbound_tgt_ITNexus_event_pid0_3); pm8001_mw32(address, 0x3C, - pm8001_ha->main_cfg_tbl.pm8001_tbl. - outbound_tgt_ITNexus_event_pid4_7); + pm8001_ha->main_cfg_tbl.outbound_tgt_ITNexus_event_pid4_7); pm8001_mw32(address, 0x40, - pm8001_ha->main_cfg_tbl.pm8001_tbl. - outbound_tgt_ssp_event_pid0_3); + pm8001_ha->main_cfg_tbl.outbound_tgt_ssp_event_pid0_3); pm8001_mw32(address, 0x44, - pm8001_ha->main_cfg_tbl.pm8001_tbl. - outbound_tgt_ssp_event_pid4_7); + pm8001_ha->main_cfg_tbl.outbound_tgt_ssp_event_pid4_7); pm8001_mw32(address, 0x48, - pm8001_ha->main_cfg_tbl.pm8001_tbl. - outbound_tgt_smp_event_pid0_3); + pm8001_ha->main_cfg_tbl.outbound_tgt_smp_event_pid0_3); pm8001_mw32(address, 0x4C, - pm8001_ha->main_cfg_tbl.pm8001_tbl. - outbound_tgt_smp_event_pid4_7); + pm8001_ha->main_cfg_tbl.outbound_tgt_smp_event_pid4_7); pm8001_mw32(address, 0x50, - pm8001_ha->main_cfg_tbl.pm8001_tbl.upper_event_log_addr); + pm8001_ha->main_cfg_tbl.upper_event_log_addr); pm8001_mw32(address, 0x54, - pm8001_ha->main_cfg_tbl.pm8001_tbl.lower_event_log_addr); - pm8001_mw32(address, 0x58, - pm8001_ha->main_cfg_tbl.pm8001_tbl.event_log_size); - pm8001_mw32(address, 0x5C, - pm8001_ha->main_cfg_tbl.pm8001_tbl.event_log_option); + pm8001_ha->main_cfg_tbl.lower_event_log_addr); + pm8001_mw32(address, 0x58, pm8001_ha->main_cfg_tbl.event_log_size); + pm8001_mw32(address, 0x5C, pm8001_ha->main_cfg_tbl.event_log_option); pm8001_mw32(address, 0x60, - pm8001_ha->main_cfg_tbl.pm8001_tbl.upper_iop_event_log_addr); + pm8001_ha->main_cfg_tbl.upper_iop_event_log_addr); pm8001_mw32(address, 0x64, - pm8001_ha->main_cfg_tbl.pm8001_tbl.lower_iop_event_log_addr); - pm8001_mw32(address, 0x68, - pm8001_ha->main_cfg_tbl.pm8001_tbl.iop_event_log_size); + pm8001_ha->main_cfg_tbl.lower_iop_event_log_addr); + pm8001_mw32(address, 0x68, pm8001_ha->main_cfg_tbl.iop_event_log_size); pm8001_mw32(address, 0x6C, - pm8001_ha->main_cfg_tbl.pm8001_tbl.iop_event_log_option); + pm8001_ha->main_cfg_tbl.iop_event_log_option); pm8001_mw32(address, 0x70, - pm8001_ha->main_cfg_tbl.pm8001_tbl.fatal_err_interrupt); + pm8001_ha->main_cfg_tbl.fatal_err_interrupt); } /** @@ -639,19 +597,6 @@ static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha) */ static int pm8001_chip_init(struct pm8001_hba_info *pm8001_ha) { - u8 i = 0; - u16 deviceid; - pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid); - /* 8081 controllers need BAR shift to access MPI space - * as this is shared with BIOS data */ - if (deviceid == 0x8081) { - if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_SM_BASE)) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("Shift Bar4 to 0x%x failed\n", - GSM_SM_BASE)); - return -1; - } - } /* check the firmware status */ if (-1 == check_fw_ready(pm8001_ha)) { PM8001_FAIL_DBG(pm8001_ha, @@ -668,16 +613,11 @@ static int pm8001_chip_init(struct pm8001_hba_info *pm8001_ha) read_outbnd_queue_table(pm8001_ha); /* update main config table ,inbound table and outbound table */ update_main_config_table(pm8001_ha); - for (i = 0; i < PM8001_MAX_INB_NUM; i++) - update_inbnd_queue_table(pm8001_ha, i); - for (i = 0; i < PM8001_MAX_OUTB_NUM; i++) - update_outbnd_queue_table(pm8001_ha, i); - /* 8081 controller donot require these operations */ - if (deviceid != 0x8081) { - mpi_set_phys_g3_with_ssc(pm8001_ha, 0); - /* 7->130ms, 34->500ms, 119->1.5s */ - mpi_set_open_retry_interval_reg(pm8001_ha, 119); - } + update_inbnd_queue_table(pm8001_ha, 0); + update_outbnd_queue_table(pm8001_ha, 0); + mpi_set_phys_g3_with_ssc(pm8001_ha, 0); + /* 7->130ms, 34->500ms, 119->1.5s */ + mpi_set_open_retry_interval_reg(pm8001_ha, 119); /* notify firmware update finished and check initialization status */ if (0 == mpi_init_check(pm8001_ha)) { PM8001_INIT_DBG(pm8001_ha, @@ -699,16 +639,6 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha) u32 max_wait_count; u32 value; u32 gst_len_mpistate; - u16 deviceid; - pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid); - if (deviceid == 0x8081) { - if (-1 == pm8001_bar4_shift(pm8001_ha, GSM_SM_BASE)) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("Shift Bar4 to 0x%x failed\n", - GSM_SM_BASE)); - return -1; - } - } init_pci_device_addresses(pm8001_ha); /* Write bit1=1 to Inbound DoorBell Register to tell the SPC FW the table is stop */ @@ -810,14 +740,14 @@ static u32 soft_reset_ready_check(struct pm8001_hba_info *pm8001_ha) * pm8001_chip_soft_rst - soft reset the PM8001 chip, so that the clear all * the FW register status to the originated status. * @pm8001_ha: our hba card information + * @signature: signature in host scratch pad0 register. */ static int -pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) +pm8001_chip_soft_rst(struct pm8001_hba_info *pm8001_ha, u32 signature) { u32 regVal, toggleVal; u32 max_wait_count; u32 regVal1, regVal2, regVal3; - u32 signature = 0x252acbcd; /* for host scratch pad0 */ unsigned long flags; /* step1: Check FW is ready for soft reset */ @@ -1183,7 +1113,7 @@ static void pm8001_hw_chip_rst(struct pm8001_hba_info *pm8001_ha) * pm8001_chip_iounmap - which maped when initialized. * @pm8001_ha: our hba card information */ -void pm8001_chip_iounmap(struct pm8001_hba_info *pm8001_ha) +static void pm8001_chip_iounmap(struct pm8001_hba_info *pm8001_ha) { s8 bar, logical = 0; for (bar = 0; bar < 6; bar++) { @@ -1262,7 +1192,7 @@ pm8001_chip_msix_interrupt_disable(struct pm8001_hba_info *pm8001_ha, * @pm8001_ha: our hba card information */ static void -pm8001_chip_interrupt_enable(struct pm8001_hba_info *pm8001_ha, u8 vec) +pm8001_chip_interrupt_enable(struct pm8001_hba_info *pm8001_ha) { #ifdef PM8001_USE_MSIX pm8001_chip_msix_interrupt_enable(pm8001_ha, 0); @@ -1277,7 +1207,7 @@ pm8001_chip_interrupt_enable(struct pm8001_hba_info *pm8001_ha, u8 vec) * @pm8001_ha: our hba card information */ static void -pm8001_chip_interrupt_disable(struct pm8001_hba_info *pm8001_ha, u8 vec) +pm8001_chip_interrupt_disable(struct pm8001_hba_info *pm8001_ha) { #ifdef PM8001_USE_MSIX pm8001_chip_msix_interrupt_disable(pm8001_ha, 0); @@ -1288,13 +1218,12 @@ pm8001_chip_interrupt_disable(struct pm8001_hba_info *pm8001_ha, u8 vec) } /** - * pm8001_mpi_msg_free_get - get the free message buffer for transfer - * inbound queue. + * mpi_msg_free_get- get the free message buffer for transfer inbound queue. * @circularQ: the inbound queue we want to transfer to HBA. * @messageSize: the message size of this transfer, normally it is 64 bytes * @messagePtr: the pointer to message. */ -int pm8001_mpi_msg_free_get(struct inbound_queue_table *circularQ, +static int mpi_msg_free_get(struct inbound_queue_table *circularQ, u16 messageSize, void **messagePtr) { u32 offset, consumer_index; @@ -1302,7 +1231,7 @@ int pm8001_mpi_msg_free_get(struct inbound_queue_table *circularQ, u8 bcCount = 1; /* only support single buffer */ /* Checks is the requested message size can be allocated in this queue*/ - if (messageSize > IOMB_SIZE_SPCV) { + if (messageSize > 64) { *messagePtr = NULL; return -1; } @@ -1316,7 +1245,7 @@ int pm8001_mpi_msg_free_get(struct inbound_queue_table *circularQ, return -1; } /* get memory IOMB buffer address */ - offset = circularQ->producer_idx * messageSize; + offset = circularQ->producer_idx * 64; /* increment to next bcCount element */ circularQ->producer_idx = (circularQ->producer_idx + bcCount) % PM8001_MPI_QUEUE; @@ -1328,30 +1257,29 @@ int pm8001_mpi_msg_free_get(struct inbound_queue_table *circularQ, } /** - * pm8001_mpi_build_cmd- build the message queue for transfer, update the PI to - * FW to tell the fw to get this message from IOMB. + * mpi_build_cmd- build the message queue for transfer, update the PI to FW + * to tell the fw to get this message from IOMB. * @pm8001_ha: our hba card information * @circularQ: the inbound queue we want to transfer to HBA. * @opCode: the operation code represents commands which LLDD and fw recognized. * @payload: the command payload of each operation command. */ -int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha, +static int mpi_build_cmd(struct pm8001_hba_info *pm8001_ha, struct inbound_queue_table *circularQ, - u32 opCode, void *payload, u32 responseQueue) + u32 opCode, void *payload) { u32 Header = 0, hpriority = 0, bc = 1, category = 0x02; + u32 responseQueue = 0; void *pMessage; - if (pm8001_mpi_msg_free_get(circularQ, pm8001_ha->iomb_size, - &pMessage) < 0) { + if (mpi_msg_free_get(circularQ, 64, &pMessage) < 0) { PM8001_IO_DBG(pm8001_ha, pm8001_printk("No free mpi buffer\n")); return -1; } BUG_ON(!payload); /*Copy to the payload*/ - memcpy(pMessage, payload, (pm8001_ha->iomb_size - - sizeof(struct mpi_msg_hdr))); + memcpy(pMessage, payload, (64 - sizeof(struct mpi_msg_hdr))); /*Build the header*/ Header = ((1 << 31) | (hpriority << 30) | ((bc & 0x1f) << 24) @@ -1363,13 +1291,12 @@ int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha, pm8001_cw32(pm8001_ha, circularQ->pi_pci_bar, circularQ->pi_offset, circularQ->producer_idx); PM8001_IO_DBG(pm8001_ha, - pm8001_printk("INB Q %x OPCODE:%x , UPDATED PI=%d CI=%d\n", - responseQueue, opCode, circularQ->producer_idx, - circularQ->consumer_index)); + pm8001_printk("after PI= %d CI= %d\n", circularQ->producer_idx, + circularQ->consumer_index)); return 0; } -u32 pm8001_mpi_msg_free_set(struct pm8001_hba_info *pm8001_ha, void *pMsg, +static u32 mpi_msg_free_set(struct pm8001_hba_info *pm8001_ha, void *pMsg, struct outbound_queue_table *circularQ, u8 bc) { u32 producer_index; @@ -1378,7 +1305,7 @@ u32 pm8001_mpi_msg_free_set(struct pm8001_hba_info *pm8001_ha, void *pMsg, msgHeader = (struct mpi_msg_hdr *)(pMsg - sizeof(struct mpi_msg_hdr)); pOutBoundMsgHeader = (struct mpi_msg_hdr *)(circularQ->base_virt + - circularQ->consumer_idx * pm8001_ha->iomb_size); + circularQ->consumer_idx * 64); if (pOutBoundMsgHeader != msgHeader) { PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("consumer_idx = %d msgHeader = %p\n", @@ -1409,14 +1336,13 @@ u32 pm8001_mpi_msg_free_set(struct pm8001_hba_info *pm8001_ha, void *pMsg, } /** - * pm8001_mpi_msg_consume- get the MPI message from outbound queue - * message table. + * mpi_msg_consume- get the MPI message from outbound queue message table. * @pm8001_ha: our hba card information * @circularQ: the outbound queue table. * @messagePtr1: the message contents of this outbound message. * @pBC: the message size. */ -u32 pm8001_mpi_msg_consume(struct pm8001_hba_info *pm8001_ha, +static u32 mpi_msg_consume(struct pm8001_hba_info *pm8001_ha, struct outbound_queue_table *circularQ, void **messagePtr1, u8 *pBC) { @@ -1430,7 +1356,7 @@ u32 pm8001_mpi_msg_consume(struct pm8001_hba_info *pm8001_ha, /*Get the pointer to the circular queue buffer element*/ msgHeader = (struct mpi_msg_hdr *) (circularQ->base_virt + - circularQ->consumer_idx * pm8001_ha->iomb_size); + circularQ->consumer_idx * 64); /* read header */ header_tmp = pm8001_read_32(msgHeader); msgHeader_tmp = cpu_to_le32(header_tmp); @@ -1490,7 +1416,7 @@ u32 pm8001_mpi_msg_consume(struct pm8001_hba_info *pm8001_ha, return MPI_IO_STATUS_BUSY; } -void pm8001_work_fn(struct work_struct *work) +static void pm8001_work_fn(struct work_struct *work) { struct pm8001_work *pw = container_of(work, struct pm8001_work, work); struct pm8001_device *pm8001_dev; @@ -1505,7 +1431,7 @@ void pm8001_work_fn(struct work_struct *work) pm8001_dev = pw->data; /* Most stash device structure */ if ((pm8001_dev == NULL) || ((pw->handler != IO_XFER_ERROR_BREAK) - && (pm8001_dev->dev_type == SAS_PHY_UNUSED))) { + && (pm8001_dev->dev_type == NO_DEVICE))) { kfree(pw); return; } @@ -1670,7 +1596,7 @@ void pm8001_work_fn(struct work_struct *work) } break; case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: dev = pm8001_dev->sas_device; - pm8001_I_T_nexus_event_handler(dev); + pm8001_I_T_nexus_reset(dev); break; case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY: dev = pm8001_dev->sas_device; @@ -1688,7 +1614,7 @@ void pm8001_work_fn(struct work_struct *work) kfree(pw); } -int pm8001_handle_event(struct pm8001_hba_info *pm8001_ha, void *data, +static int pm8001_handle_event(struct pm8001_hba_info *pm8001_ha, void *data, int handler) { struct pm8001_work *pw; @@ -1707,123 +1633,6 @@ int pm8001_handle_event(struct pm8001_hba_info *pm8001_ha, void *data, return ret; } -static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha, - struct pm8001_device *pm8001_ha_dev) -{ - int res; - u32 ccb_tag; - struct pm8001_ccb_info *ccb; - struct sas_task *task = NULL; - struct task_abort_req task_abort; - struct inbound_queue_table *circularQ; - u32 opc = OPC_INB_SATA_ABORT; - int ret; - - if (!pm8001_ha_dev) { - PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("dev is null\n")); - return; - } - - task = sas_alloc_slow_task(GFP_ATOMIC); - - if (!task) { - PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("cannot " - "allocate task\n")); - return; - } - - task->task_done = pm8001_task_done; - - res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); - if (res) - return; - - ccb = &pm8001_ha->ccb_info[ccb_tag]; - ccb->device = pm8001_ha_dev; - ccb->ccb_tag = ccb_tag; - ccb->task = task; - - circularQ = &pm8001_ha->inbnd_q_tbl[0]; - - memset(&task_abort, 0, sizeof(task_abort)); - task_abort.abort_all = cpu_to_le32(1); - task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id); - task_abort.tag = cpu_to_le32(ccb_tag); - - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, 0); - -} - -static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha, - struct pm8001_device *pm8001_ha_dev) -{ - struct sata_start_req sata_cmd; - int res; - u32 ccb_tag; - struct pm8001_ccb_info *ccb; - struct sas_task *task = NULL; - struct host_to_dev_fis fis; - struct domain_device *dev; - struct inbound_queue_table *circularQ; - u32 opc = OPC_INB_SATA_HOST_OPSTART; - - task = sas_alloc_slow_task(GFP_ATOMIC); - - if (!task) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("cannot allocate task !!!\n")); - return; - } - task->task_done = pm8001_task_done; - - res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); - if (res) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("cannot allocate tag !!!\n")); - return; - } - - /* allocate domain device by ourselves as libsas - * is not going to provide any - */ - dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC); - if (!dev) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("Domain device cannot be allocated\n")); - sas_free_task(task); - return; - } else { - task->dev = dev; - task->dev->lldd_dev = pm8001_ha_dev; - } - - ccb = &pm8001_ha->ccb_info[ccb_tag]; - ccb->device = pm8001_ha_dev; - ccb->ccb_tag = ccb_tag; - ccb->task = task; - pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG; - pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG; - - memset(&sata_cmd, 0, sizeof(sata_cmd)); - circularQ = &pm8001_ha->inbnd_q_tbl[0]; - - /* construct read log FIS */ - memset(&fis, 0, sizeof(struct host_to_dev_fis)); - fis.fis_type = 0x27; - fis.flags = 0x80; - fis.command = ATA_CMD_READ_LOG_EXT; - fis.lbal = 0x10; - fis.sector_count = 0x1; - - sata_cmd.tag = cpu_to_le32(ccb_tag); - sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id); - sata_cmd.ncqtag_atap_dir_m |= ((0x1 << 7) | (0x5 << 9)); - memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis)); - - res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, 0); - -} - /** * mpi_ssp_completion- process the event that FW response to the SSP request. * @pm8001_ha: our hba card information @@ -2058,7 +1867,7 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) break; } PM8001_IO_DBG(pm8001_ha, - pm8001_printk("scsi_status = %x\n ", + pm8001_printk("scsi_status = %x \n ", psspPayload->ssp_resp_iu.status)); spin_lock_irqsave(&t->task_state_lock, flags); t->task_state_flags &= ~SAS_TASK_STATE_PENDING; @@ -2287,44 +2096,16 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) status = le32_to_cpu(psataPayload->status); tag = le32_to_cpu(psataPayload->tag); - if (!tag) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("tag null\n")); - return; - } ccb = &pm8001_ha->ccb_info[tag]; param = le32_to_cpu(psataPayload->param); - if (ccb) { - t = ccb->task; - pm8001_dev = ccb->device; - } else { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("ccb null\n")); - return; - } - - if (t) { - if (t->dev && (t->dev->lldd_dev)) - pm8001_dev = t->dev->lldd_dev; - } else { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("task null\n")); - return; - } - - if ((pm8001_dev && !(pm8001_dev->id & NCQ_READ_LOG_FLAG)) - && unlikely(!t || !t->lldd_task || !t->dev)) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("task or dev null\n")); - return; - } - + t = ccb->task; ts = &t->task_status; - if (!ts) { + pm8001_dev = ccb->device; + if (status) PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("ts null\n")); + pm8001_printk("sata IO status 0x%x\n", status)); + if (unlikely(!t || !t->lldd_task || !t->dev)) return; - } switch (status) { case IO_SUCCESS: @@ -2332,19 +2113,6 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) if (param == 0) { ts->resp = SAS_TASK_COMPLETE; ts->stat = SAM_STAT_GOOD; - /* check if response is for SEND READ LOG */ - if (pm8001_dev && - (pm8001_dev->id & NCQ_READ_LOG_FLAG)) { - /* set new bit for abort_all */ - pm8001_dev->id |= NCQ_ABORT_ALL_FLAG; - /* clear bit for read log */ - pm8001_dev->id = pm8001_dev->id & 0x7FFFFFFF; - pm8001_send_abort_all(pm8001_ha, pm8001_dev); - /* Free the tag */ - pm8001_tag_free(pm8001_ha, tag); - sas_free_task(t); - return; - } } else { u8 len; ts->resp = SAS_TASK_COMPLETE; @@ -2655,29 +2423,6 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) u32 dev_id = le32_to_cpu(psataPayload->device_id); unsigned long flags; - ccb = &pm8001_ha->ccb_info[tag]; - - if (ccb) { - t = ccb->task; - pm8001_dev = ccb->device; - } else { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("No CCB !!!. returning\n")); - } - if (event) - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("SATA EVENT 0x%x\n", event)); - - /* Check if this is NCQ error */ - if (event == IO_XFER_ERROR_ABORTED_NCQ_MODE) { - /* find device using device id */ - pm8001_dev = pm8001_find_dev(pm8001_ha, dev_id); - /* send read log extension */ - if (pm8001_dev) - pm8001_send_read_log(pm8001_ha, pm8001_dev); - return; - } - ccb = &pm8001_ha->ccb_info[tag]; t = ccb->task; pm8001_dev = ccb->device; @@ -2687,9 +2432,9 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) if (unlikely(!t || !t->lldd_task || !t->dev)) return; ts = &t->task_status; - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "port_id:0x%x, device_id:0x%x, tag:0x%x, event:0x%x\n", - port_id, dev_id, tag, event)); + PM8001_IO_DBG(pm8001_ha, + pm8001_printk("port_id = %x,device_id = %x\n", + port_id, dev_id)); switch (event) { case IO_OVERFLOW: PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n")); @@ -3077,8 +2822,8 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) } } -void pm8001_mpi_set_dev_state_resp(struct pm8001_hba_info *pm8001_ha, - void *piomb) +static void +mpi_set_dev_state_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) { struct set_dev_state_resp *pPayload = (struct set_dev_state_resp *)(piomb + 4); @@ -3098,7 +2843,8 @@ void pm8001_mpi_set_dev_state_resp(struct pm8001_hba_info *pm8001_ha, pm8001_ccb_free(pm8001_ha, tag); } -void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) +static void +mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) { struct get_nvm_data_resp *pPayload = (struct get_nvm_data_resp *)(piomb + 4); @@ -3117,8 +2863,8 @@ void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_ccb_free(pm8001_ha, tag); } -void -pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) +static void +mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) { struct fw_control_ex *fw_control_context; struct get_nvm_data_resp *pPayload = @@ -3179,7 +2925,7 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_ccb_free(pm8001_ha, tag); } -int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb) +static int mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb) { struct local_phy_ctl_resp *pPayload = (struct local_phy_ctl_resp *)(piomb + 4); @@ -3208,7 +2954,7 @@ int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb) * while receive a broadcast(change) primitive just tell the sas * layer to discover the changed domain rather than the whole domain. */ -void pm8001_bytes_dmaed(struct pm8001_hba_info *pm8001_ha, int i) +static void pm8001_bytes_dmaed(struct pm8001_hba_info *pm8001_ha, int i) { struct pm8001_phy *phy = &pm8001_ha->phy[i]; struct asd_sas_phy *sas_phy = &phy->sas_phy; @@ -3242,7 +2988,7 @@ void pm8001_bytes_dmaed(struct pm8001_hba_info *pm8001_ha, int i) } /* Get the link rate speed */ -void pm8001_get_lrate_mode(struct pm8001_phy *phy, u8 link_rate) +static void get_lrate_mode(struct pm8001_phy *phy, u8 link_rate) { struct sas_phy *sas_phy = phy->sas_phy.phy; @@ -3279,7 +3025,7 @@ void pm8001_get_lrate_mode(struct pm8001_phy *phy, u8 link_rate) * LOCKING: the frame_rcvd_lock needs to be held since this parses the frame * buffer. */ -void pm8001_get_attached_sas_addr(struct pm8001_phy *phy, +static void pm8001_get_attached_sas_addr(struct pm8001_phy *phy, u8 *sas_addr) { if (phy->sas_phy.frame_rcvd[0] == 0x34 @@ -3321,7 +3067,7 @@ static void pm8001_hw_event_ack_req(struct pm8001_hba_info *pm8001_ha, ((phyId & 0x0F) << 4) | (port_id & 0x0F)); payload.param0 = cpu_to_le32(param0); payload.param1 = cpu_to_le32(param1); - pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); + mpi_build_cmd(pm8001_ha, circularQ, opc, &payload); } static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha, @@ -3366,19 +3112,19 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_chip_phy_ctl_req(pm8001_ha, phy_id, PHY_NOTIFY_ENABLE_SPINUP); port->port_attached = 1; - pm8001_get_lrate_mode(phy, link_rate); + get_lrate_mode(phy, link_rate); break; case SAS_EDGE_EXPANDER_DEVICE: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("expander device.\n")); port->port_attached = 1; - pm8001_get_lrate_mode(phy, link_rate); + get_lrate_mode(phy, link_rate); break; case SAS_FANOUT_EXPANDER_DEVICE: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("fanout expander device.\n")); port->port_attached = 1; - pm8001_get_lrate_mode(phy, link_rate); + get_lrate_mode(phy, link_rate); break; default: PM8001_MSG_DBG(pm8001_ha, @@ -3433,7 +3179,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) " phy id = %d\n", port_id, phy_id)); port->port_state = portstate; port->port_attached = 1; - pm8001_get_lrate_mode(phy, link_rate); + get_lrate_mode(phy, link_rate); phy->phy_type |= PORT_TYPE_SATA; phy->phy_attached = 1; phy->sas_phy.oob_mode = SATA_OOB_MODE; @@ -3443,7 +3189,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) sizeof(struct dev_to_host_fis)); phy->frame_rcvd_size = sizeof(struct dev_to_host_fis); phy->identify.target_port_protocols = SAS_PROTOCOL_SATA; - phy->identify.device_type = SAS_SATA_DEV; + phy->identify.device_type = SATA_DEV; pm8001_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr); spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags); pm8001_bytes_dmaed(pm8001_ha, phy_id); @@ -3514,7 +3260,7 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb) } /** - * pm8001_mpi_reg_resp -process register device ID response. + * mpi_reg_resp -process register device ID response. * @pm8001_ha: our hba card information * @piomb: IO message buffer * @@ -3523,7 +3269,7 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb) * has assigned, from now,inter-communication with FW is no longer using the * SAS address, use device ID which FW assigned. */ -int pm8001_mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) +static int mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) { u32 status; u32 device_id; @@ -3585,7 +3331,7 @@ int pm8001_mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) return 0; } -int pm8001_mpi_dereg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) +static int mpi_dereg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) { u32 status; u32 device_id; @@ -3601,13 +3347,8 @@ int pm8001_mpi_dereg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) return 0; } -/** - * fw_flash_update_resp - Response from FW for flash update command. - * @pm8001_ha: our hba card information - * @piomb: IO message buffer - */ -int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, - void *piomb) +static int +mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) { u32 status; struct fw_control_ex fw_control_context; @@ -3662,6 +3403,10 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, break; } ccb->fw_control_context->fw_control->retcode = status; + pci_free_consistent(pm8001_ha->pdev, + fw_control_context.len, + fw_control_context.virtAddr, + fw_control_context.phys_addr); complete(pm8001_ha->nvmd_completion); ccb->task = NULL; ccb->ccb_tag = 0xFFFFFFFF; @@ -3669,7 +3414,8 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, return 0; } -int pm8001_mpi_general_event(struct pm8001_hba_info *pm8001_ha , void *piomb) +static int +mpi_general_event(struct pm8001_hba_info *pm8001_ha , void *piomb) { u32 status; int i; @@ -3685,7 +3431,8 @@ int pm8001_mpi_general_event(struct pm8001_hba_info *pm8001_ha , void *piomb) return 0; } -int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) +static int +mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) { struct sas_task *t; struct pm8001_ccb_info *ccb; @@ -3693,29 +3440,19 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) u32 status ; u32 tag, scp; struct task_status_struct *ts; - struct pm8001_device *pm8001_dev; struct task_abort_resp *pPayload = (struct task_abort_resp *)(piomb + 4); status = le32_to_cpu(pPayload->status); tag = le32_to_cpu(pPayload->tag); - if (!tag) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk(" TAG NULL. RETURNING !!!")); - return -1; - } - scp = le32_to_cpu(pPayload->scp); ccb = &pm8001_ha->ccb_info[tag]; t = ccb->task; - pm8001_dev = ccb->device; /* retrieve device */ - - if (!t) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk(" TASK NULL. RETURNING !!!")); + PM8001_IO_DBG(pm8001_ha, + pm8001_printk(" status = 0x%x\n", status)); + if (t == NULL) return -1; - } ts = &t->task_status; if (status != 0) PM8001_FAIL_DBG(pm8001_ha, @@ -3739,15 +3476,7 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) spin_unlock_irqrestore(&t->task_state_lock, flags); pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); mb(); - - if ((pm8001_dev->id & NCQ_ABORT_ALL_FLAG) && t) { - pm8001_tag_free(pm8001_ha, tag); - sas_free_task(t); - /* clear the flag */ - pm8001_dev->id &= 0xBFFFFFFF; - } else - t->task_done(t); - + t->task_done(t); return 0; } @@ -3998,17 +3727,17 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) case OPC_OUB_LOCAL_PHY_CNTRL: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("OPC_OUB_LOCAL_PHY_CNTRL\n")); - pm8001_mpi_local_phy_ctl(pm8001_ha, piomb); + mpi_local_phy_ctl(pm8001_ha, piomb); break; case OPC_OUB_DEV_REGIST: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("OPC_OUB_DEV_REGIST\n")); - pm8001_mpi_reg_resp(pm8001_ha, piomb); + mpi_reg_resp(pm8001_ha, piomb); break; case OPC_OUB_DEREG_DEV: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("unregister the device\n")); - pm8001_mpi_dereg_resp(pm8001_ha, piomb); + mpi_dereg_resp(pm8001_ha, piomb); break; case OPC_OUB_GET_DEV_HANDLE: PM8001_MSG_DBG(pm8001_ha, @@ -4046,7 +3775,7 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) case OPC_OUB_FW_FLASH_UPDATE: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("OPC_OUB_FW_FLASH_UPDATE\n")); - pm8001_mpi_fw_flash_update_resp(pm8001_ha, piomb); + mpi_fw_flash_update_resp(pm8001_ha, piomb); break; case OPC_OUB_GPIO_RESPONSE: PM8001_MSG_DBG(pm8001_ha, @@ -4059,17 +3788,17 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) case OPC_OUB_GENERAL_EVENT: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("OPC_OUB_GENERAL_EVENT\n")); - pm8001_mpi_general_event(pm8001_ha, piomb); + mpi_general_event(pm8001_ha, piomb); break; case OPC_OUB_SSP_ABORT_RSP: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("OPC_OUB_SSP_ABORT_RSP\n")); - pm8001_mpi_task_abort_resp(pm8001_ha, piomb); + mpi_task_abort_resp(pm8001_ha, piomb); break; case OPC_OUB_SATA_ABORT_RSP: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("OPC_OUB_SATA_ABORT_RSP\n")); - pm8001_mpi_task_abort_resp(pm8001_ha, piomb); + mpi_task_abort_resp(pm8001_ha, piomb); break; case OPC_OUB_SAS_DIAG_MODE_START_END: PM8001_MSG_DBG(pm8001_ha, @@ -4094,17 +3823,17 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) case OPC_OUB_SMP_ABORT_RSP: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("OPC_OUB_SMP_ABORT_RSP\n")); - pm8001_mpi_task_abort_resp(pm8001_ha, piomb); + mpi_task_abort_resp(pm8001_ha, piomb); break; case OPC_OUB_GET_NVMD_DATA: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("OPC_OUB_GET_NVMD_DATA\n")); - pm8001_mpi_get_nvmd_resp(pm8001_ha, piomb); + mpi_get_nvmd_resp(pm8001_ha, piomb); break; case OPC_OUB_SET_NVMD_DATA: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("OPC_OUB_SET_NVMD_DATA\n")); - pm8001_mpi_set_nvmd_resp(pm8001_ha, piomb); + mpi_set_nvmd_resp(pm8001_ha, piomb); break; case OPC_OUB_DEVICE_HANDLE_REMOVAL: PM8001_MSG_DBG(pm8001_ha, @@ -4113,7 +3842,7 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) case OPC_OUB_SET_DEVICE_STATE: PM8001_MSG_DBG(pm8001_ha, pm8001_printk("OPC_OUB_SET_DEVICE_STATE\n")); - pm8001_mpi_set_dev_state_resp(pm8001_ha, piomb); + mpi_set_dev_state_resp(pm8001_ha, piomb); break; case OPC_OUB_GET_DEVICE_STATE: PM8001_MSG_DBG(pm8001_ha, @@ -4135,7 +3864,7 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) } } -static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) +static int process_oq(struct pm8001_hba_info *pm8001_ha) { struct outbound_queue_table *circularQ; void *pMsg1 = NULL; @@ -4144,15 +3873,14 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) unsigned long flags; spin_lock_irqsave(&pm8001_ha->lock, flags); - circularQ = &pm8001_ha->outbnd_q_tbl[vec]; + circularQ = &pm8001_ha->outbnd_q_tbl[0]; do { - ret = pm8001_mpi_msg_consume(pm8001_ha, circularQ, &pMsg1, &bc); + ret = mpi_msg_consume(pm8001_ha, circularQ, &pMsg1, &bc); if (MPI_IO_STATUS_SUCCESS == ret) { /* process the outbound message */ process_one_iomb(pm8001_ha, (void *)(pMsg1 - 4)); /* free the message from the outbound circular buffer */ - pm8001_mpi_msg_free_set(pm8001_ha, pMsg1, - circularQ, bc); + mpi_msg_free_set(pm8001_ha, pMsg1, circularQ, bc); } if (MPI_IO_STATUS_BUSY == ret) { /* Update the producer index from SPC */ @@ -4175,7 +3903,7 @@ static const u8 data_dir_flags[] = { [PCI_DMA_FROMDEVICE] = DATA_DIR_IN,/* INBOUND */ [PCI_DMA_NONE] = DATA_DIR_NONE,/* NO TRANSFER */ }; -void +static void pm8001_chip_make_sg(struct scatterlist *scatter, int nr, void *prd) { int i; @@ -4250,7 +3978,7 @@ static int pm8001_chip_smp_req(struct pm8001_hba_info *pm8001_ha, smp_cmd.long_smp_req.long_resp_size = cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_resp)-4); build_smp_cmd(pm8001_dev->device_id, smp_cmd.tag, &smp_cmd); - pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, (u32 *)&smp_cmd, 0); + mpi_build_cmd(pm8001_ha, circularQ, opc, (u32 *)&smp_cmd); return 0; err_out_2: @@ -4314,7 +4042,7 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, ssp_cmd.len = cpu_to_le32(task->total_xfer_len); ssp_cmd.esgl = 0; } - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &ssp_cmd, 0); + ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &ssp_cmd); return ret; } @@ -4332,7 +4060,6 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, u32 ATAP = 0x0; u32 dir; struct inbound_queue_table *circularQ; - unsigned long flags; u32 opc = OPC_INB_SATA_HOST_OPSTART; memset(&sata_cmd, 0, sizeof(sata_cmd)); circularQ = &pm8001_ha->inbnd_q_tbl[0]; @@ -4353,10 +4080,8 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, PM8001_IO_DBG(pm8001_ha, pm8001_printk("FPDMA\n")); } } - if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) { - task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3); + if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) ncg_tag = hdr_tag; - } dir = data_dir_flags[task->data_dir] << 8; sata_cmd.tag = cpu_to_le32(tag); sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id); @@ -4387,55 +4112,7 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, sata_cmd.len = cpu_to_le32(task->total_xfer_len); sata_cmd.esgl = 0; } - - /* Check for read log for failed drive and return */ - if (sata_cmd.sata_fis.command == 0x2f) { - if (pm8001_ha_dev && ((pm8001_ha_dev->id & NCQ_READ_LOG_FLAG) || - (pm8001_ha_dev->id & NCQ_ABORT_ALL_FLAG) || - (pm8001_ha_dev->id & NCQ_2ND_RLE_FLAG))) { - struct task_status_struct *ts; - - pm8001_ha_dev->id &= 0xDFFFFFFF; - ts = &task->task_status; - - spin_lock_irqsave(&task->task_state_lock, flags); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAM_STAT_GOOD; - task->task_state_flags &= ~SAS_TASK_STATE_PENDING; - task->task_state_flags &= ~SAS_TASK_AT_INITIATOR; - task->task_state_flags |= SAS_TASK_STATE_DONE; - if (unlikely((task->task_state_flags & - SAS_TASK_STATE_ABORTED))) { - spin_unlock_irqrestore(&task->task_state_lock, - flags); - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("task 0x%p resp 0x%x " - " stat 0x%x but aborted by upper layer " - "\n", task, ts->resp, ts->stat)); - pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); - } else if (task->uldd_task) { - spin_unlock_irqrestore(&task->task_state_lock, - flags); - pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); - mb();/* ditto */ - spin_unlock_irq(&pm8001_ha->lock); - task->task_done(task); - spin_lock_irq(&pm8001_ha->lock); - return 0; - } else if (!task->uldd_task) { - spin_unlock_irqrestore(&task->task_state_lock, - flags); - pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); - mb();/*ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - task->task_done(task); - spin_lock_irq(&pm8001_ha->lock); - return 0; - } - } - } - - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, 0); + ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd); return ret; } @@ -4465,12 +4142,12 @@ pm8001_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) payload.ase_sh_lm_slr_phyid = cpu_to_le32(SPINHOLD_DISABLE | LINKMODE_AUTO | LINKRATE_15 | LINKRATE_30 | LINKRATE_60 | phy_id); - payload.sas_identify.dev_type = SAS_END_DEVICE; + payload.sas_identify.dev_type = SAS_END_DEV; payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL; memcpy(payload.sas_identify.sas_addr, pm8001_ha->sas_addr, SAS_ADDR_SIZE); payload.sas_identify.phy_id = phy_id; - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload, 0); + ret = mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload); return ret; } @@ -4480,7 +4157,7 @@ pm8001_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) * @num: the inbound queue number * @phy_id: the phy id which we wanted to start up. */ -int pm8001_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha, +static int pm8001_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) { struct phy_stop_req payload; @@ -4492,12 +4169,12 @@ int pm8001_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha, memset(&payload, 0, sizeof(payload)); payload.tag = cpu_to_le32(tag); payload.phy_id = cpu_to_le32(phy_id); - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload, 0); + ret = mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload); return ret; } /** - * see comments on pm8001_mpi_reg_resp. + * see comments on mpi_reg_resp. */ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha, struct pm8001_device *pm8001_dev, u32 flag) @@ -4527,11 +4204,11 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha, if (flag == 1) stp_sspsmp_sata = 0x02; /*direct attached sata */ else { - if (pm8001_dev->dev_type == SAS_SATA_DEV) + if (pm8001_dev->dev_type == SATA_DEV) stp_sspsmp_sata = 0x00; /* stp*/ - else if (pm8001_dev->dev_type == SAS_END_DEVICE || - pm8001_dev->dev_type == SAS_EDGE_EXPANDER_DEVICE || - pm8001_dev->dev_type == SAS_FANOUT_EXPANDER_DEVICE) + else if (pm8001_dev->dev_type == SAS_END_DEV || + pm8001_dev->dev_type == EDGE_DEV || + pm8001_dev->dev_type == FANOUT_DEV) stp_sspsmp_sata = 0x01; /*ssp or smp*/ } if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) @@ -4551,14 +4228,14 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha, cpu_to_le32(ITNT | (firstBurstSize * 0x10000)); memcpy(payload.sas_addr, pm8001_dev->sas_device->sas_addr, SAS_ADDR_SIZE); - rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); + rc = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload); return rc; } /** - * see comments on pm8001_mpi_reg_resp. + * see comments on mpi_reg_resp. */ -int pm8001_chip_dereg_dev_req(struct pm8001_hba_info *pm8001_ha, +static int pm8001_chip_dereg_dev_req(struct pm8001_hba_info *pm8001_ha, u32 device_id) { struct dereg_dev_req payload; @@ -4572,7 +4249,7 @@ int pm8001_chip_dereg_dev_req(struct pm8001_hba_info *pm8001_ha, payload.device_id = cpu_to_le32(device_id); PM8001_MSG_DBG(pm8001_ha, pm8001_printk("unregister device device_id = %d\n", device_id)); - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); + ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload); return ret; } @@ -4595,7 +4272,7 @@ static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha, payload.tag = cpu_to_le32(1); payload.phyop_phyid = cpu_to_le32(((phy_op & 0xff) << 8) | (phyId & 0x0F)); - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); + ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload); return ret; } @@ -4619,11 +4296,11 @@ static u32 pm8001_chip_is_our_interupt(struct pm8001_hba_info *pm8001_ha) * @stat: stat. */ static irqreturn_t -pm8001_chip_isr(struct pm8001_hba_info *pm8001_ha, u8 vec) +pm8001_chip_isr(struct pm8001_hba_info *pm8001_ha) { - pm8001_chip_interrupt_disable(pm8001_ha, vec); - process_oq(pm8001_ha, vec); - pm8001_chip_interrupt_enable(pm8001_ha, vec); + pm8001_chip_interrupt_disable(pm8001_ha); + process_oq(pm8001_ha); + pm8001_chip_interrupt_enable(pm8001_ha); return IRQ_HANDLED; } @@ -4645,7 +4322,7 @@ static int send_task_abort(struct pm8001_hba_info *pm8001_ha, u32 opc, task_abort.device_id = cpu_to_le32(dev_id); task_abort.tag = cpu_to_le32(cmd_tag); } - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, 0); + ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort); return ret; } @@ -4654,17 +4331,16 @@ static int send_task_abort(struct pm8001_hba_info *pm8001_ha, u32 opc, * @task: the task we wanted to aborted. * @flag: the abort flag. */ -int pm8001_chip_abort_task(struct pm8001_hba_info *pm8001_ha, +static int pm8001_chip_abort_task(struct pm8001_hba_info *pm8001_ha, struct pm8001_device *pm8001_dev, u8 flag, u32 task_tag, u32 cmd_tag) { u32 opc, device_id; int rc = TMF_RESP_FUNC_FAILED; - PM8001_EH_DBG(pm8001_ha, - pm8001_printk("cmd_tag = %x, abort task tag = 0x%x", - cmd_tag, task_tag)); - if (pm8001_dev->dev_type == SAS_END_DEVICE) + PM8001_EH_DBG(pm8001_ha, pm8001_printk("cmd_tag = %x, abort task tag" + " = %x", cmd_tag, task_tag)); + if (pm8001_dev->dev_type == SAS_END_DEV) opc = OPC_INB_SSP_ABORT; - else if (pm8001_dev->dev_type == SAS_SATA_DEV) + else if (pm8001_dev->dev_type == SATA_DEV) opc = OPC_INB_SATA_ABORT; else opc = OPC_INB_SMP_ABORT;/* SMP */ @@ -4682,7 +4358,7 @@ int pm8001_chip_abort_task(struct pm8001_hba_info *pm8001_ha, * @ccb: the ccb information. * @tmf: task management function. */ -int pm8001_chip_ssp_tm_req(struct pm8001_hba_info *pm8001_ha, +static int pm8001_chip_ssp_tm_req(struct pm8001_hba_info *pm8001_ha, struct pm8001_ccb_info *ccb, struct pm8001_tmf_task *tmf) { struct sas_task *task = ccb->task; @@ -4700,11 +4376,11 @@ int pm8001_chip_ssp_tm_req(struct pm8001_hba_info *pm8001_ha, memcpy(sspTMCmd.lun, task->ssp_task.LUN, 8); sspTMCmd.tag = cpu_to_le32(ccb->ccb_tag); circularQ = &pm8001_ha->inbnd_q_tbl[0]; - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sspTMCmd, 0); + ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &sspTMCmd); return ret; } -int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha, +static int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha, void *payload) { u32 opc = OPC_INB_GET_NVMD_DATA; @@ -4721,7 +4397,7 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha, fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL); if (!fw_control_context) return -ENOMEM; - fw_control_context->usrAddr = (u8 *)ioctl_payload->func_specific; + fw_control_context->usrAddr = (u8 *)&ioctl_payload->func_specific[0]; fw_control_context->len = ioctl_payload->length; circularQ = &pm8001_ha->inbnd_q_tbl[0]; memset(&nvmd_req, 0, sizeof(nvmd_req)); @@ -4780,11 +4456,11 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha, default: break; } - rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req, 0); + rc = mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req); return rc; } -int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha, +static int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha, void *payload) { u32 opc = OPC_INB_SET_NVMD_DATA; @@ -4803,7 +4479,7 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha, return -ENOMEM; circularQ = &pm8001_ha->inbnd_q_tbl[0]; memcpy(pm8001_ha->memoryMap.region[NVMD].virt_ptr, - &ioctl_payload->func_specific, + ioctl_payload->func_specific, ioctl_payload->length); memset(&nvmd_req, 0, sizeof(nvmd_req)); rc = pm8001_tag_alloc(pm8001_ha, &tag); @@ -4860,7 +4536,7 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha, default: break; } - rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req, 0); + rc = mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req); return rc; } @@ -4869,7 +4545,7 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha, * @pm8001_ha: our hba card information. * @fw_flash_updata_info: firmware flash update param */ -int +static int pm8001_chip_fw_flash_update_build(struct pm8001_hba_info *pm8001_ha, void *fw_flash_updata_info, u32 tag) { @@ -4891,11 +4567,11 @@ pm8001_chip_fw_flash_update_build(struct pm8001_hba_info *pm8001_ha, cpu_to_le32(lower_32_bits(le64_to_cpu(info->sgl.addr))); payload.sgl_addr_hi = cpu_to_le32(upper_32_bits(le64_to_cpu(info->sgl.addr))); - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); + ret = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload); return ret; } -int +static int pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha, void *payload) { @@ -4905,14 +4581,29 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha, int rc; u32 tag; struct pm8001_ccb_info *ccb; - void *buffer = pm8001_ha->memoryMap.region[FW_FLASH].virt_ptr; - dma_addr_t phys_addr = pm8001_ha->memoryMap.region[FW_FLASH].phys_addr; + void *buffer = NULL; + dma_addr_t phys_addr; + u32 phys_addr_hi; + u32 phys_addr_lo; struct pm8001_ioctl_payload *ioctl_payload = payload; fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL); if (!fw_control_context) return -ENOMEM; - fw_control = (struct fw_control_info *)&ioctl_payload->func_specific; + fw_control = (struct fw_control_info *)&ioctl_payload->func_specific[0]; + if (fw_control->len != 0) { + if (pm8001_mem_alloc(pm8001_ha->pdev, + (void **)&buffer, + &phys_addr, + &phys_addr_hi, + &phys_addr_lo, + fw_control->len, 0) != 0) { + PM8001_FAIL_DBG(pm8001_ha, + pm8001_printk("Mem alloc failure\n")); + kfree(fw_control_context); + return -ENOMEM; + } + } memcpy(buffer, fw_control->buffer, fw_control->len); flash_update_info.sgl.addr = cpu_to_le64(phys_addr); flash_update_info.sgl.im_len.len = cpu_to_le32(fw_control->len); @@ -4922,7 +4613,6 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha, flash_update_info.total_image_len = fw_control->size; fw_control_context->fw_control = fw_control; fw_control_context->virtAddr = buffer; - fw_control_context->phys_addr = phys_addr; fw_control_context->len = fw_control->len; rc = pm8001_tag_alloc(pm8001_ha, &tag); if (rc) { @@ -4937,7 +4627,7 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha, return rc; } -int +static int pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha, struct pm8001_device *pm8001_dev, u32 state) { @@ -4958,7 +4648,7 @@ pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha, payload.tag = cpu_to_le32(tag); payload.device_id = cpu_to_le32(pm8001_dev->device_id); payload.nds = cpu_to_le32(state); - rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); + rc = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload); return rc; } @@ -4983,7 +4673,7 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha) payload.SSAHOLT = cpu_to_le32(0xd << 25); payload.sata_hol_tmo = cpu_to_le32(80); payload.open_reject_cmdretries_data_retries = cpu_to_le32(0xff00ff); - rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); + rc = mpi_build_cmd(pm8001_ha, circularQ, opc, &payload); return rc; } @@ -5016,3 +4706,4 @@ const struct pm8001_dispatch pm8001_8001_dispatch = { .set_dev_state_req = pm8001_chip_set_dev_state_req, .sas_re_init_req = pm8001_chip_sas_re_initialization, }; + diff --git a/trunk/drivers/scsi/pm8001/pm8001_hwi.h b/trunk/drivers/scsi/pm8001/pm8001_hwi.h index d7c1e2034226..d437309cb1e1 100644 --- a/trunk/drivers/scsi/pm8001/pm8001_hwi.h +++ b/trunk/drivers/scsi/pm8001/pm8001_hwi.h @@ -131,8 +131,6 @@ #define LINKRATE_30 (0x02 << 8) #define LINKRATE_60 (0x04 << 8) -/* for new SPC controllers MEMBASE III is shared between BIOS and DATA */ -#define GSM_SM_BASE 0x4F0000 struct mpi_msg_hdr{ __le32 header; /* Bits [11:0] - Message operation code */ /* Bits [15:12] - Message Category */ @@ -300,7 +298,7 @@ struct local_phy_ctl_resp { #define OP_BITS 0x0000FF00 -#define ID_BITS 0x000000FF +#define ID_BITS 0x0000000F /* * brief the data structure of PORT Control Command diff --git a/trunk/drivers/scsi/pm8001/pm8001_init.c b/trunk/drivers/scsi/pm8001/pm8001_init.c index e4b9bc7f5410..3d5e522e00fc 100644 --- a/trunk/drivers/scsi/pm8001/pm8001_init.c +++ b/trunk/drivers/scsi/pm8001/pm8001_init.c @@ -1,5 +1,5 @@ /* - * PMC-Sierra PM8001/8081/8088/8089 SAS/SATA based host adapters driver + * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver * * Copyright (c) 2008-2009 USI Co., Ltd. * All rights reserved. @@ -44,16 +44,8 @@ static struct scsi_transport_template *pm8001_stt; -/** - * chip info structure to identify chip key functionality as - * encryption available/not, no of ports, hw specific function ref - */ static const struct pm8001_chip_info pm8001_chips[] = { - [chip_8001] = {0, 8, &pm8001_8001_dispatch,}, - [chip_8008] = {0, 8, &pm8001_80xx_dispatch,}, - [chip_8009] = {1, 8, &pm8001_80xx_dispatch,}, - [chip_8018] = {0, 16, &pm8001_80xx_dispatch,}, - [chip_8019] = {1, 16, &pm8001_80xx_dispatch,}, + [chip_8001] = { 8, &pm8001_8001_dispatch,}, }; static int pm8001_id; @@ -163,75 +155,37 @@ static void pm8001_free(struct pm8001_hba_info *pm8001_ha) } #ifdef PM8001_USE_TASKLET - -/** - * tasklet for 64 msi-x interrupt handler - * @opaque: the passed general host adapter struct - * Note: pm8001_tasklet is common for pm8001 & pm80xx - */ static void pm8001_tasklet(unsigned long opaque) { struct pm8001_hba_info *pm8001_ha; - u32 vec; pm8001_ha = (struct pm8001_hba_info *)opaque; if (unlikely(!pm8001_ha)) BUG_ON(1); - vec = pm8001_ha->int_vector; - PM8001_CHIP_DISP->isr(pm8001_ha, vec); -} -#endif - -static struct pm8001_hba_info *outq_to_hba(u8 *outq) -{ - return container_of((outq - *outq), struct pm8001_hba_info, outq[0]); + PM8001_CHIP_DISP->isr(pm8001_ha); } - -/** - * pm8001_interrupt_handler_msix - main MSIX interrupt handler. - * It obtains the vector number and calls the equivalent bottom - * half or services directly. - * @opaque: the passed outbound queue/vector. Host structure is - * retrieved from the same. - */ -static irqreturn_t pm8001_interrupt_handler_msix(int irq, void *opaque) -{ - struct pm8001_hba_info *pm8001_ha = outq_to_hba(opaque); - u8 outq = *(u8 *)opaque; - irqreturn_t ret = IRQ_HANDLED; - if (unlikely(!pm8001_ha)) - return IRQ_NONE; - if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha)) - return IRQ_NONE; - pm8001_ha->int_vector = outq; -#ifdef PM8001_USE_TASKLET - tasklet_schedule(&pm8001_ha->tasklet); -#else - ret = PM8001_CHIP_DISP->isr(pm8001_ha, outq); #endif - return ret; -} -/** - * pm8001_interrupt_handler_intx - main INTx interrupt handler. - * @dev_id: sas_ha structure. The HBA is retrieved from sas_has structure. - */ -static irqreturn_t pm8001_interrupt_handler_intx(int irq, void *dev_id) + /** + * pm8001_interrupt - when HBA originate a interrupt,we should invoke this + * dispatcher to handle each case. + * @irq: irq number. + * @opaque: the passed general host adapter struct + */ +static irqreturn_t pm8001_interrupt(int irq, void *opaque) { struct pm8001_hba_info *pm8001_ha; irqreturn_t ret = IRQ_HANDLED; - struct sas_ha_struct *sha = dev_id; + struct sas_ha_struct *sha = opaque; pm8001_ha = sha->lldd_ha; if (unlikely(!pm8001_ha)) return IRQ_NONE; if (!PM8001_CHIP_DISP->is_our_interupt(pm8001_ha)) return IRQ_NONE; - - pm8001_ha->int_vector = 0; #ifdef PM8001_USE_TASKLET tasklet_schedule(&pm8001_ha->tasklet); #else - ret = PM8001_CHIP_DISP->isr(pm8001_ha, 0); + ret = PM8001_CHIP_DISP->isr(pm8001_ha); #endif return ret; } @@ -241,14 +195,10 @@ static irqreturn_t pm8001_interrupt_handler_intx(int irq, void *dev_id) * @pm8001_ha:our hba structure. * */ -static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, - const struct pci_device_id *ent) +static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha) { int i; spin_lock_init(&pm8001_ha->lock); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("pm8001_alloc: PHY:%x\n", - pm8001_ha->chip->n_phy)); for (i = 0; i < pm8001_ha->chip->n_phy; i++) { pm8001_phy_init(pm8001_ha, i); pm8001_ha->port[i].wide_port_phymap = 0; @@ -272,57 +222,30 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, pm8001_ha->memoryMap.region[IOP].total_len = PM8001_EVENT_LOG_SIZE; pm8001_ha->memoryMap.region[IOP].alignment = 32; - for (i = 0; i < PM8001_MAX_SPCV_INB_NUM; i++) { - /* MPI Memory region 3 for consumer Index of inbound queues */ - pm8001_ha->memoryMap.region[CI+i].num_elements = 1; - pm8001_ha->memoryMap.region[CI+i].element_size = 4; - pm8001_ha->memoryMap.region[CI+i].total_len = 4; - pm8001_ha->memoryMap.region[CI+i].alignment = 4; - - if ((ent->driver_data) != chip_8001) { - /* MPI Memory region 5 inbound queues */ - pm8001_ha->memoryMap.region[IB+i].num_elements = - PM8001_MPI_QUEUE; - pm8001_ha->memoryMap.region[IB+i].element_size = 128; - pm8001_ha->memoryMap.region[IB+i].total_len = - PM8001_MPI_QUEUE * 128; - pm8001_ha->memoryMap.region[IB+i].alignment = 128; - } else { - pm8001_ha->memoryMap.region[IB+i].num_elements = - PM8001_MPI_QUEUE; - pm8001_ha->memoryMap.region[IB+i].element_size = 64; - pm8001_ha->memoryMap.region[IB+i].total_len = - PM8001_MPI_QUEUE * 64; - pm8001_ha->memoryMap.region[IB+i].alignment = 64; - } - } - - for (i = 0; i < PM8001_MAX_SPCV_OUTB_NUM; i++) { - /* MPI Memory region 4 for producer Index of outbound queues */ - pm8001_ha->memoryMap.region[PI+i].num_elements = 1; - pm8001_ha->memoryMap.region[PI+i].element_size = 4; - pm8001_ha->memoryMap.region[PI+i].total_len = 4; - pm8001_ha->memoryMap.region[PI+i].alignment = 4; - - if (ent->driver_data != chip_8001) { - /* MPI Memory region 6 Outbound queues */ - pm8001_ha->memoryMap.region[OB+i].num_elements = - PM8001_MPI_QUEUE; - pm8001_ha->memoryMap.region[OB+i].element_size = 128; - pm8001_ha->memoryMap.region[OB+i].total_len = - PM8001_MPI_QUEUE * 128; - pm8001_ha->memoryMap.region[OB+i].alignment = 128; - } else { - /* MPI Memory region 6 Outbound queues */ - pm8001_ha->memoryMap.region[OB+i].num_elements = - PM8001_MPI_QUEUE; - pm8001_ha->memoryMap.region[OB+i].element_size = 64; - pm8001_ha->memoryMap.region[OB+i].total_len = - PM8001_MPI_QUEUE * 64; - pm8001_ha->memoryMap.region[OB+i].alignment = 64; - } + /* MPI Memory region 3 for consumer Index of inbound queues */ + pm8001_ha->memoryMap.region[CI].num_elements = 1; + pm8001_ha->memoryMap.region[CI].element_size = 4; + pm8001_ha->memoryMap.region[CI].total_len = 4; + pm8001_ha->memoryMap.region[CI].alignment = 4; + + /* MPI Memory region 4 for producer Index of outbound queues */ + pm8001_ha->memoryMap.region[PI].num_elements = 1; + pm8001_ha->memoryMap.region[PI].element_size = 4; + pm8001_ha->memoryMap.region[PI].total_len = 4; + pm8001_ha->memoryMap.region[PI].alignment = 4; + + /* MPI Memory region 5 inbound queues */ + pm8001_ha->memoryMap.region[IB].num_elements = PM8001_MPI_QUEUE; + pm8001_ha->memoryMap.region[IB].element_size = 64; + pm8001_ha->memoryMap.region[IB].total_len = PM8001_MPI_QUEUE * 64; + pm8001_ha->memoryMap.region[IB].alignment = 64; + + /* MPI Memory region 6 outbound queues */ + pm8001_ha->memoryMap.region[OB].num_elements = PM8001_MPI_QUEUE; + pm8001_ha->memoryMap.region[OB].element_size = 64; + pm8001_ha->memoryMap.region[OB].total_len = PM8001_MPI_QUEUE * 64; + pm8001_ha->memoryMap.region[OB].alignment = 64; - } /* Memory region write DMA*/ pm8001_ha->memoryMap.region[NVMD].num_elements = 1; pm8001_ha->memoryMap.region[NVMD].element_size = 4096; @@ -341,9 +264,6 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, pm8001_ha->memoryMap.region[CCB_MEM].total_len = PM8001_MAX_CCB * sizeof(struct pm8001_ccb_info); - /* Memory region for fw flash */ - pm8001_ha->memoryMap.region[FW_FLASH].total_len = 4096; - for (i = 0; i < USI_MAX_MEMCNT; i++) { if (pm8001_mem_alloc(pm8001_ha->pdev, &pm8001_ha->memoryMap.region[i].virt_ptr, @@ -361,7 +281,7 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, pm8001_ha->devices = pm8001_ha->memoryMap.region[DEV_MEM].virt_ptr; for (i = 0; i < PM8001_MAX_DEVICES; i++) { - pm8001_ha->devices[i].dev_type = SAS_PHY_UNUSED; + pm8001_ha->devices[i].dev_type = NO_DEVICE; pm8001_ha->devices[i].id = i; pm8001_ha->devices[i].device_id = PM8001_MAX_DEVICES; pm8001_ha->devices[i].running_req = 0; @@ -419,12 +339,10 @@ static int pm8001_ioremap(struct pm8001_hba_info *pm8001_ha) ioremap(pm8001_ha->io_mem[logicalBar].membase, pm8001_ha->io_mem[logicalBar].memsize); PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("PCI: bar %d, logicalBar %d ", - bar, logicalBar)); - PM8001_INIT_DBG(pm8001_ha, pm8001_printk( - "base addr %llx virt_addr=%llx len=%d\n", - (u64)pm8001_ha->io_mem[logicalBar].membase, - (u64)pm8001_ha->io_mem[logicalBar].memvirtaddr, + pm8001_printk("PCI: bar %d, logicalBar %d " + "virt_addr=%lx,len=%d\n", bar, logicalBar, + (unsigned long) + pm8001_ha->io_mem[logicalBar].memvirtaddr, pm8001_ha->io_mem[logicalBar].memsize)); } else { pm8001_ha->io_mem[logicalBar].membase = 0; @@ -443,9 +361,8 @@ static int pm8001_ioremap(struct pm8001_hba_info *pm8001_ha) * @shost: scsi host struct which has been initialized before. */ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev, - const struct pci_device_id *ent, - struct Scsi_Host *shost) - + u32 chip_id, + struct Scsi_Host *shost) { struct pm8001_hba_info *pm8001_ha; struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); @@ -457,7 +374,7 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev, pm8001_ha->pdev = pdev; pm8001_ha->dev = &pdev->dev; - pm8001_ha->chip_id = ent->driver_data; + pm8001_ha->chip_id = chip_id; pm8001_ha->chip = &pm8001_chips[pm8001_ha->chip_id]; pm8001_ha->irq = pdev->irq; pm8001_ha->sas = sha; @@ -465,22 +382,12 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev, pm8001_ha->id = pm8001_id++; pm8001_ha->logging_level = 0x01; sprintf(pm8001_ha->name, "%s%d", DRV_NAME, pm8001_ha->id); - /* IOMB size is 128 for 8088/89 controllers */ - if (pm8001_ha->chip_id != chip_8001) - pm8001_ha->iomb_size = IOMB_SIZE_SPCV; - else - pm8001_ha->iomb_size = IOMB_SIZE_SPC; - #ifdef PM8001_USE_TASKLET - /** - * default tasklet for non msi-x interrupt handler/first msi-x - * interrupt handler - **/ tasklet_init(&pm8001_ha->tasklet, pm8001_tasklet, - (unsigned long)pm8001_ha); + (unsigned long)pm8001_ha); #endif pm8001_ioremap(pm8001_ha); - if (!pm8001_alloc(pm8001_ha, ent)) + if (!pm8001_alloc(pm8001_ha)) return pm8001_ha; pm8001_free(pm8001_ha); return NULL; @@ -605,50 +512,21 @@ static void pm8001_post_sas_ha_init(struct Scsi_Host *shost, */ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) { - u8 i, j; + u8 i; #ifdef PM8001_READ_VPD - /* For new SPC controllers WWN is stored in flash vpd - * For SPC/SPCve controllers WWN is stored in EEPROM - * For Older SPC WWN is stored in NVMD - */ DECLARE_COMPLETION_ONSTACK(completion); struct pm8001_ioctl_payload payload; - u16 deviceid; - pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid); pm8001_ha->nvmd_completion = &completion; - - if (pm8001_ha->chip_id == chip_8001) { - if (deviceid == 0x8081) { - payload.minor_function = 4; - payload.length = 4096; - } else { - payload.minor_function = 0; - payload.length = 128; - } - } else { - payload.minor_function = 1; - payload.length = 4096; - } - payload.offset = 0; - payload.func_specific = kzalloc(payload.length, GFP_KERNEL); + payload.minor_function = 0; + payload.length = 128; + payload.func_specific = kzalloc(128, GFP_KERNEL); PM8001_CHIP_DISP->get_nvmd_req(pm8001_ha, &payload); wait_for_completion(&completion); - - for (i = 0, j = 0; i <= 7; i++, j++) { - if (pm8001_ha->chip_id == chip_8001) { - if (deviceid == 0x8081) - pm8001_ha->sas_addr[j] = - payload.func_specific[0x704 + i]; - } else - pm8001_ha->sas_addr[j] = - payload.func_specific[0x804 + i]; - } - for (i = 0; i < pm8001_ha->chip->n_phy; i++) { - memcpy(&pm8001_ha->phy[i].dev_sas_addr, - pm8001_ha->sas_addr, SAS_ADDR_SIZE); + memcpy(&pm8001_ha->phy[i].dev_sas_addr, pm8001_ha->sas_addr, + SAS_ADDR_SIZE); PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("phy %d sas_addr = %016llx\n", i, + pm8001_printk("phy %d sas_addr = %016llx \n", i, pm8001_ha->phy[i].dev_sas_addr)); } #else @@ -669,50 +547,31 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) * @chip_info: our ha struct. * @irq_handler: irq_handler */ -static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha) +static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha, + irq_handler_t irq_handler) { u32 i = 0, j = 0; - u32 number_of_intr; + u32 number_of_intr = 1; int flag = 0; u32 max_entry; int rc; - static char intr_drvname[PM8001_MAX_MSIX_VEC][sizeof(DRV_NAME)+3]; - - /* SPCv controllers supports 64 msi-x */ - if (pm8001_ha->chip_id == chip_8001) { - number_of_intr = 1; - flag |= IRQF_DISABLED; - } else { - number_of_intr = PM8001_MAX_MSIX_VEC; - flag &= ~IRQF_SHARED; - flag |= IRQF_DISABLED; - } - max_entry = sizeof(pm8001_ha->msix_entries) / sizeof(pm8001_ha->msix_entries[0]); + flag |= IRQF_DISABLED; for (i = 0; i < max_entry ; i++) pm8001_ha->msix_entries[i].entry = i; rc = pci_enable_msix(pm8001_ha->pdev, pm8001_ha->msix_entries, number_of_intr); pm8001_ha->number_of_intr = number_of_intr; if (!rc) { - PM8001_INIT_DBG(pm8001_ha, pm8001_printk( - "pci_enable_msix request ret:%d no of intr %d\n", - rc, pm8001_ha->number_of_intr)); - - for (i = 0; i < number_of_intr; i++) - pm8001_ha->outq[i] = i; - for (i = 0; i < number_of_intr; i++) { - snprintf(intr_drvname[i], sizeof(intr_drvname[0]), - DRV_NAME"%d", i); if (request_irq(pm8001_ha->msix_entries[i].vector, - pm8001_interrupt_handler_msix, flag, - intr_drvname[i], &pm8001_ha->outq[i])) { + irq_handler, flag, DRV_NAME, + SHOST_TO_SAS_HA(pm8001_ha->shost))) { for (j = 0; j < i; j++) free_irq( pm8001_ha->msix_entries[j].vector, - &pm8001_ha->outq[j]); + SHOST_TO_SAS_HA(pm8001_ha->shost)); pci_disable_msix(pm8001_ha->pdev); break; } @@ -729,24 +588,22 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha) static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha) { struct pci_dev *pdev; + irq_handler_t irq_handler = pm8001_interrupt; int rc; pdev = pm8001_ha->pdev; #ifdef PM8001_USE_MSIX if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) - return pm8001_setup_msix(pm8001_ha); - else { - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("MSIX not supported!!!\n")); + return pm8001_setup_msix(pm8001_ha, irq_handler); + else goto intx; - } #endif intx: /* initialize the INT-X interrupt */ - rc = request_irq(pdev->irq, pm8001_interrupt_handler_intx, IRQF_SHARED, - DRV_NAME, SHOST_TO_SAS_HA(pm8001_ha->shost)); + rc = request_irq(pdev->irq, irq_handler, IRQF_SHARED, DRV_NAME, + SHOST_TO_SAS_HA(pm8001_ha->shost)); return rc; } @@ -764,13 +621,12 @@ static int pm8001_pci_probe(struct pci_dev *pdev, { unsigned int rc; u32 pci_reg; - u8 i = 0; struct pm8001_hba_info *pm8001_ha; struct Scsi_Host *shost = NULL; const struct pm8001_chip_info *chip; dev_printk(KERN_INFO, &pdev->dev, - "pm80xx: driver version %s\n", DRV_VERSION); + "pm8001: driver version %s\n", DRV_VERSION); rc = pci_enable_device(pdev); if (rc) goto err_out_enable; @@ -809,39 +665,25 @@ static int pm8001_pci_probe(struct pci_dev *pdev, goto err_out_free; } pci_set_drvdata(pdev, SHOST_TO_SAS_HA(shost)); - /* ent->driver variable is used to differentiate between controllers */ - pm8001_ha = pm8001_pci_alloc(pdev, ent, shost); + pm8001_ha = pm8001_pci_alloc(pdev, chip_8001, shost); if (!pm8001_ha) { rc = -ENOMEM; goto err_out_free; } list_add_tail(&pm8001_ha->list, &hba_list); - PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha); + PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha, 0x252acbcd); rc = PM8001_CHIP_DISP->chip_init(pm8001_ha); - if (rc) { - PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( - "chip_init failed [ret: %d]\n", rc)); + if (rc) goto err_out_ha_free; - } rc = scsi_add_host(shost, &pdev->dev); if (rc) goto err_out_ha_free; rc = pm8001_request_irq(pm8001_ha); - if (rc) { - PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( - "pm8001_request_irq failed [ret: %d]\n", rc)); + if (rc) goto err_out_shost; - } - - PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, 0); - if (pm8001_ha->chip_id != chip_8001) { - for (i = 1; i < pm8001_ha->number_of_intr; i++) - PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, i); - /* setup thermal configuration. */ - pm80xx_set_thermal_config(pm8001_ha); - } + PM8001_CHIP_DISP->interrupt_enable(pm8001_ha); pm8001_init_sas_add(pm8001_ha); pm8001_post_sas_ha_init(shost, chip); rc = sas_register_ha(SHOST_TO_SAS_HA(shost)); @@ -877,15 +719,14 @@ static void pm8001_pci_remove(struct pci_dev *pdev) sas_remove_host(pm8001_ha->shost); list_del(&pm8001_ha->list); scsi_remove_host(pm8001_ha->shost); - PM8001_CHIP_DISP->interrupt_disable(pm8001_ha, 0xFF); - PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha); + PM8001_CHIP_DISP->interrupt_disable(pm8001_ha); + PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha, 0x252acbcd); #ifdef PM8001_USE_MSIX for (i = 0; i < pm8001_ha->number_of_intr; i++) synchronize_irq(pm8001_ha->msix_entries[i].vector); for (i = 0; i < pm8001_ha->number_of_intr; i++) - free_irq(pm8001_ha->msix_entries[i].vector, - &pm8001_ha->outq[i]); + free_irq(pm8001_ha->msix_entries[i].vector, sha); pci_disable_msix(pdev); #else free_irq(pm8001_ha->irq, sha); @@ -922,14 +763,13 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state) printk(KERN_ERR " PCI PM not supported\n"); return -ENODEV; } - PM8001_CHIP_DISP->interrupt_disable(pm8001_ha, 0xFF); - PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha); + PM8001_CHIP_DISP->interrupt_disable(pm8001_ha); + PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha, 0x252acbcd); #ifdef PM8001_USE_MSIX for (i = 0; i < pm8001_ha->number_of_intr; i++) synchronize_irq(pm8001_ha->msix_entries[i].vector); for (i = 0; i < pm8001_ha->number_of_intr; i++) - free_irq(pm8001_ha->msix_entries[i].vector, - &pm8001_ha->outq[i]); + free_irq(pm8001_ha->msix_entries[i].vector, sha); pci_disable_msix(pdev); #else free_irq(pm8001_ha->irq, sha); @@ -958,7 +798,6 @@ static int pm8001_pci_resume(struct pci_dev *pdev) struct sas_ha_struct *sha = pci_get_drvdata(pdev); struct pm8001_hba_info *pm8001_ha; int rc; - u8 i = 0; u32 device_state; pm8001_ha = sha->lldd_ha; device_state = pdev->current_state; @@ -981,33 +820,19 @@ static int pm8001_pci_resume(struct pci_dev *pdev) if (rc) goto err_out_disable; - /* chip soft rst only for spc */ - if (pm8001_ha->chip_id == chip_8001) { - PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("chip soft reset successful\n")); - } + PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha, 0x252acbcd); rc = PM8001_CHIP_DISP->chip_init(pm8001_ha); if (rc) goto err_out_disable; - - /* disable all the interrupt bits */ - PM8001_CHIP_DISP->interrupt_disable(pm8001_ha, 0xFF); - + PM8001_CHIP_DISP->interrupt_disable(pm8001_ha); rc = pm8001_request_irq(pm8001_ha); if (rc) goto err_out_disable; -#ifdef PM8001_USE_TASKLET - /* default tasklet for non msi-x interrupt handler/first msi-x - * interrupt handler */ + #ifdef PM8001_USE_TASKLET tasklet_init(&pm8001_ha->tasklet, pm8001_tasklet, - (unsigned long)pm8001_ha); -#endif - PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, 0); - if (pm8001_ha->chip_id != chip_8001) { - for (i = 1; i < pm8001_ha->number_of_intr; i++) - PM8001_CHIP_DISP->interrupt_enable(pm8001_ha, i); - } + (unsigned long)pm8001_ha); + #endif + PM8001_CHIP_DISP->interrupt_enable(pm8001_ha); scsi_unblock_requests(pm8001_ha->shost); return 0; @@ -1018,45 +843,14 @@ static int pm8001_pci_resume(struct pci_dev *pdev) return rc; } -/* update of pci device, vendor id and driver data with - * unique value for each of the controller - */ static struct pci_device_id pm8001_pci_table[] = { - { PCI_VDEVICE(PMC_Sierra, 0x8001), chip_8001 }, + { + PCI_VDEVICE(PMC_Sierra, 0x8001), chip_8001 + }, { PCI_DEVICE(0x117c, 0x0042), .driver_data = chip_8001 }, - /* Support for SPC/SPCv/SPCve controllers */ - { PCI_VDEVICE(ADAPTEC2, 0x8001), chip_8001 }, - { PCI_VDEVICE(PMC_Sierra, 0x8008), chip_8008 }, - { PCI_VDEVICE(ADAPTEC2, 0x8008), chip_8008 }, - { PCI_VDEVICE(PMC_Sierra, 0x8018), chip_8018 }, - { PCI_VDEVICE(ADAPTEC2, 0x8018), chip_8018 }, - { PCI_VDEVICE(PMC_Sierra, 0x8009), chip_8009 }, - { PCI_VDEVICE(ADAPTEC2, 0x8009), chip_8009 }, - { PCI_VDEVICE(PMC_Sierra, 0x8019), chip_8019 }, - { PCI_VDEVICE(ADAPTEC2, 0x8019), chip_8019 }, - { PCI_VENDOR_ID_ADAPTEC2, 0x8081, - PCI_VENDOR_ID_ADAPTEC2, 0x0400, 0, 0, chip_8001 }, - { PCI_VENDOR_ID_ADAPTEC2, 0x8081, - PCI_VENDOR_ID_ADAPTEC2, 0x0800, 0, 0, chip_8001 }, - { PCI_VENDOR_ID_ADAPTEC2, 0x8088, - PCI_VENDOR_ID_ADAPTEC2, 0x0008, 0, 0, chip_8008 }, - { PCI_VENDOR_ID_ADAPTEC2, 0x8088, - PCI_VENDOR_ID_ADAPTEC2, 0x0800, 0, 0, chip_8008 }, - { PCI_VENDOR_ID_ADAPTEC2, 0x8089, - PCI_VENDOR_ID_ADAPTEC2, 0x0008, 0, 0, chip_8009 }, - { PCI_VENDOR_ID_ADAPTEC2, 0x8089, - PCI_VENDOR_ID_ADAPTEC2, 0x0800, 0, 0, chip_8009 }, - { PCI_VENDOR_ID_ADAPTEC2, 0x8088, - PCI_VENDOR_ID_ADAPTEC2, 0x0016, 0, 0, chip_8018 }, - { PCI_VENDOR_ID_ADAPTEC2, 0x8088, - PCI_VENDOR_ID_ADAPTEC2, 0x1600, 0, 0, chip_8018 }, - { PCI_VENDOR_ID_ADAPTEC2, 0x8089, - PCI_VENDOR_ID_ADAPTEC2, 0x0016, 0, 0, chip_8019 }, - { PCI_VENDOR_ID_ADAPTEC2, 0x8089, - PCI_VENDOR_ID_ADAPTEC2, 0x1600, 0, 0, chip_8019 }, {} /* terminate list */ }; @@ -1076,7 +870,7 @@ static int __init pm8001_init(void) { int rc = -ENOMEM; - pm8001_wq = alloc_workqueue("pm80xx", 0, 0); + pm8001_wq = alloc_workqueue("pm8001", 0, 0); if (!pm8001_wq) goto err; @@ -1108,8 +902,7 @@ module_init(pm8001_init); module_exit(pm8001_exit); MODULE_AUTHOR("Jack Wang "); -MODULE_DESCRIPTION( - "PMC-Sierra PM8001/8081/8088/8089 SAS/SATA controller driver"); +MODULE_DESCRIPTION("PMC-Sierra PM8001 SAS/SATA controller driver"); MODULE_VERSION(DRV_VERSION); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, pm8001_pci_table); diff --git a/trunk/drivers/scsi/pm8001/pm8001_sas.c b/trunk/drivers/scsi/pm8001/pm8001_sas.c index a85d73de7c80..b961112395d5 100644 --- a/trunk/drivers/scsi/pm8001/pm8001_sas.c +++ b/trunk/drivers/scsi/pm8001/pm8001_sas.c @@ -1,5 +1,5 @@ /* - * PMC-Sierra PM8001/8081/8088/8089 SAS/SATA based host adapters driver + * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver * * Copyright (c) 2008-2009 USI Co., Ltd. * All rights reserved. @@ -68,7 +68,7 @@ static void pm8001_tag_clear(struct pm8001_hba_info *pm8001_ha, u32 tag) clear_bit(tag, bitmap); } -void pm8001_tag_free(struct pm8001_hba_info *pm8001_ha, u32 tag) +static void pm8001_tag_free(struct pm8001_hba_info *pm8001_ha, u32 tag) { pm8001_tag_clear(pm8001_ha, tag); } @@ -212,12 +212,10 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, break; case PHY_FUNC_GET_EVENTS: spin_lock_irqsave(&pm8001_ha->lock, flags); - if (pm8001_ha->chip_id == chip_8001) { - if (-1 == pm8001_bar4_shift(pm8001_ha, + if (-1 == pm8001_bar4_shift(pm8001_ha, (phy_id < 4) ? 0x30000 : 0x40000)) { - spin_unlock_irqrestore(&pm8001_ha->lock, flags); - return -EINVAL; - } + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + return -EINVAL; } { struct sas_phy *phy = sas_phy->phy; @@ -230,8 +228,7 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, phy->loss_of_dword_sync_count = qp[3]; phy->phy_reset_problem_count = qp[4]; } - if (pm8001_ha->chip_id == chip_8001) - pm8001_bar4_shift(pm8001_ha, 0); + pm8001_bar4_shift(pm8001_ha, 0); spin_unlock_irqrestore(&pm8001_ha->lock, flags); return 0; default: @@ -252,9 +249,7 @@ void pm8001_scan_start(struct Scsi_Host *shost) struct pm8001_hba_info *pm8001_ha; struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); pm8001_ha = sha->lldd_ha; - /* SAS_RE_INITIALIZATION not available in SPCv/ve */ - if (pm8001_ha->chip_id == chip_8001) - PM8001_CHIP_DISP->sas_re_init_req(pm8001_ha); + PM8001_CHIP_DISP->sas_re_init_req(pm8001_ha); for (i = 0; i < pm8001_ha->chip->n_phy; ++i) PM8001_CHIP_DISP->phy_start_req(pm8001_ha, i); } @@ -357,7 +352,7 @@ static int sas_find_local_port_id(struct domain_device *dev) * @tmf: the task management IU */ #define DEV_IS_GONE(pm8001_dev) \ - ((!pm8001_dev || (pm8001_dev->dev_type == SAS_PHY_UNUSED))) + ((!pm8001_dev || (pm8001_dev->dev_type == NO_DEVICE))) static int pm8001_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags, int is_tmf, struct pm8001_tmf_task *tmf) { @@ -375,7 +370,7 @@ static int pm8001_task_exec(struct sas_task *task, const int num, struct task_status_struct *tsm = &t->task_status; tsm->resp = SAS_TASK_UNDELIVERED; tsm->stat = SAS_PHY_DOWN; - if (dev->dev_type != SAS_SATA_DEV) + if (dev->dev_type != SATA_DEV) t->task_done(t); return 0; } @@ -553,7 +548,7 @@ struct pm8001_device *pm8001_alloc_dev(struct pm8001_hba_info *pm8001_ha) { u32 dev; for (dev = 0; dev < PM8001_MAX_DEVICES; dev++) { - if (pm8001_ha->devices[dev].dev_type == SAS_PHY_UNUSED) { + if (pm8001_ha->devices[dev].dev_type == NO_DEVICE) { pm8001_ha->devices[dev].id = dev; return &pm8001_ha->devices[dev]; } @@ -565,31 +560,13 @@ struct pm8001_device *pm8001_alloc_dev(struct pm8001_hba_info *pm8001_ha) } return NULL; } -/** - * pm8001_find_dev - find a matching pm8001_device - * @pm8001_ha: our hba card information - */ -struct pm8001_device *pm8001_find_dev(struct pm8001_hba_info *pm8001_ha, - u32 device_id) -{ - u32 dev; - for (dev = 0; dev < PM8001_MAX_DEVICES; dev++) { - if (pm8001_ha->devices[dev].device_id == device_id) - return &pm8001_ha->devices[dev]; - } - if (dev == PM8001_MAX_DEVICES) { - PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("NO MATCHING " - "DEVICE FOUND !!!\n")); - } - return NULL; -} static void pm8001_free_dev(struct pm8001_device *pm8001_dev) { u32 id = pm8001_dev->id; memset(pm8001_dev, 0, sizeof(*pm8001_dev)); pm8001_dev->id = id; - pm8001_dev->dev_type = SAS_PHY_UNUSED; + pm8001_dev->dev_type = NO_DEVICE; pm8001_dev->device_id = PM8001_MAX_DEVICES; pm8001_dev->sas_device = NULL; } @@ -647,7 +624,7 @@ static int pm8001_dev_found_notify(struct domain_device *dev) res = -1; } } else { - if (dev->dev_type == SAS_SATA_DEV) { + if (dev->dev_type == SATA_DEV) { pm8001_device->attached_phy = dev->rphy->identify.phy_identifier; flag = 1; /* directly sata*/ @@ -657,7 +634,7 @@ static int pm8001_dev_found_notify(struct domain_device *dev) PM8001_CHIP_DISP->reg_dev_req(pm8001_ha, pm8001_device, flag); spin_unlock_irqrestore(&pm8001_ha->lock, flags); wait_for_completion(&completion); - if (dev->dev_type == SAS_END_DEVICE) + if (dev->dev_type == SAS_END_DEV) msleep(50); pm8001_ha->flags = PM8001F_RUN_TIME; return 0; @@ -671,7 +648,7 @@ int pm8001_dev_found(struct domain_device *dev) return pm8001_dev_found_notify(dev); } -void pm8001_task_done(struct sas_task *task) +static void pm8001_task_done(struct sas_task *task) { if (!del_timer(&task->slow_task->timer)) return; @@ -927,7 +904,7 @@ void pm8001_open_reject_retry( struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[i]; pm8001_dev = ccb->device; - if (!pm8001_dev || (pm8001_dev->dev_type == SAS_PHY_UNUSED)) + if (!pm8001_dev || (pm8001_dev->dev_type == NO_DEVICE)) continue; if (!device_to_close) { uintptr_t d = (uintptr_t)pm8001_dev @@ -1018,72 +995,6 @@ int pm8001_I_T_nexus_reset(struct domain_device *dev) return rc; } -/* -* This function handle the IT_NEXUS_XXX event or completion -* status code for SSP/SATA/SMP I/O request. -*/ -int pm8001_I_T_nexus_event_handler(struct domain_device *dev) -{ - int rc = TMF_RESP_FUNC_FAILED; - struct pm8001_device *pm8001_dev; - struct pm8001_hba_info *pm8001_ha; - struct sas_phy *phy; - u32 device_id = 0; - - if (!dev || !dev->lldd_dev) - return -1; - - pm8001_dev = dev->lldd_dev; - device_id = pm8001_dev->device_id; - pm8001_ha = pm8001_find_ha_by_dev(dev); - - PM8001_EH_DBG(pm8001_ha, - pm8001_printk("I_T_Nexus handler invoked !!")); - - phy = sas_get_local_phy(dev); - - if (dev_is_sata(dev)) { - DECLARE_COMPLETION_ONSTACK(completion_setstate); - if (scsi_is_sas_phy_local(phy)) { - rc = 0; - goto out; - } - /* send internal ssp/sata/smp abort command to FW */ - rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , - dev, 1, 0); - msleep(100); - - /* deregister the target device */ - pm8001_dev_gone_notify(dev); - msleep(200); - - /*send phy reset to hard reset target */ - rc = sas_phy_reset(phy, 1); - msleep(2000); - pm8001_dev->setds_completion = &completion_setstate; - - wait_for_completion(&completion_setstate); - } else { - /* send internal ssp/sata/smp abort command to FW */ - rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , - dev, 1, 0); - msleep(100); - - /* deregister the target device */ - pm8001_dev_gone_notify(dev); - msleep(200); - - /*send phy reset to hard reset target */ - rc = sas_phy_reset(phy, 1); - msleep(2000); - } - PM8001_EH_DBG(pm8001_ha, pm8001_printk(" for device[%x]:rc=%d\n", - pm8001_dev->device_id, rc)); -out: - sas_put_local_phy(phy); - - return rc; -} /* mandatory SAM-3, the task reset the specified LUN*/ int pm8001_lu_reset(struct domain_device *dev, u8 *lun) { diff --git a/trunk/drivers/scsi/pm8001/pm8001_sas.h b/trunk/drivers/scsi/pm8001/pm8001_sas.h index 570819464d90..11008205aeb3 100644 --- a/trunk/drivers/scsi/pm8001/pm8001_sas.h +++ b/trunk/drivers/scsi/pm8001/pm8001_sas.h @@ -1,5 +1,5 @@ /* - * PMC-Sierra PM8001/8081/8088/8089 SAS/SATA based host adapters driver + * PMC-Sierra SPC 8001 SAS/SATA based host adapters driver * * Copyright (c) 2008-2009 USI Co., Ltd. * All rights reserved. @@ -57,8 +57,8 @@ #include #include "pm8001_defs.h" -#define DRV_NAME "pm80xx" -#define DRV_VERSION "0.1.37" +#define DRV_NAME "pm8001" +#define DRV_VERSION "0.1.36" #define PM8001_FAIL_LOGGING 0x01 /* Error message logging */ #define PM8001_INIT_LOGGING 0x02 /* driver init logging */ #define PM8001_DISC_LOGGING 0x04 /* discovery layer logging */ @@ -66,8 +66,8 @@ #define PM8001_EH_LOGGING 0x10 /* libsas EH function logging*/ #define PM8001_IOCTL_LOGGING 0x20 /* IOCTL message logging */ #define PM8001_MSG_LOGGING 0x40 /* misc message logging */ -#define pm8001_printk(format, arg...) printk(KERN_INFO "pm80xx %s %d:" \ - format, __func__, __LINE__, ## arg) +#define pm8001_printk(format, arg...) printk(KERN_INFO "%s %d:" format,\ + __func__, __LINE__, ## arg) #define PM8001_CHECK_LOGGING(HBA, LEVEL, CMD) \ do { \ if (unlikely(HBA->logging_level & LEVEL)) \ @@ -103,12 +103,11 @@ do { \ #define PM8001_READ_VPD -#define DEV_IS_EXPANDER(type) ((type == SAS_EDGE_EXPANDER_DEVICE) || (type == SAS_FANOUT_EXPANDER_DEVICE)) +#define DEV_IS_EXPANDER(type) ((type == EDGE_DEV) || (type == FANOUT_DEV)) #define PM8001_NAME_LENGTH 32/* generic length of strings */ extern struct list_head hba_list; extern const struct pm8001_dispatch pm8001_8001_dispatch; -extern const struct pm8001_dispatch pm8001_80xx_dispatch; struct pm8001_hba_info; struct pm8001_ccb_info; @@ -132,15 +131,15 @@ struct pm8001_ioctl_payload { struct pm8001_dispatch { char *name; int (*chip_init)(struct pm8001_hba_info *pm8001_ha); - int (*chip_soft_rst)(struct pm8001_hba_info *pm8001_ha); + int (*chip_soft_rst)(struct pm8001_hba_info *pm8001_ha, u32 signature); void (*chip_rst)(struct pm8001_hba_info *pm8001_ha); int (*chip_ioremap)(struct pm8001_hba_info *pm8001_ha); void (*chip_iounmap)(struct pm8001_hba_info *pm8001_ha); - irqreturn_t (*isr)(struct pm8001_hba_info *pm8001_ha, u8 vec); + irqreturn_t (*isr)(struct pm8001_hba_info *pm8001_ha); u32 (*is_our_interupt)(struct pm8001_hba_info *pm8001_ha); - int (*isr_process_oq)(struct pm8001_hba_info *pm8001_ha, u8 vec); - void (*interrupt_enable)(struct pm8001_hba_info *pm8001_ha, u8 vec); - void (*interrupt_disable)(struct pm8001_hba_info *pm8001_ha, u8 vec); + int (*isr_process_oq)(struct pm8001_hba_info *pm8001_ha); + void (*interrupt_enable)(struct pm8001_hba_info *pm8001_ha); + void (*interrupt_disable)(struct pm8001_hba_info *pm8001_ha); void (*make_prd)(struct scatterlist *scatter, int nr, void *prd); int (*smp_req)(struct pm8001_hba_info *pm8001_ha, struct pm8001_ccb_info *ccb); @@ -174,7 +173,6 @@ struct pm8001_dispatch { }; struct pm8001_chip_info { - u32 encrypt; u32 n_phy; const struct pm8001_dispatch *dispatch; }; @@ -206,7 +204,7 @@ struct pm8001_phy { }; struct pm8001_device { - enum sas_device_type dev_type; + enum sas_dev_type dev_type; struct domain_device *sas_device; u32 attached_phy; u32 id; @@ -258,20 +256,7 @@ struct mpi_mem_req { struct mpi_mem region[USI_MAX_MEMCNT]; }; -struct encrypt { - u32 cipher_mode; - u32 sec_mode; - u32 status; - u32 flag; -}; - -struct sas_phy_attribute_table { - u32 phystart1_16[16]; - u32 outbound_hw_event_pid1_16[16]; -}; - -union main_cfg_table { - struct { +struct main_cfg_table { u32 signature; u32 interface_rev; u32 firmware_rev; @@ -307,69 +292,19 @@ union main_cfg_table { u32 fatal_err_dump_length1; u32 hda_mode_flag; u32 anolog_setup_table_offset; - u32 rsvd[4]; - } pm8001_tbl; - - struct { - u32 signature; - u32 interface_rev; - u32 firmware_rev; - u32 max_out_io; - u32 max_sgl; - u32 ctrl_cap_flag; - u32 gst_offset; - u32 inbound_queue_offset; - u32 outbound_queue_offset; - u32 inbound_q_nppd_hppd; - u32 rsvd[8]; - u32 crc_core_dump; - u32 rsvd1; - u32 upper_event_log_addr; - u32 lower_event_log_addr; - u32 event_log_size; - u32 event_log_severity; - u32 upper_pcs_event_log_addr; - u32 lower_pcs_event_log_addr; - u32 pcs_event_log_size; - u32 pcs_event_log_severity; - u32 fatal_err_interrupt; - u32 fatal_err_dump_offset0; - u32 fatal_err_dump_length0; - u32 fatal_err_dump_offset1; - u32 fatal_err_dump_length1; - u32 gpio_led_mapping; - u32 analog_setup_table_offset; - u32 int_vec_table_offset; - u32 phy_attr_table_offset; - u32 port_recovery_timer; - u32 interrupt_reassertion_delay; - } pm80xx_tbl; }; - -union general_status_table { - struct { +struct general_status_table { u32 gst_len_mpistate; u32 iq_freeze_state0; u32 iq_freeze_state1; u32 msgu_tcnt; u32 iop_tcnt; - u32 rsvd; + u32 reserved; u32 phy_state[8]; - u32 gpio_input_val; - u32 rsvd1[2]; - u32 recover_err_info[8]; - } pm8001_tbl; - struct { - u32 gst_len_mpistate; - u32 iq_freeze_state0; - u32 iq_freeze_state1; - u32 msgu_tcnt; - u32 iop_tcnt; - u32 rsvd[9]; - u32 gpio_input_val; - u32 rsvd1[2]; + u32 reserved1; + u32 reserved2; + u32 reserved3; u32 recover_err_info[8]; - } pm80xx_tbl; }; struct inbound_queue_table { u32 element_pri_size_cnt; @@ -416,21 +351,15 @@ struct pm8001_hba_info { struct device *dev; struct pm8001_hba_memspace io_mem[6]; struct mpi_mem_req memoryMap; - struct encrypt encrypt_info; /* support encryption */ void __iomem *msg_unit_tbl_addr;/*Message Unit Table Addr*/ void __iomem *main_cfg_tbl_addr;/*Main Config Table Addr*/ void __iomem *general_stat_tbl_addr;/*General Status Table Addr*/ void __iomem *inbnd_q_tbl_addr;/*Inbound Queue Config Table Addr*/ void __iomem *outbnd_q_tbl_addr;/*Outbound Queue Config Table Addr*/ - void __iomem *pspa_q_tbl_addr; - /*MPI SAS PHY attributes Queue Config Table Addr*/ - void __iomem *ivt_tbl_addr; /*MPI IVT Table Addr */ - union main_cfg_table main_cfg_tbl; - union general_status_table gs_tbl; - struct inbound_queue_table inbnd_q_tbl[PM8001_MAX_SPCV_INB_NUM]; - struct outbound_queue_table outbnd_q_tbl[PM8001_MAX_SPCV_OUTB_NUM]; - struct sas_phy_attribute_table phy_attr_table; - /* MPI SAS PHY attributes */ + struct main_cfg_table main_cfg_tbl; + struct general_status_table gs_tbl; + struct inbound_queue_table inbnd_q_tbl[PM8001_MAX_INB_NUM]; + struct outbound_queue_table outbnd_q_tbl[PM8001_MAX_OUTB_NUM]; u8 sas_addr[SAS_ADDR_SIZE]; struct sas_ha_struct *sas;/* SCSI/SAS glue */ struct Scsi_Host *shost; @@ -443,12 +372,10 @@ struct pm8001_hba_info { struct pm8001_port port[PM8001_MAX_PHYS]; u32 id; u32 irq; - u32 iomb_size; /* SPC and SPCV IOMB size */ struct pm8001_device *devices; struct pm8001_ccb_info *ccb_info; #ifdef PM8001_USE_MSIX - struct msix_entry msix_entries[PM8001_MAX_MSIX_VEC]; - /*for msi-x interrupt*/ + struct msix_entry msix_entries[16];/*for msi-x interrupt*/ int number_of_intr;/*will be used in remove()*/ #endif #ifdef PM8001_USE_TASKLET @@ -456,10 +383,7 @@ struct pm8001_hba_info { #endif u32 logging_level; u32 fw_status; - u32 smp_exp_mode; - u32 int_vector; const struct firmware *fw_image; - u8 outq[PM8001_MAX_MSIX_VEC]; }; struct pm8001_work { @@ -495,9 +419,6 @@ struct pm8001_fw_image_header { #define FLASH_UPDATE_DNLD_NOT_SUPPORTED 0x10 #define FLASH_UPDATE_DISABLED 0x11 -#define NCQ_READ_LOG_FLAG 0x80000000 -#define NCQ_ABORT_ALL_FLAG 0x40000000 -#define NCQ_2ND_RLE_FLAG 0x20000000 /** * brief param structure for firmware flash update. */ @@ -563,7 +484,6 @@ int pm8001_dev_found(struct domain_device *dev); void pm8001_dev_gone(struct domain_device *dev); int pm8001_lu_reset(struct domain_device *dev, u8 *lun); int pm8001_I_T_nexus_reset(struct domain_device *dev); -int pm8001_I_T_nexus_event_handler(struct domain_device *dev); int pm8001_query_task(struct sas_task *task); void pm8001_open_reject_retry( struct pm8001_hba_info *pm8001_ha, @@ -573,61 +493,6 @@ int pm8001_mem_alloc(struct pci_dev *pdev, void **virt_addr, dma_addr_t *pphys_addr, u32 *pphys_addr_hi, u32 *pphys_addr_lo, u32 mem_size, u32 align); -void pm8001_chip_iounmap(struct pm8001_hba_info *pm8001_ha); -int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha, - struct inbound_queue_table *circularQ, - u32 opCode, void *payload, u32 responseQueue); -int pm8001_mpi_msg_free_get(struct inbound_queue_table *circularQ, - u16 messageSize, void **messagePtr); -u32 pm8001_mpi_msg_free_set(struct pm8001_hba_info *pm8001_ha, void *pMsg, - struct outbound_queue_table *circularQ, u8 bc); -u32 pm8001_mpi_msg_consume(struct pm8001_hba_info *pm8001_ha, - struct outbound_queue_table *circularQ, - void **messagePtr1, u8 *pBC); -int pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha, - struct pm8001_device *pm8001_dev, u32 state); -int pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha, - void *payload); -int pm8001_chip_fw_flash_update_build(struct pm8001_hba_info *pm8001_ha, - void *fw_flash_updata_info, u32 tag); -int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha, void *payload); -int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha, void *payload); -int pm8001_chip_ssp_tm_req(struct pm8001_hba_info *pm8001_ha, - struct pm8001_ccb_info *ccb, - struct pm8001_tmf_task *tmf); -int pm8001_chip_abort_task(struct pm8001_hba_info *pm8001_ha, - struct pm8001_device *pm8001_dev, - u8 flag, u32 task_tag, u32 cmd_tag); -int pm8001_chip_dereg_dev_req(struct pm8001_hba_info *pm8001_ha, u32 device_id); -void pm8001_chip_make_sg(struct scatterlist *scatter, int nr, void *prd); -void pm8001_work_fn(struct work_struct *work); -int pm8001_handle_event(struct pm8001_hba_info *pm8001_ha, - void *data, int handler); -void pm8001_mpi_set_dev_state_resp(struct pm8001_hba_info *pm8001_ha, - void *piomb); -void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, - void *piomb); -void pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, - void *piomb); -int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, - void *piomb); -void pm8001_get_lrate_mode(struct pm8001_phy *phy, u8 link_rate); -void pm8001_get_attached_sas_addr(struct pm8001_phy *phy, u8 *sas_addr); -void pm8001_bytes_dmaed(struct pm8001_hba_info *pm8001_ha, int i); -int pm8001_mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb); -int pm8001_mpi_dereg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb); -int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, - void *piomb); -int pm8001_mpi_general_event(struct pm8001_hba_info *pm8001_ha , void *piomb); -int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb); -struct sas_task *pm8001_alloc_task(void); -void pm8001_task_done(struct sas_task *task); -void pm8001_free_task(struct sas_task *task); -void pm8001_tag_free(struct pm8001_hba_info *pm8001_ha, u32 tag); -struct pm8001_device *pm8001_find_dev(struct pm8001_hba_info *pm8001_ha, - u32 device_id); -int pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha); - int pm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue); /* ctl shared API */ diff --git a/trunk/drivers/scsi/pm8001/pm80xx_hwi.c b/trunk/drivers/scsi/pm8001/pm80xx_hwi.c deleted file mode 100644 index 302514d8157b..000000000000 --- a/trunk/drivers/scsi/pm8001/pm80xx_hwi.c +++ /dev/null @@ -1,4130 +0,0 @@ -/* - * PMC-Sierra SPCv/ve 8088/8089 SAS/SATA based host adapters driver - * - * Copyright (c) 2008-2009 PMC-Sierra, Inc., - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - */ - #include - #include "pm8001_sas.h" - #include "pm80xx_hwi.h" - #include "pm8001_chips.h" - #include "pm8001_ctl.h" - -#define SMP_DIRECT 1 -#define SMP_INDIRECT 2 -/** - * read_main_config_table - read the configure table and save it. - * @pm8001_ha: our hba card information - */ -static void read_main_config_table(struct pm8001_hba_info *pm8001_ha) -{ - void __iomem *address = pm8001_ha->main_cfg_tbl_addr; - - pm8001_ha->main_cfg_tbl.pm80xx_tbl.signature = - pm8001_mr32(address, MAIN_SIGNATURE_OFFSET); - pm8001_ha->main_cfg_tbl.pm80xx_tbl.interface_rev = - pm8001_mr32(address, MAIN_INTERFACE_REVISION); - pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev = - pm8001_mr32(address, MAIN_FW_REVISION); - pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_out_io = - pm8001_mr32(address, MAIN_MAX_OUTSTANDING_IO_OFFSET); - pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_sgl = - pm8001_mr32(address, MAIN_MAX_SGL_OFFSET); - pm8001_ha->main_cfg_tbl.pm80xx_tbl.ctrl_cap_flag = - pm8001_mr32(address, MAIN_CNTRL_CAP_OFFSET); - pm8001_ha->main_cfg_tbl.pm80xx_tbl.gst_offset = - pm8001_mr32(address, MAIN_GST_OFFSET); - pm8001_ha->main_cfg_tbl.pm80xx_tbl.inbound_queue_offset = - pm8001_mr32(address, MAIN_IBQ_OFFSET); - pm8001_ha->main_cfg_tbl.pm80xx_tbl.outbound_queue_offset = - pm8001_mr32(address, MAIN_OBQ_OFFSET); - - /* read Error Dump Offset and Length */ - pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_dump_offset0 = - pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP0_OFFSET); - pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_dump_length0 = - pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP0_LENGTH); - pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_dump_offset1 = - pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP1_OFFSET); - pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_dump_length1 = - pm8001_mr32(address, MAIN_FATAL_ERROR_RDUMP1_LENGTH); - - /* read GPIO LED settings from the configuration table */ - pm8001_ha->main_cfg_tbl.pm80xx_tbl.gpio_led_mapping = - pm8001_mr32(address, MAIN_GPIO_LED_FLAGS_OFFSET); - - /* read analog Setting offset from the configuration table */ - pm8001_ha->main_cfg_tbl.pm80xx_tbl.analog_setup_table_offset = - pm8001_mr32(address, MAIN_ANALOG_SETUP_OFFSET); - - pm8001_ha->main_cfg_tbl.pm80xx_tbl.int_vec_table_offset = - pm8001_mr32(address, MAIN_INT_VECTOR_TABLE_OFFSET); - pm8001_ha->main_cfg_tbl.pm80xx_tbl.phy_attr_table_offset = - pm8001_mr32(address, MAIN_SAS_PHY_ATTR_TABLE_OFFSET); -} - -/** - * read_general_status_table - read the general status table and save it. - * @pm8001_ha: our hba card information - */ -static void read_general_status_table(struct pm8001_hba_info *pm8001_ha) -{ - void __iomem *address = pm8001_ha->general_stat_tbl_addr; - pm8001_ha->gs_tbl.pm80xx_tbl.gst_len_mpistate = - pm8001_mr32(address, GST_GSTLEN_MPIS_OFFSET); - pm8001_ha->gs_tbl.pm80xx_tbl.iq_freeze_state0 = - pm8001_mr32(address, GST_IQ_FREEZE_STATE0_OFFSET); - pm8001_ha->gs_tbl.pm80xx_tbl.iq_freeze_state1 = - pm8001_mr32(address, GST_IQ_FREEZE_STATE1_OFFSET); - pm8001_ha->gs_tbl.pm80xx_tbl.msgu_tcnt = - pm8001_mr32(address, GST_MSGUTCNT_OFFSET); - pm8001_ha->gs_tbl.pm80xx_tbl.iop_tcnt = - pm8001_mr32(address, GST_IOPTCNT_OFFSET); - pm8001_ha->gs_tbl.pm80xx_tbl.gpio_input_val = - pm8001_mr32(address, GST_GPIO_INPUT_VAL); - pm8001_ha->gs_tbl.pm80xx_tbl.recover_err_info[0] = - pm8001_mr32(address, GST_RERRINFO_OFFSET0); - pm8001_ha->gs_tbl.pm80xx_tbl.recover_err_info[1] = - pm8001_mr32(address, GST_RERRINFO_OFFSET1); - pm8001_ha->gs_tbl.pm80xx_tbl.recover_err_info[2] = - pm8001_mr32(address, GST_RERRINFO_OFFSET2); - pm8001_ha->gs_tbl.pm80xx_tbl.recover_err_info[3] = - pm8001_mr32(address, GST_RERRINFO_OFFSET3); - pm8001_ha->gs_tbl.pm80xx_tbl.recover_err_info[4] = - pm8001_mr32(address, GST_RERRINFO_OFFSET4); - pm8001_ha->gs_tbl.pm80xx_tbl.recover_err_info[5] = - pm8001_mr32(address, GST_RERRINFO_OFFSET5); - pm8001_ha->gs_tbl.pm80xx_tbl.recover_err_info[6] = - pm8001_mr32(address, GST_RERRINFO_OFFSET6); - pm8001_ha->gs_tbl.pm80xx_tbl.recover_err_info[7] = - pm8001_mr32(address, GST_RERRINFO_OFFSET7); -} -/** - * read_phy_attr_table - read the phy attribute table and save it. - * @pm8001_ha: our hba card information - */ -static void read_phy_attr_table(struct pm8001_hba_info *pm8001_ha) -{ - void __iomem *address = pm8001_ha->pspa_q_tbl_addr; - pm8001_ha->phy_attr_table.phystart1_16[0] = - pm8001_mr32(address, PSPA_PHYSTATE0_OFFSET); - pm8001_ha->phy_attr_table.phystart1_16[1] = - pm8001_mr32(address, PSPA_PHYSTATE1_OFFSET); - pm8001_ha->phy_attr_table.phystart1_16[2] = - pm8001_mr32(address, PSPA_PHYSTATE2_OFFSET); - pm8001_ha->phy_attr_table.phystart1_16[3] = - pm8001_mr32(address, PSPA_PHYSTATE3_OFFSET); - pm8001_ha->phy_attr_table.phystart1_16[4] = - pm8001_mr32(address, PSPA_PHYSTATE4_OFFSET); - pm8001_ha->phy_attr_table.phystart1_16[5] = - pm8001_mr32(address, PSPA_PHYSTATE5_OFFSET); - pm8001_ha->phy_attr_table.phystart1_16[6] = - pm8001_mr32(address, PSPA_PHYSTATE6_OFFSET); - pm8001_ha->phy_attr_table.phystart1_16[7] = - pm8001_mr32(address, PSPA_PHYSTATE7_OFFSET); - pm8001_ha->phy_attr_table.phystart1_16[8] = - pm8001_mr32(address, PSPA_PHYSTATE8_OFFSET); - pm8001_ha->phy_attr_table.phystart1_16[9] = - pm8001_mr32(address, PSPA_PHYSTATE9_OFFSET); - pm8001_ha->phy_attr_table.phystart1_16[10] = - pm8001_mr32(address, PSPA_PHYSTATE10_OFFSET); - pm8001_ha->phy_attr_table.phystart1_16[11] = - pm8001_mr32(address, PSPA_PHYSTATE11_OFFSET); - pm8001_ha->phy_attr_table.phystart1_16[12] = - pm8001_mr32(address, PSPA_PHYSTATE12_OFFSET); - pm8001_ha->phy_attr_table.phystart1_16[13] = - pm8001_mr32(address, PSPA_PHYSTATE13_OFFSET); - pm8001_ha->phy_attr_table.phystart1_16[14] = - pm8001_mr32(address, PSPA_PHYSTATE14_OFFSET); - pm8001_ha->phy_attr_table.phystart1_16[15] = - pm8001_mr32(address, PSPA_PHYSTATE15_OFFSET); - - pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[0] = - pm8001_mr32(address, PSPA_OB_HW_EVENT_PID0_OFFSET); - pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[1] = - pm8001_mr32(address, PSPA_OB_HW_EVENT_PID1_OFFSET); - pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[2] = - pm8001_mr32(address, PSPA_OB_HW_EVENT_PID2_OFFSET); - pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[3] = - pm8001_mr32(address, PSPA_OB_HW_EVENT_PID3_OFFSET); - pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[4] = - pm8001_mr32(address, PSPA_OB_HW_EVENT_PID4_OFFSET); - pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[5] = - pm8001_mr32(address, PSPA_OB_HW_EVENT_PID5_OFFSET); - pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[6] = - pm8001_mr32(address, PSPA_OB_HW_EVENT_PID6_OFFSET); - pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[7] = - pm8001_mr32(address, PSPA_OB_HW_EVENT_PID7_OFFSET); - pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[8] = - pm8001_mr32(address, PSPA_OB_HW_EVENT_PID8_OFFSET); - pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[9] = - pm8001_mr32(address, PSPA_OB_HW_EVENT_PID9_OFFSET); - pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[10] = - pm8001_mr32(address, PSPA_OB_HW_EVENT_PID10_OFFSET); - pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[11] = - pm8001_mr32(address, PSPA_OB_HW_EVENT_PID11_OFFSET); - pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[12] = - pm8001_mr32(address, PSPA_OB_HW_EVENT_PID12_OFFSET); - pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[13] = - pm8001_mr32(address, PSPA_OB_HW_EVENT_PID13_OFFSET); - pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[14] = - pm8001_mr32(address, PSPA_OB_HW_EVENT_PID14_OFFSET); - pm8001_ha->phy_attr_table.outbound_hw_event_pid1_16[15] = - pm8001_mr32(address, PSPA_OB_HW_EVENT_PID15_OFFSET); - -} - -/** - * read_inbnd_queue_table - read the inbound queue table and save it. - * @pm8001_ha: our hba card information - */ -static void read_inbnd_queue_table(struct pm8001_hba_info *pm8001_ha) -{ - int i; - void __iomem *address = pm8001_ha->inbnd_q_tbl_addr; - for (i = 0; i < PM8001_MAX_SPCV_INB_NUM; i++) { - u32 offset = i * 0x20; - pm8001_ha->inbnd_q_tbl[i].pi_pci_bar = - get_pci_bar_index(pm8001_mr32(address, - (offset + IB_PIPCI_BAR))); - pm8001_ha->inbnd_q_tbl[i].pi_offset = - pm8001_mr32(address, (offset + IB_PIPCI_BAR_OFFSET)); - } -} - -/** - * read_outbnd_queue_table - read the outbound queue table and save it. - * @pm8001_ha: our hba card information - */ -static void read_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha) -{ - int i; - void __iomem *address = pm8001_ha->outbnd_q_tbl_addr; - for (i = 0; i < PM8001_MAX_SPCV_OUTB_NUM; i++) { - u32 offset = i * 0x24; - pm8001_ha->outbnd_q_tbl[i].ci_pci_bar = - get_pci_bar_index(pm8001_mr32(address, - (offset + OB_CIPCI_BAR))); - pm8001_ha->outbnd_q_tbl[i].ci_offset = - pm8001_mr32(address, (offset + OB_CIPCI_BAR_OFFSET)); - } -} - -/** - * init_default_table_values - init the default table. - * @pm8001_ha: our hba card information - */ -static void init_default_table_values(struct pm8001_hba_info *pm8001_ha) -{ - int i; - u32 offsetib, offsetob; - void __iomem *addressib = pm8001_ha->inbnd_q_tbl_addr; - void __iomem *addressob = pm8001_ha->outbnd_q_tbl_addr; - - pm8001_ha->main_cfg_tbl.pm80xx_tbl.upper_event_log_addr = - pm8001_ha->memoryMap.region[AAP1].phys_addr_hi; - pm8001_ha->main_cfg_tbl.pm80xx_tbl.lower_event_log_addr = - pm8001_ha->memoryMap.region[AAP1].phys_addr_lo; - pm8001_ha->main_cfg_tbl.pm80xx_tbl.event_log_size = - PM8001_EVENT_LOG_SIZE; - pm8001_ha->main_cfg_tbl.pm80xx_tbl.event_log_severity = 0x01; - pm8001_ha->main_cfg_tbl.pm80xx_tbl.upper_pcs_event_log_addr = - pm8001_ha->memoryMap.region[IOP].phys_addr_hi; - pm8001_ha->main_cfg_tbl.pm80xx_tbl.lower_pcs_event_log_addr = - pm8001_ha->memoryMap.region[IOP].phys_addr_lo; - pm8001_ha->main_cfg_tbl.pm80xx_tbl.pcs_event_log_size = - PM8001_EVENT_LOG_SIZE; - pm8001_ha->main_cfg_tbl.pm80xx_tbl.pcs_event_log_severity = 0x01; - pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_interrupt = 0x01; - - /* Disable end to end CRC checking */ - pm8001_ha->main_cfg_tbl.pm80xx_tbl.crc_core_dump = (0x1 << 16); - - for (i = 0; i < PM8001_MAX_SPCV_INB_NUM; i++) { - pm8001_ha->inbnd_q_tbl[i].element_pri_size_cnt = - PM8001_MPI_QUEUE | (64 << 16) | (0x00<<30); - pm8001_ha->inbnd_q_tbl[i].upper_base_addr = - pm8001_ha->memoryMap.region[IB + i].phys_addr_hi; - pm8001_ha->inbnd_q_tbl[i].lower_base_addr = - pm8001_ha->memoryMap.region[IB + i].phys_addr_lo; - pm8001_ha->inbnd_q_tbl[i].base_virt = - (u8 *)pm8001_ha->memoryMap.region[IB + i].virt_ptr; - pm8001_ha->inbnd_q_tbl[i].total_length = - pm8001_ha->memoryMap.region[IB + i].total_len; - pm8001_ha->inbnd_q_tbl[i].ci_upper_base_addr = - pm8001_ha->memoryMap.region[CI + i].phys_addr_hi; - pm8001_ha->inbnd_q_tbl[i].ci_lower_base_addr = - pm8001_ha->memoryMap.region[CI + i].phys_addr_lo; - pm8001_ha->inbnd_q_tbl[i].ci_virt = - pm8001_ha->memoryMap.region[CI + i].virt_ptr; - offsetib = i * 0x20; - pm8001_ha->inbnd_q_tbl[i].pi_pci_bar = - get_pci_bar_index(pm8001_mr32(addressib, - (offsetib + 0x14))); - pm8001_ha->inbnd_q_tbl[i].pi_offset = - pm8001_mr32(addressib, (offsetib + 0x18)); - pm8001_ha->inbnd_q_tbl[i].producer_idx = 0; - pm8001_ha->inbnd_q_tbl[i].consumer_index = 0; - } - for (i = 0; i < PM8001_MAX_SPCV_OUTB_NUM; i++) { - pm8001_ha->outbnd_q_tbl[i].element_size_cnt = - PM8001_MPI_QUEUE | (64 << 16) | (0x01<<30); - pm8001_ha->outbnd_q_tbl[i].upper_base_addr = - pm8001_ha->memoryMap.region[OB + i].phys_addr_hi; - pm8001_ha->outbnd_q_tbl[i].lower_base_addr = - pm8001_ha->memoryMap.region[OB + i].phys_addr_lo; - pm8001_ha->outbnd_q_tbl[i].base_virt = - (u8 *)pm8001_ha->memoryMap.region[OB + i].virt_ptr; - pm8001_ha->outbnd_q_tbl[i].total_length = - pm8001_ha->memoryMap.region[OB + i].total_len; - pm8001_ha->outbnd_q_tbl[i].pi_upper_base_addr = - pm8001_ha->memoryMap.region[PI + i].phys_addr_hi; - pm8001_ha->outbnd_q_tbl[i].pi_lower_base_addr = - pm8001_ha->memoryMap.region[PI + i].phys_addr_lo; - /* interrupt vector based on oq */ - pm8001_ha->outbnd_q_tbl[i].interrup_vec_cnt_delay = (i << 24); - pm8001_ha->outbnd_q_tbl[i].pi_virt = - pm8001_ha->memoryMap.region[PI + i].virt_ptr; - offsetob = i * 0x24; - pm8001_ha->outbnd_q_tbl[i].ci_pci_bar = - get_pci_bar_index(pm8001_mr32(addressob, - offsetob + 0x14)); - pm8001_ha->outbnd_q_tbl[i].ci_offset = - pm8001_mr32(addressob, (offsetob + 0x18)); - pm8001_ha->outbnd_q_tbl[i].consumer_idx = 0; - pm8001_ha->outbnd_q_tbl[i].producer_index = 0; - } -} - -/** - * update_main_config_table - update the main default table to the HBA. - * @pm8001_ha: our hba card information - */ -static void update_main_config_table(struct pm8001_hba_info *pm8001_ha) -{ - void __iomem *address = pm8001_ha->main_cfg_tbl_addr; - pm8001_mw32(address, MAIN_IQNPPD_HPPD_OFFSET, - pm8001_ha->main_cfg_tbl.pm80xx_tbl.inbound_q_nppd_hppd); - pm8001_mw32(address, MAIN_EVENT_LOG_ADDR_HI, - pm8001_ha->main_cfg_tbl.pm80xx_tbl.upper_event_log_addr); - pm8001_mw32(address, MAIN_EVENT_LOG_ADDR_LO, - pm8001_ha->main_cfg_tbl.pm80xx_tbl.lower_event_log_addr); - pm8001_mw32(address, MAIN_EVENT_LOG_BUFF_SIZE, - pm8001_ha->main_cfg_tbl.pm80xx_tbl.event_log_size); - pm8001_mw32(address, MAIN_EVENT_LOG_OPTION, - pm8001_ha->main_cfg_tbl.pm80xx_tbl.event_log_severity); - pm8001_mw32(address, MAIN_PCS_EVENT_LOG_ADDR_HI, - pm8001_ha->main_cfg_tbl.pm80xx_tbl.upper_pcs_event_log_addr); - pm8001_mw32(address, MAIN_PCS_EVENT_LOG_ADDR_LO, - pm8001_ha->main_cfg_tbl.pm80xx_tbl.lower_pcs_event_log_addr); - pm8001_mw32(address, MAIN_PCS_EVENT_LOG_BUFF_SIZE, - pm8001_ha->main_cfg_tbl.pm80xx_tbl.pcs_event_log_size); - pm8001_mw32(address, MAIN_PCS_EVENT_LOG_OPTION, - pm8001_ha->main_cfg_tbl.pm80xx_tbl.pcs_event_log_severity); - pm8001_mw32(address, MAIN_FATAL_ERROR_INTERRUPT, - pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_interrupt); - pm8001_mw32(address, MAIN_EVENT_CRC_CHECK, - pm8001_ha->main_cfg_tbl.pm80xx_tbl.crc_core_dump); - - /* SPCv specific */ - pm8001_ha->main_cfg_tbl.pm80xx_tbl.gpio_led_mapping &= 0xCFFFFFFF; - /* Set GPIOLED to 0x2 for LED indicator */ - pm8001_ha->main_cfg_tbl.pm80xx_tbl.gpio_led_mapping |= 0x20000000; - pm8001_mw32(address, MAIN_GPIO_LED_FLAGS_OFFSET, - pm8001_ha->main_cfg_tbl.pm80xx_tbl.gpio_led_mapping); - - pm8001_mw32(address, MAIN_PORT_RECOVERY_TIMER, - pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer); - pm8001_mw32(address, MAIN_INT_REASSERTION_DELAY, - pm8001_ha->main_cfg_tbl.pm80xx_tbl.interrupt_reassertion_delay); -} - -/** - * update_inbnd_queue_table - update the inbound queue table to the HBA. - * @pm8001_ha: our hba card information - */ -static void update_inbnd_queue_table(struct pm8001_hba_info *pm8001_ha, - int number) -{ - void __iomem *address = pm8001_ha->inbnd_q_tbl_addr; - u16 offset = number * 0x20; - pm8001_mw32(address, offset + IB_PROPERITY_OFFSET, - pm8001_ha->inbnd_q_tbl[number].element_pri_size_cnt); - pm8001_mw32(address, offset + IB_BASE_ADDR_HI_OFFSET, - pm8001_ha->inbnd_q_tbl[number].upper_base_addr); - pm8001_mw32(address, offset + IB_BASE_ADDR_LO_OFFSET, - pm8001_ha->inbnd_q_tbl[number].lower_base_addr); - pm8001_mw32(address, offset + IB_CI_BASE_ADDR_HI_OFFSET, - pm8001_ha->inbnd_q_tbl[number].ci_upper_base_addr); - pm8001_mw32(address, offset + IB_CI_BASE_ADDR_LO_OFFSET, - pm8001_ha->inbnd_q_tbl[number].ci_lower_base_addr); -} - -/** - * update_outbnd_queue_table - update the outbound queue table to the HBA. - * @pm8001_ha: our hba card information - */ -static void update_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha, - int number) -{ - void __iomem *address = pm8001_ha->outbnd_q_tbl_addr; - u16 offset = number * 0x24; - pm8001_mw32(address, offset + OB_PROPERITY_OFFSET, - pm8001_ha->outbnd_q_tbl[number].element_size_cnt); - pm8001_mw32(address, offset + OB_BASE_ADDR_HI_OFFSET, - pm8001_ha->outbnd_q_tbl[number].upper_base_addr); - pm8001_mw32(address, offset + OB_BASE_ADDR_LO_OFFSET, - pm8001_ha->outbnd_q_tbl[number].lower_base_addr); - pm8001_mw32(address, offset + OB_PI_BASE_ADDR_HI_OFFSET, - pm8001_ha->outbnd_q_tbl[number].pi_upper_base_addr); - pm8001_mw32(address, offset + OB_PI_BASE_ADDR_LO_OFFSET, - pm8001_ha->outbnd_q_tbl[number].pi_lower_base_addr); - pm8001_mw32(address, offset + OB_INTERRUPT_COALES_OFFSET, - pm8001_ha->outbnd_q_tbl[number].interrup_vec_cnt_delay); -} - -/** - * mpi_init_check - check firmware initialization status. - * @pm8001_ha: our hba card information - */ -static int mpi_init_check(struct pm8001_hba_info *pm8001_ha) -{ - u32 max_wait_count; - u32 value; - u32 gst_len_mpistate; - - /* Write bit0=1 to Inbound DoorBell Register to tell the SPC FW the - table is updated */ - pm8001_cw32(pm8001_ha, 0, MSGU_IBDB_SET, SPCv_MSGU_CFG_TABLE_UPDATE); - /* wait until Inbound DoorBell Clear Register toggled */ - max_wait_count = 2 * 1000 * 1000;/* 2 sec for spcv/ve */ - do { - udelay(1); - value = pm8001_cr32(pm8001_ha, 0, MSGU_IBDB_SET); - value &= SPCv_MSGU_CFG_TABLE_UPDATE; - } while ((value != 0) && (--max_wait_count)); - - if (!max_wait_count) - return -1; - /* check the MPI-State for initialization upto 100ms*/ - max_wait_count = 100 * 1000;/* 100 msec */ - do { - udelay(1); - gst_len_mpistate = - pm8001_mr32(pm8001_ha->general_stat_tbl_addr, - GST_GSTLEN_MPIS_OFFSET); - } while ((GST_MPI_STATE_INIT != - (gst_len_mpistate & GST_MPI_STATE_MASK)) && (--max_wait_count)); - if (!max_wait_count) - return -1; - - /* check MPI Initialization error */ - gst_len_mpistate = gst_len_mpistate >> 16; - if (0x0000 != gst_len_mpistate) - return -1; - - return 0; -} - -/** - * check_fw_ready - The LLDD check if the FW is ready, if not, return error. - * @pm8001_ha: our hba card information - */ -static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) -{ - u32 value; - u32 max_wait_count; - u32 max_wait_time; - int ret = 0; - - /* reset / PCIe ready */ - max_wait_time = max_wait_count = 100 * 1000; /* 100 milli sec */ - do { - udelay(1); - value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); - } while ((value == 0xFFFFFFFF) && (--max_wait_count)); - - /* check ila status */ - max_wait_time = max_wait_count = 1000 * 1000; /* 1000 milli sec */ - do { - udelay(1); - value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); - } while (((value & SCRATCH_PAD_ILA_READY) != - SCRATCH_PAD_ILA_READY) && (--max_wait_count)); - if (!max_wait_count) - ret = -1; - else { - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" ila ready status in %d millisec\n", - (max_wait_time - max_wait_count))); - } - - /* check RAAE status */ - max_wait_time = max_wait_count = 1800 * 1000; /* 1800 milli sec */ - do { - udelay(1); - value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); - } while (((value & SCRATCH_PAD_RAAE_READY) != - SCRATCH_PAD_RAAE_READY) && (--max_wait_count)); - if (!max_wait_count) - ret = -1; - else { - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" raae ready status in %d millisec\n", - (max_wait_time - max_wait_count))); - } - - /* check iop0 status */ - max_wait_time = max_wait_count = 600 * 1000; /* 600 milli sec */ - do { - udelay(1); - value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); - } while (((value & SCRATCH_PAD_IOP0_READY) != SCRATCH_PAD_IOP0_READY) && - (--max_wait_count)); - if (!max_wait_count) - ret = -1; - else { - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" iop0 ready status in %d millisec\n", - (max_wait_time - max_wait_count))); - } - - /* check iop1 status only for 16 port controllers */ - if ((pm8001_ha->chip_id != chip_8008) && - (pm8001_ha->chip_id != chip_8009)) { - /* 200 milli sec */ - max_wait_time = max_wait_count = 200 * 1000; - do { - udelay(1); - value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); - } while (((value & SCRATCH_PAD_IOP1_READY) != - SCRATCH_PAD_IOP1_READY) && (--max_wait_count)); - if (!max_wait_count) - ret = -1; - else { - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "iop1 ready status in %d millisec\n", - (max_wait_time - max_wait_count))); - } - } - - return ret; -} - -static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha) -{ - void __iomem *base_addr; - u32 value; - u32 offset; - u32 pcibar; - u32 pcilogic; - - value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0); - offset = value & 0x03FFFFFF; /* scratch pad 0 TBL address */ - - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("Scratchpad 0 Offset: 0x%x value 0x%x\n", - offset, value)); - pcilogic = (value & 0xFC000000) >> 26; - pcibar = get_pci_bar_index(pcilogic); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("Scratchpad 0 PCI BAR: %d\n", pcibar)); - pm8001_ha->main_cfg_tbl_addr = base_addr = - pm8001_ha->io_mem[pcibar].memvirtaddr + offset; - pm8001_ha->general_stat_tbl_addr = - base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x18) & - 0xFFFFFF); - pm8001_ha->inbnd_q_tbl_addr = - base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x1C) & - 0xFFFFFF); - pm8001_ha->outbnd_q_tbl_addr = - base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x20) & - 0xFFFFFF); - pm8001_ha->ivt_tbl_addr = - base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x8C) & - 0xFFFFFF); - pm8001_ha->pspa_q_tbl_addr = - base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset + 0x90) & - 0xFFFFFF); - - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("GST OFFSET 0x%x\n", - pm8001_cr32(pm8001_ha, pcibar, offset + 0x18))); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("INBND OFFSET 0x%x\n", - pm8001_cr32(pm8001_ha, pcibar, offset + 0x1C))); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("OBND OFFSET 0x%x\n", - pm8001_cr32(pm8001_ha, pcibar, offset + 0x20))); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("IVT OFFSET 0x%x\n", - pm8001_cr32(pm8001_ha, pcibar, offset + 0x8C))); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("PSPA OFFSET 0x%x\n", - pm8001_cr32(pm8001_ha, pcibar, offset + 0x90))); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("addr - main cfg %p general status %p\n", - pm8001_ha->main_cfg_tbl_addr, - pm8001_ha->general_stat_tbl_addr)); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("addr - inbnd %p obnd %p\n", - pm8001_ha->inbnd_q_tbl_addr, - pm8001_ha->outbnd_q_tbl_addr)); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("addr - pspa %p ivt %p\n", - pm8001_ha->pspa_q_tbl_addr, - pm8001_ha->ivt_tbl_addr)); -} - -/** - * pm80xx_set_thermal_config - support the thermal configuration - * @pm8001_ha: our hba card information. - */ -int -pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha) -{ - struct set_ctrl_cfg_req payload; - struct inbound_queue_table *circularQ; - int rc; - u32 tag; - u32 opc = OPC_INB_SET_CONTROLLER_CONFIG; - - memset(&payload, 0, sizeof(struct set_ctrl_cfg_req)); - rc = pm8001_tag_alloc(pm8001_ha, &tag); - if (rc) - return -1; - - circularQ = &pm8001_ha->inbnd_q_tbl[0]; - payload.tag = cpu_to_le32(tag); - payload.cfg_pg[0] = (THERMAL_LOG_ENABLE << 9) | - (THERMAL_ENABLE << 8) | THERMAL_OP_CODE; - payload.cfg_pg[1] = (LTEMPHIL << 24) | (RTEMPHIL << 8); - - rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); - return rc; - -} - -/** -* pm80xx_set_sas_protocol_timer_config - support the SAS Protocol -* Timer configuration page -* @pm8001_ha: our hba card information. -*/ -static int -pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha) -{ - struct set_ctrl_cfg_req payload; - struct inbound_queue_table *circularQ; - SASProtocolTimerConfig_t SASConfigPage; - int rc; - u32 tag; - u32 opc = OPC_INB_SET_CONTROLLER_CONFIG; - - memset(&payload, 0, sizeof(struct set_ctrl_cfg_req)); - memset(&SASConfigPage, 0, sizeof(SASProtocolTimerConfig_t)); - - rc = pm8001_tag_alloc(pm8001_ha, &tag); - - if (rc) - return -1; - - circularQ = &pm8001_ha->inbnd_q_tbl[0]; - payload.tag = cpu_to_le32(tag); - - SASConfigPage.pageCode = SAS_PROTOCOL_TIMER_CONFIG_PAGE; - SASConfigPage.MST_MSI = 3 << 15; - SASConfigPage.STP_SSP_MCT_TMO = (STP_MCT_TMO << 16) | SSP_MCT_TMO; - SASConfigPage.STP_FRM_TMO = (SAS_MAX_OPEN_TIME << 24) | - (SMP_MAX_CONN_TIMER << 16) | STP_FRM_TIMER; - SASConfigPage.STP_IDLE_TMO = STP_IDLE_TIME; - - if (SASConfigPage.STP_IDLE_TMO > 0x3FFFFFF) - SASConfigPage.STP_IDLE_TMO = 0x3FFFFFF; - - - SASConfigPage.OPNRJT_RTRY_INTVL = (SAS_MFD << 16) | - SAS_OPNRJT_RTRY_INTVL; - SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO = (SAS_DOPNRJT_RTRY_TMO << 16) - | SAS_COPNRJT_RTRY_TMO; - SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR = (SAS_DOPNRJT_RTRY_THR << 16) - | SAS_COPNRJT_RTRY_THR; - SASConfigPage.MAX_AIP = SAS_MAX_AIP; - - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("SASConfigPage.pageCode " - "0x%08x\n", SASConfigPage.pageCode)); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("SASConfigPage.MST_MSI " - " 0x%08x\n", SASConfigPage.MST_MSI)); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("SASConfigPage.STP_SSP_MCT_TMO " - " 0x%08x\n", SASConfigPage.STP_SSP_MCT_TMO)); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("SASConfigPage.STP_FRM_TMO " - " 0x%08x\n", SASConfigPage.STP_FRM_TMO)); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("SASConfigPage.STP_IDLE_TMO " - " 0x%08x\n", SASConfigPage.STP_IDLE_TMO)); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("SASConfigPage.OPNRJT_RTRY_INTVL " - " 0x%08x\n", SASConfigPage.OPNRJT_RTRY_INTVL)); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO " - " 0x%08x\n", SASConfigPage.Data_Cmd_OPNRJT_RTRY_TMO)); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR " - " 0x%08x\n", SASConfigPage.Data_Cmd_OPNRJT_RTRY_THR)); - PM8001_INIT_DBG(pm8001_ha, pm8001_printk("SASConfigPage.MAX_AIP " - " 0x%08x\n", SASConfigPage.MAX_AIP)); - - memcpy(&payload.cfg_pg, &SASConfigPage, - sizeof(SASProtocolTimerConfig_t)); - - rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); - - return rc; -} - -/** - * pm80xx_get_encrypt_info - Check for encryption - * @pm8001_ha: our hba card information. - */ -static int -pm80xx_get_encrypt_info(struct pm8001_hba_info *pm8001_ha) -{ - u32 scratch3_value; - int ret; - - /* Read encryption status from SCRATCH PAD 3 */ - scratch3_value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3); - - if ((scratch3_value & SCRATCH_PAD3_ENC_MASK) == - SCRATCH_PAD3_ENC_READY) { - if (scratch3_value & SCRATCH_PAD3_XTS_ENABLED) - pm8001_ha->encrypt_info.cipher_mode = CIPHER_MODE_XTS; - if ((scratch3_value & SCRATCH_PAD3_SM_MASK) == - SCRATCH_PAD3_SMF_ENABLED) - pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMF; - if ((scratch3_value & SCRATCH_PAD3_SM_MASK) == - SCRATCH_PAD3_SMA_ENABLED) - pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMA; - if ((scratch3_value & SCRATCH_PAD3_SM_MASK) == - SCRATCH_PAD3_SMB_ENABLED) - pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMB; - pm8001_ha->encrypt_info.status = 0; - PM8001_INIT_DBG(pm8001_ha, pm8001_printk( - "Encryption: SCRATCH_PAD3_ENC_READY 0x%08X." - "Cipher mode 0x%x Sec mode 0x%x status 0x%x\n", - scratch3_value, pm8001_ha->encrypt_info.cipher_mode, - pm8001_ha->encrypt_info.sec_mode, - pm8001_ha->encrypt_info.status)); - ret = 0; - } else if ((scratch3_value & SCRATCH_PAD3_ENC_READY) == - SCRATCH_PAD3_ENC_DISABLED) { - PM8001_INIT_DBG(pm8001_ha, pm8001_printk( - "Encryption: SCRATCH_PAD3_ENC_DISABLED 0x%08X\n", - scratch3_value)); - pm8001_ha->encrypt_info.status = 0xFFFFFFFF; - pm8001_ha->encrypt_info.cipher_mode = 0; - pm8001_ha->encrypt_info.sec_mode = 0; - return 0; - } else if ((scratch3_value & SCRATCH_PAD3_ENC_MASK) == - SCRATCH_PAD3_ENC_DIS_ERR) { - pm8001_ha->encrypt_info.status = - (scratch3_value & SCRATCH_PAD3_ERR_CODE) >> 16; - if (scratch3_value & SCRATCH_PAD3_XTS_ENABLED) - pm8001_ha->encrypt_info.cipher_mode = CIPHER_MODE_XTS; - if ((scratch3_value & SCRATCH_PAD3_SM_MASK) == - SCRATCH_PAD3_SMF_ENABLED) - pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMF; - if ((scratch3_value & SCRATCH_PAD3_SM_MASK) == - SCRATCH_PAD3_SMA_ENABLED) - pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMA; - if ((scratch3_value & SCRATCH_PAD3_SM_MASK) == - SCRATCH_PAD3_SMB_ENABLED) - pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMB; - PM8001_INIT_DBG(pm8001_ha, pm8001_printk( - "Encryption: SCRATCH_PAD3_DIS_ERR 0x%08X." - "Cipher mode 0x%x sec mode 0x%x status 0x%x\n", - scratch3_value, pm8001_ha->encrypt_info.cipher_mode, - pm8001_ha->encrypt_info.sec_mode, - pm8001_ha->encrypt_info.status)); - ret = -1; - } else if ((scratch3_value & SCRATCH_PAD3_ENC_MASK) == - SCRATCH_PAD3_ENC_ENA_ERR) { - - pm8001_ha->encrypt_info.status = - (scratch3_value & SCRATCH_PAD3_ERR_CODE) >> 16; - if (scratch3_value & SCRATCH_PAD3_XTS_ENABLED) - pm8001_ha->encrypt_info.cipher_mode = CIPHER_MODE_XTS; - if ((scratch3_value & SCRATCH_PAD3_SM_MASK) == - SCRATCH_PAD3_SMF_ENABLED) - pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMF; - if ((scratch3_value & SCRATCH_PAD3_SM_MASK) == - SCRATCH_PAD3_SMA_ENABLED) - pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMA; - if ((scratch3_value & SCRATCH_PAD3_SM_MASK) == - SCRATCH_PAD3_SMB_ENABLED) - pm8001_ha->encrypt_info.sec_mode = SEC_MODE_SMB; - - PM8001_INIT_DBG(pm8001_ha, pm8001_printk( - "Encryption: SCRATCH_PAD3_ENA_ERR 0x%08X." - "Cipher mode 0x%x sec mode 0x%x status 0x%x\n", - scratch3_value, pm8001_ha->encrypt_info.cipher_mode, - pm8001_ha->encrypt_info.sec_mode, - pm8001_ha->encrypt_info.status)); - ret = -1; - } - return ret; -} - -/** - * pm80xx_encrypt_update - update flash with encryption informtion - * @pm8001_ha: our hba card information. - */ -static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha) -{ - struct kek_mgmt_req payload; - struct inbound_queue_table *circularQ; - int rc; - u32 tag; - u32 opc = OPC_INB_KEK_MANAGEMENT; - - memset(&payload, 0, sizeof(struct kek_mgmt_req)); - rc = pm8001_tag_alloc(pm8001_ha, &tag); - if (rc) - return -1; - - circularQ = &pm8001_ha->inbnd_q_tbl[0]; - payload.tag = cpu_to_le32(tag); - /* Currently only one key is used. New KEK index is 1. - * Current KEK index is 1. Store KEK to NVRAM is 1. - */ - payload.new_curidx_ksop = ((1 << 24) | (1 << 16) | (1 << 8) | - KEK_MGMT_SUBOP_KEYCARDUPDATE); - - rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); - - return rc; -} - -/** - * pm8001_chip_init - the main init function that initialize whole PM8001 chip. - * @pm8001_ha: our hba card information - */ -static int pm80xx_chip_init(struct pm8001_hba_info *pm8001_ha) -{ - int ret; - u8 i = 0; - - /* check the firmware status */ - if (-1 == check_fw_ready(pm8001_ha)) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("Firmware is not ready!\n")); - return -EBUSY; - } - - /* Initialize pci space address eg: mpi offset */ - init_pci_device_addresses(pm8001_ha); - init_default_table_values(pm8001_ha); - read_main_config_table(pm8001_ha); - read_general_status_table(pm8001_ha); - read_inbnd_queue_table(pm8001_ha); - read_outbnd_queue_table(pm8001_ha); - read_phy_attr_table(pm8001_ha); - - /* update main config table ,inbound table and outbound table */ - update_main_config_table(pm8001_ha); - for (i = 0; i < PM8001_MAX_SPCV_INB_NUM; i++) - update_inbnd_queue_table(pm8001_ha, i); - for (i = 0; i < PM8001_MAX_SPCV_OUTB_NUM; i++) - update_outbnd_queue_table(pm8001_ha, i); - - /* notify firmware update finished and check initialization status */ - if (0 == mpi_init_check(pm8001_ha)) { - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("MPI initialize successful!\n")); - } else - return -EBUSY; - - /* send SAS protocol timer configuration page to FW */ - ret = pm80xx_set_sas_protocol_timer_config(pm8001_ha); - - /* Check for encryption */ - if (pm8001_ha->chip->encrypt) { - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("Checking for encryption\n")); - ret = pm80xx_get_encrypt_info(pm8001_ha); - if (ret == -1) { - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("Encryption error !!\n")); - if (pm8001_ha->encrypt_info.status == 0x81) { - PM8001_INIT_DBG(pm8001_ha, pm8001_printk( - "Encryption enabled with error." - "Saving encryption key to flash\n")); - pm80xx_encrypt_update(pm8001_ha); - } - } - } - return 0; -} - -static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha) -{ - u32 max_wait_count; - u32 value; - u32 gst_len_mpistate; - init_pci_device_addresses(pm8001_ha); - /* Write bit1=1 to Inbound DoorBell Register to tell the SPC FW the - table is stop */ - pm8001_cw32(pm8001_ha, 0, MSGU_IBDB_SET, SPCv_MSGU_CFG_TABLE_RESET); - - /* wait until Inbound DoorBell Clear Register toggled */ - max_wait_count = 2 * 1000 * 1000; /* 2 sec for spcv/ve */ - do { - udelay(1); - value = pm8001_cr32(pm8001_ha, 0, MSGU_IBDB_SET); - value &= SPCv_MSGU_CFG_TABLE_RESET; - } while ((value != 0) && (--max_wait_count)); - - if (!max_wait_count) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("TIMEOUT:IBDB value/=%x\n", value)); - return -1; - } - - /* check the MPI-State for termination in progress */ - /* wait until Inbound DoorBell Clear Register toggled */ - max_wait_count = 2 * 1000 * 1000; /* 2 sec for spcv/ve */ - do { - udelay(1); - gst_len_mpistate = - pm8001_mr32(pm8001_ha->general_stat_tbl_addr, - GST_GSTLEN_MPIS_OFFSET); - if (GST_MPI_STATE_UNINIT == - (gst_len_mpistate & GST_MPI_STATE_MASK)) - break; - } while (--max_wait_count); - if (!max_wait_count) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk(" TIME OUT MPI State = 0x%x\n", - gst_len_mpistate & GST_MPI_STATE_MASK)); - return -1; - } - - return 0; -} - -/** - * pm8001_chip_soft_rst - soft reset the PM8001 chip, so that the clear all - * the FW register status to the originated status. - * @pm8001_ha: our hba card information - */ - -static int -pm80xx_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) -{ - u32 regval; - u32 bootloader_state; - - /* Check if MPI is in ready state to reset */ - if (mpi_uninit_check(pm8001_ha) != 0) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("MPI state is not ready\n")); - return -1; - } - - /* checked for reset register normal state; 0x0 */ - regval = pm8001_cr32(pm8001_ha, 0, SPC_REG_SOFT_RESET); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("reset register before write : 0x%x\n", regval)); - - pm8001_cw32(pm8001_ha, 0, SPC_REG_SOFT_RESET, SPCv_NORMAL_RESET_VALUE); - mdelay(500); - - regval = pm8001_cr32(pm8001_ha, 0, SPC_REG_SOFT_RESET); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("reset register after write 0x%x\n", regval)); - - if ((regval & SPCv_SOFT_RESET_READ_MASK) == - SPCv_SOFT_RESET_NORMAL_RESET_OCCURED) { - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" soft reset successful [regval: 0x%x]\n", - regval)); - } else { - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" soft reset failed [regval: 0x%x]\n", - regval)); - - /* check bootloader is successfully executed or in HDA mode */ - bootloader_state = - pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1) & - SCRATCH_PAD1_BOOTSTATE_MASK; - - if (bootloader_state == SCRATCH_PAD1_BOOTSTATE_HDA_SEEPROM) { - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "Bootloader state - HDA mode SEEPROM\n")); - } else if (bootloader_state == - SCRATCH_PAD1_BOOTSTATE_HDA_BOOTSTRAP) { - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "Bootloader state - HDA mode Bootstrap Pin\n")); - } else if (bootloader_state == - SCRATCH_PAD1_BOOTSTATE_HDA_SOFTRESET) { - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "Bootloader state - HDA mode soft reset\n")); - } else if (bootloader_state == - SCRATCH_PAD1_BOOTSTATE_CRIT_ERROR) { - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "Bootloader state-HDA mode critical error\n")); - } - return -EBUSY; - } - - /* check the firmware status after reset */ - if (-1 == check_fw_ready(pm8001_ha)) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("Firmware is not ready!\n")); - return -EBUSY; - } - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("SPCv soft reset Complete\n")); - return 0; -} - -static void pm80xx_hw_chip_rst(struct pm8001_hba_info *pm8001_ha) -{ - u32 i; - - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("chip reset start\n")); - - /* do SPCv chip reset. */ - pm8001_cw32(pm8001_ha, 0, SPC_REG_SOFT_RESET, 0x11); - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("SPC soft reset Complete\n")); - - /* Check this ..whether delay is required or no */ - /* delay 10 usec */ - udelay(10); - - /* wait for 20 msec until the firmware gets reloaded */ - i = 20; - do { - mdelay(1); - } while ((--i) != 0); - - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("chip reset finished\n")); -} - -/** - * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt - * @pm8001_ha: our hba card information - */ -static void -pm80xx_chip_intx_interrupt_enable(struct pm8001_hba_info *pm8001_ha) -{ - pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, ODMR_CLEAR_ALL); - pm8001_cw32(pm8001_ha, 0, MSGU_ODCR, ODCR_CLEAR_ALL); -} - -/** - * pm8001_chip_intx_interrupt_disable- disable PM8001 chip interrupt - * @pm8001_ha: our hba card information - */ -static void -pm80xx_chip_intx_interrupt_disable(struct pm8001_hba_info *pm8001_ha) -{ - pm8001_cw32(pm8001_ha, 0, MSGU_ODMR_CLR, ODMR_MASK_ALL); -} - -/** - * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt - * @pm8001_ha: our hba card information - */ -static void -pm80xx_chip_interrupt_enable(struct pm8001_hba_info *pm8001_ha, u8 vec) -{ -#ifdef PM8001_USE_MSIX - u32 mask; - mask = (u32)(1 << vec); - - pm8001_cw32(pm8001_ha, 0, MSGU_ODMR_CLR, (u32)(mask & 0xFFFFFFFF)); - return; -#endif - pm80xx_chip_intx_interrupt_enable(pm8001_ha); - -} - -/** - * pm8001_chip_interrupt_disable- disable PM8001 chip interrupt - * @pm8001_ha: our hba card information - */ -static void -pm80xx_chip_interrupt_disable(struct pm8001_hba_info *pm8001_ha, u8 vec) -{ -#ifdef PM8001_USE_MSIX - u32 mask; - if (vec == 0xFF) - mask = 0xFFFFFFFF; - else - mask = (u32)(1 << vec); - pm8001_cw32(pm8001_ha, 0, MSGU_ODMR, (u32)(mask & 0xFFFFFFFF)); - return; -#endif - pm80xx_chip_intx_interrupt_disable(pm8001_ha); -} - -static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha, - struct pm8001_device *pm8001_ha_dev) -{ - int res; - u32 ccb_tag; - struct pm8001_ccb_info *ccb; - struct sas_task *task = NULL; - struct task_abort_req task_abort; - struct inbound_queue_table *circularQ; - u32 opc = OPC_INB_SATA_ABORT; - int ret; - - if (!pm8001_ha_dev) { - PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("dev is null\n")); - return; - } - - task = sas_alloc_slow_task(GFP_ATOMIC); - - if (!task) { - PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("cannot " - "allocate task\n")); - return; - } - - task->task_done = pm8001_task_done; - - res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); - if (res) - return; - - ccb = &pm8001_ha->ccb_info[ccb_tag]; - ccb->device = pm8001_ha_dev; - ccb->ccb_tag = ccb_tag; - ccb->task = task; - - circularQ = &pm8001_ha->inbnd_q_tbl[0]; - - memset(&task_abort, 0, sizeof(task_abort)); - task_abort.abort_all = cpu_to_le32(1); - task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id); - task_abort.tag = cpu_to_le32(ccb_tag); - - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &task_abort, 0); - -} - -static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha, - struct pm8001_device *pm8001_ha_dev) -{ - struct sata_start_req sata_cmd; - int res; - u32 ccb_tag; - struct pm8001_ccb_info *ccb; - struct sas_task *task = NULL; - struct host_to_dev_fis fis; - struct domain_device *dev; - struct inbound_queue_table *circularQ; - u32 opc = OPC_INB_SATA_HOST_OPSTART; - - task = sas_alloc_slow_task(GFP_ATOMIC); - - if (!task) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("cannot allocate task !!!\n")); - return; - } - task->task_done = pm8001_task_done; - - res = pm8001_tag_alloc(pm8001_ha, &ccb_tag); - if (res) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("cannot allocate tag !!!\n")); - return; - } - - /* allocate domain device by ourselves as libsas - * is not going to provide any - */ - dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC); - if (!dev) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("Domain device cannot be allocated\n")); - sas_free_task(task); - return; - } else { - task->dev = dev; - task->dev->lldd_dev = pm8001_ha_dev; - } - - ccb = &pm8001_ha->ccb_info[ccb_tag]; - ccb->device = pm8001_ha_dev; - ccb->ccb_tag = ccb_tag; - ccb->task = task; - pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG; - pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG; - - memset(&sata_cmd, 0, sizeof(sata_cmd)); - circularQ = &pm8001_ha->inbnd_q_tbl[0]; - - /* construct read log FIS */ - memset(&fis, 0, sizeof(struct host_to_dev_fis)); - fis.fis_type = 0x27; - fis.flags = 0x80; - fis.command = ATA_CMD_READ_LOG_EXT; - fis.lbal = 0x10; - fis.sector_count = 0x1; - - sata_cmd.tag = cpu_to_le32(ccb_tag); - sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id); - sata_cmd.ncqtag_atap_dir_m_dad |= ((0x1 << 7) | (0x5 << 9)); - memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis)); - - res = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &sata_cmd, 0); - -} - -/** - * mpi_ssp_completion- process the event that FW response to the SSP request. - * @pm8001_ha: our hba card information - * @piomb: the message contents of this outbound message. - * - * When FW has completed a ssp request for example a IO request, after it has - * filled the SG data with the data, it will trigger this event represent - * that he has finished the job,please check the coresponding buffer. - * So we will tell the caller who maybe waiting the result to tell upper layer - * that the task has been finished. - */ -static void -mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) -{ - struct sas_task *t; - struct pm8001_ccb_info *ccb; - unsigned long flags; - u32 status; - u32 param; - u32 tag; - struct ssp_completion_resp *psspPayload; - struct task_status_struct *ts; - struct ssp_response_iu *iu; - struct pm8001_device *pm8001_dev; - psspPayload = (struct ssp_completion_resp *)(piomb + 4); - status = le32_to_cpu(psspPayload->status); - tag = le32_to_cpu(psspPayload->tag); - ccb = &pm8001_ha->ccb_info[tag]; - if ((status == IO_ABORTED) && ccb->open_retry) { - /* Being completed by another */ - ccb->open_retry = 0; - return; - } - pm8001_dev = ccb->device; - param = le32_to_cpu(psspPayload->param); - t = ccb->task; - - if (status && status != IO_UNDERFLOW) - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("sas IO status 0x%x\n", status)); - if (unlikely(!t || !t->lldd_task || !t->dev)) - return; - ts = &t->task_status; - switch (status) { - case IO_SUCCESS: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_SUCCESS ,param = 0x%x\n", - param)); - if (param == 0) { - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAM_STAT_GOOD; - } else { - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_PROTO_RESPONSE; - ts->residual = param; - iu = &psspPayload->ssp_resp_iu; - sas_ssp_task_response(pm8001_ha->dev, t, iu); - } - if (pm8001_dev) - pm8001_dev->running_req--; - break; - case IO_ABORTED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_ABORTED IOMB Tag\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_ABORTED_TASK; - break; - case IO_UNDERFLOW: - /* SSP Completion with error */ - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_UNDERFLOW ,param = 0x%x\n", - param)); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DATA_UNDERRUN; - ts->residual = param; - if (pm8001_dev) - pm8001_dev->running_req--; - break; - case IO_NO_DEVICE: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_NO_DEVICE\n")); - ts->resp = SAS_TASK_UNDELIVERED; - ts->stat = SAS_PHY_DOWN; - break; - case IO_XFER_ERROR_BREAK: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_BREAK\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - /* Force the midlayer to retry */ - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - break; - case IO_XFER_ERROR_PHY_NOT_READY: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - break; - case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_EPROTO; - break; - case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_UNKNOWN; - break; - case IO_OPEN_CNX_ERROR_BREAK: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - break; - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: - case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_UNKNOWN; - if (!t->uldd_task) - pm8001_handle_event(pm8001_ha, - pm8001_dev, - IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); - break; - case IO_OPEN_CNX_ERROR_BAD_DESTINATION: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_BAD_DEST; - break; - case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_CONN_RATE; - break; - case IO_OPEN_CNX_ERROR_WRONG_DESTINATION: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n")); - ts->resp = SAS_TASK_UNDELIVERED; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_WRONG_DEST; - break; - case IO_XFER_ERROR_NAK_RECEIVED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - break; - case IO_XFER_ERROR_ACK_NAK_TIMEOUT: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_NAK_R_ERR; - break; - case IO_XFER_ERROR_DMA: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_DMA\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - break; - case IO_XFER_OPEN_RETRY_TIMEOUT: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - break; - case IO_XFER_ERROR_OFFSET_MISMATCH: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_OFFSET_MISMATCH\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - break; - case IO_PORT_IN_RESET: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_PORT_IN_RESET\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - break; - case IO_DS_NON_OPERATIONAL: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_DS_NON_OPERATIONAL\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - if (!t->uldd_task) - pm8001_handle_event(pm8001_ha, - pm8001_dev, - IO_DS_NON_OPERATIONAL); - break; - case IO_DS_IN_RECOVERY: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_DS_IN_RECOVERY\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - break; - case IO_TM_TAG_NOT_FOUND: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_TM_TAG_NOT_FOUND\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - break; - case IO_SSP_EXT_IU_ZERO_LEN_ERROR: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_SSP_EXT_IU_ZERO_LEN_ERROR\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - break; - case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - break; - default: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("Unknown status 0x%x\n", status)); - /* not allowed case. Therefore, return failed status */ - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - break; - } - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("scsi_status = 0x%x\n ", - psspPayload->ssp_resp_iu.status)); - spin_lock_irqsave(&t->task_state_lock, flags); - t->task_state_flags &= ~SAS_TASK_STATE_PENDING; - t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; - t->task_state_flags |= SAS_TASK_STATE_DONE; - if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { - spin_unlock_irqrestore(&t->task_state_lock, flags); - PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( - "task 0x%p done with io_status 0x%x resp 0x%x " - "stat 0x%x but aborted by upper layer!\n", - t, status, ts->resp, ts->stat)); - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - } else { - spin_unlock_irqrestore(&t->task_state_lock, flags); - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/* in order to force CPU ordering */ - t->task_done(t); - } -} - -/*See the comments for mpi_ssp_completion */ -static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) -{ - struct sas_task *t; - unsigned long flags; - struct task_status_struct *ts; - struct pm8001_ccb_info *ccb; - struct pm8001_device *pm8001_dev; - struct ssp_event_resp *psspPayload = - (struct ssp_event_resp *)(piomb + 4); - u32 event = le32_to_cpu(psspPayload->event); - u32 tag = le32_to_cpu(psspPayload->tag); - u32 port_id = le32_to_cpu(psspPayload->port_id); - - ccb = &pm8001_ha->ccb_info[tag]; - t = ccb->task; - pm8001_dev = ccb->device; - if (event) - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("sas IO status 0x%x\n", event)); - if (unlikely(!t || !t->lldd_task || !t->dev)) - return; - ts = &t->task_status; - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("port_id:0x%x, tag:0x%x, event:0x%x\n", - port_id, tag, event)); - switch (event) { - case IO_OVERFLOW: - PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n");) - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DATA_OVERRUN; - ts->residual = 0; - if (pm8001_dev) - pm8001_dev->running_req--; - break; - case IO_XFER_ERROR_BREAK: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_BREAK\n")); - pm8001_handle_event(pm8001_ha, t, IO_XFER_ERROR_BREAK); - return; - case IO_XFER_ERROR_PHY_NOT_READY: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - break; - case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_EPROTO; - break; - case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_UNKNOWN; - break; - case IO_OPEN_CNX_ERROR_BREAK: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - break; - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: - case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_UNKNOWN; - if (!t->uldd_task) - pm8001_handle_event(pm8001_ha, - pm8001_dev, - IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); - break; - case IO_OPEN_CNX_ERROR_BAD_DESTINATION: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_BAD_DEST; - break; - case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_CONN_RATE; - break; - case IO_OPEN_CNX_ERROR_WRONG_DESTINATION: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_WRONG_DEST; - break; - case IO_XFER_ERROR_NAK_RECEIVED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - break; - case IO_XFER_ERROR_ACK_NAK_TIMEOUT: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_NAK_R_ERR; - break; - case IO_XFER_OPEN_RETRY_TIMEOUT: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); - pm8001_handle_event(pm8001_ha, t, IO_XFER_OPEN_RETRY_TIMEOUT); - return; - case IO_XFER_ERROR_UNEXPECTED_PHASE: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_UNEXPECTED_PHASE\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DATA_OVERRUN; - break; - case IO_XFER_ERROR_XFER_RDY_OVERRUN: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_XFER_RDY_OVERRUN\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DATA_OVERRUN; - break; - case IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DATA_OVERRUN; - break; - case IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DATA_OVERRUN; - break; - case IO_XFER_ERROR_OFFSET_MISMATCH: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_OFFSET_MISMATCH\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DATA_OVERRUN; - break; - case IO_XFER_ERROR_XFER_ZERO_DATA_LEN: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_XFER_ZERO_DATA_LEN\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DATA_OVERRUN; - break; - case IO_XFER_ERROR_INTERNAL_CRC_ERROR: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFR_ERROR_INTERNAL_CRC_ERROR\n")); - /* TBC: used default set values */ - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DATA_OVERRUN; - break; - case IO_XFER_CMD_FRAME_ISSUED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_CMD_FRAME_ISSUED\n")); - return; - default: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("Unknown status 0x%x\n", event)); - /* not allowed case. Therefore, return failed status */ - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DATA_OVERRUN; - break; - } - spin_lock_irqsave(&t->task_state_lock, flags); - t->task_state_flags &= ~SAS_TASK_STATE_PENDING; - t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; - t->task_state_flags |= SAS_TASK_STATE_DONE; - if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { - spin_unlock_irqrestore(&t->task_state_lock, flags); - PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( - "task 0x%p done with event 0x%x resp 0x%x " - "stat 0x%x but aborted by upper layer!\n", - t, event, ts->resp, ts->stat)); - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - } else { - spin_unlock_irqrestore(&t->task_state_lock, flags); - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/* in order to force CPU ordering */ - t->task_done(t); - } -} - -/*See the comments for mpi_ssp_completion */ -static void -mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) -{ - struct sas_task *t; - struct pm8001_ccb_info *ccb; - u32 param; - u32 status; - u32 tag; - struct sata_completion_resp *psataPayload; - struct task_status_struct *ts; - struct ata_task_resp *resp ; - u32 *sata_resp; - struct pm8001_device *pm8001_dev; - unsigned long flags; - - psataPayload = (struct sata_completion_resp *)(piomb + 4); - status = le32_to_cpu(psataPayload->status); - tag = le32_to_cpu(psataPayload->tag); - - if (!tag) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("tag null\n")); - return; - } - ccb = &pm8001_ha->ccb_info[tag]; - param = le32_to_cpu(psataPayload->param); - if (ccb) { - t = ccb->task; - pm8001_dev = ccb->device; - } else { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("ccb null\n")); - return; - } - - if (t) { - if (t->dev && (t->dev->lldd_dev)) - pm8001_dev = t->dev->lldd_dev; - } else { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("task null\n")); - return; - } - - if ((pm8001_dev && !(pm8001_dev->id & NCQ_READ_LOG_FLAG)) - && unlikely(!t || !t->lldd_task || !t->dev)) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("task or dev null\n")); - return; - } - - ts = &t->task_status; - if (!ts) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("ts null\n")); - return; - } - - switch (status) { - case IO_SUCCESS: - PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS\n")); - if (param == 0) { - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAM_STAT_GOOD; - /* check if response is for SEND READ LOG */ - if (pm8001_dev && - (pm8001_dev->id & NCQ_READ_LOG_FLAG)) { - /* set new bit for abort_all */ - pm8001_dev->id |= NCQ_ABORT_ALL_FLAG; - /* clear bit for read log */ - pm8001_dev->id = pm8001_dev->id & 0x7FFFFFFF; - pm80xx_send_abort_all(pm8001_ha, pm8001_dev); - /* Free the tag */ - pm8001_tag_free(pm8001_ha, tag); - sas_free_task(t); - return; - } - } else { - u8 len; - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_PROTO_RESPONSE; - ts->residual = param; - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("SAS_PROTO_RESPONSE len = %d\n", - param)); - sata_resp = &psataPayload->sata_resp[0]; - resp = (struct ata_task_resp *)ts->buf; - if (t->ata_task.dma_xfer == 0 && - t->data_dir == PCI_DMA_FROMDEVICE) { - len = sizeof(struct pio_setup_fis); - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("PIO read len = %d\n", len)); - } else if (t->ata_task.use_ncq) { - len = sizeof(struct set_dev_bits_fis); - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("FPDMA len = %d\n", len)); - } else { - len = sizeof(struct dev_to_host_fis); - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("other len = %d\n", len)); - } - if (SAS_STATUS_BUF_SIZE >= sizeof(*resp)) { - resp->frame_len = len; - memcpy(&resp->ending_fis[0], sata_resp, len); - ts->buf_valid_size = sizeof(*resp); - } else - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("response to large\n")); - } - if (pm8001_dev) - pm8001_dev->running_req--; - break; - case IO_ABORTED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_ABORTED IOMB Tag\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_ABORTED_TASK; - if (pm8001_dev) - pm8001_dev->running_req--; - break; - /* following cases are to do cases */ - case IO_UNDERFLOW: - /* SATA Completion with error */ - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_UNDERFLOW param = %d\n", param)); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DATA_UNDERRUN; - ts->residual = param; - if (pm8001_dev) - pm8001_dev->running_req--; - break; - case IO_NO_DEVICE: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_NO_DEVICE\n")); - ts->resp = SAS_TASK_UNDELIVERED; - ts->stat = SAS_PHY_DOWN; - break; - case IO_XFER_ERROR_BREAK: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_BREAK\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_INTERRUPTED; - break; - case IO_XFER_ERROR_PHY_NOT_READY: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - break; - case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_EPROTO; - break; - case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_UNKNOWN; - break; - case IO_OPEN_CNX_ERROR_BREAK: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_CONT0; - break; - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: - case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DEV_NO_RESPONSE; - if (!t->uldd_task) { - pm8001_handle_event(pm8001_ha, - pm8001_dev, - IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); - ts->resp = SAS_TASK_UNDELIVERED; - ts->stat = SAS_QUEUE_FULL; - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/*in order to force CPU ordering*/ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); - return; - } - break; - case IO_OPEN_CNX_ERROR_BAD_DESTINATION: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n")); - ts->resp = SAS_TASK_UNDELIVERED; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_BAD_DEST; - if (!t->uldd_task) { - pm8001_handle_event(pm8001_ha, - pm8001_dev, - IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); - ts->resp = SAS_TASK_UNDELIVERED; - ts->stat = SAS_QUEUE_FULL; - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/*ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); - return; - } - break; - case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_CONN_RATE; - break; - case IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY: - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DEV_NO_RESPONSE; - if (!t->uldd_task) { - pm8001_handle_event(pm8001_ha, - pm8001_dev, - IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY); - ts->resp = SAS_TASK_UNDELIVERED; - ts->stat = SAS_QUEUE_FULL; - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/* ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); - return; - } - break; - case IO_OPEN_CNX_ERROR_WRONG_DESTINATION: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_WRONG_DEST; - break; - case IO_XFER_ERROR_NAK_RECEIVED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_NAK_R_ERR; - break; - case IO_XFER_ERROR_ACK_NAK_TIMEOUT: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_ACK_NAK_TIMEOUT\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_NAK_R_ERR; - break; - case IO_XFER_ERROR_DMA: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_DMA\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_ABORTED_TASK; - break; - case IO_XFER_ERROR_SATA_LINK_TIMEOUT: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_SATA_LINK_TIMEOUT\n")); - ts->resp = SAS_TASK_UNDELIVERED; - ts->stat = SAS_DEV_NO_RESPONSE; - break; - case IO_XFER_ERROR_REJECTED_NCQ_MODE: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_REJECTED_NCQ_MODE\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DATA_UNDERRUN; - break; - case IO_XFER_OPEN_RETRY_TIMEOUT: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_TO; - break; - case IO_PORT_IN_RESET: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_PORT_IN_RESET\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DEV_NO_RESPONSE; - break; - case IO_DS_NON_OPERATIONAL: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_DS_NON_OPERATIONAL\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DEV_NO_RESPONSE; - if (!t->uldd_task) { - pm8001_handle_event(pm8001_ha, pm8001_dev, - IO_DS_NON_OPERATIONAL); - ts->resp = SAS_TASK_UNDELIVERED; - ts->stat = SAS_QUEUE_FULL; - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/*ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); - return; - } - break; - case IO_DS_IN_RECOVERY: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_DS_IN_RECOVERY\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DEV_NO_RESPONSE; - break; - case IO_DS_IN_ERROR: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_DS_IN_ERROR\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DEV_NO_RESPONSE; - if (!t->uldd_task) { - pm8001_handle_event(pm8001_ha, pm8001_dev, - IO_DS_IN_ERROR); - ts->resp = SAS_TASK_UNDELIVERED; - ts->stat = SAS_QUEUE_FULL; - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/*ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); - return; - } - break; - case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - default: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("Unknown status 0x%x\n", status)); - /* not allowed case. Therefore, return failed status */ - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DEV_NO_RESPONSE; - break; - } - spin_lock_irqsave(&t->task_state_lock, flags); - t->task_state_flags &= ~SAS_TASK_STATE_PENDING; - t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; - t->task_state_flags |= SAS_TASK_STATE_DONE; - if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { - spin_unlock_irqrestore(&t->task_state_lock, flags); - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("task 0x%p done with io_status 0x%x" - " resp 0x%x stat 0x%x but aborted by upper layer!\n", - t, status, ts->resp, ts->stat)); - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - } else if (t->uldd_task) { - spin_unlock_irqrestore(&t->task_state_lock, flags); - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/* ditto */ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); - } else if (!t->uldd_task) { - spin_unlock_irqrestore(&t->task_state_lock, flags); - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/*ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); - } -} - -/*See the comments for mpi_ssp_completion */ -static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) -{ - struct sas_task *t; - struct task_status_struct *ts; - struct pm8001_ccb_info *ccb; - struct pm8001_device *pm8001_dev; - struct sata_event_resp *psataPayload = - (struct sata_event_resp *)(piomb + 4); - u32 event = le32_to_cpu(psataPayload->event); - u32 tag = le32_to_cpu(psataPayload->tag); - u32 port_id = le32_to_cpu(psataPayload->port_id); - u32 dev_id = le32_to_cpu(psataPayload->device_id); - unsigned long flags; - - ccb = &pm8001_ha->ccb_info[tag]; - - if (ccb) { - t = ccb->task; - pm8001_dev = ccb->device; - } else { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("No CCB !!!. returning\n")); - return; - } - if (event) - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("SATA EVENT 0x%x\n", event)); - - /* Check if this is NCQ error */ - if (event == IO_XFER_ERROR_ABORTED_NCQ_MODE) { - /* find device using device id */ - pm8001_dev = pm8001_find_dev(pm8001_ha, dev_id); - /* send read log extension */ - if (pm8001_dev) - pm80xx_send_read_log(pm8001_ha, pm8001_dev); - return; - } - - if (unlikely(!t || !t->lldd_task || !t->dev)) { - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("task or dev null\n")); - return; - } - - ts = &t->task_status; - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("port_id:0x%x, tag:0x%x, event:0x%x\n", - port_id, tag, event)); - switch (event) { - case IO_OVERFLOW: - PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DATA_OVERRUN; - ts->residual = 0; - if (pm8001_dev) - pm8001_dev->running_req--; - break; - case IO_XFER_ERROR_BREAK: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_BREAK\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_INTERRUPTED; - break; - case IO_XFER_ERROR_PHY_NOT_READY: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - break; - case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_EPROTO; - break; - case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_UNKNOWN; - break; - case IO_OPEN_CNX_ERROR_BREAK: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_CONT0; - break; - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: - case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED: - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); - ts->resp = SAS_TASK_UNDELIVERED; - ts->stat = SAS_DEV_NO_RESPONSE; - if (!t->uldd_task) { - pm8001_handle_event(pm8001_ha, - pm8001_dev, - IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_QUEUE_FULL; - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/*ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); - return; - } - break; - case IO_OPEN_CNX_ERROR_BAD_DESTINATION: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n")); - ts->resp = SAS_TASK_UNDELIVERED; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_BAD_DEST; - break; - case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_CONN_RATE; - break; - case IO_OPEN_CNX_ERROR_WRONG_DESTINATION: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_WRONG_DEST; - break; - case IO_XFER_ERROR_NAK_RECEIVED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_NAK_RECEIVED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_NAK_R_ERR; - break; - case IO_XFER_ERROR_PEER_ABORTED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_PEER_ABORTED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_NAK_R_ERR; - break; - case IO_XFER_ERROR_REJECTED_NCQ_MODE: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_REJECTED_NCQ_MODE\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DATA_UNDERRUN; - break; - case IO_XFER_OPEN_RETRY_TIMEOUT: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_TO; - break; - case IO_XFER_ERROR_UNEXPECTED_PHASE: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_UNEXPECTED_PHASE\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_TO; - break; - case IO_XFER_ERROR_XFER_RDY_OVERRUN: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_XFER_RDY_OVERRUN\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_TO; - break; - case IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_TO; - break; - case IO_XFER_ERROR_OFFSET_MISMATCH: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_OFFSET_MISMATCH\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_TO; - break; - case IO_XFER_ERROR_XFER_ZERO_DATA_LEN: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_XFER_ZERO_DATA_LEN\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_TO; - break; - case IO_XFER_CMD_FRAME_ISSUED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_CMD_FRAME_ISSUED\n")); - break; - case IO_XFER_PIO_SETUP_ERROR: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_PIO_SETUP_ERROR\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_TO; - break; - case IO_XFER_ERROR_INTERNAL_CRC_ERROR: - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("IO_XFR_ERROR_INTERNAL_CRC_ERROR\n")); - /* TBC: used default set values */ - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_TO; - break; - case IO_XFER_DMA_ACTIVATE_TIMEOUT: - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("IO_XFR_DMA_ACTIVATE_TIMEOUT\n")); - /* TBC: used default set values */ - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_TO; - break; - default: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("Unknown status 0x%x\n", event)); - /* not allowed case. Therefore, return failed status */ - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_TO; - break; - } - spin_lock_irqsave(&t->task_state_lock, flags); - t->task_state_flags &= ~SAS_TASK_STATE_PENDING; - t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; - t->task_state_flags |= SAS_TASK_STATE_DONE; - if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { - spin_unlock_irqrestore(&t->task_state_lock, flags); - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("task 0x%p done with io_status 0x%x" - " resp 0x%x stat 0x%x but aborted by upper layer!\n", - t, event, ts->resp, ts->stat)); - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - } else if (t->uldd_task) { - spin_unlock_irqrestore(&t->task_state_lock, flags); - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/* ditto */ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); - } else if (!t->uldd_task) { - spin_unlock_irqrestore(&t->task_state_lock, flags); - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/*ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - t->task_done(t); - spin_lock_irq(&pm8001_ha->lock); - } -} - -/*See the comments for mpi_ssp_completion */ -static void -mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) -{ - u32 param, i; - struct sas_task *t; - struct pm8001_ccb_info *ccb; - unsigned long flags; - u32 status; - u32 tag; - struct smp_completion_resp *psmpPayload; - struct task_status_struct *ts; - struct pm8001_device *pm8001_dev; - char *pdma_respaddr = NULL; - - psmpPayload = (struct smp_completion_resp *)(piomb + 4); - status = le32_to_cpu(psmpPayload->status); - tag = le32_to_cpu(psmpPayload->tag); - - ccb = &pm8001_ha->ccb_info[tag]; - param = le32_to_cpu(psmpPayload->param); - t = ccb->task; - ts = &t->task_status; - pm8001_dev = ccb->device; - if (status) - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("smp IO status 0x%x\n", status)); - if (unlikely(!t || !t->lldd_task || !t->dev)) - return; - - switch (status) { - - case IO_SUCCESS: - PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAM_STAT_GOOD; - if (pm8001_dev) - pm8001_dev->running_req--; - if (pm8001_ha->smp_exp_mode == SMP_DIRECT) { - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("DIRECT RESPONSE Length:%d\n", - param)); - pdma_respaddr = (char *)(phys_to_virt(cpu_to_le64 - ((u64)sg_dma_address - (&t->smp_task.smp_resp)))); - for (i = 0; i < param; i++) { - *(pdma_respaddr+i) = psmpPayload->_r_a[i]; - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "SMP Byte%d DMA data 0x%x psmp 0x%x\n", - i, *(pdma_respaddr+i), - psmpPayload->_r_a[i])); - } - } - break; - case IO_ABORTED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_ABORTED IOMB\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_ABORTED_TASK; - if (pm8001_dev) - pm8001_dev->running_req--; - break; - case IO_OVERFLOW: - PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_UNDERFLOW\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DATA_OVERRUN; - ts->residual = 0; - if (pm8001_dev) - pm8001_dev->running_req--; - break; - case IO_NO_DEVICE: - PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_NO_DEVICE\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_PHY_DOWN; - break; - case IO_ERROR_HW_TIMEOUT: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_ERROR_HW_TIMEOUT\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAM_STAT_BUSY; - break; - case IO_XFER_ERROR_BREAK: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_BREAK\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAM_STAT_BUSY; - break; - case IO_XFER_ERROR_PHY_NOT_READY: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_PHY_NOT_READY\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAM_STAT_BUSY; - break; - case IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_UNKNOWN; - break; - case IO_OPEN_CNX_ERROR_ZONE_VIOLATION: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_ZONE_VIOLATION\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_UNKNOWN; - break; - case IO_OPEN_CNX_ERROR_BREAK: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_BREAK\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_CONT0; - break; - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS: - case IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE: - case IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_UNKNOWN; - pm8001_handle_event(pm8001_ha, - pm8001_dev, - IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS); - break; - case IO_OPEN_CNX_ERROR_BAD_DESTINATION: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_BAD_DESTINATION\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_BAD_DEST; - break; - case IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED: - PM8001_IO_DBG(pm8001_ha, pm8001_printk(\ - "IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_CONN_RATE; - break; - case IO_OPEN_CNX_ERROR_WRONG_DESTINATION: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_WRONG_DESTINATION\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_WRONG_DEST; - break; - case IO_XFER_ERROR_RX_FRAME: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_ERROR_RX_FRAME\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DEV_NO_RESPONSE; - break; - case IO_XFER_OPEN_RETRY_TIMEOUT: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_XFER_OPEN_RETRY_TIMEOUT\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - break; - case IO_ERROR_INTERNAL_SMP_RESOURCE: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_ERROR_INTERNAL_SMP_RESOURCE\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_QUEUE_FULL; - break; - case IO_PORT_IN_RESET: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_PORT_IN_RESET\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - break; - case IO_DS_NON_OPERATIONAL: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_DS_NON_OPERATIONAL\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DEV_NO_RESPONSE; - break; - case IO_DS_IN_RECOVERY: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_DS_IN_RECOVERY\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - break; - case IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY\n")); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_OPEN_REJECT; - ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; - break; - default: - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("Unknown status 0x%x\n", status)); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAS_DEV_NO_RESPONSE; - /* not allowed case. Therefore, return failed status */ - break; - } - spin_lock_irqsave(&t->task_state_lock, flags); - t->task_state_flags &= ~SAS_TASK_STATE_PENDING; - t->task_state_flags &= ~SAS_TASK_AT_INITIATOR; - t->task_state_flags |= SAS_TASK_STATE_DONE; - if (unlikely((t->task_state_flags & SAS_TASK_STATE_ABORTED))) { - spin_unlock_irqrestore(&t->task_state_lock, flags); - PM8001_FAIL_DBG(pm8001_ha, pm8001_printk( - "task 0x%p done with io_status 0x%x resp 0x%x" - "stat 0x%x but aborted by upper layer!\n", - t, status, ts->resp, ts->stat)); - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - } else { - spin_unlock_irqrestore(&t->task_state_lock, flags); - pm8001_ccb_task_free(pm8001_ha, t, ccb, tag); - mb();/* in order to force CPU ordering */ - t->task_done(t); - } -} - -/** - * pm80xx_hw_event_ack_req- For PM8001,some events need to acknowage to FW. - * @pm8001_ha: our hba card information - * @Qnum: the outbound queue message number. - * @SEA: source of event to ack - * @port_id: port id. - * @phyId: phy id. - * @param0: parameter 0. - * @param1: parameter 1. - */ -static void pm80xx_hw_event_ack_req(struct pm8001_hba_info *pm8001_ha, - u32 Qnum, u32 SEA, u32 port_id, u32 phyId, u32 param0, u32 param1) -{ - struct hw_event_ack_req payload; - u32 opc = OPC_INB_SAS_HW_EVENT_ACK; - - struct inbound_queue_table *circularQ; - - memset((u8 *)&payload, 0, sizeof(payload)); - circularQ = &pm8001_ha->inbnd_q_tbl[Qnum]; - payload.tag = cpu_to_le32(1); - payload.phyid_sea_portid = cpu_to_le32(((SEA & 0xFFFF) << 8) | - ((phyId & 0xFF) << 24) | (port_id & 0xFF)); - payload.param0 = cpu_to_le32(param0); - payload.param1 = cpu_to_le32(param1); - pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); -} - -static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha, - u32 phyId, u32 phy_op); - -/** - * hw_event_sas_phy_up -FW tells me a SAS phy up event. - * @pm8001_ha: our hba card information - * @piomb: IO message buffer - */ -static void -hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) -{ - struct hw_event_resp *pPayload = - (struct hw_event_resp *)(piomb + 4); - u32 lr_status_evt_portid = - le32_to_cpu(pPayload->lr_status_evt_portid); - u32 phyid_npip_portstate = le32_to_cpu(pPayload->phyid_npip_portstate); - - u8 link_rate = - (u8)((lr_status_evt_portid & 0xF0000000) >> 28); - u8 port_id = (u8)(lr_status_evt_portid & 0x000000FF); - u8 phy_id = - (u8)((phyid_npip_portstate & 0xFF0000) >> 16); - u8 portstate = (u8)(phyid_npip_portstate & 0x0000000F); - - struct pm8001_port *port = &pm8001_ha->port[port_id]; - struct sas_ha_struct *sas_ha = pm8001_ha->sas; - struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; - unsigned long flags; - u8 deviceType = pPayload->sas_identify.dev_type; - port->port_state = portstate; - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "portid:%d; phyid:%d; linkrate:%d; " - "portstate:%x; devicetype:%x\n", - port_id, phy_id, link_rate, portstate, deviceType)); - - switch (deviceType) { - case SAS_PHY_UNUSED: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("device type no device.\n")); - break; - case SAS_END_DEVICE: - PM8001_MSG_DBG(pm8001_ha, pm8001_printk("end device.\n")); - pm80xx_chip_phy_ctl_req(pm8001_ha, phy_id, - PHY_NOTIFY_ENABLE_SPINUP); - port->port_attached = 1; - pm8001_get_lrate_mode(phy, link_rate); - break; - case SAS_EDGE_EXPANDER_DEVICE: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("expander device.\n")); - port->port_attached = 1; - pm8001_get_lrate_mode(phy, link_rate); - break; - case SAS_FANOUT_EXPANDER_DEVICE: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("fanout expander device.\n")); - port->port_attached = 1; - pm8001_get_lrate_mode(phy, link_rate); - break; - default: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("unknown device type(%x)\n", deviceType)); - break; - } - phy->phy_type |= PORT_TYPE_SAS; - phy->identify.device_type = deviceType; - phy->phy_attached = 1; - if (phy->identify.device_type == SAS_END_DEVICE) - phy->identify.target_port_protocols = SAS_PROTOCOL_SSP; - else if (phy->identify.device_type != SAS_PHY_UNUSED) - phy->identify.target_port_protocols = SAS_PROTOCOL_SMP; - phy->sas_phy.oob_mode = SAS_OOB_MODE; - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); - spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags); - memcpy(phy->frame_rcvd, &pPayload->sas_identify, - sizeof(struct sas_identify_frame)-4); - phy->frame_rcvd_size = sizeof(struct sas_identify_frame) - 4; - pm8001_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr); - spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags); - if (pm8001_ha->flags == PM8001F_RUN_TIME) - mdelay(200);/*delay a moment to wait disk to spinup*/ - pm8001_bytes_dmaed(pm8001_ha, phy_id); -} - -/** - * hw_event_sata_phy_up -FW tells me a SATA phy up event. - * @pm8001_ha: our hba card information - * @piomb: IO message buffer - */ -static void -hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) -{ - struct hw_event_resp *pPayload = - (struct hw_event_resp *)(piomb + 4); - u32 phyid_npip_portstate = le32_to_cpu(pPayload->phyid_npip_portstate); - u32 lr_status_evt_portid = - le32_to_cpu(pPayload->lr_status_evt_portid); - u8 link_rate = - (u8)((lr_status_evt_portid & 0xF0000000) >> 28); - u8 port_id = (u8)(lr_status_evt_portid & 0x000000FF); - u8 phy_id = - (u8)((phyid_npip_portstate & 0xFF0000) >> 16); - - u8 portstate = (u8)(phyid_npip_portstate & 0x0000000F); - - struct pm8001_port *port = &pm8001_ha->port[port_id]; - struct sas_ha_struct *sas_ha = pm8001_ha->sas; - struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; - unsigned long flags; - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "port id %d, phy id %d link_rate %d portstate 0x%x\n", - port_id, phy_id, link_rate, portstate)); - - port->port_state = portstate; - port->port_attached = 1; - pm8001_get_lrate_mode(phy, link_rate); - phy->phy_type |= PORT_TYPE_SATA; - phy->phy_attached = 1; - phy->sas_phy.oob_mode = SATA_OOB_MODE; - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE); - spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags); - memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4), - sizeof(struct dev_to_host_fis)); - phy->frame_rcvd_size = sizeof(struct dev_to_host_fis); - phy->identify.target_port_protocols = SAS_PROTOCOL_SATA; - phy->identify.device_type = SAS_SATA_DEV; - pm8001_get_attached_sas_addr(phy, phy->sas_phy.attached_sas_addr); - spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags); - pm8001_bytes_dmaed(pm8001_ha, phy_id); -} - -/** - * hw_event_phy_down -we should notify the libsas the phy is down. - * @pm8001_ha: our hba card information - * @piomb: IO message buffer - */ -static void -hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb) -{ - struct hw_event_resp *pPayload = - (struct hw_event_resp *)(piomb + 4); - - u32 lr_status_evt_portid = - le32_to_cpu(pPayload->lr_status_evt_portid); - u8 port_id = (u8)(lr_status_evt_portid & 0x000000FF); - u32 phyid_npip_portstate = le32_to_cpu(pPayload->phyid_npip_portstate); - u8 phy_id = - (u8)((phyid_npip_portstate & 0xFF0000) >> 16); - u8 portstate = (u8)(phyid_npip_portstate & 0x0000000F); - - struct pm8001_port *port = &pm8001_ha->port[port_id]; - struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; - port->port_state = portstate; - phy->phy_type = 0; - phy->identify.device_type = 0; - phy->phy_attached = 0; - memset(&phy->dev_sas_addr, 0, SAS_ADDR_SIZE); - switch (portstate) { - case PORT_VALID: - break; - case PORT_INVALID: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" PortInvalid portID %d\n", port_id)); - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" Last phy Down and port invalid\n")); - port->port_attached = 0; - pm80xx_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN, - port_id, phy_id, 0, 0); - break; - case PORT_IN_RESET: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" Port In Reset portID %d\n", port_id)); - break; - case PORT_NOT_ESTABLISHED: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" phy Down and PORT_NOT_ESTABLISHED\n")); - port->port_attached = 0; - break; - case PORT_LOSTCOMM: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" phy Down and PORT_LOSTCOMM\n")); - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" Last phy Down and port invalid\n")); - port->port_attached = 0; - pm80xx_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN, - port_id, phy_id, 0, 0); - break; - default: - port->port_attached = 0; - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" phy Down and(default) = 0x%x\n", - portstate)); - break; - - } -} - -static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) -{ - struct phy_start_resp *pPayload = - (struct phy_start_resp *)(piomb + 4); - u32 status = - le32_to_cpu(pPayload->status); - u32 phy_id = - le32_to_cpu(pPayload->phyid); - struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; - - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("phy start resp status:0x%x, phyid:0x%x\n", - status, phy_id)); - if (status == 0) { - phy->phy_state = 1; - if (pm8001_ha->flags == PM8001F_RUN_TIME) - complete(phy->enable_completion); - } - return 0; - -} - -/** - * mpi_thermal_hw_event -The hw event has come. - * @pm8001_ha: our hba card information - * @piomb: IO message buffer - */ -static int mpi_thermal_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) -{ - struct thermal_hw_event *pPayload = - (struct thermal_hw_event *)(piomb + 4); - - u32 thermal_event = le32_to_cpu(pPayload->thermal_event); - u32 rht_lht = le32_to_cpu(pPayload->rht_lht); - - if (thermal_event & 0x40) { - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "Thermal Event: Local high temperature violated!\n")); - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "Thermal Event: Measured local high temperature %d\n", - ((rht_lht & 0xFF00) >> 8))); - } - if (thermal_event & 0x10) { - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "Thermal Event: Remote high temperature violated!\n")); - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "Thermal Event: Measured remote high temperature %d\n", - ((rht_lht & 0xFF000000) >> 24))); - } - return 0; -} - -/** - * mpi_hw_event -The hw event has come. - * @pm8001_ha: our hba card information - * @piomb: IO message buffer - */ -static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) -{ - unsigned long flags; - struct hw_event_resp *pPayload = - (struct hw_event_resp *)(piomb + 4); - u32 lr_status_evt_portid = - le32_to_cpu(pPayload->lr_status_evt_portid); - u32 phyid_npip_portstate = le32_to_cpu(pPayload->phyid_npip_portstate); - u8 port_id = (u8)(lr_status_evt_portid & 0x000000FF); - u8 phy_id = - (u8)((phyid_npip_portstate & 0xFF0000) >> 16); - u16 eventType = - (u16)((lr_status_evt_portid & 0x00FFFF00) >> 8); - u8 status = - (u8)((lr_status_evt_portid & 0x0F000000) >> 24); - - struct sas_ha_struct *sas_ha = pm8001_ha->sas; - struct pm8001_phy *phy = &pm8001_ha->phy[phy_id]; - struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("portid:%d phyid:%d event:0x%x status:0x%x\n", - port_id, phy_id, eventType, status)); - - switch (eventType) { - - case HW_EVENT_SAS_PHY_UP: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_PHY_START_STATUS\n")); - hw_event_sas_phy_up(pm8001_ha, piomb); - break; - case HW_EVENT_SATA_PHY_UP: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_SATA_PHY_UP\n")); - hw_event_sata_phy_up(pm8001_ha, piomb); - break; - case HW_EVENT_SATA_SPINUP_HOLD: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_SATA_SPINUP_HOLD\n")); - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD); - break; - case HW_EVENT_PHY_DOWN: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_PHY_DOWN\n")); - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL); - phy->phy_attached = 0; - phy->phy_state = 0; - hw_event_phy_down(pm8001_ha, piomb); - break; - case HW_EVENT_PORT_INVALID: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_PORT_INVALID\n")); - sas_phy_disconnected(sas_phy); - phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); - break; - /* the broadcast change primitive received, tell the LIBSAS this event - to revalidate the sas domain*/ - case HW_EVENT_BROADCAST_CHANGE: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_BROADCAST_CHANGE\n")); - pm80xx_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_BROADCAST_CHANGE, - port_id, phy_id, 1, 0); - spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); - sas_phy->sas_prim = HW_EVENT_BROADCAST_CHANGE; - spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); - sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); - break; - case HW_EVENT_PHY_ERROR: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_PHY_ERROR\n")); - sas_phy_disconnected(&phy->sas_phy); - phy->phy_attached = 0; - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_ERROR); - break; - case HW_EVENT_BROADCAST_EXP: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_BROADCAST_EXP\n")); - spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); - sas_phy->sas_prim = HW_EVENT_BROADCAST_EXP; - spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); - sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); - break; - case HW_EVENT_LINK_ERR_INVALID_DWORD: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_LINK_ERR_INVALID_DWORD\n")); - pm80xx_hw_event_ack_req(pm8001_ha, 0, - HW_EVENT_LINK_ERR_INVALID_DWORD, port_id, phy_id, 0, 0); - sas_phy_disconnected(sas_phy); - phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); - break; - case HW_EVENT_LINK_ERR_DISPARITY_ERROR: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_LINK_ERR_DISPARITY_ERROR\n")); - pm80xx_hw_event_ack_req(pm8001_ha, 0, - HW_EVENT_LINK_ERR_DISPARITY_ERROR, - port_id, phy_id, 0, 0); - sas_phy_disconnected(sas_phy); - phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); - break; - case HW_EVENT_LINK_ERR_CODE_VIOLATION: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_LINK_ERR_CODE_VIOLATION\n")); - pm80xx_hw_event_ack_req(pm8001_ha, 0, - HW_EVENT_LINK_ERR_CODE_VIOLATION, - port_id, phy_id, 0, 0); - sas_phy_disconnected(sas_phy); - phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); - break; - case HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH: - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH\n")); - pm80xx_hw_event_ack_req(pm8001_ha, 0, - HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH, - port_id, phy_id, 0, 0); - sas_phy_disconnected(sas_phy); - phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); - break; - case HW_EVENT_MALFUNCTION: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_MALFUNCTION\n")); - break; - case HW_EVENT_BROADCAST_SES: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_BROADCAST_SES\n")); - spin_lock_irqsave(&sas_phy->sas_prim_lock, flags); - sas_phy->sas_prim = HW_EVENT_BROADCAST_SES; - spin_unlock_irqrestore(&sas_phy->sas_prim_lock, flags); - sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); - break; - case HW_EVENT_INBOUND_CRC_ERROR: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_INBOUND_CRC_ERROR\n")); - pm80xx_hw_event_ack_req(pm8001_ha, 0, - HW_EVENT_INBOUND_CRC_ERROR, - port_id, phy_id, 0, 0); - break; - case HW_EVENT_HARD_RESET_RECEIVED: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_HARD_RESET_RECEIVED\n")); - sas_ha->notify_port_event(sas_phy, PORTE_HARD_RESET); - break; - case HW_EVENT_ID_FRAME_TIMEOUT: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_ID_FRAME_TIMEOUT\n")); - sas_phy_disconnected(sas_phy); - phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); - break; - case HW_EVENT_LINK_ERR_PHY_RESET_FAILED: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_LINK_ERR_PHY_RESET_FAILED\n")); - pm80xx_hw_event_ack_req(pm8001_ha, 0, - HW_EVENT_LINK_ERR_PHY_RESET_FAILED, - port_id, phy_id, 0, 0); - sas_phy_disconnected(sas_phy); - phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); - break; - case HW_EVENT_PORT_RESET_TIMER_TMO: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_PORT_RESET_TIMER_TMO\n")); - sas_phy_disconnected(sas_phy); - phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); - break; - case HW_EVENT_PORT_RECOVERY_TIMER_TMO: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_PORT_RECOVERY_TIMER_TMO\n")); - pm80xx_hw_event_ack_req(pm8001_ha, 0, - HW_EVENT_PORT_RECOVERY_TIMER_TMO, - port_id, phy_id, 0, 0); - sas_phy_disconnected(sas_phy); - phy->phy_attached = 0; - sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR); - break; - case HW_EVENT_PORT_RECOVER: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_PORT_RECOVER\n")); - break; - case HW_EVENT_PORT_RESET_COMPLETE: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("HW_EVENT_PORT_RESET_COMPLETE\n")); - break; - case EVENT_BROADCAST_ASYNCH_EVENT: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("EVENT_BROADCAST_ASYNCH_EVENT\n")); - break; - default: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("Unknown event type 0x%x\n", eventType)); - break; - } - return 0; -} - -/** - * mpi_phy_stop_resp - SPCv specific - * @pm8001_ha: our hba card information - * @piomb: IO message buffer - */ -static int mpi_phy_stop_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) -{ - struct phy_stop_resp *pPayload = - (struct phy_stop_resp *)(piomb + 4); - u32 status = - le32_to_cpu(pPayload->status); - u32 phyid = - le32_to_cpu(pPayload->phyid); - struct pm8001_phy *phy = &pm8001_ha->phy[phyid]; - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("phy:0x%x status:0x%x\n", - phyid, status)); - if (status == 0) - phy->phy_state = 0; - return 0; -} - -/** - * mpi_set_controller_config_resp - SPCv specific - * @pm8001_ha: our hba card information - * @piomb: IO message buffer - */ -static int mpi_set_controller_config_resp(struct pm8001_hba_info *pm8001_ha, - void *piomb) -{ - struct set_ctrl_cfg_resp *pPayload = - (struct set_ctrl_cfg_resp *)(piomb + 4); - u32 status = le32_to_cpu(pPayload->status); - u32 err_qlfr_pgcd = le32_to_cpu(pPayload->err_qlfr_pgcd); - - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "SET CONTROLLER RESP: status 0x%x qlfr_pgcd 0x%x\n", - status, err_qlfr_pgcd)); - - return 0; -} - -/** - * mpi_get_controller_config_resp - SPCv specific - * @pm8001_ha: our hba card information - * @piomb: IO message buffer - */ -static int mpi_get_controller_config_resp(struct pm8001_hba_info *pm8001_ha, - void *piomb) -{ - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" pm80xx_addition_functionality\n")); - - return 0; -} - -/** - * mpi_get_phy_profile_resp - SPCv specific - * @pm8001_ha: our hba card information - * @piomb: IO message buffer - */ -static int mpi_get_phy_profile_resp(struct pm8001_hba_info *pm8001_ha, - void *piomb) -{ - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" pm80xx_addition_functionality\n")); - - return 0; -} - -/** - * mpi_flash_op_ext_resp - SPCv specific - * @pm8001_ha: our hba card information - * @piomb: IO message buffer - */ -static int mpi_flash_op_ext_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) -{ - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" pm80xx_addition_functionality\n")); - - return 0; -} - -/** - * mpi_set_phy_profile_resp - SPCv specific - * @pm8001_ha: our hba card information - * @piomb: IO message buffer - */ -static int mpi_set_phy_profile_resp(struct pm8001_hba_info *pm8001_ha, - void *piomb) -{ - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" pm80xx_addition_functionality\n")); - - return 0; -} - -/** - * mpi_kek_management_resp - SPCv specific - * @pm8001_ha: our hba card information - * @piomb: IO message buffer - */ -static int mpi_kek_management_resp(struct pm8001_hba_info *pm8001_ha, - void *piomb) -{ - struct kek_mgmt_resp *pPayload = (struct kek_mgmt_resp *)(piomb + 4); - - u32 status = le32_to_cpu(pPayload->status); - u32 kidx_new_curr_ksop = le32_to_cpu(pPayload->kidx_new_curr_ksop); - u32 err_qlfr = le32_to_cpu(pPayload->err_qlfr); - - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "KEK MGMT RESP. Status 0x%x idx_ksop 0x%x err_qlfr 0x%x\n", - status, kidx_new_curr_ksop, err_qlfr)); - - return 0; -} - -/** - * mpi_dek_management_resp - SPCv specific - * @pm8001_ha: our hba card information - * @piomb: IO message buffer - */ -static int mpi_dek_management_resp(struct pm8001_hba_info *pm8001_ha, - void *piomb) -{ - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" pm80xx_addition_functionality\n")); - - return 0; -} - -/** - * ssp_coalesced_comp_resp - SPCv specific - * @pm8001_ha: our hba card information - * @piomb: IO message buffer - */ -static int ssp_coalesced_comp_resp(struct pm8001_hba_info *pm8001_ha, - void *piomb) -{ - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk(" pm80xx_addition_functionality\n")); - - return 0; -} - -/** - * process_one_iomb - process one outbound Queue memory block - * @pm8001_ha: our hba card information - * @piomb: IO message buffer - */ -static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) -{ - __le32 pHeader = *(__le32 *)piomb; - u32 opc = (u32)((le32_to_cpu(pHeader)) & 0xFFF); - - switch (opc) { - case OPC_OUB_ECHO: - PM8001_MSG_DBG(pm8001_ha, pm8001_printk("OPC_OUB_ECHO\n")); - break; - case OPC_OUB_HW_EVENT: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_HW_EVENT\n")); - mpi_hw_event(pm8001_ha, piomb); - break; - case OPC_OUB_THERM_HW_EVENT: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_THERMAL_EVENT\n")); - mpi_thermal_hw_event(pm8001_ha, piomb); - break; - case OPC_OUB_SSP_COMP: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_SSP_COMP\n")); - mpi_ssp_completion(pm8001_ha, piomb); - break; - case OPC_OUB_SMP_COMP: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_SMP_COMP\n")); - mpi_smp_completion(pm8001_ha, piomb); - break; - case OPC_OUB_LOCAL_PHY_CNTRL: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_LOCAL_PHY_CNTRL\n")); - pm8001_mpi_local_phy_ctl(pm8001_ha, piomb); - break; - case OPC_OUB_DEV_REGIST: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_DEV_REGIST\n")); - pm8001_mpi_reg_resp(pm8001_ha, piomb); - break; - case OPC_OUB_DEREG_DEV: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("unresgister the deviece\n")); - pm8001_mpi_dereg_resp(pm8001_ha, piomb); - break; - case OPC_OUB_GET_DEV_HANDLE: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_GET_DEV_HANDLE\n")); - break; - case OPC_OUB_SATA_COMP: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_SATA_COMP\n")); - mpi_sata_completion(pm8001_ha, piomb); - break; - case OPC_OUB_SATA_EVENT: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_SATA_EVENT\n")); - mpi_sata_event(pm8001_ha, piomb); - break; - case OPC_OUB_SSP_EVENT: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_SSP_EVENT\n")); - mpi_ssp_event(pm8001_ha, piomb); - break; - case OPC_OUB_DEV_HANDLE_ARRIV: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_DEV_HANDLE_ARRIV\n")); - /*This is for target*/ - break; - case OPC_OUB_SSP_RECV_EVENT: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_SSP_RECV_EVENT\n")); - /*This is for target*/ - break; - case OPC_OUB_FW_FLASH_UPDATE: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_FW_FLASH_UPDATE\n")); - pm8001_mpi_fw_flash_update_resp(pm8001_ha, piomb); - break; - case OPC_OUB_GPIO_RESPONSE: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_GPIO_RESPONSE\n")); - break; - case OPC_OUB_GPIO_EVENT: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_GPIO_EVENT\n")); - break; - case OPC_OUB_GENERAL_EVENT: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_GENERAL_EVENT\n")); - pm8001_mpi_general_event(pm8001_ha, piomb); - break; - case OPC_OUB_SSP_ABORT_RSP: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_SSP_ABORT_RSP\n")); - pm8001_mpi_task_abort_resp(pm8001_ha, piomb); - break; - case OPC_OUB_SATA_ABORT_RSP: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_SATA_ABORT_RSP\n")); - pm8001_mpi_task_abort_resp(pm8001_ha, piomb); - break; - case OPC_OUB_SAS_DIAG_MODE_START_END: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_SAS_DIAG_MODE_START_END\n")); - break; - case OPC_OUB_SAS_DIAG_EXECUTE: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_SAS_DIAG_EXECUTE\n")); - break; - case OPC_OUB_GET_TIME_STAMP: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_GET_TIME_STAMP\n")); - break; - case OPC_OUB_SAS_HW_EVENT_ACK: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_SAS_HW_EVENT_ACK\n")); - break; - case OPC_OUB_PORT_CONTROL: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_PORT_CONTROL\n")); - break; - case OPC_OUB_SMP_ABORT_RSP: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_SMP_ABORT_RSP\n")); - pm8001_mpi_task_abort_resp(pm8001_ha, piomb); - break; - case OPC_OUB_GET_NVMD_DATA: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_GET_NVMD_DATA\n")); - pm8001_mpi_get_nvmd_resp(pm8001_ha, piomb); - break; - case OPC_OUB_SET_NVMD_DATA: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_SET_NVMD_DATA\n")); - pm8001_mpi_set_nvmd_resp(pm8001_ha, piomb); - break; - case OPC_OUB_DEVICE_HANDLE_REMOVAL: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_DEVICE_HANDLE_REMOVAL\n")); - break; - case OPC_OUB_SET_DEVICE_STATE: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_SET_DEVICE_STATE\n")); - pm8001_mpi_set_dev_state_resp(pm8001_ha, piomb); - break; - case OPC_OUB_GET_DEVICE_STATE: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_GET_DEVICE_STATE\n")); - break; - case OPC_OUB_SET_DEV_INFO: - PM8001_MSG_DBG(pm8001_ha, - pm8001_printk("OPC_OUB_SET_DEV_INFO\n")); - break; - /* spcv specifc commands */ - case OPC_OUB_PHY_START_RESP: - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "OPC_OUB_PHY_START_RESP opcode:%x\n", opc)); - mpi_phy_start_resp(pm8001_ha, piomb); - break; - case OPC_OUB_PHY_STOP_RESP: - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "OPC_OUB_PHY_STOP_RESP opcode:%x\n", opc)); - mpi_phy_stop_resp(pm8001_ha, piomb); - break; - case OPC_OUB_SET_CONTROLLER_CONFIG: - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "OPC_OUB_SET_CONTROLLER_CONFIG opcode:%x\n", opc)); - mpi_set_controller_config_resp(pm8001_ha, piomb); - break; - case OPC_OUB_GET_CONTROLLER_CONFIG: - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "OPC_OUB_GET_CONTROLLER_CONFIG opcode:%x\n", opc)); - mpi_get_controller_config_resp(pm8001_ha, piomb); - break; - case OPC_OUB_GET_PHY_PROFILE: - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "OPC_OUB_GET_PHY_PROFILE opcode:%x\n", opc)); - mpi_get_phy_profile_resp(pm8001_ha, piomb); - break; - case OPC_OUB_FLASH_OP_EXT: - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "OPC_OUB_FLASH_OP_EXT opcode:%x\n", opc)); - mpi_flash_op_ext_resp(pm8001_ha, piomb); - break; - case OPC_OUB_SET_PHY_PROFILE: - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "OPC_OUB_SET_PHY_PROFILE opcode:%x\n", opc)); - mpi_set_phy_profile_resp(pm8001_ha, piomb); - break; - case OPC_OUB_KEK_MANAGEMENT_RESP: - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "OPC_OUB_KEK_MANAGEMENT_RESP opcode:%x\n", opc)); - mpi_kek_management_resp(pm8001_ha, piomb); - break; - case OPC_OUB_DEK_MANAGEMENT_RESP: - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "OPC_OUB_DEK_MANAGEMENT_RESP opcode:%x\n", opc)); - mpi_dek_management_resp(pm8001_ha, piomb); - break; - case OPC_OUB_SSP_COALESCED_COMP_RESP: - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "OPC_OUB_SSP_COALESCED_COMP_RESP opcode:%x\n", opc)); - ssp_coalesced_comp_resp(pm8001_ha, piomb); - break; - default: - PM8001_MSG_DBG(pm8001_ha, pm8001_printk( - "Unknown outbound Queue IOMB OPC = 0x%x\n", opc)); - break; - } -} - -static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) -{ - struct outbound_queue_table *circularQ; - void *pMsg1 = NULL; - u8 uninitialized_var(bc); - u32 ret = MPI_IO_STATUS_FAIL; - unsigned long flags; - - spin_lock_irqsave(&pm8001_ha->lock, flags); - circularQ = &pm8001_ha->outbnd_q_tbl[vec]; - do { - ret = pm8001_mpi_msg_consume(pm8001_ha, circularQ, &pMsg1, &bc); - if (MPI_IO_STATUS_SUCCESS == ret) { - /* process the outbound message */ - process_one_iomb(pm8001_ha, (void *)(pMsg1 - 4)); - /* free the message from the outbound circular buffer */ - pm8001_mpi_msg_free_set(pm8001_ha, pMsg1, - circularQ, bc); - } - if (MPI_IO_STATUS_BUSY == ret) { - /* Update the producer index from SPC */ - circularQ->producer_index = - cpu_to_le32(pm8001_read_32(circularQ->pi_virt)); - if (le32_to_cpu(circularQ->producer_index) == - circularQ->consumer_idx) - /* OQ is empty */ - break; - } - } while (1); - spin_unlock_irqrestore(&pm8001_ha->lock, flags); - return ret; -} - -/* PCI_DMA_... to our direction translation. */ -static const u8 data_dir_flags[] = { - [PCI_DMA_BIDIRECTIONAL] = DATA_DIR_BYRECIPIENT,/* UNSPECIFIED */ - [PCI_DMA_TODEVICE] = DATA_DIR_OUT,/* OUTBOUND */ - [PCI_DMA_FROMDEVICE] = DATA_DIR_IN,/* INBOUND */ - [PCI_DMA_NONE] = DATA_DIR_NONE,/* NO TRANSFER */ -}; - -static void build_smp_cmd(u32 deviceID, __le32 hTag, - struct smp_req *psmp_cmd, int mode, int length) -{ - psmp_cmd->tag = hTag; - psmp_cmd->device_id = cpu_to_le32(deviceID); - if (mode == SMP_DIRECT) { - length = length - 4; /* subtract crc */ - psmp_cmd->len_ip_ir = cpu_to_le32(length << 16); - } else { - psmp_cmd->len_ip_ir = cpu_to_le32(1|(1 << 1)); - } -} - -/** - * pm8001_chip_smp_req - send a SMP task to FW - * @pm8001_ha: our hba card information. - * @ccb: the ccb information this request used. - */ -static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha, - struct pm8001_ccb_info *ccb) -{ - int elem, rc; - struct sas_task *task = ccb->task; - struct domain_device *dev = task->dev; - struct pm8001_device *pm8001_dev = dev->lldd_dev; - struct scatterlist *sg_req, *sg_resp; - u32 req_len, resp_len; - struct smp_req smp_cmd; - u32 opc; - struct inbound_queue_table *circularQ; - char *preq_dma_addr = NULL; - __le64 tmp_addr; - u32 i, length; - - memset(&smp_cmd, 0, sizeof(smp_cmd)); - /* - * DMA-map SMP request, response buffers - */ - sg_req = &task->smp_task.smp_req; - elem = dma_map_sg(pm8001_ha->dev, sg_req, 1, PCI_DMA_TODEVICE); - if (!elem) - return -ENOMEM; - req_len = sg_dma_len(sg_req); - - sg_resp = &task->smp_task.smp_resp; - elem = dma_map_sg(pm8001_ha->dev, sg_resp, 1, PCI_DMA_FROMDEVICE); - if (!elem) { - rc = -ENOMEM; - goto err_out; - } - resp_len = sg_dma_len(sg_resp); - /* must be in dwords */ - if ((req_len & 0x3) || (resp_len & 0x3)) { - rc = -EINVAL; - goto err_out_2; - } - - opc = OPC_INB_SMP_REQUEST; - circularQ = &pm8001_ha->inbnd_q_tbl[0]; - smp_cmd.tag = cpu_to_le32(ccb->ccb_tag); - - length = sg_req->length; - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("SMP Frame Length %d\n", sg_req->length)); - if (!(length - 8)) - pm8001_ha->smp_exp_mode = SMP_DIRECT; - else - pm8001_ha->smp_exp_mode = SMP_INDIRECT; - - /* DIRECT MODE support only in spcv/ve */ - pm8001_ha->smp_exp_mode = SMP_DIRECT; - - tmp_addr = cpu_to_le64((u64)sg_dma_address(&task->smp_task.smp_req)); - preq_dma_addr = (char *)phys_to_virt(tmp_addr); - - /* INDIRECT MODE command settings. Use DMA */ - if (pm8001_ha->smp_exp_mode == SMP_INDIRECT) { - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("SMP REQUEST INDIRECT MODE\n")); - /* for SPCv indirect mode. Place the top 4 bytes of - * SMP Request header here. */ - for (i = 0; i < 4; i++) - smp_cmd.smp_req16[i] = *(preq_dma_addr + i); - /* exclude top 4 bytes for SMP req header */ - smp_cmd.long_smp_req.long_req_addr = - cpu_to_le64((u64)sg_dma_address - (&task->smp_task.smp_req) - 4); - /* exclude 4 bytes for SMP req header and CRC */ - smp_cmd.long_smp_req.long_req_size = - cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_req)-8); - smp_cmd.long_smp_req.long_resp_addr = - cpu_to_le64((u64)sg_dma_address - (&task->smp_task.smp_resp)); - smp_cmd.long_smp_req.long_resp_size = - cpu_to_le32((u32)sg_dma_len - (&task->smp_task.smp_resp)-4); - } else { /* DIRECT MODE */ - smp_cmd.long_smp_req.long_req_addr = - cpu_to_le64((u64)sg_dma_address - (&task->smp_task.smp_req)); - smp_cmd.long_smp_req.long_req_size = - cpu_to_le32((u32)sg_dma_len(&task->smp_task.smp_req)-4); - smp_cmd.long_smp_req.long_resp_addr = - cpu_to_le64((u64)sg_dma_address - (&task->smp_task.smp_resp)); - smp_cmd.long_smp_req.long_resp_size = - cpu_to_le32 - ((u32)sg_dma_len(&task->smp_task.smp_resp)-4); - } - if (pm8001_ha->smp_exp_mode == SMP_DIRECT) { - PM8001_IO_DBG(pm8001_ha, - pm8001_printk("SMP REQUEST DIRECT MODE\n")); - for (i = 0; i < length; i++) - if (i < 16) { - smp_cmd.smp_req16[i] = *(preq_dma_addr+i); - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "Byte[%d]:%x (DMA data:%x)\n", - i, smp_cmd.smp_req16[i], - *(preq_dma_addr))); - } else { - smp_cmd.smp_req[i] = *(preq_dma_addr+i); - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "Byte[%d]:%x (DMA data:%x)\n", - i, smp_cmd.smp_req[i], - *(preq_dma_addr))); - } - } - - build_smp_cmd(pm8001_dev->device_id, smp_cmd.tag, - &smp_cmd, pm8001_ha->smp_exp_mode, length); - pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, (u32 *)&smp_cmd, 0); - return 0; - -err_out_2: - dma_unmap_sg(pm8001_ha->dev, &ccb->task->smp_task.smp_resp, 1, - PCI_DMA_FROMDEVICE); -err_out: - dma_unmap_sg(pm8001_ha->dev, &ccb->task->smp_task.smp_req, 1, - PCI_DMA_TODEVICE); - return rc; -} - -static int check_enc_sas_cmd(struct sas_task *task) -{ - if ((task->ssp_task.cdb[0] == READ_10) - || (task->ssp_task.cdb[0] == WRITE_10) - || (task->ssp_task.cdb[0] == WRITE_VERIFY)) - return 1; - else - return 0; -} - -static int check_enc_sat_cmd(struct sas_task *task) -{ - int ret = 0; - switch (task->ata_task.fis.command) { - case ATA_CMD_FPDMA_READ: - case ATA_CMD_READ_EXT: - case ATA_CMD_READ: - case ATA_CMD_FPDMA_WRITE: - case ATA_CMD_WRITE_EXT: - case ATA_CMD_WRITE: - case ATA_CMD_PIO_READ: - case ATA_CMD_PIO_READ_EXT: - case ATA_CMD_PIO_WRITE: - case ATA_CMD_PIO_WRITE_EXT: - ret = 1; - break; - default: - ret = 0; - break; - } - return ret; -} - -/** - * pm80xx_chip_ssp_io_req - send a SSP task to FW - * @pm8001_ha: our hba card information. - * @ccb: the ccb information this request used. - */ -static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, - struct pm8001_ccb_info *ccb) -{ - struct sas_task *task = ccb->task; - struct domain_device *dev = task->dev; - struct pm8001_device *pm8001_dev = dev->lldd_dev; - struct ssp_ini_io_start_req ssp_cmd; - u32 tag = ccb->ccb_tag; - int ret; - u64 phys_addr; - struct inbound_queue_table *circularQ; - static u32 inb; - static u32 outb; - u32 opc = OPC_INB_SSPINIIOSTART; - memset(&ssp_cmd, 0, sizeof(ssp_cmd)); - memcpy(ssp_cmd.ssp_iu.lun, task->ssp_task.LUN, 8); - /* data address domain added for spcv; set to 0 by host, - * used internally by controller - * 0 for SAS 1.1 and SAS 2.0 compatible TLR - */ - ssp_cmd.dad_dir_m_tlr = - cpu_to_le32(data_dir_flags[task->data_dir] << 8 | 0x0); - ssp_cmd.data_len = cpu_to_le32(task->total_xfer_len); - ssp_cmd.device_id = cpu_to_le32(pm8001_dev->device_id); - ssp_cmd.tag = cpu_to_le32(tag); - if (task->ssp_task.enable_first_burst) - ssp_cmd.ssp_iu.efb_prio_attr |= 0x80; - ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3); - ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7); - memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cdb, 16); - circularQ = &pm8001_ha->inbnd_q_tbl[0]; - - /* Check if encryption is set */ - if (pm8001_ha->chip->encrypt && - !(pm8001_ha->encrypt_info.status) && check_enc_sas_cmd(task)) { - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "Encryption enabled.Sending Encrypt SAS command 0x%x\n", - task->ssp_task.cdb[0])); - opc = OPC_INB_SSP_INI_DIF_ENC_IO; - /* enable encryption. 0 for SAS 1.1 and SAS 2.0 compatible TLR*/ - ssp_cmd.dad_dir_m_tlr = cpu_to_le32 - ((data_dir_flags[task->data_dir] << 8) | 0x20 | 0x0); - - /* fill in PRD (scatter/gather) table, if any */ - if (task->num_scatter > 1) { - pm8001_chip_make_sg(task->scatter, - ccb->n_elem, ccb->buf_prd); - phys_addr = ccb->ccb_dma_handle + - offsetof(struct pm8001_ccb_info, buf_prd[0]); - ssp_cmd.enc_addr_low = - cpu_to_le32(lower_32_bits(phys_addr)); - ssp_cmd.enc_addr_high = - cpu_to_le32(upper_32_bits(phys_addr)); - ssp_cmd.enc_esgl = cpu_to_le32(1<<31); - } else if (task->num_scatter == 1) { - u64 dma_addr = sg_dma_address(task->scatter); - ssp_cmd.enc_addr_low = - cpu_to_le32(lower_32_bits(dma_addr)); - ssp_cmd.enc_addr_high = - cpu_to_le32(upper_32_bits(dma_addr)); - ssp_cmd.enc_len = cpu_to_le32(task->total_xfer_len); - ssp_cmd.enc_esgl = 0; - } else if (task->num_scatter == 0) { - ssp_cmd.enc_addr_low = 0; - ssp_cmd.enc_addr_high = 0; - ssp_cmd.enc_len = cpu_to_le32(task->total_xfer_len); - ssp_cmd.enc_esgl = 0; - } - /* XTS mode. All other fields are 0 */ - ssp_cmd.key_cmode = 0x6 << 4; - /* set tweak values. Should be the start lba */ - ssp_cmd.twk_val0 = cpu_to_le32((task->ssp_task.cdb[2] << 24) | - (task->ssp_task.cdb[3] << 16) | - (task->ssp_task.cdb[4] << 8) | - (task->ssp_task.cdb[5])); - } else { - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "Sending Normal SAS command 0x%x inb q %x\n", - task->ssp_task.cdb[0], inb)); - /* fill in PRD (scatter/gather) table, if any */ - if (task->num_scatter > 1) { - pm8001_chip_make_sg(task->scatter, ccb->n_elem, - ccb->buf_prd); - phys_addr = ccb->ccb_dma_handle + - offsetof(struct pm8001_ccb_info, buf_prd[0]); - ssp_cmd.addr_low = - cpu_to_le32(lower_32_bits(phys_addr)); - ssp_cmd.addr_high = - cpu_to_le32(upper_32_bits(phys_addr)); - ssp_cmd.esgl = cpu_to_le32(1<<31); - } else if (task->num_scatter == 1) { - u64 dma_addr = sg_dma_address(task->scatter); - ssp_cmd.addr_low = cpu_to_le32(lower_32_bits(dma_addr)); - ssp_cmd.addr_high = - cpu_to_le32(upper_32_bits(dma_addr)); - ssp_cmd.len = cpu_to_le32(task->total_xfer_len); - ssp_cmd.esgl = 0; - } else if (task->num_scatter == 0) { - ssp_cmd.addr_low = 0; - ssp_cmd.addr_high = 0; - ssp_cmd.len = cpu_to_le32(task->total_xfer_len); - ssp_cmd.esgl = 0; - } - } - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &ssp_cmd, outb++); - - /* rotate the outb queue */ - outb = outb%PM8001_MAX_SPCV_OUTB_NUM; - - return ret; -} - -static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, - struct pm8001_ccb_info *ccb) -{ - struct sas_task *task = ccb->task; - struct domain_device *dev = task->dev; - struct pm8001_device *pm8001_ha_dev = dev->lldd_dev; - u32 tag = ccb->ccb_tag; - int ret; - static u32 inb; - static u32 outb; - struct sata_start_req sata_cmd; - u32 hdr_tag, ncg_tag = 0; - u64 phys_addr; - u32 ATAP = 0x0; - u32 dir; - struct inbound_queue_table *circularQ; - unsigned long flags; - u32 opc = OPC_INB_SATA_HOST_OPSTART; - memset(&sata_cmd, 0, sizeof(sata_cmd)); - circularQ = &pm8001_ha->inbnd_q_tbl[0]; - - if (task->data_dir == PCI_DMA_NONE) { - ATAP = 0x04; /* no data*/ - PM8001_IO_DBG(pm8001_ha, pm8001_printk("no data\n")); - } else if (likely(!task->ata_task.device_control_reg_update)) { - if (task->ata_task.dma_xfer) { - ATAP = 0x06; /* DMA */ - PM8001_IO_DBG(pm8001_ha, pm8001_printk("DMA\n")); - } else { - ATAP = 0x05; /* PIO*/ - PM8001_IO_DBG(pm8001_ha, pm8001_printk("PIO\n")); - } - if (task->ata_task.use_ncq && - dev->sata_dev.command_set != ATAPI_COMMAND_SET) { - ATAP = 0x07; /* FPDMA */ - PM8001_IO_DBG(pm8001_ha, pm8001_printk("FPDMA\n")); - } - } - if (task->ata_task.use_ncq && pm8001_get_ncq_tag(task, &hdr_tag)) { - task->ata_task.fis.sector_count |= (u8) (hdr_tag << 3); - ncg_tag = hdr_tag; - } - dir = data_dir_flags[task->data_dir] << 8; - sata_cmd.tag = cpu_to_le32(tag); - sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id); - sata_cmd.data_len = cpu_to_le32(task->total_xfer_len); - - sata_cmd.sata_fis = task->ata_task.fis; - if (likely(!task->ata_task.device_control_reg_update)) - sata_cmd.sata_fis.flags |= 0x80;/* C=1: update ATA cmd reg */ - sata_cmd.sata_fis.flags &= 0xF0;/* PM_PORT field shall be 0 */ - - /* Check if encryption is set */ - if (pm8001_ha->chip->encrypt && - !(pm8001_ha->encrypt_info.status) && check_enc_sat_cmd(task)) { - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "Encryption enabled.Sending Encrypt SATA cmd 0x%x\n", - sata_cmd.sata_fis.command)); - opc = OPC_INB_SATA_DIF_ENC_IO; - - /* set encryption bit */ - sata_cmd.ncqtag_atap_dir_m_dad = - cpu_to_le32(((ncg_tag & 0xff)<<16)| - ((ATAP & 0x3f) << 10) | 0x20 | dir); - /* dad (bit 0-1) is 0 */ - /* fill in PRD (scatter/gather) table, if any */ - if (task->num_scatter > 1) { - pm8001_chip_make_sg(task->scatter, - ccb->n_elem, ccb->buf_prd); - phys_addr = ccb->ccb_dma_handle + - offsetof(struct pm8001_ccb_info, buf_prd[0]); - sata_cmd.enc_addr_low = lower_32_bits(phys_addr); - sata_cmd.enc_addr_high = upper_32_bits(phys_addr); - sata_cmd.enc_esgl = cpu_to_le32(1 << 31); - } else if (task->num_scatter == 1) { - u64 dma_addr = sg_dma_address(task->scatter); - sata_cmd.enc_addr_low = lower_32_bits(dma_addr); - sata_cmd.enc_addr_high = upper_32_bits(dma_addr); - sata_cmd.enc_len = cpu_to_le32(task->total_xfer_len); - sata_cmd.enc_esgl = 0; - } else if (task->num_scatter == 0) { - sata_cmd.enc_addr_low = 0; - sata_cmd.enc_addr_high = 0; - sata_cmd.enc_len = cpu_to_le32(task->total_xfer_len); - sata_cmd.enc_esgl = 0; - } - /* XTS mode. All other fields are 0 */ - sata_cmd.key_index_mode = 0x6 << 4; - /* set tweak values. Should be the start lba */ - sata_cmd.twk_val0 = - cpu_to_le32((sata_cmd.sata_fis.lbal_exp << 24) | - (sata_cmd.sata_fis.lbah << 16) | - (sata_cmd.sata_fis.lbam << 8) | - (sata_cmd.sata_fis.lbal)); - sata_cmd.twk_val1 = - cpu_to_le32((sata_cmd.sata_fis.lbah_exp << 8) | - (sata_cmd.sata_fis.lbam_exp)); - } else { - PM8001_IO_DBG(pm8001_ha, pm8001_printk( - "Sending Normal SATA command 0x%x inb %x\n", - sata_cmd.sata_fis.command, inb)); - /* dad (bit 0-1) is 0 */ - sata_cmd.ncqtag_atap_dir_m_dad = - cpu_to_le32(((ncg_tag & 0xff)<<16) | - ((ATAP & 0x3f) << 10) | dir); - - /* fill in PRD (scatter/gather) table, if any */ - if (task->num_scatter > 1) { - pm8001_chip_make_sg(task->scatter, - ccb->n_elem, ccb->buf_prd); - phys_addr = ccb->ccb_dma_handle + - offsetof(struct pm8001_ccb_info, buf_prd[0]); - sata_cmd.addr_low = lower_32_bits(phys_addr); - sata_cmd.addr_high = upper_32_bits(phys_addr); - sata_cmd.esgl = cpu_to_le32(1 << 31); - } else if (task->num_scatter == 1) { - u64 dma_addr = sg_dma_address(task->scatter); - sata_cmd.addr_low = lower_32_bits(dma_addr); - sata_cmd.addr_high = upper_32_bits(dma_addr); - sata_cmd.len = cpu_to_le32(task->total_xfer_len); - sata_cmd.esgl = 0; - } else if (task->num_scatter == 0) { - sata_cmd.addr_low = 0; - sata_cmd.addr_high = 0; - sata_cmd.len = cpu_to_le32(task->total_xfer_len); - sata_cmd.esgl = 0; - } - /* scsi cdb */ - sata_cmd.atapi_scsi_cdb[0] = - cpu_to_le32(((task->ata_task.atapi_packet[0]) | - (task->ata_task.atapi_packet[1] << 8) | - (task->ata_task.atapi_packet[2] << 16) | - (task->ata_task.atapi_packet[3] << 24))); - sata_cmd.atapi_scsi_cdb[1] = - cpu_to_le32(((task->ata_task.atapi_packet[4]) | - (task->ata_task.atapi_packet[5] << 8) | - (task->ata_task.atapi_packet[6] << 16) | - (task->ata_task.atapi_packet[7] << 24))); - sata_cmd.atapi_scsi_cdb[2] = - cpu_to_le32(((task->ata_task.atapi_packet[8]) | - (task->ata_task.atapi_packet[9] << 8) | - (task->ata_task.atapi_packet[10] << 16) | - (task->ata_task.atapi_packet[11] << 24))); - sata_cmd.atapi_scsi_cdb[3] = - cpu_to_le32(((task->ata_task.atapi_packet[12]) | - (task->ata_task.atapi_packet[13] << 8) | - (task->ata_task.atapi_packet[14] << 16) | - (task->ata_task.atapi_packet[15] << 24))); - } - - /* Check for read log for failed drive and return */ - if (sata_cmd.sata_fis.command == 0x2f) { - if (pm8001_ha_dev && ((pm8001_ha_dev->id & NCQ_READ_LOG_FLAG) || - (pm8001_ha_dev->id & NCQ_ABORT_ALL_FLAG) || - (pm8001_ha_dev->id & NCQ_2ND_RLE_FLAG))) { - struct task_status_struct *ts; - - pm8001_ha_dev->id &= 0xDFFFFFFF; - ts = &task->task_status; - - spin_lock_irqsave(&task->task_state_lock, flags); - ts->resp = SAS_TASK_COMPLETE; - ts->stat = SAM_STAT_GOOD; - task->task_state_flags &= ~SAS_TASK_STATE_PENDING; - task->task_state_flags &= ~SAS_TASK_AT_INITIATOR; - task->task_state_flags |= SAS_TASK_STATE_DONE; - if (unlikely((task->task_state_flags & - SAS_TASK_STATE_ABORTED))) { - spin_unlock_irqrestore(&task->task_state_lock, - flags); - PM8001_FAIL_DBG(pm8001_ha, - pm8001_printk("task 0x%p resp 0x%x " - " stat 0x%x but aborted by upper layer " - "\n", task, ts->resp, ts->stat)); - pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); - return 0; - } else if (task->uldd_task) { - spin_unlock_irqrestore(&task->task_state_lock, - flags); - pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); - mb();/* ditto */ - spin_unlock_irq(&pm8001_ha->lock); - task->task_done(task); - spin_lock_irq(&pm8001_ha->lock); - return 0; - } else if (!task->uldd_task) { - spin_unlock_irqrestore(&task->task_state_lock, - flags); - pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); - mb();/*ditto*/ - spin_unlock_irq(&pm8001_ha->lock); - task->task_done(task); - spin_lock_irq(&pm8001_ha->lock); - return 0; - } - } - } - - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, - &sata_cmd, outb++); - - /* rotate the outb queue */ - outb = outb%PM8001_MAX_SPCV_OUTB_NUM; - return ret; -} - -/** - * pm80xx_chip_phy_start_req - start phy via PHY_START COMMAND - * @pm8001_ha: our hba card information. - * @num: the inbound queue number - * @phy_id: the phy id which we wanted to start up. - */ -static int -pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) -{ - struct phy_start_req payload; - struct inbound_queue_table *circularQ; - int ret; - u32 tag = 0x01; - u32 opcode = OPC_INB_PHYSTART; - circularQ = &pm8001_ha->inbnd_q_tbl[0]; - memset(&payload, 0, sizeof(payload)); - payload.tag = cpu_to_le32(tag); - - PM8001_INIT_DBG(pm8001_ha, - pm8001_printk("PHY START REQ for phy_id %d\n", phy_id)); - /* - ** [0:7] PHY Identifier - ** [8:11] link rate 1.5G, 3G, 6G - ** [12:13] link mode 01b SAS mode; 10b SATA mode; 11b Auto mode - ** [14] 0b disable spin up hold; 1b enable spin up hold - ** [15] ob no change in current PHY analig setup 1b enable using SPAST - */ - payload.ase_sh_lm_slr_phyid = cpu_to_le32(SPINHOLD_DISABLE | - LINKMODE_AUTO | LINKRATE_15 | - LINKRATE_30 | LINKRATE_60 | phy_id); - /* SSC Disable and SAS Analog ST configuration */ - /** - payload.ase_sh_lm_slr_phyid = - cpu_to_le32(SSC_DISABLE_30 | SAS_ASE | SPINHOLD_DISABLE | - LINKMODE_AUTO | LINKRATE_15 | LINKRATE_30 | LINKRATE_60 | - phy_id); - Have to add "SAS PHY Analog Setup SPASTI 1 Byte" Based on need - **/ - - payload.sas_identify.dev_type = SAS_END_DEVICE; - payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL; - memcpy(payload.sas_identify.sas_addr, - pm8001_ha->sas_addr, SAS_ADDR_SIZE); - payload.sas_identify.phy_id = phy_id; - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload, 0); - return ret; -} - -/** - * pm8001_chip_phy_stop_req - start phy via PHY_STOP COMMAND - * @pm8001_ha: our hba card information. - * @num: the inbound queue number - * @phy_id: the phy id which we wanted to start up. - */ -static int pm80xx_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha, - u8 phy_id) -{ - struct phy_stop_req payload; - struct inbound_queue_table *circularQ; - int ret; - u32 tag = 0x01; - u32 opcode = OPC_INB_PHYSTOP; - circularQ = &pm8001_ha->inbnd_q_tbl[0]; - memset(&payload, 0, sizeof(payload)); - payload.tag = cpu_to_le32(tag); - payload.phy_id = cpu_to_le32(phy_id); - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opcode, &payload, 0); - return ret; -} - -/** - * see comments on pm8001_mpi_reg_resp. - */ -static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha, - struct pm8001_device *pm8001_dev, u32 flag) -{ - struct reg_dev_req payload; - u32 opc; - u32 stp_sspsmp_sata = 0x4; - struct inbound_queue_table *circularQ; - u32 linkrate, phy_id; - int rc, tag = 0xdeadbeef; - struct pm8001_ccb_info *ccb; - u8 retryFlag = 0x1; - u16 firstBurstSize = 0; - u16 ITNT = 2000; - struct domain_device *dev = pm8001_dev->sas_device; - struct domain_device *parent_dev = dev->parent; - circularQ = &pm8001_ha->inbnd_q_tbl[0]; - - memset(&payload, 0, sizeof(payload)); - rc = pm8001_tag_alloc(pm8001_ha, &tag); - if (rc) - return rc; - ccb = &pm8001_ha->ccb_info[tag]; - ccb->device = pm8001_dev; - ccb->ccb_tag = tag; - payload.tag = cpu_to_le32(tag); - - if (flag == 1) { - stp_sspsmp_sata = 0x02; /*direct attached sata */ - } else { - if (pm8001_dev->dev_type == SAS_SATA_DEV) - stp_sspsmp_sata = 0x00; /* stp*/ - else if (pm8001_dev->dev_type == SAS_END_DEVICE || - pm8001_dev->dev_type == SAS_EDGE_EXPANDER_DEVICE || - pm8001_dev->dev_type == SAS_FANOUT_EXPANDER_DEVICE) - stp_sspsmp_sata = 0x01; /*ssp or smp*/ - } - if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) - phy_id = parent_dev->ex_dev.ex_phy->phy_id; - else - phy_id = pm8001_dev->attached_phy; - - opc = OPC_INB_REG_DEV; - - linkrate = (pm8001_dev->sas_device->linkrate < dev->port->linkrate) ? - pm8001_dev->sas_device->linkrate : dev->port->linkrate; - - payload.phyid_portid = - cpu_to_le32(((pm8001_dev->sas_device->port->id) & 0xFF) | - ((phy_id & 0xFF) << 8)); - - payload.dtype_dlr_mcn_ir_retry = cpu_to_le32((retryFlag & 0x01) | - ((linkrate & 0x0F) << 24) | - ((stp_sspsmp_sata & 0x03) << 28)); - payload.firstburstsize_ITNexustimeout = - cpu_to_le32(ITNT | (firstBurstSize * 0x10000)); - - memcpy(payload.sas_addr, pm8001_dev->sas_device->sas_addr, - SAS_ADDR_SIZE); - - rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); - - return rc; -} - -/** - * pm80xx_chip_phy_ctl_req - support the local phy operation - * @pm8001_ha: our hba card information. - * @num: the inbound queue number - * @phy_id: the phy id which we wanted to operate - * @phy_op: - */ -static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha, - u32 phyId, u32 phy_op) -{ - struct local_phy_ctl_req payload; - struct inbound_queue_table *circularQ; - int ret; - u32 opc = OPC_INB_LOCAL_PHY_CONTROL; - memset(&payload, 0, sizeof(payload)); - circularQ = &pm8001_ha->inbnd_q_tbl[0]; - payload.tag = cpu_to_le32(1); - payload.phyop_phyid = - cpu_to_le32(((phy_op & 0xFF) << 8) | (phyId & 0xFF)); - ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0); - return ret; -} - -static u32 pm80xx_chip_is_our_interupt(struct pm8001_hba_info *pm8001_ha) -{ - u32 value; -#ifdef PM8001_USE_MSIX - return 1; -#endif - value = pm8001_cr32(pm8001_ha, 0, MSGU_ODR); - if (value) - return 1; - return 0; - -} - -/** - * pm8001_chip_isr - PM8001 isr handler. - * @pm8001_ha: our hba card information. - * @irq: irq number. - * @stat: stat. - */ -static irqreturn_t -pm80xx_chip_isr(struct pm8001_hba_info *pm8001_ha, u8 vec) -{ - pm80xx_chip_interrupt_disable(pm8001_ha, vec); - process_oq(pm8001_ha, vec); - pm80xx_chip_interrupt_enable(pm8001_ha, vec); - return IRQ_HANDLED; -} - -const struct pm8001_dispatch pm8001_80xx_dispatch = { - .name = "pmc80xx", - .chip_init = pm80xx_chip_init, - .chip_soft_rst = pm80xx_chip_soft_rst, - .chip_rst = pm80xx_hw_chip_rst, - .chip_iounmap = pm8001_chip_iounmap, - .isr = pm80xx_chip_isr, - .is_our_interupt = pm80xx_chip_is_our_interupt, - .isr_process_oq = process_oq, - .interrupt_enable = pm80xx_chip_interrupt_enable, - .interrupt_disable = pm80xx_chip_interrupt_disable, - .make_prd = pm8001_chip_make_sg, - .smp_req = pm80xx_chip_smp_req, - .ssp_io_req = pm80xx_chip_ssp_io_req, - .sata_req = pm80xx_chip_sata_req, - .phy_start_req = pm80xx_chip_phy_start_req, - .phy_stop_req = pm80xx_chip_phy_stop_req, - .reg_dev_req = pm80xx_chip_reg_dev_req, - .dereg_dev_req = pm8001_chip_dereg_dev_req, - .phy_ctl_req = pm80xx_chip_phy_ctl_req, - .task_abort = pm8001_chip_abort_task, - .ssp_tm_req = pm8001_chip_ssp_tm_req, - .get_nvmd_req = pm8001_chip_get_nvmd_req, - .set_nvmd_req = pm8001_chip_set_nvmd_req, - .fw_flash_update_req = pm8001_chip_fw_flash_update_req, - .set_dev_state_req = pm8001_chip_set_dev_state_req, -}; diff --git a/trunk/drivers/scsi/pm8001/pm80xx_hwi.h b/trunk/drivers/scsi/pm8001/pm80xx_hwi.h deleted file mode 100644 index 2b760ba75d7b..000000000000 --- a/trunk/drivers/scsi/pm8001/pm80xx_hwi.h +++ /dev/null @@ -1,1523 +0,0 @@ -/* - * PMC-Sierra SPCv/ve 8088/8089 SAS/SATA based host adapters driver - * - * Copyright (c) 2008-2009 USI Co., Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - */ - -#ifndef _PMC8001_REG_H_ -#define _PMC8001_REG_H_ - -#include -#include - -/* for Request Opcode of IOMB */ -#define OPC_INB_ECHO 1 /* 0x000 */ -#define OPC_INB_PHYSTART 4 /* 0x004 */ -#define OPC_INB_PHYSTOP 5 /* 0x005 */ -#define OPC_INB_SSPINIIOSTART 6 /* 0x006 */ -#define OPC_INB_SSPINITMSTART 7 /* 0x007 */ -/* 0x8 RESV IN SPCv */ -#define OPC_INB_RSVD 8 /* 0x008 */ -#define OPC_INB_DEV_HANDLE_ACCEPT 9 /* 0x009 */ -#define OPC_INB_SSPTGTIOSTART 10 /* 0x00A */ -#define OPC_INB_SSPTGTRSPSTART 11 /* 0x00B */ -/* 0xC, 0xD, 0xE removed in SPCv */ -#define OPC_INB_SSP_ABORT 15 /* 0x00F */ -#define OPC_INB_DEREG_DEV_HANDLE 16 /* 0x010 */ -#define OPC_INB_GET_DEV_HANDLE 17 /* 0x011 */ -#define OPC_INB_SMP_REQUEST 18 /* 0x012 */ -/* 0x13 SMP_RESPONSE is removed in SPCv */ -#define OPC_INB_SMP_ABORT 20 /* 0x014 */ -/* 0x16 RESV IN SPCv */ -#define OPC_INB_RSVD1 22 /* 0x016 */ -#define OPC_INB_SATA_HOST_OPSTART 23 /* 0x017 */ -#define OPC_INB_SATA_ABORT 24 /* 0x018 */ -#define OPC_INB_LOCAL_PHY_CONTROL 25 /* 0x019 */ -/* 0x1A RESV IN SPCv */ -#define OPC_INB_RSVD2 26 /* 0x01A */ -#define OPC_INB_FW_FLASH_UPDATE 32 /* 0x020 */ -#define OPC_INB_GPIO 34 /* 0x022 */ -#define OPC_INB_SAS_DIAG_MODE_START_END 35 /* 0x023 */ -#define OPC_INB_SAS_DIAG_EXECUTE 36 /* 0x024 */ -/* 0x25 RESV IN SPCv */ -#define OPC_INB_RSVD3 37 /* 0x025 */ -#define OPC_INB_GET_TIME_STAMP 38 /* 0x026 */ -#define OPC_INB_PORT_CONTROL 39 /* 0x027 */ -#define OPC_INB_GET_NVMD_DATA 40 /* 0x028 */ -#define OPC_INB_SET_NVMD_DATA 41 /* 0x029 */ -#define OPC_INB_SET_DEVICE_STATE 42 /* 0x02A */ -#define OPC_INB_GET_DEVICE_STATE 43 /* 0x02B */ -#define OPC_INB_SET_DEV_INFO 44 /* 0x02C */ -/* 0x2D RESV IN SPCv */ -#define OPC_INB_RSVD4 45 /* 0x02D */ -#define OPC_INB_SGPIO_REGISTER 46 /* 0x02E */ -#define OPC_INB_PCIE_DIAG_EXEC 47 /* 0x02F */ -#define OPC_INB_SET_CONTROLLER_CONFIG 48 /* 0x030 */ -#define OPC_INB_GET_CONTROLLER_CONFIG 49 /* 0x031 */ -#define OPC_INB_REG_DEV 50 /* 0x032 */ -#define OPC_INB_SAS_HW_EVENT_ACK 51 /* 0x033 */ -#define OPC_INB_GET_DEVICE_INFO 52 /* 0x034 */ -#define OPC_INB_GET_PHY_PROFILE 53 /* 0x035 */ -#define OPC_INB_FLASH_OP_EXT 54 /* 0x036 */ -#define OPC_INB_SET_PHY_PROFILE 55 /* 0x037 */ -#define OPC_INB_KEK_MANAGEMENT 256 /* 0x100 */ -#define OPC_INB_DEK_MANAGEMENT 257 /* 0x101 */ -#define OPC_INB_SSP_INI_DIF_ENC_IO 258 /* 0x102 */ -#define OPC_INB_SATA_DIF_ENC_IO 259 /* 0x103 */ - -/* for Response Opcode of IOMB */ -#define OPC_OUB_ECHO 1 /* 0x001 */ -#define OPC_OUB_RSVD 4 /* 0x004 */ -#define OPC_OUB_SSP_COMP 5 /* 0x005 */ -#define OPC_OUB_SMP_COMP 6 /* 0x006 */ -#define OPC_OUB_LOCAL_PHY_CNTRL 7 /* 0x007 */ -#define OPC_OUB_RSVD1 10 /* 0x00A */ -#define OPC_OUB_DEREG_DEV 11 /* 0x00B */ -#define OPC_OUB_GET_DEV_HANDLE 12 /* 0x00C */ -#define OPC_OUB_SATA_COMP 13 /* 0x00D */ -#define OPC_OUB_SATA_EVENT 14 /* 0x00E */ -#define OPC_OUB_SSP_EVENT 15 /* 0x00F */ -#define OPC_OUB_RSVD2 16 /* 0x010 */ -/* 0x11 - SMP_RECEIVED Notification removed in SPCv*/ -#define OPC_OUB_SSP_RECV_EVENT 18 /* 0x012 */ -#define OPC_OUB_RSVD3 19 /* 0x013 */ -#define OPC_OUB_FW_FLASH_UPDATE 20 /* 0x014 */ -#define OPC_OUB_GPIO_RESPONSE 22 /* 0x016 */ -#define OPC_OUB_GPIO_EVENT 23 /* 0x017 */ -#define OPC_OUB_GENERAL_EVENT 24 /* 0x018 */ -#define OPC_OUB_SSP_ABORT_RSP 26 /* 0x01A */ -#define OPC_OUB_SATA_ABORT_RSP 27 /* 0x01B */ -#define OPC_OUB_SAS_DIAG_MODE_START_END 28 /* 0x01C */ -#define OPC_OUB_SAS_DIAG_EXECUTE 29 /* 0x01D */ -#define OPC_OUB_GET_TIME_STAMP 30 /* 0x01E */ -#define OPC_OUB_RSVD4 31 /* 0x01F */ -#define OPC_OUB_PORT_CONTROL 32 /* 0x020 */ -#define OPC_OUB_SKIP_ENTRY 33 /* 0x021 */ -#define OPC_OUB_SMP_ABORT_RSP 34 /* 0x022 */ -#define OPC_OUB_GET_NVMD_DATA 35 /* 0x023 */ -#define OPC_OUB_SET_NVMD_DATA 36 /* 0x024 */ -#define OPC_OUB_DEVICE_HANDLE_REMOVAL 37 /* 0x025 */ -#define OPC_OUB_SET_DEVICE_STATE 38 /* 0x026 */ -#define OPC_OUB_GET_DEVICE_STATE 39 /* 0x027 */ -#define OPC_OUB_SET_DEV_INFO 40 /* 0x028 */ -#define OPC_OUB_RSVD5 41 /* 0x029 */ -#define OPC_OUB_HW_EVENT 1792 /* 0x700 */ -#define OPC_OUB_DEV_HANDLE_ARRIV 1824 /* 0x720 */ -#define OPC_OUB_THERM_HW_EVENT 1840 /* 0x730 */ -#define OPC_OUB_SGPIO_RESP 2094 /* 0x82E */ -#define OPC_OUB_PCIE_DIAG_EXECUTE 2095 /* 0x82F */ -#define OPC_OUB_DEV_REGIST 2098 /* 0x832 */ -#define OPC_OUB_SAS_HW_EVENT_ACK 2099 /* 0x833 */ -#define OPC_OUB_GET_DEVICE_INFO 2100 /* 0x834 */ -/* spcv specific commands */ -#define OPC_OUB_PHY_START_RESP 2052 /* 0x804 */ -#define OPC_OUB_PHY_STOP_RESP 2053 /* 0x805 */ -#define OPC_OUB_SET_CONTROLLER_CONFIG 2096 /* 0x830 */ -#define OPC_OUB_GET_CONTROLLER_CONFIG 2097 /* 0x831 */ -#define OPC_OUB_GET_PHY_PROFILE 2101 /* 0x835 */ -#define OPC_OUB_FLASH_OP_EXT 2102 /* 0x836 */ -#define OPC_OUB_SET_PHY_PROFILE 2103 /* 0x837 */ -#define OPC_OUB_KEK_MANAGEMENT_RESP 2304 /* 0x900 */ -#define OPC_OUB_DEK_MANAGEMENT_RESP 2305 /* 0x901 */ -#define OPC_OUB_SSP_COALESCED_COMP_RESP 2306 /* 0x902 */ - -/* for phy start*/ -#define SSC_DISABLE_15 (0x01 << 16) -#define SSC_DISABLE_30 (0x02 << 16) -#define SSC_DISABLE_60 (0x04 << 16) -#define SAS_ASE (0x01 << 15) -#define SPINHOLD_DISABLE (0x00 << 14) -#define SPINHOLD_ENABLE (0x01 << 14) -#define LINKMODE_SAS (0x01 << 12) -#define LINKMODE_DSATA (0x02 << 12) -#define LINKMODE_AUTO (0x03 << 12) -#define LINKRATE_15 (0x01 << 8) -#define LINKRATE_30 (0x02 << 8) -#define LINKRATE_60 (0x06 << 8) - -/* Thermal related */ -#define THERMAL_ENABLE 0x1 -#define THERMAL_LOG_ENABLE 0x1 -#define THERMAL_OP_CODE 0x6 -#define LTEMPHIL 70 -#define RTEMPHIL 100 - -/* Encryption info */ -#define SCRATCH_PAD3_ENC_DISABLED 0x00000000 -#define SCRATCH_PAD3_ENC_DIS_ERR 0x00000001 -#define SCRATCH_PAD3_ENC_ENA_ERR 0x00000002 -#define SCRATCH_PAD3_ENC_READY 0x00000003 -#define SCRATCH_PAD3_ENC_MASK SCRATCH_PAD3_ENC_READY - -#define SCRATCH_PAD3_XTS_ENABLED (1 << 14) -#define SCRATCH_PAD3_SMA_ENABLED (1 << 4) -#define SCRATCH_PAD3_SMB_ENABLED (1 << 5) -#define SCRATCH_PAD3_SMF_ENABLED 0 -#define SCRATCH_PAD3_SM_MASK 0x000000F0 -#define SCRATCH_PAD3_ERR_CODE 0x00FF0000 - -#define SEC_MODE_SMF 0x0 -#define SEC_MODE_SMA 0x100 -#define SEC_MODE_SMB 0x200 -#define CIPHER_MODE_ECB 0x00000001 -#define CIPHER_MODE_XTS 0x00000002 -#define KEK_MGMT_SUBOP_KEYCARDUPDATE 0x4 - -/* SAS protocol timer configuration page */ -#define SAS_PROTOCOL_TIMER_CONFIG_PAGE 0x04 -#define STP_MCT_TMO 32 -#define SSP_MCT_TMO 32 -#define SAS_MAX_OPEN_TIME 5 -#define SMP_MAX_CONN_TIMER 0xFF -#define STP_FRM_TIMER 0 -#define STP_IDLE_TIME 5 /* 5 us; controller default */ -#define SAS_MFD 0 -#define SAS_OPNRJT_RTRY_INTVL 2 -#define SAS_DOPNRJT_RTRY_TMO 128 -#define SAS_COPNRJT_RTRY_TMO 128 - -/* - Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second. - Assuming a bigger value 3 second, 3000000/128 = 23437.5 where 128 - is DOPNRJT_RTRY_TMO -*/ -#define SAS_DOPNRJT_RTRY_THR 23438 -#define SAS_COPNRJT_RTRY_THR 23438 -#define SAS_MAX_AIP 0x200000 -#define IT_NEXUS_TIMEOUT 0x7D0 -#define PORT_RECOVERY_TIMEOUT ((IT_NEXUS_TIMEOUT/100) + 30) - -struct mpi_msg_hdr { - __le32 header; /* Bits [11:0] - Message operation code */ - /* Bits [15:12] - Message Category */ - /* Bits [21:16] - Outboundqueue ID for the - operation completion message */ - /* Bits [23:22] - Reserved */ - /* Bits [28:24] - Buffer Count, indicates how - many buffer are allocated for the massage */ - /* Bits [30:29] - Reserved */ - /* Bits [31] - Message Valid bit */ -} __attribute__((packed, aligned(4))); - -/* - * brief the data structure of PHY Start Command - * use to describe enable the phy (128 bytes) - */ -struct phy_start_req { - __le32 tag; - __le32 ase_sh_lm_slr_phyid; - struct sas_identify_frame sas_identify; /* 28 Bytes */ - __le32 spasti; - u32 reserved[21]; -} __attribute__((packed, aligned(4))); - -/* - * brief the data structure of PHY Start Command - * use to disable the phy (128 bytes) - */ -struct phy_stop_req { - __le32 tag; - __le32 phy_id; - u32 reserved[29]; -} __attribute__((packed, aligned(4))); - -/* set device bits fis - device to host */ -struct set_dev_bits_fis { - u8 fis_type; /* 0xA1*/ - u8 n_i_pmport; - /* b7 : n Bit. Notification bit. If set device needs attention. */ - /* b6 : i Bit. Interrupt Bit */ - /* b5-b4: reserved2 */ - /* b3-b0: PM Port */ - u8 status; - u8 error; - u32 _r_a; -} __attribute__ ((packed)); -/* PIO setup FIS - device to host */ -struct pio_setup_fis { - u8 fis_type; /* 0x5f */ - u8 i_d_pmPort; - /* b7 : reserved */ - /* b6 : i bit. Interrupt bit */ - /* b5 : d bit. data transfer direction. set to 1 for device to host - xfer */ - /* b4 : reserved */ - /* b3-b0: PM Port */ - u8 status; - u8 error; - u8 lbal; - u8 lbam; - u8 lbah; - u8 device; - u8 lbal_exp; - u8 lbam_exp; - u8 lbah_exp; - u8 _r_a; - u8 sector_count; - u8 sector_count_exp; - u8 _r_b; - u8 e_status; - u8 _r_c[2]; - u8 transfer_count; -} __attribute__ ((packed)); - -/* - * brief the data structure of SATA Completion Response - * use to describe the sata task response (64 bytes) - */ -struct sata_completion_resp { - __le32 tag; - __le32 status; - __le32 param; - u32 sata_resp[12]; -} __attribute__((packed, aligned(4))); - -/* - * brief the data structure of SAS HW Event Notification - * use to alert the host about the hardware event(64 bytes) - */ -/* updated outbound struct for spcv */ - -struct hw_event_resp { - __le32 lr_status_evt_portid; - __le32 evt_param; - __le32 phyid_npip_portstate; - struct sas_identify_frame sas_identify; - struct dev_to_host_fis sata_fis; -} __attribute__((packed, aligned(4))); - -/* - * brief the data structure for thermal event notification - */ - -struct thermal_hw_event { - __le32 thermal_event; - __le32 rht_lht; -} __attribute__((packed, aligned(4))); - -/* - * brief the data structure of REGISTER DEVICE Command - * use to describe MPI REGISTER DEVICE Command (64 bytes) - */ - -struct reg_dev_req { - __le32 tag; - __le32 phyid_portid; - __le32 dtype_dlr_mcn_ir_retry; - __le32 firstburstsize_ITNexustimeout; - u8 sas_addr[SAS_ADDR_SIZE]; - __le32 upper_device_id; - u32 reserved[24]; -} __attribute__((packed, aligned(4))); - -/* - * brief the data structure of DEREGISTER DEVICE Command - * use to request spc to remove all internal resources associated - * with the device id (64 bytes) - */ - -struct dereg_dev_req { - __le32 tag; - __le32 device_id; - u32 reserved[29]; -} __attribute__((packed, aligned(4))); - -/* - * brief the data structure of DEVICE_REGISTRATION Response - * use to notify the completion of the device registration (64 bytes) - */ -struct dev_reg_resp { - __le32 tag; - __le32 status; - __le32 device_id; - u32 reserved[12]; -} __attribute__((packed, aligned(4))); - -/* - * brief the data structure of Local PHY Control Command - * use to issue PHY CONTROL to local phy (64 bytes) - */ -struct local_phy_ctl_req { - __le32 tag; - __le32 phyop_phyid; - u32 reserved1[29]; -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure of Local Phy Control Response - * use to describe MPI Local Phy Control Response (64 bytes) - */ - struct local_phy_ctl_resp { - __le32 tag; - __le32 phyop_phyid; - __le32 status; - u32 reserved[12]; -} __attribute__((packed, aligned(4))); - -#define OP_BITS 0x0000FF00 -#define ID_BITS 0x000000FF - -/* - * brief the data structure of PORT Control Command - * use to control port properties (64 bytes) - */ - -struct port_ctl_req { - __le32 tag; - __le32 portop_portid; - __le32 param0; - __le32 param1; - u32 reserved1[27]; -} __attribute__((packed, aligned(4))); - -/* - * brief the data structure of HW Event Ack Command - * use to acknowledge receive HW event (64 bytes) - */ -struct hw_event_ack_req { - __le32 tag; - __le32 phyid_sea_portid; - __le32 param0; - __le32 param1; - u32 reserved1[27]; -} __attribute__((packed, aligned(4))); - -/* - * brief the data structure of PHY_START Response Command - * indicates the completion of PHY_START command (64 bytes) - */ -struct phy_start_resp { - __le32 tag; - __le32 status; - __le32 phyid; - u32 reserved[12]; -} __attribute__((packed, aligned(4))); - -/* - * brief the data structure of PHY_STOP Response Command - * indicates the completion of PHY_STOP command (64 bytes) - */ -struct phy_stop_resp { - __le32 tag; - __le32 status; - __le32 phyid; - u32 reserved[12]; -} __attribute__((packed, aligned(4))); - -/* - * brief the data structure of SSP Completion Response - * use to indicate a SSP Completion (n bytes) - */ -struct ssp_completion_resp { - __le32 tag; - __le32 status; - __le32 param; - __le32 ssptag_rescv_rescpad; - struct ssp_response_iu ssp_resp_iu; - __le32 residual_count; -} __attribute__((packed, aligned(4))); - -#define SSP_RESCV_BIT 0x00010000 - -/* - * brief the data structure of SATA EVNET response - * use to indicate a SATA Completion (64 bytes) - */ -struct sata_event_resp { - __le32 tag; - __le32 event; - __le32 port_id; - __le32 device_id; - u32 reserved; - __le32 event_param0; - __le32 event_param1; - __le32 sata_addr_h32; - __le32 sata_addr_l32; - __le32 e_udt1_udt0_crc; - __le32 e_udt5_udt4_udt3_udt2; - __le32 a_udt1_udt0_crc; - __le32 a_udt5_udt4_udt3_udt2; - __le32 hwdevid_diferr; - __le32 err_framelen_byteoffset; - __le32 err_dataframe; -} __attribute__((packed, aligned(4))); - -/* - * brief the data structure of SSP EVNET esponse - * use to indicate a SSP Completion (64 bytes) - */ -struct ssp_event_resp { - __le32 tag; - __le32 event; - __le32 port_id; - __le32 device_id; - __le32 ssp_tag; - __le32 event_param0; - __le32 event_param1; - __le32 sas_addr_h32; - __le32 sas_addr_l32; - __le32 e_udt1_udt0_crc; - __le32 e_udt5_udt4_udt3_udt2; - __le32 a_udt1_udt0_crc; - __le32 a_udt5_udt4_udt3_udt2; - __le32 hwdevid_diferr; - __le32 err_framelen_byteoffset; - __le32 err_dataframe; -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure of General Event Notification Response - * use to describe MPI General Event Notification Response (64 bytes) - */ -struct general_event_resp { - __le32 status; - __le32 inb_IOMB_payload[14]; -} __attribute__((packed, aligned(4))); - -#define GENERAL_EVENT_PAYLOAD 14 -#define OPCODE_BITS 0x00000fff - -/* - * brief the data structure of SMP Request Command - * use to describe MPI SMP REQUEST Command (64 bytes) - */ -struct smp_req { - __le32 tag; - __le32 device_id; - __le32 len_ip_ir; - /* Bits [0] - Indirect response */ - /* Bits [1] - Indirect Payload */ - /* Bits [15:2] - Reserved */ - /* Bits [23:16] - direct payload Len */ - /* Bits [31:24] - Reserved */ - u8 smp_req16[16]; - union { - u8 smp_req[32]; - struct { - __le64 long_req_addr;/* sg dma address, LE */ - __le32 long_req_size;/* LE */ - u32 _r_a; - __le64 long_resp_addr;/* sg dma address, LE */ - __le32 long_resp_size;/* LE */ - u32 _r_b; - } long_smp_req;/* sequencer extension */ - }; - __le32 rsvd[16]; -} __attribute__((packed, aligned(4))); -/* - * brief the data structure of SMP Completion Response - * use to describe MPI SMP Completion Response (64 bytes) - */ -struct smp_completion_resp { - __le32 tag; - __le32 status; - __le32 param; - u8 _r_a[252]; -} __attribute__((packed, aligned(4))); - -/* - *brief the data structure of SSP SMP SATA Abort Command - * use to describe MPI SSP SMP & SATA Abort Command (64 bytes) - */ -struct task_abort_req { - __le32 tag; - __le32 device_id; - __le32 tag_to_abort; - __le32 abort_all; - u32 reserved[27]; -} __attribute__((packed, aligned(4))); - -/* These flags used for SSP SMP & SATA Abort */ -#define ABORT_MASK 0x3 -#define ABORT_SINGLE 0x0 -#define ABORT_ALL 0x1 - -/** - * brief the data structure of SSP SATA SMP Abort Response - * use to describe SSP SMP & SATA Abort Response ( 64 bytes) - */ -struct task_abort_resp { - __le32 tag; - __le32 status; - __le32 scp; - u32 reserved[12]; -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure of SAS Diagnostic Start/End Command - * use to describe MPI SAS Diagnostic Start/End Command (64 bytes) - */ -struct sas_diag_start_end_req { - __le32 tag; - __le32 operation_phyid; - u32 reserved[29]; -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure of SAS Diagnostic Execute Command - * use to describe MPI SAS Diagnostic Execute Command (64 bytes) - */ -struct sas_diag_execute_req { - __le32 tag; - __le32 cmdtype_cmddesc_phyid; - __le32 pat1_pat2; - __le32 threshold; - __le32 codepat_errmsk; - __le32 pmon; - __le32 pERF1CTL; - u32 reserved[24]; -} __attribute__((packed, aligned(4))); - -#define SAS_DIAG_PARAM_BYTES 24 - -/* - * brief the data structure of Set Device State Command - * use to describe MPI Set Device State Command (64 bytes) - */ -struct set_dev_state_req { - __le32 tag; - __le32 device_id; - __le32 nds; - u32 reserved[28]; -} __attribute__((packed, aligned(4))); - -/* - * brief the data structure of SATA Start Command - * use to describe MPI SATA IO Start Command (64 bytes) - * Note: This structure is common for normal / encryption I/O - */ - -struct sata_start_req { - __le32 tag; - __le32 device_id; - __le32 data_len; - __le32 ncqtag_atap_dir_m_dad; - struct host_to_dev_fis sata_fis; - u32 reserved1; - u32 reserved2; /* dword 11. rsvd for normal I/O. */ - /* EPLE Descl for enc I/O */ - u32 addr_low; /* dword 12. rsvd for enc I/O */ - u32 addr_high; /* dword 13. reserved for enc I/O */ - __le32 len; /* dword 14: length for normal I/O. */ - /* EPLE Desch for enc I/O */ - __le32 esgl; /* dword 15. rsvd for enc I/O */ - __le32 atapi_scsi_cdb[4]; /* dword 16-19. rsvd for enc I/O */ - /* The below fields are reserved for normal I/O */ - __le32 key_index_mode; /* dword 20 */ - __le32 sector_cnt_enss;/* dword 21 */ - __le32 keytagl; /* dword 22 */ - __le32 keytagh; /* dword 23 */ - __le32 twk_val0; /* dword 24 */ - __le32 twk_val1; /* dword 25 */ - __le32 twk_val2; /* dword 26 */ - __le32 twk_val3; /* dword 27 */ - __le32 enc_addr_low; /* dword 28. Encryption SGL address high */ - __le32 enc_addr_high; /* dword 29. Encryption SGL address low */ - __le32 enc_len; /* dword 30. Encryption length */ - __le32 enc_esgl; /* dword 31. Encryption esgl bit */ -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure of SSP INI TM Start Command - * use to describe MPI SSP INI TM Start Command (64 bytes) - */ -struct ssp_ini_tm_start_req { - __le32 tag; - __le32 device_id; - __le32 relate_tag; - __le32 tmf; - u8 lun[8]; - __le32 ds_ads_m; - u32 reserved[24]; -} __attribute__((packed, aligned(4))); - -struct ssp_info_unit { - u8 lun[8];/* SCSI Logical Unit Number */ - u8 reserved1;/* reserved */ - u8 efb_prio_attr; - /* B7 : enabledFirstBurst */ - /* B6-3 : taskPriority */ - /* B2-0 : taskAttribute */ - u8 reserved2; /* reserved */ - u8 additional_cdb_len; - /* B7-2 : additional_cdb_len */ - /* B1-0 : reserved */ - u8 cdb[16];/* The SCSI CDB up to 16 bytes length */ -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure of SSP INI IO Start Command - * use to describe MPI SSP INI IO Start Command (64 bytes) - * Note: This structure is common for normal / encryption I/O - */ -struct ssp_ini_io_start_req { - __le32 tag; - __le32 device_id; - __le32 data_len; - __le32 dad_dir_m_tlr; - struct ssp_info_unit ssp_iu; - __le32 addr_low; /* dword 12: sgl low for normal I/O. */ - /* epl_descl for encryption I/O */ - __le32 addr_high; /* dword 13: sgl hi for normal I/O */ - /* dpl_descl for encryption I/O */ - __le32 len; /* dword 14: len for normal I/O. */ - /* edpl_desch for encryption I/O */ - __le32 esgl; /* dword 15: ESGL bit for normal I/O. */ - /* user defined tag mask for enc I/O */ - /* The below fields are reserved for normal I/O */ - u8 udt[12]; /* dword 16-18 */ - __le32 sectcnt_ios; /* dword 19 */ - __le32 key_cmode; /* dword 20 */ - __le32 ks_enss; /* dword 21 */ - __le32 keytagl; /* dword 22 */ - __le32 keytagh; /* dword 23 */ - __le32 twk_val0; /* dword 24 */ - __le32 twk_val1; /* dword 25 */ - __le32 twk_val2; /* dword 26 */ - __le32 twk_val3; /* dword 27 */ - __le32 enc_addr_low; /* dword 28: Encryption sgl addr low */ - __le32 enc_addr_high; /* dword 29: Encryption sgl addr hi */ - __le32 enc_len; /* dword 30: Encryption length */ - __le32 enc_esgl; /* dword 31: ESGL bit for encryption */ -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure for SSP_INI_DIF_ENC_IO COMMAND - * use to initiate SSP I/O operation with optional DIF/ENC - */ -struct ssp_dif_enc_io_req { - __le32 tag; - __le32 device_id; - __le32 data_len; - __le32 dirMTlr; - __le32 sspiu0; - __le32 sspiu1; - __le32 sspiu2; - __le32 sspiu3; - __le32 sspiu4; - __le32 sspiu5; - __le32 sspiu6; - __le32 epl_des; - __le32 dpl_desl_ndplr; - __le32 dpl_desh; - __le32 uum_uuv_bss_difbits; - u8 udt[12]; - __le32 sectcnt_ios; - __le32 key_cmode; - __le32 ks_enss; - __le32 keytagl; - __le32 keytagh; - __le32 twk_val0; - __le32 twk_val1; - __le32 twk_val2; - __le32 twk_val3; - __le32 addr_low; - __le32 addr_high; - __le32 len; - __le32 esgl; -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure of Firmware download - * use to describe MPI FW DOWNLOAD Command (64 bytes) - */ -struct fw_flash_Update_req { - __le32 tag; - __le32 cur_image_offset; - __le32 cur_image_len; - __le32 total_image_len; - u32 reserved0[7]; - __le32 sgl_addr_lo; - __le32 sgl_addr_hi; - __le32 len; - __le32 ext_reserved; - u32 reserved1[16]; -} __attribute__((packed, aligned(4))); - -#define FWFLASH_IOMB_RESERVED_LEN 0x07 -/** - * brief the data structure of FW_FLASH_UPDATE Response - * use to describe MPI FW_FLASH_UPDATE Response (64 bytes) - * - */ - struct fw_flash_Update_resp { - __le32 tag; - __le32 status; - u32 reserved[13]; -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure of Get NVM Data Command - * use to get data from NVM in HBA(64 bytes) - */ -struct get_nvm_data_req { - __le32 tag; - __le32 len_ir_vpdd; - __le32 vpd_offset; - u32 reserved[8]; - __le32 resp_addr_lo; - __le32 resp_addr_hi; - __le32 resp_len; - u32 reserved1[17]; -} __attribute__((packed, aligned(4))); - -struct set_nvm_data_req { - __le32 tag; - __le32 len_ir_vpdd; - __le32 vpd_offset; - u32 reserved[8]; - __le32 resp_addr_lo; - __le32 resp_addr_hi; - __le32 resp_len; - u32 reserved1[17]; -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure for SET CONTROLLER CONFIG COMMAND - * use to modify controller configuration - */ -struct set_ctrl_cfg_req { - __le32 tag; - __le32 cfg_pg[14]; - u32 reserved[16]; -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure for GET CONTROLLER CONFIG COMMAND - * use to get controller configuration page - */ -struct get_ctrl_cfg_req { - __le32 tag; - __le32 pgcd; - __le32 int_vec; - u32 reserved[28]; -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure for KEK_MANAGEMENT COMMAND - * use for KEK management - */ -struct kek_mgmt_req { - __le32 tag; - __le32 new_curidx_ksop; - u32 reserved; - __le32 kblob[12]; - u32 reserved1[16]; -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure for DEK_MANAGEMENT COMMAND - * use for DEK management - */ -struct dek_mgmt_req { - __le32 tag; - __le32 kidx_dsop; - __le32 dekidx; - __le32 addr_l; - __le32 addr_h; - __le32 nent; - __le32 dbf_tblsize; - u32 reserved[24]; -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure for SET PHY PROFILE COMMAND - * use to retrive phy specific information - */ -struct set_phy_profile_req { - __le32 tag; - __le32 ppc_phyid; - u32 reserved[29]; -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure for GET PHY PROFILE COMMAND - * use to retrive phy specific information - */ -struct get_phy_profile_req { - __le32 tag; - __le32 ppc_phyid; - __le32 profile[29]; -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure for EXT FLASH PARTITION - * use to manage ext flash partition - */ -struct ext_flash_partition_req { - __le32 tag; - __le32 cmd; - __le32 offset; - __le32 len; - u32 reserved[7]; - __le32 addr_low; - __le32 addr_high; - __le32 len1; - __le32 ext; - u32 reserved1[16]; -} __attribute__((packed, aligned(4))); - -#define TWI_DEVICE 0x0 -#define C_SEEPROM 0x1 -#define VPD_FLASH 0x4 -#define AAP1_RDUMP 0x5 -#define IOP_RDUMP 0x6 -#define EXPAN_ROM 0x7 - -#define IPMode 0x80000000 -#define NVMD_TYPE 0x0000000F -#define NVMD_STAT 0x0000FFFF -#define NVMD_LEN 0xFF000000 -/** - * brief the data structure of Get NVMD Data Response - * use to describe MPI Get NVMD Data Response (64 bytes) - */ -struct get_nvm_data_resp { - __le32 tag; - __le32 ir_tda_bn_dps_das_nvm; - __le32 dlen_status; - __le32 nvm_data[12]; -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure of SAS Diagnostic Start/End Response - * use to describe MPI SAS Diagnostic Start/End Response (64 bytes) - * - */ -struct sas_diag_start_end_resp { - __le32 tag; - __le32 status; - u32 reserved[13]; -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure of SAS Diagnostic Execute Response - * use to describe MPI SAS Diagnostic Execute Response (64 bytes) - * - */ -struct sas_diag_execute_resp { - __le32 tag; - __le32 cmdtype_cmddesc_phyid; - __le32 Status; - __le32 ReportData; - u32 reserved[11]; -} __attribute__((packed, aligned(4))); - -/** - * brief the data structure of Set Device State Response - * use to describe MPI Set Device State Response (64 bytes) - * - */ -struct set_dev_state_resp { - __le32 tag; - __le32 status; - __le32 device_id; - __le32 pds_nds; - u32 reserved[11]; -} __attribute__((packed, aligned(4))); - -/* new outbound structure for spcv - begins */ -/** - * brief the data structure for SET CONTROLLER CONFIG COMMAND - * use to modify controller configuration - */ -struct set_ctrl_cfg_resp { - __le32 tag; - __le32 status; - __le32 err_qlfr_pgcd; - u32 reserved[12]; -} __attribute__((packed, aligned(4))); - -struct get_ctrl_cfg_resp { - __le32 tag; - __le32 status; - __le32 err_qlfr; - __le32 confg_page[12]; -} __attribute__((packed, aligned(4))); - -struct kek_mgmt_resp { - __le32 tag; - __le32 status; - __le32 kidx_new_curr_ksop; - __le32 err_qlfr; - u32 reserved[11]; -} __attribute__((packed, aligned(4))); - -struct dek_mgmt_resp { - __le32 tag; - __le32 status; - __le32 kekidx_tbls_dsop; - __le32 dekidx; - __le32 err_qlfr; - u32 reserved[10]; -} __attribute__((packed, aligned(4))); - -struct get_phy_profile_resp { - __le32 tag; - __le32 status; - __le32 ppc_phyid; - __le32 ppc_specific_rsp[12]; -} __attribute__((packed, aligned(4))); - -struct flash_op_ext_resp { - __le32 tag; - __le32 cmd; - __le32 status; - __le32 epart_size; - __le32 epart_sect_size; - u32 reserved[10]; -} __attribute__((packed, aligned(4))); - -struct set_phy_profile_resp { - __le32 tag; - __le32 status; - __le32 ppc_phyid; - __le32 ppc_specific_rsp[12]; -} __attribute__((packed, aligned(4))); - -struct ssp_coalesced_comp_resp { - __le32 coal_cnt; - __le32 tag0; - __le32 ssp_tag0; - __le32 tag1; - __le32 ssp_tag1; - __le32 add_tag_ssp_tag[10]; -} __attribute__((packed, aligned(4))); - -/* new outbound structure for spcv - ends */ - -/* brief data structure for SAS protocol timer configuration page. - * - */ -struct SASProtocolTimerConfig { - __le32 pageCode; /* 0 */ - __le32 MST_MSI; /* 1 */ - __le32 STP_SSP_MCT_TMO; /* 2 */ - __le32 STP_FRM_TMO; /* 3 */ - __le32 STP_IDLE_TMO; /* 4 */ - __le32 OPNRJT_RTRY_INTVL; /* 5 */ - __le32 Data_Cmd_OPNRJT_RTRY_TMO; /* 6 */ - __le32 Data_Cmd_OPNRJT_RTRY_THR; /* 7 */ - __le32 MAX_AIP; /* 8 */ -} __attribute__((packed, aligned(4))); - -typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t; - -#define NDS_BITS 0x0F -#define PDS_BITS 0xF0 - -/* - * HW Events type - */ - -#define HW_EVENT_RESET_START 0x01 -#define HW_EVENT_CHIP_RESET_COMPLETE 0x02 -#define HW_EVENT_PHY_STOP_STATUS 0x03 -#define HW_EVENT_SAS_PHY_UP 0x04 -#define HW_EVENT_SATA_PHY_UP 0x05 -#define HW_EVENT_SATA_SPINUP_HOLD 0x06 -#define HW_EVENT_PHY_DOWN 0x07 -#define HW_EVENT_PORT_INVALID 0x08 -#define HW_EVENT_BROADCAST_CHANGE 0x09 -#define HW_EVENT_PHY_ERROR 0x0A -#define HW_EVENT_BROADCAST_SES 0x0B -#define HW_EVENT_INBOUND_CRC_ERROR 0x0C -#define HW_EVENT_HARD_RESET_RECEIVED 0x0D -#define HW_EVENT_MALFUNCTION 0x0E -#define HW_EVENT_ID_FRAME_TIMEOUT 0x0F -#define HW_EVENT_BROADCAST_EXP 0x10 -#define HW_EVENT_PHY_START_STATUS 0x11 -#define HW_EVENT_LINK_ERR_INVALID_DWORD 0x12 -#define HW_EVENT_LINK_ERR_DISPARITY_ERROR 0x13 -#define HW_EVENT_LINK_ERR_CODE_VIOLATION 0x14 -#define HW_EVENT_LINK_ERR_LOSS_OF_DWORD_SYNCH 0x15 -#define HW_EVENT_LINK_ERR_PHY_RESET_FAILED 0x16 -#define HW_EVENT_PORT_RECOVERY_TIMER_TMO 0x17 -#define HW_EVENT_PORT_RECOVER 0x18 -#define HW_EVENT_PORT_RESET_TIMER_TMO 0x19 -#define HW_EVENT_PORT_RESET_COMPLETE 0x20 -#define EVENT_BROADCAST_ASYNCH_EVENT 0x21 - -/* port state */ -#define PORT_NOT_ESTABLISHED 0x00 -#define PORT_VALID 0x01 -#define PORT_LOSTCOMM 0x02 -#define PORT_IN_RESET 0x04 -#define PORT_3RD_PARTY_RESET 0x07 -#define PORT_INVALID 0x08 - -/* - * SSP/SMP/SATA IO Completion Status values - */ - -#define IO_SUCCESS 0x00 -#define IO_ABORTED 0x01 -#define IO_OVERFLOW 0x02 -#define IO_UNDERFLOW 0x03 -#define IO_FAILED 0x04 -#define IO_ABORT_RESET 0x05 -#define IO_NOT_VALID 0x06 -#define IO_NO_DEVICE 0x07 -#define IO_ILLEGAL_PARAMETER 0x08 -#define IO_LINK_FAILURE 0x09 -#define IO_PROG_ERROR 0x0A - -#define IO_EDC_IN_ERROR 0x0B -#define IO_EDC_OUT_ERROR 0x0C -#define IO_ERROR_HW_TIMEOUT 0x0D -#define IO_XFER_ERROR_BREAK 0x0E -#define IO_XFER_ERROR_PHY_NOT_READY 0x0F -#define IO_OPEN_CNX_ERROR_PROTOCOL_NOT_SUPPORTED 0x10 -#define IO_OPEN_CNX_ERROR_ZONE_VIOLATION 0x11 -#define IO_OPEN_CNX_ERROR_BREAK 0x12 -#define IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS 0x13 -#define IO_OPEN_CNX_ERROR_BAD_DESTINATION 0x14 -#define IO_OPEN_CNX_ERROR_CONNECTION_RATE_NOT_SUPPORTED 0x15 -#define IO_OPEN_CNX_ERROR_STP_RESOURCES_BUSY 0x16 -#define IO_OPEN_CNX_ERROR_WRONG_DESTINATION 0x17 -/* This error code 0x18 is not used on SPCv */ -#define IO_OPEN_CNX_ERROR_UNKNOWN_ERROR 0x18 -#define IO_XFER_ERROR_NAK_RECEIVED 0x19 -#define IO_XFER_ERROR_ACK_NAK_TIMEOUT 0x1A -#define IO_XFER_ERROR_PEER_ABORTED 0x1B -#define IO_XFER_ERROR_RX_FRAME 0x1C -#define IO_XFER_ERROR_DMA 0x1D -#define IO_XFER_ERROR_CREDIT_TIMEOUT 0x1E -#define IO_XFER_ERROR_SATA_LINK_TIMEOUT 0x1F -#define IO_XFER_ERROR_SATA 0x20 - -/* This error code 0x22 is not used on SPCv */ -#define IO_XFER_ERROR_ABORTED_DUE_TO_SRST 0x22 -#define IO_XFER_ERROR_REJECTED_NCQ_MODE 0x21 -#define IO_XFER_ERROR_ABORTED_NCQ_MODE 0x23 -#define IO_XFER_OPEN_RETRY_TIMEOUT 0x24 -/* This error code 0x25 is not used on SPCv */ -#define IO_XFER_SMP_RESP_CONNECTION_ERROR 0x25 -#define IO_XFER_ERROR_UNEXPECTED_PHASE 0x26 -#define IO_XFER_ERROR_XFER_RDY_OVERRUN 0x27 -#define IO_XFER_ERROR_XFER_RDY_NOT_EXPECTED 0x28 -#define IO_XFER_ERROR_CMD_ISSUE_ACK_NAK_TIMEOUT 0x30 - -/* The following error code 0x31 and 0x32 are not using (obsolete) */ -#define IO_XFER_ERROR_CMD_ISSUE_BREAK_BEFORE_ACK_NAK 0x31 -#define IO_XFER_ERROR_CMD_ISSUE_PHY_DOWN_BEFORE_ACK_NAK 0x32 - -#define IO_XFER_ERROR_OFFSET_MISMATCH 0x34 -#define IO_XFER_ERROR_XFER_ZERO_DATA_LEN 0x35 -#define IO_XFER_CMD_FRAME_ISSUED 0x36 -#define IO_ERROR_INTERNAL_SMP_RESOURCE 0x37 -#define IO_PORT_IN_RESET 0x38 -#define IO_DS_NON_OPERATIONAL 0x39 -#define IO_DS_IN_RECOVERY 0x3A -#define IO_TM_TAG_NOT_FOUND 0x3B -#define IO_XFER_PIO_SETUP_ERROR 0x3C -#define IO_SSP_EXT_IU_ZERO_LEN_ERROR 0x3D -#define IO_DS_IN_ERROR 0x3E -#define IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY 0x3F -#define IO_ABORT_IN_PROGRESS 0x40 -#define IO_ABORT_DELAYED 0x41 -#define IO_INVALID_LENGTH 0x42 - -/********** additional response event values *****************/ - -#define IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY_ALT 0x43 -#define IO_XFER_OPEN_RETRY_BACKOFF_THRESHOLD_REACHED 0x44 -#define IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_TMO 0x45 -#define IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_NO_DEST 0x46 -#define IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE 0x47 -#define IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED 0x48 -#define IO_DS_INVALID 0x49 -/* WARNING: the value is not contiguous from here */ -#define IO_XFER_ERR_LAST_PIO_DATAIN_CRC_ERR 0x52 -#define IO_XFER_DMA_ACTIVATE_TIMEOUT 0x53 -#define IO_XFER_ERROR_INTERNAL_CRC_ERROR 0x54 -#define MPI_IO_RQE_BUSY_FULL 0x55 -#define IO_XFER_ERR_EOB_DATA_OVERRUN 0x56 -#define IO_XFR_ERROR_INVALID_SSP_RSP_FRAME 0x57 -#define IO_OPEN_CNX_ERROR_OPEN_PREEMPTED 0x58 - -#define MPI_ERR_IO_RESOURCE_UNAVAILABLE 0x1004 -#define MPI_ERR_ATAPI_DEVICE_BUSY 0x1024 - -#define IO_XFR_ERROR_DEK_KEY_CACHE_MISS 0x2040 -/* - * An encryption IO request failed due to DEK Key Tag mismatch. - * The key tag supplied in the encryption IOMB does not match with - * the Key Tag in the referenced DEK Entry. - */ -#define IO_XFR_ERROR_DEK_KEY_TAG_MISMATCH 0x2041 -#define IO_XFR_ERROR_CIPHER_MODE_INVALID 0x2042 -/* - * An encryption I/O request failed because the initial value (IV) - * in the unwrapped DEK blob didn't match the IV used to unwrap it. - */ -#define IO_XFR_ERROR_DEK_IV_MISMATCH 0x2043 -/* An encryption I/O request failed due to an internal RAM ECC or - * interface error while unwrapping the DEK. */ -#define IO_XFR_ERROR_DEK_RAM_INTERFACE_ERROR 0x2044 -/* An encryption I/O request failed due to an internal RAM ECC or - * interface error while unwrapping the DEK. */ -#define IO_XFR_ERROR_INTERNAL_RAM 0x2045 -/* - * An encryption I/O request failed - * because the DEK index specified in the I/O was outside the bounds of - * the total number of entries in the host DEK table. - */ -#define IO_XFR_ERROR_DEK_INDEX_OUT_OF_BOUNDS0x2046 - -/* define DIF IO response error status code */ -#define IO_XFR_ERROR_DIF_MISMATCH 0x3000 -#define IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH 0x3001 -#define IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH 0x3002 -#define IO_XFR_ERROR_DIF_CRC_MISMATCH 0x3003 - -/* define operator management response status and error qualifier code */ -#define OPR_MGMT_OP_NOT_SUPPORTED 0x2060 -#define OPR_MGMT_MPI_ENC_ERR_OPR_PARAM_ILLEGAL 0x2061 -#define OPR_MGMT_MPI_ENC_ERR_OPR_ID_NOT_FOUND 0x2062 -#define OPR_MGMT_MPI_ENC_ERR_OPR_ROLE_NOT_MATCH 0x2063 -#define OPR_MGMT_MPI_ENC_ERR_OPR_MAX_NUM_EXCEEDED 0x2064 -#define OPR_MGMT_MPI_ENC_ERR_KEK_UNWRAP_FAIL 0x2022 -#define OPR_MGMT_MPI_ENC_ERR_NVRAM_OPERATION_FAILURE 0x2023 -/***************** additional response event values ***************/ - -/* WARNING: This error code must always be the last number. - * If you add error code, modify this code also - * It is used as an index - */ -#define IO_ERROR_UNKNOWN_GENERIC 0x2023 - -/* MSGU CONFIGURATION TABLE*/ - -#define SPCv_MSGU_CFG_TABLE_UPDATE 0x01 -#define SPCv_MSGU_CFG_TABLE_RESET 0x02 -#define SPCv_MSGU_CFG_TABLE_FREEZE 0x04 -#define SPCv_MSGU_CFG_TABLE_UNFREEZE 0x08 -#define MSGU_IBDB_SET 0x00 -#define MSGU_HOST_INT_STATUS 0x08 -#define MSGU_HOST_INT_MASK 0x0C -#define MSGU_IOPIB_INT_STATUS 0x18 -#define MSGU_IOPIB_INT_MASK 0x1C -#define MSGU_IBDB_CLEAR 0x20 - -#define MSGU_MSGU_CONTROL 0x24 -#define MSGU_ODR 0x20 -#define MSGU_ODCR 0x28 - -#define MSGU_ODMR 0x30 -#define MSGU_ODMR_U 0x34 -#define MSGU_ODMR_CLR 0x38 -#define MSGU_ODMR_CLR_U 0x3C -#define MSGU_OD_RSVD 0x40 - -#define MSGU_SCRATCH_PAD_0 0x44 -#define MSGU_SCRATCH_PAD_1 0x48 -#define MSGU_SCRATCH_PAD_2 0x4C -#define MSGU_SCRATCH_PAD_3 0x50 -#define MSGU_HOST_SCRATCH_PAD_0 0x54 -#define MSGU_HOST_SCRATCH_PAD_1 0x58 -#define MSGU_HOST_SCRATCH_PAD_2 0x5C -#define MSGU_HOST_SCRATCH_PAD_3 0x60 -#define MSGU_HOST_SCRATCH_PAD_4 0x64 -#define MSGU_HOST_SCRATCH_PAD_5 0x68 -#define MSGU_HOST_SCRATCH_PAD_6 0x6C -#define MSGU_HOST_SCRATCH_PAD_7 0x70 - -/* bit definition for ODMR register */ -#define ODMR_MASK_ALL 0xFFFFFFFF/* mask all - interrupt vector */ -#define ODMR_CLEAR_ALL 0 /* clear all - interrupt vector */ -/* bit definition for ODCR register */ -#define ODCR_CLEAR_ALL 0xFFFFFFFF /* mask all - interrupt vector*/ -/* MSIX Interupts */ -#define MSIX_TABLE_OFFSET 0x2000 -#define MSIX_TABLE_ELEMENT_SIZE 0x10 -#define MSIX_INTERRUPT_CONTROL_OFFSET 0xC -#define MSIX_TABLE_BASE (MSIX_TABLE_OFFSET + \ - MSIX_INTERRUPT_CONTROL_OFFSET) -#define MSIX_INTERRUPT_DISABLE 0x1 -#define MSIX_INTERRUPT_ENABLE 0x0 - -/* state definition for Scratch Pad1 register */ -#define SCRATCH_PAD_RAAE_READY 0x3 -#define SCRATCH_PAD_ILA_READY 0xC -#define SCRATCH_PAD_BOOT_LOAD_SUCCESS 0x0 -#define SCRATCH_PAD_IOP0_READY 0xC00 -#define SCRATCH_PAD_IOP1_READY 0x3000 - -/* boot loader state */ -#define SCRATCH_PAD1_BOOTSTATE_MASK 0x70 /* Bit 4-6 */ -#define SCRATCH_PAD1_BOOTSTATE_SUCESS 0x0 /* Load successful */ -#define SCRATCH_PAD1_BOOTSTATE_HDA_SEEPROM 0x10 /* HDA SEEPROM */ -#define SCRATCH_PAD1_BOOTSTATE_HDA_BOOTSTRAP 0x20 /* HDA BootStrap Pins */ -#define SCRATCH_PAD1_BOOTSTATE_HDA_SOFTRESET 0x30 /* HDA Soft Reset */ -#define SCRATCH_PAD1_BOOTSTATE_CRIT_ERROR 0x40 /* HDA critical error */ -#define SCRATCH_PAD1_BOOTSTATE_R1 0x50 /* Reserved */ -#define SCRATCH_PAD1_BOOTSTATE_R2 0x60 /* Reserved */ -#define SCRATCH_PAD1_BOOTSTATE_FATAL 0x70 /* Fatal Error */ - - /* state definition for Scratch Pad2 register */ -#define SCRATCH_PAD2_POR 0x00 /* power on state */ -#define SCRATCH_PAD2_SFR 0x01 /* soft reset state */ -#define SCRATCH_PAD2_ERR 0x02 /* error state */ -#define SCRATCH_PAD2_RDY 0x03 /* ready state */ -#define SCRATCH_PAD2_FWRDY_RST 0x04 /* FW rdy for soft reset flag */ -#define SCRATCH_PAD2_IOPRDY_RST 0x08 /* IOP ready for soft reset */ -#define SCRATCH_PAD2_STATE_MASK 0xFFFFFFF4 /* ScratchPad 2 - Mask, bit1-0 State */ -#define SCRATCH_PAD2_RESERVED 0x000003FC/* Scratch Pad1 - Reserved bit 2 to 9 */ - -#define SCRATCH_PAD_ERROR_MASK 0xFFFFFC00 /* Error mask bits */ -#define SCRATCH_PAD_STATE_MASK 0x00000003 /* State Mask bits */ - -/* main configuration offset - byte offset */ -#define MAIN_SIGNATURE_OFFSET 0x00 /* DWORD 0x00 */ -#define MAIN_INTERFACE_REVISION 0x04 /* DWORD 0x01 */ -#define MAIN_FW_REVISION 0x08 /* DWORD 0x02 */ -#define MAIN_MAX_OUTSTANDING_IO_OFFSET 0x0C /* DWORD 0x03 */ -#define MAIN_MAX_SGL_OFFSET 0x10 /* DWORD 0x04 */ -#define MAIN_CNTRL_CAP_OFFSET 0x14 /* DWORD 0x05 */ -#define MAIN_GST_OFFSET 0x18 /* DWORD 0x06 */ -#define MAIN_IBQ_OFFSET 0x1C /* DWORD 0x07 */ -#define MAIN_OBQ_OFFSET 0x20 /* DWORD 0x08 */ -#define MAIN_IQNPPD_HPPD_OFFSET 0x24 /* DWORD 0x09 */ - -/* 0x28 - 0x4C - RSVD */ -#define MAIN_EVENT_CRC_CHECK 0x48 /* DWORD 0x12 */ -#define MAIN_EVENT_LOG_ADDR_HI 0x50 /* DWORD 0x14 */ -#define MAIN_EVENT_LOG_ADDR_LO 0x54 /* DWORD 0x15 */ -#define MAIN_EVENT_LOG_BUFF_SIZE 0x58 /* DWORD 0x16 */ -#define MAIN_EVENT_LOG_OPTION 0x5C /* DWORD 0x17 */ -#define MAIN_PCS_EVENT_LOG_ADDR_HI 0x60 /* DWORD 0x18 */ -#define MAIN_PCS_EVENT_LOG_ADDR_LO 0x64 /* DWORD 0x19 */ -#define MAIN_PCS_EVENT_LOG_BUFF_SIZE 0x68 /* DWORD 0x1A */ -#define MAIN_PCS_EVENT_LOG_OPTION 0x6C /* DWORD 0x1B */ -#define MAIN_FATAL_ERROR_INTERRUPT 0x70 /* DWORD 0x1C */ -#define MAIN_FATAL_ERROR_RDUMP0_OFFSET 0x74 /* DWORD 0x1D */ -#define MAIN_FATAL_ERROR_RDUMP0_LENGTH 0x78 /* DWORD 0x1E */ -#define MAIN_FATAL_ERROR_RDUMP1_OFFSET 0x7C /* DWORD 0x1F */ -#define MAIN_FATAL_ERROR_RDUMP1_LENGTH 0x80 /* DWORD 0x20 */ -#define MAIN_GPIO_LED_FLAGS_OFFSET 0x84 /* DWORD 0x21 */ -#define MAIN_ANALOG_SETUP_OFFSET 0x88 /* DWORD 0x22 */ - -#define MAIN_INT_VECTOR_TABLE_OFFSET 0x8C /* DWORD 0x23 */ -#define MAIN_SAS_PHY_ATTR_TABLE_OFFSET 0x90 /* DWORD 0x24 */ -#define MAIN_PORT_RECOVERY_TIMER 0x94 /* DWORD 0x25 */ -#define MAIN_INT_REASSERTION_DELAY 0x98 /* DWORD 0x26 */ - -/* Gereral Status Table offset - byte offset */ -#define GST_GSTLEN_MPIS_OFFSET 0x00 -#define GST_IQ_FREEZE_STATE0_OFFSET 0x04 -#define GST_IQ_FREEZE_STATE1_OFFSET 0x08 -#define GST_MSGUTCNT_OFFSET 0x0C -#define GST_IOPTCNT_OFFSET 0x10 -/* 0x14 - 0x34 - RSVD */ -#define GST_GPIO_INPUT_VAL 0x38 -/* 0x3c - 0x40 - RSVD */ -#define GST_RERRINFO_OFFSET0 0x44 -#define GST_RERRINFO_OFFSET1 0x48 -#define GST_RERRINFO_OFFSET2 0x4c -#define GST_RERRINFO_OFFSET3 0x50 -#define GST_RERRINFO_OFFSET4 0x54 -#define GST_RERRINFO_OFFSET5 0x58 -#define GST_RERRINFO_OFFSET6 0x5c -#define GST_RERRINFO_OFFSET7 0x60 - -/* General Status Table - MPI state */ -#define GST_MPI_STATE_UNINIT 0x00 -#define GST_MPI_STATE_INIT 0x01 -#define GST_MPI_STATE_TERMINATION 0x02 -#define GST_MPI_STATE_ERROR 0x03 -#define GST_MPI_STATE_MASK 0x07 - -/* Per SAS PHY Attributes */ - -#define PSPA_PHYSTATE0_OFFSET 0x00 /* Dword V */ -#define PSPA_OB_HW_EVENT_PID0_OFFSET 0x04 /* DWORD V+1 */ -#define PSPA_PHYSTATE1_OFFSET 0x08 /* Dword V+2 */ -#define PSPA_OB_HW_EVENT_PID1_OFFSET 0x0C /* DWORD V+3 */ -#define PSPA_PHYSTATE2_OFFSET 0x10 /* Dword V+4 */ -#define PSPA_OB_HW_EVENT_PID2_OFFSET 0x14 /* DWORD V+5 */ -#define PSPA_PHYSTATE3_OFFSET 0x18 /* Dword V+6 */ -#define PSPA_OB_HW_EVENT_PID3_OFFSET 0x1C /* DWORD V+7 */ -#define PSPA_PHYSTATE4_OFFSET 0x20 /* Dword V+8 */ -#define PSPA_OB_HW_EVENT_PID4_OFFSET 0x24 /* DWORD V+9 */ -#define PSPA_PHYSTATE5_OFFSET 0x28 /* Dword V+10 */ -#define PSPA_OB_HW_EVENT_PID5_OFFSET 0x2C /* DWORD V+11 */ -#define PSPA_PHYSTATE6_OFFSET 0x30 /* Dword V+12 */ -#define PSPA_OB_HW_EVENT_PID6_OFFSET 0x34 /* DWORD V+13 */ -#define PSPA_PHYSTATE7_OFFSET 0x38 /* Dword V+14 */ -#define PSPA_OB_HW_EVENT_PID7_OFFSET 0x3C /* DWORD V+15 */ -#define PSPA_PHYSTATE8_OFFSET 0x40 /* DWORD V+16 */ -#define PSPA_OB_HW_EVENT_PID8_OFFSET 0x44 /* DWORD V+17 */ -#define PSPA_PHYSTATE9_OFFSET 0x48 /* DWORD V+18 */ -#define PSPA_OB_HW_EVENT_PID9_OFFSET 0x4C /* DWORD V+19 */ -#define PSPA_PHYSTATE10_OFFSET 0x50 /* DWORD V+20 */ -#define PSPA_OB_HW_EVENT_PID10_OFFSET 0x54 /* DWORD V+21 */ -#define PSPA_PHYSTATE11_OFFSET 0x58 /* DWORD V+22 */ -#define PSPA_OB_HW_EVENT_PID11_OFFSET 0x5C /* DWORD V+23 */ -#define PSPA_PHYSTATE12_OFFSET 0x60 /* DWORD V+24 */ -#define PSPA_OB_HW_EVENT_PID12_OFFSET 0x64 /* DWORD V+25 */ -#define PSPA_PHYSTATE13_OFFSET 0x68 /* DWORD V+26 */ -#define PSPA_OB_HW_EVENT_PID13_OFFSET 0x6c /* DWORD V+27 */ -#define PSPA_PHYSTATE14_OFFSET 0x70 /* DWORD V+28 */ -#define PSPA_OB_HW_EVENT_PID14_OFFSET 0x74 /* DWORD V+29 */ -#define PSPA_PHYSTATE15_OFFSET 0x78 /* DWORD V+30 */ -#define PSPA_OB_HW_EVENT_PID15_OFFSET 0x7c /* DWORD V+31 */ -/* end PSPA */ - -/* inbound queue configuration offset - byte offset */ -#define IB_PROPERITY_OFFSET 0x00 -#define IB_BASE_ADDR_HI_OFFSET 0x04 -#define IB_BASE_ADDR_LO_OFFSET 0x08 -#define IB_CI_BASE_ADDR_HI_OFFSET 0x0C -#define IB_CI_BASE_ADDR_LO_OFFSET 0x10 -#define IB_PIPCI_BAR 0x14 -#define IB_PIPCI_BAR_OFFSET 0x18 -#define IB_RESERVED_OFFSET 0x1C - -/* outbound queue configuration offset - byte offset */ -#define OB_PROPERITY_OFFSET 0x00 -#define OB_BASE_ADDR_HI_OFFSET 0x04 -#define OB_BASE_ADDR_LO_OFFSET 0x08 -#define OB_PI_BASE_ADDR_HI_OFFSET 0x0C -#define OB_PI_BASE_ADDR_LO_OFFSET 0x10 -#define OB_CIPCI_BAR 0x14 -#define OB_CIPCI_BAR_OFFSET 0x18 -#define OB_INTERRUPT_COALES_OFFSET 0x1C -#define OB_DYNAMIC_COALES_OFFSET 0x20 -#define OB_PROPERTY_INT_ENABLE 0x40000000 - -#define MBIC_NMI_ENABLE_VPE0_IOP 0x000418 -#define MBIC_NMI_ENABLE_VPE0_AAP1 0x000418 -/* PCIE registers - BAR2(0x18), BAR1(win) 0x010000 */ -#define PCIE_EVENT_INTERRUPT_ENABLE 0x003040 -#define PCIE_EVENT_INTERRUPT 0x003044 -#define PCIE_ERROR_INTERRUPT_ENABLE 0x003048 -#define PCIE_ERROR_INTERRUPT 0x00304C - -/* SPCV soft reset */ -#define SPC_REG_SOFT_RESET 0x00001000 -#define SPCv_NORMAL_RESET_VALUE 0x1 - -#define SPCv_SOFT_RESET_READ_MASK 0xC0 -#define SPCv_SOFT_RESET_NO_RESET 0x0 -#define SPCv_SOFT_RESET_NORMAL_RESET_OCCURED 0x40 -#define SPCv_SOFT_RESET_HDA_MODE_OCCURED 0x80 -#define SPCv_SOFT_RESET_CHIP_RESET_OCCURED 0xC0 - -/* signature definition for host scratch pad0 register */ -#define SPC_SOFT_RESET_SIGNATURE 0x252acbcd -/* Signature for Soft Reset */ - -/* SPC Reset register - BAR4(0x20), BAR2(win) (need dynamic mapping) */ -#define SPC_REG_RESET 0x000000/* reset register */ - -/* bit definition for SPC_RESET register */ -#define SPC_REG_RESET_OSSP 0x00000001 -#define SPC_REG_RESET_RAAE 0x00000002 -#define SPC_REG_RESET_PCS_SPBC 0x00000004 -#define SPC_REG_RESET_PCS_IOP_SS 0x00000008 -#define SPC_REG_RESET_PCS_AAP1_SS 0x00000010 -#define SPC_REG_RESET_PCS_AAP2_SS 0x00000020 -#define SPC_REG_RESET_PCS_LM 0x00000040 -#define SPC_REG_RESET_PCS 0x00000080 -#define SPC_REG_RESET_GSM 0x00000100 -#define SPC_REG_RESET_DDR2 0x00010000 -#define SPC_REG_RESET_BDMA_CORE 0x00020000 -#define SPC_REG_RESET_BDMA_SXCBI 0x00040000 -#define SPC_REG_RESET_PCIE_AL_SXCBI 0x00080000 -#define SPC_REG_RESET_PCIE_PWR 0x00100000 -#define SPC_REG_RESET_PCIE_SFT 0x00200000 -#define SPC_REG_RESET_PCS_SXCBI 0x00400000 -#define SPC_REG_RESET_LMS_SXCBI 0x00800000 -#define SPC_REG_RESET_PMIC_SXCBI 0x01000000 -#define SPC_REG_RESET_PMIC_CORE 0x02000000 -#define SPC_REG_RESET_PCIE_PC_SXCBI 0x04000000 -#define SPC_REG_RESET_DEVICE 0x80000000 - -/* registers for BAR Shifting - BAR2(0x18), BAR1(win) */ -#define SPCV_IBW_AXI_TRANSLATION_LOW 0x001010 - -#define MBIC_AAP1_ADDR_BASE 0x060000 -#define MBIC_IOP_ADDR_BASE 0x070000 -#define GSM_ADDR_BASE 0x0700000 -/* Dynamic map through Bar4 - 0x00700000 */ -#define GSM_CONFIG_RESET 0x00000000 -#define RAM_ECC_DB_ERR 0x00000018 -#define GSM_READ_ADDR_PARITY_INDIC 0x00000058 -#define GSM_WRITE_ADDR_PARITY_INDIC 0x00000060 -#define GSM_WRITE_DATA_PARITY_INDIC 0x00000068 -#define GSM_READ_ADDR_PARITY_CHECK 0x00000038 -#define GSM_WRITE_ADDR_PARITY_CHECK 0x00000040 -#define GSM_WRITE_DATA_PARITY_CHECK 0x00000048 - -#define RB6_ACCESS_REG 0x6A0000 -#define HDAC_EXEC_CMD 0x0002 -#define HDA_C_PA 0xcb -#define HDA_SEQ_ID_BITS 0x00ff0000 -#define HDA_GSM_OFFSET_BITS 0x00FFFFFF -#define HDA_GSM_CMD_OFFSET_BITS 0x42C0 -#define HDA_GSM_RSP_OFFSET_BITS 0x42E0 - -#define MBIC_AAP1_ADDR_BASE 0x060000 -#define MBIC_IOP_ADDR_BASE 0x070000 -#define GSM_ADDR_BASE 0x0700000 -#define SPC_TOP_LEVEL_ADDR_BASE 0x000000 -#define GSM_CONFIG_RESET_VALUE 0x00003b00 -#define GPIO_ADDR_BASE 0x00090000 -#define GPIO_GPIO_0_0UTPUT_CTL_OFFSET 0x0000010c - -/* RB6 offset */ -#define SPC_RB6_OFFSET 0x80C0 -/* Magic number of soft reset for RB6 */ -#define RB6_MAGIC_NUMBER_RST 0x1234 - -/* Device Register status */ -#define DEVREG_SUCCESS 0x00 -#define DEVREG_FAILURE_OUT_OF_RESOURCE 0x01 -#define DEVREG_FAILURE_DEVICE_ALREADY_REGISTERED 0x02 -#define DEVREG_FAILURE_INVALID_PHY_ID 0x03 -#define DEVREG_FAILURE_PHY_ID_ALREADY_REGISTERED 0x04 -#define DEVREG_FAILURE_PORT_ID_OUT_OF_RANGE 0x05 -#define DEVREG_FAILURE_PORT_NOT_VALID_STATE 0x06 -#define DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID 0x07 - -#endif diff --git a/trunk/drivers/scsi/qla2xxx/Kconfig b/trunk/drivers/scsi/qla2xxx/Kconfig index 23d607218ae8..317a7fdc3b82 100644 --- a/trunk/drivers/scsi/qla2xxx/Kconfig +++ b/trunk/drivers/scsi/qla2xxx/Kconfig @@ -24,9 +24,7 @@ config SCSI_QLA_FC Firmware images can be retrieved from: - http://ldriver.qlogic.com/firmware/ - - They are also included in the linux-firmware tree as well. + ftp://ftp.qlogic.com/outgoing/linux/firmware/ config TCM_QLA2XXX tristate "TCM_QLA2XXX fabric module for Qlogic 2xxx series target mode HBAs" diff --git a/trunk/drivers/scsi/qla2xxx/qla_mr.c b/trunk/drivers/scsi/qla2xxx/qla_mr.c index 937fed8cb038..729b74389f83 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mr.c @@ -3003,10 +3003,12 @@ qlafx00_build_scsi_iocbs(srb_t *sp, struct cmd_type_7_fx00 *cmd_pkt, /* Set transfer direction */ if (cmd->sc_data_direction == DMA_TO_DEVICE) { - lcmd_pkt->cntrl_flags = TMF_WRITE_DATA; + lcmd_pkt->cntrl_flags = + __constant_cpu_to_le16(TMF_WRITE_DATA); vha->qla_stats.output_bytes += scsi_bufflen(cmd); } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) { - lcmd_pkt->cntrl_flags = TMF_READ_DATA; + lcmd_pkt->cntrl_flags = + __constant_cpu_to_le16(TMF_READ_DATA); vha->qla_stats.input_bytes += scsi_bufflen(cmd); } diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index ad72c1d85111..5307bf86d5e0 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -644,7 +644,7 @@ qla2x00_sp_free_dma(void *vha, void *ptr) qla2x00_rel_sp(sp->fcport->vha, sp); } -static void +void qla2x00_sp_compl(void *data, void *ptr, int res) { struct qla_hw_data *ha = (struct qla_hw_data *)data; diff --git a/trunk/drivers/scsi/qla4xxx/ql4_iocb.c b/trunk/drivers/scsi/qla4xxx/ql4_iocb.c index fad71ed067ec..14fec976f634 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_iocb.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_iocb.c @@ -507,7 +507,6 @@ static int qla4xxx_send_mbox_iocb(struct scsi_qla_host *ha, struct mrb *mrb, mrb->mbox_cmd = in_mbox[0]; wmb(); - ha->iocb_cnt += mrb->iocb_cnt; ha->isp_ops->queue_iocb(ha); exit_mbox_iocb: spin_unlock_irqrestore(&ha->hardware_lock, flags); diff --git a/trunk/drivers/scsi/qla4xxx/ql4_os.c b/trunk/drivers/scsi/qla4xxx/ql4_os.c index 4d231c12463e..a47f99957ba8 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_os.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_os.c @@ -2216,14 +2216,14 @@ static int qla4xxx_copy_to_fwddb_param(struct iscsi_bus_flash_session *sess, fw_ddb_entry->iscsi_def_time2retain = cpu_to_le16(sess->time2retain); fw_ddb_entry->tgt_portal_grp = cpu_to_le16(sess->tpgt); fw_ddb_entry->mss = cpu_to_le16(conn->max_segment_size); - fw_ddb_entry->tcp_xmt_wsf = (uint8_t) cpu_to_le32(conn->tcp_xmit_wsf); - fw_ddb_entry->tcp_rcv_wsf = (uint8_t) cpu_to_le32(conn->tcp_recv_wsf); + fw_ddb_entry->tcp_xmt_wsf = cpu_to_le16(conn->tcp_xmit_wsf); + fw_ddb_entry->tcp_rcv_wsf = cpu_to_le16(conn->tcp_recv_wsf); fw_ddb_entry->ipv4_tos = conn->ipv4_tos; fw_ddb_entry->ipv6_flow_lbl = cpu_to_le16(conn->ipv6_flow_label); fw_ddb_entry->ka_timeout = cpu_to_le16(conn->keepalive_timeout); fw_ddb_entry->lcl_port = cpu_to_le16(conn->local_port); - fw_ddb_entry->stat_sn = cpu_to_le32(conn->statsn); - fw_ddb_entry->exp_stat_sn = cpu_to_le32(conn->exp_statsn); + fw_ddb_entry->stat_sn = cpu_to_le16(conn->statsn); + fw_ddb_entry->exp_stat_sn = cpu_to_le16(conn->exp_statsn); fw_ddb_entry->ddb_link = cpu_to_le16(sess->discovery_parent_type); fw_ddb_entry->chap_tbl_idx = cpu_to_le16(sess->chap_out_idx); fw_ddb_entry->tsid = cpu_to_le16(sess->tsid); @@ -5504,9 +5504,9 @@ static int qla4xxx_sysfs_ddb_is_non_persistent(struct device *dev, void *data) * If this is invoked as a result of a userspace call then the entry is marked * as nonpersistent using flash_state field. **/ -static int qla4xxx_sysfs_ddb_tgt_create(struct scsi_qla_host *ha, - struct dev_db_entry *fw_ddb_entry, - uint16_t *idx, int user) +int qla4xxx_sysfs_ddb_tgt_create(struct scsi_qla_host *ha, + struct dev_db_entry *fw_ddb_entry, + uint16_t *idx, int user) { struct iscsi_bus_flash_session *fnode_sess = NULL; struct iscsi_bus_flash_conn *fnode_conn = NULL; @@ -5605,7 +5605,6 @@ static int qla4xxx_sysfs_ddb_add(struct Scsi_Host *shost, const char *buf, ql4_printk(KERN_ERR, ha, "%s: A non-persistent entry %s found\n", __func__, dev->kobj.name); - put_device(dev); goto exit_ddb_add; } @@ -6113,7 +6112,8 @@ qla4xxx_sysfs_ddb_get_param(struct iscsi_bus_flash_session *fnode_sess, int parent_type, parent_index = 0xffff; int rc = 0; - dev = iscsi_find_flashnode_conn(fnode_sess); + dev = iscsi_find_flashnode_conn(fnode_sess, NULL, + iscsi_is_flashnode_conn_dev); if (!dev) return -EIO; @@ -6276,7 +6276,8 @@ qla4xxx_sysfs_ddb_get_param(struct iscsi_bus_flash_session *fnode_sess, rc = sprintf(buf, "\n"); break; case ISCSI_FLASHNODE_DISCOVERY_PARENT_IDX: - if (fnode_sess->discovery_parent_idx < MAX_DDB_ENTRIES) + if ((fnode_sess->discovery_parent_idx) >= 0 && + (fnode_sess->discovery_parent_idx < MAX_DDB_ENTRIES)) parent_index = fnode_sess->discovery_parent_idx; rc = sprintf(buf, "%u\n", parent_index); @@ -6286,7 +6287,8 @@ qla4xxx_sysfs_ddb_get_param(struct iscsi_bus_flash_session *fnode_sess, parent_type = ISCSI_DISC_PARENT_ISNS; else if (fnode_sess->discovery_parent_type == DDB_NO_LINK) parent_type = ISCSI_DISC_PARENT_UNKNOWN; - else if (fnode_sess->discovery_parent_type < MAX_DDB_ENTRIES) + else if (fnode_sess->discovery_parent_type >= 0 && + fnode_sess->discovery_parent_type < MAX_DDB_ENTRIES) parent_type = ISCSI_DISC_PARENT_SENDTGT; else parent_type = ISCSI_DISC_PARENT_UNKNOWN; @@ -6347,8 +6349,6 @@ qla4xxx_sysfs_ddb_get_param(struct iscsi_bus_flash_session *fnode_sess, rc = -ENOSYS; break; } - - put_device(dev); return rc; } @@ -6368,11 +6368,20 @@ qla4xxx_sysfs_ddb_set_param(struct iscsi_bus_flash_session *fnode_sess, { struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess); struct scsi_qla_host *ha = to_qla_host(shost); + struct dev_db_entry *fw_ddb_entry = NULL; struct iscsi_flashnode_param_info *fnode_param; struct nlattr *attr; int rc = QLA_ERROR; uint32_t rem = len; + fw_ddb_entry = kzalloc(sizeof(*fw_ddb_entry), GFP_KERNEL); + if (!fw_ddb_entry) { + DEBUG2(ql4_printk(KERN_ERR, ha, + "%s: Unable to allocate ddb buffer\n", + __func__)); + return -ENOMEM; + } + nla_for_each_attr(attr, data, len, rem) { fnode_param = nla_data(attr); @@ -6581,11 +6590,16 @@ static int qla4xxx_sysfs_ddb_delete(struct iscsi_bus_flash_session *fnode_sess) struct dev_db_entry *fw_ddb_entry = NULL; dma_addr_t fw_ddb_entry_dma; uint16_t *ddb_cookie = NULL; - size_t ddb_size = 0; + size_t ddb_size; void *pddb = NULL; int target_id; int rc = 0; + if (!fnode_sess) { + rc = -EINVAL; + goto exit_ddb_del; + } + if (fnode_sess->is_boot_target) { rc = -EPERM; DEBUG2(ql4_printk(KERN_ERR, ha, @@ -6617,7 +6631,8 @@ static int qla4xxx_sysfs_ddb_delete(struct iscsi_bus_flash_session *fnode_sess) dev_db_start_offset += (fnode_sess->target_id * sizeof(*fw_ddb_entry)); - dev_db_start_offset += offsetof(struct dev_db_entry, cookie); + dev_db_start_offset += (void *)&(fw_ddb_entry->cookie) - + (void *)fw_ddb_entry; ddb_size = sizeof(*ddb_cookie); } diff --git a/trunk/drivers/scsi/qla4xxx/ql4_version.h b/trunk/drivers/scsi/qla4xxx/ql4_version.h index fe873cf7570d..83e0fec35d56 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_version.h +++ b/trunk/drivers/scsi/qla4xxx/ql4_version.h @@ -5,4 +5,4 @@ * See LICENSE.qla4xxx for copyright and licensing details. */ -#define QLA4XXX_DRIVER_VERSION "5.03.00-k9" +#define QLA4XXX_DRIVER_VERSION "5.03.00-k8" diff --git a/trunk/drivers/scsi/scsi_debug.c b/trunk/drivers/scsi/scsi_debug.c index 0a537a0515ca..5add6f4e7928 100644 --- a/trunk/drivers/scsi/scsi_debug.c +++ b/trunk/drivers/scsi/scsi_debug.c @@ -1997,39 +1997,24 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, return ret; } -static unsigned long lba_to_map_index(sector_t lba) -{ - if (scsi_debug_unmap_alignment) { - lba += scsi_debug_unmap_granularity - - scsi_debug_unmap_alignment; - } - do_div(lba, scsi_debug_unmap_granularity); - - return lba; -} - -static sector_t map_index_to_lba(unsigned long index) -{ - return index * scsi_debug_unmap_granularity - - scsi_debug_unmap_alignment; -} - static unsigned int map_state(sector_t lba, unsigned int *num) { - sector_t end; - unsigned int mapped; - unsigned long index; - unsigned long next; + unsigned int granularity, alignment, mapped; + sector_t block, next, end; + + granularity = scsi_debug_unmap_granularity; + alignment = granularity - scsi_debug_unmap_alignment; + block = lba + alignment; + do_div(block, granularity); - index = lba_to_map_index(lba); - mapped = test_bit(index, map_storep); + mapped = test_bit(block, map_storep); if (mapped) - next = find_next_zero_bit(map_storep, map_size, index); + next = find_next_zero_bit(map_storep, map_size, block); else - next = find_next_bit(map_storep, map_size, index); + next = find_next_bit(map_storep, map_size, block); - end = min_t(sector_t, sdebug_store_sectors, map_index_to_lba(next)); + end = next * granularity - scsi_debug_unmap_alignment; *num = end - lba; return mapped; @@ -2037,37 +2022,47 @@ static unsigned int map_state(sector_t lba, unsigned int *num) static void map_region(sector_t lba, unsigned int len) { + unsigned int granularity, alignment; sector_t end = lba + len; + granularity = scsi_debug_unmap_granularity; + alignment = granularity - scsi_debug_unmap_alignment; + while (lba < end) { - unsigned long index = lba_to_map_index(lba); + sector_t block, rem; + + block = lba + alignment; + rem = do_div(block, granularity); - if (index < map_size) - set_bit(index, map_storep); + if (block < map_size) + set_bit(block, map_storep); - lba = map_index_to_lba(index + 1); + lba += granularity - rem; } } static void unmap_region(sector_t lba, unsigned int len) { + unsigned int granularity, alignment; sector_t end = lba + len; + granularity = scsi_debug_unmap_granularity; + alignment = granularity - scsi_debug_unmap_alignment; + while (lba < end) { - unsigned long index = lba_to_map_index(lba); + sector_t block, rem; + + block = lba + alignment; + rem = do_div(block, granularity); - if (lba == map_index_to_lba(index) && - lba + scsi_debug_unmap_granularity <= end && - index < map_size) { - clear_bit(index, map_storep); - if (scsi_debug_lbprz) { + if (rem == 0 && lba + granularity < end && block < map_size) { + clear_bit(block, map_storep); + if (scsi_debug_lbprz) memset(fake_storep + - lba * scsi_debug_sector_size, 0, - scsi_debug_sector_size * - scsi_debug_unmap_granularity); - } + block * scsi_debug_sector_size, 0, + scsi_debug_sector_size); } - lba = map_index_to_lba(index + 1); + lba += granularity - rem; } } @@ -2094,7 +2089,7 @@ static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba, write_lock_irqsave(&atomic_rw, iflags); ret = do_device_access(SCpnt, devip, lba, num, 1); - if (scsi_debug_lbp()) + if (scsi_debug_unmap_granularity) map_region(lba, num); write_unlock_irqrestore(&atomic_rw, iflags); if (-1 == ret) @@ -2127,7 +2122,7 @@ static int resp_write_same(struct scsi_cmnd *scmd, unsigned long long lba, write_lock_irqsave(&atomic_rw, iflags); - if (unmap && scsi_debug_lbp()) { + if (unmap && scsi_debug_unmap_granularity) { unmap_region(lba, num); goto out; } @@ -2151,7 +2146,7 @@ static int resp_write_same(struct scsi_cmnd *scmd, unsigned long long lba, fake_storep + (lba * scsi_debug_sector_size), scsi_debug_sector_size); - if (scsi_debug_lbp()) + if (scsi_debug_unmap_granularity) map_region(lba, num); out: write_unlock_irqrestore(&atomic_rw, iflags); @@ -3394,6 +3389,8 @@ static int __init scsi_debug_init(void) /* Logical Block Provisioning */ if (scsi_debug_lbp()) { + unsigned int map_bytes; + scsi_debug_unmap_max_blocks = clamp(scsi_debug_unmap_max_blocks, 0U, 0xffffffffU); @@ -3404,16 +3401,16 @@ static int __init scsi_debug_init(void) clamp(scsi_debug_unmap_granularity, 1U, 0xffffffffU); if (scsi_debug_unmap_alignment && - scsi_debug_unmap_granularity <= - scsi_debug_unmap_alignment) { + scsi_debug_unmap_granularity < scsi_debug_unmap_alignment) { printk(KERN_ERR - "%s: ERR: unmap_granularity <= unmap_alignment\n", + "%s: ERR: unmap_granularity < unmap_alignment\n", __func__); return -EINVAL; } - map_size = lba_to_map_index(sdebug_store_sectors - 1) + 1; - map_storep = vmalloc(BITS_TO_LONGS(map_size) * sizeof(long)); + map_size = (sdebug_store_sectors / scsi_debug_unmap_granularity); + map_bytes = map_size >> 3; + map_storep = vmalloc(map_bytes); printk(KERN_INFO "scsi_debug_init: %lu provisioning blocks\n", map_size); @@ -3424,7 +3421,7 @@ static int __init scsi_debug_init(void) goto free_vm; } - bitmap_zero(map_storep, map_size); + memset(map_storep, 0x0, map_bytes); /* Map first 1KB for partition table */ if (scsi_debug_num_parts) diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c index f43de1e56420..c1b05a83d403 100644 --- a/trunk/drivers/scsi/scsi_error.c +++ b/trunk/drivers/scsi/scsi_error.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -792,48 +791,32 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, struct scsi_device *sdev = scmd->device; struct Scsi_Host *shost = sdev->host; DECLARE_COMPLETION_ONSTACK(done); - unsigned long timeleft = timeout; + unsigned long timeleft; struct scsi_eh_save ses; - const unsigned long stall_for = msecs_to_jiffies(100); int rtn; -retry: scsi_eh_prep_cmnd(scmd, &ses, cmnd, cmnd_size, sense_bytes); shost->eh_action = &done; scsi_log_send(scmd); scmd->scsi_done = scsi_eh_done; - rtn = shost->hostt->queuecommand(shost, scmd); - if (rtn) { - if (timeleft > stall_for) { - scsi_eh_restore_cmnd(scmd, &ses); - timeleft -= stall_for; - msleep(jiffies_to_msecs(stall_for)); - goto retry; - } - /* signal not to enter either branch of the if () below */ - timeleft = 0; - rtn = NEEDS_RETRY; - } else { - timeleft = wait_for_completion_timeout(&done, timeout); - } + shost->hostt->queuecommand(shost, scmd); + + timeleft = wait_for_completion_timeout(&done, timeout); shost->eh_action = NULL; - scsi_log_completion(scmd, rtn); + scsi_log_completion(scmd, SUCCESS); SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd: %p, timeleft: %ld\n", __func__, scmd, timeleft)); /* - * If there is time left scsi_eh_done got called, and we will examine - * the actual status codes to see whether the command actually did - * complete normally, else if we have a zero return and no time left, - * the command must still be pending, so abort it and return FAILED. - * If we never actually managed to issue the command, because - * ->queuecommand() kept returning non zero, use the rtn = FAILED - * value above (so don't execute either branch of the if) + * If there is time left scsi_eh_done got called, and we will + * examine the actual status codes to see whether the command + * actually did complete normally, else tell the host to forget + * about this command. */ if (timeleft) { rtn = scsi_eh_completed_normally(scmd); @@ -854,7 +837,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, rtn = FAILED; break; } - } else if (!rtn) { + } else { scsi_abort_eh_cmnd(scmd); rtn = FAILED; } diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 86d522004a20..c31187d79343 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -276,10 +276,11 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, } EXPORT_SYMBOL(scsi_execute); -int scsi_execute_req_flags(struct scsi_device *sdev, const unsigned char *cmd, + +int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, int data_direction, void *buffer, unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout, int retries, - int *resid, int flags) + int *resid) { char *sense = NULL; int result; @@ -290,14 +291,14 @@ int scsi_execute_req_flags(struct scsi_device *sdev, const unsigned char *cmd, return DRIVER_ERROR << 24; } result = scsi_execute(sdev, cmd, data_direction, buffer, bufflen, - sense, timeout, retries, flags, resid); + sense, timeout, retries, 0, resid); if (sshdr) scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, sshdr); kfree(sense); return result; } -EXPORT_SYMBOL(scsi_execute_req_flags); +EXPORT_SYMBOL(scsi_execute_req); /* * Function: scsi_init_cmd_errh() diff --git a/trunk/drivers/scsi/scsi_pm.c b/trunk/drivers/scsi/scsi_pm.c index 42539ee2cb11..8f6b12cbd224 100644 --- a/trunk/drivers/scsi/scsi_pm.c +++ b/trunk/drivers/scsi/scsi_pm.c @@ -144,83 +144,33 @@ static int scsi_bus_restore(struct device *dev) #ifdef CONFIG_PM_RUNTIME -static int sdev_blk_runtime_suspend(struct scsi_device *sdev, - int (*cb)(struct device *)) -{ - int err; - - err = blk_pre_runtime_suspend(sdev->request_queue); - if (err) - return err; - if (cb) - err = cb(&sdev->sdev_gendev); - blk_post_runtime_suspend(sdev->request_queue, err); - - return err; -} - -static int sdev_runtime_suspend(struct device *dev) -{ - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - int (*cb)(struct device *) = pm ? pm->runtime_suspend : NULL; - struct scsi_device *sdev = to_scsi_device(dev); - int err; - - if (sdev->request_queue->dev) - return sdev_blk_runtime_suspend(sdev, cb); - - err = scsi_dev_type_suspend(dev, cb); - if (err == -EAGAIN) - pm_schedule_suspend(dev, jiffies_to_msecs( - round_jiffies_up_relative(HZ/10))); - return err; -} - static int scsi_runtime_suspend(struct device *dev) { int err = 0; + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; dev_dbg(dev, "scsi_runtime_suspend\n"); - if (scsi_is_sdev_device(dev)) - err = sdev_runtime_suspend(dev); + if (scsi_is_sdev_device(dev)) { + err = scsi_dev_type_suspend(dev, + pm ? pm->runtime_suspend : NULL); + if (err == -EAGAIN) + pm_schedule_suspend(dev, jiffies_to_msecs( + round_jiffies_up_relative(HZ/10))); + } /* Insert hooks here for targets, hosts, and transport classes */ return err; } -static int sdev_blk_runtime_resume(struct scsi_device *sdev, - int (*cb)(struct device *)) -{ - int err = 0; - - blk_pre_runtime_resume(sdev->request_queue); - if (cb) - err = cb(&sdev->sdev_gendev); - blk_post_runtime_resume(sdev->request_queue, err); - - return err; -} - -static int sdev_runtime_resume(struct device *dev) -{ - struct scsi_device *sdev = to_scsi_device(dev); - const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - int (*cb)(struct device *) = pm ? pm->runtime_resume : NULL; - - if (sdev->request_queue->dev) - return sdev_blk_runtime_resume(sdev, cb); - else - return scsi_dev_type_resume(dev, cb); -} - static int scsi_runtime_resume(struct device *dev) { int err = 0; + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; dev_dbg(dev, "scsi_runtime_resume\n"); if (scsi_is_sdev_device(dev)) - err = sdev_runtime_resume(dev); + err = scsi_dev_type_resume(dev, pm ? pm->runtime_resume : NULL); /* Insert hooks here for targets, hosts, and transport classes */ @@ -235,18 +185,10 @@ static int scsi_runtime_idle(struct device *dev) /* Insert hooks here for targets, hosts, and transport classes */ - if (scsi_is_sdev_device(dev)) { - struct scsi_device *sdev = to_scsi_device(dev); - - if (sdev->request_queue->dev) { - pm_runtime_mark_last_busy(dev); - err = pm_runtime_autosuspend(dev); - } else { - err = pm_runtime_suspend(dev); - } - } else { + if (scsi_is_sdev_device(dev)) + err = pm_schedule_suspend(dev, 100); + else err = pm_runtime_suspend(dev); - } return err; } diff --git a/trunk/drivers/scsi/scsi_transport_iscsi.c b/trunk/drivers/scsi/scsi_transport_iscsi.c index 133926b1bb78..47799a33d6ca 100644 --- a/trunk/drivers/scsi/scsi_transport_iscsi.c +++ b/trunk/drivers/scsi/scsi_transport_iscsi.c @@ -1019,7 +1019,8 @@ static int flashnode_match_index(struct device *dev, void *data) /** * iscsi_get_flashnode_by_index -finds flashnode session entry by index * @shost: pointer to host data - * @idx: index to match + * @data: pointer to data containing value to use for comparison + * @fn: function pointer that does actual comparison * * Finds the flashnode session object for the passed index * @@ -1028,13 +1029,13 @@ static int flashnode_match_index(struct device *dev, void *data) * %NULL on failure */ static struct iscsi_bus_flash_session * -iscsi_get_flashnode_by_index(struct Scsi_Host *shost, uint32_t idx) +iscsi_get_flashnode_by_index(struct Scsi_Host *shost, void *data, + int (*fn)(struct device *dev, void *data)) { struct iscsi_bus_flash_session *fnode_sess = NULL; struct device *dev; - dev = device_find_child(&shost->shost_gendev, &idx, - flashnode_match_index); + dev = device_find_child(&shost->shost_gendev, data, fn); if (dev) fnode_sess = iscsi_dev_to_flash_session(dev); @@ -1058,13 +1059,18 @@ struct device * iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data, int (*fn)(struct device *dev, void *data)) { - return device_find_child(&shost->shost_gendev, data, fn); + struct device *dev; + + dev = device_find_child(&shost->shost_gendev, data, fn); + return dev; } EXPORT_SYMBOL_GPL(iscsi_find_flashnode_sess); /** * iscsi_find_flashnode_conn - finds flashnode connection entry * @fnode_sess: pointer to parent flashnode session entry + * @data: pointer to data containing value to use for comparison + * @fn: function pointer that does actual comparison * * Finds the flashnode connection object comparing the data passed using logic * defined in passed function pointer @@ -1074,10 +1080,14 @@ EXPORT_SYMBOL_GPL(iscsi_find_flashnode_sess); * %NULL on failure */ struct device * -iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess) +iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess, + void *data, + int (*fn)(struct device *dev, void *data)) { - return device_find_child(&fnode_sess->dev, NULL, - iscsi_is_flashnode_conn_dev); + struct device *dev; + + dev = device_find_child(&fnode_sess->dev, data, fn); + return dev; } EXPORT_SYMBOL_GPL(iscsi_find_flashnode_conn); @@ -2798,7 +2808,7 @@ static int iscsi_set_flashnode_param(struct iscsi_transport *transport, struct iscsi_bus_flash_session *fnode_sess; struct iscsi_bus_flash_conn *fnode_conn; struct device *dev; - uint32_t idx; + uint32_t *idx; int err = 0; if (!transport->set_flashnode_param) { @@ -2814,27 +2824,25 @@ static int iscsi_set_flashnode_param(struct iscsi_transport *transport, goto put_host; } - idx = ev->u.set_flashnode.flashnode_idx; - fnode_sess = iscsi_get_flashnode_by_index(shost, idx); + idx = &ev->u.set_flashnode.flashnode_idx; + fnode_sess = iscsi_get_flashnode_by_index(shost, idx, + flashnode_match_index); if (!fnode_sess) { pr_err("%s could not find flashnode %u for host no %u\n", - __func__, idx, ev->u.set_flashnode.host_no); + __func__, *idx, ev->u.set_flashnode.host_no); err = -ENODEV; goto put_host; } - dev = iscsi_find_flashnode_conn(fnode_sess); + dev = iscsi_find_flashnode_conn(fnode_sess, NULL, + iscsi_is_flashnode_conn_dev); if (!dev) { err = -ENODEV; - goto put_sess; + goto put_host; } fnode_conn = iscsi_dev_to_flash_conn(dev); err = transport->set_flashnode_param(fnode_sess, fnode_conn, data, len); - put_device(dev); - -put_sess: - put_device(&fnode_sess->dev); put_host: scsi_host_put(shost); @@ -2883,7 +2891,7 @@ static int iscsi_del_flashnode(struct iscsi_transport *transport, { struct Scsi_Host *shost; struct iscsi_bus_flash_session *fnode_sess; - uint32_t idx; + uint32_t *idx; int err = 0; if (!transport->del_flashnode) { @@ -2899,17 +2907,17 @@ static int iscsi_del_flashnode(struct iscsi_transport *transport, goto put_host; } - idx = ev->u.del_flashnode.flashnode_idx; - fnode_sess = iscsi_get_flashnode_by_index(shost, idx); + idx = &ev->u.del_flashnode.flashnode_idx; + fnode_sess = iscsi_get_flashnode_by_index(shost, idx, + flashnode_match_index); if (!fnode_sess) { pr_err("%s could not find flashnode %u for host no %u\n", - __func__, idx, ev->u.del_flashnode.host_no); + __func__, *idx, ev->u.del_flashnode.host_no); err = -ENODEV; goto put_host; } err = transport->del_flashnode(fnode_sess); - put_device(&fnode_sess->dev); put_host: scsi_host_put(shost); @@ -2925,7 +2933,7 @@ static int iscsi_login_flashnode(struct iscsi_transport *transport, struct iscsi_bus_flash_session *fnode_sess; struct iscsi_bus_flash_conn *fnode_conn; struct device *dev; - uint32_t idx; + uint32_t *idx; int err = 0; if (!transport->login_flashnode) { @@ -2941,27 +2949,25 @@ static int iscsi_login_flashnode(struct iscsi_transport *transport, goto put_host; } - idx = ev->u.login_flashnode.flashnode_idx; - fnode_sess = iscsi_get_flashnode_by_index(shost, idx); + idx = &ev->u.login_flashnode.flashnode_idx; + fnode_sess = iscsi_get_flashnode_by_index(shost, idx, + flashnode_match_index); if (!fnode_sess) { pr_err("%s could not find flashnode %u for host no %u\n", - __func__, idx, ev->u.login_flashnode.host_no); + __func__, *idx, ev->u.login_flashnode.host_no); err = -ENODEV; goto put_host; } - dev = iscsi_find_flashnode_conn(fnode_sess); + dev = iscsi_find_flashnode_conn(fnode_sess, NULL, + iscsi_is_flashnode_conn_dev); if (!dev) { err = -ENODEV; - goto put_sess; + goto put_host; } fnode_conn = iscsi_dev_to_flash_conn(dev); err = transport->login_flashnode(fnode_sess, fnode_conn); - put_device(dev); - -put_sess: - put_device(&fnode_sess->dev); put_host: scsi_host_put(shost); @@ -2977,7 +2983,7 @@ static int iscsi_logout_flashnode(struct iscsi_transport *transport, struct iscsi_bus_flash_session *fnode_sess; struct iscsi_bus_flash_conn *fnode_conn; struct device *dev; - uint32_t idx; + uint32_t *idx; int err = 0; if (!transport->logout_flashnode) { @@ -2993,28 +2999,26 @@ static int iscsi_logout_flashnode(struct iscsi_transport *transport, goto put_host; } - idx = ev->u.logout_flashnode.flashnode_idx; - fnode_sess = iscsi_get_flashnode_by_index(shost, idx); + idx = &ev->u.logout_flashnode.flashnode_idx; + fnode_sess = iscsi_get_flashnode_by_index(shost, idx, + flashnode_match_index); if (!fnode_sess) { pr_err("%s could not find flashnode %u for host no %u\n", - __func__, idx, ev->u.logout_flashnode.host_no); + __func__, *idx, ev->u.logout_flashnode.host_no); err = -ENODEV; goto put_host; } - dev = iscsi_find_flashnode_conn(fnode_sess); + dev = iscsi_find_flashnode_conn(fnode_sess, NULL, + iscsi_is_flashnode_conn_dev); if (!dev) { err = -ENODEV; - goto put_sess; + goto put_host; } fnode_conn = iscsi_dev_to_flash_conn(dev); err = transport->logout_flashnode(fnode_sess, fnode_conn); - put_device(dev); - -put_sess: - put_device(&fnode_sess->dev); put_host: scsi_host_put(shost); @@ -3981,10 +3985,8 @@ static __init int iscsi_transport_init(void) } iscsi_eh_timer_workq = create_singlethread_workqueue("iscsi_eh"); - if (!iscsi_eh_timer_workq) { - err = -ENOMEM; + if (!iscsi_eh_timer_workq) goto release_nls; - } return 0; diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index c1c555242d0d..e6689776b4f6 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -142,7 +142,6 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, char *buffer_data; struct scsi_mode_data data; struct scsi_sense_hdr sshdr; - const char *temp = "temporary "; int len; if (sdp->type != TYPE_DISK) @@ -151,13 +150,6 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, * it's not worth the risk */ return -EINVAL; - if (strncmp(buf, temp, sizeof(temp) - 1) == 0) { - buf += sizeof(temp) - 1; - sdkp->cache_override = 1; - } else { - sdkp->cache_override = 0; - } - for (i = 0; i < ARRAY_SIZE(sd_cache_types); i++) { len = strlen(sd_cache_types[i]); if (strncmp(sd_cache_types[i], buf, len) == 0 && @@ -170,13 +162,6 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, return -EINVAL; rcd = ct & 0x01 ? 1 : 0; wce = ct & 0x02 ? 1 : 0; - - if (sdkp->cache_override) { - sdkp->WCE = wce; - sdkp->RCD = rcd; - return count; - } - if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), SD_TIMEOUT, SD_MAX_RETRIES, &data, NULL)) return -EINVAL; @@ -1136,6 +1121,10 @@ static int sd_open(struct block_device *bdev, fmode_t mode) sdev = sdkp->device; + retval = scsi_autopm_get_device(sdev); + if (retval) + goto error_autopm; + /* * If the device is in error recovery, wait until it is done. * If the device is offline, then disallow any access to it. @@ -1180,6 +1169,8 @@ static int sd_open(struct block_device *bdev, fmode_t mode) return 0; error_out: + scsi_autopm_put_device(sdev); +error_autopm: scsi_disk_put(sdkp); return retval; } @@ -1214,6 +1205,7 @@ static void sd_release(struct gendisk *disk, fmode_t mode) * XXX is followed by a "rmmod sd_mod"? */ + scsi_autopm_put_device(sdev); scsi_disk_put(sdkp); } @@ -1374,9 +1366,14 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing) retval = -ENODEV; if (scsi_block_when_processing_errors(sdp)) { + retval = scsi_autopm_get_device(sdp); + if (retval) + goto out; + sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL); retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES, sshdr); + scsi_autopm_put_device(sdp); } /* failed to execute TUR, assume media not present */ @@ -1426,9 +1423,8 @@ static int sd_sync_cache(struct scsi_disk *sdkp) * Leave the rest of the command zero to indicate * flush everything. */ - res = scsi_execute_req_flags(sdp, cmd, DMA_NONE, NULL, 0, - &sshdr, SD_FLUSH_TIMEOUT, - SD_MAX_RETRIES, NULL, REQ_PM); + res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr, + SD_FLUSH_TIMEOUT, SD_MAX_RETRIES, NULL); if (res == 0) break; } @@ -2322,10 +2318,6 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) int old_rcd = sdkp->RCD; int old_dpofua = sdkp->DPOFUA; - - if (sdkp->cache_override) - return; - first_len = 4; if (sdp->skip_ms_page_8) { if (sdp->type == TYPE_RBC) @@ -2819,7 +2811,6 @@ static void sd_probe_async(void *data, async_cookie_t cookie) sdkp->capacity = 0; sdkp->media_present = 1; sdkp->write_prot = 0; - sdkp->cache_override = 0; sdkp->WCE = 0; sdkp->RCD = 0; sdkp->ATO = 0; @@ -2846,7 +2837,6 @@ static void sd_probe_async(void *data, async_cookie_t cookie) sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", sdp->removable ? "removable " : ""); - blk_pm_runtime_init(sdp->request_queue, dev); scsi_autopm_put_device(sdp); put_device(&sdkp->dev); } @@ -3030,8 +3020,8 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start) if (!scsi_device_online(sdp)) return -ENODEV; - res = scsi_execute_req_flags(sdp, cmd, DMA_NONE, NULL, 0, &sshdr, - SD_TIMEOUT, SD_MAX_RETRIES, NULL, REQ_PM); + res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr, + SD_TIMEOUT, SD_MAX_RETRIES, NULL); if (res) { sd_printk(KERN_WARNING, sdkp, "START_STOP FAILED\n"); sd_print_result(sdkp, res); diff --git a/trunk/drivers/scsi/sd.h b/trunk/drivers/scsi/sd.h index 2386aeb41fe8..74a1e4ca5401 100644 --- a/trunk/drivers/scsi/sd.h +++ b/trunk/drivers/scsi/sd.h @@ -73,7 +73,6 @@ struct scsi_disk { u8 protection_type;/* Data Integrity Field */ u8 provisioning_mode; unsigned ATO : 1; /* state of disk ATO bit */ - unsigned cache_override : 1; /* temp override of WCE,RCD */ unsigned WCE : 1; /* state of disk WCE bit */ unsigned RCD : 1; /* state of disk RCD bit, unused */ unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ diff --git a/trunk/drivers/scsi/sd_dif.c b/trunk/drivers/scsi/sd_dif.c index 6174ca4ea275..04998f36e507 100644 --- a/trunk/drivers/scsi/sd_dif.c +++ b/trunk/drivers/scsi/sd_dif.c @@ -93,6 +93,14 @@ static int sd_dif_type1_verify(struct blk_integrity_exchg *bix, csum_fn *fn) if (sdt->app_tag == 0xffff) return 0; + /* Bad ref tag received from disk */ + if (sdt->ref_tag == 0xffffffff) { + printk(KERN_ERR + "%s: bad phys ref tag on sector %lu\n", + bix->disk_name, (unsigned long)sector); + return -EIO; + } + if (be32_to_cpu(sdt->ref_tag) != (sector & 0xffffffff)) { printk(KERN_ERR "%s: ref tag error on sector %lu (rcvd %u)\n", diff --git a/trunk/drivers/scsi/ufs/Kconfig b/trunk/drivers/scsi/ufs/Kconfig index 35faf24c6044..0371047c5922 100644 --- a/trunk/drivers/scsi/ufs/Kconfig +++ b/trunk/drivers/scsi/ufs/Kconfig @@ -57,14 +57,3 @@ config SCSI_UFSHCD_PCI If you have a controller with this interface, say Y or M here. If unsure, say N. - -config SCSI_UFSHCD_PLATFORM - tristate "Platform bus based UFS Controller support" - depends on SCSI_UFSHCD - ---help--- - This selects the UFS host controller support. Select this if - you have an UFS controller on Platform bus. - - If you have a controller with this interface, say Y or M here. - - If unsure, say N. diff --git a/trunk/drivers/scsi/ufs/Makefile b/trunk/drivers/scsi/ufs/Makefile index 1e5bd48457d6..9eda0dfbd6df 100644 --- a/trunk/drivers/scsi/ufs/Makefile +++ b/trunk/drivers/scsi/ufs/Makefile @@ -1,4 +1,3 @@ # UFSHCD makefile obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o -obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o diff --git a/trunk/drivers/scsi/ufs/ufshcd-pltfrm.c b/trunk/drivers/scsi/ufs/ufshcd-pltfrm.c deleted file mode 100644 index 03319acd9c72..000000000000 --- a/trunk/drivers/scsi/ufs/ufshcd-pltfrm.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Universal Flash Storage Host controller Platform bus based glue driver - * - * This code is based on drivers/scsi/ufs/ufshcd-pltfrm.c - * Copyright (C) 2011-2013 Samsung India Software Operations - * - * Authors: - * Santosh Yaraganavi - * Vinayak Holikatti - * - * 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 - * of the License, or (at your option) any later version. - * See the COPYING file in the top-level directory or visit - * - * - * 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. - * - * This program is provided "AS IS" and "WITH ALL FAULTS" and - * without warranty of any kind. You are solely responsible for - * determining the appropriateness of using and distributing - * the program and assume all risks associated with your exercise - * of rights with respect to the program, including but not limited - * to infringement of third party rights, the risks and costs of - * program errors, damage to or loss of data, programs or equipment, - * and unavailability or interruption of operations. Under no - * circumstances will the contributor of this Program be liable for - * any damages of any kind arising from your use or distribution of - * this program. - */ - -#include "ufshcd.h" -#include - -#ifdef CONFIG_PM -/** - * ufshcd_pltfrm_suspend - suspend power management function - * @dev: pointer to device handle - * - * - * Returns 0 - */ -static int ufshcd_pltfrm_suspend(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct ufs_hba *hba = platform_get_drvdata(pdev); - - /* - * TODO: - * 1. Call ufshcd_suspend - * 2. Do bus specific power management - */ - - disable_irq(hba->irq); - - return 0; -} - -/** - * ufshcd_pltfrm_resume - resume power management function - * @dev: pointer to device handle - * - * Returns 0 - */ -static int ufshcd_pltfrm_resume(struct device *dev) -{ - struct platform_device *pdev = to_platform_device(dev); - struct ufs_hba *hba = platform_get_drvdata(pdev); - - /* - * TODO: - * 1. Call ufshcd_resume. - * 2. Do bus specific wake up - */ - - enable_irq(hba->irq); - - return 0; -} -#else -#define ufshcd_pltfrm_suspend NULL -#define ufshcd_pltfrm_resume NULL -#endif - -/** - * ufshcd_pltfrm_probe - probe routine of the driver - * @pdev: pointer to Platform device handle - * - * Returns 0 on success, non-zero value on failure - */ -static int ufshcd_pltfrm_probe(struct platform_device *pdev) -{ - struct ufs_hba *hba; - void __iomem *mmio_base; - struct resource *mem_res; - struct resource *irq_res; - resource_size_t mem_size; - int err; - struct device *dev = &pdev->dev; - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem_res) { - dev_err(&pdev->dev, - "Memory resource not available\n"); - err = -ENODEV; - goto out_error; - } - - mem_size = resource_size(mem_res); - if (!request_mem_region(mem_res->start, mem_size, "ufshcd")) { - dev_err(&pdev->dev, - "Cannot reserve the memory resource\n"); - err = -EBUSY; - goto out_error; - } - - mmio_base = ioremap_nocache(mem_res->start, mem_size); - if (!mmio_base) { - dev_err(&pdev->dev, "memory map failed\n"); - err = -ENOMEM; - goto out_release_regions; - } - - irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!irq_res) { - dev_err(&pdev->dev, "IRQ resource not available\n"); - err = -ENODEV; - goto out_iounmap; - } - - err = dma_set_coherent_mask(dev, dev->coherent_dma_mask); - if (err) { - dev_err(&pdev->dev, "set dma mask failed\n"); - goto out_iounmap; - } - - err = ufshcd_init(&pdev->dev, &hba, mmio_base, irq_res->start); - if (err) { - dev_err(&pdev->dev, "Intialization failed\n"); - goto out_iounmap; - } - - platform_set_drvdata(pdev, hba); - - return 0; - -out_iounmap: - iounmap(mmio_base); -out_release_regions: - release_mem_region(mem_res->start, mem_size); -out_error: - return err; -} - -/** - * ufshcd_pltfrm_remove - remove platform driver routine - * @pdev: pointer to platform device handle - * - * Returns 0 on success, non-zero value on failure - */ -static int ufshcd_pltfrm_remove(struct platform_device *pdev) -{ - struct resource *mem_res; - resource_size_t mem_size; - struct ufs_hba *hba = platform_get_drvdata(pdev); - - disable_irq(hba->irq); - - /* Some buggy controllers raise interrupt after - * the resources are removed. So first we unregister the - * irq handler and then the resources used by driver - */ - - free_irq(hba->irq, hba); - ufshcd_remove(hba); - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem_res) - dev_err(&pdev->dev, "ufshcd: Memory resource not available\n"); - else { - mem_size = resource_size(mem_res); - release_mem_region(mem_res->start, mem_size); - } - platform_set_drvdata(pdev, NULL); - return 0; -} - -static const struct of_device_id ufs_of_match[] = { - { .compatible = "jedec,ufs-1.1"}, -}; - -static const struct dev_pm_ops ufshcd_dev_pm_ops = { - .suspend = ufshcd_pltfrm_suspend, - .resume = ufshcd_pltfrm_resume, -}; - -static struct platform_driver ufshcd_pltfrm_driver = { - .probe = ufshcd_pltfrm_probe, - .remove = ufshcd_pltfrm_remove, - .driver = { - .name = "ufshcd", - .owner = THIS_MODULE, - .pm = &ufshcd_dev_pm_ops, - .of_match_table = ufs_of_match, - }, -}; - -module_platform_driver(ufshcd_pltfrm_driver); - -MODULE_AUTHOR("Santosh Yaragnavi "); -MODULE_AUTHOR("Vinayak Holikatti "); -MODULE_DESCRIPTION("UFS host controller Pltform bus based glue driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(UFSHCD_DRIVER_VERSION); diff --git a/trunk/drivers/scsi/ufs/ufshcd.c b/trunk/drivers/scsi/ufs/ufshcd.c index c32a478df81b..60fd40c4e4c2 100644 --- a/trunk/drivers/scsi/ufs/ufshcd.c +++ b/trunk/drivers/scsi/ufs/ufshcd.c @@ -478,7 +478,7 @@ static void ufshcd_compose_upiu(struct ufshcd_lrb *lrbp) ucd_cmd_ptr->header.dword_2 = 0; ucd_cmd_ptr->exp_data_transfer_len = - cpu_to_be32(lrbp->cmd->sdb.length); + cpu_to_be32(lrbp->cmd->transfersize); memcpy(ucd_cmd_ptr->cdb, lrbp->cmd->cmnd, diff --git a/trunk/drivers/spi/spi-atmel.c b/trunk/drivers/spi/spi-atmel.c index 380387a47b1d..787bd2c22bca 100644 --- a/trunk/drivers/spi/spi-atmel.c +++ b/trunk/drivers/spi/spi-atmel.c @@ -526,17 +526,13 @@ static void atmel_spi_next_xfer_pio(struct spi_master *master, } if (xfer->tx_buf) - if (xfer->bits_per_word > 8) - spi_writel(as, TDR, *(u16 *)(xfer->tx_buf)); - else - spi_writel(as, TDR, *(u8 *)(xfer->tx_buf)); + spi_writel(as, TDR, *(u8 *)(xfer->tx_buf)); else spi_writel(as, TDR, 0); dev_dbg(master->dev.parent, - " start pio xfer %p: len %u tx %p rx %p bitpw %d\n", - xfer, xfer->len, xfer->tx_buf, xfer->rx_buf, - xfer->bits_per_word); + " start pio xfer %p: len %u tx %p rx %p\n", + xfer, xfer->len, xfer->tx_buf, xfer->rx_buf); /* Enable relevant interrupts */ spi_writel(as, IER, SPI_BIT(RDRF) | SPI_BIT(OVRES)); @@ -954,39 +950,21 @@ atmel_spi_pump_pio_data(struct atmel_spi *as, struct spi_transfer *xfer) { u8 *txp; u8 *rxp; - u16 *txp16; - u16 *rxp16; unsigned long xfer_pos = xfer->len - as->current_remaining_bytes; if (xfer->rx_buf) { - if (xfer->bits_per_word > 8) { - rxp16 = (u16 *)(((u8 *)xfer->rx_buf) + xfer_pos); - *rxp16 = spi_readl(as, RDR); - } else { - rxp = ((u8 *)xfer->rx_buf) + xfer_pos; - *rxp = spi_readl(as, RDR); - } + rxp = ((u8 *)xfer->rx_buf) + xfer_pos; + *rxp = spi_readl(as, RDR); } else { spi_readl(as, RDR); } - if (xfer->bits_per_word > 8) { - as->current_remaining_bytes -= 2; - if (as->current_remaining_bytes < 0) - as->current_remaining_bytes = 0; - } else { - as->current_remaining_bytes--; - } + + as->current_remaining_bytes--; if (as->current_remaining_bytes) { if (xfer->tx_buf) { - if (xfer->bits_per_word > 8) { - txp16 = (u16 *)(((u8 *)xfer->tx_buf) - + xfer_pos + 2); - spi_writel(as, TDR, *txp16); - } else { - txp = ((u8 *)xfer->tx_buf) + xfer_pos + 1; - spi_writel(as, TDR, *txp); - } + txp = ((u8 *)xfer->tx_buf) + xfer_pos + 1; + spi_writel(as, TDR, *txp); } else { spi_writel(as, TDR, 0); } @@ -1400,16 +1378,9 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg) } } - if (xfer->bits_per_word > 8) { - if (xfer->len % 2) { - dev_dbg(&spi->dev, "buffer len should be 16 bits aligned\n"); - return -EINVAL; - } - } - /* FIXME implement these protocol options!! */ - if (xfer->speed_hz < spi->max_speed_hz) { - dev_dbg(&spi->dev, "can't change speed in transfer\n"); + if (xfer->speed_hz) { + dev_dbg(&spi->dev, "no protocol options yet\n"); return -ENOPROTOOPT; } diff --git a/trunk/drivers/spi/spi-davinci.c b/trunk/drivers/spi/spi-davinci.c index 50b13c9b1ab6..2e8f24a1fb95 100644 --- a/trunk/drivers/spi/spi-davinci.c +++ b/trunk/drivers/spi/spi-davinci.c @@ -784,7 +784,7 @@ static const struct of_device_id davinci_spi_of_match[] = { }, { }, }; -MODULE_DEVICE_TABLE(of, davinci_spi_of_match); +MODULE_DEVICE_TABLE(of, davini_spi_of_match); /** * spi_davinci_get_pdata - Get platform data from DTS binding diff --git a/trunk/drivers/spi/spi.c b/trunk/drivers/spi/spi.c index 32b7bb111eb6..163fd802b7ac 100644 --- a/trunk/drivers/spi/spi.c +++ b/trunk/drivers/spi/spi.c @@ -334,7 +334,7 @@ struct spi_device *spi_alloc_device(struct spi_master *master) spi->dev.parent = &master->dev; spi->dev.bus = &spi_bus_type; spi->dev.release = spidev_release; - spi->cs_gpio = -ENOENT; + spi->cs_gpio = -EINVAL; device_initialize(&spi->dev); return spi; } @@ -1067,11 +1067,8 @@ static int of_spi_register_master(struct spi_master *master) nb = of_gpio_named_count(np, "cs-gpios"); master->num_chipselect = max(nb, (int)master->num_chipselect); - /* Return error only for an incorrectly formed cs-gpios property */ - if (nb == 0 || nb == -ENOENT) + if (nb < 1) return 0; - else if (nb < 0) - return nb; cs = devm_kzalloc(&master->dev, sizeof(int) * master->num_chipselect, @@ -1082,7 +1079,7 @@ static int of_spi_register_master(struct spi_master *master) return -ENOMEM; for (i = 0; i < master->num_chipselect; i++) - cs[i] = -ENOENT; + cs[i] = -EINVAL; for (i = 0; i < nb; i++) cs[i] = of_get_named_gpio(np, "cs-gpios", i); diff --git a/trunk/drivers/tty/tty_audit.c b/trunk/drivers/tty/tty_audit.c index a4fdce74f883..6953dc82850c 100644 --- a/trunk/drivers/tty/tty_audit.c +++ b/trunk/drivers/tty/tty_audit.c @@ -60,22 +60,24 @@ static void tty_audit_buf_put(struct tty_audit_buf *buf) tty_audit_buf_free(buf); } -static void tty_audit_log(const char *description, int major, int minor, - unsigned char *data, size_t size) +static void tty_audit_log(const char *description, struct task_struct *tsk, + kuid_t loginuid, unsigned sessionid, int major, + int minor, unsigned char *data, size_t size) { struct audit_buffer *ab; - struct task_struct *tsk = current; - uid_t uid = from_kuid(&init_user_ns, task_uid(tsk)); - uid_t loginuid = from_kuid(&init_user_ns, audit_get_loginuid(tsk)); - u32 sessionid = audit_get_sessionid(tsk); ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_TTY); if (ab) { char name[sizeof(tsk->comm)]; - - audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u major=%d" - " minor=%d comm=", description, tsk->pid, uid, - loginuid, sessionid, major, minor); + kuid_t uid = task_uid(tsk); + + audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u " + "major=%d minor=%d comm=", description, + tsk->pid, + from_kuid(&init_user_ns, uid), + from_kuid(&init_user_ns, loginuid), + sessionid, + major, minor); get_task_comm(name, tsk); audit_log_untrustedstring(ab, name); audit_log_format(ab, " data="); @@ -88,9 +90,11 @@ static void tty_audit_log(const char *description, int major, int minor, * tty_audit_buf_push - Push buffered data out * * Generate an audit message from the contents of @buf, which is owned by - * the current task. @buf->mutex must be locked. + * @tsk with @loginuid. @buf->mutex must be locked. */ -static void tty_audit_buf_push(struct tty_audit_buf *buf) +static void tty_audit_buf_push(struct task_struct *tsk, kuid_t loginuid, + unsigned int sessionid, + struct tty_audit_buf *buf) { if (buf->valid == 0) return; @@ -98,10 +102,24 @@ static void tty_audit_buf_push(struct tty_audit_buf *buf) buf->valid = 0; return; } - tty_audit_log("tty", buf->major, buf->minor, buf->data, buf->valid); + tty_audit_log("tty", tsk, loginuid, sessionid, buf->major, buf->minor, + buf->data, buf->valid); buf->valid = 0; } +/** + * tty_audit_buf_push_current - Push buffered data out + * + * Generate an audit message from the contents of @buf, which is owned by + * the current task. @buf->mutex must be locked. + */ +static void tty_audit_buf_push_current(struct tty_audit_buf *buf) +{ + kuid_t auid = audit_get_loginuid(current); + unsigned int sessionid = audit_get_sessionid(current); + tty_audit_buf_push(current, auid, sessionid, buf); +} + /** * tty_audit_exit - Handle a task exit * @@ -112,13 +130,15 @@ void tty_audit_exit(void) { struct tty_audit_buf *buf; + spin_lock_irq(¤t->sighand->siglock); buf = current->signal->tty_audit_buf; current->signal->tty_audit_buf = NULL; + spin_unlock_irq(¤t->sighand->siglock); if (!buf) return; mutex_lock(&buf->mutex); - tty_audit_buf_push(buf); + tty_audit_buf_push_current(buf); mutex_unlock(&buf->mutex); tty_audit_buf_put(buf); @@ -131,8 +151,9 @@ void tty_audit_exit(void) */ void tty_audit_fork(struct signal_struct *sig) { + spin_lock_irq(¤t->sighand->siglock); sig->audit_tty = current->signal->audit_tty; - sig->audit_tty_log_passwd = current->signal->audit_tty_log_passwd; + spin_unlock_irq(¤t->sighand->siglock); } /** @@ -142,21 +163,20 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch) { struct tty_audit_buf *buf; int major, minor, should_audit; - unsigned long flags; - spin_lock_irqsave(¤t->sighand->siglock, flags); + spin_lock_irq(¤t->sighand->siglock); should_audit = current->signal->audit_tty; buf = current->signal->tty_audit_buf; if (buf) atomic_inc(&buf->count); - spin_unlock_irqrestore(¤t->sighand->siglock, flags); + spin_unlock_irq(¤t->sighand->siglock); major = tty->driver->major; minor = tty->driver->minor_start + tty->index; if (buf) { mutex_lock(&buf->mutex); if (buf->major == major && buf->minor == minor) - tty_audit_buf_push(buf); + tty_audit_buf_push_current(buf); mutex_unlock(&buf->mutex); tty_audit_buf_put(buf); } @@ -167,20 +187,24 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch) auid = audit_get_loginuid(current); sessionid = audit_get_sessionid(current); - tty_audit_log("ioctl=TIOCSTI", major, minor, &ch, 1); + tty_audit_log("ioctl=TIOCSTI", current, auid, sessionid, major, + minor, &ch, 1); } } /** - * tty_audit_push_current - Flush current's pending audit data + * tty_audit_push_task - Flush task's pending audit data + * @tsk: task pointer + * @loginuid: sender login uid + * @sessionid: sender session id * - * Try to lock sighand and get a reference to the tty audit buffer if available. + * Called with a ref on @tsk held. Try to lock sighand and get a + * reference to the tty audit buffer if available. * Flush the buffer or return an appropriate error code. */ -int tty_audit_push_current(void) +int tty_audit_push_task(struct task_struct *tsk, kuid_t loginuid, u32 sessionid) { struct tty_audit_buf *buf = ERR_PTR(-EPERM); - struct task_struct *tsk = current; unsigned long flags; if (!lock_task_sighand(tsk, &flags)) @@ -201,7 +225,7 @@ int tty_audit_push_current(void) return PTR_ERR(buf); mutex_lock(&buf->mutex); - tty_audit_buf_push(buf); + tty_audit_buf_push(tsk, loginuid, sessionid, buf); mutex_unlock(&buf->mutex); tty_audit_buf_put(buf); @@ -219,11 +243,10 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty, unsigned icanon) { struct tty_audit_buf *buf, *buf2; - unsigned long flags; buf = NULL; buf2 = NULL; - spin_lock_irqsave(¤t->sighand->siglock, flags); + spin_lock_irq(¤t->sighand->siglock); if (likely(!current->signal->audit_tty)) goto out; buf = current->signal->tty_audit_buf; @@ -231,7 +254,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty, atomic_inc(&buf->count); goto out; } - spin_unlock_irqrestore(¤t->sighand->siglock, flags); + spin_unlock_irq(¤t->sighand->siglock); buf2 = tty_audit_buf_alloc(tty->driver->major, tty->driver->minor_start + tty->index, @@ -241,7 +264,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty, return NULL; } - spin_lock_irqsave(¤t->sighand->siglock, flags); + spin_lock_irq(¤t->sighand->siglock); if (!current->signal->audit_tty) goto out; buf = current->signal->tty_audit_buf; @@ -253,7 +276,7 @@ static struct tty_audit_buf *tty_audit_buf_get(struct tty_struct *tty, atomic_inc(&buf->count); /* Fall through */ out: - spin_unlock_irqrestore(¤t->sighand->siglock, flags); + spin_unlock_irq(¤t->sighand->siglock); if (buf2) tty_audit_buf_free(buf2); return buf; @@ -269,18 +292,10 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, { struct tty_audit_buf *buf; int major, minor; - int audit_log_tty_passwd; - unsigned long flags; if (unlikely(size == 0)) return; - spin_lock_irqsave(¤t->sighand->siglock, flags); - audit_log_tty_passwd = current->signal->audit_tty_log_passwd; - spin_unlock_irqrestore(¤t->sighand->siglock, flags); - if (!audit_log_tty_passwd && icanon && !L_ECHO(tty)) - return; - if (tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_MASTER) return; @@ -294,7 +309,7 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, minor = tty->driver->minor_start + tty->index; if (buf->major != major || buf->minor != minor || buf->icanon != icanon) { - tty_audit_buf_push(buf); + tty_audit_buf_push_current(buf); buf->major = major; buf->minor = minor; buf->icanon = icanon; @@ -310,7 +325,7 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, data += run; size -= run; if (buf->valid == N_TTY_BUF_SIZE) - tty_audit_buf_push(buf); + tty_audit_buf_push_current(buf); } while (size != 0); mutex_unlock(&buf->mutex); tty_audit_buf_put(buf); @@ -324,17 +339,16 @@ void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, void tty_audit_push(struct tty_struct *tty) { struct tty_audit_buf *buf; - unsigned long flags; - spin_lock_irqsave(¤t->sighand->siglock, flags); + spin_lock_irq(¤t->sighand->siglock); if (likely(!current->signal->audit_tty)) { - spin_unlock_irqrestore(¤t->sighand->siglock, flags); + spin_unlock_irq(¤t->sighand->siglock); return; } buf = current->signal->tty_audit_buf; if (buf) atomic_inc(&buf->count); - spin_unlock_irqrestore(¤t->sighand->siglock, flags); + spin_unlock_irq(¤t->sighand->siglock); if (buf) { int major, minor; @@ -343,7 +357,7 @@ void tty_audit_push(struct tty_struct *tty) minor = tty->driver->minor_start + tty->index; mutex_lock(&buf->mutex); if (buf->major == major && buf->minor == minor) - tty_audit_buf_push(buf); + tty_audit_buf_push_current(buf); mutex_unlock(&buf->mutex); tty_audit_buf_put(buf); } diff --git a/trunk/drivers/vhost/vringh.c b/trunk/drivers/vhost/vringh.c index 5174ebac288d..bff0775e258c 100644 --- a/trunk/drivers/vhost/vringh.c +++ b/trunk/drivers/vhost/vringh.c @@ -3,7 +3,6 @@ * * Since these may be in userspace, we use (inline) accessors. */ -#include #include #include #include @@ -1006,5 +1005,3 @@ int vringh_need_notify_kern(struct vringh *vrh) return __vringh_need_notify(vrh, getu16_kern); } EXPORT_SYMBOL(vringh_need_notify_kern); - -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/xen/Kconfig b/trunk/drivers/xen/Kconfig index f03bf501527f..dd4d9cb86243 100644 --- a/trunk/drivers/xen/Kconfig +++ b/trunk/drivers/xen/Kconfig @@ -141,7 +141,7 @@ config XEN_GRANT_DEV_ALLOC config SWIOTLB_XEN def_bool y - depends on PCI && X86 + depends on PCI select SWIOTLB config XEN_TMEM diff --git a/trunk/drivers/xen/events.c b/trunk/drivers/xen/events.c index 6a6bbe4ede92..d8cc8127f19c 100644 --- a/trunk/drivers/xen/events.c +++ b/trunk/drivers/xen/events.c @@ -167,8 +167,6 @@ static void xen_irq_info_common_init(struct irq_info *info, info->cpu = cpu; evtchn_to_irq[evtchn] = irq; - - irq_clear_status_flags(irq, IRQ_NOREQUEST|IRQ_NOAUTOEN); } static void xen_irq_info_evtchn_init(unsigned irq, @@ -876,6 +874,7 @@ int bind_evtchn_to_irq(unsigned int evtchn) struct irq_info *info = info_for_irq(irq); WARN_ON(info == NULL || info->type != IRQT_EVTCHN); } + irq_clear_status_flags(irq, IRQ_NOREQUEST|IRQ_NOAUTOEN); out: mutex_unlock(&irq_mapping_update_lock); diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 85e40d1c0a8f..57ae9c8c66bf 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -2740,7 +2740,7 @@ static int do_last(struct nameidata *nd, struct path *path, if (error) return error; - audit_inode(name, dir, LOOKUP_PARENT); + audit_inode(name, dir, 0); error = -EISDIR; /* trailing slashes? */ if (nd->last.name[nd->last.len]) diff --git a/trunk/include/drm/drmP.h b/trunk/include/drm/drmP.h index 63d17ee9eb48..61196592152e 100644 --- a/trunk/include/drm/drmP.h +++ b/trunk/include/drm/drmP.h @@ -316,7 +316,6 @@ struct drm_ioctl_desc { int flags; drm_ioctl_t *func; unsigned int cmd_drv; - const char *name; }; /** @@ -325,7 +324,7 @@ struct drm_ioctl_desc { */ #define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) \ - [DRM_IOCTL_NR(DRM_##ioctl)] = {.cmd = DRM_##ioctl, .func = _func, .flags = _flags, .cmd_drv = DRM_IOCTL_##ioctl, .name = #ioctl} + [DRM_IOCTL_NR(DRM_##ioctl)] = {.cmd = DRM_##ioctl, .func = _func, .flags = _flags, .cmd_drv = DRM_IOCTL_##ioctl} struct drm_magic_entry { struct list_head head; diff --git a/trunk/include/drm/drm_fb_helper.h b/trunk/include/drm/drm_fb_helper.h index 471f276ce8f7..8230b46fdd73 100644 --- a/trunk/include/drm/drm_fb_helper.h +++ b/trunk/include/drm/drm_fb_helper.h @@ -50,14 +50,13 @@ struct drm_fb_helper_surface_size { /** * struct drm_fb_helper_funcs - driver callbacks for the fbdev emulation library - * @gamma_set: Set the given gamma lut register on the given crtc. - * @gamma_get: Read the given gamma lut register on the given crtc, used to - * save the current lut when force-restoring the fbdev for e.g. - * kdbg. - * @fb_probe: Driver callback to allocate and initialize the fbdev info - * structure. Futhermore it also needs to allocate the drm - * framebuffer used to back the fbdev. - * @initial_config: Setup an initial fbdev display configuration + * @gamma_set: - Set the given gamma lut register on the given crtc. + * @gamma_get: - Read the given gamma lut register on the given crtc, used to + * save the current lut when force-restoring the fbdev for e.g. + * kdbg. + * @fb_probe: - Driver callback to allocate and initialize the fbdev info + * structure. Futhermore it also needs to allocate the drm + * framebuffer used to back the fbdev. * * Driver callbacks used by the fbdev emulation helper library. */ diff --git a/trunk/include/linux/audit.h b/trunk/include/linux/audit.h index b20b03852f21..5a6d718adf34 100644 --- a/trunk/include/linux/audit.h +++ b/trunk/include/linux/audit.h @@ -84,13 +84,8 @@ extern int audit_classify_arch(int arch); #define AUDIT_TYPE_CHILD_DELETE 3 /* a child being deleted */ #define AUDIT_TYPE_CHILD_CREATE 4 /* a child being created */ -/* maximized args number that audit_socketcall can process */ -#define AUDITSC_ARGS 6 - struct filename; -extern void audit_log_session_info(struct audit_buffer *ab); - #ifdef CONFIG_AUDITSYSCALL /* These are defined in auditsc.c */ /* Public API */ @@ -125,7 +120,7 @@ static inline void audit_syscall_entry(int arch, int major, unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3) { - if (unlikely(current->audit_context)) + if (unlikely(!audit_dummy_context())) __audit_syscall_entry(arch, major, a0, a1, a2, a3); } static inline void audit_syscall_exit(void *pt_regs) @@ -190,10 +185,12 @@ static inline int audit_get_sessionid(struct task_struct *tsk) return tsk->sessionid; } +extern void audit_log_task_context(struct audit_buffer *ab); +extern void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk); extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp); extern void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mode); extern int __audit_bprm(struct linux_binprm *bprm); -extern int __audit_socketcall(int nargs, unsigned long *args); +extern void __audit_socketcall(int nargs, unsigned long *args); extern int __audit_sockaddr(int len, void *addr); extern void __audit_fd_pair(int fd1, int fd2); extern void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr); @@ -227,11 +224,10 @@ static inline int audit_bprm(struct linux_binprm *bprm) return __audit_bprm(bprm); return 0; } -static inline int audit_socketcall(int nargs, unsigned long *args) +static inline void audit_socketcall(int nargs, unsigned long *args) { if (unlikely(!audit_dummy_context())) - return __audit_socketcall(nargs, args); - return 0; + __audit_socketcall(nargs, args); } static inline int audit_sockaddr(int len, void *addr) { @@ -344,6 +340,11 @@ static inline int audit_get_sessionid(struct task_struct *tsk) { return -1; } +static inline void audit_log_task_context(struct audit_buffer *ab) +{ } +static inline void audit_log_task_info(struct audit_buffer *ab, + struct task_struct *tsk) +{ } static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp) { } static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid, @@ -353,10 +354,8 @@ static inline int audit_bprm(struct linux_binprm *bprm) { return 0; } -static inline int audit_socketcall(int nargs, unsigned long *args) -{ - return 0; -} +static inline void audit_socketcall(int nargs, unsigned long *args) +{ } static inline void audit_fd_pair(int fd1, int fd2) { } static inline int audit_sockaddr(int len, void *addr) @@ -391,11 +390,6 @@ static inline void audit_ptrace(struct task_struct *t) #define audit_signals 0 #endif /* CONFIG_AUDITSYSCALL */ -static inline bool audit_loginuid_set(struct task_struct *tsk) -{ - return uid_valid(audit_get_loginuid(tsk)); -} - #ifdef CONFIG_AUDIT /* These are defined in audit.c */ /* Public API */ @@ -435,17 +429,14 @@ static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid) { } #endif -extern int audit_log_task_context(struct audit_buffer *ab); -extern void audit_log_task_info(struct audit_buffer *ab, - struct task_struct *tsk); - extern int audit_update_lsm_rules(void); /* Private API (for audit.c only) */ -extern int audit_filter_user(int type); +extern int audit_filter_user(void); extern int audit_filter_type(int type); extern int audit_receive_filter(int type, int pid, int seq, - void *data, size_t datasz); + void *data, size_t datasz, kuid_t loginuid, + u32 sessionid, u32 sid); extern int audit_enabled; #else /* CONFIG_AUDIT */ static inline __printf(4, 5) @@ -485,13 +476,6 @@ static inline void audit_log_link_denied(const char *string, { } static inline void audit_log_secctx(struct audit_buffer *ab, u32 secid) { } -static inline int audit_log_task_context(struct audit_buffer *ab) -{ - return 0; -} -static inline void audit_log_task_info(struct audit_buffer *ab, - struct task_struct *tsk) -{ } #define audit_enabled 0 #endif /* CONFIG_AUDIT */ static inline void audit_log_string(struct audit_buffer *ab, const char *buf) diff --git a/trunk/include/linux/cpuidle.h b/trunk/include/linux/cpuidle.h index 8f0406230a0a..3c86faa59798 100644 --- a/trunk/include/linux/cpuidle.h +++ b/trunk/include/linux/cpuidle.h @@ -17,7 +17,7 @@ #include #include -#define CPUIDLE_STATE_MAX 10 +#define CPUIDLE_STATE_MAX 8 #define CPUIDLE_NAME_LEN 16 #define CPUIDLE_DESC_LEN 32 diff --git a/trunk/include/linux/ftrace.h b/trunk/include/linux/ftrace.h index 99d0fbcbaf79..f83e17a40e8b 100644 --- a/trunk/include/linux/ftrace.h +++ b/trunk/include/linux/ftrace.h @@ -90,8 +90,6 @@ typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip, * not set this, then the ftrace infrastructure will add recursion * protection for the caller. * STUB - The ftrace_ops is just a place holder. - * INITIALIZED - The ftrace_ops has already been initialized (first use time - * register_ftrace_function() is called, it will initialized the ops) */ enum { FTRACE_OPS_FL_ENABLED = 1 << 0, @@ -102,7 +100,6 @@ enum { FTRACE_OPS_FL_SAVE_REGS_IF_SUPPORTED = 1 << 5, FTRACE_OPS_FL_RECURSION_SAFE = 1 << 6, FTRACE_OPS_FL_STUB = 1 << 7, - FTRACE_OPS_FL_INITIALIZED = 1 << 8, }; struct ftrace_ops { @@ -113,7 +110,6 @@ struct ftrace_ops { #ifdef CONFIG_DYNAMIC_FTRACE struct ftrace_hash *notrace_hash; struct ftrace_hash *filter_hash; - struct mutex regex_lock; #endif }; diff --git a/trunk/include/linux/ftrace_event.h b/trunk/include/linux/ftrace_event.h index 4372658c73ae..34e00fb49bec 100644 --- a/trunk/include/linux/ftrace_event.h +++ b/trunk/include/linux/ftrace_event.h @@ -293,7 +293,6 @@ struct ftrace_event_file { * caching and such. Which is mostly OK ;-) */ unsigned long flags; - atomic_t sm_ref; /* soft-mode reference counter */ }; #define __TRACE_EVENT_FLAGS(name, value) \ diff --git a/trunk/include/linux/mlx4/qp.h b/trunk/include/linux/mlx4/qp.h index 352eec9df1b8..67f46ad6920a 100644 --- a/trunk/include/linux/mlx4/qp.h +++ b/trunk/include/linux/mlx4/qp.h @@ -126,7 +126,7 @@ struct mlx4_rss_context { struct mlx4_qp_path { u8 fl; - u8 vlan_control; + u8 reserved1[1]; u8 disable_pkey_check; u8 pkey_index; u8 counter_index; @@ -141,32 +141,11 @@ struct mlx4_qp_path { u8 sched_queue; u8 vlan_index; u8 feup; - u8 fvl_rx; + u8 reserved3; u8 reserved4[2]; u8 dmac[6]; }; -enum { /* fl */ - MLX4_FL_CV = 1 << 6, - MLX4_FL_ETH_HIDE_CQE_VLAN = 1 << 2 -}; -enum { /* vlan_control */ - MLX4_VLAN_CTRL_ETH_TX_BLOCK_TAGGED = 1 << 6, - MLX4_VLAN_CTRL_ETH_RX_BLOCK_TAGGED = 1 << 2, - MLX4_VLAN_CTRL_ETH_RX_BLOCK_PRIO_TAGGED = 1 << 1, /* 802.1p priority tag */ - MLX4_VLAN_CTRL_ETH_RX_BLOCK_UNTAGGED = 1 << 0 -}; - -enum { /* feup */ - MLX4_FEUP_FORCE_ETH_UP = 1 << 6, /* force Eth UP */ - MLX4_FSM_FORCE_ETH_SRC_MAC = 1 << 5, /* force Source MAC */ - MLX4_FVL_FORCE_ETH_VLAN = 1 << 3 /* force Eth vlan */ -}; - -enum { /* fvl_rx */ - MLX4_FVL_RX_FORCE_ETH_VLAN = 1 << 0 /* enforce Eth rx vlan */ -}; - struct mlx4_qp_context { __be32 flags; __be32 pd; @@ -206,10 +185,6 @@ struct mlx4_qp_context { u32 reserved5[10]; }; -enum { /* param3 */ - MLX4_STRIP_VLAN = 1 << 30 -}; - /* Which firmware version adds support for NEC (NoErrorCompletion) bit */ #define MLX4_FW_VER_WQE_CTRL_NEC mlx4_fw_ver(2, 2, 232) diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index c12916248469..2b85c521f737 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -2147,13 +2147,11 @@ #define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e #define PCI_DEVICE_ID_NX2_57712 0x1662 #define PCI_DEVICE_ID_NX2_57712E 0x1663 -#define PCI_DEVICE_ID_NX2_57712_MF 0x1663 #define PCI_DEVICE_ID_TIGON3_5714 0x1668 #define PCI_DEVICE_ID_TIGON3_5714S 0x1669 #define PCI_DEVICE_ID_TIGON3_5780 0x166a #define PCI_DEVICE_ID_TIGON3_5780S 0x166b #define PCI_DEVICE_ID_TIGON3_5705F 0x166e -#define PCI_DEVICE_ID_NX2_57712_VF 0x166f #define PCI_DEVICE_ID_TIGON3_5754M 0x1672 #define PCI_DEVICE_ID_TIGON3_5755M 0x1673 #define PCI_DEVICE_ID_TIGON3_5756 0x1674 @@ -2179,15 +2177,13 @@ #define PCI_DEVICE_ID_TIGON3_5787 0x169b #define PCI_DEVICE_ID_TIGON3_5788 0x169c #define PCI_DEVICE_ID_TIGON3_5789 0x169d -#define PCI_DEVICE_ID_NX2_57840_4_10 0x16a1 -#define PCI_DEVICE_ID_NX2_57840_2_20 0x16a2 -#define PCI_DEVICE_ID_NX2_57840_MF 0x16a4 #define PCI_DEVICE_ID_NX2_57800_MF 0x16a5 #define PCI_DEVICE_ID_TIGON3_5702X 0x16a6 #define PCI_DEVICE_ID_TIGON3_5703X 0x16a7 #define PCI_DEVICE_ID_TIGON3_5704S 0x16a8 #define PCI_DEVICE_ID_NX2_57800_VF 0x16a9 #define PCI_DEVICE_ID_NX2_5706S 0x16aa +#define PCI_DEVICE_ID_NX2_57840_MF 0x16a4 #define PCI_DEVICE_ID_NX2_5708S 0x16ac #define PCI_DEVICE_ID_NX2_57840_VF 0x16ad #define PCI_DEVICE_ID_NX2_57810_MF 0x16ae diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 178a8d909f14..caa8f4d0186b 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -593,7 +593,6 @@ struct signal_struct { #endif #ifdef CONFIG_AUDIT unsigned audit_tty; - unsigned audit_tty_log_passwd; struct tty_audit_buf *tty_audit_buf; #endif #ifdef CONFIG_CGROUPS diff --git a/trunk/include/linux/spi/spi.h b/trunk/include/linux/spi/spi.h index 6ff26c8db7b9..733eb5ee31c5 100644 --- a/trunk/include/linux/spi/spi.h +++ b/trunk/include/linux/spi/spi.h @@ -57,7 +57,7 @@ extern struct bus_type spi_bus_type; * @modalias: Name of the driver to use with this device, or an alias * for that name. This appears in the sysfs "modalias" attribute * for driver coldplugging, and in uevents used for hotplugging - * @cs_gpio: gpio number of the chipselect line (optional, -ENOENT when + * @cs_gpio: gpio number of the chipselect line (optional, -EINVAL when * when not using a GPIO line) * * A @spi_device is used to interchange data between an SPI slave @@ -266,7 +266,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * queue so the subsystem notifies the driver that it may relax the * hardware by issuing this call * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS - * number. Any individual value may be -ENOENT for CS lines that + * number. Any individual value may be -EINVAL for CS lines that * are not GPIOs (driven by the SPI controller itself). * * Each SPI master controller can communicate with one or more @spi_device diff --git a/trunk/include/linux/tty.h b/trunk/include/linux/tty.h index 8780bd2a272a..7e92bd86a808 100644 --- a/trunk/include/linux/tty.h +++ b/trunk/include/linux/tty.h @@ -575,7 +575,8 @@ extern void tty_audit_exit(void); extern void tty_audit_fork(struct signal_struct *sig); extern void tty_audit_tiocsti(struct tty_struct *tty, char ch); extern void tty_audit_push(struct tty_struct *tty); -extern int tty_audit_push_current(void); +extern int tty_audit_push_task(struct task_struct *tsk, + kuid_t loginuid, u32 sessionid); #else static inline void tty_audit_add_data(struct tty_struct *tty, unsigned char *data, size_t size, unsigned icanon) @@ -593,7 +594,8 @@ static inline void tty_audit_fork(struct signal_struct *sig) static inline void tty_audit_push(struct tty_struct *tty) { } -static inline int tty_audit_push_current(void) +static inline int tty_audit_push_task(struct task_struct *tsk, + kuid_t loginuid, u32 sessionid) { return 0; } diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index 66772cf8c3c5..5c97b0fc5623 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -866,18 +866,6 @@ struct inet_hashinfo; struct raw_hashinfo; struct module; -/* - * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes - * un-modified. Special care is taken when initializing object to zero. - */ -static inline void sk_prot_clear_nulls(struct sock *sk, int size) -{ - if (offsetof(struct sock, sk_node.next) != 0) - memset(sk, 0, offsetof(struct sock, sk_node.next)); - memset(&sk->sk_node.pprev, 0, - size - offsetof(struct sock, sk_node.pprev)); -} - /* Networking protocol blocks we attach to sockets. * socket layer -> transport layer interface * transport -> network interface is defined by struct inet_proto diff --git a/trunk/include/scsi/libsas.h b/trunk/include/scsi/libsas.h index e2c1e66d58ae..ef937b56f9b5 100644 --- a/trunk/include/scsi/libsas.h +++ b/trunk/include/scsi/libsas.h @@ -118,7 +118,7 @@ struct ex_phy { enum ex_phy_state phy_state; - enum sas_device_type attached_dev_type; + enum sas_dev_type attached_dev_type; enum sas_linkrate linkrate; u8 attached_sata_host:1; @@ -195,7 +195,7 @@ enum { struct domain_device { spinlock_t done_lock; - enum sas_device_type dev_type; + enum sas_dev_type dev_type; enum sas_linkrate linkrate; enum sas_linkrate min_linkrate; diff --git a/trunk/include/scsi/osd_protocol.h b/trunk/include/scsi/osd_protocol.h index 25ac6283b9c7..a6026da25f3e 100644 --- a/trunk/include/scsi/osd_protocol.h +++ b/trunk/include/scsi/osd_protocol.h @@ -107,7 +107,7 @@ enum osd_attributes_mode { * int exponent: 04; * } */ -typedef __be32 osd_cdb_offset; +typedef __be32 __bitwise osd_cdb_offset; enum { OSD_OFFSET_UNUSED = 0xFFFFFFFF, diff --git a/trunk/include/scsi/sas.h b/trunk/include/scsi/sas.h index 0d2607d12387..be3eb0bf1ac0 100644 --- a/trunk/include/scsi/sas.h +++ b/trunk/include/scsi/sas.h @@ -90,18 +90,16 @@ enum sas_oob_mode { }; /* See sas_discover.c if you plan on changing these */ -enum sas_device_type { - /* these are SAS protocol defined (attached device type field) */ - SAS_PHY_UNUSED = 0, - SAS_END_DEVICE = 1, - SAS_EDGE_EXPANDER_DEVICE = 2, - SAS_FANOUT_EXPANDER_DEVICE = 3, - /* these are internal to libsas */ - SAS_HA = 4, - SAS_SATA_DEV = 5, - SAS_SATA_PM = 7, - SAS_SATA_PM_PORT = 8, - SAS_SATA_PENDING = 9, +enum sas_dev_type { + NO_DEVICE = 0, /* protocol */ + SAS_END_DEV = 1, /* protocol */ + EDGE_DEV = 2, /* protocol */ + FANOUT_DEV = 3, /* protocol */ + SAS_HA = 4, + SATA_DEV = 5, + SATA_PM = 7, + SATA_PM_PORT= 8, + SATA_PENDING = 9, }; enum sas_protocol { diff --git a/trunk/include/scsi/sas_ata.h b/trunk/include/scsi/sas_ata.h index 00f41aeeecf5..ff71a5654684 100644 --- a/trunk/include/scsi/sas_ata.h +++ b/trunk/include/scsi/sas_ata.h @@ -32,8 +32,8 @@ static inline int dev_is_sata(struct domain_device *dev) { - return dev->dev_type == SAS_SATA_DEV || dev->dev_type == SAS_SATA_PM || - dev->dev_type == SAS_SATA_PM_PORT || dev->dev_type == SAS_SATA_PENDING; + return dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM || + dev->dev_type == SATA_PM_PORT || dev->dev_type == SATA_PENDING; } int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy); diff --git a/trunk/include/scsi/scsi_device.h b/trunk/include/scsi/scsi_device.h index cc645876d147..a7f9cba275e9 100644 --- a/trunk/include/scsi/scsi_device.h +++ b/trunk/include/scsi/scsi_device.h @@ -394,18 +394,10 @@ extern int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, int data_direction, void *buffer, unsigned bufflen, unsigned char *sense, int timeout, int retries, int flag, int *resid); -extern int scsi_execute_req_flags(struct scsi_device *sdev, - const unsigned char *cmd, int data_direction, void *buffer, - unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout, - int retries, int *resid, int flags); -static inline int scsi_execute_req(struct scsi_device *sdev, - const unsigned char *cmd, int data_direction, void *buffer, - unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout, - int retries, int *resid) -{ - return scsi_execute_req_flags(sdev, cmd, data_direction, buffer, - bufflen, sshdr, timeout, retries, resid, 0); -} +extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, + int data_direction, void *buffer, unsigned bufflen, + struct scsi_sense_hdr *, int timeout, int retries, + int *resid); extern void sdev_disable_disk_events(struct scsi_device *sdev); extern void sdev_enable_disk_events(struct scsi_device *sdev); diff --git a/trunk/include/scsi/scsi_transport_iscsi.h b/trunk/include/scsi/scsi_transport_iscsi.h index d0f1602985e7..4a58cca2ecc1 100644 --- a/trunk/include/scsi/scsi_transport_iscsi.h +++ b/trunk/include/scsi/scsi_transport_iscsi.h @@ -471,10 +471,14 @@ iscsi_destroy_flashnode_sess(struct iscsi_bus_flash_session *fnode_sess); extern void iscsi_destroy_all_flashnode(struct Scsi_Host *shost); extern int iscsi_flashnode_bus_match(struct device *dev, struct device_driver *drv); +extern int iscsi_is_flashnode_conn_dev(struct device *dev, void *data); + extern struct device * iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data, int (*fn)(struct device *dev, void *data)); -extern struct device * -iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess); +extern struct device * +iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess, + void *data, + int (*fn)(struct device *dev, void *data)); #endif diff --git a/trunk/include/scsi/scsi_transport_sas.h b/trunk/include/scsi/scsi_transport_sas.h index 0bd71e2702e3..9b8e08879cfc 100644 --- a/trunk/include/scsi/scsi_transport_sas.h +++ b/trunk/include/scsi/scsi_transport_sas.h @@ -10,6 +10,13 @@ struct scsi_transport_template; struct sas_rphy; struct request; +enum sas_device_type { + SAS_PHY_UNUSED = 0, + SAS_END_DEVICE = 1, + SAS_EDGE_EXPANDER_DEVICE = 2, + SAS_FANOUT_EXPANDER_DEVICE = 3, +}; + static inline int sas_protocol_ata(enum sas_protocol proto) { return ((proto & SAS_PROTOCOL_SATA) || diff --git a/trunk/include/uapi/linux/audit.h b/trunk/include/uapi/linux/audit.h index 75cef3fd97ad..9f096f1c0907 100644 --- a/trunk/include/uapi/linux/audit.h +++ b/trunk/include/uapi/linux/audit.h @@ -246,7 +246,6 @@ #define AUDIT_OBJ_TYPE 21 #define AUDIT_OBJ_LEV_LOW 22 #define AUDIT_OBJ_LEV_HIGH 23 -#define AUDIT_LOGINUID_SET 24 /* These are ONLY useful when checking * at syscall exit time (AUDIT_AT_EXIT). */ @@ -370,8 +369,7 @@ struct audit_status { }; struct audit_tty_status { - __u32 enabled; /* 1 = enabled, 0 = disabled */ - __u32 log_passwd; /* 1 = enabled, 0 = disabled */ + __u32 enabled; /* 1 = enabled, 0 = disabled */ }; /* audit_rule_data supports filter rules with both integer and string diff --git a/trunk/kernel/audit.c b/trunk/kernel/audit.c index 21c7fa615bd3..0b084fa44b1f 100644 --- a/trunk/kernel/audit.c +++ b/trunk/kernel/audit.c @@ -49,8 +49,6 @@ #include #include #include -#include -#include #include @@ -267,6 +265,7 @@ void audit_log_lost(const char *message) } static int audit_log_config_change(char *function_name, int new, int old, + kuid_t loginuid, u32 sessionid, u32 sid, int allow_changes) { struct audit_buffer *ab; @@ -275,17 +274,29 @@ static int audit_log_config_change(char *function_name, int new, int old, ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); if (unlikely(!ab)) return rc; - audit_log_format(ab, "%s=%d old=%d", function_name, new, old); - audit_log_session_info(ab); - rc = audit_log_task_context(ab); - if (rc) - allow_changes = 0; /* Something weird, deny request */ + audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new, + old, from_kuid(&init_user_ns, loginuid), sessionid); + if (sid) { + char *ctx = NULL; + u32 len; + + rc = security_secid_to_secctx(sid, &ctx, &len); + if (rc) { + audit_log_format(ab, " sid=%u", sid); + allow_changes = 0; /* Something weird, deny request */ + } else { + audit_log_format(ab, " subj=%s", ctx); + security_release_secctx(ctx, len); + } + } audit_log_format(ab, " res=%d", allow_changes); audit_log_end(ab); return rc; } -static int audit_do_config_change(char *function_name, int *to_change, int new) +static int audit_do_config_change(char *function_name, int *to_change, + int new, kuid_t loginuid, u32 sessionid, + u32 sid) { int allow_changes, rc = 0, old = *to_change; @@ -296,7 +307,8 @@ static int audit_do_config_change(char *function_name, int *to_change, int new) allow_changes = 1; if (audit_enabled != AUDIT_OFF) { - rc = audit_log_config_change(function_name, new, old, allow_changes); + rc = audit_log_config_change(function_name, new, old, loginuid, + sessionid, sid, allow_changes); if (rc) allow_changes = 0; } @@ -310,37 +322,44 @@ static int audit_do_config_change(char *function_name, int *to_change, int new) return rc; } -static int audit_set_rate_limit(int limit) +static int audit_set_rate_limit(int limit, kuid_t loginuid, u32 sessionid, + u32 sid) { - return audit_do_config_change("audit_rate_limit", &audit_rate_limit, limit); + return audit_do_config_change("audit_rate_limit", &audit_rate_limit, + limit, loginuid, sessionid, sid); } -static int audit_set_backlog_limit(int limit) +static int audit_set_backlog_limit(int limit, kuid_t loginuid, u32 sessionid, + u32 sid) { - return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, limit); + return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit, + limit, loginuid, sessionid, sid); } -static int audit_set_enabled(int state) +static int audit_set_enabled(int state, kuid_t loginuid, u32 sessionid, u32 sid) { int rc; if (state < AUDIT_OFF || state > AUDIT_LOCKED) return -EINVAL; - rc = audit_do_config_change("audit_enabled", &audit_enabled, state); + rc = audit_do_config_change("audit_enabled", &audit_enabled, state, + loginuid, sessionid, sid); + if (!rc) audit_ever_enabled |= !!state; return rc; } -static int audit_set_failure(int state) +static int audit_set_failure(int state, kuid_t loginuid, u32 sessionid, u32 sid) { if (state != AUDIT_FAIL_SILENT && state != AUDIT_FAIL_PRINTK && state != AUDIT_FAIL_PANIC) return -EINVAL; - return audit_do_config_change("audit_failure", &audit_failure, state); + return audit_do_config_change("audit_failure", &audit_failure, state, + loginuid, sessionid, sid); } /* @@ -398,53 +417,34 @@ static void kauditd_send_skb(struct sk_buff *skb) consume_skb(skb); } -/* - * flush_hold_queue - empty the hold queue if auditd appears - * - * If auditd just started, drain the queue of messages already - * sent to syslog/printk. Remember loss here is ok. We already - * called audit_log_lost() if it didn't go out normally. so the - * race between the skb_dequeue and the next check for audit_pid - * doesn't matter. - * - * If you ever find kauditd to be too slow we can get a perf win - * by doing our own locking and keeping better track if there - * are messages in this queue. I don't see the need now, but - * in 5 years when I want to play with this again I'll see this - * note and still have no friggin idea what i'm thinking today. - */ -static void flush_hold_queue(void) +static int kauditd_thread(void *dummy) { struct sk_buff *skb; - if (!audit_default || !audit_pid) - return; - - skb = skb_dequeue(&audit_skb_hold_queue); - if (likely(!skb)) - return; - - while (skb && audit_pid) { - kauditd_send_skb(skb); - skb = skb_dequeue(&audit_skb_hold_queue); - } - - /* - * if auditd just disappeared but we - * dequeued an skb we need to drop ref - */ - if (skb) - consume_skb(skb); -} - -static int kauditd_thread(void *dummy) -{ set_freezable(); while (!kthread_should_stop()) { - struct sk_buff *skb; - DECLARE_WAITQUEUE(wait, current); - - flush_hold_queue(); + /* + * if auditd just started drain the queue of messages already + * sent to syslog/printk. remember loss here is ok. we already + * called audit_log_lost() if it didn't go out normally. so the + * race between the skb_dequeue and the next check for audit_pid + * doesn't matter. + * + * if you ever find kauditd to be too slow we can get a perf win + * by doing our own locking and keeping better track if there + * are messages in this queue. I don't see the need now, but + * in 5 years when I want to play with this again I'll see this + * note and still have no friggin idea what i'm thinking today. + */ + if (audit_default && audit_pid) { + skb = skb_dequeue(&audit_skb_hold_queue); + if (unlikely(skb)) { + while (skb && audit_pid) { + kauditd_send_skb(skb); + skb = skb_dequeue(&audit_skb_hold_queue); + } + } + } skb = skb_dequeue(&audit_skb_queue); wake_up(&audit_backlog_wait); @@ -453,18 +453,19 @@ static int kauditd_thread(void *dummy) kauditd_send_skb(skb); else audit_printk_skb(skb); - continue; - } - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&kauditd_wait, &wait); + } else { + DECLARE_WAITQUEUE(wait, current); + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&kauditd_wait, &wait); - if (!skb_queue_len(&audit_skb_queue)) { - try_to_freeze(); - schedule(); - } + if (!skb_queue_len(&audit_skb_queue)) { + try_to_freeze(); + schedule(); + } - __set_current_state(TASK_RUNNING); - remove_wait_queue(&kauditd_wait, &wait); + __set_current_state(TASK_RUNNING); + remove_wait_queue(&kauditd_wait, &wait); + } } return 0; } @@ -578,14 +579,13 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) return -EPERM; switch (msg_type) { - case AUDIT_LIST: - case AUDIT_ADD: - case AUDIT_DEL: - return -EOPNOTSUPP; case AUDIT_GET: - case AUDIT_SET: + case AUDIT_LIST: case AUDIT_LIST_RULES: + case AUDIT_SET: + case AUDIT_ADD: case AUDIT_ADD_RULE: + case AUDIT_DEL: case AUDIT_DEL_RULE: case AUDIT_SIGNAL_INFO: case AUDIT_TTY_GET: @@ -608,10 +608,12 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) return err; } -static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type) +static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, + kuid_t auid, u32 ses, u32 sid) { int rc = 0; - uid_t uid = from_kuid(&init_user_ns, current_uid()); + char *ctx = NULL; + u32 len; if (!audit_enabled) { *ab = NULL; @@ -621,21 +623,33 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type) *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); if (unlikely(!*ab)) return rc; - audit_log_format(*ab, "pid=%d uid=%u", task_tgid_vnr(current), uid); - audit_log_session_info(*ab); - audit_log_task_context(*ab); + audit_log_format(*ab, "pid=%d uid=%u auid=%u ses=%u", + task_tgid_vnr(current), + from_kuid(&init_user_ns, current_uid()), + from_kuid(&init_user_ns, auid), ses); + if (sid) { + rc = security_secid_to_secctx(sid, &ctx, &len); + if (rc) + audit_log_format(*ab, " ssid=%u", sid); + else { + audit_log_format(*ab, " subj=%s", ctx); + security_release_secctx(ctx, len); + } + } return rc; } static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { - u32 seq; + u32 seq, sid; void *data; struct audit_status *status_get, status_set; int err; struct audit_buffer *ab; u16 msg_type = nlh->nlmsg_type; + kuid_t loginuid; /* loginuid of sender */ + u32 sessionid; struct audit_sig_info *sig_data; char *ctx = NULL; u32 len; @@ -654,6 +668,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) return err; } } + loginuid = audit_get_loginuid(current); + sessionid = audit_get_sessionid(current); + security_task_getsecid(current, &sid); seq = nlh->nlmsg_seq; data = nlmsg_data(nlh); @@ -674,12 +691,14 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) return -EINVAL; status_get = (struct audit_status *)data; if (status_get->mask & AUDIT_STATUS_ENABLED) { - err = audit_set_enabled(status_get->enabled); + err = audit_set_enabled(status_get->enabled, + loginuid, sessionid, sid); if (err < 0) return err; } if (status_get->mask & AUDIT_STATUS_FAILURE) { - err = audit_set_failure(status_get->failure); + err = audit_set_failure(status_get->failure, + loginuid, sessionid, sid); if (err < 0) return err; } @@ -687,17 +706,22 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) int new_pid = status_get->pid; if (audit_enabled != AUDIT_OFF) - audit_log_config_change("audit_pid", new_pid, audit_pid, 1); + audit_log_config_change("audit_pid", new_pid, + audit_pid, loginuid, + sessionid, sid, 1); + audit_pid = new_pid; audit_nlk_portid = NETLINK_CB(skb).portid; } if (status_get->mask & AUDIT_STATUS_RATE_LIMIT) { - err = audit_set_rate_limit(status_get->rate_limit); + err = audit_set_rate_limit(status_get->rate_limit, + loginuid, sessionid, sid); if (err < 0) return err; } if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT) - err = audit_set_backlog_limit(status_get->backlog_limit); + err = audit_set_backlog_limit(status_get->backlog_limit, + loginuid, sessionid, sid); break; case AUDIT_USER: case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: @@ -705,22 +729,25 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (!audit_enabled && msg_type != AUDIT_USER_AVC) return 0; - err = audit_filter_user(msg_type); + err = audit_filter_user(); if (err == 1) { err = 0; if (msg_type == AUDIT_USER_TTY) { - err = tty_audit_push_current(); + err = tty_audit_push_task(current, loginuid, + sessionid); if (err) break; } - audit_log_common_recv_msg(&ab, msg_type); + audit_log_common_recv_msg(&ab, msg_type, + loginuid, sessionid, sid); + if (msg_type != AUDIT_USER_TTY) audit_log_format(ab, " msg='%.1024s'", (char *)data); else { int size; - audit_log_format(ab, " data="); + audit_log_format(ab, " msg="); size = nlmsg_len(nlh); if (size > 0 && ((unsigned char *)data)[size - 1] == '\0') @@ -731,24 +758,50 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) audit_log_end(ab); } break; + case AUDIT_ADD: + case AUDIT_DEL: + if (nlmsg_len(nlh) < sizeof(struct audit_rule)) + return -EINVAL; + if (audit_enabled == AUDIT_LOCKED) { + audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, + loginuid, sessionid, sid); + + audit_log_format(ab, " audit_enabled=%d res=0", + audit_enabled); + audit_log_end(ab); + return -EPERM; + } + /* fallthrough */ + case AUDIT_LIST: + err = audit_receive_filter(msg_type, NETLINK_CB(skb).portid, + seq, data, nlmsg_len(nlh), + loginuid, sessionid, sid); + break; case AUDIT_ADD_RULE: case AUDIT_DEL_RULE: if (nlmsg_len(nlh) < sizeof(struct audit_rule_data)) return -EINVAL; if (audit_enabled == AUDIT_LOCKED) { - audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); - audit_log_format(ab, " audit_enabled=%d res=0", audit_enabled); + audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, + loginuid, sessionid, sid); + + audit_log_format(ab, " audit_enabled=%d res=0", + audit_enabled); audit_log_end(ab); return -EPERM; } /* fallthrough */ case AUDIT_LIST_RULES: err = audit_receive_filter(msg_type, NETLINK_CB(skb).portid, - seq, data, nlmsg_len(nlh)); + seq, data, nlmsg_len(nlh), + loginuid, sessionid, sid); break; case AUDIT_TRIM: audit_trim_trees(); - audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); + + audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, + loginuid, sessionid, sid); + audit_log_format(ab, " op=trim res=1"); audit_log_end(ab); break; @@ -778,7 +831,8 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) /* OK, here comes... */ err = audit_tag_tree(old, new); - audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE); + audit_log_common_recv_msg(&ab, AUDIT_CONFIG_CHANGE, + loginuid, sessionid, sid); audit_log_format(ab, " op=make_equiv old="); audit_log_untrustedstring(ab, old); @@ -817,30 +871,27 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) struct audit_tty_status s; struct task_struct *tsk = current; - spin_lock(&tsk->sighand->siglock); + spin_lock_irq(&tsk->sighand->siglock); s.enabled = tsk->signal->audit_tty != 0; - s.log_passwd = tsk->signal->audit_tty_log_passwd; - spin_unlock(&tsk->sighand->siglock); + spin_unlock_irq(&tsk->sighand->siglock); audit_send_reply(NETLINK_CB(skb).portid, seq, AUDIT_TTY_GET, 0, 0, &s, sizeof(s)); break; } case AUDIT_TTY_SET: { - struct audit_tty_status s; + struct audit_tty_status *s; struct task_struct *tsk = current; - memset(&s, 0, sizeof(s)); - /* guard against past and future API changes */ - memcpy(&s, data, min(sizeof(s), (size_t)nlh->nlmsg_len)); - if ((s.enabled != 0 && s.enabled != 1) || - (s.log_passwd != 0 && s.log_passwd != 1)) + if (nlh->nlmsg_len < sizeof(struct audit_tty_status)) + return -EINVAL; + s = data; + if (s->enabled != 0 && s->enabled != 1) return -EINVAL; - spin_lock(&tsk->sighand->siglock); - tsk->signal->audit_tty = s.enabled; - tsk->signal->audit_tty_log_passwd = s.log_passwd; - spin_unlock(&tsk->sighand->siglock); + spin_lock_irq(&tsk->sighand->siglock); + tsk->signal->audit_tty = s->enabled != 0; + spin_unlock_irq(&tsk->sighand->siglock); break; } default: @@ -1383,14 +1434,6 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix, kfree(pathname); } -void audit_log_session_info(struct audit_buffer *ab) -{ - u32 sessionid = audit_get_sessionid(current); - uid_t auid = from_kuid(&init_user_ns, audit_get_loginuid(current)); - - audit_log_format(ab, " auid=%u ses=%u\n", auid, sessionid); -} - void audit_log_key(struct audit_buffer *ab, char *key) { audit_log_format(ab, " key="); @@ -1400,224 +1443,6 @@ void audit_log_key(struct audit_buffer *ab, char *key) audit_log_format(ab, "(null)"); } -void audit_log_cap(struct audit_buffer *ab, char *prefix, kernel_cap_t *cap) -{ - int i; - - audit_log_format(ab, " %s=", prefix); - CAP_FOR_EACH_U32(i) { - audit_log_format(ab, "%08x", - cap->cap[(_KERNEL_CAPABILITY_U32S-1) - i]); - } -} - -void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) -{ - kernel_cap_t *perm = &name->fcap.permitted; - kernel_cap_t *inh = &name->fcap.inheritable; - int log = 0; - - if (!cap_isclear(*perm)) { - audit_log_cap(ab, "cap_fp", perm); - log = 1; - } - if (!cap_isclear(*inh)) { - audit_log_cap(ab, "cap_fi", inh); - log = 1; - } - - if (log) - audit_log_format(ab, " cap_fe=%d cap_fver=%x", - name->fcap.fE, name->fcap_ver); -} - -static inline int audit_copy_fcaps(struct audit_names *name, - const struct dentry *dentry) -{ - struct cpu_vfs_cap_data caps; - int rc; - - if (!dentry) - return 0; - - rc = get_vfs_caps_from_disk(dentry, &caps); - if (rc) - return rc; - - name->fcap.permitted = caps.permitted; - name->fcap.inheritable = caps.inheritable; - name->fcap.fE = !!(caps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE); - name->fcap_ver = (caps.magic_etc & VFS_CAP_REVISION_MASK) >> - VFS_CAP_REVISION_SHIFT; - - return 0; -} - -/* Copy inode data into an audit_names. */ -void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, - const struct inode *inode) -{ - name->ino = inode->i_ino; - name->dev = inode->i_sb->s_dev; - name->mode = inode->i_mode; - name->uid = inode->i_uid; - name->gid = inode->i_gid; - name->rdev = inode->i_rdev; - security_inode_getsecid(inode, &name->osid); - audit_copy_fcaps(name, dentry); -} - -/** - * audit_log_name - produce AUDIT_PATH record from struct audit_names - * @context: audit_context for the task - * @n: audit_names structure with reportable details - * @path: optional path to report instead of audit_names->name - * @record_num: record number to report when handling a list of names - * @call_panic: optional pointer to int that will be updated if secid fails - */ -void audit_log_name(struct audit_context *context, struct audit_names *n, - struct path *path, int record_num, int *call_panic) -{ - struct audit_buffer *ab; - ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH); - if (!ab) - return; - - audit_log_format(ab, "item=%d", record_num); - - if (path) - audit_log_d_path(ab, " name=", path); - else if (n->name) { - switch (n->name_len) { - case AUDIT_NAME_FULL: - /* log the full path */ - audit_log_format(ab, " name="); - audit_log_untrustedstring(ab, n->name->name); - break; - case 0: - /* name was specified as a relative path and the - * directory component is the cwd */ - audit_log_d_path(ab, " name=", &context->pwd); - break; - default: - /* log the name's directory component */ - audit_log_format(ab, " name="); - audit_log_n_untrustedstring(ab, n->name->name, - n->name_len); - } - } else - audit_log_format(ab, " name=(null)"); - - if (n->ino != (unsigned long)-1) { - audit_log_format(ab, " inode=%lu" - " dev=%02x:%02x mode=%#ho" - " ouid=%u ogid=%u rdev=%02x:%02x", - n->ino, - MAJOR(n->dev), - MINOR(n->dev), - n->mode, - from_kuid(&init_user_ns, n->uid), - from_kgid(&init_user_ns, n->gid), - MAJOR(n->rdev), - MINOR(n->rdev)); - } - if (n->osid != 0) { - char *ctx = NULL; - u32 len; - if (security_secid_to_secctx( - n->osid, &ctx, &len)) { - audit_log_format(ab, " osid=%u", n->osid); - if (call_panic) - *call_panic = 2; - } else { - audit_log_format(ab, " obj=%s", ctx); - security_release_secctx(ctx, len); - } - } - - audit_log_fcaps(ab, n); - audit_log_end(ab); -} - -int audit_log_task_context(struct audit_buffer *ab) -{ - char *ctx = NULL; - unsigned len; - int error; - u32 sid; - - security_task_getsecid(current, &sid); - if (!sid) - return 0; - - error = security_secid_to_secctx(sid, &ctx, &len); - if (error) { - if (error != -EINVAL) - goto error_path; - return 0; - } - - audit_log_format(ab, " subj=%s", ctx); - security_release_secctx(ctx, len); - return 0; - -error_path: - audit_panic("error in audit_log_task_context"); - return error; -} -EXPORT_SYMBOL(audit_log_task_context); - -void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) -{ - const struct cred *cred; - char name[sizeof(tsk->comm)]; - struct mm_struct *mm = tsk->mm; - char *tty; - - if (!ab) - return; - - /* tsk == current */ - cred = current_cred(); - - spin_lock_irq(&tsk->sighand->siglock); - if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name) - tty = tsk->signal->tty->name; - else - tty = "(none)"; - spin_unlock_irq(&tsk->sighand->siglock); - - audit_log_format(ab, - " ppid=%ld pid=%d auid=%u uid=%u gid=%u" - " euid=%u suid=%u fsuid=%u" - " egid=%u sgid=%u fsgid=%u ses=%u tty=%s", - sys_getppid(), - tsk->pid, - from_kuid(&init_user_ns, audit_get_loginuid(tsk)), - from_kuid(&init_user_ns, cred->uid), - from_kgid(&init_user_ns, cred->gid), - from_kuid(&init_user_ns, cred->euid), - from_kuid(&init_user_ns, cred->suid), - from_kuid(&init_user_ns, cred->fsuid), - from_kgid(&init_user_ns, cred->egid), - from_kgid(&init_user_ns, cred->sgid), - from_kgid(&init_user_ns, cred->fsgid), - audit_get_sessionid(tsk), tty); - - get_task_comm(name, tsk); - audit_log_format(ab, " comm="); - audit_log_untrustedstring(ab, name); - - if (mm) { - down_read(&mm->mmap_sem); - if (mm->exe_file) - audit_log_d_path(ab, " exe=", &mm->exe_file->f_path); - up_read(&mm->mmap_sem); - } - audit_log_task_context(ab); -} -EXPORT_SYMBOL(audit_log_task_info); - /** * audit_log_link_denied - report a link restriction denial * @operation: specific link opreation @@ -1626,28 +1451,19 @@ EXPORT_SYMBOL(audit_log_task_info); void audit_log_link_denied(const char *operation, struct path *link) { struct audit_buffer *ab; - struct audit_names *name; - - name = kzalloc(sizeof(*name), GFP_NOFS); - if (!name) - return; - /* Generate AUDIT_ANOM_LINK with subject, operation, outcome. */ ab = audit_log_start(current->audit_context, GFP_KERNEL, AUDIT_ANOM_LINK); if (!ab) - goto out; - audit_log_format(ab, "op=%s", operation); - audit_log_task_info(ab, current); - audit_log_format(ab, " res=0"); + return; + audit_log_format(ab, "op=%s action=denied", operation); + audit_log_format(ab, " pid=%d comm=", current->pid); + audit_log_untrustedstring(ab, current->comm); + audit_log_d_path(ab, " path=", link); + audit_log_format(ab, " dev="); + audit_log_untrustedstring(ab, link->dentry->d_inode->i_sb->s_id); + audit_log_format(ab, " ino=%lu", link->dentry->d_inode->i_ino); audit_log_end(ab); - - /* Generate AUDIT_PATH record with object. */ - name->type = AUDIT_TYPE_NORMAL; - audit_copy_inode(name, link->dentry, link->dentry->d_inode); - audit_log_name(current->audit_context, name, link, 0, NULL); -out: - kfree(name); } /** diff --git a/trunk/kernel/audit.h b/trunk/kernel/audit.h index 1c95131ef760..11468d99dad0 100644 --- a/trunk/kernel/audit.h +++ b/trunk/kernel/audit.h @@ -22,7 +22,6 @@ #include #include #include -#include /* 0 = no checking 1 = put_count checking @@ -30,11 +29,6 @@ */ #define AUDIT_DEBUG 0 -/* AUDIT_NAMES is the number of slots we reserve in the audit_context - * for saving names from getname(). If we get more names we will allocate - * a name dynamically and also add those to the list anchored by names_list. */ -#define AUDIT_NAMES 5 - /* At task start time, the audit_state is set in the audit_context using a per-task filter. At syscall entry, the audit_state is augmented by the syscall filter. */ @@ -65,158 +59,8 @@ struct audit_entry { struct audit_krule rule; }; -struct audit_cap_data { - kernel_cap_t permitted; - kernel_cap_t inheritable; - union { - unsigned int fE; /* effective bit of file cap */ - kernel_cap_t effective; /* effective set of process */ - }; -}; - -/* When fs/namei.c:getname() is called, we store the pointer in name and - * we don't let putname() free it (instead we free all of the saved - * pointers at syscall exit time). - * - * Further, in fs/namei.c:path_lookup() we store the inode and device. - */ -struct audit_names { - struct list_head list; /* audit_context->names_list */ - - struct filename *name; - int name_len; /* number of chars to log */ - bool name_put; /* call __putname()? */ - - unsigned long ino; - dev_t dev; - umode_t mode; - kuid_t uid; - kgid_t gid; - dev_t rdev; - u32 osid; - struct audit_cap_data fcap; - unsigned int fcap_ver; - unsigned char type; /* record type */ - /* - * This was an allocated audit_names and not from the array of - * names allocated in the task audit context. Thus this name - * should be freed on syscall exit. - */ - bool should_free; -}; - -/* The per-task audit context. */ -struct audit_context { - int dummy; /* must be the first element */ - int in_syscall; /* 1 if task is in a syscall */ - enum audit_state state, current_state; - unsigned int serial; /* serial number for record */ - int major; /* syscall number */ - struct timespec ctime; /* time of syscall entry */ - unsigned long argv[4]; /* syscall arguments */ - long return_code;/* syscall return code */ - u64 prio; - int return_valid; /* return code is valid */ - /* - * The names_list is the list of all audit_names collected during this - * syscall. The first AUDIT_NAMES entries in the names_list will - * actually be from the preallocated_names array for performance - * reasons. Except during allocation they should never be referenced - * through the preallocated_names array and should only be found/used - * by running the names_list. - */ - struct audit_names preallocated_names[AUDIT_NAMES]; - int name_count; /* total records in names_list */ - struct list_head names_list; /* struct audit_names->list anchor */ - char *filterkey; /* key for rule that triggered record */ - struct path pwd; - struct audit_aux_data *aux; - struct audit_aux_data *aux_pids; - struct sockaddr_storage *sockaddr; - size_t sockaddr_len; - /* Save things to print about task_struct */ - pid_t pid, ppid; - kuid_t uid, euid, suid, fsuid; - kgid_t gid, egid, sgid, fsgid; - unsigned long personality; - int arch; - - pid_t target_pid; - kuid_t target_auid; - kuid_t target_uid; - unsigned int target_sessionid; - u32 target_sid; - char target_comm[TASK_COMM_LEN]; - - struct audit_tree_refs *trees, *first_trees; - struct list_head killed_trees; - int tree_count; - - int type; - union { - struct { - int nargs; - long args[6]; - } socketcall; - struct { - kuid_t uid; - kgid_t gid; - umode_t mode; - u32 osid; - int has_perm; - uid_t perm_uid; - gid_t perm_gid; - umode_t perm_mode; - unsigned long qbytes; - } ipc; - struct { - mqd_t mqdes; - struct mq_attr mqstat; - } mq_getsetattr; - struct { - mqd_t mqdes; - int sigev_signo; - } mq_notify; - struct { - mqd_t mqdes; - size_t msg_len; - unsigned int msg_prio; - struct timespec abs_timeout; - } mq_sendrecv; - struct { - int oflag; - umode_t mode; - struct mq_attr attr; - } mq_open; - struct { - pid_t pid; - struct audit_cap_data cap; - } capset; - struct { - int fd; - int flags; - } mmap; - }; - int fds[2]; - -#if AUDIT_DEBUG - int put_count; - int ino_count; -#endif -}; - extern int audit_ever_enabled; -extern void audit_copy_inode(struct audit_names *name, - const struct dentry *dentry, - const struct inode *inode); -extern void audit_log_cap(struct audit_buffer *ab, char *prefix, - kernel_cap_t *cap); -extern void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name); -extern void audit_log_name(struct audit_context *context, - struct audit_names *n, struct path *path, - int record_num, int *call_panic); - extern int audit_pid; #define AUDIT_INODE_BUCKETS 32 diff --git a/trunk/kernel/auditfilter.c b/trunk/kernel/auditfilter.c index 83a2970295d1..267436826c3b 100644 --- a/trunk/kernel/auditfilter.c +++ b/trunk/kernel/auditfilter.c @@ -310,83 +310,121 @@ static u32 audit_to_op(u32 op) return n; } -/* check if an audit field is valid */ -static int audit_field_valid(struct audit_entry *entry, struct audit_field *f) + +/* Translate struct audit_rule to kernel's rule respresentation. + * Exists for backward compatibility with userspace. */ +static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) { - switch(f->type) { - case AUDIT_MSGTYPE: - if (entry->rule.listnr != AUDIT_FILTER_TYPE && - entry->rule.listnr != AUDIT_FILTER_USER) - return -EINVAL; - break; - }; + struct audit_entry *entry; + int err = 0; + int i; - switch(f->type) { - default: - return -EINVAL; - case AUDIT_UID: - case AUDIT_EUID: - case AUDIT_SUID: - case AUDIT_FSUID: - case AUDIT_LOGINUID: - case AUDIT_OBJ_UID: - case AUDIT_GID: - case AUDIT_EGID: - case AUDIT_SGID: - case AUDIT_FSGID: - case AUDIT_OBJ_GID: - case AUDIT_PID: - case AUDIT_PERS: - case AUDIT_MSGTYPE: - case AUDIT_PPID: - case AUDIT_DEVMAJOR: - case AUDIT_DEVMINOR: - case AUDIT_EXIT: - case AUDIT_SUCCESS: - /* bit ops are only useful on syscall args */ - if (f->op == Audit_bitmask || f->op == Audit_bittest) - return -EINVAL; - break; - case AUDIT_ARG0: - case AUDIT_ARG1: - case AUDIT_ARG2: - case AUDIT_ARG3: - case AUDIT_SUBJ_USER: - case AUDIT_SUBJ_ROLE: - case AUDIT_SUBJ_TYPE: - case AUDIT_SUBJ_SEN: - case AUDIT_SUBJ_CLR: - case AUDIT_OBJ_USER: - case AUDIT_OBJ_ROLE: - case AUDIT_OBJ_TYPE: - case AUDIT_OBJ_LEV_LOW: - case AUDIT_OBJ_LEV_HIGH: - case AUDIT_WATCH: - case AUDIT_DIR: - case AUDIT_FILTERKEY: - break; - case AUDIT_LOGINUID_SET: - if ((f->val != 0) && (f->val != 1)) - return -EINVAL; - /* FALL THROUGH */ - case AUDIT_ARCH: - if (f->op != Audit_not_equal && f->op != Audit_equal) - return -EINVAL; - break; - case AUDIT_PERM: - if (f->val & ~15) - return -EINVAL; - break; - case AUDIT_FILETYPE: - if (f->val & ~S_IFMT) - return -EINVAL; - break; - case AUDIT_FIELD_COMPARE: - if (f->val > AUDIT_MAX_FIELD_COMPARE) - return -EINVAL; - break; - }; - return 0; + entry = audit_to_entry_common(rule); + if (IS_ERR(entry)) + goto exit_nofree; + + for (i = 0; i < rule->field_count; i++) { + struct audit_field *f = &entry->rule.fields[i]; + u32 n; + + n = rule->fields[i] & (AUDIT_NEGATE|AUDIT_OPERATORS); + + /* Support for legacy operators where + * AUDIT_NEGATE bit signifies != and otherwise assumes == */ + if (n & AUDIT_NEGATE) + f->op = Audit_not_equal; + else if (!n) + f->op = Audit_equal; + else + f->op = audit_to_op(n); + + entry->rule.vers_ops = (n & AUDIT_OPERATORS) ? 2 : 1; + + f->type = rule->fields[i] & ~(AUDIT_NEGATE|AUDIT_OPERATORS); + f->val = rule->values[i]; + f->uid = INVALID_UID; + f->gid = INVALID_GID; + + err = -EINVAL; + if (f->op == Audit_bad) + goto exit_free; + + switch(f->type) { + default: + goto exit_free; + case AUDIT_UID: + case AUDIT_EUID: + case AUDIT_SUID: + case AUDIT_FSUID: + case AUDIT_LOGINUID: + /* bit ops not implemented for uid comparisons */ + if (f->op == Audit_bitmask || f->op == Audit_bittest) + goto exit_free; + + f->uid = make_kuid(current_user_ns(), f->val); + if (!uid_valid(f->uid)) + goto exit_free; + break; + case AUDIT_GID: + case AUDIT_EGID: + case AUDIT_SGID: + case AUDIT_FSGID: + /* bit ops not implemented for gid comparisons */ + if (f->op == Audit_bitmask || f->op == Audit_bittest) + goto exit_free; + + f->gid = make_kgid(current_user_ns(), f->val); + if (!gid_valid(f->gid)) + goto exit_free; + break; + case AUDIT_PID: + case AUDIT_PERS: + case AUDIT_MSGTYPE: + case AUDIT_PPID: + case AUDIT_DEVMAJOR: + case AUDIT_DEVMINOR: + case AUDIT_EXIT: + case AUDIT_SUCCESS: + /* bit ops are only useful on syscall args */ + if (f->op == Audit_bitmask || f->op == Audit_bittest) + goto exit_free; + break; + case AUDIT_ARG0: + case AUDIT_ARG1: + case AUDIT_ARG2: + case AUDIT_ARG3: + break; + /* arch is only allowed to be = or != */ + case AUDIT_ARCH: + if (f->op != Audit_not_equal && f->op != Audit_equal) + goto exit_free; + entry->rule.arch_f = f; + break; + case AUDIT_PERM: + if (f->val & ~15) + goto exit_free; + break; + case AUDIT_FILETYPE: + if (f->val & ~S_IFMT) + goto exit_free; + break; + case AUDIT_INODE: + err = audit_to_inode(&entry->rule, f); + if (err) + goto exit_free; + break; + } + } + + if (entry->rule.inode_f && entry->rule.inode_f->op == Audit_not_equal) + entry->rule.inode_f = NULL; + +exit_nofree: + return entry; + +exit_free: + audit_free_rule(entry); + return ERR_PTR(err); } /* Translate struct audit_rule_data to kernel's rule respresentation. */ @@ -421,25 +459,17 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, f->gid = INVALID_GID; f->lsm_str = NULL; f->lsm_rule = NULL; - - /* Support legacy tests for a valid loginuid */ - if ((f->type == AUDIT_LOGINUID) && (f->val == 4294967295)) { - f->type = AUDIT_LOGINUID_SET; - f->val = 0; - } - - err = audit_field_valid(entry, f); - if (err) - goto exit_free; - - err = -EINVAL; - switch (f->type) { - case AUDIT_LOGINUID: + switch(f->type) { case AUDIT_UID: case AUDIT_EUID: case AUDIT_SUID: case AUDIT_FSUID: + case AUDIT_LOGINUID: case AUDIT_OBJ_UID: + /* bit ops not implemented for uid comparisons */ + if (f->op == Audit_bitmask || f->op == Audit_bittest) + goto exit_free; + f->uid = make_kuid(current_user_ns(), f->val); if (!uid_valid(f->uid)) goto exit_free; @@ -449,10 +479,27 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, case AUDIT_SGID: case AUDIT_FSGID: case AUDIT_OBJ_GID: + /* bit ops not implemented for gid comparisons */ + if (f->op == Audit_bitmask || f->op == Audit_bittest) + goto exit_free; + f->gid = make_kgid(current_user_ns(), f->val); if (!gid_valid(f->gid)) goto exit_free; break; + case AUDIT_PID: + case AUDIT_PERS: + case AUDIT_MSGTYPE: + case AUDIT_PPID: + case AUDIT_DEVMAJOR: + case AUDIT_DEVMINOR: + case AUDIT_EXIT: + case AUDIT_SUCCESS: + case AUDIT_ARG0: + case AUDIT_ARG1: + case AUDIT_ARG2: + case AUDIT_ARG3: + break; case AUDIT_ARCH: entry->rule.arch_f = f; break; @@ -523,6 +570,20 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, entry->rule.buflen += f->val; entry->rule.filterkey = str; break; + case AUDIT_PERM: + if (f->val & ~15) + goto exit_free; + break; + case AUDIT_FILETYPE: + if (f->val & ~S_IFMT) + goto exit_free; + break; + case AUDIT_FIELD_COMPARE: + if (f->val > AUDIT_MAX_FIELD_COMPARE) + goto exit_free; + break; + default: + goto exit_free; } } @@ -552,6 +613,36 @@ static inline size_t audit_pack_string(void **bufp, const char *str) return len; } +/* Translate kernel rule respresentation to struct audit_rule. + * Exists for backward compatibility with userspace. */ +static struct audit_rule *audit_krule_to_rule(struct audit_krule *krule) +{ + struct audit_rule *rule; + int i; + + rule = kzalloc(sizeof(*rule), GFP_KERNEL); + if (unlikely(!rule)) + return NULL; + + rule->flags = krule->flags | krule->listnr; + rule->action = krule->action; + rule->field_count = krule->field_count; + for (i = 0; i < rule->field_count; i++) { + rule->values[i] = krule->fields[i].val; + rule->fields[i] = krule->fields[i].type; + + if (krule->vers_ops == 1) { + if (krule->fields[i].op == Audit_not_equal) + rule->fields[i] |= AUDIT_NEGATE; + } else { + rule->fields[i] |= audit_ops[krule->fields[i].op]; + } + } + for (i = 0; i < AUDIT_BITMASK_SIZE; i++) rule->mask[i] = krule->mask[i]; + + return rule; +} + /* Translate kernel rule respresentation to struct audit_rule_data. */ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule) { @@ -964,6 +1055,35 @@ static inline int audit_del_rule(struct audit_entry *entry) return ret; } +/* List rules using struct audit_rule. Exists for backward + * compatibility with userspace. */ +static void audit_list(int pid, int seq, struct sk_buff_head *q) +{ + struct sk_buff *skb; + struct audit_krule *r; + int i; + + /* This is a blocking read, so use audit_filter_mutex instead of rcu + * iterator to sync with list writers. */ + for (i=0; irule, !err); + audit_log_rule_change(loginuid, sessionid, sid, "add rule", + &entry->rule, !err); + if (err) audit_free_rule(entry); break; + case AUDIT_DEL: case AUDIT_DEL_RULE: - entry = audit_data_to_entry(data, datasz); + if (type == AUDIT_DEL) + entry = audit_rule_to_entry(data); + else + entry = audit_data_to_entry(data, datasz); if (IS_ERR(entry)) return PTR_ERR(entry); err = audit_del_rule(entry); - audit_log_rule_change("remove rule", &entry->rule, !err); + audit_log_rule_change(loginuid, sessionid, sid, "remove rule", + &entry->rule, !err); + audit_free_rule(entry); break; default: @@ -1211,7 +1358,7 @@ int audit_compare_dname_path(const char *dname, const char *path, int parentlen) return strncmp(p, dname, dlen); } -static int audit_filter_user_rules(struct audit_krule *rule, int type, +static int audit_filter_user_rules(struct audit_krule *rule, enum audit_state *state) { int i; @@ -1235,13 +1382,6 @@ static int audit_filter_user_rules(struct audit_krule *rule, int type, result = audit_uid_comparator(audit_get_loginuid(current), f->op, f->uid); break; - case AUDIT_LOGINUID_SET: - result = audit_comparator(audit_loginuid_set(current), - f->op, f->val); - break; - case AUDIT_MSGTYPE: - result = audit_comparator(type, f->op, f->val); - break; case AUDIT_SUBJ_USER: case AUDIT_SUBJ_ROLE: case AUDIT_SUBJ_TYPE: @@ -1268,7 +1408,7 @@ static int audit_filter_user_rules(struct audit_krule *rule, int type, return 1; } -int audit_filter_user(int type) +int audit_filter_user(void) { enum audit_state state = AUDIT_DISABLED; struct audit_entry *e; @@ -1276,7 +1416,7 @@ int audit_filter_user(int type) rcu_read_lock(); list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_USER], list) { - if (audit_filter_user_rules(&e->rule, type, &state)) { + if (audit_filter_user_rules(&e->rule, &state)) { if (state == AUDIT_DISABLED) ret = 0; break; diff --git a/trunk/kernel/auditsc.c b/trunk/kernel/auditsc.c index 3c8a601324a2..c68229411a7c 100644 --- a/trunk/kernel/auditsc.c +++ b/trunk/kernel/auditsc.c @@ -76,6 +76,11 @@ #define AUDITSC_SUCCESS 1 #define AUDITSC_FAILURE 2 +/* AUDIT_NAMES is the number of slots we reserve in the audit_context + * for saving names from getname(). If we get more names we will allocate + * a name dynamically and also add those to the list anchored by names_list. */ +#define AUDIT_NAMES 5 + /* no execve audit message should be longer than this (userspace limits) */ #define MAX_EXECVE_AUDIT_LEN 7500 @@ -85,6 +90,44 @@ int audit_n_rules; /* determines whether we collect data for signals sent */ int audit_signals; +struct audit_cap_data { + kernel_cap_t permitted; + kernel_cap_t inheritable; + union { + unsigned int fE; /* effective bit of a file capability */ + kernel_cap_t effective; /* effective set of a process */ + }; +}; + +/* When fs/namei.c:getname() is called, we store the pointer in name and + * we don't let putname() free it (instead we free all of the saved + * pointers at syscall exit time). + * + * Further, in fs/namei.c:path_lookup() we store the inode and device. + */ +struct audit_names { + struct list_head list; /* audit_context->names_list */ + struct filename *name; + unsigned long ino; + dev_t dev; + umode_t mode; + kuid_t uid; + kgid_t gid; + dev_t rdev; + u32 osid; + struct audit_cap_data fcap; + unsigned int fcap_ver; + int name_len; /* number of name's characters to log */ + unsigned char type; /* record type */ + bool name_put; /* call __putname() for this name */ + /* + * This was an allocated audit_names and not from the array of + * names allocated in the task audit context. Thus this name + * should be freed on syscall exit + */ + bool should_free; +}; + struct audit_aux_data { struct audit_aux_data *next; int type; @@ -132,6 +175,106 @@ struct audit_tree_refs { struct audit_chunk *c[31]; }; +/* The per-task audit context. */ +struct audit_context { + int dummy; /* must be the first element */ + int in_syscall; /* 1 if task is in a syscall */ + enum audit_state state, current_state; + unsigned int serial; /* serial number for record */ + int major; /* syscall number */ + struct timespec ctime; /* time of syscall entry */ + unsigned long argv[4]; /* syscall arguments */ + long return_code;/* syscall return code */ + u64 prio; + int return_valid; /* return code is valid */ + /* + * The names_list is the list of all audit_names collected during this + * syscall. The first AUDIT_NAMES entries in the names_list will + * actually be from the preallocated_names array for performance + * reasons. Except during allocation they should never be referenced + * through the preallocated_names array and should only be found/used + * by running the names_list. + */ + struct audit_names preallocated_names[AUDIT_NAMES]; + int name_count; /* total records in names_list */ + struct list_head names_list; /* anchor for struct audit_names->list */ + char * filterkey; /* key for rule that triggered record */ + struct path pwd; + struct audit_aux_data *aux; + struct audit_aux_data *aux_pids; + struct sockaddr_storage *sockaddr; + size_t sockaddr_len; + /* Save things to print about task_struct */ + pid_t pid, ppid; + kuid_t uid, euid, suid, fsuid; + kgid_t gid, egid, sgid, fsgid; + unsigned long personality; + int arch; + + pid_t target_pid; + kuid_t target_auid; + kuid_t target_uid; + unsigned int target_sessionid; + u32 target_sid; + char target_comm[TASK_COMM_LEN]; + + struct audit_tree_refs *trees, *first_trees; + struct list_head killed_trees; + int tree_count; + + int type; + union { + struct { + int nargs; + long args[6]; + } socketcall; + struct { + kuid_t uid; + kgid_t gid; + umode_t mode; + u32 osid; + int has_perm; + uid_t perm_uid; + gid_t perm_gid; + umode_t perm_mode; + unsigned long qbytes; + } ipc; + struct { + mqd_t mqdes; + struct mq_attr mqstat; + } mq_getsetattr; + struct { + mqd_t mqdes; + int sigev_signo; + } mq_notify; + struct { + mqd_t mqdes; + size_t msg_len; + unsigned int msg_prio; + struct timespec abs_timeout; + } mq_sendrecv; + struct { + int oflag; + umode_t mode; + struct mq_attr attr; + } mq_open; + struct { + pid_t pid; + struct audit_cap_data cap; + } capset; + struct { + int fd; + int flags; + } mmap; + }; + int fds[2]; + +#if AUDIT_DEBUG + int put_count; + int ino_count; +#endif +}; + static inline int open_arg(int flags, int mask) { int n = ACC_MODE(flags); @@ -490,23 +633,9 @@ static int audit_filter_rules(struct task_struct *tsk, break; case AUDIT_GID: result = audit_gid_comparator(cred->gid, f->op, f->gid); - if (f->op == Audit_equal) { - if (!result) - result = in_group_p(f->gid); - } else if (f->op == Audit_not_equal) { - if (result) - result = !in_group_p(f->gid); - } break; case AUDIT_EGID: result = audit_gid_comparator(cred->egid, f->op, f->gid); - if (f->op == Audit_equal) { - if (!result) - result = in_egroup_p(f->gid); - } else if (f->op == Audit_not_equal) { - if (result) - result = !in_egroup_p(f->gid); - } break; case AUDIT_SGID: result = audit_gid_comparator(cred->sgid, f->op, f->gid); @@ -613,9 +742,6 @@ static int audit_filter_rules(struct task_struct *tsk, if (ctx) result = audit_uid_comparator(tsk->loginuid, f->op, f->uid); break; - case AUDIT_LOGINUID_SET: - result = audit_comparator(audit_loginuid_set(tsk), f->op, f->val); - break; case AUDIT_SUBJ_USER: case AUDIT_SUBJ_ROLE: case AUDIT_SUBJ_TYPE: @@ -861,8 +987,6 @@ static inline void audit_free_names(struct audit_context *context) #if AUDIT_DEBUG == 2 if (context->put_count + context->ino_count != context->name_count) { - int i = 0; - printk(KERN_ERR "%s:%d(:%d): major=%d in_syscall=%d" " name_count=%d put_count=%d" " ino_count=%d [NOT freeing]\n", @@ -871,7 +995,7 @@ static inline void audit_free_names(struct audit_context *context) context->name_count, context->put_count, context->ino_count); list_for_each_entry(n, &context->names_list, list) { - printk(KERN_ERR "names[%d] = %p = %s\n", i++, + printk(KERN_ERR "names[%d] = %p = %s\n", i, n->name, n->name->name ?: "(null)"); } dump_stack(); @@ -886,7 +1010,7 @@ static inline void audit_free_names(struct audit_context *context) list_for_each_entry_safe(n, next, &context->names_list, list) { list_del(&n->list); if (n->name && n->name_put) - final_putname(n->name); + __putname(n->name); if (n->should_free) kfree(n); } @@ -969,6 +1093,88 @@ static inline void audit_free_context(struct audit_context *context) kfree(context); } +void audit_log_task_context(struct audit_buffer *ab) +{ + char *ctx = NULL; + unsigned len; + int error; + u32 sid; + + security_task_getsecid(current, &sid); + if (!sid) + return; + + error = security_secid_to_secctx(sid, &ctx, &len); + if (error) { + if (error != -EINVAL) + goto error_path; + return; + } + + audit_log_format(ab, " subj=%s", ctx); + security_release_secctx(ctx, len); + return; + +error_path: + audit_panic("error in audit_log_task_context"); + return; +} + +EXPORT_SYMBOL(audit_log_task_context); + +void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk) +{ + const struct cred *cred; + char name[sizeof(tsk->comm)]; + struct mm_struct *mm = tsk->mm; + char *tty; + + if (!ab) + return; + + /* tsk == current */ + cred = current_cred(); + + spin_lock_irq(&tsk->sighand->siglock); + if (tsk->signal && tsk->signal->tty) + tty = tsk->signal->tty->name; + else + tty = "(none)"; + spin_unlock_irq(&tsk->sighand->siglock); + + + audit_log_format(ab, + " ppid=%ld pid=%d auid=%u uid=%u gid=%u" + " euid=%u suid=%u fsuid=%u" + " egid=%u sgid=%u fsgid=%u ses=%u tty=%s", + sys_getppid(), + tsk->pid, + from_kuid(&init_user_ns, tsk->loginuid), + from_kuid(&init_user_ns, cred->uid), + from_kgid(&init_user_ns, cred->gid), + from_kuid(&init_user_ns, cred->euid), + from_kuid(&init_user_ns, cred->suid), + from_kuid(&init_user_ns, cred->fsuid), + from_kgid(&init_user_ns, cred->egid), + from_kgid(&init_user_ns, cred->sgid), + from_kgid(&init_user_ns, cred->fsgid), + tsk->sessionid, tty); + + get_task_comm(name, tsk); + audit_log_format(ab, " comm="); + audit_log_untrustedstring(ab, name); + + if (mm) { + down_read(&mm->mmap_sem); + if (mm->exe_file) + audit_log_d_path(ab, " exe=", &mm->exe_file->f_path); + up_read(&mm->mmap_sem); + } + audit_log_task_context(ab); +} + +EXPORT_SYMBOL(audit_log_task_info); + static int audit_log_pid_context(struct audit_context *context, pid_t pid, kuid_t auid, kuid_t uid, unsigned int sessionid, u32 sid, char *comm) @@ -985,14 +1191,12 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, from_kuid(&init_user_ns, auid), from_kuid(&init_user_ns, uid), sessionid); - if (sid) { - if (security_secid_to_secctx(sid, &ctx, &len)) { - audit_log_format(ab, " obj=(none)"); - rc = 1; - } else { - audit_log_format(ab, " obj=%s", ctx); - security_release_secctx(ctx, len); - } + if (security_secid_to_secctx(sid, &ctx, &len)) { + audit_log_format(ab, " obj=(none)"); + rc = 1; + } else { + audit_log_format(ab, " obj=%s", ctx); + security_release_secctx(ctx, len); } audit_log_format(ab, " ocomm="); audit_log_untrustedstring(ab, comm); @@ -1186,6 +1390,35 @@ static void audit_log_execve_info(struct audit_context *context, kfree(buf); } +static void audit_log_cap(struct audit_buffer *ab, char *prefix, kernel_cap_t *cap) +{ + int i; + + audit_log_format(ab, " %s=", prefix); + CAP_FOR_EACH_U32(i) { + audit_log_format(ab, "%08x", cap->cap[(_KERNEL_CAPABILITY_U32S-1) - i]); + } +} + +static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) +{ + kernel_cap_t *perm = &name->fcap.permitted; + kernel_cap_t *inh = &name->fcap.inheritable; + int log = 0; + + if (!cap_isclear(*perm)) { + audit_log_cap(ab, "cap_fp", perm); + log = 1; + } + if (!cap_isclear(*inh)) { + audit_log_cap(ab, "cap_fi", inh); + log = 1; + } + + if (log) + audit_log_format(ab, " cap_fe=%d cap_fver=%x", name->fcap.fE, name->fcap_ver); +} + static void show_special(struct audit_context *context, int *call_panic) { struct audit_buffer *ab; @@ -1283,6 +1516,68 @@ static void show_special(struct audit_context *context, int *call_panic) audit_log_end(ab); } +static void audit_log_name(struct audit_context *context, struct audit_names *n, + int record_num, int *call_panic) +{ + struct audit_buffer *ab; + ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH); + if (!ab) + return; /* audit_panic has been called */ + + audit_log_format(ab, "item=%d", record_num); + + if (n->name) { + switch (n->name_len) { + case AUDIT_NAME_FULL: + /* log the full path */ + audit_log_format(ab, " name="); + audit_log_untrustedstring(ab, n->name->name); + break; + case 0: + /* name was specified as a relative path and the + * directory component is the cwd */ + audit_log_d_path(ab, " name=", &context->pwd); + break; + default: + /* log the name's directory component */ + audit_log_format(ab, " name="); + audit_log_n_untrustedstring(ab, n->name->name, + n->name_len); + } + } else + audit_log_format(ab, " name=(null)"); + + if (n->ino != (unsigned long)-1) { + audit_log_format(ab, " inode=%lu" + " dev=%02x:%02x mode=%#ho" + " ouid=%u ogid=%u rdev=%02x:%02x", + n->ino, + MAJOR(n->dev), + MINOR(n->dev), + n->mode, + from_kuid(&init_user_ns, n->uid), + from_kgid(&init_user_ns, n->gid), + MAJOR(n->rdev), + MINOR(n->rdev)); + } + if (n->osid != 0) { + char *ctx = NULL; + u32 len; + if (security_secid_to_secctx( + n->osid, &ctx, &len)) { + audit_log_format(ab, " osid=%u", n->osid); + *call_panic = 2; + } else { + audit_log_format(ab, " obj=%s", ctx); + security_release_secctx(ctx, len); + } + } + + audit_log_fcaps(ab, n); + + audit_log_end(ab); +} + static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) { int i, call_panic = 0; @@ -1400,7 +1695,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts i = 0; list_for_each_entry(n, &context->names_list, list) - audit_log_name(context, n, NULL, i++, &call_panic); + audit_log_name(context, n, i++, &call_panic); /* Send end of event record to help user space know we are finished */ ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE); @@ -1735,18 +2030,18 @@ void audit_putname(struct filename *name) BUG_ON(!context); if (!context->in_syscall) { #if AUDIT_DEBUG == 2 - printk(KERN_ERR "%s:%d(:%d): final_putname(%p)\n", + printk(KERN_ERR "%s:%d(:%d): __putname(%p)\n", __FILE__, __LINE__, context->serial, name); if (context->name_count) { struct audit_names *n; - int i = 0; + int i; list_for_each_entry(n, &context->names_list, list) - printk(KERN_ERR "name[%d] = %p = %s\n", i++, + printk(KERN_ERR "name[%d] = %p = %s\n", i, n->name, n->name->name ?: "(null)"); } #endif - final_putname(name); + __putname(name); } #if AUDIT_DEBUG else { @@ -1765,6 +2060,41 @@ void audit_putname(struct filename *name) #endif } +static inline int audit_copy_fcaps(struct audit_names *name, const struct dentry *dentry) +{ + struct cpu_vfs_cap_data caps; + int rc; + + if (!dentry) + return 0; + + rc = get_vfs_caps_from_disk(dentry, &caps); + if (rc) + return rc; + + name->fcap.permitted = caps.permitted; + name->fcap.inheritable = caps.inheritable; + name->fcap.fE = !!(caps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE); + name->fcap_ver = (caps.magic_etc & VFS_CAP_REVISION_MASK) >> VFS_CAP_REVISION_SHIFT; + + return 0; +} + + +/* Copy inode data into an audit_names. */ +static void audit_copy_inode(struct audit_names *name, const struct dentry *dentry, + const struct inode *inode) +{ + name->ino = inode->i_ino; + name->dev = inode->i_sb->s_dev; + name->mode = inode->i_mode; + name->uid = inode->i_uid; + name->gid = inode->i_gid; + name->rdev = inode->i_rdev; + security_inode_getsecid(inode, &name->osid); + audit_copy_fcaps(name, dentry); +} + /** * __audit_inode - store the inode and device from a lookup * @name: name being audited @@ -1973,7 +2303,7 @@ int audit_set_loginuid(kuid_t loginuid) unsigned int sessionid; #ifdef CONFIG_AUDIT_LOGINUID_IMMUTABLE - if (audit_loginuid_set(task)) + if (uid_valid(task->loginuid)) return -EPERM; #else /* CONFIG_AUDIT_LOGINUID_IMMUTABLE */ if (!capable(CAP_AUDIT_CONTROL)) @@ -2141,20 +2471,17 @@ int __audit_bprm(struct linux_binprm *bprm) /** * audit_socketcall - record audit data for sys_socketcall - * @nargs: number of args, which should not be more than AUDITSC_ARGS. + * @nargs: number of args * @args: args array * */ -int __audit_socketcall(int nargs, unsigned long *args) +void __audit_socketcall(int nargs, unsigned long *args) { struct audit_context *context = current->audit_context; - if (nargs <= 0 || nargs > AUDITSC_ARGS || !args) - return -EINVAL; context->type = AUDIT_SOCKETCALL; context->socketcall.nargs = nargs; memcpy(context->socketcall.args, args, nargs * sizeof(unsigned long)); - return 0; } /** diff --git a/trunk/kernel/trace/Kconfig b/trunk/kernel/trace/Kconfig index 015f85aaca08..5e9efd4b83a4 100644 --- a/trunk/kernel/trace/Kconfig +++ b/trunk/kernel/trace/Kconfig @@ -71,7 +71,6 @@ config TRACE_CLOCK config RING_BUFFER bool select TRACE_CLOCK - select IRQ_WORK config FTRACE_NMI_ENTER bool @@ -108,6 +107,7 @@ config TRACING select BINARY_PRINTF select EVENT_TRACING select TRACE_CLOCK + select IRQ_WORK config GENERIC_TRACER bool diff --git a/trunk/kernel/trace/ftrace.c b/trunk/kernel/trace/ftrace.c index b549b0f5b977..8a5c017bb50c 100644 --- a/trunk/kernel/trace/ftrace.c +++ b/trunk/kernel/trace/ftrace.c @@ -64,13 +64,6 @@ #define FL_GLOBAL_CONTROL_MASK (FTRACE_OPS_FL_GLOBAL | FTRACE_OPS_FL_CONTROL) -#ifdef CONFIG_DYNAMIC_FTRACE -#define INIT_REGEX_LOCK(opsname) \ - .regex_lock = __MUTEX_INITIALIZER(opsname.regex_lock), -#else -#define INIT_REGEX_LOCK(opsname) -#endif - static struct ftrace_ops ftrace_list_end __read_mostly = { .func = ftrace_stub, .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_STUB, @@ -138,16 +131,6 @@ static void ftrace_ops_no_ops(unsigned long ip, unsigned long parent_ip); while (likely(op = rcu_dereference_raw((op)->next)) && \ unlikely((op) != &ftrace_list_end)) -static inline void ftrace_ops_init(struct ftrace_ops *ops) -{ -#ifdef CONFIG_DYNAMIC_FTRACE - if (!(ops->flags & FTRACE_OPS_FL_INITIALIZED)) { - mutex_init(&ops->regex_lock); - ops->flags |= FTRACE_OPS_FL_INITIALIZED; - } -#endif -} - /** * ftrace_nr_registered_ops - return number of ops registered * @@ -924,8 +907,7 @@ static void unregister_ftrace_profiler(void) #else static struct ftrace_ops ftrace_profile_ops __read_mostly = { .func = function_profile_call, - .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_INITIALIZED, - INIT_REGEX_LOCK(ftrace_profile_ops) + .flags = FTRACE_OPS_FL_RECURSION_SAFE, }; static int register_ftrace_profiler(void) @@ -1121,10 +1103,11 @@ static struct ftrace_ops global_ops = { .func = ftrace_stub, .notrace_hash = EMPTY_HASH, .filter_hash = EMPTY_HASH, - .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_INITIALIZED, - INIT_REGEX_LOCK(global_ops) + .flags = FTRACE_OPS_FL_RECURSION_SAFE, }; +static DEFINE_MUTEX(ftrace_regex_lock); + struct ftrace_page { struct ftrace_page *next; struct dyn_ftrace *records; @@ -1264,7 +1247,6 @@ static void free_ftrace_hash_rcu(struct ftrace_hash *hash) void ftrace_free_filter(struct ftrace_ops *ops) { - ftrace_ops_init(ops); free_ftrace_hash(ops->filter_hash); free_ftrace_hash(ops->notrace_hash); } @@ -2459,7 +2441,7 @@ t_next(struct seq_file *m, void *v, loff_t *pos) !ftrace_lookup_ip(ops->notrace_hash, rec->ip)) || ((iter->flags & FTRACE_ITER_ENABLED) && - !(rec->flags & FTRACE_FL_ENABLED))) { + !(rec->flags & ~FTRACE_FL_MASK))) { rec = NULL; goto retry; @@ -2642,8 +2624,6 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag, struct ftrace_hash *hash; int ret = 0; - ftrace_ops_init(ops); - if (unlikely(ftrace_disabled)) return -ENODEV; @@ -2656,26 +2636,28 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag, return -ENOMEM; } - iter->ops = ops; - iter->flags = flag; - - mutex_lock(&ops->regex_lock); - if (flag & FTRACE_ITER_NOTRACE) hash = ops->notrace_hash; else hash = ops->filter_hash; + iter->ops = ops; + iter->flags = flag; + if (file->f_mode & FMODE_WRITE) { + mutex_lock(&ftrace_lock); iter->hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, hash); + mutex_unlock(&ftrace_lock); + if (!iter->hash) { trace_parser_put(&iter->parser); kfree(iter); - ret = -ENOMEM; - goto out_unlock; + return -ENOMEM; } } + mutex_lock(&ftrace_regex_lock); + if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) ftrace_filter_reset(iter->hash); @@ -2695,9 +2677,7 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag, } } else file->private_data = iter; - - out_unlock: - mutex_unlock(&ops->regex_lock); + mutex_unlock(&ftrace_regex_lock); return ret; } @@ -2930,8 +2910,6 @@ static void function_trace_probe_call(unsigned long ip, unsigned long parent_ip, static struct ftrace_ops trace_probe_ops __read_mostly = { .func = function_trace_probe_call, - .flags = FTRACE_OPS_FL_INITIALIZED, - INIT_REGEX_LOCK(trace_probe_ops) }; static int ftrace_probe_registered; @@ -2941,12 +2919,8 @@ static void __enable_ftrace_function_probe(void) int ret; int i; - if (ftrace_probe_registered) { - /* still need to update the function call sites */ - if (ftrace_enabled) - ftrace_run_update_code(FTRACE_UPDATE_CALLS); + if (ftrace_probe_registered) return; - } for (i = 0; i < FTRACE_FUNC_HASHSIZE; i++) { struct hlist_head *hhd = &ftrace_func_hash[i]; @@ -3016,21 +2990,19 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, if (WARN_ON(not)) return -EINVAL; - mutex_lock(&trace_probe_ops.regex_lock); + mutex_lock(&ftrace_lock); hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, *orig_hash); if (!hash) { count = -ENOMEM; - goto out; + goto out_unlock; } if (unlikely(ftrace_disabled)) { count = -ENODEV; - goto out; + goto out_unlock; } - mutex_lock(&ftrace_lock); - do_for_each_ftrace_rec(pg, rec) { if (!ftrace_match_record(rec, NULL, search, len, type)) @@ -3084,8 +3056,6 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, out_unlock: mutex_unlock(&ftrace_lock); - out: - mutex_unlock(&trace_probe_ops.regex_lock); free_ftrace_hash(hash); return count; @@ -3125,7 +3095,7 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, return; } - mutex_lock(&trace_probe_ops.regex_lock); + mutex_lock(&ftrace_lock); hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, *orig_hash); if (!hash) @@ -3163,7 +3133,6 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, list_add(&entry->free_list, &free_list); } } - mutex_lock(&ftrace_lock); __disable_ftrace_function_probe(); /* * Remove after the disable is called. Otherwise, if the last @@ -3175,10 +3144,9 @@ __unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops, list_del(&entry->free_list); ftrace_free_entry(entry); } - mutex_unlock(&ftrace_lock); out_unlock: - mutex_unlock(&trace_probe_ops.regex_lock); + mutex_unlock(&ftrace_lock); free_ftrace_hash(hash); } @@ -3288,17 +3256,18 @@ ftrace_regex_write(struct file *file, const char __user *ubuf, if (!cnt) return 0; + mutex_lock(&ftrace_regex_lock); + + ret = -ENODEV; + if (unlikely(ftrace_disabled)) + goto out_unlock; + if (file->f_mode & FMODE_READ) { struct seq_file *m = file->private_data; iter = m->private; } else iter = file->private_data; - if (unlikely(ftrace_disabled)) - return -ENODEV; - - /* iter->hash is a local copy, so we don't need regex_lock */ - parser = &iter->parser; read = trace_get_user(parser, ubuf, cnt, ppos); @@ -3307,12 +3276,14 @@ ftrace_regex_write(struct file *file, const char __user *ubuf, ret = ftrace_process_regex(iter->hash, parser->buffer, parser->idx, enable); trace_parser_clear(parser); - if (ret < 0) - goto out; + if (ret) + goto out_unlock; } ret = read; - out: +out_unlock: + mutex_unlock(&ftrace_regex_lock); + return ret; } @@ -3364,19 +3335,16 @@ ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len, if (unlikely(ftrace_disabled)) return -ENODEV; - mutex_lock(&ops->regex_lock); - if (enable) orig_hash = &ops->filter_hash; else orig_hash = &ops->notrace_hash; hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, *orig_hash); - if (!hash) { - ret = -ENOMEM; - goto out_regex_unlock; - } + if (!hash) + return -ENOMEM; + mutex_lock(&ftrace_regex_lock); if (reset) ftrace_filter_reset(hash); if (buf && !ftrace_match_records(hash, buf, len)) { @@ -3398,7 +3366,7 @@ ftrace_set_hash(struct ftrace_ops *ops, unsigned char *buf, int len, mutex_unlock(&ftrace_lock); out_regex_unlock: - mutex_unlock(&ops->regex_lock); + mutex_unlock(&ftrace_regex_lock); free_ftrace_hash(hash); return ret; @@ -3424,7 +3392,6 @@ ftrace_set_addr(struct ftrace_ops *ops, unsigned long ip, int remove, int ftrace_set_filter_ip(struct ftrace_ops *ops, unsigned long ip, int remove, int reset) { - ftrace_ops_init(ops); return ftrace_set_addr(ops, ip, remove, reset, 1); } EXPORT_SYMBOL_GPL(ftrace_set_filter_ip); @@ -3449,7 +3416,6 @@ ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len, int ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf, int len, int reset) { - ftrace_ops_init(ops); return ftrace_set_regex(ops, buf, len, reset, 1); } EXPORT_SYMBOL_GPL(ftrace_set_filter); @@ -3468,7 +3434,6 @@ EXPORT_SYMBOL_GPL(ftrace_set_filter); int ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf, int len, int reset) { - ftrace_ops_init(ops); return ftrace_set_regex(ops, buf, len, reset, 0); } EXPORT_SYMBOL_GPL(ftrace_set_notrace); @@ -3559,8 +3524,6 @@ ftrace_set_early_filter(struct ftrace_ops *ops, char *buf, int enable) { char *func; - ftrace_ops_init(ops); - while (buf) { func = strsep(&buf, ","); ftrace_set_regex(ops, func, strlen(func), 0, enable); @@ -3588,8 +3551,10 @@ int ftrace_regex_release(struct inode *inode, struct file *file) int filter_hash; int ret; + mutex_lock(&ftrace_regex_lock); if (file->f_mode & FMODE_READ) { iter = m->private; + seq_release(inode, file); } else iter = file->private_data; @@ -3602,8 +3567,6 @@ int ftrace_regex_release(struct inode *inode, struct file *file) trace_parser_put(parser); - mutex_lock(&iter->ops->regex_lock); - if (file->f_mode & FMODE_WRITE) { filter_hash = !!(iter->flags & FTRACE_ITER_FILTER); @@ -3621,11 +3584,10 @@ int ftrace_regex_release(struct inode *inode, struct file *file) mutex_unlock(&ftrace_lock); } - - mutex_unlock(&iter->ops->regex_lock); free_ftrace_hash(iter->hash); kfree(iter); + mutex_unlock(&ftrace_regex_lock); return 0; } @@ -4164,8 +4126,7 @@ void __init ftrace_init(void) static struct ftrace_ops global_ops = { .func = ftrace_stub, - .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_INITIALIZED, - INIT_REGEX_LOCK(global_ops) + .flags = FTRACE_OPS_FL_RECURSION_SAFE, }; static int __init ftrace_nodyn_init(void) @@ -4219,9 +4180,8 @@ ftrace_ops_control_func(unsigned long ip, unsigned long parent_ip, } static struct ftrace_ops control_ops = { - .func = ftrace_ops_control_func, - .flags = FTRACE_OPS_FL_RECURSION_SAFE | FTRACE_OPS_FL_INITIALIZED, - INIT_REGEX_LOCK(control_ops) + .func = ftrace_ops_control_func, + .flags = FTRACE_OPS_FL_RECURSION_SAFE, }; static inline void @@ -4579,8 +4539,6 @@ int register_ftrace_function(struct ftrace_ops *ops) { int ret = -1; - ftrace_ops_init(ops); - mutex_lock(&ftrace_lock); ret = __register_ftrace_function(ops); diff --git a/trunk/kernel/trace/trace_events.c b/trunk/kernel/trace/trace_events.c index 7a0cf68027cc..53582e982e51 100644 --- a/trunk/kernel/trace/trace_events.c +++ b/trunk/kernel/trace/trace_events.c @@ -251,8 +251,7 @@ static int __ftrace_event_enable_disable(struct ftrace_event_file *file, switch (enable) { case 0: /* - * When soft_disable is set and enable is cleared, the sm_ref - * reference counter is decremented. If it reaches 0, we want + * When soft_disable is set and enable is cleared, we want * to clear the SOFT_DISABLED flag but leave the event in the * state that it was. That is, if the event was enabled and * SOFT_DISABLED isn't set, then do nothing. But if SOFT_DISABLED @@ -264,8 +263,6 @@ static int __ftrace_event_enable_disable(struct ftrace_event_file *file, * "soft enable"s (clearing the SOFT_DISABLED bit) wont work. */ if (soft_disable) { - if (atomic_dec_return(&file->sm_ref) > 0) - break; disable = file->flags & FTRACE_EVENT_FL_SOFT_DISABLED; clear_bit(FTRACE_EVENT_FL_SOFT_MODE_BIT, &file->flags); } else @@ -294,11 +291,8 @@ static int __ftrace_event_enable_disable(struct ftrace_event_file *file, */ if (!soft_disable) clear_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &file->flags); - else { - if (atomic_inc_return(&file->sm_ref) > 1) - break; + else set_bit(FTRACE_EVENT_FL_SOFT_MODE_BIT, &file->flags); - } if (!(file->flags & FTRACE_EVENT_FL_ENABLED)) { @@ -629,8 +623,6 @@ event_enable_read(struct file *filp, char __user *ubuf, size_t cnt, if (file->flags & FTRACE_EVENT_FL_ENABLED) { if (file->flags & FTRACE_EVENT_FL_SOFT_DISABLED) buf = "0*\n"; - else if (file->flags & FTRACE_EVENT_FL_SOFT_MODE) - buf = "1*\n"; else buf = "1\n"; } else @@ -1529,24 +1521,6 @@ __register_event(struct ftrace_event_call *call, struct module *mod) return 0; } -static struct ftrace_event_file * -trace_create_new_event(struct ftrace_event_call *call, - struct trace_array *tr) -{ - struct ftrace_event_file *file; - - file = kmem_cache_alloc(file_cachep, GFP_TRACE); - if (!file) - return NULL; - - file->event_call = call; - file->tr = tr; - atomic_set(&file->sm_ref, 0); - list_add(&file->list, &tr->events); - - return file; -} - /* Add an event to a trace directory */ static int __trace_add_new_event(struct ftrace_event_call *call, @@ -1558,10 +1532,14 @@ __trace_add_new_event(struct ftrace_event_call *call, { struct ftrace_event_file *file; - file = trace_create_new_event(call, tr); + file = kmem_cache_alloc(file_cachep, GFP_TRACE); if (!file) return -ENOMEM; + file->event_call = call; + file->tr = tr; + list_add(&file->list, &tr->events); + return event_create_dir(tr->event_dir, file, id, enable, filter, format); } @@ -1576,10 +1554,14 @@ __trace_early_add_new_event(struct ftrace_event_call *call, { struct ftrace_event_file *file; - file = trace_create_new_event(call, tr); + file = kmem_cache_alloc(file_cachep, GFP_TRACE); if (!file) return -ENOMEM; + file->event_call = call; + file->tr = tr; + list_add(&file->list, &tr->events); + return 0; } @@ -2079,18 +2061,8 @@ event_enable_func(struct ftrace_hash *hash, if (ret < 0) goto out_put; ret = register_ftrace_function_probe(glob, ops, data); - /* - * The above returns on success the # of functions enabled, - * but if it didn't find any functions it returns zero. - * Consider no functions a failure too. - */ - if (!ret) { - ret = -ENOENT; - goto out_disable; - } else if (ret < 0) + if (!ret) goto out_disable; - /* Just return zero, not the number of enabled functions */ - ret = 0; out: mutex_unlock(&event_mutex); return ret; diff --git a/trunk/kernel/trace/trace_kprobe.c b/trunk/kernel/trace/trace_kprobe.c index 636d45fe69b3..1865d5f76538 100644 --- a/trunk/kernel/trace/trace_kprobe.c +++ b/trunk/kernel/trace/trace_kprobe.c @@ -27,6 +27,7 @@ /** * Kprobe event core functions */ + struct trace_probe { struct list_head list; struct kretprobe rp; /* Use rp.kp for kprobe use */ @@ -35,7 +36,6 @@ struct trace_probe { const char *symbol; /* symbol name */ struct ftrace_event_class class; struct ftrace_event_call call; - struct ftrace_event_file **files; ssize_t size; /* trace entry size */ unsigned int nr_args; struct probe_arg args[]; @@ -46,7 +46,7 @@ struct trace_probe { (sizeof(struct probe_arg) * (n))) -static __kprobes bool trace_probe_is_return(struct trace_probe *tp) +static __kprobes int trace_probe_is_return(struct trace_probe *tp) { return tp->rp.handler != NULL; } @@ -183,57 +183,12 @@ static struct trace_probe *find_trace_probe(const char *event, return NULL; } -static int trace_probe_nr_files(struct trace_probe *tp) -{ - struct ftrace_event_file **file = tp->files; - int ret = 0; - - if (file) - while (*(file++)) - ret++; - - return ret; -} - -static DEFINE_MUTEX(probe_enable_lock); - -/* - * Enable trace_probe - * if the file is NULL, enable "perf" handler, or enable "trace" handler. - */ -static int -enable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file) +/* Enable trace_probe - @flag must be TP_FLAG_TRACE or TP_FLAG_PROFILE */ +static int enable_trace_probe(struct trace_probe *tp, int flag) { int ret = 0; - mutex_lock(&probe_enable_lock); - - if (file) { - struct ftrace_event_file **new, **old = tp->files; - int n = trace_probe_nr_files(tp); - - /* 1 is for new one and 1 is for stopper */ - new = kzalloc((n + 2) * sizeof(struct ftrace_event_file *), - GFP_KERNEL); - if (!new) { - ret = -ENOMEM; - goto out_unlock; - } - memcpy(new, old, n * sizeof(struct ftrace_event_file *)); - new[n] = file; - /* The last one keeps a NULL */ - - rcu_assign_pointer(tp->files, new); - tp->flags |= TP_FLAG_TRACE; - - if (old) { - /* Make sure the probe is done with old files */ - synchronize_sched(); - kfree(old); - } - } else - tp->flags |= TP_FLAG_PROFILE; - + tp->flags |= flag; if (trace_probe_is_enabled(tp) && trace_probe_is_registered(tp) && !trace_probe_has_gone(tp)) { if (trace_probe_is_return(tp)) @@ -242,83 +197,19 @@ enable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file) ret = enable_kprobe(&tp->rp.kp); } - out_unlock: - mutex_unlock(&probe_enable_lock); - return ret; } -static int -trace_probe_file_index(struct trace_probe *tp, struct ftrace_event_file *file) -{ - int i; - - if (tp->files) { - for (i = 0; tp->files[i]; i++) - if (tp->files[i] == file) - return i; - } - - return -1; -} - -/* - * Disable trace_probe - * if the file is NULL, disable "perf" handler, or disable "trace" handler. - */ -static int -disable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file) +/* Disable trace_probe - @flag must be TP_FLAG_TRACE or TP_FLAG_PROFILE */ +static void disable_trace_probe(struct trace_probe *tp, int flag) { - int ret = 0; - - mutex_lock(&probe_enable_lock); - - if (file) { - struct ftrace_event_file **new, **old = tp->files; - int n = trace_probe_nr_files(tp); - int i, j; - - if (n == 0 || trace_probe_file_index(tp, file) < 0) { - ret = -EINVAL; - goto out_unlock; - } - - if (n == 1) { /* Remove the last file */ - tp->flags &= ~TP_FLAG_TRACE; - new = NULL; - } else { - new = kzalloc(n * sizeof(struct ftrace_event_file *), - GFP_KERNEL); - if (!new) { - ret = -ENOMEM; - goto out_unlock; - } - - /* This copy & check loop copies the NULL stopper too */ - for (i = 0, j = 0; j < n && i < n + 1; i++) - if (old[i] != file) - new[j++] = old[i]; - } - - rcu_assign_pointer(tp->files, new); - - /* Make sure the probe is done with old files */ - synchronize_sched(); - kfree(old); - } else - tp->flags &= ~TP_FLAG_PROFILE; - + tp->flags &= ~flag; if (!trace_probe_is_enabled(tp) && trace_probe_is_registered(tp)) { if (trace_probe_is_return(tp)) disable_kretprobe(&tp->rp); else disable_kprobe(&tp->rp.kp); } - - out_unlock: - mutex_unlock(&probe_enable_lock); - - return ret; } /* Internal register function - just handle k*probes and flags */ @@ -832,10 +723,9 @@ static __kprobes void store_trace_args(int ent_size, struct trace_probe *tp, } /* Kprobe handler */ -static __kprobes void -__kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs, - struct ftrace_event_file *ftrace_file) +static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) { + struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp); struct kprobe_trace_entry_head *entry; struct ring_buffer_event *event; struct ring_buffer *buffer; @@ -843,10 +733,7 @@ __kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs, unsigned long irq_flags; struct ftrace_event_call *call = &tp->call; - WARN_ON(call != ftrace_file->event_call); - - if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags)) - return; + tp->nhit++; local_save_flags(irq_flags); pc = preempt_count(); @@ -854,14 +741,13 @@ __kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs, dsize = __get_data_size(tp, regs); size = sizeof(*entry) + tp->size + dsize; - event = trace_event_buffer_lock_reserve(&buffer, ftrace_file, - call->event.type, - size, irq_flags, pc); + event = trace_current_buffer_lock_reserve(&buffer, call->event.type, + size, irq_flags, pc); if (!event) return; entry = ring_buffer_event_data(event); - entry->ip = (unsigned long)tp->rp.kp.addr; + entry->ip = (unsigned long)kp->addr; store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize); if (!filter_current_check_discard(buffer, call, entry, event)) @@ -869,24 +755,11 @@ __kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs, irq_flags, pc, regs); } -static __kprobes void -kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs) -{ - struct ftrace_event_file **file = tp->files; - - /* Note: preempt is already disabled around the kprobe handler */ - while (*file) { - __kprobe_trace_func(tp, regs, *file); - file++; - } -} - /* Kretprobe handler */ -static __kprobes void -__kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri, - struct pt_regs *regs, - struct ftrace_event_file *ftrace_file) +static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri, + struct pt_regs *regs) { + struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp); struct kretprobe_trace_entry_head *entry; struct ring_buffer_event *event; struct ring_buffer *buffer; @@ -894,20 +767,14 @@ __kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri, unsigned long irq_flags; struct ftrace_event_call *call = &tp->call; - WARN_ON(call != ftrace_file->event_call); - - if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags)) - return; - local_save_flags(irq_flags); pc = preempt_count(); dsize = __get_data_size(tp, regs); size = sizeof(*entry) + tp->size + dsize; - event = trace_event_buffer_lock_reserve(&buffer, ftrace_file, - call->event.type, - size, irq_flags, pc); + event = trace_current_buffer_lock_reserve(&buffer, call->event.type, + size, irq_flags, pc); if (!event) return; @@ -921,19 +788,6 @@ __kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri, irq_flags, pc, regs); } -static __kprobes void -kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri, - struct pt_regs *regs) -{ - struct ftrace_event_file **file = tp->files; - - /* Note: preempt is already disabled around the kprobe handler */ - while (*file) { - __kretprobe_trace_func(tp, ri, regs, *file); - file++; - } -} - /* Event entry printers */ enum print_line_t print_kprobe_event(struct trace_iterator *iter, int flags, @@ -1121,9 +975,10 @@ static int set_print_fmt(struct trace_probe *tp) #ifdef CONFIG_PERF_EVENTS /* Kprobe profile handler */ -static __kprobes void -kprobe_perf_func(struct trace_probe *tp, struct pt_regs *regs) +static __kprobes void kprobe_perf_func(struct kprobe *kp, + struct pt_regs *regs) { + struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp); struct ftrace_event_call *call = &tp->call; struct kprobe_trace_entry_head *entry; struct hlist_head *head; @@ -1142,7 +997,7 @@ kprobe_perf_func(struct trace_probe *tp, struct pt_regs *regs) if (!entry) return; - entry->ip = (unsigned long)tp->rp.kp.addr; + entry->ip = (unsigned long)kp->addr; memset(&entry[1], 0, dsize); store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize); @@ -1152,10 +1007,10 @@ kprobe_perf_func(struct trace_probe *tp, struct pt_regs *regs) } /* Kretprobe profile handler */ -static __kprobes void -kretprobe_perf_func(struct trace_probe *tp, struct kretprobe_instance *ri, - struct pt_regs *regs) +static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri, + struct pt_regs *regs) { + struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp); struct ftrace_event_call *call = &tp->call; struct kretprobe_trace_entry_head *entry; struct hlist_head *head; @@ -1189,19 +1044,20 @@ int kprobe_register(struct ftrace_event_call *event, enum trace_reg type, void *data) { struct trace_probe *tp = (struct trace_probe *)event->data; - struct ftrace_event_file *file = data; switch (type) { case TRACE_REG_REGISTER: - return enable_trace_probe(tp, file); + return enable_trace_probe(tp, TP_FLAG_TRACE); case TRACE_REG_UNREGISTER: - return disable_trace_probe(tp, file); + disable_trace_probe(tp, TP_FLAG_TRACE); + return 0; #ifdef CONFIG_PERF_EVENTS case TRACE_REG_PERF_REGISTER: - return enable_trace_probe(tp, NULL); + return enable_trace_probe(tp, TP_FLAG_PROFILE); case TRACE_REG_PERF_UNREGISTER: - return disable_trace_probe(tp, NULL); + disable_trace_probe(tp, TP_FLAG_PROFILE); + return 0; case TRACE_REG_PERF_OPEN: case TRACE_REG_PERF_CLOSE: case TRACE_REG_PERF_ADD: @@ -1217,13 +1073,11 @@ int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs) { struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp); - tp->nhit++; - if (tp->flags & TP_FLAG_TRACE) - kprobe_trace_func(tp, regs); + kprobe_trace_func(kp, regs); #ifdef CONFIG_PERF_EVENTS if (tp->flags & TP_FLAG_PROFILE) - kprobe_perf_func(tp, regs); + kprobe_perf_func(kp, regs); #endif return 0; /* We don't tweek kernel, so just return 0 */ } @@ -1233,13 +1087,11 @@ int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs) { struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp); - tp->nhit++; - if (tp->flags & TP_FLAG_TRACE) - kretprobe_trace_func(tp, ri, regs); + kretprobe_trace_func(ri, regs); #ifdef CONFIG_PERF_EVENTS if (tp->flags & TP_FLAG_PROFILE) - kretprobe_perf_func(tp, ri, regs); + kretprobe_perf_func(ri, regs); #endif return 0; /* We don't tweek kernel, so just return 0 */ } @@ -1337,24 +1189,11 @@ static __used int kprobe_trace_selftest_target(int a1, int a2, int a3, return a1 + a2 + a3 + a4 + a5 + a6; } -static struct ftrace_event_file * -find_trace_probe_file(struct trace_probe *tp, struct trace_array *tr) -{ - struct ftrace_event_file *file; - - list_for_each_entry(file, &tr->events, list) - if (file->event_call == &tp->call) - return file; - - return NULL; -} - static __init int kprobe_trace_self_tests_init(void) { int ret, warn = 0; int (*target)(int, int, int, int, int, int); struct trace_probe *tp; - struct ftrace_event_file *file; target = kprobe_trace_selftest_target; @@ -1364,43 +1203,31 @@ static __init int kprobe_trace_self_tests_init(void) "$stack $stack0 +0($stack)", create_trace_probe); if (WARN_ON_ONCE(ret)) { - pr_warn("error on probing function entry.\n"); + pr_warning("error on probing function entry.\n"); warn++; } else { /* Enable trace point */ tp = find_trace_probe("testprobe", KPROBE_EVENT_SYSTEM); if (WARN_ON_ONCE(tp == NULL)) { - pr_warn("error on getting new probe.\n"); + pr_warning("error on getting new probe.\n"); warn++; - } else { - file = find_trace_probe_file(tp, top_trace_array()); - if (WARN_ON_ONCE(file == NULL)) { - pr_warn("error on getting probe file.\n"); - warn++; - } else - enable_trace_probe(tp, file); - } + } else + enable_trace_probe(tp, TP_FLAG_TRACE); } ret = traceprobe_command("r:testprobe2 kprobe_trace_selftest_target " "$retval", create_trace_probe); if (WARN_ON_ONCE(ret)) { - pr_warn("error on probing function return.\n"); + pr_warning("error on probing function return.\n"); warn++; } else { /* Enable trace point */ tp = find_trace_probe("testprobe2", KPROBE_EVENT_SYSTEM); if (WARN_ON_ONCE(tp == NULL)) { - pr_warn("error on getting 2nd new probe.\n"); + pr_warning("error on getting new probe.\n"); warn++; - } else { - file = find_trace_probe_file(tp, top_trace_array()); - if (WARN_ON_ONCE(file == NULL)) { - pr_warn("error on getting probe file.\n"); - warn++; - } else - enable_trace_probe(tp, file); - } + } else + enable_trace_probe(tp, TP_FLAG_TRACE); } if (warn) @@ -1411,39 +1238,27 @@ static __init int kprobe_trace_self_tests_init(void) /* Disable trace points before removing it */ tp = find_trace_probe("testprobe", KPROBE_EVENT_SYSTEM); if (WARN_ON_ONCE(tp == NULL)) { - pr_warn("error on getting test probe.\n"); + pr_warning("error on getting test probe.\n"); warn++; - } else { - file = find_trace_probe_file(tp, top_trace_array()); - if (WARN_ON_ONCE(file == NULL)) { - pr_warn("error on getting probe file.\n"); - warn++; - } else - disable_trace_probe(tp, file); - } + } else + disable_trace_probe(tp, TP_FLAG_TRACE); tp = find_trace_probe("testprobe2", KPROBE_EVENT_SYSTEM); if (WARN_ON_ONCE(tp == NULL)) { - pr_warn("error on getting 2nd test probe.\n"); + pr_warning("error on getting 2nd test probe.\n"); warn++; - } else { - file = find_trace_probe_file(tp, top_trace_array()); - if (WARN_ON_ONCE(file == NULL)) { - pr_warn("error on getting probe file.\n"); - warn++; - } else - disable_trace_probe(tp, file); - } + } else + disable_trace_probe(tp, TP_FLAG_TRACE); ret = traceprobe_command("-:testprobe", create_trace_probe); if (WARN_ON_ONCE(ret)) { - pr_warn("error on deleting a probe.\n"); + pr_warning("error on deleting a probe.\n"); warn++; } ret = traceprobe_command("-:testprobe2", create_trace_probe); if (WARN_ON_ONCE(ret)) { - pr_warn("error on deleting a probe.\n"); + pr_warning("error on deleting a probe.\n"); warn++; } diff --git a/trunk/net/batman-adv/distributed-arp-table.c b/trunk/net/batman-adv/distributed-arp-table.c index 239992021b1d..8e15d966d9b0 100644 --- a/trunk/net/batman-adv/distributed-arp-table.c +++ b/trunk/net/batman-adv/distributed-arp-table.c @@ -837,19 +837,6 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv, dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst); if (dat_entry) { - /* If the ARP request is destined for a local client the local - * client will answer itself. DAT would only generate a - * duplicate packet. - * - * Moreover, if the soft-interface is enslaved into a bridge, an - * additional DAT answer may trigger kernel warnings about - * a packet coming from the wrong port. - */ - if (batadv_is_my_client(bat_priv, dat_entry->mac_addr)) { - ret = true; - goto out; - } - skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src, bat_priv->soft_iface, ip_dst, hw_src, dat_entry->mac_addr, hw_src); diff --git a/trunk/net/batman-adv/main.c b/trunk/net/batman-adv/main.c index 1240f07ad31d..3e30a0f1b908 100644 --- a/trunk/net/batman-adv/main.c +++ b/trunk/net/batman-adv/main.c @@ -163,22 +163,14 @@ void batadv_mesh_free(struct net_device *soft_iface) batadv_vis_quit(bat_priv); batadv_gw_node_purge(bat_priv); + batadv_originator_free(bat_priv); batadv_nc_free(bat_priv); - batadv_dat_free(bat_priv); - batadv_bla_free(bat_priv); - /* Free the TT and the originator tables only after having terminated - * all the other depending components which may use these structures for - * their purposes. - */ batadv_tt_free(bat_priv); - /* Since the originator table clean up routine is accessing the TT - * tables as well, it has to be invoked after the TT tables have been - * freed and marked as empty. This ensures that no cleanup RCU callbacks - * accessing the TT data are scheduled for later execution. - */ - batadv_originator_free(bat_priv); + batadv_bla_free(bat_priv); + + batadv_dat_free(bat_priv); free_percpu(bat_priv->bat_counters); @@ -483,7 +475,7 @@ static int batadv_param_set_ra(const char *val, const struct kernel_param *kp) char *algo_name = (char *)val; size_t name_len = strlen(algo_name); - if (name_len > 0 && algo_name[name_len - 1] == '\n') + if (algo_name[name_len - 1] == '\n') algo_name[name_len - 1] = '\0'; bat_algo_ops = batadv_algo_get(algo_name); diff --git a/trunk/net/batman-adv/network-coding.c b/trunk/net/batman-adv/network-coding.c index e84629ece9b7..f7c54305a918 100644 --- a/trunk/net/batman-adv/network-coding.c +++ b/trunk/net/batman-adv/network-coding.c @@ -1514,7 +1514,6 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb, struct ethhdr *ethhdr, ethhdr_tmp; uint8_t *orig_dest, ttl, ttvn; unsigned int coding_len; - int err; /* Save headers temporarily */ memcpy(&coded_packet_tmp, skb->data, sizeof(coded_packet_tmp)); @@ -1569,11 +1568,8 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb, coding_len); /* Resize decoded skb if decoded with larger packet */ - if (nc_packet->skb->len > coding_len + h_size) { - err = pskb_trim_rcsum(skb, coding_len + h_size); - if (err) - return NULL; - } + if (nc_packet->skb->len > coding_len + h_size) + pskb_trim_rcsum(skb, coding_len + h_size); /* Create decoded unicast packet */ unicast_packet = (struct batadv_unicast_packet *)skb->data; diff --git a/trunk/net/core/sock.c b/trunk/net/core/sock.c index 6ba327da79e1..d4f4cea726e7 100644 --- a/trunk/net/core/sock.c +++ b/trunk/net/core/sock.c @@ -1217,6 +1217,18 @@ static void sock_copy(struct sock *nsk, const struct sock *osk) #endif } +/* + * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes + * un-modified. Special care is taken when initializing object to zero. + */ +static inline void sk_prot_clear_nulls(struct sock *sk, int size) +{ + if (offsetof(struct sock, sk_node.next) != 0) + memset(sk, 0, offsetof(struct sock, sk_node.next)); + memset(&sk->sk_node.pprev, 0, + size - offsetof(struct sock, sk_node.pprev)); +} + void sk_prot_clear_portaddr_nulls(struct sock *sk, int size) { unsigned long nulls1, nulls2; diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c index 4bcabf3ab4ca..147abf5275aa 100644 --- a/trunk/net/ipv4/ip_output.c +++ b/trunk/net/ipv4/ip_output.c @@ -84,7 +84,7 @@ int sysctl_ip_default_ttl __read_mostly = IPDEFTTL; EXPORT_SYMBOL(sysctl_ip_default_ttl); /* Generate a checksum for an outgoing IP datagram. */ -void ip_send_check(struct iphdr *iph) +__inline__ void ip_send_check(struct iphdr *iph) { iph->check = 0; iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); diff --git a/trunk/net/ipv6/ip6_gre.c b/trunk/net/ipv6/ip6_gre.c index ecd60733e5e2..d3ddd8400354 100644 --- a/trunk/net/ipv6/ip6_gre.c +++ b/trunk/net/ipv6/ip6_gre.c @@ -1081,7 +1081,6 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev, } if (t == NULL) t = netdev_priv(dev); - memset(&p, 0, sizeof(p)); ip6gre_tnl_parm_to_user(&p, &t->parms); if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) err = -EFAULT; @@ -1129,7 +1128,6 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev, if (t) { err = 0; - memset(&p, 0, sizeof(p)); ip6gre_tnl_parm_to_user(&p, &t->parms); if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) err = -EFAULT; diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index 0a17ed9eaf39..71167069b394 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -1890,17 +1890,6 @@ void tcp6_proc_exit(struct net *net) } #endif -static void tcp_v6_clear_sk(struct sock *sk, int size) -{ - struct inet_sock *inet = inet_sk(sk); - - /* we do not want to clear pinet6 field, because of RCU lookups */ - sk_prot_clear_nulls(sk, offsetof(struct inet_sock, pinet6)); - - size -= offsetof(struct inet_sock, pinet6) + sizeof(inet->pinet6); - memset(&inet->pinet6 + 1, 0, size); -} - struct proto tcpv6_prot = { .name = "TCPv6", .owner = THIS_MODULE, @@ -1944,7 +1933,6 @@ struct proto tcpv6_prot = { #ifdef CONFIG_MEMCG_KMEM .proto_cgroup = tcp_proto_cgroup, #endif - .clear_sk = tcp_v6_clear_sk, }; static const struct inet6_protocol tcpv6_protocol = { diff --git a/trunk/net/ipv6/udp.c b/trunk/net/ipv6/udp.c index 42923b14dfa6..d4defdd44937 100644 --- a/trunk/net/ipv6/udp.c +++ b/trunk/net/ipv6/udp.c @@ -1432,17 +1432,6 @@ void udp6_proc_exit(struct net *net) { } #endif /* CONFIG_PROC_FS */ -void udp_v6_clear_sk(struct sock *sk, int size) -{ - struct inet_sock *inet = inet_sk(sk); - - /* we do not want to clear pinet6 field, because of RCU lookups */ - sk_prot_clear_portaddr_nulls(sk, offsetof(struct inet_sock, pinet6)); - - size -= offsetof(struct inet_sock, pinet6) + sizeof(inet->pinet6); - memset(&inet->pinet6 + 1, 0, size); -} - /* ------------------------------------------------------------------------ */ struct proto udpv6_prot = { @@ -1473,7 +1462,7 @@ struct proto udpv6_prot = { .compat_setsockopt = compat_udpv6_setsockopt, .compat_getsockopt = compat_udpv6_getsockopt, #endif - .clear_sk = udp_v6_clear_sk, + .clear_sk = sk_prot_clear_portaddr_nulls, }; static struct inet_protosw udpv6_protosw = { diff --git a/trunk/net/ipv6/udp_impl.h b/trunk/net/ipv6/udp_impl.h index 4691ed50a928..d7571046bfc4 100644 --- a/trunk/net/ipv6/udp_impl.h +++ b/trunk/net/ipv6/udp_impl.h @@ -31,8 +31,6 @@ extern int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, extern int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb); extern void udpv6_destroy_sock(struct sock *sk); -extern void udp_v6_clear_sk(struct sock *sk, int size); - #ifdef CONFIG_PROC_FS extern int udp6_seq_show(struct seq_file *seq, void *v); #endif diff --git a/trunk/net/ipv6/udplite.c b/trunk/net/ipv6/udplite.c index dfcc4be46898..1d08e21d9f69 100644 --- a/trunk/net/ipv6/udplite.c +++ b/trunk/net/ipv6/udplite.c @@ -56,7 +56,7 @@ struct proto udplitev6_prot = { .compat_setsockopt = compat_udpv6_setsockopt, .compat_getsockopt = compat_udpv6_getsockopt, #endif - .clear_sk = udp_v6_clear_sk, + .clear_sk = sk_prot_clear_portaddr_nulls, }; static struct inet_protosw udplite6_protosw = { diff --git a/trunk/net/ipv6/xfrm6_policy.c b/trunk/net/ipv6/xfrm6_policy.c index 23ed03d786c8..4ef7bdb65440 100644 --- a/trunk/net/ipv6/xfrm6_policy.c +++ b/trunk/net/ipv6/xfrm6_policy.c @@ -103,10 +103,8 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, dev_hold(dev); xdst->u.rt6.rt6i_idev = in6_dev_get(dev); - if (!xdst->u.rt6.rt6i_idev) { - dev_put(dev); + if (!xdst->u.rt6.rt6i_idev) return -ENODEV; - } rt6_transfer_peer(&xdst->u.rt6, rt); diff --git a/trunk/net/socket.c b/trunk/net/socket.c index 6b94633ca61d..b416093997da 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -2412,7 +2412,7 @@ static const unsigned char nargs[21] = { SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) { - unsigned long a[AUDITSC_ARGS]; + unsigned long a[6]; unsigned long a0, a1; int err; unsigned int len; @@ -2428,9 +2428,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) if (copy_from_user(a, args, len)) return -EFAULT; - err = audit_socketcall(nargs[call] / sizeof(unsigned long), a); - if (err) - return err; + audit_socketcall(nargs[call] / sizeof(unsigned long), a); a0 = a[0]; a1 = a[1]; diff --git a/trunk/tools/power/x86/turbostat/turbostat.c b/trunk/tools/power/x86/turbostat/turbostat.c index 9e9d34871195..321e066a0753 100644 --- a/trunk/tools/power/x86/turbostat/turbostat.c +++ b/trunk/tools/power/x86/turbostat/turbostat.c @@ -46,7 +46,6 @@ unsigned int skip_c0; unsigned int skip_c1; unsigned int do_nhm_cstates; unsigned int do_snb_cstates; -unsigned int do_c8_c9_c10; unsigned int has_aperf; unsigned int has_epb; unsigned int units = 1000000000; /* Ghz etc */ @@ -121,9 +120,6 @@ struct pkg_data { unsigned long long pc3; unsigned long long pc6; unsigned long long pc7; - unsigned long long pc8; - unsigned long long pc9; - unsigned long long pc10; unsigned int package_id; unsigned int energy_pkg; /* MSR_PKG_ENERGY_STATUS */ unsigned int energy_dram; /* MSR_DRAM_ENERGY_STATUS */ @@ -286,11 +282,6 @@ void print_header(void) outp += sprintf(outp, " %%pc6"); if (do_snb_cstates) outp += sprintf(outp, " %%pc7"); - if (do_c8_c9_c10) { - outp += sprintf(outp, " %%pc8"); - outp += sprintf(outp, " %%pc9"); - outp += sprintf(outp, " %%pc10"); - } if (do_rapl & RAPL_PKG) outp += sprintf(outp, " Pkg_W"); @@ -345,9 +336,6 @@ int dump_counters(struct thread_data *t, struct core_data *c, fprintf(stderr, "pc3: %016llX\n", p->pc3); fprintf(stderr, "pc6: %016llX\n", p->pc6); fprintf(stderr, "pc7: %016llX\n", p->pc7); - fprintf(stderr, "pc8: %016llX\n", p->pc8); - fprintf(stderr, "pc9: %016llX\n", p->pc9); - fprintf(stderr, "pc10: %016llX\n", p->pc10); fprintf(stderr, "Joules PKG: %0X\n", p->energy_pkg); fprintf(stderr, "Joules COR: %0X\n", p->energy_cores); fprintf(stderr, "Joules GFX: %0X\n", p->energy_gfx); @@ -505,11 +493,6 @@ int format_counters(struct thread_data *t, struct core_data *c, outp += sprintf(outp, " %6.2f", 100.0 * p->pc6/t->tsc); if (do_snb_cstates) outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc); - if (do_c8_c9_c10) { - outp += sprintf(outp, " %6.2f", 100.0 * p->pc8/t->tsc); - outp += sprintf(outp, " %6.2f", 100.0 * p->pc9/t->tsc); - outp += sprintf(outp, " %6.2f", 100.0 * p->pc10/t->tsc); - } /* * If measurement interval exceeds minimum RAPL Joule Counter range, @@ -586,9 +569,6 @@ delta_package(struct pkg_data *new, struct pkg_data *old) old->pc3 = new->pc3 - old->pc3; old->pc6 = new->pc6 - old->pc6; old->pc7 = new->pc7 - old->pc7; - old->pc8 = new->pc8 - old->pc8; - old->pc9 = new->pc9 - old->pc9; - old->pc10 = new->pc10 - old->pc10; old->pkg_temp_c = new->pkg_temp_c; DELTA_WRAP32(new->energy_pkg, old->energy_pkg); @@ -722,9 +702,6 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data p->pc3 = 0; p->pc6 = 0; p->pc7 = 0; - p->pc8 = 0; - p->pc9 = 0; - p->pc10 = 0; p->energy_pkg = 0; p->energy_dram = 0; @@ -763,9 +740,6 @@ int sum_counters(struct thread_data *t, struct core_data *c, average.packages.pc3 += p->pc3; average.packages.pc6 += p->pc6; average.packages.pc7 += p->pc7; - average.packages.pc8 += p->pc8; - average.packages.pc9 += p->pc9; - average.packages.pc10 += p->pc10; average.packages.energy_pkg += p->energy_pkg; average.packages.energy_dram += p->energy_dram; @@ -807,10 +781,6 @@ void compute_average(struct thread_data *t, struct core_data *c, average.packages.pc3 /= topo.num_packages; average.packages.pc6 /= topo.num_packages; average.packages.pc7 /= topo.num_packages; - - average.packages.pc8 /= topo.num_packages; - average.packages.pc9 /= topo.num_packages; - average.packages.pc10 /= topo.num_packages; } static unsigned long long rdtsc(void) @@ -910,14 +880,6 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7)) return -12; } - if (do_c8_c9_c10) { - if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8)) - return -13; - if (get_msr(cpu, MSR_PKG_C9_RESIDENCY, &p->pc9)) - return -13; - if (get_msr(cpu, MSR_PKG_C10_RESIDENCY, &p->pc10)) - return -13; - } if (do_rapl & RAPL_PKG) { if (get_msr(cpu, MSR_PKG_ENERGY_STATUS, &msr)) return -13; @@ -1800,19 +1762,6 @@ int is_snb(unsigned int family, unsigned int model) return 0; } -int has_c8_c9_c10(unsigned int family, unsigned int model) -{ - if (!genuine_intel) - return 0; - - switch (model) { - case 0x45: - return 1; - } - return 0; -} - - double discover_bclk(unsigned int family, unsigned int model) { if (is_snb(family, model)) @@ -1969,7 +1918,6 @@ void check_cpuid() do_nhm_cstates = genuine_intel; /* all Intel w/ non-stop TSC have NHM counters */ do_smi = do_nhm_cstates; do_snb_cstates = is_snb(family, model); - do_c8_c9_c10 = has_c8_c9_c10(family, model); bclk = discover_bclk(family, model); do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model); @@ -2331,7 +2279,7 @@ int main(int argc, char **argv) cmdline(argc, argv); if (verbose) - fprintf(stderr, "turbostat v3.4 April 17, 2013" + fprintf(stderr, "turbostat v3.3 March 15, 2013" " - Len Brown \n"); turbostat_init();