📄 isp_linux.h
字号:
/* @(#)isp_linux.h 1.39 *//* * Qlogic ISP SCSI Host Adapter Linux Wrapper Definitions *--------------------------------------- * Copyright (c) 1998, 1999, 2000, 2001 by Matthew Jacob * 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, immediately at the beginning of the file. * 2. The name of the author may not 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 * the GNU Public License ("GPL"). * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, 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 DAMAGE. * * Matthew Jacob * Feral Software * PMB #825 * 5214-F Diamond Hts Blvd * San Francisco, CA, 94131 * mjacob@feral.com */#ifndef _ISP_LINUX_H#define _ISP_LINUX_H#ifndef ISP_MODULE#define __NO_VERSION__#endif#ifdef LINUX_ISP_TARGET_MODE#define EXPORT_SYMTAB#endif#include <linux/version.h>#ifndef KERNEL_VERSION#define KERNEL_VERSION(v,p,s) (((v)<<16)+(p<<8)+s)#endif#define _KVC KERNEL_VERSION#if LINUX_VERSION_CODE <= _KVC(2,2,0)#error "Linux 2.0 and 2.1 kernels are not supported anymore"#endif#if LINUX_VERSION_CODE >= _KVC(2,3,0) && LINUX_VERSION_CODE < _KVC(2,4,0)#error "Linux 2.3 kernels are not supported"#endif#ifndef UNUSED_PARAMETER#define UNUSED_PARAMETER(x) (void) x#endif#include <linux/autoconf.h>#ifdef CONFIG_SMP#define __SMP__ 1#endif#include <linux/module.h>#include <linux/config.h>#include <linux/init.h>#include <linux/types.h>#include <linux/blk.h>#include <linux/blkdev.h>#include <linux/delay.h>#include <linux/ioport.h>#include <linux/mm.h>#include <linux/sched.h>#include <linux/stat.h>#include <linux/pci.h>#include <asm/dma.h>#include <asm/io.h>#include <asm/irq.h>#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)#include <linux/smp.h>#include <linux/spinlock.h>#else#include <asm/spinlock.h>#endif#include <asm/system.h>#include <asm/byteorder.h>#include <linux/interrupt.h>#include "scsi.h"#include "hosts.h"#include "sd.h"/* * These bits and pieces of keeping track of Linux versions * and some of the various foo items for locking/unlocking * gratefully borrowed from (amongst others) Doug Ledford * and Gerard Roudier. */#define PWRB(p, o, r) pci_write_config_byte(p->pci_dev, o, r)#define PWRW(p, o, r) pci_write_config_word(p->pci_dev, o, r)#define PWRL(p, o, r) pci_write_config_dword(p->pci_dev, o, r)#define PRDW(p, o, r) pci_read_config_word(p->pci_dev, o, r)#define PRDD(p, o, r) pci_read_config_dword(p->pci_dev, o, r)#define PRDB(p, o, r) pci_read_config_byte(p->pci_dev, o, r)#ifndef bus_dvma_to_mem#if defined (__alpha__)#define bus_dvma_to_mem(p) ((p) & 0xfffffffful)#else#define bus_dvma_to_mem(p) (p)#endif#endif#if defined (__powerpc__)#undef __pa#define __pa(x) x#endif#if defined (__i386__) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)#undef __pa#define __pa(x) x#endif#if defined (__sparc__) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)#undef __pa#define __pa(x) x#endif#if defined (__alpha__) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)#undef __pa#define __pa(x) x#endif/* * Efficiency- get rid of SBus code && tests unless we need them. */#if defined(__sparcv9__ ) || defined(__sparc__)#define ISP_SBUS_SUPPORTED 1#else#define ISP_SBUS_SUPPORTED 0#endif#define ISP_PLATFORM_VERSION_MAJOR 2#define ISP_PLATFORM_VERSION_MINOR 1#ifndef BIG_ENDIAN#define BIG_ENDIAN 4321#endif#ifndef LITTLE_ENDIAN#define LITTLE_ENDIAN 1234#endif#ifdef __BIG_ENDIAN#define BYTE_ORDER BIG_ENDIAN#endif#ifdef __LITTLE_ENDIAN#define BYTE_ORDER LITTLE_ENDIAN#endif#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)#define DMA_ADDR_T unsigned long#define QLA_SG_C(sg) sg->length#define QLA_SG_A(sg) virt_to_bus(sg->address)#else#define DMA_ADDR_T dma_addr_t#define QLA_SG_C(sg) sg_dma_len(sg)#define QLA_SG_A(sg) (DMA_ADDR_T) sg_dma_address(sg)#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,16)#define DMA_HTYPE_T char *#define QLA_HANDLE(cmd) (cmd)->SCp.ptr#else#define DMA_HTYPE_T dma_addr_t#define QLA_HANDLE(cmd) (cmd)->SCp.dma_handle#endif#endif#define HANDLE_LOOPSTATE_IN_OUTER_LAYERS 1#ifdef min#undef min#endif#ifdef max#undef max#endif/* * Normally this should be taken care of by typedefs, * but linux includes are a complete dog's breakfast. */#define u_int8_t unsigned char#define u_int16_t unsigned short#define u_int32_t unsigned int#if BITS_PER_LONG == 64#define u_int64_t unsigned long#else#define u_int64_t unsigned long long#endif#define int8_t char#define int16_t short#define int32_t int#define u_long unsigned long#define u_int unsigned int#define u_char unsigned chartypedef u_long vm_offset_t;#ifdef LINUX_ISP_TARGET_MODE#define DEFAULT_DEVICE_TYPE 3#define NTGT_CMDS 256#define _WIX(isp, b, ix) (((b << 6)) | (ix >> 5))#define _BIX(isp, ix) (1 << (ix & 0x1f))#define LUN_BTST(isp, b, ix) \ (((isp)->isp_osinfo.lunbmap[_WIX(isp, b, ix)] & _BIX(isp, ix)) != 0)#define LUN_BSET(isp, b, ix) \ isp->isp_osinfo.lunbmap[_WIX(isp, b, ix)] |= _BIX(isp, ix)#define LUN_BCLR(isp, b, ix) \ isp->isp_osinfo.lunbmap[_WIX(isp, b, ix)] &= ~_BIX(isp, ix)#if defined(__alpha__) || defined(__sparc_v9__)#define _TMD_PAD_LEN 12#else#define _TMD_PAD_LEN 24#endif#endiftypedef struct { enum { ISP_THREAD_NIL=1, ISP_THREAD_FC_RESCAN, ISP_THREAD_REINIT, ISP_THREAD_FW_CRASH_DUMP, ISP_THREAD_EXIT } thread_action; struct semaphore * thread_waiter;} isp_thread_action_t;#define MAX_THREAD_ACTION 10union pstore;struct isposinfo { struct ispsoftc * isp_next; struct Scsi_Host * host; Scsi_Cmnd *wqnext, *wqtail; Scsi_Cmnd *dqnext, *dqtail; union pstore *storep; char hbaname[16]; unsigned short instance; unsigned short wqcnt; unsigned short wqhiwater; unsigned short hiwater; struct timer_list timer; struct timer_list _mbtimer; struct semaphore _mbox_sem; struct semaphore _mbox_c_sem; struct semaphore _fcs_sem; spinlock_t slock; unsigned volatile int _downcnt : 8, : 16, : 1, _deadloop : 1, _blocked : 1, _fcrswdog : 1, _fcrspend : 1, _dogactive : 1, _mbox_waiting : 1, _mbintsok : 1; void * misc[8]; /* private platform variant usage */ unsigned long _iflags; struct task_struct * task_thread; struct semaphore * task_request; struct semaphore * task_ctl_sem; spinlock_t tlock; unsigned int nt_actions; unsigned int device_id; isp_thread_action_t t_actions[MAX_THREAD_ACTION];#ifdef LINUX_ISP_TARGET_MODE#define TM_WANTED 0x08#define TM_BUSY 0x04#define TM_TMODE_ENABLED 0x03 u_int32_t rollinfo : 16, rstatus : 8, : 4, tmflags : 4; struct semaphore tgt_inisem; struct semaphore * rsemap; /* * This is very inefficient, but is in fact big enough * to cover a complete bitmap for Fibre Channel, as well * as the dual bus SCSI cards. This works out without * overflow easily because the most you can enable * for the SCSI cards is 64 luns (x 2 busses). * * For Fibre Channel, we can run the max luns up to 65536, * but we'll default to the minimum we can support here. */#define TM_MAX_LUN_FC 128#define TM_MAX_LUN_SCSI 64 u_int32_t lunbmap[TM_MAX_LUN_FC >> 5]; struct tmd_cmd * pending_t; struct tmd_cmd * tfreelist; struct tmd_cmd * pool; void (*hcb)(int, void *); void *hcb_token;#endif};#define mbtimer isp_osinfo._mbtimer#define dogactive isp_osinfo._dogactive#define mbox_sem isp_osinfo._mbox_sem#define mbox_c_sem isp_osinfo._mbox_c_sem#define fcs_sem isp_osinfo._fcs_sem#define mbintsok isp_osinfo._mbintsok#define mbox_waiting isp_osinfo._mbox_waiting#define isp_pbuf isp_osinfo._pbuf#define isp_fcrspend isp_osinfo._fcrspend#define isp_fcrswdog isp_osinfo._fcrswdog#define isp_blocked isp_osinfo._blocked#define isp_downcnt isp_osinfo._downcnt#define isp_deadloop isp_osinfo._deadloop#define iflags isp_osinfo._iflags#define SEND_THREAD_EVENT(isp, action, dowait) \if (isp->isp_osinfo.task_request) { \ unsigned long flags; \ spin_lock_irqsave(&isp->isp_osinfo.tlock, flags); \ if (isp->isp_osinfo.nt_actions >= MAX_THREAD_ACTION) { \ spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags); \ isp_prt(isp, ISP_LOGERR, "thread event overflow"); \ } else if (action == ISP_THREAD_FC_RESCAN && isp->isp_fcrspend) { \ spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags); \ } else { \ DECLARE_MUTEX_LOCKED(sem); \ isp_thread_action_t *tap; \ tap = &isp->isp_osinfo.t_actions[isp->isp_osinfo.nt_actions++]; \ tap->thread_action = action; \ if (dowait) \ tap->thread_waiter = &sem; \ else \ tap->thread_waiter = 0; \ if (action == ISP_THREAD_FC_RESCAN) \ isp->isp_fcrspend = 1; \ up(isp->isp_osinfo.task_request); \ spin_unlock_irqrestore(&isp->isp_osinfo.tlock, flags); \ if (dowait) { \ down(&sem); \ isp_prt(isp, ISP_LOGDEBUG1, \ "action %d done from %p", action, &sem); \ } else { \ isp_prt(isp, ISP_LOGDEBUG1, \ "action %d sent", action); \ } \ } \}/* * Locking macros... */#define ISP_LOCK_INIT(isp) spin_lock_init(&isp->isp_osinfo.slock)#define ISP_LOCK_SOFTC(isp) { \ unsigned long _flags; \ spin_lock_irqsave(&isp->isp_osinfo.slock, _flags); \ isp->iflags = _flags; \ }#define ISP_UNLK_SOFTC(isp) { \ unsigned long _flags = isp->iflags; \ spin_unlock_irqrestore(&isp->isp_osinfo.slock, _flags); \ }#define ISP_ILOCK_SOFTC ISP_LOCK_SOFTC#define ISP_IUNLK_SOFTC ISP_UNLK_SOFTC#define ISP_IGET_LK_SOFTC ISP_LOCK_SOFTC#define ISP_DROP_LK_SOFTC ISP_UNLK_SOFTC#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)#define ISP_LOCK_SCSI_DONE(isp) { \ unsigned long _flags; \ spin_lock_irqsave(&io_request_lock, _flags); \ isp->iflags = _flags; \ }#define ISP_UNLK_SCSI_DONE(isp) { \ unsigned long _flags = isp->iflags; \ spin_unlock_irqrestore(&io_request_lock, _flags); \ }#else#define ISP_LOCK_SCSI_DONE(isp) do { } while(0)#define ISP_UNLK_SCSI_DONE(isp) do { } while(0)#endif#define ISP_LOCKU_SOFTC ISP_ILOCK_SOFTC#define ISP_UNLKU_SOFTC ISP_IUNLK_SOFTC#define ISP_TLOCK_INIT(isp) spin_lock_init(&isp->isp_osinfo.tlock)#define ISP_DRIVER_ENTRY_LOCK(isp) spin_unlock_irq(&io_request_lock)#define ISP_DRIVER_EXIT_LOCK(isp) spin_lock_irq(&io_request_lock)#define ISP_MUST_POLL(isp) (in_interrupt() || isp->mbintsok == 0)/* * Misc SCSI defines */#define MSG_SIMPLE_Q_TAG 0x21#define MSG_HEAD_OF_Q_TAG 0x22#define MSG_ORDERED_Q_TAG 0x23/* * Required Macros/Defines */#define INLINE __inline#define ISP2100_SCRLEN 0x800#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)#define MEMZERO _isp_memzero#define MEMCPY _isp_memcpy#else#define MEMZERO(b, a) memset(b, 0, a)#define MEMCPY memcpy#endif#define SNPRINTF isp_snprintf#define STRNCAT strncat#define USEC_DELAY _isp_usec_delay#define USEC_SLEEP(isp, x) \ ISP_DROP_LK_SOFTC(isp); \ __set_current_state(TASK_UNINTERRUPTIBLE); \ (void) schedule_timeout(((x? x: 1) + (HZ - 1)) / HZ); \ ISP_IGET_LK_SOFTC(isp)#define NANOTIME_T struct timeval/* for prior to 2.2.19, use do_gettimeofday, and, well, it'll be inaccurate */#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18)#define GET_NANOTIME(ptr) \ (ptr)->tv_sec = 0, (ptr)->tv_usec = 0, get_fast_time(ptr)#else#define GET_NANOTIME(ptr) \ (ptr)->tv_sec = 0, (ptr)->tv_usec = 0, do_gettimeofday(ptr)#endif#define GET_NANOSEC(x) \ ((u_int64_t) ((((u_int64_t)(x)->tv_sec) * 1000000 + (x)->tv_usec)))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -