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