1/* $NetBSD: util.c,v 1.6 2008/04/28 20:24:17 martin Exp $ */ 2 3/*- 4 * Copyright (c) 2001 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. 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/*- 33 * Copyright (c) 1999 Michael Smith 34 * All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 55 * SUCH DAMAGE. 56 */ 57 58#ifndef lint 59#include <sys/cdefs.h> 60__RCSID("$NetBSD: util.c,v 1.6 2008/04/28 20:24:17 martin Exp $"); 61#endif /* not lint */ 62 63#include <sys/types.h> 64#include <sys/ioctl.h> 65#include <sys/queue.h> 66 67#include <dev/ic/mlxreg.h> 68#include <dev/ic/mlxio.h> 69 70#include <dev/scsipi/scsipi_all.h> 71 72#include <stdio.h> 73#include <stdlib.h> 74#include <string.h> 75#include <unistd.h> 76#include <err.h> 77 78#include "extern.h" 79 80int 81mlx_command(struct mlx_usercommand *mu, int bomb) 82{ 83 int rv; 84 85 if ((rv = ioctl(mlxfd, MLX_COMMAND, mu)) != 0 && bomb) 86 err(EXIT_FAILURE, "cmd 0x%02x failed", 87 mu->mu_command[0]); 88 89 return (rv); 90} 91 92void 93mlx_enquiry(struct mlx_enquiry2 *enq) 94{ 95 struct mlx_usercommand mu; 96 struct mlx_enquiry_old meo; 97 98 memset(&mu, 0, sizeof(mu)); 99 100 mu.mu_datasize = sizeof(*enq); 101 mu.mu_buf = enq; 102 mu.mu_bufptr = 8; 103 mu.mu_bufdir = MU_XFER_IN; 104 mu.mu_command[0] = MLX_CMD_ENQUIRY2; 105 106 mlx_command(&mu, 1); 107 108 /* 109 * If we get back a firmware major of 0, this is (probably) an old 110 * controller, so we need to pull the firmware version from the old 111 * enquiry structure. 112 */ 113 if (enq->me_firmware_id[0] == 0) { 114 memset(&mu, 0, sizeof(mu)); 115 116 mu.mu_datasize = sizeof(meo); 117 mu.mu_buf = &meo; 118 mu.mu_bufptr = 8; 119 mu.mu_bufdir = MU_XFER_IN; 120 mu.mu_command[0] = MLX_CMD_ENQUIRY_OLD; 121 122 mlx_command(&mu, 1); 123 124 enq->me_firmware_id[0] = meo.me_fwmajor; 125 enq->me_firmware_id[1] = meo.me_fwminor; 126 enq->me_firmware_id[2] = 0; 127 enq->me_firmware_id[3] = '0'; 128 } 129} 130 131void 132mlx_configuration(struct mlx_core_cfg *cfg, int wr) 133{ 134 struct mlx_usercommand mu; 135 136 memset(&mu, 0, sizeof(mu)); 137 138 mu.mu_datasize = sizeof(*cfg); 139 mu.mu_buf = cfg; 140 mu.mu_bufptr = 8; 141 mu.mu_bufdir = (wr ? MU_XFER_OUT : MU_XFER_IN); 142 mu.mu_command[0] = (wr ? MLX_CMD_WRITE_CONFIG : MLX_CMD_READ_CONFIG); 143 144 mlx_command(&mu, 1); 145} 146 147int 148mlx_get_device_state(int chan, int targ, struct mlx_phys_drv *pd) 149{ 150 struct mlx_usercommand mu; 151 152 memset(&mu, 0, sizeof(mu)); 153 154 mu.mu_datasize = sizeof(*pd); 155 mu.mu_buf = pd; 156 mu.mu_bufptr = 8; 157 mu.mu_bufdir = MU_XFER_IN; 158 mu.mu_command[0] = MLX_CMD_DEVICE_STATE; 159 mu.mu_command[2] = chan; 160 mu.mu_command[3] = targ; 161 162 return (mlx_command(&mu, 0)); 163} 164 165int 166mlx_scsi_inquiry(int chan, int targ, char **vendor, char **device, 167 char **revision) 168{ 169 struct mlx_usercommand mu; 170 static struct { 171 struct mlx_dcdb dcdb; 172 struct scsipi_inquiry_data inq; 173 } __packed dcdb_cmd; 174 struct scsipi_inquiry *inq_cmd; 175 int rv; 176 177 inq_cmd = (struct scsipi_inquiry *)&dcdb_cmd.dcdb.dcdb_cdb[0]; 178 179 memset(&mu, 0, sizeof(mu)); 180 mu.mu_datasize = sizeof(dcdb_cmd); 181 mu.mu_buf = &dcdb_cmd; 182 mu.mu_command[0] = MLX_CMD_DIRECT_CDB; 183 mu.mu_bufdir = MU_XFER_IN | MU_XFER_OUT; 184 185 memset(&dcdb_cmd, 0, sizeof(dcdb_cmd)); 186 dcdb_cmd.dcdb.dcdb_target = (chan << 4) | targ; 187 dcdb_cmd.dcdb.dcdb_flags = MLX_DCDB_DATA_IN | MLX_DCDB_TIMEOUT_10S; 188 dcdb_cmd.dcdb.dcdb_datasize = sizeof(dcdb_cmd.inq); 189 dcdb_cmd.dcdb.dcdb_length = 6; 190 dcdb_cmd.dcdb.dcdb_sense_length = 40; 191 192 inq_cmd->opcode = INQUIRY; 193 inq_cmd->length = sizeof(dcdb_cmd.inq); 194 195 if ((rv = mlx_command(&mu, 0)) == 0) { 196 *vendor = &dcdb_cmd.inq.vendor[0]; 197 *device = &dcdb_cmd.inq.product[0]; 198 *revision = &dcdb_cmd.inq.revision[0]; 199 } 200 201 return (rv); 202} 203 204void 205mlx_print_phys_drv(struct mlx_phys_drv *pd, int chn, int targ, 206 const char *prefix) 207{ 208 const char *type; 209 char *device, *vendor, *revision; 210 211 switch (pd->pd_flags2 & 0x03) { 212 case MLX_PHYS_DRV_DISK: 213 type = "disk"; 214 break; 215 216 case MLX_PHYS_DRV_SEQUENTIAL: 217 type = "tape"; 218 break; 219 220 case MLX_PHYS_DRV_CDROM: 221 type= "cdrom"; 222 break; 223 224 case MLX_PHYS_DRV_OTHER: 225 default: 226 type = "unknown"; 227 break; 228 } 229 230 printf("%s%s%02d%02d ", prefix, type, chn, targ); 231 232 switch (pd->pd_status) { 233 case MLX_PHYS_DRV_DEAD: 234 printf(" (dead) "); 235 break; 236 237 case MLX_PHYS_DRV_WRONLY: 238 printf(" (write-only) "); 239 break; 240 241 case MLX_PHYS_DRV_ONLINE: 242 printf(" (online) "); 243 break; 244 245 case MLX_PHYS_DRV_STANDBY: 246 printf(" (standby) "); 247 break; 248 249 default: 250 printf(" (0x%02x) ", pd->pd_status); 251 break; 252 } 253 254 printf("\n"); 255 if (verbosity == 0) 256 return; 257 258 printf("%s ", prefix); 259 if (!mlx_scsi_inquiry(chn, targ, &vendor, &device, &revision)) 260 printf("'%8.8s' '%16.16s' '%4.4s'", vendor, device, revision); 261 else 262 printf("<IDENTIFY FAILED>"); 263 264 printf(" %dMB ", pd->pd_config_size / 2048); 265 266 if ((pd->pd_flags2 & MLX_PHYS_DRV_FAST20) != 0) 267 printf(" ultra"); 268 else if ((pd->pd_flags2 & MLX_PHYS_DRV_FAST) != 0) 269 printf(" fast"); 270 271 if ((pd->pd_flags2 & MLX_PHYS_DRV_WIDE) != 0) 272 printf(" wide"); 273 274 if ((pd->pd_flags2 & MLX_PHYS_DRV_SYNC) != 0) 275 printf(" sync"); 276 277 if ((pd->pd_flags2 & MLX_PHYS_DRV_TAG) != 0) 278 printf(" tag-enabled"); 279 280 printf("\n"); 281} 282