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 * $FreeBSD: src/sys/dev/mfi/mfi_debug.c,v 1.3 2006/10/16 04:18:38 scottl Exp $ 27 * FreeBSD projects/head_mfi/ r228320 28 */ 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/buf2.h> 40 #include <sys/lock.h> 41 #include <sys/mutex.h> 42 #include <sys/malloc.h> 43 #include <sys/taskqueue.h> 44 #include <sys/uio.h> 45 46 #include <vm/vm.h> 47 #include <vm/pmap.h> 48 49 #include <dev/raid/mfi/mfireg.h> 50 #include <dev/raid/mfi/mfi_ioctl.h> 51 #include <dev/raid/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 "\6IEEESGL"); 64 } 65 66 static void 67 mfi_print_sgl(struct mfi_frame_header *hdr, union mfi_sgl *sgl, int count) 68 { 69 int i, columns = 0; 70 71 kprintf("SG List:\n"); 72 for (i = 0; i < count; i++) { 73 if (hdr->flags & MFI_FRAME_IEEE_SGL) { 74 kprintf("0x%lx:%06d ", (u_long)sgl->sg_skinny[i].addr, 75 sgl->sg_skinny[i].len); 76 columns += 26; 77 if (columns > 77) { 78 kprintf("\n"); 79 columns = 0; 80 } 81 } else if (hdr->flags & MFI_FRAME_SGL64) { 82 kprintf("0x%lx:%06d ", (u_long)sgl->sg64[i].addr, 83 sgl->sg64[i].len); 84 columns += 26; 85 if (columns > 77) { 86 kprintf("\n"); 87 columns = 0; 88 } 89 } else { 90 kprintf("0x%x:%06d ", sgl->sg32[i].addr, 91 sgl->sg32[i].len); 92 columns += 18; 93 if (columns > 71) { 94 kprintf("\n"); 95 columns = 0; 96 } 97 } 98 } 99 if (columns != 0) 100 kprintf("\n"); 101 102 } 103 104 static void 105 mfi_print_ldio(struct mfi_softc *sc, device_t dev, struct mfi_command *cm) 106 { 107 struct mfi_io_frame *io; 108 struct mfi_frame_header *hdr; 109 110 io = &cm->cm_frame->io; 111 hdr = &io->header; 112 113 device_printf(dev, "cmd=%s target_id=%d sg_count=%d data_len=%d " 114 "lba=%d\n", (hdr->cmd == MFI_CMD_LD_READ) ? "LD_READ":"LD_WRITE", 115 hdr->target_id, hdr->sg_count, hdr->data_len, io->lba_lo); 116 mfi_print_frame_flags(dev, hdr->flags); 117 mfi_print_sgl(hdr, &io->sgl, hdr->sg_count); 118 119 } 120 121 static void 122 mfi_print_dcmd(struct mfi_softc *sc, device_t dev, struct mfi_command *cm) 123 { 124 struct mfi_dcmd_frame *dcmd; 125 struct mfi_frame_header *hdr; 126 const char *opcode; 127 128 dcmd = &cm->cm_frame->dcmd; 129 hdr = &dcmd->header; 130 131 switch (dcmd->opcode) { 132 case MFI_DCMD_CTRL_GETINFO: 133 opcode = "CTRL_GETINFO"; 134 break; 135 case MFI_DCMD_CTRL_FLUSHCACHE: 136 opcode = "CTRL_FLUSHCACHE"; 137 break; 138 case MFI_DCMD_CTRL_SHUTDOWN: 139 opcode = "CTRL_SHUTDOWN"; 140 break; 141 case MFI_DCMD_CTRL_EVENT_GETINFO: 142 opcode = "EVENT_GETINFO"; 143 break; 144 case MFI_DCMD_CTRL_EVENT_GET: 145 opcode = "EVENT_GET"; 146 break; 147 case MFI_DCMD_CTRL_EVENT_WAIT: 148 opcode = "EVENT_WAIT"; 149 break; 150 case MFI_DCMD_LD_GET_LIST: 151 opcode = "LD_GET_LIST"; 152 break; 153 case MFI_DCMD_LD_GET_INFO: 154 opcode = "LD_GET_INFO"; 155 break; 156 case MFI_DCMD_LD_GET_PROP: 157 opcode = "LD_GET_PROP"; 158 break; 159 case MFI_DCMD_LD_SET_PROP: 160 opcode = "LD_SET_PROP"; 161 break; 162 case MFI_DCMD_CLUSTER: 163 opcode = "CLUSTER"; 164 break; 165 case MFI_DCMD_CLUSTER_RESET_ALL: 166 opcode = "CLUSTER_RESET_ALL"; 167 break; 168 case MFI_DCMD_CLUSTER_RESET_LD: 169 opcode = "CLUSTER_RESET_LD"; 170 break; 171 default: 172 opcode = "UNKNOWN"; 173 break; 174 } 175 176 device_printf(dev, "cmd=MFI_CMD_DCMD opcode=%s data_len=%d\n", 177 opcode, hdr->data_len); 178 mfi_print_frame_flags(dev, hdr->flags); 179 mfi_print_sgl(hdr, &dcmd->sgl, hdr->sg_count); 180 181 } 182 183 static void 184 mfi_print_generic_frame(struct mfi_softc *sc, struct mfi_command *cm) 185 { 186 hexdump(cm->cm_frame, cm->cm_total_frame_size, NULL, HD_OMIT_CHARS); 187 } 188 189 void 190 mfi_print_cmd(struct mfi_command *cm) 191 { 192 device_t dev; 193 struct mfi_softc *sc; 194 195 sc = cm->cm_sc; 196 dev = sc->mfi_dev; 197 198 device_printf(dev, "cm=%p index=%d total_frame_size=%d " 199 "extra_frames=%d\n", cm, cm->cm_index, cm->cm_total_frame_size, 200 cm->cm_extra_frames); 201 device_printf(dev, "flags=%b\n", cm->cm_flags, 202 "\20" 203 "\1MAPPED" 204 "\2DATAIN" 205 "\3DATAOUT" 206 "\4COMPLETED" 207 "\5POLLED" 208 "\6Q_FREE" 209 "\7Q_READY" 210 "\10Q_BUSY"); 211 212 switch (cm->cm_frame->header.cmd) { 213 case MFI_CMD_DCMD: 214 mfi_print_dcmd(sc, dev, cm); 215 break; 216 case MFI_CMD_LD_READ: 217 case MFI_CMD_LD_WRITE: 218 mfi_print_ldio(sc, dev, cm); 219 break; 220 default: 221 mfi_print_generic_frame(sc, cm); 222 break; 223 } 224 225 return; 226 } 227 228 void 229 mfi_dump_cmds(struct mfi_softc *sc) 230 { 231 int i; 232 233 for (i = 0; i < sc->mfi_total_cmds; i++) 234 mfi_print_generic_frame(sc, &sc->mfi_commands[i]); 235 } 236 237 void 238 mfi_validate_sg(struct mfi_softc *sc, struct mfi_command *cm, 239 const char *function, int line) 240 { 241 struct mfi_frame_header *hdr; 242 int i; 243 uint32_t count = 0, data_len; 244 245 hdr = &cm->cm_frame->header; 246 count = 0; 247 for (i = 0; i < hdr->sg_count; i++) { 248 if (hdr->flags & MFI_FRAME_IEEE_SGL) 249 count += cm->cm_sg->sg_skinny[i].len; 250 else if (hdr->flags & MFI_FRAME_SGL64) 251 count += cm->cm_sg->sg64[i].len; 252 else 253 count += cm->cm_sg->sg32[i].len; 254 } 255 /* 256 count++; 257 */ 258 data_len = hdr->data_len; 259 switch (hdr->cmd) { 260 case MFI_CMD_LD_READ: 261 case MFI_CMD_LD_WRITE: 262 data_len = data_len * 512; 263 case MFI_CMD_DCMD: 264 if (count != data_len) { 265 device_printf(sc->mfi_dev, 266 "%s %d COMMAND %p S/G count bad %d %d %d 0x%jx\n", 267 function, line, cm, count, data_len, cm->cm_len, 268 (intmax_t)pmap_kextract((vm_offset_t)cm->cm_data)); 269 MFI_PRINT_CMD(cm); 270 } 271 } 272 } 273 274 #endif 275