?? aic7xxx_osm.h
字號:
uint8_t version1[2]; uint8_t version2[2]; uint8_t version3[2]; uint8_t version4[2]; uint8_t version5[2]; uint8_t version6[2]; uint8_t version7[2]; uint8_t version8[2]; uint8_t reserved3[22];#define SID_VENDOR_SPECIFIC_1_SIZE 160 uint8_t vendor_specific1[SID_VENDOR_SPECIFIC_1_SIZE];};/********************************** Includes **********************************//* Host template and function declarations referenced by the template. */#include "aic7xxx_linux_host.h"/* Core driver definitions */#include "aic7xxx.h"/* SMP support */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,17)#include <linux/spinlock.h>#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93)#include <linux/smp.h>#endif#define AIC7XXX_DRIVER_VERSION "6.2.4"/**************************** Front End Queues ********************************//* * Data structure used to cast the Linux struct scsi_cmnd to something * that allows us to use the queue macros. The linux structure has * plenty of space to hold the links fields as required by the queue * macros, but the queue macors require them to have the correct type. */struct ahc_cmd_internal { /* Area owned by the Linux scsi layer. */ uint8_t private[offsetof(struct scsi_cmnd, SCp.Status)]; union { STAILQ_ENTRY(ahc_cmd) ste; LIST_ENTRY(ahc_cmd) le; TAILQ_ENTRY(ahc_cmd) tqe; } links; uint32_t end;};struct ahc_cmd { union { struct ahc_cmd_internal icmd; struct scsi_cmnd scsi_cmd; } un;};#define acmd_icmd(cmd) ((cmd)->un.icmd)#define acmd_scsi_cmd(cmd) ((cmd)->un.scsi_cmd)#define acmd_links un.icmd.links/*************************** Device Data Structures ***************************//* * A per probed device structure used to deal with some error recovery * scenarios that the Linux mid-layer code just doesn't know how to * handle. The structure allocated for a device only becomes persistant * after a successfully completed inquiry command to the target when * that inquiry data indicates a lun is present. */TAILQ_HEAD(ahc_busyq, ahc_cmd);typedef enum { AHC_DEV_UNCONFIGURED = 0x01, AHC_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */ AHC_DEV_TIMER_ACTIVE = 0x04, /* Our timer is active */ AHC_DEV_ON_RUN_LIST = 0x08, /* Queued to be run later */ AHC_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */ AHC_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */ AHC_DEV_PERIODIC_OTAG = 0x40 /* Send OTAG to prevent starvation */} ahc_dev_flags;struct ahc_linux_target;struct ahc_linux_device { TAILQ_ENTRY(ahc_linux_device) links; struct ahc_busyq busyq; /* * The number of transactions currently * queued to the device. */ int active; /* * The currently allowed number of * transactions that can be queued to * the device. Must be signed for * conversion from tagged to untagged * mode where the device may have more * than one outstanding active transaction. */ int openings; /* * A positive count indicates that this * device's queue is halted. */ u_int qfrozen; /* * Cumulative command counter. */ u_long commands_issued; /* * The number of tagged transactions when * running at our current opening level * that have been successfully received by * this device since the last QUEUE FULL. */ u_int tag_success_count;#define AHC_TAG_SUCCESS_INTERVAL 50 ahc_dev_flags flags; /* * The high limit for the tags variable. */ u_int maxtags; /* * The computed number of tags outstanding * at the time of the last QUEUE FULL event. */ u_int tags_on_last_queuefull; /* * How many times we have seen a queue full * with the same number of tags. This is used * to stop our adaptive queue depth algorithm * on devices with a fixed number of tags. */ u_int last_queuefull_same_count;#define AHC_LOCK_TAGS_COUNT 50 /* * How many transactions have been queued * without the device going idle. We use * this statistic to determine when to issue * an ordered tag to prevent transaction * starvation. This statistic is only updated * if the AHC_DEV_PERIODIC_OTAG flag is set * on this device. */ u_int commands_since_idle_or_otag;#define AHC_OTAG_THRESH 500 int lun; struct ahc_linux_target *target;};struct ahc_linux_target { struct ahc_linux_device *devices[AHC_NUM_LUNS]; int channel; int target; int refcount; struct ahc_transinfo last_tinfo;};/********************* Definitions Required by the Core ***********************//* * Number of SG segments we require. So long as the S/G segments for * a particular transaction are allocated in a physically contiguous * manner and are allocated below 4GB, the number of S/G segments is * unrestricted. */#define AHC_NSEG 128/* * Per-SCB OSM storage. */struct scb_platform_data { struct ahc_linux_device *dev; uint32_t xfer_len;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) uint32_t resid; /* Transfer residual */#endif};/* * Define a structure used for each host adapter. All members are * aligned on a boundary >= the size of the member to honor the * alignment restrictions of the various platforms supported by * this driver. */TAILQ_HEAD(ahc_completeq, ahc_cmd);struct ahc_platform_data { /* * Fields accessed from interrupt context. */ struct ahc_linux_target *targets[AHC_NUM_TARGETS]; TAILQ_HEAD(, ahc_linux_device) device_runq; struct ahc_completeq completeq;#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) spinlock_t spin_lock;#endif u_int qfrozen; struct timer_list reset_timer; struct semaphore eh_sem; struct Scsi_Host *host; /* pointer to scsi host */ uint32_t irq; /* IRQ for this adapter */ uint32_t bios_address; uint32_t mem_busaddr; /* Mem Base Addr */ bus_addr_t hw_dma_mask;};/************************** OS Utility Wrappers *******************************/#define printf printk#define M_NOWAIT GFP_ATOMIC#define M_WAITOK 0#define malloc(size, type, flags) kmalloc(size, flags)#define free(ptr, type) kfree(ptr)static __inline void ahc_delay(long);static __inline voidahc_delay(long usec){ /* * udelay on Linux can have problems for * multi-millisecond waits. Wait at most * 1024us per call. */ while (usec > 0) { udelay(usec % 1024); usec -= 1024; }}/***************************** Low Level I/O **********************************/#if defined(__powerpc__) || defined(__i386__) || defined(__ia64__)#define MMAPIO#endifstatic __inline uint8_t ahc_inb(struct ahc_softc * ahc, long port);static __inline void ahc_outb(struct ahc_softc * ahc, long port, uint8_t val);static __inline void ahc_outsb(struct ahc_softc * ahc, long port, uint8_t *, int count);static __inline void ahc_insb(struct ahc_softc * ahc, long port, uint8_t *, int count);static __inline uint8_tahc_inb(struct ahc_softc * ahc, long port){ uint8_t x;#ifdef MMAPIO if (ahc->tag == BUS_SPACE_MEMIO) { x = readb(ahc->bsh.maddr + port); } else { x = inb(ahc->bsh.ioport + port); }#else x = inb(ahc->bsh.ioport + port);#endif mb(); return (x);}static __inline voidahc_outb(struct ahc_softc * ahc, long port, uint8_t val){#ifdef MMAPIO if (ahc->tag == BUS_SPACE_MEMIO) { writeb(val, ahc->bsh.maddr + port); } else { outb(val, ahc->bsh.ioport + port); }#else outb(val, ahc->bsh.ioport + port);#endif mb();}static __inline voidahc_outsb(struct ahc_softc * ahc, long port, uint8_t *array, int count){ int i; /* * There is probably a more efficient way to do this on Linux * but we don't use this for anything speed critical and this * should work. */ for (i = 0; i < count; i++) ahc_outb(ahc, port, *array++);}static __inline voidahc_insb(struct ahc_softc * ahc, long port, uint8_t *array, int count){ int i; /* * There is probably a more efficient way to do this on Linux * but we don't use this for anything speed critical and this * should work. */ for (i = 0; i < count; i++) *array++ = ahc_inb(ahc, port);}/**************************** Initialization **********************************/int ahc_linux_register_host(struct ahc_softc *, Scsi_Host_Template *);uint64_t ahc_linux_get_memsize(void);/*************************** Pretty Printing **********************************/struct info_str { char *buffer; int length; off_t offset; int pos;};void ahc_format_transinfo(struct info_str *info, struct ahc_transinfo *tinfo);/******************************** Locking *************************************//* Lock protecting internal data structures */static __inline void ahc_lockinit(struct ahc_softc *);static __inline void ahc_lock(struct ahc_softc *, unsigned long *flags);static __inline void ahc_unlock(struct ahc_softc *, unsigned long *flags);/* Lock held during command compeletion to the upper layer */static __inline void ahc_done_lockinit(struct ahc_softc *);static __inline void ahc_done_lock(struct ahc_softc *, unsigned long *flags);static __inline void ahc_done_unlock(struct ahc_softc *, unsigned long *flags);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93)static __inline voidahc_lockinit(struct ahc_softc *ahc){ spin_lock_init(&ahc->platform_data->spin_lock);}static __inline voidahc_lock(struct ahc_softc *ahc, unsigned long *flags){ *flags = 0; spin_lock_irqsave(&ahc->platform_data->spin_lock, *flags);}static __inline voidahc_unlock(struct ahc_softc *ahc, unsigned long *flags){ spin_unlock_irqrestore(&ahc->platform_data->spin_lock, *flags);}static __inline voidahc_done_lockinit(struct ahc_softc *ahc){ /* We don't own the iorequest lock, so we don't initialize it. */}static __inline voidahc_done_lock(struct ahc_softc *ahc, unsigned long *flags){ *flags = 0; spin_lock_irqsave(&io_request_lock, *flags);}static __inline voidahc_done_unlock(struct ahc_softc *ahc, unsigned long *flags){ spin_unlock_irqrestore(&io_request_lock, *flags);}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -