fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
f645cd15cd9c30aa3b568ad85bd8a63996112c4bMilan Jurik * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern int rand_r(unsigned int *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int wait_random_time(void);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void string_dump(char *hdr, uchar_t *src, int nbytes, int format,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int issue_uscsi_cmd(int file, struct uscsi_cmd *command, int flag);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get the system time and use "system seconds"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * as 'seed' to generate a random number. Then,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wait between 1/10 - 1/2 seconds before retry.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Get the current process id and ex-or it with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the seed so that the random number is always
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * different even in case of multiple processes
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * generate a random number at the same time.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get a random number. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Special string dump for error message
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestring_dump(char *hdr, uchar_t *src, int nbytes, int format, char msg_string[])
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char s[256];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte assert(format == HEX_ONLY || format == HEX_ASCII);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (p = s; *p; p++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (nbytes > 0) {
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (void) sprintf(&msg_string[strlen(msg_string)], "%s", p);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < n; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = BYTES_PER_LINE-n; i > 0; i--) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < n; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(&msg_string[strlen(msg_string)], "\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return a pointer to a string telling us the name of the command.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char *
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * Names of commands. Must have SCMD_UNKNOWN at end of list.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik register struct scsi_command_name *c;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[0].command = SCMD_TEST_UNIT_READY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[0].name = MSGSTR(61, "Test Unit Ready");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[1].name = MSGSTR(110, "Format");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[2].command = SCMD_REASSIGN_BLOCK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[2].name = MSGSTR(77, "Reassign Block");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[4].name = MSGSTR(54, "Write");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[5].name = MSGSTR(79, "Read(10 Byte)");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[6].name = MSGSTR(51, "Write(10 Byte)");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[7].command = SCMD_MODE_SELECT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[7].name = MSGSTR(97, "Mode Select");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[8].name = MSGSTR(95, "Mode Sense");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[9].command = SCMD_REASSIGN_BLOCK;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[9].name = MSGSTR(77, "Reassign Block");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[10].command = SCMD_REQUEST_SENSE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[10].name = MSGSTR(74, "Request Sense");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[11].command = SCMD_READ_DEFECT_LIST;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[11].name = MSGSTR(80, "Read Defect List");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[12].name = MSGSTR(102, "Inquiry");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[13].command = SCMD_WRITE_BUFFER;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[13].name = MSGSTR(53, "Write Buffer");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[14].command = SCMD_READ_BUFFER;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[14].name = MSGSTR(82, "Read Buffer");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[15].command = SCMD_START_STOP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[15].name = MSGSTR(67, "Start/Stop");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[16].name = MSGSTR(72, "Reserve");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[17].name = MSGSTR(75, "Release");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[18].command = SCMD_MODE_SENSE_G1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[18].name = MSGSTR(94, "Mode Sense(10 Byte)");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[19].command = SCMD_MODE_SELECT_G1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[19].name = MSGSTR(96, "Mode Select(10 Byte)");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[20].command = SCMD_READ_CAPACITY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[20].name = MSGSTR(81, "Read Capacity");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[21].command = SCMD_SYNC_CACHE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[21].name = MSGSTR(64, "Synchronize Cache");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[22].command = SCMD_READ_DEFECT_LIST;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[22].name = MSGSTR(80, "Read Defect List");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[23].name = MSGSTR(108, "Get Diagnostic");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[24].name = MSGSTR(69, "Set Diagnostic");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[25].command = SCMD_PERS_RESERV_IN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[25].name = MSGSTR(10500, "Persistent Reserve In");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[26].command = SCMD_PERS_RESERV_OUT;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[26].name = MSGSTR(10501, "Persistent Reserve out");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[27].name = MSGSTR(10502, "Log Sense");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_command_names[28].name = MSGSTR(25, "Unknown");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (c = scsi_command_names; c->command != SCMD_UNKNOWN; c++)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (c->name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Function to create error message containing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * scsi request sense information
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortescsi_printerr(struct uscsi_cmd *ucmd, struct scsi_extended_sense *rq,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(msg_string, MSGSTR(91, "No sense error"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(msg_string, MSGSTR(76, "Recoverable error"));
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik "Device Not ready. Error: Random Retry Failed: %s\n."),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(msg_string, MSGSTR(99, "Medium error"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(msg_string, MSGSTR(106, "Hardware error"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(msg_string, MSGSTR(103, "Illegal request"));
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik "Unit attention."
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik "Error: Random Retry Failed.\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(msg_string, MSGSTR(52, "Write protect error"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(msg_string, MSGSTR(131, "Blank check error"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(msg_string, MSGSTR(58, "Vendor unique error"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(msg_string, MSGSTR(123, "Copy aborted error"));
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik "Aborted command. Error: Random Retry Failed.\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(msg_string, MSGSTR(117, "Equal error"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(msg_string, MSGSTR(57, "Volume overflow"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(msg_string, MSGSTR(98, "Miscompare error"));
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik "Reserved value found"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(msg_string, MSGSTR(59, "Unknown error"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte blkno = (rq->es_info_1 << 24) | (rq->es_info_2 << 16) |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(&msg_string[strlen(msg_string)], "\n");
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik "ASC Qualifier: 0x%x\n"),
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * rq->es_add_info[ADD_SENSE_CODE],
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * rq->es_add_info[ADD_SENSE_QUAL_CODE]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte string_dump(MSGSTR(47, " cmd: "), (uchar_t *)ucmd,
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik sizeof (struct uscsi_cmd), HEX_ONLY, msg_string);
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (uchar_t *)rq, 8 + rq->es_add_len, HEX_ONLY, msg_string);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Execute a command and determine the result.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteissue_uscsi_cmd(int file, struct uscsi_cmd *command, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set function flags for driver.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set Automatic request sense enable
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* intialize error message array */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* print command for debug */
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik "SCSI command: %s\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < (int)command->uscsi_cdblen; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) printf("\n\tlen=0x%x bufaddr=0x%x buflen=0x%x"
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik " flags=0x%x\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Default command timeout in case command left it 0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Issue command - finally */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((status != 0) && (command->uscsi_status == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) printf("Unexpected USCSICMD ioctl error: %s\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Just a SCSI error, create error message
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Retry once for Unit Attention,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Not Ready, and Aborted Command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (((char)command->uscsi_rqlen - (char)command->uscsi_rqresid) > 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rqbuf = (struct scsi_extended_sense *)command->uscsi_rqbuf;
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik " Retrying...\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " UNIT_ATTENTION: Retrying...\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " Retrying...\n");
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (struct scsi_extended_sense *)command->uscsi_rqbuf,
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (command->uscsi_rqlen - command->uscsi_rqresid),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Retry 5 times in case of BUSY, and only
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * once for Reservation-conflict, Command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Termination and Queue Full. Wait for
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * random amount of time (between 1/10 - 1/2 secs.)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * between each retry. This random wait is to avoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the multiple threads being executed at the same time
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and also the constraint in Photon IB, where the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * command queue has a depth of one command.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch ((uchar_t)command->uscsi_status & STATUS_MASK) {
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik " STATUS_BUSY: Retrying...\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " RESERVATION_CONFLICT:"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " Retrying...\n");
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik " Retrying...\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " Retrying...\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * MODE SENSE USCSI command
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pc = page control field
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * page_code = Pages to return
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik /* 10 byte Mode Select cmd */
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik union scsi_cdb cdb = {SCMD_MODE_SENSE_G1, 0, 0, 0, 0, 0, 0, 0, 0, 0};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fd < 0) || (buf_ptr == NULL) || (buf_len < 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Just for me - a sanity check */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((page_code > MODEPAGE_ALLPAGES) || (pc > 3) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ucmd.uscsi_rqlen = sizeof (struct scsi_extended_sense);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Bytes actually transfered */
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (void) dump_hex_data(" Mode Sense data: ", buf_ptr,
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik union scsi_cdb cdb = {SCMD_RELEASE, 0, 0, 0, 0, 0};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte P_DPRINTF(" scsi_release: Release: Path %s\n", path);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fd = open(path, O_NDELAY | O_RDONLY)) == -1)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ucmd.uscsi_rqlen = sizeof (struct scsi_extended_sense);
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik union scsi_cdb cdb = {SCMD_RESERVE, 0, 0, 0, 0, 0};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte P_DPRINTF(" scsi_reserve: Reserve: Path %s\n", path);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fd = open(path, O_NDELAY | O_RDONLY)) == -1)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ucmd.uscsi_rqlen = sizeof (struct scsi_extended_sense);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Print out fabric dev dtype
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteprint_fabric_dtype_prop(uchar_t *hba_port_wwn, uchar_t *port_wwn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Check to see if this is the HBA */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (wwnConversion(hba_port_wwn) != wwnConversion(port_wwn)) {
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik " 0x%-2x (Unknown Type)\n"),
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik " 0x%-2x (Unknown Type,Host Bus Adapter)\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteprint_inq_data(char *arg_path, char *path, L_inquiry inq, uchar_t *serial,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Intialize scsi_inquiry_labels_2 with i18n strings
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_2[0] = MSGSTR(138, "Vendor: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_2[1] = MSGSTR(149, "Product: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_2[2] = MSGSTR(139, "Revision: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_2[3] = MSGSTR(143, "Firmware Revision ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_2[4] = MSGSTR(144, "Serial Number ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_2[5] = MSGSTR(140, "Device type: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_2[6] = MSGSTR(145, "Removable media: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_2[7] = MSGSTR(146, "ISO version: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_2[8] = MSGSTR(147, "ECMA version: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_2[9] = MSGSTR(148, "ANSI version: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_2[12] = MSGSTR(150, "Response data format: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_2[13] = MSGSTR(151, "Additional length: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_2[14] = MSGSTR(152, "Relative addressing: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_2[18] = MSGSTR(153, "Linked commands: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_2[19] = MSGSTR(154, "Command queueing: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Intialize scsi_inquiry_labels_3 with i18n strings
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_3[0] = MSGSTR(138, "Vendor: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_3[1] = MSGSTR(149, "Product: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_3[2] = MSGSTR(139, "Revision: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_3[3] = MSGSTR(143, "Firmware Revision ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_3[4] = MSGSTR(144, "Serial Number ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_3[5] = MSGSTR(140, "Device type: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_3[6] = MSGSTR(145, "Removable media: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_3[7] = MSGSTR(2174, "Medium Changer Element: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_3[8] = MSGSTR(146, "ISO version: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_3[9] = MSGSTR(147, "ECMA version: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_3[10] = MSGSTR(148, "ANSI version: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_3[14] = MSGSTR(150, "Response data format: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_3[15] = MSGSTR(151, "Additional length: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_3[18] = MSGSTR(152, "Relative addressing: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_3[19] = MSGSTR(153, "Linked commands: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte scsi_inquiry_labels_3[21] = MSGSTR(154, "Command queueing: ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Intialize scsi_inquiry_labels_3 with i18n strings
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik " (Device might or might not comply to an ANSI version)");
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik " (This code is reserved for historical uses)");
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik " (Device complies to ANSI X3.131-1994 (SCSI-2))");
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik " (Device complies to ANSI INCITS 301-1997 (SPC))");
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik " (Device complies to ANSI INCITS 351-2001 (SPC-2))");
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik " (Device complies to ANSI INCITS 408-2005 (SPC-3))");
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik /* print inquiry information */
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (void) fprintf(stdout, MSGSTR(2185, "\nINQUIRY:\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * arg_path is the path sent to luxadm by the user. if arg_path
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is a /devices path, then we do not need to print out physical
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte print_chars(inq.inq_vid, sizeof (inq.inq_vid), 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte print_chars(inq.inq_pid, sizeof (inq.inq_pid), 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte print_chars(inq.inq_revision, sizeof (inq.inq_revision), 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If Pluto then print
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * firmware rev & serial #.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((inq.inq_dtype & DTYPE_MASK) != DTYPE_ESI) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if we miss both the above if's */
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (void) fprintf(stdout, "%s0x%x (", *p++, (inq.inq_dtype & DTYPE_MASK));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "%s", dtype[inq.inq_dtype & DTYPE_MASK]);
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik } else if ((inq.inq_dtype & DTYPE_MASK) < 0x1f) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, MSGSTR(2186, "Unknown device"));
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (void) fprintf(stdout, "%s%d\n", *p++, inq.inq_iso);
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (void) fprintf(stdout, "%s%d\n", *p++, inq.inq_ecma);
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (void) fprintf(stdout, "%s%d", *p++, inq.inq_ansi);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stdout, "%s", ansi_version[inq.inq_ansi]);
f645cd15cd9c30aa3b568ad85bd8a63996112c4bMilan Jurik (void) fprintf(stdout, " (%s)", MSGSTR(71, "Reserved"));
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (void) fprintf(stdout, "%s%d\n", *p++, inq.inq_rdf);
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik (void) fprintf(stdout, "%s0x%x\n", *p++, inq.inq_len);
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik "%sa\n"), *p++);
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik "%sb\n"), *p++);
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * Now print the vendor-specific data.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik "Number of Ports, Targets: %d,%d\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if ((strstr((char *)inq.inq_pid, "SUN") != 0) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Do hex Dump of rest of the data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " VENDOR-SPECIFIC PARAMETERS\n"));
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik "Byte# Hex Value "
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik " ASCII\n"));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Skip reserved bytes 56-95.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Internal routine to clean up ../'s in paths.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns 0 if no "../" are left.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Wouldn't it be nice if there was a standard system library
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * routine to do this...?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Find the first "/../" in the string */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the [0] character is '/' and "../" immediatly
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * follows it, then we can strip the ../
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * /../../foo/bar == /foo/bar
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now look for the LAST "/" before the "/../"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * as this is the parent dir we can get rid of.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We do this by temporarily truncating the string
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * at the '/' just before "../" using the dotdot pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * hmm, somethings wrong. path looks something
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * like "foo/../bar/" so we can't really deal with it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now truncate the path just after the previous '/'
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and slam everything after the "../" back on
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Follow symbolic links from the logical device name to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the /devfs physical device name. To be complete, we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * handle the case of multiple links. This function
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * either returns NULL (no links, or some other error),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or the physical device name, alloc'ed on the heap.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NOTE: If the path is relative, it will be forced into
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * an absolute path by pre-pending the pwd to it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteget_slash_devices_from_osDevName(char *osDevName, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* return NULL if path is NULL */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * First make sure the path is absolute. If not, make it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If it's already an absolute path, we have no need
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to determine the cwd, so the program should still
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * function within security-by-obscurity directories.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Handle special case of "./foo/bar"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else { /* no "./" so just take everything */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Clean up any "../"s that are in the path
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * source is now an absolute path to the link we're
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * concerned with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In order not to ingore dangling links, check
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the lstat. If lstat succeeds, return the path
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from readlink.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note: osDevName input with /devices path from
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a dangling /dev link doesn't pass lstat so
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NULL is returned.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * lstat succeeded previously and source
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * contains "/devices" then it is
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * dangling node.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik /* check lstat result. */
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik /* and continue */
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * With algorithm that resolves a link
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * and then issues readlink(), should
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * not be reached here.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * when stat succeeds it is not
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * a dangling node so it is not
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik * a special case.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See if there's a real file out there. If not,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we have a dangling link and we ignore it.
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik /* invalid flag */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the file is not a link, we're done one
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * way or the other. If there were links,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return the full pathname of the resulting
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note: All of our temp's are on the stack,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so we have to copy the final result to the heap.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte phys_path = (char *)calloc(1, strlen(source) + 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cnt = readlink(source, scratch, sizeof (scratch));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * scratch is on the heap, and for some reason readlink
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * doesn't always terminate things properly so we have
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to make certain we're properly terminated
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now check to see if the link is relative. If so,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * then we have to append it to the directory
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * which the source was in. (This is non trivial)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tmp == NULL) { /* Whoa! Something's hosed! */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now strip off just the directory path */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* and append the new link */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Note: At this point, source should have "../"s
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * but we'll clean it up in the next pass through
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* It's an absolute link so no worries */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Never reach here */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Input - Space for client_path, phci_path and paddr fields of ioc structure
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * need to be allocated by the caller of this routine.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteget_scsi_vhci_pathinfo(char *dev_path, sv_iocdata_t *ioc, int *path_count)
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik if (strncmp(dev_path, SCSI_VHCI, strlen(SCSI_VHCI)) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((physical_path = get_slash_devices_from_osDevName(
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik dev_path, STANDARD_DEVNAME_HANDLING)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((physical_path = calloc(1, MAXPATHLEN)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* move beyond "/devices" prefix */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* remove :c,raw suffix */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if we didn't find the ':' fine, else truncate */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We'll call ioctl SCSI_VHCI_GET_CLIENT_MULTIPATH_INFO
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * at least twice. The first time will get the path count
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and the size of the ioctl propoerty buffer. The second
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * time will get the path_info for each path.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It's possible that additional paths are added while this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * code is running. If the path count increases between the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 2 ioctl's above, then we'll retry (and assume all is well).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* free physical path */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* 0 buf_size asks driver to return actual size needed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* open the ioctl file descriptor */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fd = open("/devices/scsi_vhci:devctl", O_RDWR)) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte retval = ioctl(fd, SCSI_VHCI_GET_CLIENT_MULTIPATH_INFO, ioc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Make driver put actual # paths in variable */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate space for array of path_info structures.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate enough space for # paths from get_pathcount
fc23152c0568d631ad6c47a2537542c6c8fab02cMilan Jurik calloc(initial_path_count, sizeof (sv_path_info_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate space for path properties returned by driver
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < initial_path_count; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ioc->ret_buf[i].ret_prop.buf_size = prop_buf_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < initial_path_count; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte retval = ioctl(fd, SCSI_VHCI_GET_CLIENT_MULTIPATH_INFO, ioc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < initial_path_count; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* then a new path was added */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we are done with ioctl's, lose the fd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Compare the length num elements from the ioctl response
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and the caller's request - use smaller value.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pathlist_p->path_count now has count returned from ioctl.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ioc.buf_elem has the value the caller provided.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* More paths exist than we allocated space for */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* open controller */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Read the first part of the page to get the page size
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((*pg_buf = (uchar_t *)calloc(1, size)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* read page */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (status = scsi_mode_sense_cmd(fd, *pg_buf, size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Now get the size for all pages */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode_header_ptr = (struct mode_header_g1 *)(void *)*pg_buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((*pg_buf = (uchar_t *)calloc(1, size)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* read all pages */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (status = scsi_mode_sense_cmd(fd, *pg_buf, size,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Dump a structure in hexadecimal.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedump_hex_data(char *hdr, uchar_t *src, int nbytes, int format)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char s[256];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte assert(format == HEX_ONLY || format == HEX_ASCII);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (p = s; *p; p++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (nbytes > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < n; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = BYTES_PER_LINE-n; i > 0; i--) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < n; i++) {