ips.h revision 116852
1237434Skib/*- 2237434Skib * Copyright (c) 2002 Adaptec Inc. 3237434Skib * All rights reserved. 4237434Skib * 5237434Skib * Written by: David Jeffery 6237434Skib * 7237434Skib * Redistribution and use in source and binary forms, with or without 8237434Skib * modification, are permitted provided that the following conditions 9237434Skib * are met: 10237434Skib * 1. Redistributions of source code must retain the above copyright 11237434Skib * notice, this list of conditions and the following disclaimer. 12237434Skib * 2. Redistributions in binary form must reproduce the above copyright 13237434Skib * notice, this list of conditions and the following disclaimer in the 14237434Skib * documentation and/or other materials provided with the distribution. 15237434Skib * 16237434Skib * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17237434Skib * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18237434Skib * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19237434Skib * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20237434Skib * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21237434Skib * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22237434Skib * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23237434Skib * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24237434Skib * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25237434Skib * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26237434Skib * SUCH DAMAGE. 27237434Skib * 28237434Skib * $FreeBSD: head/sys/dev/ips/ips.h 116852 2003-06-26 00:03:59Z scottl $ 29237434Skib */ 30237434Skib 31237434Skib 32237434Skib#include <sys/param.h> 33237434Skib#include <sys/systm.h> 34237434Skib#include <sys/kernel.h> 35237434Skib#include <sys/bus.h> 36237434Skib#include <sys/conf.h> 37237434Skib#include <sys/types.h> 38237434Skib#include <sys/queue.h> 39237434Skib#include <sys/bio.h> 40237434Skib#include <sys/malloc.h> 41237434Skib#include <sys/mutex.h> 42237434Skib 43237434Skib#include <machine/bus_memio.h> 44246117Skib#include <machine/bus.h> 45237434Skib#include <sys/rman.h> 46237434Skib#include <machine/resource.h> 47237434Skib 48237434Skib#include <pci/pcireg.h> 49#include <pci/pcivar.h> 50 51/* 52 * IPS CONSTANTS 53 */ 54#define IPS_VENDOR_ID 0x1014 55#define IPS_MORPHEUS_DEVICE_ID 0x01BD 56#define IPS_COPPERHEAD_DEVICE_ID 0x002E 57#define IPS_CSL 0xff 58#define IPS_POCL 0x30 59 60/* amounts of memory to allocate for certain commands */ 61#define IPS_ADAPTER_INFO_LEN (sizeof(ips_adapter_info_t)) 62#define IPS_DRIVE_INFO_LEN (sizeof(ips_drive_info_t)) 63#define IPS_COMMAND_LEN 24 64#define IPS_MAX_SG_LEN (sizeof(ips_sg_element_t) * IPS_MAX_SG_ELEMENTS) 65#define IPS_NVRAM_PAGE_SIZE 128 66/* various flags */ 67#define IPS_NOWAIT_FLAG 1 68 69/* states for the card to be in */ 70#define IPS_DEV_OPEN 0x01 71#define IPS_TIMEOUT 0x02 /* command time out, need reset */ 72#define IPS_OFFLINE 0x04 /* can't reset card/card failure */ 73 74/* max number of commands set to something low for now */ 75#define IPS_MAX_CMD_NUM 128 76#define IPS_MAX_NUM_DRIVES 8 77#define IPS_MAX_SG_ELEMENTS 32 78#define IPS_MAX_IOBUF_SIZE (64 * 1024) 79#define IPS_BLKSIZE 512 80 81/* logical drive states */ 82 83#define IPS_LD_OFFLINE 0x02 84#define IPS_LD_OKAY 0x03 85#define IPS_LD_FREE 0x00 86#define IPS_LD_SYS 0x06 87#define IPS_LD_CRS 0x24 88 89/* register offsets */ 90#define MORPHEUS_REG_OMR0 0x0018 /* Outbound Msg. Reg. 0 */ 91#define MORPHEUS_REG_OMR1 0x001C /* Outbound Msg. Reg. 1 */ 92#define MORPHEUS_REG_IDR 0x0020 /* Inbound Doorbell Reg. */ 93#define MORPHEUS_REG_IISR 0x0024 /* Inbound IRQ Status Reg. */ 94#define MORPHEUS_REG_IIMR 0x0028 /* Inbound IRQ Mask Reg. */ 95#define MORPHEUS_REG_OISR 0x0030 /* Outbound IRQ Status Reg. */ 96#define MORPHEUS_REG_OIMR 0x0034 /* Outbound IRQ Status Reg. */ 97#define MORPHEUS_REG_IQPR 0x0040 /* Inbound Queue Port Reg. */ 98#define MORPHEUS_REG_OQPR 0x0044 /* Outbound Queue Port Reg. */ 99 100#define COPPER_REG_SCPR 0x05 /* Subsystem Ctrl. Port Reg. */ 101#define COPPER_REG_ISPR 0x06 /* IRQ Status Port Reg. */ 102#define COPPER_REG_CBSP 0x07 /* ? Reg. */ 103#define COPPER_REG_HISR 0x08 /* Host IRQ Status Reg. */ 104#define COPPER_REG_CCSAR 0x10 /* Cmd. Channel Sys Addr Reg.*/ 105#define COPPER_REG_CCCR 0x14 /* Cmd. Channel Ctrl. Reg. */ 106#define COPPER_REG_SQHR 0x20 /* Status Queue Head Reg. */ 107#define COPPER_REG_SQTR 0x24 /* Status Queue Tail Reg. */ 108#define COPPER_REG_SQER 0x28 /* Status Queue End Reg. */ 109#define COPPER_REG_SQSR 0x2C /* Status Queue Start Reg. */ 110 111/* bit definitions */ 112#define MORPHEUS_BIT_POST1 0x01 113#define MORPHEUS_BIT_POST2 0x02 114#define MORPHEUS_BIT_CMD_IRQ 0x08 115 116#define COPPER_CMD_START 0x101A 117#define COPPER_SEM_BIT 0x08 118#define COPPER_EI_BIT 0x80 119#define COPPER_EBM_BIT 0x02 120#define COPPER_RESET_BIT 0x80 121#define COPPER_GHI_BIT 0x04 122#define COPPER_SCE_BIT 0x01 123#define COPPER_OP_BIT 0x01 124#define COPPER_ILE_BIT 0x10 125 126/* status defines */ 127#define IPS_POST1_OK 0x8000 128#define IPS_POST2_OK 0x000f 129 130/* command op codes */ 131#define IPS_READ_CMD 0x02 132#define IPS_WRITE_CMD 0x03 133#define IPS_ADAPTER_INFO_CMD 0x05 134#define IPS_CACHE_FLUSH_CMD 0x0A 135#define IPS_REBUILD_STATUS_CMD 0x0C 136#define IPS_ERROR_TABLE_CMD 0x17 137#define IPS_DRIVE_INFO_CMD 0x19 138#define IPS_SUBSYS_PARAM_CMD 0x40 139#define IPS_CONFIG_SYNC_CMD 0x58 140#define IPS_SG_READ_CMD 0x82 141#define IPS_SG_WRITE_CMD 0x83 142#define IPS_RW_NVRAM_CMD 0xBC 143 144/* error information returned by the adapter */ 145#define IPS_MIN_ERROR 0x02 146#define IPS_ERROR_STATUS 0x13000200 /* ahh, magic numbers */ 147 148#define IPS_OS_FREEBSD 10 149#define IPS_VERSION_MAJOR "0.90" 150#define IPS_VERSION_MINOR ".00" 151 152/* 153 * IPS MACROS 154 */ 155 156#define ips_read_1(sc,offset) bus_space_read_1(sc->bustag, sc->bushandle, offset) 157#define ips_read_2(sc,offset) bus_space_read_2(sc->bustag, sc->bushandle, offset) 158#define ips_read_4(sc,offset) bus_space_read_4(sc->bustag, sc->bushandle, offset) 159 160#define ips_write_1(sc,offset,value) bus_space_write_1(sc->bustag, sc->bushandle, offset, value) 161#define ips_write_2(sc,offset,value) bus_space_write_2(sc->bustag, sc->bushandle, offset, value) 162#define ips_write_4(sc,offset,value) bus_space_write_4(sc->bustag, sc->bushandle, offset, value) 163 164/* this is ugly. It zeros the end elements in an ips_command_t struct starting with the status element */ 165#define clear_ips_command(command) bzero(&((command)->status), (unsigned long)(&(command)[1])-(unsigned long)&((command)->status)) 166 167#define ips_read_request(iobuf) ((iobuf)->bio_cmd == BIO_READ) 168 169#define COMMAND_ERROR(status) (((status)->fields.basic_status & 0x0f) >= IPS_MIN_ERROR) 170 171#ifndef IPS_DEBUG 172#define DEVICE_PRINTF(x...) 173#define PRINTF(x...) 174#else 175#define DEVICE_PRINTF(level,x...) if(IPS_DEBUG >= level)device_printf(x) 176#define PRINTF(level,x...) if(IPS_DEBUG >= level)printf(x) 177#endif 178/* 179 * IPS STRUCTS 180 */ 181 182struct ips_softc; 183 184typedef struct{ 185 u_int8_t command; 186 u_int8_t id; 187 u_int8_t drivenum; 188 u_int8_t reserve2; 189 u_int32_t lba; 190 u_int32_t buffaddr; 191 u_int32_t reserve3; 192} __attribute__ ((packed)) ips_generic_cmd; 193 194typedef struct{ 195 u_int8_t command; 196 u_int8_t id; 197 u_int8_t drivenum; 198 u_int8_t segnum; 199 u_int32_t lba; 200 u_int32_t buffaddr; 201 u_int16_t length; 202 u_int16_t reserve1; 203} __attribute__ ((packed)) ips_io_cmd; 204 205typedef struct{ 206 u_int8_t command; 207 u_int8_t id; 208 u_int8_t pagenum; 209 u_int8_t rw; 210 u_int32_t reserve1; 211 u_int32_t buffaddr; 212 u_int32_t reserve3; 213} __attribute__ ((packed)) ips_rw_nvram_cmd; 214 215typedef struct{ 216 u_int8_t command; 217 u_int8_t id; 218 u_int8_t drivenum; 219 u_int8_t reserve1; 220 u_int32_t reserve2; 221 u_int32_t buffaddr; 222 u_int32_t reserve3; 223} __attribute__ ((packed)) ips_drive_cmd; 224 225typedef struct{ 226 u_int8_t command; 227 u_int8_t id; 228 u_int8_t reserve1; 229 u_int8_t commandtype; 230 u_int32_t reserve2; 231 u_int32_t buffaddr; 232 u_int32_t reserve3; 233} __attribute__((packed)) ips_adapter_info_cmd; 234 235typedef union{ 236 ips_generic_cmd generic_cmd; 237 ips_drive_cmd drive_cmd; 238 ips_adapter_info_cmd adapter_info_cmd; 239} ips_cmd_buff_t; 240 241typedef struct { 242 u_int32_t signature; 243 u_int8_t reserved; 244 u_int8_t adapter_slot; 245 u_int16_t adapter_type; 246 u_int8_t bios_high[4]; 247 u_int8_t bios_low[4]; 248 u_int16_t reserve2; 249 u_int8_t reserve3; 250 u_int8_t operating_system; 251 u_int8_t driver_high[4]; 252 u_int8_t driver_low[4]; 253 u_int8_t reserve4[100]; 254}__attribute__((packed)) ips_nvram_page5; 255 256typedef struct{ 257 u_int32_t addr; 258 u_int32_t len; 259} ips_sg_element_t; 260 261typedef struct{ 262 u_int8_t drivenum; 263 u_int8_t merge_id; 264 u_int8_t raid_lvl; 265 u_int8_t state; 266 u_int32_t sector_count; 267} __attribute__((packed)) ips_drive_t; 268 269typedef struct{ 270 u_int8_t drivecount; 271 u_int8_t reserve1; 272 u_int16_t reserve2; 273 ips_drive_t drives[IPS_MAX_NUM_DRIVES]; 274}__attribute__((packed)) ips_drive_info_t; 275 276typedef struct{ 277 u_int8_t drivecount; 278 u_int8_t miscflags; 279 u_int8_t SLTflags; 280 u_int8_t BSTflags; 281 u_int8_t pwr_chg_count; 282 u_int8_t wrong_addr_count; 283 u_int8_t unident_count; 284 u_int8_t nvram_dev_chg_count; 285 u_int8_t codeblock_version[8]; 286 u_int8_t bootblock_version[8]; 287 u_int32_t drive_sector_count[IPS_MAX_NUM_DRIVES]; 288 u_int8_t max_concurrent_cmds; 289 u_int8_t max_phys_devices; 290 u_int16_t flash_prog_count; 291 u_int8_t defunct_disks; 292 u_int8_t rebuildflags; 293 u_int8_t offline_drivecount; 294 u_int8_t critical_drivecount; 295 u_int16_t config_update_count; 296 u_int8_t blockedflags; 297 u_int8_t psdn_error; 298 u_int16_t addr_dead_disk[4*16];/* ugly, max # channels * max # scsi devices per channel */ 299}__attribute__((packed)) ips_adapter_info_t; 300 301typedef struct { 302 u_int32_t status[IPS_MAX_CMD_NUM]; 303 u_int32_t base_phys_addr; 304 int nextstatus; 305 bus_dma_tag_t dmatag; 306 bus_dmamap_t dmamap; 307} ips_copper_queue_t; 308 309typedef union { 310 struct { 311 u_int8_t reserved; 312 u_int8_t command_id; 313 u_int8_t basic_status; 314 u_int8_t extended_status; 315 } fields; 316 volatile u_int32_t value; 317} ips_cmd_status_t; 318 319/* used to keep track of current commands to the card */ 320typedef struct ips_command{ 321 u_int8_t command_number; 322 u_int8_t id; 323 u_int8_t timeout; 324 struct ips_softc * sc; 325 bus_dmamap_t command_dmamap; 326 void * command_buffer; 327 u_int32_t command_phys_addr;/*WARNING! must be changed if 64bit addressing ever used*/ 328 ips_cmd_status_t status; 329 SLIST_ENTRY(ips_command) next; 330 bus_dma_tag_t data_dmatag; 331 bus_dmamap_t data_dmamap; 332 void * data_buffer; 333 void * arg; 334 void (* callback)(struct ips_command *command); 335}ips_command_t; 336 337typedef struct ips_wait_list{ 338 STAILQ_ENTRY(ips_wait_list) next; 339 void *data; 340 int (* callback)(ips_command_t *command); 341}ips_wait_list_t; 342 343typedef struct ips_softc{ 344 struct resource * iores; 345 struct resource * irqres; 346 int configured; 347 int state; 348 int iotype; 349 int rid; 350 int irqrid; 351 void * irqcookie; 352 bus_space_tag_t bustag; 353 bus_space_handle_t bushandle; 354 bus_dma_tag_t adapter_dmatag; 355 bus_dma_tag_t command_dmatag; 356 bus_dma_tag_t sg_dmatag; 357 device_t dev; 358 dev_t device_file; 359 struct callout_handle timer; 360 ips_adapter_info_t adapter_info; 361 device_t diskdev[IPS_MAX_NUM_DRIVES]; 362 ips_drive_t drives[IPS_MAX_NUM_DRIVES]; 363 u_int8_t drivecount; 364 u_int8_t next_drive; 365 u_int8_t max_cmds; 366 volatile u_int8_t used_commands; 367 ips_command_t commandarray[IPS_MAX_CMD_NUM]; 368 SLIST_HEAD(command_list, ips_command) free_cmd_list; 369 STAILQ_HEAD(command_wait_list,ips_wait_list) cmd_wait_list; 370 int (* ips_adapter_reinit)(struct ips_softc *sc, 371 int force); 372 void (* ips_adapter_intr)(void *sc); 373 void (* ips_issue_cmd)(ips_command_t *command); 374 ips_copper_queue_t * copper_queue; 375 struct mtx cmd_mtx; 376}ips_softc_t; 377 378/* function defines from ips_ioctl.c */ 379extern int ips_ioctl_request(ips_softc_t *sc, u_long ioctl_cmd, caddr_t addr, 380 int32_t flags); 381/* function defines from ips_disk.c */ 382extern void ipsd_finish(struct bio *iobuf); 383 384/* function defines from ips_commands.c */ 385extern int ips_flush_cache(ips_softc_t *sc); 386extern void ips_start_io_request(ips_softc_t *sc, struct bio *iobuf); 387extern int ips_get_drive_info(ips_softc_t *sc); 388extern int ips_get_adapter_info(ips_softc_t *sc); 389extern int ips_update_nvram(ips_softc_t *sc); 390extern int ips_clear_adapter(ips_softc_t *sc); 391 392/* function defines from ips.c */ 393extern int ips_get_free_cmd(ips_softc_t *sc, int (*callback)(ips_command_t *), 394 void *data, unsigned long flags); 395extern void ips_insert_free_cmd(ips_softc_t *sc, ips_command_t *command); 396extern int ips_adapter_init(ips_softc_t *sc); 397extern int ips_morpheus_reinit(ips_softc_t *sc, int force); 398extern int ips_adapter_free(ips_softc_t *sc); 399extern void ips_morpheus_intr(void *sc); 400extern void ips_issue_morpheus_cmd(ips_command_t *command); 401extern int ips_copperhead_reinit(ips_softc_t *sc, int force); 402extern void ips_copperhead_intr(void *sc); 403extern void ips_issue_copperhead_cmd(ips_command_t *command); 404 405