mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-18 13:16:34 +00:00
With a realtime kernel with full preemption (CONFIG_PREEMPT_RT_FULL), spinlocks can sleep, interrupt handlers run in thread context, and the standard local_irq functions manipulate preemptibility, not HW interruptibility. Under these conditions, most calls to local_irq functions should be replaced by no-ops. The CONFIG_PREEMPT_RT patch defines _nort versions of local_irq functions that compile away under CONFIG_PREEMPT_RT_FULL and compile to their "normal" equivalents otherwise. Define _nort equivalents to support compilation against both "normal" and RT-patched kernels, and use the _nort local_irq functons in cases where spinlocks are taken within a local_irq_save() or local_irq_disable() block. Without these changes, runtime warnings about "sleeping function called from invalid context" occur. Signed-off-by: Steven J. Magnani <steve@digidescorp.com> [bvanassche: Edited patch description and comment in scst_priv.h] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@5288 d57e44dd-8a1f-0410-8b47-8ef2f437770f
82 lines
1.5 KiB
C
82 lines
1.5 KiB
C
/*
|
|
* QLogic Fibre Channel HBA Driver
|
|
* Copyright (c) 2003-2008 QLogic Corporation
|
|
*
|
|
* See LICENSE.qla2xxx for copyright and licensing details.
|
|
*/
|
|
|
|
/*
|
|
* qla2x00_debounce_register
|
|
* Debounce register.
|
|
*
|
|
* Input:
|
|
* port = register address.
|
|
*
|
|
* Returns:
|
|
* register value.
|
|
*/
|
|
static __inline__ uint16_t
|
|
qla2x00_debounce_register(volatile uint16_t __iomem *addr)
|
|
{
|
|
volatile uint16_t first;
|
|
volatile uint16_t second;
|
|
|
|
do {
|
|
first = RD_REG_WORD(addr);
|
|
barrier();
|
|
cpu_relax();
|
|
second = RD_REG_WORD(addr);
|
|
} while (first != second);
|
|
|
|
return (first);
|
|
}
|
|
|
|
static inline void
|
|
qla2x00_poll(scsi_qla_host_t *ha)
|
|
{
|
|
unsigned long flags;
|
|
|
|
#ifdef CONFIG_PREEMPT_RT_FULL
|
|
local_irq_save_nort(flags);
|
|
#else
|
|
local_irq_save(flags);
|
|
#endif
|
|
|
|
ha->isp_ops->intr_handler(0, ha);
|
|
|
|
#ifdef CONFIG_PREEMPT_RT_FULL
|
|
local_irq_restore_nort(flags);
|
|
#else
|
|
local_irq_restore(flags);
|
|
#endif
|
|
}
|
|
|
|
static __inline__ scsi_qla_host_t *
|
|
to_qla_parent(scsi_qla_host_t *ha)
|
|
{
|
|
return ha->parent ? ha->parent : ha;
|
|
}
|
|
|
|
static inline uint8_t *
|
|
host_to_fcp_swap(uint8_t *fcp, uint32_t bsize)
|
|
{
|
|
uint32_t *ifcp = (uint32_t *) fcp;
|
|
uint32_t *ofcp = (uint32_t *) fcp;
|
|
uint32_t iter = bsize >> 2;
|
|
|
|
for (; iter ; iter--)
|
|
*ofcp++ = swab32(*ifcp++);
|
|
|
|
return fcp;
|
|
}
|
|
|
|
static inline int
|
|
qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id)
|
|
{
|
|
if (IS_FWI2_CAPABLE(ha))
|
|
return (loop_id > NPH_LAST_HANDLE);
|
|
|
|
return ((loop_id > ha->last_loop_id && loop_id < SNS_FIRST_LOOP_ID) ||
|
|
loop_id == MANAGEMENT_SERVER || loop_id == BROADCAST);
|
|
};
|