Deleted Added
full compact
scsi_all.c (298411) scsi_all.c (298431)
1/*-
2 * Implementation of Utility functions for all SCSI device types.
3 *
4 * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs.
5 * Copyright (c) 1997, 1998, 2003 Kenneth D. Merry.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
1/*-
2 * Implementation of Utility functions for all SCSI device types.
3 *
4 * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs.
5 * Copyright (c) 1997, 1998, 2003 Kenneth D. Merry.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_all.c 298411 2016-04-21 15:38:28Z pfg $");
31__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_all.c 298431 2016-04-21 19:40:10Z pfg $");
32
33#include <sys/param.h>
34#include <sys/types.h>
35#include <sys/stdint.h>
36
37#ifdef _KERNEL
38#include <opt_scsi.h>
39

--- 109 unchanged lines hidden (view full) ---

149 * to read CD-DA data. I'm not sure which Plextor CDROM
150 * models support the command, though. I know for sure
151 * that the 4X, 8X, and 12X models do, and presumably the
152 * 12-20X does. I don't know about any earlier models,
153 * though. If anyone has any more complete information,
154 * feel free to change this quirk entry.
155 */
156 {T_CDROM, SIP_MEDIA_REMOVABLE, "PLEXTOR", "CD-ROM PX*", "*"},
32
33#include <sys/param.h>
34#include <sys/types.h>
35#include <sys/stdint.h>
36
37#ifdef _KERNEL
38#include <opt_scsi.h>
39

--- 109 unchanged lines hidden (view full) ---

149 * to read CD-DA data. I'm not sure which Plextor CDROM
150 * models support the command, though. I know for sure
151 * that the 4X, 8X, and 12X models do, and presumably the
152 * 12-20X does. I don't know about any earlier models,
153 * though. If anyone has any more complete information,
154 * feel free to change this quirk entry.
155 */
156 {T_CDROM, SIP_MEDIA_REMOVABLE, "PLEXTOR", "CD-ROM PX*", "*"},
157 sizeof(plextor_cd_ops)/sizeof(struct op_table_entry),
157 nitems(plextor_cd_ops),
158 plextor_cd_ops
159 }
160};
161
162static struct op_table_entry scsi_op_codes[] = {
163 /*
164 * From: http://www.t10.org/lists/op-num.txt
165 * Modifications by Kenneth Merry (ken@FreeBSD.ORG)

--- 474 unchanged lines hidden (view full) ---

640 if (inq_data == NULL) {
641 pd_type = T_DIRECT;
642 match = NULL;
643 } else {
644 pd_type = SID_TYPE(inq_data);
645
646 match = cam_quirkmatch((caddr_t)inq_data,
647 (caddr_t)scsi_op_quirk_table,
158 plextor_cd_ops
159 }
160};
161
162static struct op_table_entry scsi_op_codes[] = {
163 /*
164 * From: http://www.t10.org/lists/op-num.txt
165 * Modifications by Kenneth Merry (ken@FreeBSD.ORG)

--- 474 unchanged lines hidden (view full) ---

640 if (inq_data == NULL) {
641 pd_type = T_DIRECT;
642 match = NULL;
643 } else {
644 pd_type = SID_TYPE(inq_data);
645
646 match = cam_quirkmatch((caddr_t)inq_data,
647 (caddr_t)scsi_op_quirk_table,
648 sizeof(scsi_op_quirk_table)/
648 nitems(scsi_op_quirk_table),
649 sizeof(*scsi_op_quirk_table),
649 sizeof(*scsi_op_quirk_table),
650 sizeof(*scsi_op_quirk_table),
651 scsi_inquiry_match);
652 }
653
654 if (match != NULL) {
655 table[0] = ((struct scsi_op_quirk_entry *)match)->op_table;
656 num_ops[0] = ((struct scsi_op_quirk_entry *)match)->num_ops;
657 table[1] = scsi_op_codes;
650 scsi_inquiry_match);
651 }
652
653 if (match != NULL) {
654 table[0] = ((struct scsi_op_quirk_entry *)match)->op_table;
655 num_ops[0] = ((struct scsi_op_quirk_entry *)match)->num_ops;
656 table[1] = scsi_op_codes;
658 num_ops[1] = sizeof(scsi_op_codes)/sizeof(scsi_op_codes[0]);
657 num_ops[1] = nitems(scsi_op_codes);
659 num_tables = 2;
660 } else {
661 /*
662 * If this is true, we have a vendor specific opcode that
663 * wasn't covered in the quirk table.
664 */
665 if ((opcode > 0xBF) || ((opcode > 0x5F) && (opcode < 0x80)))
666 return("Vendor Specific Command");
667
668 table[0] = scsi_op_codes;
658 num_tables = 2;
659 } else {
660 /*
661 * If this is true, we have a vendor specific opcode that
662 * wasn't covered in the quirk table.
663 */
664 if ((opcode > 0xBF) || ((opcode > 0x5F) && (opcode < 0x80)))
665 return("Vendor Specific Command");
666
667 table[0] = scsi_op_codes;
669 num_ops[0] = sizeof(scsi_op_codes)/sizeof(scsi_op_codes[0]);
668 num_ops[0] = nitems(scsi_op_codes);
670 num_tables = 1;
671 }
672
673 /* RBC is 'Simplified' Direct Access Device */
674 if (pd_type == T_RBC)
675 pd_type = T_DIRECT;
676
677 /* Map NODEVICE to Direct Access Device to handle REPORT LUNS, etc. */

--- 238 unchanged lines hidden (view full) ---

916static struct scsi_sense_quirk_entry sense_quirk_table[] = {
917 {
918 /*
919 * XXX The Quantum Fireball ST and SE like to return 0x04 0x0b
920 * when they really should return 0x04 0x02.
921 */
922 {T_DIRECT, SIP_MEDIA_FIXED, "QUANTUM", "FIREBALL S*", "*"},
923 /*num_sense_keys*/0,
669 num_tables = 1;
670 }
671
672 /* RBC is 'Simplified' Direct Access Device */
673 if (pd_type == T_RBC)
674 pd_type = T_DIRECT;
675
676 /* Map NODEVICE to Direct Access Device to handle REPORT LUNS, etc. */

--- 238 unchanged lines hidden (view full) ---

915static struct scsi_sense_quirk_entry sense_quirk_table[] = {
916 {
917 /*
918 * XXX The Quantum Fireball ST and SE like to return 0x04 0x0b
919 * when they really should return 0x04 0x02.
920 */
921 {T_DIRECT, SIP_MEDIA_FIXED, "QUANTUM", "FIREBALL S*", "*"},
922 /*num_sense_keys*/0,
924 sizeof(quantum_fireball_entries)/sizeof(struct asc_table_entry),
923 nitems(quantum_fireball_entries),
925 /*sense key entries*/NULL,
926 quantum_fireball_entries
927 },
928 {
929 /*
930 * This Sony MO drive likes to return 0x04, 0x00 when it
931 * isn't spun up.
932 */
933 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SONY", "SMO-*", "*"},
934 /*num_sense_keys*/0,
924 /*sense key entries*/NULL,
925 quantum_fireball_entries
926 },
927 {
928 /*
929 * This Sony MO drive likes to return 0x04, 0x00 when it
930 * isn't spun up.
931 */
932 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SONY", "SMO-*", "*"},
933 /*num_sense_keys*/0,
935 sizeof(sony_mo_entries)/sizeof(struct asc_table_entry),
934 nitems(sony_mo_entries),
936 /*sense key entries*/NULL,
937 sony_mo_entries
938 },
939 {
940 /*
941 * HGST vendor-specific error codes
942 */
943 {T_DIRECT, SIP_MEDIA_FIXED, "HGST", "*", "*"},
944 /*num_sense_keys*/0,
935 /*sense key entries*/NULL,
936 sony_mo_entries
937 },
938 {
939 /*
940 * HGST vendor-specific error codes
941 */
942 {T_DIRECT, SIP_MEDIA_FIXED, "HGST", "*", "*"},
943 /*num_sense_keys*/0,
945 sizeof(hgst_entries)/sizeof(struct asc_table_entry),
944 nitems(hgst_entries),
946 /*sense key entries*/NULL,
947 hgst_entries
948 },
949 {
950 /*
951 * SEAGATE vendor-specific error codes
952 */
953 {T_DIRECT, SIP_MEDIA_FIXED, "SEAGATE", "*", "*"},
954 /*num_sense_keys*/0,
945 /*sense key entries*/NULL,
946 hgst_entries
947 },
948 {
949 /*
950 * SEAGATE vendor-specific error codes
951 */
952 {T_DIRECT, SIP_MEDIA_FIXED, "SEAGATE", "*", "*"},
953 /*num_sense_keys*/0,
955 sizeof(seagate_entries)/sizeof(struct asc_table_entry),
954 nitems(seagate_entries),
956 /*sense key entries*/NULL,
957 seagate_entries
958 }
959};
960
955 /*sense key entries*/NULL,
956 seagate_entries
957 }
958};
959
961const int sense_quirk_table_size =
962 sizeof(sense_quirk_table)/sizeof(sense_quirk_table[0]);
960const int sense_quirk_table_size = nitems(sense_quirk_table);
963
964static struct asc_table_entry asc_table[] = {
965 /*
966 * From: http://www.t10.org/lists/asc-num.txt
967 * Modifications by Jung-uk Kim (jkim@FreeBSD.org)
968 */
969 /*
970 * File: ASC-NUM.TXT

--- 2219 unchanged lines hidden (view full) ---

3190 /* DT R M E V */
3191 { SST(0x74, 0x71, SS_RDEF, /* XXX TBD */
3192 "Logical unit access not authorized") },
3193 /* D */
3194 { SST(0x74, 0x79, SS_RDEF, /* XXX TBD */
3195 "Security conflict in translated device") }
3196};
3197
961
962static struct asc_table_entry asc_table[] = {
963 /*
964 * From: http://www.t10.org/lists/asc-num.txt
965 * Modifications by Jung-uk Kim (jkim@FreeBSD.org)
966 */
967 /*
968 * File: ASC-NUM.TXT

--- 2219 unchanged lines hidden (view full) ---

3188 /* DT R M E V */
3189 { SST(0x74, 0x71, SS_RDEF, /* XXX TBD */
3190 "Logical unit access not authorized") },
3191 /* D */
3192 { SST(0x74, 0x79, SS_RDEF, /* XXX TBD */
3193 "Security conflict in translated device") }
3194};
3195
3198const int asc_table_size = sizeof(asc_table)/sizeof(asc_table[0]);
3196const int asc_table_size = nitems(asc_table);
3199
3200struct asc_key
3201{
3202 int asc;
3203 int ascq;
3204};
3205
3206static int

--- 1492 unchanged lines hidden (view full) ---

4699void
4700scsi_sense_desc_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
4701 u_int sense_len, uint8_t *cdb, int cdb_len,
4702 struct scsi_inquiry_data *inq_data,
4703 struct scsi_sense_desc_header *header)
4704{
4705 int i;
4706
3197
3198struct asc_key
3199{
3200 int asc;
3201 int ascq;
3202};
3203
3204static int

--- 1492 unchanged lines hidden (view full) ---

4697void
4698scsi_sense_desc_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
4699 u_int sense_len, uint8_t *cdb, int cdb_len,
4700 struct scsi_inquiry_data *inq_data,
4701 struct scsi_sense_desc_header *header)
4702{
4703 int i;
4704
4707 for (i = 0; i < (sizeof(scsi_sense_printers) /
4708 sizeof(scsi_sense_printers[0])); i++) {
4705 for (i = 0; i < (nitems(scsi_sense_printers)); i++) {
4709 struct scsi_sense_desc_printer *printer;
4710
4711 printer = &scsi_sense_printers[i];
4712
4713 /*
4714 * The list is sorted, so quit if we've passed our
4715 * descriptor number.
4716 */

--- 768 unchanged lines hidden (view full) ---

5485 * It's a bug if period is zero, but if it is anyway, don't
5486 * die with a divide fault- instead return something which
5487 * 'approximates' async
5488 */
5489 if (period_factor == 0) {
5490 return (3300);
5491 }
5492
4706 struct scsi_sense_desc_printer *printer;
4707
4708 printer = &scsi_sense_printers[i];
4709
4710 /*
4711 * The list is sorted, so quit if we've passed our
4712 * descriptor number.
4713 */

--- 768 unchanged lines hidden (view full) ---

5482 * It's a bug if period is zero, but if it is anyway, don't
5483 * die with a divide fault- instead return something which
5484 * 'approximates' async
5485 */
5486 if (period_factor == 0) {
5487 return (3300);
5488 }
5489
5493 num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]);
5490 num_syncrates = nitems(scsi_syncrates);
5494 /* See if the period is in the "exception" table */
5495 for (i = 0; i < num_syncrates; i++) {
5496
5497 if (period_factor == scsi_syncrates[i].period_factor) {
5498 /* Period in kHz */
5499 return (100000000 / scsi_syncrates[i].period);
5500 }
5501 }

--- 15 unchanged lines hidden (view full) ---

5517 int i;
5518 int num_syncrates;
5519
5520 if (period == 0)
5521 return (~0); /* Async */
5522
5523 /* Adjust for exception table being in 100ths. */
5524 period *= 10;
5491 /* See if the period is in the "exception" table */
5492 for (i = 0; i < num_syncrates; i++) {
5493
5494 if (period_factor == scsi_syncrates[i].period_factor) {
5495 /* Period in kHz */
5496 return (100000000 / scsi_syncrates[i].period);
5497 }
5498 }

--- 15 unchanged lines hidden (view full) ---

5514 int i;
5515 int num_syncrates;
5516
5517 if (period == 0)
5518 return (~0); /* Async */
5519
5520 /* Adjust for exception table being in 100ths. */
5521 period *= 10;
5525 num_syncrates = sizeof(scsi_syncrates) / sizeof(scsi_syncrates[0]);
5522 num_syncrates = nitems(scsi_syncrates);
5526 /* See if the period is in the "exception" table */
5527 for (i = 0; i < num_syncrates; i++) {
5528
5529 if (period <= scsi_syncrates[i].period) {
5530 /* Period in 100ths of ns */
5531 return (scsi_syncrates[i].period_factor);
5532 }
5533 }

--- 1029 unchanged lines hidden (view full) ---

6563 if (error_str != NULL) {
6564 snprintf(error_str, error_str_len,
6565 "%s: transportid_str is NULL", __func__);
6566 }
6567 retval = 1;
6568 goto bailout;
6569 }
6570
5523 /* See if the period is in the "exception" table */
5524 for (i = 0; i < num_syncrates; i++) {
5525
5526 if (period <= scsi_syncrates[i].period) {
5527 /* Period in 100ths of ns */
5528 return (scsi_syncrates[i].period_factor);
5529 }
5530 }

--- 1029 unchanged lines hidden (view full) ---

6560 if (error_str != NULL) {
6561 snprintf(error_str, error_str_len,
6562 "%s: transportid_str is NULL", __func__);
6563 }
6564 retval = 1;
6565 goto bailout;
6566 }
6567
6571 num_proto_entries = sizeof(scsi_proto_map) /
6572 sizeof(scsi_proto_map[0]);
6568 num_proto_entries = nitems(scsi_proto_map);
6573 status = scsi_get_nv(scsi_proto_map, num_proto_entries, tmpstr,
6574 &table_entry, SCSI_NV_FLAG_IG_CASE);
6575 if (status != SCSI_NV_FOUND) {
6576 if (error_str != NULL) {
6577 snprintf(error_str, error_str_len, "%s: %s protocol "
6578 "name %s", __func__,
6579 (status == SCSI_NV_AMBIGUOUS) ? "ambiguous" :
6580 "invalid", tmpstr);

--- 703 unchanged lines hidden (view full) ---

7284
7285 return (NULL);
7286}
7287
7288struct scsi_attrib_table_entry *
7289scsi_get_attrib_entry(uint32_t id)
7290{
7291 return (scsi_find_attrib_entry(scsi_mam_attr_table,
6569 status = scsi_get_nv(scsi_proto_map, num_proto_entries, tmpstr,
6570 &table_entry, SCSI_NV_FLAG_IG_CASE);
6571 if (status != SCSI_NV_FOUND) {
6572 if (error_str != NULL) {
6573 snprintf(error_str, error_str_len, "%s: %s protocol "
6574 "name %s", __func__,
6575 (status == SCSI_NV_AMBIGUOUS) ? "ambiguous" :
6576 "invalid", tmpstr);

--- 703 unchanged lines hidden (view full) ---

7280
7281 return (NULL);
7282}
7283
7284struct scsi_attrib_table_entry *
7285scsi_get_attrib_entry(uint32_t id)
7286{
7287 return (scsi_find_attrib_entry(scsi_mam_attr_table,
7292 sizeof(scsi_mam_attr_table) / sizeof(scsi_mam_attr_table[0]),
7288 nitems(scsi_mam_attr_table),
7293 id));
7294}
7295
7296int
7297scsi_attrib_value_sbuf(struct sbuf *sb, uint32_t valid_len,
7298 struct scsi_mam_attribute_header *hdr, uint32_t output_flags,
7299 char *error_str, size_t error_str_len)
7300{

--- 110 unchanged lines hidden (view full) ---

7411
7412 id = scsi_2btoul(hdr->id);
7413
7414 if (user_table != NULL) {
7415 if (prefer_user_table != 0) {
7416 table1 = user_table;
7417 table1_size = num_user_entries;
7418 table2 = scsi_mam_attr_table;
7289 id));
7290}
7291
7292int
7293scsi_attrib_value_sbuf(struct sbuf *sb, uint32_t valid_len,
7294 struct scsi_mam_attribute_header *hdr, uint32_t output_flags,
7295 char *error_str, size_t error_str_len)
7296{

--- 110 unchanged lines hidden (view full) ---

7407
7408 id = scsi_2btoul(hdr->id);
7409
7410 if (user_table != NULL) {
7411 if (prefer_user_table != 0) {
7412 table1 = user_table;
7413 table1_size = num_user_entries;
7414 table2 = scsi_mam_attr_table;
7419 table2_size = sizeof(scsi_mam_attr_table) /
7420 sizeof(scsi_mam_attr_table[0]);
7415 table2_size = nitems(scsi_mam_attr_table);
7421 } else {
7422 table1 = scsi_mam_attr_table;
7416 } else {
7417 table1 = scsi_mam_attr_table;
7423 table1_size = sizeof(scsi_mam_attr_table) /
7424 sizeof(scsi_mam_attr_table[0]);
7418 table1_size = nitems(scsi_mam_attr_table);
7425 table2 = user_table;
7426 table2_size = num_user_entries;
7427 }
7428 } else {
7429 table1 = scsi_mam_attr_table;
7419 table2 = user_table;
7420 table2_size = num_user_entries;
7421 }
7422 } else {
7423 table1 = scsi_mam_attr_table;
7430 table1_size = sizeof(scsi_mam_attr_table) /
7431 sizeof(scsi_mam_attr_table[0]);
7424 table1_size = nitems(scsi_mam_attr_table);
7432 }
7433
7434 entry = scsi_find_attrib_entry(table1, table1_size, id);
7435 if (entry != NULL) {
7436 scsi_attrib_prefix_sbuf(sb, output_flags, hdr, valid_len,
7437 entry->desc);
7438 if (entry->to_str == NULL)
7439 goto print_default;

--- 1399 unchanged lines hidden ---
7425 }
7426
7427 entry = scsi_find_attrib_entry(table1, table1_size, id);
7428 if (entry != NULL) {
7429 scsi_attrib_prefix_sbuf(sb, output_flags, hdr, valid_len,
7430 entry->desc);
7431 if (entry->to_str == NULL)
7432 goto print_default;

--- 1399 unchanged lines hidden ---