📄 ncr53c8xx.c
字号:
#define initverbose (driver_setup.verbose)#define bootverbose (np->verbose)#ifdef SCSI_NCR_NVRAM_SUPPORT/*** Symbios NvRAM data format*/#define SYMBIOS_NVRAM_SIZE 368#define SYMBIOS_NVRAM_ADDRESS 0x100struct Symbios_nvram {/* Header 6 bytes */ u_short start_marker; /* 0x0000 */ u_short byte_count; /* excluding header/trailer */ u_short checksum;/* Controller set up 20 bytes */ u_short word0; /* 0x3000 */ u_short word2; /* 0x0000 */ u_short word4; /* 0x0000 */ u_short flags;#define SYMBIOS_SCAM_ENABLE (1)#define SYMBIOS_PARITY_ENABLE (1<<1)#define SYMBIOS_VERBOSE_MSGS (1<<2) u_short flags1;#define SYMBIOS_SCAN_HI_LO (1) u_short word10; /* 0x00 */ u_short flags3; /* 0x00 */#define SYMBIOS_REMOVABLE_FLAGS (3) /* 0=none, 1=bootable, 2=all */ u_char host_id; u_char byte15; /* 0x04 */ u_short word16; /* 0x0410 */ u_short word18; /* 0x0000 *//* Boot order 14 bytes * 4 */ struct Symbios_host{ u_char word0; /* 0x0004:ok / 0x0000:nok */ u_short device_id; /* PCI device id */ u_short vendor_id; /* PCI vendor id */ u_char byte6; /* 0x00 */ u_char device_fn; /* PCI device/function number << 3*/ u_short word8; u_short flags;#define SYMBIOS_INIT_SCAN_AT_BOOT (1) u_short io_port; /* PCI io_port address */ } host[4];/* Targets 8 bytes * 16 */ struct Symbios_target { u_short flags;#define SYMBIOS_DISCONNECT_ENABLE (1)#define SYMBIOS_SCAN_AT_BOOT_TIME (1<<1)#define SYMBIOS_SCAN_LUNS (1<<2)#define SYMBIOS_QUEUE_TAGS_ENABLED (1<<3) u_char bus_width; /* 0x08/0x10 */ u_char sync_offset; u_char sync_period; /* 4*period factor */ u_char byte6; /* 0x00 */ u_short timeout; } target[16]; u_char spare_devices[19*8]; u_char trailer[6]; /* 0xfe 0xfe 0x00 0x00 0x00 0x00 */};typedef struct Symbios_nvram Symbios_nvram;typedef struct Symbios_host Symbios_host;typedef struct Symbios_target Symbios_target;/*** Tekram NvRAM data format.*/#define TEKRAM_NVRAM_SIZE 64#define TEKRAM_NVRAM_ADDRESS 0struct Tekram_nvram { struct Tekram_target { u_char flags;#define TEKRAM_PARITY_CHECK (1)#define TEKRAM_SYNC_NEGO (1<<1)#define TEKRAM_DISCONNECT_ENABLE (1<<2)#define TEKRAM_START_CMD (1<<3)#define TEKRAM_TAGGED_COMMANDS (1<<4)#define TEKRAM_WIDE_NEGO (1<<5) u_char sync_index; u_short word2; } target[16]; u_char host_id; u_char flags;#define TEKRAM_MORE_THAN_2_DRIVES (1)#define TEKRAM_DRIVES_SUP_1GB (1<<1)#define TEKRAM_RESET_ON_POWER_ON (1<<2)#define TEKRAM_ACTIVE_NEGATION (1<<3)#define TEKRAM_IMMEDIATE_SEEK (1<<4)#define TEKRAM_SCAN_LUNS (1<<5)#define TEKRAM_REMOVABLE_FLAGS (3<<6) /* 0: disable; 1: boot device; 2:all */ u_char boot_delay_index; u_char max_tags_index; u_short flags1;#define TEKRAM_F2_F6_ENABLED (1) u_short spare[29];};typedef struct Tekram_nvram Tekram_nvram;typedef struct Tekram_target Tekram_target;static u_char Tekram_sync[12] __initdata = {25,31,37,43,50,62,75,125,12,15,18,21};#endif /* SCSI_NCR_NVRAM_SUPPORT *//*** Structures used by ncr53c8xx_detect/ncr53c8xx_pci_init to ** transmit device configuration to the ncr_attach() function.*/typedef struct { int bus; u_char device_fn; u_int base; u_int base_2; u_int io_port; int irq;/* port and reg fields to use INB, OUTB macros */ u_int port; volatile struct ncr_reg *reg;} ncr_slot;typedef struct { int type;#define SCSI_NCR_SYMBIOS_NVRAM (1)#define SCSI_NCR_TEKRAM_NVRAM (2)#ifdef SCSI_NCR_NVRAM_SUPPORT union { Symbios_nvram Symbios; Tekram_nvram Tekram; } data;#endif} ncr_nvram;/*** Structure used by ncr53c8xx_detect/ncr53c8xx_pci_init** to save data on each detected board for ncr_attach().*/typedef struct { ncr_slot slot; ncr_chip chip; ncr_nvram *nvram; int attach_done;} ncr_device;/*==========================================================**** Debugging tags****==========================================================*/#define DEBUG_ALLOC (0x0001)#define DEBUG_PHASE (0x0002)#define DEBUG_POLL (0x0004)#define DEBUG_QUEUE (0x0008)#define DEBUG_RESULT (0x0010)#define DEBUG_SCATTER (0x0020)#define DEBUG_SCRIPT (0x0040)#define DEBUG_TINY (0x0080)#define DEBUG_TIMING (0x0100)#define DEBUG_NEGO (0x0200)#define DEBUG_TAGS (0x0400)#define DEBUG_FREEZE (0x0800)#define DEBUG_RESTART (0x1000)/*** Enable/Disable debug messages.** Can be changed at runtime too.*/#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT #define DEBUG_FLAGS ncr_debug#else #define DEBUG_FLAGS SCSI_NCR_DEBUG_FLAGS#endif/*==========================================================**** assert ()****==========================================================**** modified copy from 386bsd:/usr/include/sys/assert.h****----------------------------------------------------------*/#define assert(expression) { \ if (!(expression)) { \ (void)printf(\ "assertion \"%s\" failed: file \"%s\", line %d\n", \ #expression, \ __FILE__, __LINE__); \ } \}/*==========================================================**** Big/Little endian support.****==========================================================*//*** If the NCR uses big endian addressing mode over the ** PCI, actual io register addresses for byte and word ** accesses must be changed according to lane routing.** Btw, ncr_offb() and ncr_offw() macros only apply to ** constants and so donnot generate bloated code.*/#if defined(SCSI_NCR_BIG_ENDIAN)#define ncr_offb(o) (((o)&~3)+((~((o)&3))&3))#define ncr_offw(o) (((o)&~3)+((~((o)&3))&2))#else#define ncr_offb(o) (o)#define ncr_offw(o) (o)#endif/*** If the CPU and the NCR use same endian-ness adressing,** no byte reordering is needed for script patching.** Macro cpu_to_scr() is to be used for script patching.** Macro scr_to_cpu() is to be used for getting a DWORD ** from the script.*/#if defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)#define cpu_to_scr(dw) cpu_to_le32(dw)#define scr_to_cpu(dw) le32_to_cpu(dw)#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)#define cpu_to_scr(dw) cpu_to_be32(dw)#define scr_to_cpu(dw) be32_to_cpu(dw)#else#define cpu_to_scr(dw) (dw)#define scr_to_cpu(dw) (dw)#endif/*==========================================================**** Access to the controller chip.**** If NCR_IOMAPPED is defined, only IO are used by the driver.****==========================================================*//*** If the CPU and the NCR use same endian-ness adressing,** no byte reordering is needed for accessing chip io ** registers. Functions suffixed by '_raw' are assumed ** to access the chip over the PCI without doing byte ** reordering. Functions suffixed by '_l2b' are ** assumed to perform little-endian to big-endian byte ** reordering, those suffixed by '_b2l' blah, blah,** blah, ...*/#if defined(NCR_IOMAPPED)/*** IO mapped only input / ouput*/#define INB_OFF(o) inb (np->port + ncr_offb(o))#define OUTB_OFF(o, val) outb ((val), np->port + ncr_offb(o))#if defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)#define INW_OFF(o) inw_l2b (np->port + ncr_offw(o))#define INL_OFF(o) inl_l2b (np->port + (o))#define OUTW_OFF(o, val) outw_b2l ((val), np->port + ncr_offw(o))#define OUTL_OFF(o, val) outl_b2l ((val), np->port + (o))#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)#define INW_OFF(o) inw_b2l (np->port + ncr_offw(o))#define INL_OFF(o) inl_b2l (np->port + (o))#define OUTW_OFF(o, val) outw_l2b ((val), np->port + ncr_offw(o))#define OUTL_OFF(o, val) outl_l2b ((val), np->port + (o))#else#define INW_OFF(o) inw_raw (np->port + ncr_offw(o))#define INL_OFF(o) inl_raw (np->port + (o))#define OUTW_OFF(o, val) outw_raw ((val), np->port + ncr_offw(o))#define OUTL_OFF(o, val) outl_raw ((val), np->port + (o))#endif /* ENDIANs */#else /* defined NCR_IOMAPPED *//*** MEMORY mapped IO input / output*/#define INB_OFF(o) readb((char *)np->reg + ncr_offb(o))#define OUTB_OFF(o, val) writeb((val), (char *)np->reg + ncr_offb(o))#if defined(__BIG_ENDIAN) && !defined(SCSI_NCR_BIG_ENDIAN)#define INW_OFF(o) readw_l2b((char *)np->reg + ncr_offw(o))#define INL_OFF(o) readl_l2b((char *)np->reg + (o))#define OUTW_OFF(o, val) writew_b2l((val), (char *)np->reg + ncr_offw(o))#define OUTL_OFF(o, val) writel_b2l((val), (char *)np->reg + (o))#elif defined(__LITTLE_ENDIAN) && defined(SCSI_NCR_BIG_ENDIAN)#define INW_OFF(o) readw_b2l((char *)np->reg + ncr_offw(o))#define INL_OFF(o) readl_b2l((char *)np->reg + (o))#define OUTW_OFF(o, val) writew_l2b((val), (char *)np->reg + ncr_offw(o))#define OUTL_OFF(o, val) writel_l2b((val), (char *)np->reg + (o))#else#define INW_OFF(o) readw_raw((char *)np->reg + ncr_offw(o))#define INL_OFF(o) readl_raw((char *)np->reg + (o))#define OUTW_OFF(o, val) writew_raw((val), (char *)np->reg + ncr_offw(o))#define OUTL_OFF(o, val) writel_raw((val), (char *)np->reg + (o))#endif#endif /* defined NCR_IOMAPPED */#define INB(r) INB_OFF (offsetof(struct ncr_reg,r))#define INW(r) INW_OFF (offsetof(struct ncr_reg,r))#define INL(r) INL_OFF (offsetof(struct ncr_reg,r))#define OUTB(r, val) OUTB_OFF (offsetof(struct ncr_reg,r), (val))#define OUTW(r, val) OUTW_OFF (offsetof(struct ncr_reg,r), (val))#define OUTL(r, val) OUTL_OFF (offsetof(struct ncr_reg,r), (val))/*** Set bit field ON, OFF */#define OUTONB(r, m) OUTB(r, INB(r) | (m))#define OUTOFFB(r, m) OUTB(r, INB(r) & ~(m))#define OUTONW(r, m) OUTW(r, INW(r) | (m))#define OUTOFFW(r, m) OUTW(r, INW(r) & ~(m))#define OUTONL(r, m) OUTL(r, INL(r) | (m))#define OUTOFFL(r, m) OUTL(r, INL(r) & ~(m))/*==========================================================**** Command control block states.****==========================================================*/#define HS_IDLE (0)#define HS_BUSY (1)#define HS_NEGOTIATE (2) /* sync/wide data transfer*/#define HS_DISCONNECT (3) /* Disconnected by target */#define HS_COMPLETE (4)#define HS_SEL_TIMEOUT (5) /* Selection timeout */#define HS_RESET (6) /* SCSI reset */#define HS_ABORTED (7) /* Transfer aborted */#define HS_TIMEOUT (8) /* Software timeout */#define HS_FAIL (9) /* SCSI or PCI bus errors */#define HS_UNEXPECTED (10) /* Unexpected disconnect */#define HS_DONEMASK (0xfc)/*==========================================================**** Software Interrupt Codes****==========================================================*/#define SIR_SENSE_RESTART (1)#define SIR_SENSE_FAILED (2)#define SIR_STALL_RESTART (3)#define SIR_STALL_QUEUE (4)#define SIR_NEGO_SYNC (5)#define SIR_NEGO_WIDE (6)#define SIR_NEGO_FAILED (7)#define SIR_NEGO_PROTO (8)#define SIR_REJECT_RECEIVED (9)#define SIR_REJECT_SENT (10)#define SIR_IGN_RESIDUE (11)#define SIR_MISSING_SAVE (12)#define SIR_DATA_IO_IS_OUT (13)#define SIR_DATA_IO_IS_IN (14)#define SIR_MAX (14)/*==========================================================**** Extended error codes.** xerr_status field of struct ccb.****==========================================================*/#define XE_OK (0)#define XE_EXTRA_DATA (1) /* unexpected data phase */#define XE_BAD_PHASE (2) /* illegal phase (4/5) *//*==========================================================**** Negotiation status.** nego_status field of struct ccb.****==========================================================*/#define NS_SYNC (1)#define NS_WIDE (2)/*==========================================================**** "Special features" of targets.** quirks field of struct tcb.** actualquirks field of struct ccb.****==========================================================*/#define QUIRK_AUTOSAVE (0x01)#define QUIRK_NOMSG (0x02)#define QUIRK_NOSYNC (0x10)#define QUIRK_NOWIDE16 (0x20)#define QUIRK_UPDATE (0x80)/*==========================================================**** Capability bits in Inquire response byte 7.****==========================================================*/#define INQ7_QUEUE (0x02)#define INQ7_SYNC (0x10)#define INQ7_WIDE16 (0x20)/*==========================================================**** Misc.****==========================================================*/#define CCB_MAGIC (0xf2691ad2)/*==========================================================**** Declaration of structs.****==========================================================*/struct tcb;struct lcb;struct ccb;struct ncb;struct script;typedef struct ncb * ncb_p;typedef struct tcb * tcb_p;typedef struct lcb * lcb_p;typedef struct ccb * ccb_p;struct link { ncrcmd l_cmd; ncrcmd l_paddr;};struct usrcmd { u_long target; u_long lun; u_long data; u_long cmd;};#define UC_SETSYNC 10#define UC_SETTAGS 11#define UC_SETDEBUG 12#define UC_SETORDER 13#define UC_SETWIDE 14#define UC_SETFLAG 15#define UC_CLEARPROF 16#ifdef SCSI_NCR_DEBUG_ERROR_RECOVERY_SUPPORT#define UC_DEBUG_ERROR_RECOVERY 17#endif#define UF_TRACE (0x01)#define UF_NODISC (0x02)#define UF_NOSCAN (0x04)/*---------------------------------------**** Timestamps for profiling****---------------------------------------*/struct tstamp { u_long start; u_long end; u_long select; u_long command; u_long status; u_long disconnect; u_long reselect;};/*** profiling data (per device)*/struct profile { u_long num_trans; u_long num_kbytes; u_long rest_bytes; u_long num_disc; u_long num_break; u_long num_int; u_long num_fly; u_long ms_setup; u_long ms_data; u_long ms_disc; u_long ms_post;};/*==========================================================**** Declaration of structs: target control block**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -