454 "ORDERED QUEUE TAG",
455 "IGNORE WIDE RESIDUE",
456 "ACA",
457 "LOGICAL UNIT RESET"
458 };
459
460 if (msg < 23) {
461 return (imsgs[msg]);
462 } else if (IS_IDENTIFY_MSG(msg)) {
463 return ("IDENTIFY");
464 } else if (IS_2BYTE_MSG(msg) &&
465 (int)((msg) & 0xF) < (sizeof (imsgs_2) / sizeof (char *))) {
466 return (imsgs_2[msg & 0xF]);
467 } else {
468 return ("<unknown msg>");
469 }
470
471 }
472
473 char *
474 scsi_cname(uchar_t cmd, register char **cmdvec)
475 {
476 while (*cmdvec != (char *)0) {
477 if (cmd == **cmdvec) {
478 return ((char *)((long)(*cmdvec)+1));
479 }
480 cmdvec++;
481 }
482 return (sprintf(scsi_tmpname, "<undecoded cmd 0x%x>", cmd));
483 }
484
485 char *
486 scsi_cmd_name(uchar_t cmd, struct scsi_key_strings *cmdlist, char *tmpstr)
487 {
488 int i = 0;
489
490 while (cmdlist[i].key != -1) {
491 if (cmd == cmdlist[i].key) {
492 return ((char *)cmdlist[i].message);
493 }
494 i++;
495 }
496 return (sprintf(tmpstr, "<undecoded cmd 0x%x>", cmd));
497 }
498
499 static struct scsi_asq_key_strings extended_sense_list[] = {
1008 if ((asc == extended_sense_list[i].asc) &&
1009 ((ascq == extended_sense_list[i].ascq) ||
1010 (extended_sense_list[i].ascq == 0xffff))) {
1011 return ((char *)extended_sense_list[i].message);
1012 }
1013 i++;
1014 }
1015 return (sprintf(tmpstr, "<vendor unique code 0x%x>", asc));
1016 }
1017
1018 char *
1019 scsi_sname(uchar_t sense_key)
1020 {
1021 if (sense_key >= (uchar_t)(NUM_SENSE_KEYS+NUM_IMPL_SENSE_KEYS)) {
1022 return ("<unknown sense key>");
1023 } else {
1024 return (sense_keys[sense_key]);
1025 }
1026 }
1027
1028
1029 /*
1030 * Print a piece of inquiry data- cleaned up for non-printable characters.
1031 */
1032 static void
1033 inq_fill(char *p, int l, char *s)
1034 {
1035 register unsigned i = 0;
1036 char c;
1037
1038 if (!p)
1039 return;
1040
1041 while (i++ < l) {
1042 /* clean string of non-printing chars */
1043 if ((c = *p++) < ' ' || c >= 0177) {
1044 c = ' ';
1045 }
1046 *s++ = c;
1047 }
1048 *s++ = 0;
1049 }
1050
1051 static char *
1052 scsi_asc_search(uint_t asc, uint_t ascq,
1053 struct scsi_asq_key_strings *list)
1054 {
1055 int i = 0;
1056
1057 while (list[i].asc != 0xffff) {
1058 if ((asc == list[i].asc) &&
1059 ((ascq == list[i].ascq) ||
1060 (list[i].ascq == 0xffff))) {
1061 return ((char *)list[i].message);
1062 }
1063 i++;
1064 }
1065 return (NULL);
1066 }
1067
1068 static char *
1069 scsi_asc_ascq_name(uint_t asc, uint_t ascq, char *tmpstr,
1070 struct scsi_asq_key_strings *list)
1071 {
1072 char *message;
1073
1074 if (list) {
1075 if (message = scsi_asc_search(asc, ascq, list)) {
1076 return (message);
1077 }
1078 }
1079 if (message = scsi_asc_search(asc, ascq, extended_sense_list)) {
1080 return (message);
1081 }
1082
1083 return (sprintf(tmpstr, "<vendor unique code 0x%x>", asc));
1084 }
1085
1086 /*
1087 * The first part/column of the error message will be at least this length.
1088 * This number has been calculated so that each line fits in 80 chars.
1089 */
1090 #define SCSI_ERRMSG_COLUMN_LEN 42
1091 #define SCSI_ERRMSG_BUF_LEN 256
1092
1093 void
1094 scsi_generic_errmsg(struct scsi_device *devp, char *label, int severity,
1095 daddr_t blkno, daddr_t err_blkno,
1096 uchar_t cmd_name, struct scsi_key_strings *cmdlist,
1097 uint8_t *sensep, struct scsi_asq_key_strings *asc_list,
1098 char *(*decode_fru)(struct scsi_device *, char *, int, uchar_t))
1099 {
1100 uchar_t com;
1101 static char buf[SCSI_ERRMSG_BUF_LEN];
1102 static char buf1[SCSI_ERRMSG_BUF_LEN];
1103 static char tmpbuf[64];
1104 static char pad[SCSI_ERRMSG_COLUMN_LEN];
1105 dev_info_t *dev = devp->sd_dev;
1106 static char *error_classes[] = {
1107 "All", "Unknown", "Informational",
1108 "Recovered", "Retryable", "Fatal"
1109 };
1110 uchar_t sense_key, asc, ascq, fru_code;
1111 uchar_t *fru_code_ptr;
1112 int i, buflen;
1113
1114 mutex_enter(&scsi_log_mutex);
1115
1116 /*
1117 * We need to put our space padding code because kernel version
1118 * of sprintf(9F) doesn't support %-<number>s type of left alignment.
1119 */
1120 for (i = 0; i < SCSI_ERRMSG_COLUMN_LEN; i++) {
1121 pad[i] = ' ';
1122 }
1123
1124 bzero(buf, SCSI_ERRMSG_BUF_LEN);
1125 com = cmd_name;
1126 (void) sprintf(buf, "Error for Command: %s",
1127 scsi_cmd_name(com, cmdlist, tmpbuf));
1128 buflen = strlen(buf);
1129 if (buflen < SCSI_ERRMSG_COLUMN_LEN) {
1130 pad[SCSI_ERRMSG_COLUMN_LEN - buflen] = '\0';
1131 (void) sprintf(&buf[buflen], "%s Error Level: %s",
1132 pad, error_classes[severity]);
1133 pad[SCSI_ERRMSG_COLUMN_LEN - buflen] = ' ';
1134 } else {
1135 (void) sprintf(&buf[buflen], " Error Level: %s",
1136 error_classes[severity]);
1137 }
1138 impl_scsi_log(dev, label, CE_WARN, buf);
1139
1140 if (blkno != -1 || err_blkno != -1 &&
1141 ((com & 0xf) == SCMD_READ) || ((com & 0xf) == SCMD_WRITE)) {
1142 bzero(buf, SCSI_ERRMSG_BUF_LEN);
1143 (void) sprintf(buf, "Requested Block: %ld", blkno);
1144 buflen = strlen(buf);
1145 if (buflen < SCSI_ERRMSG_COLUMN_LEN) {
1146 pad[SCSI_ERRMSG_COLUMN_LEN - buflen] = '\0';
1147 (void) sprintf(&buf[buflen], "%s Error Block: %ld\n",
1148 pad, err_blkno);
1149 pad[SCSI_ERRMSG_COLUMN_LEN - buflen] = ' ';
1150 } else {
1151 (void) sprintf(&buf[buflen], " Error Block: %ld\n",
1152 err_blkno);
1153 }
1154 impl_scsi_log(dev, label, CE_CONT, buf);
1155 }
1156
1157 bzero(buf, SCSI_ERRMSG_BUF_LEN);
1158 (void) strcpy(buf, "Vendor: ");
1159 inq_fill(devp->sd_inq->inq_vid, 8, &buf[strlen(buf)]);
1160 buflen = strlen(buf);
1161 if (buflen < SCSI_ERRMSG_COLUMN_LEN) {
1162 pad[SCSI_ERRMSG_COLUMN_LEN - buflen] = '\0';
1163 (void) sprintf(&buf[strlen(buf)], "%s Serial Number: ", pad);
1164 pad[SCSI_ERRMSG_COLUMN_LEN - buflen] = ' ';
1165 } else {
1166 (void) sprintf(&buf[strlen(buf)], " Serial Number: ");
1167 }
1168 inq_fill(devp->sd_inq->inq_serial, 12, &buf[strlen(buf)]);
1169 impl_scsi_log(dev, label, CE_CONT, "%s\n", buf);
1170
1171 if (sensep) {
1172 sense_key = scsi_sense_key(sensep);
1173 asc = scsi_sense_asc(sensep);
1174 ascq = scsi_sense_ascq(sensep);
1175 scsi_ext_sense_fields(sensep, SENSE_LENGTH,
1176 NULL, NULL, &fru_code_ptr, NULL, NULL);
1177 fru_code = (fru_code_ptr ? *fru_code_ptr : 0);
1178
1179 bzero(buf, SCSI_ERRMSG_BUF_LEN);
1180 (void) sprintf(buf, "Sense Key: %s\n",
1181 sense_keys[sense_key]);
1182 impl_scsi_log(dev, label, CE_CONT, buf);
1183
1184 bzero(buf, SCSI_ERRMSG_BUF_LEN);
1185 if ((fru_code != 0) &&
1186 (decode_fru != NULL)) {
1187 (*decode_fru)(devp, buf, SCSI_ERRMSG_BUF_LEN,
1188 fru_code);
1189 if (buf[0] != NULL) {
1190 bzero(buf1, SCSI_ERRMSG_BUF_LEN);
1191 (void) sprintf(&buf1[strlen(buf1)],
1192 "ASC: 0x%x (%s)", asc,
1193 scsi_asc_ascq_name(asc, ascq,
1194 tmpbuf, asc_list));
1195 buflen = strlen(buf1);
1196 if (buflen < SCSI_ERRMSG_COLUMN_LEN) {
1197 pad[SCSI_ERRMSG_COLUMN_LEN - buflen] =
1198 '\0';
1199 (void) sprintf(&buf1[buflen],
1200 "%s ASCQ: 0x%x", pad, ascq);
1201 } else {
1202 (void) sprintf(&buf1[buflen],
1203 " ASCQ: 0x%x", ascq);
1204 }
1205 impl_scsi_log(dev,
1206 label, CE_CONT, "%s\n", buf1);
1207 impl_scsi_log(dev,
1208 label, CE_CONT, "FRU: 0x%x (%s)\n",
1209 fru_code, buf);
1210 mutex_exit(&scsi_log_mutex);
1211 return;
1212 }
1213 }
1214 (void) sprintf(&buf[strlen(buf)],
1215 "ASC: 0x%x (%s), ASCQ: 0x%x, FRU: 0x%x",
1216 asc, scsi_asc_ascq_name(asc, ascq, tmpbuf, asc_list),
1217 ascq, fru_code);
1218 impl_scsi_log(dev, label, CE_CONT, "%s\n", buf);
1219 }
1220 mutex_exit(&scsi_log_mutex);
1221 }
1222
1223 void
1224 scsi_vu_errmsg(struct scsi_device *devp, struct scsi_pkt *pkt, char *label,
1225 int severity, daddr_t blkno, daddr_t err_blkno,
1226 struct scsi_key_strings *cmdlist, struct scsi_extended_sense *sensep,
1227 struct scsi_asq_key_strings *asc_list,
1228 char *(*decode_fru)(struct scsi_device *, char *, int, uchar_t))
1229 {
1230 uchar_t com;
1231
1232 com = ((union scsi_cdb *)pkt->pkt_cdbp)->scc_cmd;
1233
1234 scsi_generic_errmsg(devp, label, severity, blkno, err_blkno,
1235 com, cmdlist, (uint8_t *)sensep, asc_list, decode_fru);
1236
1237
1238 }
1239
1240 void
1241 scsi_errmsg(struct scsi_device *devp, struct scsi_pkt *pkt, char *label,
1242 int severity, daddr_t blkno, daddr_t err_blkno,
1243 struct scsi_key_strings *cmdlist, struct scsi_extended_sense *sensep)
1244 {
1245 scsi_vu_errmsg(devp, pkt, label, severity, blkno,
1246 err_blkno, cmdlist, sensep, NULL, NULL);
1247 }
1248
1249 /*PRINTFLIKE4*/
1250 void
1251 scsi_log(dev_info_t *dev, char *label, uint_t level,
1252 const char *fmt, ...)
1253 {
1254 va_list ap;
1255
1256 va_start(ap, fmt);
1257 mutex_enter(&scsi_log_mutex);
1258 v_scsi_log(dev, label, level, fmt, ap);
1259 mutex_exit(&scsi_log_mutex);
1260 va_end(ap);
1261 }
1262
1263 /*PRINTFLIKE4*/
1264 static void
1265 impl_scsi_log(dev_info_t *dev, char *label, uint_t level,
1266 const char *fmt, ...)
1267 {
1268 va_list ap;
1269
1270 ASSERT(mutex_owned(&scsi_log_mutex));
1271
1272 va_start(ap, fmt);
1273 v_scsi_log(dev, label, level, fmt, ap);
1274 va_end(ap);
1275 }
1276
1277
1278 char *ddi_pathname(dev_info_t *dip, char *path);
1279
1280 /*PRINTFLIKE4*/
1281 static void
1282 v_scsi_log(dev_info_t *dev, char *label, uint_t level,
1283 const char *fmt, va_list ap)
1284 {
1285 static char name[256];
1286 int log_only = 0;
1287 int boot_only = 0;
1288 int console_only = 0;
1289
1290 ASSERT(mutex_owned(&scsi_log_mutex));
1291
1292 if (dev) {
1293 if (level == CE_PANIC || level == CE_WARN ||
1294 level == CE_NOTE) {
1295 (void) sprintf(name, "%s (%s%d):\n",
1296 ddi_pathname(dev, scsi_log_buffer),
1297 label, ddi_get_instance(dev));
1298 } else if (level >= (uint_t)SCSI_DEBUG) {
1299 (void) sprintf(name,
1300 "%s%d:", label, ddi_get_instance(dev));
1301 } else {
1302 name[0] = '\0';
1303 }
1304 } else {
1305 (void) sprintf(name, "%s:", label);
1306 }
1307
1308 (void) vsprintf(scsi_log_buffer, fmt, ap);
1309
1310 switch (scsi_log_buffer[0]) {
1311 case '!':
1312 log_only = 1;
1313 break;
1314 case '?':
1315 boot_only = 1;
1316 break;
1317 case '^':
1318 console_only = 1;
1319 break;
1320 }
1321
1322 switch (level) {
1323 case CE_NOTE:
1324 level = CE_CONT;
1325 /* FALLTHROUGH */
1326 case CE_CONT:
1327 case CE_WARN:
1328 case CE_PANIC:
1329 if (boot_only) {
1330 cmn_err(level, "?%s\t%s", name, &scsi_log_buffer[1]);
1331 } else if (console_only) {
1332 cmn_err(level, "^%s\t%s", name, &scsi_log_buffer[1]);
1333 } else if (log_only) {
1334 cmn_err(level, "!%s\t%s", name, &scsi_log_buffer[1]);
1335 } else {
1336 cmn_err(level, "%s\t%s", name, scsi_log_buffer);
1337 }
1338 break;
1339 case (uint_t)SCSI_DEBUG:
1340 default:
1341 cmn_err(CE_CONT, "^DEBUG: %s\t%s", name, scsi_log_buffer);
1342 break;
1343 }
1344 }
1345
1346 /*
1347 * Lookup the 'prop_name' string array property and walk thru its list of
1348 * tuple values looking for a tuple who's VID/PID string (first part of tuple)
1349 * matches the inquiry VID/PID information for the scsi_device. On a match,
1350 * return a duplicate of the second part of the tuple. If no match is found,
1351 * return NULL. On non-NULL return, caller is responsible for freeing return
1352 * result via:
1353 * kmem_free(string, strlen(string) + 1);
1354 *
1355 * This interface can either be used directly, or indirectly by
1356 * scsi_get_device_type_scsi_options.
1357 */
1358 char *
1359 scsi_get_device_type_string(char *prop_name,
1360 dev_info_t *dip, struct scsi_device *devp)
1361 {
|
454 "ORDERED QUEUE TAG",
455 "IGNORE WIDE RESIDUE",
456 "ACA",
457 "LOGICAL UNIT RESET"
458 };
459
460 if (msg < 23) {
461 return (imsgs[msg]);
462 } else if (IS_IDENTIFY_MSG(msg)) {
463 return ("IDENTIFY");
464 } else if (IS_2BYTE_MSG(msg) &&
465 (int)((msg) & 0xF) < (sizeof (imsgs_2) / sizeof (char *))) {
466 return (imsgs_2[msg & 0xF]);
467 } else {
468 return ("<unknown msg>");
469 }
470
471 }
472
473 char *
474 scsi_cname(uchar_t cmd, char **cmdvec)
475 {
476 while (*cmdvec != NULL) {
477 if (cmd == **cmdvec)
478 return ((char *)(uintptr_t)(*cmdvec + 1));
479 cmdvec++;
480 }
481 return (sprintf(scsi_tmpname, "<undecoded cmd 0x%x>", cmd));
482 }
483
484 char *
485 scsi_cmd_name(uchar_t cmd, struct scsi_key_strings *cmdlist, char *tmpstr)
486 {
487 int i = 0;
488
489 while (cmdlist[i].key != -1) {
490 if (cmd == cmdlist[i].key) {
491 return ((char *)cmdlist[i].message);
492 }
493 i++;
494 }
495 return (sprintf(tmpstr, "<undecoded cmd 0x%x>", cmd));
496 }
497
498 static struct scsi_asq_key_strings extended_sense_list[] = {
1007 if ((asc == extended_sense_list[i].asc) &&
1008 ((ascq == extended_sense_list[i].ascq) ||
1009 (extended_sense_list[i].ascq == 0xffff))) {
1010 return ((char *)extended_sense_list[i].message);
1011 }
1012 i++;
1013 }
1014 return (sprintf(tmpstr, "<vendor unique code 0x%x>", asc));
1015 }
1016
1017 char *
1018 scsi_sname(uchar_t sense_key)
1019 {
1020 if (sense_key >= (uchar_t)(NUM_SENSE_KEYS+NUM_IMPL_SENSE_KEYS)) {
1021 return ("<unknown sense key>");
1022 } else {
1023 return (sense_keys[sense_key]);
1024 }
1025 }
1026
1027 static char *
1028 scsi_asc_search(uint_t asc, uint_t ascq,
1029 struct scsi_asq_key_strings *list)
1030 {
1031 int i = 0;
1032
1033 while (list[i].asc != 0xffff) {
1034 if ((asc == list[i].asc) &&
1035 ((ascq == list[i].ascq) ||
1036 (list[i].ascq == 0xffff))) {
1037 return ((char *)list[i].message);
1038 }
1039 i++;
1040 }
1041 return (NULL);
1042 }
1043
1044 static char *
1045 scsi_asc_ascq_name(uint_t asc, uint_t ascq, char *tmpstr,
1046 struct scsi_asq_key_strings *list)
1047 {
1048 char *message;
1049
1050 if (list) {
1051 if (message = scsi_asc_search(asc, ascq, list)) {
1052 return (message);
1053 }
1054 }
1055 if (message = scsi_asc_search(asc, ascq, extended_sense_list)) {
1056 return (message);
1057 }
1058
1059 return (sprintf(tmpstr, "<vendor unique code 0x%x>", asc));
1060 }
1061
1062 #define SCSI_LOGBUF_LEN 512
1063
1064 void
1065 scsi_generic_errmsg(struct scsi_device *devp, char *label, int severity,
1066 daddr_t blkno, daddr_t err_blkno,
1067 uchar_t cmd_name, struct scsi_key_strings *cmdlist,
1068 uint8_t *sensep, struct scsi_asq_key_strings *asc_list,
1069 char *(*decode_fru)(struct scsi_device *, char *, int, uchar_t))
1070 {
1071 char cmdbuf[SCSI_LOGBUF_LEN];
1072 char blkbuf[SCSI_LOGBUF_LEN];
1073 char sensebuf[SCSI_LOGBUF_LEN];
1074 char frubuf[SCSI_LOGBUF_LEN];
1075 char tmpbuf[SCSI_LOGBUF_LEN];
1076 static char *error_classes[] = {
1077 "All", "Unknown", "Informational",
1078 "Recovered", "Retryable", "Fatal"
1079 };
1080
1081 mutex_enter(&scsi_log_mutex);
1082
1083 (void) snprintf(cmdbuf, sizeof (cmdbuf), "%s: cmd=%s",
1084 error_classes[severity], scsi_cmd_name(cmd_name, cmdlist, tmpbuf));
1085
1086 blkbuf[0] = '\0';
1087 if ((blkno != -1 || err_blkno != -1) &&
1088 ((cmd_name & 0xf) == SCMD_READ || (cmd_name & 0xf) == SCMD_WRITE)) {
1089 (void) snprintf(blkbuf, sizeof (blkbuf),
1090 " (reqblk=%ld errblk=%ld)", blkno, err_blkno);
1091 }
1092
1093 sensebuf[0] = '\0';
1094 frubuf[0] = '\0';
1095 if (sensep != NULL) {
1096 uchar_t sense_key, asc, ascq, fru_code;
1097 uchar_t *fru_code_ptr;
1098
1099 sense_key = scsi_sense_key(sensep);
1100 asc = scsi_sense_asc(sensep);
1101 ascq = scsi_sense_ascq(sensep);
1102 scsi_ext_sense_fields(sensep, SENSE_LENGTH,
1103 NULL, NULL, &fru_code_ptr, NULL, NULL);
1104
1105 (void) snprintf(sensebuf, sizeof (sensebuf),
1106 " key=%s asc/ascq=0x%x/0x%x (\"%s\")",
1107 sense_keys[sense_key], asc, ascq,
1108 scsi_asc_ascq_name(asc, ascq, tmpbuf, asc_list));
1109
1110 fru_code = (fru_code_ptr != NULL ? *fru_code_ptr : 0);
1111 if (fru_code != 0 &&
1112 decode_fru != NULL) {
1113 (*decode_fru)(devp, tmpbuf, sizeof (tmpbuf), fru_code);
1114 if (tmpbuf[0] != '\0') {
1115 (void) snprintf(frubuf, sizeof (frubuf),
1116 " fru=0x%x (\"%s\")", fru_code, tmpbuf);
1117 }
1118 }
1119 }
1120
1121 impl_scsi_log(devp->sd_dev, label, CE_WARN, "!%s%s%s%s",
1122 cmdbuf, blkbuf, sensebuf, frubuf);
1123
1124 mutex_exit(&scsi_log_mutex);
1125 }
1126
1127 void
1128 scsi_vu_errmsg(struct scsi_device *devp, struct scsi_pkt *pkt, char *label,
1129 int severity, daddr_t blkno, daddr_t err_blkno,
1130 struct scsi_key_strings *cmdlist, struct scsi_extended_sense *sensep,
1131 struct scsi_asq_key_strings *asc_list,
1132 char *(*decode_fru)(struct scsi_device *, char *, int, uchar_t))
1133 {
1134 uchar_t com;
1135
1136 com = ((union scsi_cdb *)pkt->pkt_cdbp)->scc_cmd;
1137
1138 scsi_generic_errmsg(devp, label, severity, blkno, err_blkno,
1139 com, cmdlist, (uint8_t *)sensep, asc_list, decode_fru);
1140 }
1141
1142 void
1143 scsi_errmsg(struct scsi_device *devp, struct scsi_pkt *pkt, char *label,
1144 int severity, daddr_t blkno, daddr_t err_blkno,
1145 struct scsi_key_strings *cmdlist, struct scsi_extended_sense *sensep)
1146 {
1147 scsi_vu_errmsg(devp, pkt, label, severity, blkno,
1148 err_blkno, cmdlist, sensep, NULL, NULL);
1149 }
1150
1151 /*PRINTFLIKE4*/
1152 void
1153 scsi_log(dev_info_t *dev, char *label, uint_t level,
1154 const char *fmt, ...)
1155 {
1156 va_list ap;
1157
1158 va_start(ap, fmt);
1159 mutex_enter(&scsi_log_mutex);
1160 v_scsi_log(dev, label, level, fmt, ap);
1161 mutex_exit(&scsi_log_mutex);
1162 va_end(ap);
1163 }
1164
1165 /*PRINTFLIKE4*/
1166 static void
1167 impl_scsi_log(dev_info_t *dev, char *label, uint_t level,
1168 const char *fmt, ...)
1169 {
1170 va_list ap;
1171
1172 ASSERT(mutex_owned(&scsi_log_mutex));
1173
1174 va_start(ap, fmt);
1175 v_scsi_log(dev, label, level, fmt, ap);
1176 va_end(ap);
1177 }
1178
1179 /*PRINTFLIKE4*/
1180 static void
1181 v_scsi_log(dev_info_t *dev, char *label, uint_t level,
1182 const char *fmt, va_list ap)
1183 {
1184 static char name[256];
1185 int log_only = 0;
1186 int boot_only = 0;
1187 int console_only = 0;
1188
1189 ASSERT(mutex_owned(&scsi_log_mutex));
1190
1191 if (dev != NULL) {
1192 if (level == CE_PANIC || level == CE_WARN ||
1193 level == CE_NOTE || level >= (uint_t)SCSI_DEBUG) {
1194 (void) snprintf(name, sizeof (name), "%s%d: ",
1195 ddi_driver_name(dev), ddi_get_instance(dev));
1196 } else {
1197 name[0] = '\0';
1198 }
1199 } else {
1200 (void) sprintf(name, "%s: ", label);
1201 }
1202
1203 (void) vsprintf(scsi_log_buffer, fmt, ap);
1204
1205 switch (scsi_log_buffer[0]) {
1206 case '!':
1207 log_only = 1;
1208 break;
1209 case '?':
1210 boot_only = 1;
1211 break;
1212 case '^':
1213 console_only = 1;
1214 break;
1215 }
1216
1217 switch (level) {
1218 case CE_NOTE:
1219 level = CE_CONT;
1220 /* FALLTHROUGH */
1221 case CE_CONT:
1222 case CE_WARN:
1223 case CE_PANIC:
1224 if (boot_only) {
1225 cmn_err(level, "?%s%s", name, &scsi_log_buffer[1]);
1226 } else if (console_only) {
1227 cmn_err(level, "^%s%s", name, &scsi_log_buffer[1]);
1228 } else if (log_only) {
1229 cmn_err(level, "!%s%s", name, &scsi_log_buffer[1]);
1230 } else {
1231 cmn_err(level, "%s%s", name, scsi_log_buffer);
1232 }
1233 break;
1234 case (uint_t)SCSI_DEBUG:
1235 default:
1236 cmn_err(CE_CONT, "?DEBUG: %s%s", name, scsi_log_buffer);
1237 break;
1238 }
1239 }
1240
1241 /*
1242 * Lookup the 'prop_name' string array property and walk thru its list of
1243 * tuple values looking for a tuple who's VID/PID string (first part of tuple)
1244 * matches the inquiry VID/PID information for the scsi_device. On a match,
1245 * return a duplicate of the second part of the tuple. If no match is found,
1246 * return NULL. On non-NULL return, caller is responsible for freeing return
1247 * result via:
1248 * kmem_free(string, strlen(string) + 1);
1249 *
1250 * This interface can either be used directly, or indirectly by
1251 * scsi_get_device_type_scsi_options.
1252 */
1253 char *
1254 scsi_get_device_type_string(char *prop_name,
1255 dev_info_t *dip, struct scsi_device *devp)
1256 {
|