1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/byteorder.h> 27 #include <sys/scsi/scsi.h> 28 29 static int 30 smp_device_prop_update_inqstring(struct smp_device *smp_sd, 31 char *name, char *data, size_t len) 32 { 33 int ilen; 34 char *data_string; 35 int rv; 36 37 /* SMP information follows SCSI INQUIRY rules */ 38 ilen = scsi_ascii_inquiry_len(data, len); 39 ASSERT(ilen <= (int)len); 40 if (ilen <= 0) 41 return (DDI_PROP_INVAL_ARG); 42 43 /* ensure null termination */ 44 data_string = kmem_zalloc(ilen + 1, KM_SLEEP); 45 bcopy(data, data_string, ilen); 46 rv = ndi_prop_update_string(DDI_DEV_T_NONE, 47 smp_sd->smp_sd_dev, name, data_string); 48 kmem_free(data_string, ilen + 1); 49 return (rv); 50 } 51 52 /* 53 * smp_probe: probe device and create inquiry-like properties. 54 */ 55 int 56 smp_probe(struct smp_device *smp_sd) 57 { 58 smp_pkt_t *smp_pkt; 59 smp_pkt_t smp_pkt_data; 60 smp_request_frame_t *srq; 61 smp_response_frame_t *srs; 62 smp_report_manufacturer_info_resp_t *srmir; 63 int ilen, clen; 64 char *component; 65 uint8_t srq_buf[SMP_REQ_MINLEN]; 66 uint8_t srs_buf[SMP_RESP_MINLEN + sizeof (*srmir)]; 67 68 srq = (smp_request_frame_t *)srq_buf; 69 bzero(srq, sizeof (srq_buf)); 70 srq->srf_frame_type = SMP_FRAME_TYPE_REQUEST; 71 srq->srf_function = SMP_FUNC_REPORT_MANUFACTURER_INFO; 72 73 smp_pkt = &smp_pkt_data; 74 bzero(smp_pkt, sizeof (*smp_pkt)); 75 smp_pkt->smp_pkt_address = &smp_sd->smp_sd_address; 76 smp_pkt->smp_pkt_req = (caddr_t)srq; 77 smp_pkt->smp_pkt_reqsize = sizeof (srq_buf); 78 smp_pkt->smp_pkt_rsp = (caddr_t)srs_buf; 79 smp_pkt->smp_pkt_rspsize = sizeof (srs_buf); 80 smp_pkt->smp_pkt_timeout = SMP_DEFAULT_TIMEOUT; 81 82 bzero(srs_buf, sizeof (srs_buf)); 83 84 if (smp_transport(smp_pkt) != DDI_SUCCESS) { 85 /* 86 * The EOVERFLOW should be excluded here, because it indicates 87 * the buffer (defined according to SAS1.1 Spec) to store 88 * response is shorter than transferred message frame. 89 * In this case, the smp device is alive and should be 90 * enumerated. 91 */ 92 if (smp_pkt->smp_pkt_reason != EOVERFLOW) 93 return (DDI_PROBE_FAILURE); 94 } 95 96 /* 97 * NOTE: Deal with old drivers (mpt, mpt_sas) that allocate 98 * 'struct smp_device' on the stack. When these drivers convert to 99 * SCSAv3, the check for a NULL smp_sd_dev can be removed. 100 */ 101 if (smp_sd->smp_sd_dev == NULL) 102 return (DDI_PROBE_SUCCESS); 103 104 /* Save raw response data for devid */ 105 srs = (smp_response_frame_t *)srs_buf; 106 if (srs->srf_result != SMP_RES_FUNCTION_ACCEPTED) 107 return (DDI_PROBE_SUCCESS); 108 109 /* 110 * Convert smp_report_manufacturer_info_resp_t data into properties. 111 * NOTE: since things show up in the oposite order in prtconf, we are 112 * going from detailed information to generic here. 113 */ 114 srmir = (smp_report_manufacturer_info_resp_t *)&srs->srf_data[0]; 115 if (srmir->srmir_sas_1_1_format) { 116 /* Establish 'component' property. */ 117 ilen = scsi_ascii_inquiry_len( 118 srmir->srmir_component_vendor_identification, 119 sizeof (srmir->srmir_component_vendor_identification)); 120 if (ilen > 0) { 121 /* component value format is '%s.%05d.%03d' */ 122 clen = ilen + 1 + 5 + 1 + 3 + 1; 123 component = kmem_zalloc(clen, KM_SLEEP); 124 bcopy(srmir->srmir_component_vendor_identification, 125 component, ilen); 126 (void) snprintf(&component[ilen], clen - ilen, 127 ".%05d.%03d", BE_16(srmir->srmir_component_id), 128 srmir->srmir_component_revision_level); 129 if (ddi_prop_exists(DDI_DEV_T_NONE, smp_sd->smp_sd_dev, 130 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 131 "component") == 0) 132 (void) ndi_prop_update_string(DDI_DEV_T_NONE, 133 smp_sd->smp_sd_dev, "component", component); 134 kmem_free(component, clen); 135 } 136 } 137 /* First one to define the property wins */ 138 if (ddi_prop_exists(DDI_DEV_T_NONE, smp_sd->smp_sd_dev, 139 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, INQUIRY_REVISION_ID) == 0) 140 (void) smp_device_prop_update_inqstring(smp_sd, 141 INQUIRY_REVISION_ID, srmir->srmir_product_revision_level, 142 sizeof (srmir->srmir_product_revision_level)); 143 144 if (ddi_prop_exists(DDI_DEV_T_NONE, smp_sd->smp_sd_dev, 145 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, INQUIRY_PRODUCT_ID) == 0) 146 (void) smp_device_prop_update_inqstring(smp_sd, 147 INQUIRY_PRODUCT_ID, srmir->srmir_product_identification, 148 sizeof (srmir->srmir_product_identification)); 149 150 if (ddi_prop_exists(DDI_DEV_T_NONE, smp_sd->smp_sd_dev, 151 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, INQUIRY_VENDOR_ID) == 0) 152 (void) smp_device_prop_update_inqstring(smp_sd, 153 INQUIRY_VENDOR_ID, srmir->srmir_vendor_identification, 154 sizeof (srmir->srmir_vendor_identification)); 155 156 /* NOTE: SMP_PROP_REPORT_MANUFACTURER is deleted after devid created */ 157 if (ddi_prop_exists(DDI_DEV_T_NONE, smp_sd->smp_sd_dev, 158 DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, 159 SMP_PROP_REPORT_MANUFACTURER) == 0) 160 (void) ndi_prop_update_byte_array(DDI_DEV_T_NONE, 161 smp_sd->smp_sd_dev, SMP_PROP_REPORT_MANUFACTURER, 162 (uchar_t *)srs, sizeof (srs_buf)); 163 164 return (DDI_PROBE_SUCCESS); 165 } 166 167 int 168 smp_transport(struct smp_pkt *smp_pkt) 169 { 170 return (smp_pkt->smp_pkt_address-> 171 smp_a_hba_tran->smp_tran_start(smp_pkt)); 172 } 173