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 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*", "*"}, |
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, |
648 nitems(scsi_op_quirk_table), |
649 sizeof(*scsi_op_quirk_table), |
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; |
657 num_ops[1] = nitems(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; |
668 num_ops[0] = nitems(scsi_op_codes); |
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, |
923 nitems(quantum_fireball_entries), |
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, |
934 nitems(sony_mo_entries), |
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, |
944 nitems(hgst_entries), |
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, |
954 nitems(seagate_entries), |
955 /*sense key entries*/NULL, 956 seagate_entries 957 } 958}; 959 |
960const int sense_quirk_table_size = nitems(sense_quirk_table); |
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 |
3196const int asc_table_size = nitems(asc_table); |
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 |
4705 for (i = 0; i < (nitems(scsi_sense_printers)); i++) { |
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 |
5490 num_syncrates = nitems(scsi_syncrates); |
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; |
5522 num_syncrates = nitems(scsi_syncrates); |
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 |
6568 num_proto_entries = nitems(scsi_proto_map); |
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, |
7288 nitems(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; |
7415 table2_size = nitems(scsi_mam_attr_table); |
7416 } else { 7417 table1 = scsi_mam_attr_table; |
7418 table1_size = nitems(scsi_mam_attr_table); |
7419 table2 = user_table; 7420 table2_size = num_user_entries; 7421 } 7422 } else { 7423 table1 = scsi_mam_attr_table; |
7424 table1_size = nitems(scsi_mam_attr_table); |
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 --- |