1 /* $NetBSD: icpvar.h,v 1.9 2007/03/11 22:16:32 ad 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 <sys/mutex.h> 43 44 #include <dev/ic/icp_ioctl.h> 45 46 /* 47 * Miscellaneous constants. 48 */ 49 #define ICP_RETRIES 6 50 #define ICP_WATCHDOG_FREQ 5 51 #define ICP_BUSY_WAIT_MS 2500 52 #define ICP_MAX_XFER 65536 53 #define ICP_UCMD_SCRATCH_SIZE 4096 54 #define ICP_SCRATCH_SIZE (8192 + ICP_UCMD_SCRATCH_SIZE) 55 #define ICP_SCRATCH_SENSE \ 56 (ICP_SCRATCH_SIZE - sizeof(struct scsi_sense_data) * ICP_NCCBS) 57 #define ICP_SCRATCH_UCMD (ICP_SCRATCH_SENSE - ICP_UCMD_SCRATCH_SIZE) 58 59 #define ICP_NCCBS ICP_MAX_CMDS 60 #define ICP_NCCB_RESERVE 4 61 62 /* 63 * Context structure for interrupt service. 64 */ 65 struct icp_intr_ctx { 66 u_int32_t info; 67 u_int32_t info2; 68 u_int16_t cmd_status; 69 u_int16_t service; 70 u_int8_t istatus; 71 }; 72 73 /* 74 * Command control block. 75 */ 76 struct icp_ccb { 77 SIMPLEQ_ENTRY(icp_ccb) ic_chain; 78 u_int ic_service; 79 u_int ic_flags; 80 u_int ic_status; 81 u_int ic_ident; 82 u_int ic_nsgent; 83 u_int ic_cmdlen; 84 u_int ic_xfer_size; 85 bus_dmamap_t ic_xfer_map; 86 struct icp_sg *ic_sg; 87 struct device *ic_dv; 88 void *ic_context; 89 void (*ic_intr)(struct icp_ccb *); 90 struct icp_cmd ic_cmd; 91 }; 92 #define IC_XFER_IN 0x01 /* Map describes inbound xfer */ 93 #define IC_XFER_OUT 0x02 /* Map describes outbound xfer */ 94 #define IC_WAITING 0x04 /* We have waiters */ 95 #define IC_COMPLETE 0x08 /* Command completed */ 96 #define IC_ALLOCED 0x10 /* CCB allocated */ 97 #define IC_UCMD 0x20 /* user ioctl */ 98 99 /* 100 * Logical drive information. 101 */ 102 struct icp_cachedrv { 103 u_int cd_size; 104 u_int cd_type; 105 }; 106 107 /* 108 * Call-backs into the service back-ends (ld for cache service, 109 * icpsp for raw service). 110 */ 111 struct icp_servicecb { 112 void (*iscb_openings)(struct device *, int); 113 }; 114 115 /* 116 * Per-controller context. 117 */ 118 struct icp_softc { 119 struct device icp_dv; 120 void *icp_ih; 121 bus_dma_tag_t icp_dmat; 122 bus_space_tag_t icp_dpmemt; 123 bus_space_handle_t icp_dpmemh; 124 bus_addr_t icp_dpmembase; 125 bus_space_tag_t icp_iot; 126 bus_space_handle_t icp_ioh; 127 bus_addr_t icp_iobase; 128 129 int icp_class; 130 u_int16_t icp_fw_vers; 131 u_int16_t icp_ic_all_size; 132 u_int8_t icp_bus_cnt; 133 u_int8_t icp_bus_id[ICP_MAXBUS]; 134 struct icp_cachedrv icp_cdr[ICP_MAX_HDRIVES]; 135 const struct icp_servicecb *icp_servicecb[ICP_MAX_HDRIVES + ICP_MAXBUS]; 136 struct device *icp_children[ICP_MAX_HDRIVES + ICP_MAXBUS]; 137 int icp_ndevs; 138 int icp_openings; 139 int icp_features; 140 int icp_nchan; 141 142 u_int32_t icp_info; 143 u_int32_t icp_info2; 144 u_int16_t icp_status; 145 u_int16_t icp_service; 146 147 bus_dmamap_t icp_scr_dmamap; 148 bus_dma_segment_t icp_scr_seg[1]; 149 void * icp_scr; 150 151 struct icp_ccb *icp_ccbs; 152 u_int icp_nccbs; 153 u_int icp_flags; 154 u_int icp_qfreeze; 155 u_int icp_running; 156 SIMPLEQ_HEAD(,icp_ccb) icp_ccb_freelist; 157 SIMPLEQ_HEAD(,icp_ccb) icp_ccb_queue; 158 SIMPLEQ_HEAD(,icp_ccb) icp_ucmd_queue; 159 struct callout icp_wdog_callout; 160 161 struct icp_ccb *icp_ucmd_ccb; 162 163 /* Temporary buffer for event data. */ 164 gdt_evt_data icp_evt; 165 166 void (*icp_copy_cmd)(struct icp_softc *, struct icp_ccb *); 167 u_int8_t (*icp_get_status)(struct icp_softc *); 168 void (*icp_intr)(struct icp_softc *, struct icp_intr_ctx *); 169 void (*icp_release_event)(struct icp_softc *, 170 struct icp_ccb *); 171 void (*icp_set_sema0)(struct icp_softc *); 172 int (*icp_test_busy)(struct icp_softc *); 173 174 /* 175 * This info is needed by the user ioctl interface needed to 176 * support the ICP configuration tools. 177 */ 178 int icp_pci_bus; 179 int icp_pci_device; 180 int icp_pci_device_id; 181 int icp_pci_subdevice_id; 182 }; 183 184 /* icp_features */ 185 #define ICP_FEAT_CACHESERVICE 0x01 /* cache service usable */ 186 #define ICP_FEAT_RAWSERVICE 0x02 /* raw service usable */ 187 188 /* icp_flags */ 189 #define ICP_F_WAIT_CCB 0x01 /* someone waiting for CCBs */ 190 #define ICP_F_WAIT_FREEZE 0x02 /* someone waiting for qfreeze */ 191 192 #define ICP_HAS_WORK(icp) \ 193 (! SIMPLEQ_EMPTY(&(icp)->icp_ccb_queue) || \ 194 ! SIMPLEQ_EMPTY(&(icp)->icp_ucmd_queue)) 195 196 #define ICP_STAT_INCR(icp, x) \ 197 do { \ 198 /* XXX Globals, for now. XXX */ \ 199 icp_stats. ## x ## _act++; \ 200 if (icp_stats. ## x ## _act > icp_stats. ## x ## _max) \ 201 icp_stats. ## x ## _max = icp_stats. ## x ## _act; \ 202 } while (/*CONSTCOND*/0) 203 204 #define ICP_STAT_SET(icp, x, v) \ 205 do { \ 206 /* XXX Globals, for now. XXX */ \ 207 icp_stats. ## x ## _act = (v); \ 208 if (icp_stats. ## x ## _act > icp_stats. ## x ## _max) \ 209 icp_stats. ## x ## _max = icp_stats. ## x ## _act; \ 210 } while (/*CONSTCOND*/0) 211 212 #define ICP_STAT_DECR(icp, x) \ 213 do { \ 214 /* XXX Globals, for now. XXX */ \ 215 icp_stats. ## x ## _act--; \ 216 } while (/*CONSTCOND*/0) 217 218 #define ICP_ISA 0x01 219 #define ICP_EISA 0x02 220 #define ICP_PCI 0x03 221 #define ICP_PCINEW 0x04 222 #define ICP_MPR 0x05 223 #define ICP_CLASS_MASK 0x07 224 #define ICP_FC 0x10 225 #define ICP_CLASS(icp) ((icp)->icp_class & ICP_CLASS_MASK) 226 227 int icp_init(struct icp_softc *, const char *); 228 int icp_intr(void *); 229 230 extern int icp_count; 231 extern gdt_statist_t icp_stats; 232 233 /* 234 * Consumer interface. 235 */ 236 struct icp_attach_args { 237 int icpa_unit; 238 }; 239 240 #define ICPA_UNIT_SCSI 100 241 242 struct icp_ccb *icp_ccb_alloc(struct icp_softc *); 243 struct icp_ccb *icp_ccb_alloc_wait(struct icp_softc *); 244 void icp_ccb_enqueue(struct icp_softc *, struct icp_ccb *); 245 void icp_ccb_free(struct icp_softc *, struct icp_ccb *); 246 int icp_ccb_map(struct icp_softc *, struct icp_ccb *, void *, int, int); 247 int icp_ccb_poll(struct icp_softc *, struct icp_ccb *, int); 248 void icp_ccb_unmap(struct icp_softc *, struct icp_ccb *); 249 int icp_ccb_wait(struct icp_softc *, struct icp_ccb *, int); 250 int icp_ccb_wait_user(struct icp_softc *, struct icp_ccb *, int); 251 int icp_cmd(struct icp_softc *, u_int8_t, u_int16_t, u_int32_t, u_int32_t, 252 u_int32_t); 253 int icp_ucmd(struct icp_softc *, gdt_ucmd_t *); 254 int icp_freeze(struct icp_softc *); 255 void icp_unfreeze(struct icp_softc *); 256 257 void icp_rescan(struct icp_softc *, int); 258 void icp_rescan_all(struct icp_softc *); 259 260 void icp_register_servicecb(struct icp_softc *, int, 261 const struct icp_servicecb *); 262 263 gdt_evt_str *icp_store_event(struct icp_softc *, u_int16_t, u_int16_t, 264 gdt_evt_data *); 265 int icp_read_event(struct icp_softc *, int, gdt_evt_str *); 266 void icp_readapp_event(struct icp_softc *, u_int8_t, gdt_evt_str *); 267 void icp_clear_events(struct icp_softc *); 268 269 extern kmutex_t icp_ioctl_mutex; 270 271 #endif /* !_IC_ICPVAR_H_ */ 272