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