1 /* 2 * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the acknowledgement as bellow: 15 * 16 * This product includes software developed by K. Kobayashi and H. Shimokawa 17 * 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 * 33 * $FreeBSD$ 34 * 35 */ 36 37 #if __FreeBSD_version >= 500000 38 typedef struct thread fw_proc; 39 #include <sys/selinfo.h> 40 #else 41 typedef struct proc fw_proc; 42 #include <sys/select.h> 43 #endif 44 45 #define splfw splimp 46 47 struct fw_device{ 48 u_int16_t dst; 49 struct fw_eui64 eui; 50 #if 0 51 u_int32_t spec; 52 u_int32_t ver; 53 #endif 54 u_int8_t speed; 55 u_int8_t maxrec; 56 u_int8_t nport; 57 u_int8_t power; 58 #define CSRROMOFF 0x400 59 #define CSRROMSIZE 0x400 60 int rommax; /* offset from 0xffff f000 0000 */ 61 u_int32_t csrrom[CSRROMSIZE/4]; 62 int rcnt; 63 struct firewire_comm *fc; 64 u_int32_t status; 65 #define FWDEVINIT 1 66 #define FWDEVATTACHED 2 67 #define FWDEVINVAL 3 68 STAILQ_ENTRY(fw_device) link; 69 #if 0 70 LIST_HEAD(, fw_xfer) txqueue; 71 LIST_HEAD(, fw_xfer) rxqueue; 72 #endif 73 }; 74 75 struct firewire_softc { 76 #if __FreeBSD_version >= 500000 77 dev_t dev; 78 #else 79 dev_t dev[FWMAXNDMA+1]; 80 #endif 81 struct firewire_comm *fc; 82 }; 83 84 #define FW_MAX_DMACH 0x20 85 #define FW_MAX_DEVCH FW_MAX_DMACH 86 #define FW_XFERTIMEOUT 1 87 88 struct firewire_dev_comm { 89 device_t dev; 90 struct firewire_comm *fc; 91 void (*post_explore) __P((void *)); 92 }; 93 94 struct tcode_info { 95 u_char hdr_len; /* IEEE1394 header length */ 96 u_char flag; 97 #define FWTI_REQ (1 << 0) 98 #define FWTI_RES (1 << 1) 99 #define FWTI_TLABEL (1 << 2) 100 #define FWTI_BLOCK_STR (1 << 3) 101 #define FWTI_BLOCK_ASY (1 << 4) 102 }; 103 104 struct firewire_comm{ 105 device_t dev; 106 device_t bdev; 107 u_int16_t busid:10, 108 nodeid:6; 109 u_int mode; 110 u_int nport; 111 u_int speed; 112 u_int maxrec; 113 u_int irm; 114 u_int max_node; 115 u_int max_hop; 116 u_int max_asyretry; 117 #define FWPHYASYST (1 << 0) 118 u_int retry_count; 119 u_int32_t ongobus:10, 120 ongonode:6, 121 ongoaddr:16; 122 struct fw_device *ongodev; 123 struct fw_eui64 ongoeui; 124 #define FWMAXCSRDIR 16 125 SLIST_HEAD(, csrdir) ongocsr; 126 SLIST_HEAD(, csrdir) csrfree; 127 u_int32_t status; 128 #define FWBUSRESET 0 129 #define FWBUSINIT 1 130 #define FWBUSCYMELECT 2 131 #define FWBUSMGRELECT 3 132 #define FWBUSMGRDONE 4 133 #define FWBUSEXPLORE 5 134 #define FWBUSPHYCONF 6 135 #define FWBUSEXPDONE 7 136 #define FWBUSCOMPLETION 10 137 int nisodma; 138 struct fw_eui64 eui; 139 STAILQ_HEAD(fw_queue, fw_xfer); 140 struct fw_xferq 141 *arq, *atq, *ars, *ats, *it[FW_MAX_DMACH],*ir[FW_MAX_DMACH]; 142 STAILQ_HEAD(, tlabel) tlabels[0x40]; 143 STAILQ_HEAD(, fw_bind) binds; 144 STAILQ_HEAD(, fw_device) devices; 145 STAILQ_HEAD(, fw_xfer) pending; 146 volatile u_int32_t *sid_buf; 147 u_int sid_cnt; 148 #define CSRSIZE 0x4000 149 u_int32_t csr_arc[CSRSIZE/4]; 150 #define CROMSIZE 0x400 151 u_int32_t *config_rom; 152 struct fw_topology_map *topology_map; 153 struct fw_speed_map *speed_map; 154 struct callout busprobe_callout; 155 struct callout bmr_callout; 156 struct callout timeout_callout; 157 struct callout retry_probe_callout; 158 u_int32_t (*cyctimer) __P((struct firewire_comm *)); 159 void (*ibr) __P((struct firewire_comm *)); 160 u_int32_t (*set_bmr) __P((struct firewire_comm *, u_int32_t)); 161 int (*ioctl) __P((dev_t, u_long, caddr_t, int, fw_proc *)); 162 int (*irx_enable) __P((struct firewire_comm *, int)); 163 int (*irx_disable) __P((struct firewire_comm *, int)); 164 int (*itx_enable) __P((struct firewire_comm *, int)); 165 int (*itx_disable) __P((struct firewire_comm *, int)); 166 void (*timeout) __P((void *)); 167 void (*poll) __P((struct firewire_comm *, int, int)); 168 void (*set_intr) __P((struct firewire_comm *, int)); 169 void (*irx_post) __P((struct firewire_comm *, u_int32_t *)); 170 void (*itx_post) __P((struct firewire_comm *, u_int32_t *)); 171 struct tcode_info *tcode; 172 }; 173 #define CSRARC(sc, offset) ((sc)->csr_arc[(offset)/4]) 174 175 struct csrdir{ 176 u_int32_t ongoaddr; 177 u_int32_t off; 178 SLIST_ENTRY(csrdir) link; 179 }; 180 181 struct fw_xferq { 182 int flag; 183 #define FWXFERQ_CHTAGMASK 0xff 184 #define FWXFERQ_RUNNING (1 << 8) 185 #define FWXFERQ_STREAM (1 << 9) 186 187 #define FWXFERQ_PACKET (1 << 10) 188 #define FWXFERQ_BULK (1 << 11) 189 #if 0 /* BROKEN */ 190 #define FWXFERQ_DV (1 << 12) 191 #endif 192 #define FWXFERQ_MODEMASK (7 << 10) 193 194 #define FWXFERQ_EXTBUF (1 << 13) 195 #define FWXFERQ_OPEN (1 << 14) 196 197 #define FWXFERQ_HANDLER (1 << 16) 198 #define FWXFERQ_WAKEUP (1 << 17) 199 200 void (*start) __P((struct firewire_comm*)); 201 void (*drain) __P((struct firewire_comm*, struct fw_xfer*)); 202 struct fw_queue q; 203 u_int queued; 204 u_int maxq; 205 u_int psize; 206 u_int packets; 207 STAILQ_HEAD(, fw_bind) binds; 208 caddr_t buf; 209 u_int bnchunk; 210 u_int bnpacket; 211 struct fw_bulkxfer *bulkxfer; 212 STAILQ_HEAD(, fw_bulkxfer) stvalid; 213 STAILQ_HEAD(, fw_bulkxfer) stfree; 214 STAILQ_HEAD(, fw_bulkxfer) stdma; 215 struct fw_bulkxfer *stproc; 216 #ifdef FWXFERQ_DV 217 int dvdbc, dvdiff, dvsync, dvoffset; 218 struct fw_dvbuf *dvbuf; 219 STAILQ_HEAD(, fw_dvbuf) dvvalid; 220 STAILQ_HEAD(, fw_dvbuf) dvfree; 221 struct fw_dvbuf *dvdma; 222 struct fw_dvbuf *dvproc; 223 u_int dvptr; 224 u_int dvpacket; 225 #endif 226 struct selinfo rsel; 227 caddr_t sc; 228 void (*hand) __P((struct fw_xferq *)); 229 }; 230 231 struct fw_bulkxfer{ 232 caddr_t buf; 233 struct mbuf *mbuf; 234 STAILQ_ENTRY(fw_bulkxfer) link; 235 caddr_t start; 236 caddr_t end; 237 u_int npacket; 238 int resp; 239 }; 240 241 struct fw_dvbuf{ 242 caddr_t buf; 243 STAILQ_ENTRY(fw_dvbuf) link; 244 }; 245 246 struct tlabel{ 247 struct fw_xfer *xfer; 248 STAILQ_ENTRY(tlabel) link; 249 }; 250 251 struct fw_bind{ 252 u_int32_t start_hi, start_lo, addrlen; 253 struct fw_xfer* xfer; 254 STAILQ_ENTRY(fw_bind) fclist; 255 STAILQ_ENTRY(fw_bind) chlist; 256 }; 257 258 struct fw_xfer{ 259 caddr_t sc; 260 struct firewire_comm *fc; 261 struct fw_xferq *q; 262 #ifdef XFER_TIMEOUT 263 struct callout_handle ch; 264 #endif 265 struct timeval tv; 266 struct fw_tlabel *tlabel; 267 u_int8_t spd; 268 u_int8_t tcode; 269 int resp; 270 #define FWXF_INIT 0 271 #define FWXF_INQ 1 272 #define FWXF_START 2 273 #define FWXF_SENT 3 274 #define FWXF_SENTERR 4 275 #define FWXF_BUSY 8 276 #define FWXF_RCVD 10 277 int state; 278 u_int8_t retry; 279 u_int8_t tl; 280 int sub; 281 int32_t dst; 282 u_int8_t act_type; 283 #define FWACT_NULL 0 284 #define FWACT_XFER 2 285 #define FWACT_CH 3 286 void (*retry_req) __P((struct fw_xfer *)); 287 union{ 288 void (*hand) __P((struct fw_xfer *)); 289 } act; 290 #if 0 291 union{ 292 struct { 293 struct fw_device *device; 294 } req; 295 struct { 296 struct stch *channel; 297 } stream; 298 } mode; 299 #endif 300 struct { 301 u_int16_t len, off; 302 caddr_t buf; 303 } send, recv; 304 struct mbuf *mbuf; 305 STAILQ_ENTRY(fw_xfer) link; 306 struct malloc_type *malloc; 307 }; 308 void fw_sidrcv __P((struct firewire_comm *, caddr_t, u_int, u_int)); 309 void fw_rcv __P((struct firewire_comm *, caddr_t, u_int, u_int, u_int, u_int)); 310 void fw_xfer_free __P(( struct fw_xfer*)); 311 struct fw_xfer *fw_xfer_alloc __P((struct malloc_type *)); 312 void fw_init __P((struct firewire_comm *)); 313 int fw_tbuf_update __P((struct firewire_comm *, int, int)); 314 int fw_rbuf_update __P((struct firewire_comm *, int, int)); 315 int fw_readreqq __P((struct firewire_comm *, u_int32_t, u_int32_t, u_int32_t *)); 316 int fw_writereqb __P((struct firewire_comm *, u_int32_t, u_int32_t, u_int32_t, u_int32_t *)); 317 int fw_readresb __P((struct firewire_comm *, u_int32_t, u_int32_t, u_int32_t, u_int32_t*)); 318 int fw_writeres __P((struct firewire_comm *, u_int32_t, u_int32_t)); 319 u_int32_t getcsrdata __P((struct fw_device *, u_int8_t)); 320 void fw_asybusy __P((struct fw_xfer *)); 321 int fw_bindadd __P((struct firewire_comm *, struct fw_bind *)); 322 int fw_bindremove __P((struct firewire_comm *, struct fw_bind *)); 323 int fw_asyreq __P((struct firewire_comm *, int, struct fw_xfer*)); 324 void fw_busreset __P((struct firewire_comm *)); 325 u_int16_t fw_crc16 __P((u_int32_t *, u_int32_t)); 326 void fw_xfer_timeout __P((void *)); 327 void fw_xfer_done __P((struct fw_xfer *)); 328 void fw_asy_callback __P((struct fw_xfer *)); 329 struct fw_device *fw_noderesolve_nodeid __P((struct firewire_comm *, int)); 330 struct fw_device *fw_noderesolve_eui64 __P((struct firewire_comm *, struct fw_eui64 *)); 331 struct fw_bind *fw_bindlookup __P((struct firewire_comm *, u_int32_t, u_int32_t)); 332 void fw_drain_txq __P((struct firewire_comm *)); 333 334 335 extern int firewire_debug; 336 extern devclass_t firewire_devclass; 337 338 #define DV_BROADCAST_ON (1<<30) 339 #define IP_CHANNELS 0x0234 340 341 #define STATE_CLEAR 0x0000 342 #define STATE_SET 0x0004 343 #define NODE_IDS 0x0008 344 #define RESET_START 0x000c 345 #define SPLIT_TIMEOUT_HI 0x0018 346 #define SPLIT_TIMEOUT_LO 0x001c 347 #define CYCLE_TIME 0x0200 348 #define BUS_TIME 0x0204 349 #define BUSY_TIMEOUT 0x0210 350 #define BUS_MGR_ID 0x021c 351 #define BANDWIDTH_AV 0x0220 352 #define CHANNELS_AV_HI 0x0224 353 #define CHANNELS_AV_LO 0x0228 354 355 #define CONF_ROM 0x0400 356 357 #define TOPO_MAP 0x1000 358 #define SPED_MAP 0x2000 359 360 #define oMPR 0x900 361 #define oPCR 0x904 362 363 #define iMPR 0x980 364 #define iPCR 0x984 365 366 #define FWPRI ((PZERO+8)|PCATCH) 367 368 #ifdef __alpha__ 369 #undef vtophys 370 #define vtophys(va) alpha_XXX_dmamap((vm_offset_t)(va)) 371 #endif /* __alpha__ */ 372 373 #if __FreeBSD_version >= 500000 374 #define CALLOUT_INIT(x) callout_init(x, 0 /* mpsafe */) 375 #else 376 #define CALLOUT_INIT(x) callout_init(x) 377 #endif 378 379 MALLOC_DECLARE(M_FW); 380 MALLOC_DECLARE(M_FWXFER); 381