1152919Sscottl/*- 2152919Sscottl * Copyright (c) 2002 Adaptec Inc. 3152919Sscottl * All rights reserved. 4152919Sscottl * 5152919Sscottl * Written by: David Jeffery 6152919Sscottl * 7152919Sscottl * Redistribution and use in source and binary forms, with or without 8152919Sscottl * modification, are permitted provided that the following conditions 9152919Sscottl * are met: 10152919Sscottl * 1. Redistributions of source code must retain the above copyright 11152919Sscottl * notice, this list of conditions and the following disclaimer. 12152919Sscottl * 2. Redistributions in binary form must reproduce the above copyright 13152919Sscottl * notice, this list of conditions and the following disclaimer in the 14152919Sscottl * documentation and/or other materials provided with the distribution. 15152919Sscottl * 16152919Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17152919Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18152919Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19152919Sscottl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20152919Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21152919Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22152919Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23152919Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24152919Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25152919Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26152919Sscottl * SUCH DAMAGE. 27152919Sscottl * 28152919Sscottl * $FreeBSD$ 29152919Sscottl */ 30152919Sscottl 31152919Sscottl#include <sys/param.h> 32152919Sscottl 33152919Sscottl/* 34152919Sscottl * IPS CONSTANTS 35152919Sscottl */ 36152919Sscottl#define IPS_VENDOR_ID 0x1014 37152919Sscottl#define IPS_VENDOR_ID_ADAPTEC 0x9005 38152919Sscottl#define IPS_MORPHEUS_DEVICE_ID 0x01BD 39152919Sscottl#define IPS_COPPERHEAD_DEVICE_ID 0x002E 40152919Sscottl#define IPS_MARCO_DEVICE_ID 0x0250 41152919Sscottl#define IPS_CSL 0xff 42152919Sscottl#define IPS_POCL 0x30 43152919Sscottl 44152919Sscottl/* amounts of memory to allocate for certain commands */ 45152919Sscottl#define IPS_ADAPTER_INFO_LEN (sizeof(ips_adapter_info_t)) 46152919Sscottl#define IPS_DRIVE_INFO_LEN (sizeof(ips_drive_info_t)) 47152919Sscottl#define IPS_COMMAND_LEN 24 48152919Sscottl#define IPS_MAX_SG_LEN (sizeof(ips_sg_element_t) * IPS_MAX_SG_ELEMENTS) 49152919Sscottl#define IPS_NVRAM_PAGE_SIZE 128 50152919Sscottl/* various flags */ 51152919Sscottl#define IPS_STATIC_FLAG 0x01 52152919Sscottl 53152919Sscottl/* states for the card to be in */ 54152919Sscottl#define IPS_DEV_OPEN 0x01 55152919Sscottl#define IPS_TIMEOUT 0x02 /* command time out, need reset */ 56152919Sscottl#define IPS_OFFLINE 0x04 /* can't reset card/card failure */ 57152919Sscottl#define IPS_STATIC_BUSY 0x08 58152919Sscottl 59152919Sscottl/* max number of commands set to something low for now */ 60152919Sscottl#define IPS_MAX_CMD_NUM 128 61152919Sscottl#define IPS_MAX_NUM_DRIVES 8 62152919Sscottl#define IPS_MAX_SG_ELEMENTS 32 63152919Sscottl#define IPS_MAX_IOBUF_SIZE (64 * 1024) 64152919Sscottl#define IPS_BLKSIZE 512 65154005Sscottl#define IPS_MAX_LD 8 66154005Sscottl#define IPS_MAX_CHANNELS 4 67154005Sscottl#define IPS_MAX_TARGETS 15 68154005Sscottl#define IPS_MAX_CHUNKS 16 69152919Sscottl 70152919Sscottl/* logical drive states */ 71152919Sscottl 72152919Sscottl#define IPS_LD_OFFLINE 0x02 73152919Sscottl#define IPS_LD_OKAY 0x03 74152919Sscottl#define IPS_LD_DEGRADED 0x04 75152919Sscottl#define IPS_LD_FREE 0x00 76152919Sscottl#define IPS_LD_SYS 0x06 77152919Sscottl#define IPS_LD_CRS 0x24 78152919Sscottl 79152919Sscottl/* register offsets */ 80152919Sscottl#define MORPHEUS_REG_OMR0 0x0018 /* Outbound Msg. Reg. 0 */ 81152919Sscottl#define MORPHEUS_REG_OMR1 0x001C /* Outbound Msg. Reg. 1 */ 82152919Sscottl#define MORPHEUS_REG_IDR 0x0020 /* Inbound Doorbell Reg. */ 83152919Sscottl#define MORPHEUS_REG_IISR 0x0024 /* Inbound IRQ Status Reg. */ 84152919Sscottl#define MORPHEUS_REG_IIMR 0x0028 /* Inbound IRQ Mask Reg. */ 85152919Sscottl#define MORPHEUS_REG_OISR 0x0030 /* Outbound IRQ Status Reg. */ 86152919Sscottl#define MORPHEUS_REG_OIMR 0x0034 /* Outbound IRQ Mask Reg. */ 87152919Sscottl#define MORPHEUS_REG_IQPR 0x0040 /* Inbound Queue Port Reg. */ 88152919Sscottl#define MORPHEUS_REG_OQPR 0x0044 /* Outbound Queue Port Reg. */ 89152919Sscottl 90152919Sscottl#define COPPER_REG_SCPR 0x05 /* Subsystem Ctrl. Port Reg. */ 91152919Sscottl#define COPPER_REG_ISPR 0x06 /* IRQ Status Port Reg. */ 92152919Sscottl#define COPPER_REG_CBSP 0x07 /* ? Reg. */ 93152919Sscottl#define COPPER_REG_HISR 0x08 /* Host IRQ Status Reg. */ 94152919Sscottl#define COPPER_REG_CCSAR 0x10 /* Cmd. Channel Sys Addr Reg.*/ 95152919Sscottl#define COPPER_REG_CCCR 0x14 /* Cmd. Channel Ctrl. Reg. */ 96152919Sscottl#define COPPER_REG_SQHR 0x20 /* Status Queue Head Reg. */ 97152919Sscottl#define COPPER_REG_SQTR 0x24 /* Status Queue Tail Reg. */ 98152919Sscottl#define COPPER_REG_SQER 0x28 /* Status Queue End Reg. */ 99152919Sscottl#define COPPER_REG_SQSR 0x2C /* Status Queue Start Reg. */ 100152919Sscottl 101152919Sscottl/* bit definitions */ 102152919Sscottl#define MORPHEUS_BIT_POST1 0x01 103152919Sscottl#define MORPHEUS_BIT_POST2 0x02 104152919Sscottl#define MORPHEUS_BIT_CMD_IRQ 0x08 105152919Sscottl 106152919Sscottl#define COPPER_CMD_START 0x101A 107152919Sscottl#define COPPER_SEM_BIT 0x08 108152919Sscottl#define COPPER_EI_BIT 0x80 109152919Sscottl#define COPPER_EBM_BIT 0x02 110152919Sscottl#define COPPER_RESET_BIT 0x80 111152919Sscottl#define COPPER_GHI_BIT 0x04 112152919Sscottl#define COPPER_SCE_BIT 0x01 113152919Sscottl#define COPPER_OP_BIT 0x01 114152919Sscottl#define COPPER_ILE_BIT 0x10 115152919Sscottl 116152919Sscottl/* status defines */ 117152919Sscottl#define IPS_POST1_OK 0x8000 118152919Sscottl#define IPS_POST2_OK 0x000f 119152919Sscottl 120152919Sscottl/* command op codes */ 121152919Sscottl#define IPS_READ_CMD 0x02 122152919Sscottl#define IPS_WRITE_CMD 0x03 123152919Sscottl#define IPS_ADAPTER_INFO_CMD 0x05 124152919Sscottl#define IPS_CACHE_FLUSH_CMD 0x0A 125152919Sscottl#define IPS_REBUILD_STATUS_CMD 0x0C 126152919Sscottl#define IPS_ERROR_TABLE_CMD 0x17 127152919Sscottl#define IPS_DRIVE_INFO_CMD 0x19 128154005Sscottl#define IPS_CMD_READ_CONF 0x38 129152919Sscottl#define IPS_SUBSYS_PARAM_CMD 0x40 130152919Sscottl#define IPS_CONFIG_SYNC_CMD 0x58 131152919Sscottl#define IPS_SG_READ_CMD 0x82 132152919Sscottl#define IPS_SG_WRITE_CMD 0x83 133152919Sscottl#define IPS_RW_NVRAM_CMD 0xBC 134152919Sscottl#define IPS_FFDC_CMD 0xD7 135152919Sscottl 136152919Sscottl/* basic_status information returned by the adapter */ 137152919Sscottl#define IPS_MIN_ERROR 0x02 138152919Sscottl#define IPS_BASIC_STATUS_MASK 0xFF 139152919Sscottl#define IPS_GSC_STATUS_MASK 0x0F 140152919Sscottl#define IPS_CMD_SUCCESS 0x00 141152919Sscottl#define IPS_CMD_RECOVERED_ERROR 0x01 142152919Sscottl#define IPS_DRV_ERROR 0x02 /* Driver supplied error */ 143152919Sscottl#define IPS_INVAL_OPCO 0x03 144152919Sscottl#define IPS_INVAL_CMD_BLK 0x04 145152919Sscottl#define IPS_INVAL_PARM_BLK 0x05 146152919Sscottl#define IPS_BUSY 0x08 147152919Sscottl#define IPS_CMD_CMPLT_WERROR 0x0C 148152919Sscottl#define IPS_LD_ERROR 0x0D 149152919Sscottl#define IPS_CMD_TIMEOUT 0x0E 150152919Sscottl#define IPS_PHYS_DRV_ERROR 0x0F 151152919Sscottl 152152919Sscottl/* extended_status information returned by the adapter */ 153152919Sscottl#define IPS_ERR_SEL_TO 0xF0 154152919Sscottl#define IPS_ERR_OU_RUN 0xF2 155152919Sscottl#define IPS_ERR_HOST_RESET 0xF7 156152919Sscottl#define IPS_ERR_DEV_RESET 0xF8 157152919Sscottl#define IPS_ERR_RECOVERY 0xFC 158152919Sscottl#define IPS_ERR_CKCOND 0xFF 159152919Sscottl 160152919Sscottl#define IPS_OS_FREEBSD 8 161152919Sscottl#define IPS_VERSION_MAJOR "0.90" 162152919Sscottl#define IPS_VERSION_MINOR ".10" 163152919Sscottl 164152919Sscottl/* Adapter Types */ 165152919Sscottl#define IPS_ADAPTER_COPPERHEAD 0x01 166152919Sscottl#define IPS_ADAPTER_COPPERHEAD2 0x02 167152919Sscottl#define IPS_ADAPTER_COPPERHEADOB1 0x03 168152919Sscottl#define IPS_ADAPTER_COPPERHEADOB2 0x04 169152919Sscottl#define IPS_ADAPTER_CLARINET 0x05 170152919Sscottl#define IPS_ADAPTER_CLARINETLITE 0x06 171152919Sscottl#define IPS_ADAPTER_TROMBONE 0x07 172152919Sscottl#define IPS_ADAPTER_MORPHEUS 0x08 173152919Sscottl#define IPS_ADAPTER_MORPHEUSLITE 0x09 174152919Sscottl#define IPS_ADAPTER_NEO 0x0A 175152919Sscottl#define IPS_ADAPTER_NEOLITE 0x0B 176152919Sscottl#define IPS_ADAPTER_SARASOTA2 0x0C 177152919Sscottl#define IPS_ADAPTER_SARASOTA1 0x0D 178152919Sscottl#define IPS_ADAPTER_MARCO 0x0E 179152919Sscottl#define IPS_ADAPTER_SEBRING 0x0F 180163024Smaxim#define IPS_ADAPTER_7T 0x10 181163024Smaxim#define IPS_ADAPTER_7K 0x11 182163024Smaxim#define IPS_ADAPTER_7M 0x12 183163024Smaxim#define IPS_ADAPTER_MAX_T IPS_ADAPTER_7M 184152919Sscottl 185152919Sscottl/* values for ffdc_settime (from gmtime) */ 186152919Sscottl#define IPS_SECSPERMIN 60 187152919Sscottl#define IPS_MINSPERHOUR 60 188152919Sscottl#define IPS_HOURSPERDAY 24 189152919Sscottl#define IPS_DAYSPERWEEK 7 190152919Sscottl#define IPS_DAYSPERNYEAR 365 191152919Sscottl#define IPS_DAYSPERLYEAR 366 192152919Sscottl#define IPS_SECSPERHOUR (IPS_SECSPERMIN * IPS_MINSPERHOUR) 193152919Sscottl#define IPS_SECSPERDAY ((long) IPS_SECSPERHOUR * IPS_HOURSPERDAY) 194152919Sscottl#define IPS_MONSPERYEAR 12 195152919Sscottl#define IPS_EPOCH_YEAR 1970 196152919Sscottl#define IPS_LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) 197152919Sscottl#define ips_isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) 198152919Sscottl 199152919Sscottl/* 200152919Sscottl * IPS STRUCTS 201152919Sscottl */ 202152919Sscottl 203152919Sscottltypedef struct{ 204152919Sscottl u_int8_t command; 205152919Sscottl u_int8_t id; 206152919Sscottl u_int8_t drivenum; 207152919Sscottl u_int8_t reserve2; 208152919Sscottl u_int32_t lba; 209152919Sscottl u_int32_t buffaddr; 210152919Sscottl u_int32_t reserve3; 211152919Sscottl} __attribute__ ((packed)) ips_generic_cmd; 212152919Sscottl 213152919Sscottltypedef struct{ 214152919Sscottl u_int8_t command; 215152919Sscottl u_int8_t id; 216152919Sscottl u_int8_t drivenum; 217152919Sscottl u_int8_t segnum; 218152919Sscottl u_int32_t lba; 219152919Sscottl u_int32_t buffaddr; 220152919Sscottl u_int16_t length; 221152919Sscottl u_int16_t reserve1; 222152919Sscottl} __attribute__ ((packed)) ips_io_cmd; 223152919Sscottl 224152919Sscottltypedef struct{ 225152919Sscottl u_int8_t command; 226152919Sscottl u_int8_t id; 227152919Sscottl u_int8_t pagenum; 228152919Sscottl u_int8_t rw; 229152919Sscottl u_int32_t reserve1; 230152919Sscottl u_int32_t buffaddr; 231152919Sscottl u_int32_t reserve3; 232152919Sscottl} __attribute__ ((packed)) ips_rw_nvram_cmd; 233152919Sscottl 234152919Sscottltypedef struct{ 235152919Sscottl u_int8_t command; 236152919Sscottl u_int8_t id; 237152919Sscottl u_int8_t drivenum; 238152919Sscottl u_int8_t reserve1; 239152919Sscottl u_int32_t reserve2; 240152919Sscottl u_int32_t buffaddr; 241152919Sscottl u_int32_t reserve3; 242152919Sscottl} __attribute__ ((packed)) ips_drive_cmd; 243152919Sscottl 244152919Sscottltypedef struct{ 245152919Sscottl u_int8_t command; 246152919Sscottl u_int8_t id; 247152919Sscottl u_int8_t reserve1; 248152919Sscottl u_int8_t commandtype; 249152919Sscottl u_int32_t reserve2; 250152919Sscottl u_int32_t buffaddr; 251152919Sscottl u_int32_t reserve3; 252152919Sscottl} __attribute__((packed)) ips_adapter_info_cmd; 253152919Sscottl 254152919Sscottltypedef struct{ 255152919Sscottl u_int8_t command; 256152919Sscottl u_int8_t id; 257152919Sscottl u_int8_t reset_count; 258152919Sscottl u_int8_t reset_type; 259152919Sscottl u_int8_t second; 260152919Sscottl u_int8_t minute; 261152919Sscottl u_int8_t hour; 262152919Sscottl u_int8_t day; 263152919Sscottl u_int8_t reserve1[4]; 264152919Sscottl u_int8_t month; 265152919Sscottl u_int8_t yearH; 266152919Sscottl u_int8_t yearL; 267152919Sscottl u_int8_t reserve2; 268152919Sscottl} __attribute__((packed)) ips_adapter_ffdc_cmd; 269152919Sscottl 270152919Sscottltypedef union{ 271152919Sscottl ips_generic_cmd generic_cmd; 272152919Sscottl ips_drive_cmd drive_cmd; 273152919Sscottl ips_adapter_info_cmd adapter_info_cmd; 274152919Sscottl} ips_cmd_buff_t; 275152919Sscottl 276152919Sscottltypedef struct { 277152919Sscottl u_int32_t signature; 278152919Sscottl u_int8_t reserved; 279152919Sscottl u_int8_t adapter_slot; 280152919Sscottl u_int16_t adapter_type; 281152919Sscottl u_int8_t bios_high[4]; 282152919Sscottl u_int8_t bios_low[4]; 283152919Sscottl u_int16_t reserve2; 284152919Sscottl u_int8_t reserve3; 285152919Sscottl u_int8_t operating_system; 286152919Sscottl u_int8_t driver_high[4]; 287152919Sscottl u_int8_t driver_low[4]; 288152919Sscottl u_int8_t reserve4[100]; 289152919Sscottl}__attribute__((packed)) ips_nvram_page5; 290152919Sscottl 291152919Sscottltypedef struct{ 292152919Sscottl u_int32_t addr; 293152919Sscottl u_int32_t len; 294152919Sscottl} ips_sg_element_t; 295152919Sscottl 296152919Sscottltypedef struct{ 297152919Sscottl u_int8_t drivenum; 298152919Sscottl u_int8_t merge_id; 299152919Sscottl u_int8_t raid_lvl; 300152919Sscottl u_int8_t state; 301152919Sscottl u_int32_t sector_count; 302152919Sscottl} __attribute__((packed)) ips_drive_t; 303152919Sscottl 304152919Sscottltypedef struct{ 305152919Sscottl u_int8_t drivecount; 306152919Sscottl u_int8_t reserve1; 307152919Sscottl u_int16_t reserve2; 308152919Sscottl ips_drive_t drives[IPS_MAX_NUM_DRIVES]; 309152919Sscottl}__attribute__((packed)) ips_drive_info_t; 310152919Sscottl 311152919Sscottltypedef struct{ 312152919Sscottl u_int8_t drivecount; 313152919Sscottl u_int8_t miscflags; 314152919Sscottl u_int8_t SLTflags; 315152919Sscottl u_int8_t BSTflags; 316152919Sscottl u_int8_t pwr_chg_count; 317152919Sscottl u_int8_t wrong_addr_count; 318152919Sscottl u_int8_t unident_count; 319152919Sscottl u_int8_t nvram_dev_chg_count; 320152919Sscottl u_int8_t codeblock_version[8]; 321152919Sscottl u_int8_t bootblock_version[8]; 322152919Sscottl u_int32_t drive_sector_count[IPS_MAX_NUM_DRIVES]; 323152919Sscottl u_int8_t max_concurrent_cmds; 324152919Sscottl u_int8_t max_phys_devices; 325152919Sscottl u_int16_t flash_prog_count; 326152919Sscottl u_int8_t defunct_disks; 327152919Sscottl u_int8_t rebuildflags; 328152919Sscottl u_int8_t offline_drivecount; 329152919Sscottl u_int8_t critical_drivecount; 330152919Sscottl u_int16_t config_update_count; 331152919Sscottl u_int8_t blockedflags; 332152919Sscottl u_int8_t psdn_error; 333154005Sscottl u_int16_t addr_dead_disk[IPS_MAX_CHANNELS][IPS_MAX_TARGETS]; 334152919Sscottl}__attribute__((packed)) ips_adapter_info_t; 335152919Sscottl 336154005Sscottltypedef struct { 337154005Sscottl u_int8_t initiator; 338154005Sscottl u_int8_t parameters; 339154005Sscottl u_int8_t miscflag; 340154005Sscottl u_int8_t state; 341154005Sscottl u_int32_t blkcount; 342154005Sscottl u_int8_t deviceid[28]; 343154005Sscottl} __attribute__((packed)) ips_devstate_t; 344154005Sscottl 345154005Sscottl/* 346154005Sscottl * The states that a physical drive can be in. The 'present' value can be 347154005Sscottl * OR'd with the other values. 348154005Sscottl */ 349154005Sscottl#define IPS_DEVSTATE_PRESENT 0x81 350154005Sscottl#define IPS_DEVSTATE_REBUILD 0x02 351154005Sscottl#define IPS_DEVSTATE_SPARE 0x04 352154005Sscottl#define IPS_DEVSTATE_MEMBER 0x08 353154005Sscottl 354154005Sscottltypedef struct { 355154005Sscottl u_int8_t channel; 356154005Sscottl u_int8_t target; 357154005Sscottl u_int16_t reserved; 358154005Sscottl u_int32_t startsectors; 359154005Sscottl u_int32_t numsectors; 360154005Sscottl} __attribute__((packed)) ips_chunk_t; 361154005Sscottl 362154005Sscottltypedef struct { 363154005Sscottl u_int16_t userfield; 364154005Sscottl u_int8_t state; 365154005Sscottl u_int8_t raidcacheparam; 366154005Sscottl u_int8_t numchunkunits; 367154005Sscottl u_int8_t stripesize; 368154005Sscottl u_int8_t params; 369154005Sscottl u_int8_t reserved; 370154005Sscottl u_int32_t ldsize; 371154005Sscottl ips_chunk_t chunk[IPS_MAX_CHUNKS]; 372154005Sscottl} __attribute__((packed)) ips_ld_t; 373154005Sscottl 374154005Sscottltypedef struct { 375154005Sscottl u_int8_t boarddisc[8]; 376154005Sscottl u_int8_t processor[8]; 377154005Sscottl u_int8_t numchantype; 378154005Sscottl u_int8_t numhostinttype; 379154005Sscottl u_int8_t compression; 380154005Sscottl u_int8_t nvramtype; 381154005Sscottl u_int32_t nvramsize; 382154005Sscottl} __attribute__((packed)) ips_hardware_t; 383154005Sscottl 384154005Sscottltypedef struct { 385154005Sscottl u_int8_t ldcount; 386154005Sscottl u_int8_t day; 387154005Sscottl u_int8_t month; 388154005Sscottl u_int8_t year; 389154005Sscottl u_int8_t initiatorid[4]; 390154005Sscottl u_int8_t hostid[12]; 391154005Sscottl u_int8_t timesign[8]; 392154005Sscottl u_int32_t useropt; 393154005Sscottl u_int16_t userfield; 394154005Sscottl u_int8_t rebuildrate; 395154005Sscottl u_int8_t reserve; 396154005Sscottl ips_hardware_t hardwaredisc; 397154005Sscottl ips_ld_t ld[IPS_MAX_LD]; 398154005Sscottl ips_devstate_t dev[IPS_MAX_CHANNELS][IPS_MAX_TARGETS+1]; 399154005Sscottl u_int8_t reserved[512]; 400154005Sscottl} __attribute__((packed)) ips_conf_t; 401154005Sscottl 402152919Sscottltypedef union { 403152919Sscottl struct { 404152919Sscottl u_int8_t reserved; 405152919Sscottl u_int8_t command_id; 406152919Sscottl u_int8_t basic_status; 407152919Sscottl u_int8_t extended_status; 408152919Sscottl } fields; 409152919Sscottl volatile u_int32_t value; 410152919Sscottl} ips_cmd_status_t; 411152919Sscottl 412