1/* $NetBSD: icpvar.h,v 1.11 2009/01/29 12:13:30 bouyer Exp $ */ 2 3/*- 4 * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran, and by Jason R. Thorpe of Wasabi Systems, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#ifndef _IC_ICPVAR_H_ 33#define _IC_ICPVAR_H_ 34 35#include <sys/mutex.h> 36 37#include <dev/ic/icp_ioctl.h> 38 39/* 40 * Miscellaneous constants. 41 */ 42#define ICP_RETRIES 6 43#define ICP_WATCHDOG_FREQ 5 44#define ICP_BUSY_WAIT_MS 2500 45#define ICP_MAX_XFER 65536 46#define ICP_UCMD_SCRATCH_SIZE 4096 47#define ICP_SCRATCH_SIZE (8192 + ICP_UCMD_SCRATCH_SIZE) 48#define ICP_SCRATCH_SENSE \ 49 (ICP_SCRATCH_SIZE - sizeof(struct scsi_sense_data) * (ICP_NCCBS + ICP_NCCB_RESERVE)) 50#define ICP_SCRATCH_UCMD (ICP_SCRATCH_SENSE - ICP_UCMD_SCRATCH_SIZE) 51 52#define ICP_NCCBS ICP_MAX_CMDS 53#define ICP_NCCB_RESERVE 4 54 55/* 56 * Context structure for interrupt service. 57 */ 58struct icp_intr_ctx { 59 u_int32_t info; 60 u_int32_t info2; 61 u_int16_t cmd_status; 62 u_int16_t service; 63 u_int8_t istatus; 64}; 65 66/* 67 * Command control block. 68 */ 69struct icp_ccb { 70 SIMPLEQ_ENTRY(icp_ccb) ic_chain; 71 u_int ic_service; 72 u_int ic_flags; 73 u_int ic_status; 74 u_int ic_ident; 75 u_int ic_nsgent; 76 u_int ic_cmdlen; 77 u_int ic_xfer_size; 78 bus_dmamap_t ic_xfer_map; 79 struct icp_sg *ic_sg; 80 struct device *ic_dv; 81 void *ic_context; 82 void (*ic_intr)(struct icp_ccb *); 83 struct icp_cmd ic_cmd; 84}; 85#define IC_XFER_IN 0x01 /* Map describes inbound xfer */ 86#define IC_XFER_OUT 0x02 /* Map describes outbound xfer */ 87#define IC_WAITING 0x04 /* We have waiters */ 88#define IC_COMPLETE 0x08 /* Command completed */ 89#define IC_ALLOCED 0x10 /* CCB allocated */ 90#define IC_UCMD 0x20 /* user ioctl */ 91 92/* 93 * Logical drive information. 94 */ 95struct icp_cachedrv { 96 u_int cd_size; 97 u_int cd_type; 98}; 99 100/* 101 * Call-backs into the service back-ends (ld for cache service, 102 * icpsp for raw service). 103 */ 104struct icp_servicecb { 105 void (*iscb_openings)(device_t, int); 106}; 107 108/* 109 * Per-controller context. 110 */ 111struct icp_softc { 112 struct device icp_dv; 113 void *icp_ih; 114 bus_dma_tag_t icp_dmat; 115 bus_space_tag_t icp_dpmemt; 116 bus_space_handle_t icp_dpmemh; 117 bus_addr_t icp_dpmembase; 118 bus_space_tag_t icp_iot; 119 bus_space_handle_t icp_ioh; 120 bus_addr_t icp_iobase; 121 122 int icp_class; 123 u_int16_t icp_fw_vers; 124 u_int16_t icp_ic_all_size; 125 u_int8_t icp_bus_cnt; 126 u_int8_t icp_bus_id[ICP_MAXBUS]; 127 struct icp_cachedrv icp_cdr[ICP_MAX_HDRIVES]; 128 const struct icp_servicecb *icp_servicecb[ICP_MAX_HDRIVES + ICP_MAXBUS]; 129 struct device *icp_children[ICP_MAX_HDRIVES + ICP_MAXBUS]; 130 int icp_ndevs; 131 int icp_openings; 132 int icp_features; 133 int icp_nchan; 134 135 u_int32_t icp_info; 136 u_int32_t icp_info2; 137 u_int16_t icp_status; 138 u_int16_t icp_service; 139 140 bus_dmamap_t icp_scr_dmamap; 141 bus_dma_segment_t icp_scr_seg[1]; 142 void * icp_scr; 143 144 struct icp_ccb *icp_ccbs; 145 u_int icp_nccbs; 146 u_int icp_flags; 147 u_int icp_qfreeze; 148 u_int icp_running; 149 SIMPLEQ_HEAD(,icp_ccb) icp_ccb_freelist; 150 SIMPLEQ_HEAD(,icp_ccb) icp_ccb_queue; 151 SIMPLEQ_HEAD(,icp_ccb) icp_ucmd_queue; 152 struct callout icp_wdog_callout; 153 154 struct icp_ccb *icp_ucmd_ccb; 155 156 /* Temporary buffer for event data. */ 157 gdt_evt_data icp_evt; 158 159 void (*icp_copy_cmd)(struct icp_softc *, struct icp_ccb *); 160 u_int8_t (*icp_get_status)(struct icp_softc *); 161 void (*icp_intr)(struct icp_softc *, struct icp_intr_ctx *); 162 void (*icp_release_event)(struct icp_softc *, 163 struct icp_ccb *); 164 void (*icp_set_sema0)(struct icp_softc *); 165 int (*icp_test_busy)(struct icp_softc *); 166 167 /* 168 * This info is needed by the user ioctl interface needed to 169 * support the ICP configuration tools. 170 */ 171 int icp_pci_bus; 172 int icp_pci_device; 173 int icp_pci_device_id; 174 int icp_pci_subdevice_id; 175}; 176 177/* icp_features */ 178#define ICP_FEAT_CACHESERVICE 0x01 /* cache service usable */ 179#define ICP_FEAT_RAWSERVICE 0x02 /* raw service usable */ 180 181/* icp_flags */ 182#define ICP_F_WAIT_CCB 0x01 /* someone waiting for CCBs */ 183#define ICP_F_WAIT_FREEZE 0x02 /* someone waiting for qfreeze */ 184 185#define ICP_HAS_WORK(icp) \ 186 (! SIMPLEQ_EMPTY(&(icp)->icp_ccb_queue) || \ 187 ! SIMPLEQ_EMPTY(&(icp)->icp_ucmd_queue)) 188 189#define ICP_STAT_INCR(icp, x) \ 190do { \ 191 /* XXX Globals, for now. XXX */ \ 192 icp_stats. ## x ## _act++; \ 193 if (icp_stats. ## x ## _act > icp_stats. ## x ## _max) \ 194 icp_stats. ## x ## _max = icp_stats. ## x ## _act; \ 195} while (/*CONSTCOND*/0) 196 197#define ICP_STAT_SET(icp, x, v) \ 198do { \ 199 /* XXX Globals, for now. XXX */ \ 200 icp_stats. ## x ## _act = (v); \ 201 if (icp_stats. ## x ## _act > icp_stats. ## x ## _max) \ 202 icp_stats. ## x ## _max = icp_stats. ## x ## _act; \ 203} while (/*CONSTCOND*/0) 204 205#define ICP_STAT_DECR(icp, x) \ 206do { \ 207 /* XXX Globals, for now. XXX */ \ 208 icp_stats. ## x ## _act--; \ 209} while (/*CONSTCOND*/0) 210 211#define ICP_ISA 0x01 212#define ICP_EISA 0x02 213#define ICP_PCI 0x03 214#define ICP_PCINEW 0x04 215#define ICP_MPR 0x05 216#define ICP_CLASS_MASK 0x07 217#define ICP_FC 0x10 218#define ICP_CLASS(icp) ((icp)->icp_class & ICP_CLASS_MASK) 219 220int icp_init(struct icp_softc *, const char *); 221int icp_intr(void *); 222 223extern int icp_count; 224extern gdt_statist_t icp_stats; 225 226/* 227 * Consumer interface. 228 */ 229struct icp_attach_args { 230 int icpa_unit; 231}; 232 233#define ICPA_UNIT_SCSI 100 234 235struct icp_ccb *icp_ccb_alloc(struct icp_softc *); 236struct icp_ccb *icp_ccb_alloc_wait(struct icp_softc *); 237void icp_ccb_enqueue(struct icp_softc *, struct icp_ccb *); 238void icp_ccb_free(struct icp_softc *, struct icp_ccb *); 239int icp_ccb_map(struct icp_softc *, struct icp_ccb *, void *, int, int); 240int icp_ccb_poll(struct icp_softc *, struct icp_ccb *, int); 241void icp_ccb_unmap(struct icp_softc *, struct icp_ccb *); 242int icp_ccb_wait(struct icp_softc *, struct icp_ccb *, int); 243int icp_ccb_wait_user(struct icp_softc *, struct icp_ccb *, int); 244int icp_cmd(struct icp_softc *, u_int8_t, u_int16_t, u_int32_t, u_int32_t, 245 u_int32_t); 246int icp_ucmd(struct icp_softc *, gdt_ucmd_t *); 247int icp_freeze(struct icp_softc *); 248void icp_unfreeze(struct icp_softc *); 249 250void icp_rescan(struct icp_softc *, int); 251void icp_rescan_all(struct icp_softc *); 252 253void icp_register_servicecb(struct icp_softc *, int, 254 const struct icp_servicecb *); 255 256gdt_evt_str *icp_store_event(struct icp_softc *, u_int16_t, u_int16_t, 257 gdt_evt_data *); 258int icp_read_event(struct icp_softc *, int, gdt_evt_str *); 259void icp_readapp_event(struct icp_softc *, u_int8_t, gdt_evt_str *); 260void icp_clear_events(struct icp_softc *); 261 262extern kmutex_t icp_ioctl_mutex; 263 264#endif /* !_IC_ICPVAR_H_ */ 265