1 /*- 2 * Copyright (c) 2003 Hidetoshi Shimokawa 3 * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the acknowledgement as bellow: 16 * 17 * This product includes software developed by K. Kobayashi and H. Shimokawa 18 * 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 25 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 * 34 * $FreeBSD$ 35 * 36 */ 37 38 typedef struct thread fw_proc; 39 #include <sys/selinfo.h> 40 41 #include <sys/uio.h> 42 #include <sys/mutex.h> 43 #include <sys/taskqueue.h> 44 45 #define splfw splimp 46 47 STAILQ_HEAD(fw_xferlist, fw_xfer); 48 49 struct fw_device { 50 uint16_t dst; 51 struct fw_eui64 eui; 52 uint8_t speed; 53 uint8_t maxrec; 54 uint8_t nport; 55 uint8_t power; 56 #define CSRROMOFF 0x400 57 #define CSRROMSIZE 0x400 58 int rommax; /* offset from 0xffff f000 0000 */ 59 uint32_t csrrom[CSRROMSIZE / 4]; 60 int rcnt; 61 struct firewire_comm *fc; 62 uint32_t status; 63 #define FWDEVINIT 1 64 #define FWDEVATTACHED 2 65 #define FWDEVINVAL 3 66 STAILQ_ENTRY(fw_device) link; 67 }; 68 69 struct firewire_softc { 70 struct cdev *dev; 71 struct firewire_comm *fc; 72 }; 73 74 #define FW_MAX_DMACH 0x20 75 #define FW_MAX_DEVCH FW_MAX_DMACH 76 #define FW_XFERTIMEOUT 1 77 78 struct firewire_dev_comm { 79 device_t dev; 80 struct firewire_comm *fc; 81 void (*post_busreset) (void *); 82 void (*post_explore) (void *); 83 }; 84 85 struct tcode_info { 86 u_char hdr_len; /* IEEE1394 header length */ 87 u_char flag; 88 #define FWTI_REQ (1 << 0) 89 #define FWTI_RES (1 << 1) 90 #define FWTI_TLABEL (1 << 2) 91 #define FWTI_BLOCK_STR (1 << 3) 92 #define FWTI_BLOCK_ASY (1 << 4) 93 u_char valid_res; 94 }; 95 96 struct firewire_comm { 97 device_t dev; 98 device_t bdev; 99 uint16_t busid:10, 100 nodeid:6; 101 u_int mode; 102 u_int nport; 103 u_int speed; 104 u_int maxrec; 105 u_int irm; 106 u_int max_node; 107 u_int max_hop; 108 #define FWPHYASYST (1 << 0) 109 uint32_t status; 110 #define FWBUSDETACH (-2) 111 #define FWBUSNOTREADY (-1) 112 #define FWBUSRESET 0 113 #define FWBUSINIT 1 114 #define FWBUSCYMELECT 2 115 #define FWBUSMGRELECT 3 116 #define FWBUSMGRDONE 4 117 #define FWBUSEXPLORE 5 118 #define FWBUSPHYCONF 6 119 #define FWBUSEXPDONE 7 120 #define FWBUSCOMPLETION 10 121 int nisodma; 122 struct fw_eui64 eui; 123 struct fw_xferq 124 *arq, *atq, *ars, *ats, *it[FW_MAX_DMACH],*ir[FW_MAX_DMACH]; 125 struct fw_xferlist tlabels[0x40]; 126 u_char last_tlabel[0x40]; 127 struct mtx tlabel_lock; 128 STAILQ_HEAD(, fw_bind) binds; 129 STAILQ_HEAD(, fw_device) devices; 130 u_int sid_cnt; 131 #define CSRSIZE 0x4000 132 uint32_t csr_arc[CSRSIZE / 4]; 133 #define CROMSIZE 0x400 134 uint32_t *config_rom; 135 struct crom_src_buf *crom_src_buf; 136 struct crom_src *crom_src; 137 struct crom_chunk *crom_root; 138 struct fw_topology_map *topology_map; 139 struct fw_speed_map *speed_map; 140 struct callout busprobe_callout; 141 struct callout bmr_callout; 142 struct callout timeout_callout; 143 struct task task_timeout; 144 uint32_t (*cyctimer) (struct firewire_comm *); 145 void (*ibr) (struct firewire_comm *); 146 uint32_t (*set_bmr) (struct firewire_comm *, uint32_t); 147 int (*ioctl) (struct cdev *, u_long, caddr_t, int, fw_proc *); 148 int (*irx_enable) (struct firewire_comm *, int); 149 int (*irx_disable) (struct firewire_comm *, int); 150 int (*itx_enable) (struct firewire_comm *, int); 151 int (*itx_disable) (struct firewire_comm *, int); 152 void (*timeout) (void *); 153 void (*poll) (struct firewire_comm *, int, int); 154 void (*set_intr) (struct firewire_comm *, int); 155 void (*irx_post) (struct firewire_comm *, uint32_t *); 156 void (*itx_post) (struct firewire_comm *, uint32_t *); 157 struct tcode_info *tcode; 158 bus_dma_tag_t dmat; 159 struct mtx mtx; 160 struct mtx wait_lock; 161 struct taskqueue *taskqueue; 162 struct proc *probe_thread; 163 }; 164 #define CSRARC(sc, offset) ((sc)->csr_arc[(offset) / 4]) 165 166 #define FW_GMTX(fc) (&(fc)->mtx) 167 #define FW_GLOCK(fc) mtx_lock(FW_GMTX(fc)) 168 #define FW_GUNLOCK(fc) mtx_unlock(FW_GMTX(fc)) 169 #define FW_GLOCK_ASSERT(fc) mtx_assert(FW_GMTX(fc), MA_OWNED) 170 171 struct fw_xferq { 172 int flag; 173 #define FWXFERQ_CHTAGMASK 0xff 174 #define FWXFERQ_RUNNING (1 << 8) 175 #define FWXFERQ_STREAM (1 << 9) 176 177 #define FWXFERQ_BULK (1 << 11) 178 #define FWXFERQ_MODEMASK (7 << 10) 179 180 #define FWXFERQ_EXTBUF (1 << 13) 181 #define FWXFERQ_OPEN (1 << 14) 182 183 #define FWXFERQ_HANDLER (1 << 16) 184 #define FWXFERQ_WAKEUP (1 << 17) 185 void (*start) (struct firewire_comm *); 186 int dmach; 187 struct fw_xferlist q; 188 u_int queued; 189 u_int maxq; 190 u_int psize; 191 struct fwdma_alloc_multi *buf; 192 u_int bnchunk; 193 u_int bnpacket; 194 struct fw_bulkxfer *bulkxfer; 195 STAILQ_HEAD(, fw_bulkxfer) stvalid; 196 STAILQ_HEAD(, fw_bulkxfer) stfree; 197 STAILQ_HEAD(, fw_bulkxfer) stdma; 198 struct fw_bulkxfer *stproc; 199 struct selinfo rsel; 200 caddr_t sc; 201 void (*hand) (struct fw_xferq *); 202 }; 203 204 struct fw_bulkxfer { 205 int poffset; 206 struct mbuf *mbuf; 207 STAILQ_ENTRY(fw_bulkxfer) link; 208 caddr_t start; 209 caddr_t end; 210 int resp; 211 }; 212 213 struct fw_bind { 214 u_int64_t start; 215 u_int64_t end; 216 struct fw_xferlist xferlist; 217 STAILQ_ENTRY(fw_bind) fclist; 218 STAILQ_ENTRY(fw_bind) chlist; 219 void *sc; 220 }; 221 222 struct fw_xfer { 223 caddr_t sc; 224 struct firewire_comm *fc; 225 struct fw_xferq *q; 226 struct timeval tv; 227 int8_t resp; 228 #define FWXF_INIT 0x00 229 #define FWXF_INQ 0x01 230 #define FWXF_START 0x02 231 #define FWXF_SENT 0x04 232 #define FWXF_SENTERR 0x08 233 #define FWXF_BUSY 0x10 234 #define FWXF_RCVD 0x20 235 236 #define FWXF_WAKE 0x80 237 uint8_t flag; 238 int8_t tl; 239 void (*hand) (struct fw_xfer *); 240 struct { 241 struct fw_pkt hdr; 242 uint32_t *payload; 243 uint16_t pay_len; 244 uint8_t spd; 245 } send, recv; 246 struct mbuf *mbuf; 247 STAILQ_ENTRY(fw_xfer) link; 248 STAILQ_ENTRY(fw_xfer) tlabel; 249 struct malloc_type *malloc; 250 }; 251 252 struct fw_rcv_buf { 253 struct firewire_comm *fc; 254 struct fw_xfer *xfer; 255 struct iovec *vec; 256 u_int nvec; 257 uint8_t spd; 258 }; 259 260 void fw_sidrcv (struct firewire_comm *, uint32_t *, u_int); 261 void fw_rcv (struct fw_rcv_buf *); 262 void fw_xfer_unload (struct fw_xfer *); 263 void fw_xfer_free_buf (struct fw_xfer *); 264 void fw_xfer_free (struct fw_xfer*); 265 struct fw_xfer *fw_xfer_alloc (struct malloc_type *); 266 struct fw_xfer *fw_xfer_alloc_buf (struct malloc_type *, int, int); 267 void fw_init (struct firewire_comm *); 268 int fw_tbuf_update (struct firewire_comm *, int, int); 269 int fw_rbuf_update (struct firewire_comm *, int, int); 270 int fw_bindadd (struct firewire_comm *, struct fw_bind *); 271 int fw_bindremove (struct firewire_comm *, struct fw_bind *); 272 int fw_xferlist_add (struct fw_xferlist *, struct malloc_type *, int, int, int, 273 struct firewire_comm *, void *, void (*)(struct fw_xfer *)); 274 void fw_xferlist_remove (struct fw_xferlist *); 275 int fw_asyreq (struct firewire_comm *, int, struct fw_xfer *); 276 void fw_busreset (struct firewire_comm *, uint32_t); 277 uint16_t fw_crc16 (uint32_t *, uint32_t); 278 void fw_xfer_timeout (void *); 279 void fw_xfer_done (struct fw_xfer *); 280 void fw_xferwake (struct fw_xfer *); 281 int fw_xferwait (struct fw_xfer *); 282 void fw_asy_callback_free (struct fw_xfer *); 283 struct fw_device *fw_noderesolve_nodeid (struct firewire_comm *, int); 284 struct fw_device *fw_noderesolve_eui64 (struct firewire_comm *, struct fw_eui64 *); 285 struct fw_bind *fw_bindlookup (struct firewire_comm *, uint16_t, uint32_t); 286 void fw_drain_txq (struct firewire_comm *); 287 int fwdev_makedev (struct firewire_softc *); 288 int fwdev_destroydev (struct firewire_softc *); 289 void fwdev_clone (void *, struct ucred *, char *, int, struct cdev **); 290 int fw_open_isodma(struct firewire_comm *, int); 291 292 extern int firewire_debug; 293 extern devclass_t firewire_devclass; 294 extern int firewire_phydma_enable; 295 296 #define FWPRI ((PZERO + 8) | PCATCH) 297 298 #define CALLOUT_INIT(x) callout_init(x, 1 /* mpsafe */) 299 300 MALLOC_DECLARE(M_FW); 301 MALLOC_DECLARE(M_FWXFER); 302