1 /* $NetBSD: icpvar.h,v 1.13 2012/10/27 17:18:20 chs 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 */ 58 struct 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 */ 69 struct 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 device_t 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 */ 95 struct 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 */ 104 struct icp_servicecb { 105 void (*iscb_openings)(device_t, int); 106 }; 107 108 /* 109 * Per-controller context. 110 */ 111 struct icp_softc { 112 device_t 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 device_t 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) \ 190 do { \ 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) \ 198 do { \ 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) \ 206 do { \ 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 220 int icp_init(struct icp_softc *, const char *); 221 int icp_intr(void *); 222 223 extern int icp_count; 224 extern gdt_statist_t icp_stats; 225 226 /* 227 * Consumer interface. 228 */ 229 struct icp_attach_args { 230 int icpa_unit; 231 }; 232 233 #define ICPA_UNIT_SCSI 100 234 235 struct icp_ccb *icp_ccb_alloc(struct icp_softc *); 236 struct icp_ccb *icp_ccb_alloc_wait(struct icp_softc *); 237 void icp_ccb_enqueue(struct icp_softc *, struct icp_ccb *); 238 void icp_ccb_free(struct icp_softc *, struct icp_ccb *); 239 int icp_ccb_map(struct icp_softc *, struct icp_ccb *, void *, int, int); 240 int icp_ccb_poll(struct icp_softc *, struct icp_ccb *, int); 241 void icp_ccb_unmap(struct icp_softc *, struct icp_ccb *); 242 int icp_ccb_wait(struct icp_softc *, struct icp_ccb *, int); 243 int icp_ccb_wait_user(struct icp_softc *, struct icp_ccb *, int); 244 int icp_cmd(struct icp_softc *, u_int8_t, u_int16_t, u_int32_t, u_int32_t, 245 u_int32_t); 246 int icp_ucmd(struct icp_softc *, gdt_ucmd_t *); 247 int icp_freeze(struct icp_softc *); 248 void icp_unfreeze(struct icp_softc *); 249 250 void icp_rescan(struct icp_softc *, int); 251 void icp_rescan_all(struct icp_softc *); 252 253 void icp_register_servicecb(struct icp_softc *, int, 254 const struct icp_servicecb *); 255 256 gdt_evt_str *icp_store_event(struct icp_softc *, u_int16_t, u_int16_t, 257 gdt_evt_data *); 258 int icp_read_event(struct icp_softc *, int, gdt_evt_str *); 259 void icp_readapp_event(struct icp_softc *, u_int8_t, gdt_evt_str *); 260 void icp_clear_events(struct icp_softc *); 261 262 extern kmutex_t icp_ioctl_mutex; 263 264 #endif /* !_IC_ICPVAR_H_ */ 265