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 --- |