1 /*- 2 * Copyright (c) 2006 IronPort Systems 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 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <opt_mfi.h> 31 32 #ifdef MFI_DEBUG 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/conf.h> 38 #include <sys/bus.h> 39 #include <sys/bio.h> 40 #include <sys/lock.h> 41 #include <sys/mutex.h> 42 #include <sys/malloc.h> 43 #include <sys/selinfo.h> 44 #include <sys/taskqueue.h> 45 #include <sys/uio.h> 46 #include <machine/resource.h> 47 #include <machine/bus.h> 48 49 #include <dev/mfi/mfireg.h> 50 #include <dev/mfi/mfi_ioctl.h> 51 #include <dev/mfi/mfivar.h> 52 53 static void 54 mfi_print_frame_flags(device_t dev, uint32_t flags) 55 { 56 device_printf(dev, "flags=%b\n", flags, 57 "\20" 58 "\1NOPOST" 59 "\2SGL64" 60 "\3SENSE64" 61 "\4WRITE" 62 "\5READ"); 63 } 64 65 static void 66 mfi_print_sgl(struct mfi_frame_header *hdr, union mfi_sgl *sgl, int count) 67 { 68 int i, columns = 0; 69 70 printf("SG List:\n"); 71 for (i = 0; i < count; i++) { 72 if (hdr->flags & MFI_FRAME_SGL64) { 73 printf("0x%lx:%06d ", (u_long)sgl->sg64[i].addr, 74 sgl->sg64[i].len); 75 columns += 26; 76 if (columns > 77) { 77 printf("\n"); 78 columns = 0; 79 } 80 } else { 81 printf("0x%x:%06d ", sgl->sg32[i].addr, 82 sgl->sg32[i].len); 83 columns += 18; 84 if (columns > 71) { 85 printf("\n"); 86 columns = 0; 87 } 88 } 89 } 90 if (columns != 0) 91 printf("\n"); 92 93 } 94 95 static void 96 mfi_print_ldio(struct mfi_softc *sc, device_t dev, struct mfi_command *cm) 97 { 98 struct mfi_io_frame *io; 99 struct mfi_frame_header *hdr; 100 101 io = &cm->cm_frame->io; 102 hdr = &io->header; 103 104 device_printf(dev, "cmd=%s target_id=%d sg_count=%d data_len=%d " 105 "lba=%d\n", (hdr->cmd == MFI_CMD_LD_READ) ? "LD_READ":"LD_WRITE", 106 hdr->target_id, hdr->sg_count, hdr->data_len, io->lba_lo); 107 mfi_print_frame_flags(dev, hdr->flags); 108 mfi_print_sgl(hdr, &io->sgl, hdr->sg_count); 109 110 } 111 112 static void 113 mfi_print_dcmd(struct mfi_softc *sc, device_t dev, struct mfi_command *cm) 114 { 115 struct mfi_dcmd_frame *dcmd; 116 struct mfi_frame_header *hdr; 117 const char *opcode; 118 119 dcmd = &cm->cm_frame->dcmd; 120 hdr = &dcmd->header; 121 122 switch (dcmd->opcode) { 123 case MFI_DCMD_CTRL_GETINFO: 124 opcode = "CTRL_GETINFO"; 125 break; 126 case MFI_DCMD_CTRL_FLUSHCACHE: 127 opcode = "CTRL_FLUSHCACHE"; 128 break; 129 case MFI_DCMD_CTRL_SHUTDOWN: 130 opcode = "CTRL_SHUTDOWN"; 131 break; 132 case MFI_DCMD_CTRL_EVENT_GETINFO: 133 opcode = "EVENT_GETINFO"; 134 break; 135 case MFI_DCMD_CTRL_EVENT_GET: 136 opcode = "EVENT_GET"; 137 break; 138 case MFI_DCMD_CTRL_EVENT_WAIT: 139 opcode = "EVENT_WAIT"; 140 break; 141 case MFI_DCMD_LD_GET_LIST: 142 opcode = "LD_GET_LIST"; 143 break; 144 case MFI_DCMD_LD_GET_INFO: 145 opcode = "LD_GET_INFO"; 146 break; 147 case MFI_DCMD_LD_GET_PROP: 148 opcode = "LD_GET_PROP"; 149 break; 150 case MFI_DCMD_LD_SET_PROP: 151 opcode = "LD_SET_PROP"; 152 break; 153 case MFI_DCMD_CLUSTER: 154 opcode = "CLUSTER"; 155 break; 156 case MFI_DCMD_CLUSTER_RESET_ALL: 157 opcode = "CLUSTER_RESET_ALL"; 158 break; 159 case MFI_DCMD_CLUSTER_RESET_LD: 160 opcode = "CLUSTER_RESET_LD"; 161 break; 162 default: 163 opcode = "UNKNOWN"; 164 break; 165 } 166 167 device_printf(dev, "cmd=MFI_CMD_DCMD opcode=%s data_len=%d\n", 168 opcode, hdr->data_len); 169 mfi_print_frame_flags(dev, hdr->flags); 170 mfi_print_sgl(hdr, &dcmd->sgl, hdr->sg_count); 171 172 } 173 174 static void 175 mfi_print_generic_frame(struct mfi_softc *sc, struct mfi_command *cm) 176 { 177 hexdump(cm->cm_frame, cm->cm_total_frame_size, NULL, HD_OMIT_CHARS); 178 } 179 180 void 181 mfi_print_cmd(struct mfi_command *cm) 182 { 183 device_t dev; 184 struct mfi_softc *sc; 185 186 sc = cm->cm_sc; 187 dev = sc->mfi_dev; 188 189 device_printf(dev, "cm=%p index=%d total_frame_size=%d " 190 "extra_frames=%d\n", cm, cm->cm_index, cm->cm_total_frame_size, 191 cm->cm_extra_frames); 192 device_printf(dev, "flags=%b\n", cm->cm_flags, 193 "\20" 194 "\1MAPPED" 195 "\2DATAIN" 196 "\3DATAOUT" 197 "\4COMPLETED" 198 "\5POLLED" 199 "\6Q_FREE" 200 "\7Q_READY" 201 "\10Q_BUSY"); 202 203 switch (cm->cm_frame->header.cmd) { 204 case MFI_CMD_DCMD: 205 mfi_print_dcmd(sc, dev, cm); 206 break; 207 case MFI_CMD_LD_READ: 208 case MFI_CMD_LD_WRITE: 209 mfi_print_ldio(sc, dev, cm); 210 break; 211 default: 212 mfi_print_generic_frame(sc, cm); 213 break; 214 } 215 216 return; 217 } 218 219 void 220 mfi_dump_cmds(struct mfi_softc *sc) 221 { 222 int i; 223 224 for (i = 0; i < sc->mfi_total_cmds; i++) 225 mfi_print_generic_frame(sc, &sc->mfi_commands[i]); 226 } 227 228 #endif 229