/* * Core definitions and data structures shareable across OS platforms. * * Copyright (c) 1994-2001 Justin T. Gibbs. * Copyright (c) 2000-2001 Adaptec Inc. * 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. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * substantially similar to the "NO WARRANTY" disclaimer below * ("Disclaimer") and any redistribution must be conditioned upon * including a substantially similar Disclaimer requirement for further * binary redistribution. * 3. Neither the names of the above-listed copyright holders nor the names * of any contributors may 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 * GNU General Public License ("GPL") version 2 as published by the Free * Software Foundation. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES. * * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#85 $ * * $FreeBSD$ */ #ifndef _AIC7XXX_H_ #define _AIC7XXX_H_ /* Register Definitions */ #include "aic7xxx_reg.h" /************************* Forward Declarations *******************************/ struct ahc_platform_data; struct scb_platform_data; struct seeprom_descriptor; /****************************** Useful Macros *********************************/ #ifndef TRUE #define TRUE … #endif #ifndef FALSE #define FALSE … #endif #define ALL_CHANNELS … #define ALL_TARGETS_MASK … #define INITIATOR_WILDCARD … #define SCSIID_TARGET(ahc, scsiid) … #define SCSIID_OUR_ID(scsiid) … #define SCSIID_CHANNEL(ahc, scsiid) … #define SCB_IS_SCSIBUS_B(ahc, scb) … #define SCB_GET_OUR_ID(scb) … #define SCB_GET_TARGET(ahc, scb) … #define SCB_GET_CHANNEL(ahc, scb) … #define SCB_GET_LUN(scb) … #define SCB_GET_TARGET_OFFSET(ahc, scb) … #define SCB_GET_TARGET_MASK(ahc, scb) … #ifdef AHC_DEBUG #define SCB_IS_SILENT(scb) … #else #define SCB_IS_SILENT … #endif #define TCL_TARGET_OFFSET(tcl) … #define TCL_LUN(tcl) … #define BUILD_TCL(scsiid, lun) … #ifndef AHC_TARGET_MODE #undef AHC_TMODE_ENABLE #define AHC_TMODE_ENABLE … #endif /**************************** Driver Constants ********************************/ /* * The maximum number of supported targets. */ #define AHC_NUM_TARGETS … /* * The maximum number of supported luns. * The identify message only supports 64 luns in SPI3. * You can have 2^64 luns when information unit transfers are enabled, * but it is doubtful this driver will ever support IUTs. */ #define AHC_NUM_LUNS … /* * The maximum transfer per S/G segment. */ #define AHC_MAXTRANSFER_SIZE … /* * The maximum amount of SCB storage in hardware on a controller. * This value represents an upper bound. Controllers vary in the number * they actually support. */ #define AHC_SCB_MAX … /* * The maximum number of concurrent transactions supported per driver instance. * Sequencer Control Blocks (SCBs) store per-transaction information. Although * the space for SCBs on the host adapter varies by model, the driver will * page the SCBs between host and controller memory as needed. We are limited * to 253 because: * 1) The 8bit nature of the RISC engine holds us to an 8bit value. * 2) We reserve one value, 255, to represent the invalid element. * 3) Our input queue scheme requires one SCB to always be reserved * in advance of queuing any SCBs. This takes us down to 254. * 4) To handle our output queue correctly on machines that only * support 32bit stores, we must clear the array 4 bytes at a * time. To avoid colliding with a DMA write from the sequencer, * we must be sure that 4 slots are empty when we write to clear * the queue. This reduces us to 253 SCBs: 1 that just completed * and the known three additional empty slots in the queue that * precede it. */ #define AHC_MAX_QUEUE … /* * The maximum amount of SCB storage we allocate in host memory. This * number should reflect the 1 additional SCB we require to handle our * qinfifo mechanism. */ #define AHC_SCB_MAX_ALLOC … /* * Ring Buffer of incoming target commands. * We allocate 256 to simplify the logic in the sequencer * by using the natural wrap point of an 8bit counter. */ #define AHC_TMODE_CMDS … /* Reset line assertion time in us */ #define AHC_BUSRESET_DELAY … /******************* Chip Characteristics/Operating Settings *****************/ /* * Chip Type * The chip order is from least sophisticated to most sophisticated. */ ahc_chip; /* * Features available in each chip type. */ ahc_feature; /* * Bugs in the silicon that we work around in software. */ ahc_bug; /* * Configuration specific settings. * The driver determines these settings by probing the * chip/controller's configuration. */ ahc_flag; /************************* Hardware SCB Definition ***************************/ /* * The driver keeps up to MAX_SCB scb structures per card in memory. The SCB * consists of a "hardware SCB" mirroring the fields available on the card * and additional information the kernel stores for each transaction. * * To minimize space utilization, a portion of the hardware scb stores * different data during different portions of a SCSI transaction. * As initialized by the host driver for the initiator role, this area * contains the SCSI cdb (or a pointer to the cdb) to be executed. After * the cdb has been presented to the target, this area serves to store * residual transfer information and the SCSI status byte. * For the target role, the contents of this area do not change, but * still serve a different purpose than for the initiator role. See * struct target_data for details. */ /* * Status information embedded in the shared poriton of * an SCB after passing the cdb to the target. The kernel * driver will only read this data for transactions that * complete abnormally (non-zero status byte). */ struct status_pkt { … }; /* * Target mode version of the shared data SCB segment. */ struct target_data { … }; struct hardware_scb { … }; /************************ Kernel SCB Definitions ******************************/ /* * Some fields of the SCB are OS dependent. Here we collect the * definitions for elements that all OS platforms need to include * in there SCB definition. */ /* * Definition of a scatter/gather element as transferred to the controller. * The aic7xxx chips only support a 24bit length. We use the top byte of * the length to store additional address bits and a flag to indicate * that a given segment terminates the transfer. This gives us an * addressable range of 512GB on machines with 64bit PCI or with chips * that can support dual address cycles on 32bit PCI busses. */ struct ahc_dma_seg { … }; struct sg_map_node { … }; /* * The current state of this SCB. */ scb_flag; struct scb { … }; struct scb_data { … }; /************************ Target Mode Definitions *****************************/ /* * Connection descriptor for select-in requests in target mode. */ struct target_cmd { … }; /* * Number of events we can buffer up if we run out * of immediate notify ccbs. */ #define AHC_TMODE_EVENT_BUFFER_SIZE … struct ahc_tmode_event { … }; /* * Per enabled lun target mode state. * As this state is directly influenced by the host OS'es target mode * environment, we let the OS module define it. Forward declare the * structure here so we can store arrays of them, etc. in OS neutral * data structures. */ #ifdef AHC_TARGET_MODE struct ahc_tmode_lstate { struct cam_path *path; struct ccb_hdr_slist accept_tios; struct ccb_hdr_slist immed_notifies; struct ahc_tmode_event event_buffer[AHC_TMODE_EVENT_BUFFER_SIZE]; uint8_t event_r_idx; uint8_t event_w_idx; }; #else struct ahc_tmode_lstate; #endif /******************** Transfer Negotiation Datastructures *********************/ #define AHC_TRANS_CUR … #define AHC_TRANS_ACTIVE … #define AHC_TRANS_GOAL … #define AHC_TRANS_USER … #define AHC_WIDTH_UNKNOWN … #define AHC_PERIOD_UNKNOWN … #define AHC_OFFSET_UNKNOWN … #define AHC_PPR_OPTS_UNKNOWN … /* * Transfer Negotiation Information. */ struct ahc_transinfo { … }; /* * Per-initiator current, goal and user transfer negotiation information. */ struct ahc_initiator_tinfo { … }; /* * Per enabled target ID state. * Pointers to lun target state as well as sync/wide negotiation information * for each initiator<->target mapping. For the initiator role we pretend * that we are the target and the targets are the initiators since the * negotiation is the same regardless of role. */ struct ahc_tmode_tstate { … }; /* * Data structure for our table of allowed synchronous transfer rates. */ struct ahc_syncrate { … }; /* Safe and valid period for async negotiations. */ #define AHC_ASYNC_XFER_PERIOD … #define AHC_ULTRA2_XFER_PERIOD … /* * Indexes into our table of syncronous transfer rates. */ #define AHC_SYNCRATE_DT … #define AHC_SYNCRATE_ULTRA2 … #define AHC_SYNCRATE_ULTRA … #define AHC_SYNCRATE_FAST … #define AHC_SYNCRATE_MAX … #define AHC_SYNCRATE_MIN … /***************************** Lookup Tables **********************************/ /* * Phase -> name and message out response * to parity errors in each phase table. */ struct ahc_phase_table_entry { … }; /************************** Serial EEPROM Format ******************************/ struct seeprom_config { … }; /**************************** Message Buffer *********************************/ ahc_msg_type; msg_loop_stat; /*********************** Software Configuration Structure *********************/ TAILQ_HEAD(scb_tailq, scb); struct ahc_aic7770_softc { … }; struct ahc_pci_softc { … }; ahc_bus_softc; ahc_bus_intr_t; ahc_bus_chip_init_t; ahc_callback_t; struct ahc_softc { … }; /************************ Active Device Information ***************************/ role_t; struct ahc_devinfo { … }; /****************************** PCI Structures ********************************/ ahc_device_setup_t; struct ahc_pci_identity { … }; /***************************** VL/EISA Declarations ***************************/ struct aic7770_identity { … }; extern struct aic7770_identity aic7770_ident_table[]; extern const int ahc_num_aic7770_devs; #define AHC_EISA_SLOT_OFFSET … #define AHC_EISA_IOSIZE … /*************************** Function Declarations ****************************/ /******************************************************************************/ /***************************** PCI Front End *********************************/ const struct ahc_pci_identity *ahc_find_pci_device(ahc_dev_softc_t); int ahc_pci_config(struct ahc_softc *, const struct ahc_pci_identity *); int ahc_pci_test_register_access(struct ahc_softc *); void __maybe_unused ahc_pci_resume(struct ahc_softc *ahc); /*************************** EISA/VL Front End ********************************/ struct aic7770_identity *aic7770_find_device(uint32_t); int aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *, u_int port); /************************** SCB and SCB queue management **********************/ int ahc_probe_scbs(struct ahc_softc *); void ahc_qinfifo_requeue_tail(struct ahc_softc *ahc, struct scb *scb); int ahc_match_scb(struct ahc_softc *ahc, struct scb *scb, int target, char channel, int lun, u_int tag, role_t role); /****************************** Initialization ********************************/ struct ahc_softc *ahc_alloc(void *platform_arg, char *name); int ahc_softc_init(struct ahc_softc *); void ahc_controller_info(struct ahc_softc *ahc, char *buf); int ahc_chip_init(struct ahc_softc *ahc); int ahc_init(struct ahc_softc *ahc); void ahc_intr_enable(struct ahc_softc *ahc, int enable); void ahc_pause_and_flushwork(struct ahc_softc *ahc); int __maybe_unused ahc_suspend(struct ahc_softc *ahc); int __maybe_unused ahc_resume(struct ahc_softc *ahc); void ahc_set_unit(struct ahc_softc *, int); void ahc_set_name(struct ahc_softc *, char *); void ahc_free(struct ahc_softc *ahc); int ahc_reset(struct ahc_softc *ahc, int reinit); /***************************** Error Recovery *********************************/ ahc_search_action; int ahc_search_qinfifo(struct ahc_softc *ahc, int target, char channel, int lun, u_int tag, role_t role, uint32_t status, ahc_search_action action); int ahc_search_untagged_queues(struct ahc_softc *ahc, ahc_io_ctx_t ctx, int target, char channel, int lun, uint32_t status, ahc_search_action action); int ahc_search_disc_list(struct ahc_softc *ahc, int target, char channel, int lun, u_int tag, int stop_on_first, int remove, int save_state); int ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset); /*************************** Utility Functions ********************************/ void ahc_compile_devinfo(struct ahc_devinfo *devinfo, u_int our_id, u_int target, u_int lun, char channel, role_t role); /************************** Transfer Negotiation ******************************/ const struct ahc_syncrate* ahc_find_syncrate(struct ahc_softc *ahc, u_int *period, u_int *ppr_options, u_int maxsync); u_int ahc_find_period(struct ahc_softc *ahc, u_int scsirate, u_int maxsync); /* * Negotiation types. These are used to qualify if we should renegotiate * even if our goal and current transport parameters are identical. */ ahc_neg_type; int ahc_update_neg_request(struct ahc_softc*, struct ahc_devinfo*, struct ahc_tmode_tstate*, struct ahc_initiator_tinfo*, ahc_neg_type); void ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, u_int width, u_int type, int paused); void ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, const struct ahc_syncrate *syncrate, u_int period, u_int offset, u_int ppr_options, u_int type, int paused); ahc_queue_alg; /**************************** Target Mode *************************************/ #ifdef AHC_TARGET_MODE void ahc_send_lstate_events(struct ahc_softc *, struct ahc_tmode_lstate *); void ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb); cam_status ahc_find_tmode_devs(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb, struct ahc_tmode_tstate **tstate, struct ahc_tmode_lstate **lstate, int notfound_failure); #ifndef AHC_TMODE_ENABLE #define AHC_TMODE_ENABLE … #endif #endif /******************************* Debug ***************************************/ #ifdef AHC_DEBUG extern uint32_t ahc_debug; #define AHC_SHOW_MISC … #define AHC_SHOW_SENSE … #define AHC_DUMP_SEEPROM … #define AHC_SHOW_TERMCTL … #define AHC_SHOW_MEMORY … #define AHC_SHOW_MESSAGES … #define AHC_SHOW_DV … #define AHC_SHOW_SELTO … #define AHC_SHOW_QFULL … #define AHC_SHOW_QUEUE … #define AHC_SHOW_TQIN … #define AHC_SHOW_MASKED_ERRORS … #define AHC_DEBUG_SEQUENCER … #endif void ahc_print_devinfo(struct ahc_softc *ahc, struct ahc_devinfo *dev); void ahc_dump_card_state(struct ahc_softc *ahc); int ahc_print_register(const ahc_reg_parse_entry_t *table, u_int num_entries, const char *name, u_int address, u_int value, u_int *cur_column, u_int wrap_point); /******************************* SEEPROM *************************************/ int ahc_acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd); void ahc_release_seeprom(struct seeprom_descriptor *sd); #endif /* _AIC7XXX_H_ */