diff options
author | Niklas Hallqvist <niklas@cvs.openbsd.org> | 2000-02-07 00:33:05 +0000 |
---|---|---|
committer | Niklas Hallqvist <niklas@cvs.openbsd.org> | 2000-02-07 00:33:05 +0000 |
commit | aa1b9218a068bee309a7955bcc937df8e1bc4103 (patch) | |
tree | 1270d378c8b925505195a34f9742075ac4f5798c /sys/dev/ic/gdtvar.h | |
parent | f8937e16f74e7d7928b897443f2f80a71d603949 (diff) |
Rough but working driver for ICP-Vortex RAID
Diffstat (limited to 'sys/dev/ic/gdtvar.h')
-rw-r--r-- | sys/dev/ic/gdtvar.h | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/sys/dev/ic/gdtvar.h b/sys/dev/ic/gdtvar.h new file mode 100644 index 00000000000..2ab04ed56d0 --- /dev/null +++ b/sys/dev/ic/gdtvar.h @@ -0,0 +1,272 @@ +/* $OpenBSD: gdtvar.h,v 1.1 2000/02/07 00:33:03 niklas Exp $ */ + +/* + * Copyright (c) 1999, 2000 Niklas Hallqvist. 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. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Niklas Hallqvist. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, 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 DAMAGE. + */ + +/* + * This driver would not have written if it was not for the hardware donations + * from both ICP-Vortex and Öko.neT. I want to thank them for their support. + */ + +/* Debugging */ +#ifdef GDT_DEBUG +#define GDT_DPRINTF(mask, args) if (gdt_debug & (mask)) printf args +#define GDT_D_INTR 0x01 +#define GDT_D_MISC 0x02 +#define GDT_D_CMD 0x04 +#define GDT_D_QUEUE 0x08 +#define GDT_D_IO 0x10 +extern int gdt_debug; +#else +#define GDT_PRINTF(args) +#endif + +/* Miscellaneous constants */ +#define GDT_RETRIES 100000000 /* 100000 * 1us = 100s */ +#define GDT_TIMEOUT 100000000 /* 100000 * 1us = 100s */ +#define GDT_POLL_TIMEOUT 10000000 /* 10000 * 1us = 10s */ +#define GDT_WATCH_TIMEOUT 10000000 /* 10000 * 1us = 10s */ +#define GDT_SCRATCH_SZ 4096 /* 4KB scratch buffer */ + +/* Context structure for interrupt services */ +struct gdt_intr_ctx { + u_int32_t info, info2; + u_int16_t cmd_status, service; + u_int8_t istatus; +}; + +/* + * A command contol block, one for each corresponding command index of the + * controller. + */ +struct gdt_ccb { + TAILQ_ENTRY(gdt_ccb) gc_chain; + struct scsi_xfer *gc_xs; + int gc_timeout; + u_int32_t gc_info; + u_int32_t gc_blockno; + u_int32_t gc_blockcnt; + u_int16_t gc_status; + u_int8_t gc_service; + u_int8_t gc_cmd_index; + u_int8_t gc_flags; +#define GDT_GCF_CMD_MASK 0x3 +#define GDT_GCF_UNUSED 0 +#define GDT_GCF_INTERNAL 1 +#define GDT_GCF_SCREEN 2 +#define GDT_GCF_SCSI 3 +#define GDT_GCF_WATCHDOG 0x4 +}; + +static __inline__ int gdt_ccb_set_cmd __P((struct gdt_ccb *, int)); +static __inline__ int +gdt_ccb_set_cmd(ccb, flag) + struct gdt_ccb *ccb; + int flag; +{ + int rv = ccb->gc_flags & GDT_GCF_CMD_MASK; + + ccb->gc_flags &= ~GDT_GCF_CMD_MASK; + ccb->gc_flags |= flag; + return (rv); +} + +struct gdt_softc { + struct device sc_dev; + void *sc_ih; + struct scsi_link sc_link; /* Virtual SCSI bus for cache devs */ + struct scsi_link *sc_raw_link; /* Raw SCSI busses */ + + int sc_class; /* Controller class */ +#define GDT_ISA 0x01 +#define GDT_EISA 0x02 +#define GDT_PCI 0x03 +#define GDT_PCINEW 0x04 +#define GDT_MPR 0x05 +#define GDT_CLASS_MASK 0x07 +#define GDT_FC 0x10 +#define GDT_CLASS(gdt) ((gdt)->sc_class & GDT_CLASS_MASK) + + bus_space_tag_t sc_dpmemt; + bus_space_handle_t sc_dpmemh; + bus_addr_t sc_dpmembase; + + /* XXX These could go into a class-dependent opaque struct instead */ + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + bus_addr_t sc_iobase; + + u_int16_t sc_ic_all_size; + + struct gdt_ccb sc_ccbs[GDT_MAXCMDS]; + TAILQ_HEAD(, gdt_ccb) sc_free_ccb, sc_ccbq; + LIST_HEAD(, scsi_xfer) sc_queue; + struct scsi_xfer *sc_queuelast; + + u_int16_t sc_cmd_len; + u_int16_t sc_cmd_off; + u_int16_t sc_cmd_cnt; + u_int8_t sc_cmd[GDT_CMD_SZ]; + + u_int32_t sc_info; + u_int32_t sc_info2; + u_int16_t sc_status; + u_int8_t sc_scratch[GDT_SCRATCH_SZ]; + + u_int8_t sc_bus_cnt; + u_int8_t sc_bus_id[GDT_MAXBUS]; + u_int8_t sc_more_proc; + + struct { + u_int8_t hd_present; + u_int8_t hd_is_logdrv; + u_int8_t hd_is_arraydrv; + u_int8_t hd_is_master; + u_int8_t hd_is_parity; + u_int8_t hd_is_hotfix; + u_int8_t hd_master_no; + u_int8_t hd_lock; + u_int8_t hd_heads; + u_int8_t hd_secs; + u_int16_t hd_devtype; + u_int32_t hd_size; + u_int8_t hd_ldr_no; + u_int8_t hd_rw_attribs; + u_int32_t hd_start_sec; + } sc_hdr[GDT_MAX_HDRIVES]; + + struct { + u_int32_t cp_version; + u_int16_t cp_state; + u_int16_t cp_strategy; + u_int16_t cp_write_back; + u_int16_t cp_block_size; + } sc_cpar; + + struct { + u_int32_t bi_ser_no; /* serial number */ + u_int8_t bi_oem_id[2]; /* u_int8_t OEM ID */ + u_int16_t bi_ep_flags; /* eprom flags */ + u_int32_t bi_proc_id; /* processor ID */ + u_int32_t bi_memsize; /* memory size (bytes) */ + u_int8_t bi_mem_banks; /* memory banks */ + u_int8_t bi_chan_type; /* channel type */ + u_int8_t bi_chan_count; /* channel count */ + u_int8_t bi_rdongle_pres; /* dongle present */ + u_int32_t bi_epr_fw_ver; /* (eprom) firmware ver */ + u_int32_t bi_upd_fw_ver; /* (update) firmware ver */ + u_int32_t bi_upd_revision; /* update revision */ + char bi_type_string[16]; /* char controller name */ + char bi_raid_string[16]; /* char RAID firmware name */ + u_int8_t bi_update_pres; /* update present? */ + u_int8_t bi_xor_pres; /* XOR engine present */ + u_int8_t bi_prom_type; /* ROM type (eprom/flash) */ + u_int8_t bi_prom_count; /* number of ROM devices */ + u_int32_t bi_dup_pres; /* duplexing module pres? */ + u_int32_t bi_chan_pres; /* # of exp. channels */ + u_int32_t bi_mem_pres; /* memory expansion inst? */ + u_int8_t bi_ft_bus_system; /* fault bus supported? */ + u_int8_t bi_subtype_valid; /* board_subtype valid */ + u_int8_t bi_board_subtype; /* subtype/hardware level */ + u_int8_t bi_rampar_pres; /* RAM parity check hw? */ + } sc_binfo; + + struct { + u_int8_t bf_chaining; /* chaining supported */ + u_int8_t bf_striping; /* striping (RAID-0) supported */ + u_int8_t bf_mirroring; /* mirroring (RAID-1) supported */ + u_int8_t bf_raid; /* RAID-4/5/10 supported */ + } sc_bfeat; + + u_int16_t sc_raw_feat; + u_int16_t sc_cache_feat; + + int sc_spl; + + void (*sc_copy_cmd) __P((struct gdt_softc *, struct gdt_ccb *)); + u_int8_t (*sc_get_status) __P((struct gdt_softc *)); + void (*sc_intr) __P((struct gdt_softc *, struct gdt_intr_ctx *)); + void (*sc_release_event) __P((struct gdt_softc *, struct gdt_ccb *)); + void (*sc_set_sema0) __P((struct gdt_softc *)); + int (*sc_test_busy) __P((struct gdt_softc *)); +}; + +/* XXX These have to become spinlocks in case of SMP */ +#define GDT_LOCK_GDT(gdt) (gdt)->sc_spl = splbio() +#define GDT_UNLOCK_GDT(gdt) splx((gdt)->sc_spl) + +void gdtminphys __P((struct buf *)); +int gdt_attach __P((struct gdt_softc *)); +int gdt_intr __P((void *)); + +#ifdef __GNUC__ +/* These all require correctly aligned buffers */ +static __inline__ void gdt_enc16 __P((u_int8_t *, u_int16_t)); +static __inline__ void gdt_enc32 __P((u_int8_t *, u_int32_t)); +static __inline__ u_int16_t gdt_dec16 __P((u_int8_t *)); +static __inline__ u_int32_t gdt_dec32 __P((u_int8_t *)); + +static __inline__ void +gdt_enc16(addr, value) + u_int8_t *addr; + u_int16_t value; +{ + *(u_int16_t *)addr = htole16(value); +} + +static __inline__ void +gdt_enc32(addr, value) + u_int8_t *addr; + u_int32_t value; +{ + *(u_int32_t *)addr = htole32(value); +} + +static __inline__ u_int16_t +gdt_dec16(addr) + u_int8_t *addr; +{ + return letoh16(*(u_int16_t *)addr); +} + +static __inline__ u_int32_t +gdt_dec32(addr) + u_int8_t *addr; +{ + return letoh32(*(u_int32_t *)addr); +} +#endif + +#if defined(__alpha__) +/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */ +#undef vtophys +#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va)) +#endif + +extern u_int8_t gdt_polling; |