#ifdef _KERNEL #include #include /********************************************************** ** ** Debug definitions */ #ifdef PIO_TRACE #define QL_LOG_CNT 512 #endif /********************************************************** ** ** Macro Definitions */ #ifdef _STANDALONE #define CRITICAL_BEGIN {int s = splhi(); #define CRITICAL_EXIT splx(s) #define CRITICAL_END splx(s);} #endif /********************************************************** ** ** General Information */ #ifdef A64_BIT_OPERATION /* this switch is defined in ql.c */ #define IOCB_SEGS 2 #define CONTINUATION_SEGS 5 #else #define IOCB_SEGS 4 #define CONTINUATION_SEGS 7 #endif /* A64_BIT_OPERATION */ #define MAX_CONTINUATION_ENTRIES 254 #define MAX_ADAPTERS 128 #define QL_MAXTARG 16 #define QL_MAXLUN 8 #ifdef _STANDALONE #define REQUEST_QUEUE_DEPTH 8 #define RESPONSE_QUEUE_DEPTH 8 #define MAX_REQ_INFO 7 #else #define REQUEST_QUEUE_DEPTH 2048 #define RESPONSE_QUEUE_DEPTH 256 #define MAX_REQ_INFO 255 #endif /* STANDALONE */ #define DEF_EXECUTION_THROTTLE 255 /********************************************************** ** ** Internal Command Information */ #define READ_CAP_DATA_LENGTH 8 #ifdef _STANDALONE #define REQ_SENSE_DATA_LENGTH 18 #else #define REQ_SENSE_DATA_LENGTH 32 #endif /********************************************************* ** ** Host Adapter Information */ /*** **** Queue Entry. **** Used only to allocate space for request and response structures. ***/ typedef struct { u_char data[64]; } queue_entry; /*** **** DATA SEGMENT structures. ***/ typedef struct { __psint_t base; u_int count; } data_seg; typedef struct { u_int base_low_32; #ifdef A64_BIT_OPERATION u_int base_high_32; #endif u_int count; } ql_data_seg; typedef struct scatter_g { /* array of scatter gather elements*/ uint num_pages; data_seg dseg[REQUEST_QUEUE_DEPTH*CONTINUATION_SEGS]; } scatter,*p_scatter; typedef struct req_information { #ifndef _STANDALONE alenlist_t alen_l; int timeout; void * ha_p; int cmd_age; int starttime; #endif scsi_request_t* req; } REQ_INFO, *pREQ_INFO; #ifndef _STANDALONE typedef struct timeout_info { int current_timeout; int watchdog_timer; int ql_dups; int ql_tcmd; int time_base; int t_last_intr; mutex_t per_tgt_tlock; } TO_INFO, *pTO_INFO; #endif typedef struct { char id[4]; /* "ISP " */ u_char version; u_char Fifo_Threshold; /* bits */ u_char Not_Used0 :1; /* 2 */ u_char HA_Enable :1; /* 3 */ u_char Initiator_SCSI_Id :4; /* 4,5,6,7 */ u_char Bus_Reset_Delay; u_char Retry_Count; u_char Retry_Delay; union { u_char byte; /* access by entire byte */ struct { /* bits */ /* munged for SGI */ u_char Command_DMA_Burst_Enable :1; /* 7 */ u_char Data_DMA_Burst_Enable :1; /* 6 */ u_char DATA_Line_Active_Negation :1; /* 5 */ u_char REQ_ACK_Active_Negation :1; /* 4 */ u_char ASync_Data_Setup_Time :4; /* 0,1,2,3 */ } bits; } Capability; u_char Tag_Age_Limit; u_char Not_Used1; u_short Selection_Timeout; u_short Max_Queue_Depth; u_short Delay_after_reset; u_char Pad0[12]; /* pad for byte alignment */ struct { union { u_char byte; /* access by entire byte */ struct { /*bit*/ u_char Disconnect_Allowed :1; /* 7 */ u_char Parity_Checking :1; /* 6 */ u_char Wide_Data_Transfers :1; /* 5 */ u_char Sync_Data_Transfers :1; /* 4 */ u_char Tagged_Queuing :1; /* 3 */ u_char Auto_Request_Sense :1; /* 2 */ u_char Stop_Queue_on_Check :1; /* 1 */ u_char Renegotiate_on_Error :1; /* 0 */ } bits; } Capability; u_char Throttle; u_char Sync_Period; /* bits */ u_char Sync_Offset :4; /* 0,1,2,3 */ u_char Wide_Allowed :1; /* 4 */ u_char Sync_Allowed :1; /* 5 */ u_char Force_Sync :1; /* 6 */ u_char Is_CDROM :1; /* 7 */ u_char Available0; u_char Available1; } Id[QL_MAXTARG]; } Default_parameters; typedef struct ha_information { /* ** Linked list pointer of ha structures for interrupt sharing. */ struct ha_information* next_ha; /* ** Base I/O Address for this card. ** Make sure to convert this to a usable virtual address. */ caddr_t ha_base; caddr_t ha_config_base; #ifndef _STANDALONE vertex_hdl_t ctlr_vhdl; vertex_hdl_t pci_vhdl; /* temporary hack 06/04/96 */ /* bus quiesce timeout id's */ int quiesce_in_progress_id; /* how long to wait for quiesce to */ /* complete */ toid_t quiesce_id; /* id for quiesce_time */ int quiesce_time; /* how long to keep the bus quiesced */ #endif u_int flags; /* general flags for this adapter */ u_short revision; /* PCI Revision ID Register */ u_short bridge_revnum; /* Bridge rev number */ /* ** Request and Response pointers */ u_short request_in; /* request in pointer */ u_short request_out; /* request out pointer */ u_short response_out; /* response out pointer (copy of mailbox 5 OUT) */ u_short response_in; /* response in pointer (copy of mailbox 5 IN) */ int queue_space; queue_entry* request_ptr; queue_entry* request_base; #ifndef _STANDALONE pciio_dmamap_t request_dmamap; paddr_t request_dmaptr; #endif queue_entry* response_ptr; queue_entry* response_base; int ql_request_queue_depth; int ql_response_queue_depth; #ifndef _STANDALONE pciio_dmamap_t response_dmamap; paddr_t response_dmaptr; #endif /* ** General flags for each device. ** This is used to determine if the device driver ** has performed a SCSI_INIT on the device AND whether the ** device has been enabled in the NVRAM. */ #if defined(_STANDALONE) u_short controller_number; /* only for standalone */ u_char dev_init[QL_MAXTARG]; /* set with 1<8 reserved */ /* 7->4 Extended FIFO control */ /* 3 SXP Register Select */ /* 2 Burst enable */ /* 1->0 FIFO control */ /* */ /* */ /* the original 1020 only used bits 0 and 1 */ /* but this could not occomodate 128 the btye option*/ /* Now only use the Extended FIFO control */ /* bits 7->4 bits 1->0 burst size */ /* */ /* 4 x 128 */ /* 3 x 64 */ /* 2 x 32 */ /* 1 x 16 */ /* 0 3 64 */ /* 0 2 32 */ /* 0 1 16 */ /* 0 0 8 */ #define BURST_128 0x40 #define BURST_64 0x30 #define BURST_32 0x20 #define BURST_16 0x10 #define HA_ENABLE 1 /* enabled */ #if defined(EVEREST) #define INITIATOR_SCSI_ID 7 #else #define INITIATOR_SCSI_ID 0 #endif #define BUS_RESET_DELAY 3 /* 3 seconds */ #define RETRY_COUNT 0 /* no retries */ #define RETRY_DELAY 0 /* no time between tries*/ #define ASYNC_DATA_SETUP_TIME 9 /* 9 clock periods */ #define REQ_ACK_ACTIVE_NEGATION 1 /* enabled */ #define DATA_ACTIVE_NEGATION 1 /* enabled */ #define DATA_DMA_BURST_ENABLE 1 /* enabled */ #define CMD_DMA_BURST_ENABLE 1 /* enabled */ #define TAG_AGE_LIMIT 8 #define SELECTION_TIMEOUT 250 /* 250 ms */ #define SELECTION_TIMEOUT_SHORT 75 /* 75 us */ #define MAX_QUEUE_DEPTH 256 /* 256 commands */ #define DELAY_AFTER_RESET 1 /*second*/ /* ** Drive defaults. */ #ifdef _STANDALONE #define RENEGOTIATE_ON_ERROR 0 #define STOP_QUEUE_ON_CHECK 0 #define AUTO_REQUEST_SENSE 1 #define TAGGED_QUEUING 0 #define WIDE_DATA_TRANSFERS 0 #define PARITY_CHECKING 0 #if SN0 || IP30 #define DISCONNECT_ALLOWED 0 #define SYNC_DATA_TRANSFERS 0 #else #define DISCONNECT_ALLOWED 1 #define SYNC_DATA_TRANSFERS 1 #endif #define EXECUTION_THROTTLE 16 #define SYNC_PERIOD 25 #define SYNC_PERIOD_FAST20 12 #define SYNC_OFFSET 8 #define DEVICE_ENABLE 1 #define DEFAULT_TIMEOUT 10 #else /* !_STANDALONE */ #define RENEGOTIATE_ON_ERROR 1 /* ON */ #define STOP_QUEUE_ON_CHECK 0 /* OFF */ #define AUTO_REQUEST_SENSE 1 /* ON */ #define TAGGED_QUEUING 1 /* ON */ #define SYNC_DATA_TRANSFERS 1 /* ON */ #ifndef WIDE_DATA_TRANSFERS #if defined(SN0) || defined(EVEREST) || defined(IP30) #define WIDE_DATA_TRANSFERS 1 /* ON */ #else #define WIDE_DATA_TRANSFERS 0 /* OFF */ #endif #endif /* WIDE_DATA_TRANSFERS */ #define PARITY_CHECKING 1 #define DISCONNECT_ALLOWED 1 #define EXECUTION_THROTTLE 255 #define SYNC_PERIOD 25 /* 100 ns */ #define SYNC_PERIOD_FAST20 12 /* 50 ns */ #define SYNC_OFFSET 8 #define MAX_SYNC_OFFSET 12 #define DEFAULT_TIMEOUT 10 /* default scsi timeout is 10 sec */ #endif /* _STANDALONE */ /* part revision numbers */ #define REV_ISP1020 1 #define REV_ISP1040 1 /* note that this is the same as 1020 */ /* early part were speed graded only */ #define REV_ISP1040A 2 #define REV_ISP1040AV4 3 #define REV_ISP1040B 4 #define REV_ISP1040BV2 5 /* qlogic 1040B rev 2 */ /* the following are defines for MBOX_CMD_SET_DATA_RECOVERY_MODE */ /* we are supporting mode 2 right now */ #define DATA_OVERRUN_MODE_0 0 /* pad data until the target switches out */ /* of data phase */ #define DATA_OVERRUN_MODE_1 1 /* hang the bus interrupt host with */ /* 0x800c in outgoing mailbox 0 register */ /* the host must reset the bus with mail */ /* box command */ #define DATA_OVERRUN_MODE_2 2 /* ISP resets the SCSI bus places 0x800D */ /* in outgoing mailbox 0 and returns all */ /* outstanding io's */ /********************************************************** ** ** PCI Service Information */ #define PCI_CONFIG 0xCF8 #define PCI_ENABLE 0x80 #define PCI_CONFIG_START 0xC000 #define PCI_CONFIG_LAST 0xCFFF #define PCI_FUNCTION_ID 0xB100 /* ** PCI Function List. */ #define PCI_BIOS_PRESENT 0xB101 #define FIND_PCI_DEVICE 0xB102 #define FIND_PCI_CLASS_CODE 0xB103 #define GENERATE_SPECIAL_CYCLE 0xB106 #define READ_CONFIG_BYTE 0xB108 #define READ_CONFIG_WORD 0xB109 #define READ_CONFIG_DWORD 0xB10A #define WRITE_CONFIG_BYTE 0xB10B #define WRITE_CONFIG_WORD 0xB10C #define WRITE_CONFIG_DWORD 0xB10D /* ** PCI Return Code List. */ #define SUCCESSFUL 0x00 #define FUNC_NOT_SUPPORTED 0x81 #define BAD_VENDOR_ID 0x83 #define DEVICE_NOT_FOUND 0x86 #define BAD_REGISTER_NUMBER 0x87 /********************************************************** ** ** our PCI Information */ /* ** PCI Bus configuration space registers. */ typedef struct PCI_Config_Registers { u_short Device_Id; u_short Vendor_Id; /* 00 */ u_short Status; u_short Command; /* 04 */ u_char Class_Code[3]; u_char Rev_Id; /* 08 */ u_char Bits; u_char Header_Type; u_char Latency_Timer; u_char Cache_Line_Size; /* 0C */ u_int IO_Base_Address; /* 10 */ u_int Memory_Base_Address; /* 14 */ u_int Not_Used1[6]; /* 18 - 2F */ u_int ROM_Base_Address; /* 30 */ u_int Not_Used2[2]; /* 34 - 3B */ u_char Interrupt_Line; /* 3C */ u_char Interrupt_Pin; u_char Minimum_Grant; u_char Maximum_Latency; u_short ISP_Config_1; /* 40 */ u_short Not_Used3; } PCI_REG, *pPCI_REG; /* ** Configuration space offsets: */ #define CONF_VENDOR_ID_OFFSET 0x00 #define QLogic_VENDOR_ID 0x1077 #define CONF_DEVICE_ID_OFFSET 0x02 #define QLogic_DEVICE_ID 0x1020 #define CONF_COMMAND_OFFSET 0x04 #define CONF_COMMAND_VALUE 0x0156 /* ** 0x0156 = IO Space Disabled ** Memory Space Enabled ** PCI Master Capable ** Memory Write & Invalidate Enabled ** Parity Error Response Enabled ** SERR# Enabled ** Back to Back Transfers Disabled */ #define CONF_IO_BASE_OFFSET 0x10 #define CONF_MEM_BASE_OFFSET 0x14 #define MEMORY_SPACE_INDICATOR_MASK 0x00000001 #define IO_BASE_MASK 0xF800 #define MEMORY_BASE_MASK 0xFFFFF800 #define CONF_INTERRUPT_LINE_OFFSET 0x3C typedef struct { int commands_issued; int responses_handled; int errors; } dev_stats; /* ** Structure to return for IOCSTATS. */ typedef struct stats { int commands; /* # of commands processed */ int responses; /* # of responses processed */ int interrupts; /* # of interrupts processed */ int intrs_processed; /* # of interrupts ACTUALLY processed */ int responses_handled; /* # IORB processed */ int markers; /* # of markers issued */ dev_stats dev[QL_MAXTARG]; } stats, *ha_stats; struct irix5_stats { app32_int_t commands; /* # of commands processed */ app32_int_t responses; /* # of responses processed */ app32_int_t interrupts; /* # of interrupts processed */ app32_int_t intrs_processed; /* # of interrupts ACTUALLY processed */ app32_int_t responses_handled; /* # IORB processed */ app32_int_t markers; /* # of markers issued */ }; /* ** Structure to peek and poke risc memory. */ struct addr_data { unsigned short address; /* word address in risc memory */ unsigned short data; /* word data to write (if write) */ }; /* * info specific to the ql lun vertex */ typedef struct ql_local_info { mutex_t qli_open_mutex; /* open lock */ mutex_t qli_lun_mutex; /* LUN lock */ u_int qli_dev_flags; /* lun device flags */ int qli_ref_count; /* no. of references */ int qli_cmd_rcnt; /* issued command count to this LUN */ int qli_cmd_awcnt; /* abort waiting command count for this LUN */ int qli_cmd_iwcnt; /* init waiting command count for this LUN */ scsi_request_t* qli_awaitf; /* forward pointer for commands awaiting abort completion */ scsi_request_t* qli_awaitb; /* backward pointer for commands awaiting abort completion */ scsi_request_t* qli_iwaitf; /* forward pointer for commands awaiting init. completion */ scsi_request_t* qli_iwaitb; /* backward pointer for commands awaiting init. completion */ scsi_target_info_t *qli_tinfo; /* scsi target info */ void (*qli_sense_callback)(); /* Sense callback routine */ } ql_local_info_t; /* * macros associated with this structure */ #define QLI_DEVFLAGS(p) (p->qli_dev_flags) #define QLI_OPENMUTEX(p) (p->qli_open_mutex) #define QLI_LUNMUTEX(p) (p->qli_lun_mutex) #define QLI_REFCOUNT(p) (p->qli_ref_count) #define QLI_TINFO(p) (p->qli_tinfo) /* * macros associated with the scsi lun info structure specific * to ql */ #define QL_DEVFLAGS(p) QLI_DEVFLAGS(((ql_local_info_t *)p)) #define QL_OPENMUTEX(p) QLI_OPENMUTEX(((ql_local_info_t *)p)) #define QL_LUNMUTEX(p) QLI_LUNMUTEX(((ql_local_info_t *)p)) #define QL_REFCOUNT(p) QLI_REFCOUNT(((ql_local_info_t *)p)) #define QL_TINFO(p) QLI_TINFO(((ql_local_info_t *)p)) #define DEV_FLAGS(p) QL_DEVFLAGS(SLI_INFO(p)) #define OPEN_MUTEX(p) QL_OPENMUTEX(SLI_INFO(p)) #define LUN_MUTEX(p) QL_LUNMUTEX(SLI_INFO(p)) #define REF_COUNT(p) QL_REFCOUNT(SLI_INFO(p)) #define TINFO(p) QL_TINFO(SLI_INFO(p)) #define SCI_HA_INFO(p) ((pHA_INFO)(SCI_INFO(p))) #define SLI_HA_INFO(p) ((pHA_INFO)(SCI_INFO(SLI_CTLR_INFO(p)))) #endif /* KERNEL */ /* ** Some miscellaneous configuration parameters. */ #define QL_RESET 1000 #define QL_COMPUTE_PARITY_MEMORY 4000 #define WATCHDOG_TIME 10 /* for bringup set to 10 */ #define SCSI_INFO_BYTE 7 #define SCSI_CTQ_BIT 2 /* * Encoding of GPIO bits on channel 0 - MSCSI/A * [3](r) [2](r) [1](w) [0](w) * 0 = in slot XIO1 * 1 = not in slot XIO1 * diffsense * 0 = no internal terminator * 1 = internal terminator * 0 = internal bus selected * 1 = external bus selected * * Encoding of GPIO bits on channel 0 - MSCSI/B * [3](r) [2](r) [1](w) [0](w) * 0 = in slot XIO1 * 1 = not in slot XIO1 * not connected * 0 0 = Internal SE selected * 0 1 = External SE selected * 1 0 = External DF (no termination) * 1 1 = External DF (termination) * */ #define GPIO0 0x01 #define GPIO1 0x02 #define GPIO2 0x04 #define GPIO3 0x08 #define ENABLE_WRITE (GPIO0 | GPIO1) #define ENABLE_WRITE_SN00 0x01 #define NOT_SLOT_ZERO GPIO3 #define MAX_HANDLE_NO ((QL_MAXTARG * (MAX_REQ_INFO +1)) | MAX_REQ_INFO) #define QLPRI 0 /* Doesn't matter, since pri isn't used anymore */ #define INITLOCK(l,n,s) init_mutex(l, MUTEX_DEFAULT, n, s) #define LOCK(l) mutex_lock(&(l), QLPRI) #define UNLOCK(l) mutex_unlock(&(l)) #define IOLOCK(l,s) mutex_lock(&(l), QLPRI) #define IOUNLOCK(l,s) mutex_unlock(&(l)) #define SPL_DECL(s) #define QL_MUTEX_ENTER(ha) IOLOCK(ha->res_lock,s), \ IOLOCK(ha->req_lock,s) #define QL_MUTEX_EXIT(ha) IOUNLOCK(ha->res_lock,s), \ IOUNLOCK(ha->req_lock,s)