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 /* 23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2016 Nexenta Systems, Inc. All rights reserved. 25 * Copyright (c) 2014, Joyent, Inc. All rights reserved. 26 * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved. 27 * Copyright (c) 2014, Tegile Systems Inc. All rights reserved. 28 */ 29 30 /* 31 * Copyright (c) 2000 to 2010, LSI Corporation. 32 * All rights reserved. 33 * 34 * Redistribution and use in source and binary forms of all code within 35 * this file that is exclusively owned by LSI, with or without 36 * modification, is permitted provided that, in addition to the CDDL 1.0 37 * License requirements, the following conditions are met: 38 * 39 * Neither the name of the author nor the names of its contributors may be 40 * used to endorse or promote products derived from this software without 41 * specific prior written permission. 42 * 43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 46 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 47 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 48 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 49 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 50 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 51 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 52 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 53 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 54 * DAMAGE. 55 */ 56 57 /* 58 * mptsas - This is a driver based on LSI Logic's MPT2.0/2.5 interface. 59 * 60 */ 61 62 #if defined(lint) || defined(DEBUG) 63 #define MPTSAS_DEBUG 64 #endif 65 66 /* 67 * standard header files. 68 */ 69 #include <sys/note.h> 70 #include <sys/scsi/scsi.h> 71 #include <sys/pci.h> 72 #include <sys/file.h> 73 #include <sys/policy.h> 74 #include <sys/model.h> 75 #include <sys/sysevent.h> 76 #include <sys/sysevent/eventdefs.h> 77 #include <sys/sysevent/dr.h> 78 #include <sys/sata/sata_defs.h> 79 #include <sys/sata/sata_hba.h> 80 #include <sys/scsi/generic/sas.h> 81 #include <sys/scsi/impl/scsi_sas.h> 82 83 #pragma pack(1) 84 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h> 85 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h> 86 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h> 87 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h> 88 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h> 89 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h> 90 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h> 91 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h> 92 #pragma pack() 93 94 /* 95 * private header files. 96 * 97 */ 98 #include <sys/scsi/impl/scsi_reset_notify.h> 99 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h> 100 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h> 101 #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h> 102 #include <sys/scsi/adapters/mpt_sas/mptsas_hash.h> 103 #include <sys/raidioctl.h> 104 105 #include <sys/fs/dv_node.h> /* devfs_clean */ 106 107 /* 108 * FMA header files 109 */ 110 #include <sys/ddifm.h> 111 #include <sys/fm/protocol.h> 112 #include <sys/fm/util.h> 113 #include <sys/fm/io/ddi.h> 114 115 /* 116 * autoconfiguration data and routines. 117 */ 118 static int mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 119 static int mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd); 120 static int mptsas_power(dev_info_t *dip, int component, int level); 121 122 /* 123 * cb_ops function 124 */ 125 static int mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, 126 cred_t *credp, int *rval); 127 #ifdef __sparc 128 static int mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd); 129 #else /* __sparc */ 130 static int mptsas_quiesce(dev_info_t *devi); 131 #endif /* __sparc */ 132 133 /* 134 * Resource initilaization for hardware 135 */ 136 static void mptsas_setup_cmd_reg(mptsas_t *mpt); 137 static void mptsas_disable_bus_master(mptsas_t *mpt); 138 static void mptsas_hba_fini(mptsas_t *mpt); 139 static void mptsas_cfg_fini(mptsas_t *mptsas_blkp); 140 static int mptsas_hba_setup(mptsas_t *mpt); 141 static void mptsas_hba_teardown(mptsas_t *mpt); 142 static int mptsas_config_space_init(mptsas_t *mpt); 143 static void mptsas_config_space_fini(mptsas_t *mpt); 144 static void mptsas_iport_register(mptsas_t *mpt); 145 static int mptsas_smp_setup(mptsas_t *mpt); 146 static void mptsas_smp_teardown(mptsas_t *mpt); 147 static int mptsas_cache_create(mptsas_t *mpt); 148 static void mptsas_cache_destroy(mptsas_t *mpt); 149 static int mptsas_alloc_request_frames(mptsas_t *mpt); 150 static int mptsas_alloc_sense_bufs(mptsas_t *mpt); 151 static int mptsas_alloc_reply_frames(mptsas_t *mpt); 152 static int mptsas_alloc_free_queue(mptsas_t *mpt); 153 static int mptsas_alloc_post_queue(mptsas_t *mpt); 154 static void mptsas_alloc_reply_args(mptsas_t *mpt); 155 static int mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd); 156 static void mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd); 157 static int mptsas_init_chip(mptsas_t *mpt, int first_time); 158 159 /* 160 * SCSA function prototypes 161 */ 162 static int mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt); 163 static int mptsas_scsi_reset(struct scsi_address *ap, int level); 164 static int mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt); 165 static int mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly); 166 static int mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, 167 int tgtonly); 168 static void mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt); 169 static struct scsi_pkt *mptsas_scsi_init_pkt(struct scsi_address *ap, 170 struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen, 171 int tgtlen, int flags, int (*callback)(), caddr_t arg); 172 static void mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt); 173 static void mptsas_scsi_destroy_pkt(struct scsi_address *ap, 174 struct scsi_pkt *pkt); 175 static int mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 176 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 177 static void mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 178 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 179 static int mptsas_scsi_reset_notify(struct scsi_address *ap, int flag, 180 void (*callback)(caddr_t), caddr_t arg); 181 static int mptsas_get_name(struct scsi_device *sd, char *name, int len); 182 static int mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len); 183 static int mptsas_scsi_quiesce(dev_info_t *dip); 184 static int mptsas_scsi_unquiesce(dev_info_t *dip); 185 static int mptsas_bus_config(dev_info_t *pdip, uint_t flags, 186 ddi_bus_config_op_t op, void *arg, dev_info_t **childp); 187 188 /* 189 * SMP functions 190 */ 191 static int mptsas_smp_start(struct smp_pkt *smp_pkt); 192 193 /* 194 * internal function prototypes. 195 */ 196 static void mptsas_list_add(mptsas_t *mpt); 197 static void mptsas_list_del(mptsas_t *mpt); 198 199 static int mptsas_quiesce_bus(mptsas_t *mpt); 200 static int mptsas_unquiesce_bus(mptsas_t *mpt); 201 202 static int mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size); 203 static void mptsas_free_handshake_msg(mptsas_t *mpt); 204 205 static void mptsas_ncmds_checkdrain(void *arg); 206 207 static int mptsas_prepare_pkt(mptsas_cmd_t *cmd); 208 static int mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *sp); 209 static int mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *sp); 210 static void mptsas_accept_tx_waitq(mptsas_t *mpt); 211 212 static int mptsas_do_detach(dev_info_t *dev); 213 static int mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl); 214 static int mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, 215 struct scsi_pkt *pkt); 216 static int mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp); 217 218 static void mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd); 219 static void mptsas_handle_event(void *args); 220 static int mptsas_handle_event_sync(void *args); 221 static void mptsas_handle_dr(void *args); 222 static void mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node, 223 dev_info_t *pdip); 224 225 static void mptsas_restart_cmd(void *); 226 227 static void mptsas_flush_hba(mptsas_t *mpt); 228 static void mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, 229 uint8_t tasktype); 230 static void mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, 231 uchar_t reason, uint_t stat); 232 233 static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2); 234 static void mptsas_process_intr(mptsas_t *mpt, 235 pMpi2ReplyDescriptorsUnion_t reply_desc_union); 236 static void mptsas_handle_scsi_io_success(mptsas_t *mpt, 237 pMpi2ReplyDescriptorsUnion_t reply_desc); 238 static void mptsas_handle_address_reply(mptsas_t *mpt, 239 pMpi2ReplyDescriptorsUnion_t reply_desc); 240 static int mptsas_wait_intr(mptsas_t *mpt, int polltime); 241 static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, 242 uint32_t *control, pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl); 243 244 static void mptsas_watch(void *arg); 245 static void mptsas_watchsubr(mptsas_t *mpt); 246 static void mptsas_cmd_timeout(mptsas_t *mpt, mptsas_target_t *ptgt); 247 248 static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd); 249 static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply, 250 uint8_t *data, uint32_t request_size, uint32_t reply_size, 251 uint32_t data_size, uint32_t direction, uint8_t *dataout, 252 uint32_t dataout_size, short timeout, int mode); 253 static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl); 254 255 static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, 256 uint32_t unique_id); 257 static void mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd); 258 static int mptsas_post_fw_diag_buffer(mptsas_t *mpt, 259 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code); 260 static int mptsas_release_fw_diag_buffer(mptsas_t *mpt, 261 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code, 262 uint32_t diag_type); 263 static int mptsas_diag_register(mptsas_t *mpt, 264 mptsas_fw_diag_register_t *diag_register, uint32_t *return_code); 265 static int mptsas_diag_unregister(mptsas_t *mpt, 266 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code); 267 static int mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query, 268 uint32_t *return_code); 269 static int mptsas_diag_read_buffer(mptsas_t *mpt, 270 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf, 271 uint32_t *return_code, int ioctl_mode); 272 static int mptsas_diag_release(mptsas_t *mpt, 273 mptsas_fw_diag_release_t *diag_release, uint32_t *return_code); 274 static int mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, 275 uint8_t *diag_action, uint32_t length, uint32_t *return_code, 276 int ioctl_mode); 277 static int mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *data, 278 int mode); 279 280 static int mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd, 281 int cmdlen, int tgtlen, int statuslen, int kf); 282 static void mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd); 283 284 static int mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags); 285 static void mptsas_kmem_cache_destructor(void *buf, void *cdrarg); 286 287 static int mptsas_cache_frames_constructor(void *buf, void *cdrarg, 288 int kmflags); 289 static void mptsas_cache_frames_destructor(void *buf, void *cdrarg); 290 291 static void mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, 292 mptsas_cmd_t *cmd); 293 static void mptsas_check_task_mgt(mptsas_t *mpt, 294 pMpi2SCSIManagementReply_t reply, mptsas_cmd_t *cmd); 295 static int mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap, 296 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp, 297 int *resid); 298 299 static int mptsas_alloc_active_slots(mptsas_t *mpt, int flag); 300 static void mptsas_free_active_slots(mptsas_t *mpt); 301 static int mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd); 302 303 static void mptsas_restart_hba(mptsas_t *mpt); 304 static void mptsas_restart_waitq(mptsas_t *mpt); 305 306 static void mptsas_deliver_doneq_thread(mptsas_t *mpt); 307 static void mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd); 308 static void mptsas_doneq_mv(mptsas_t *mpt, uint64_t t); 309 310 static mptsas_cmd_t *mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t); 311 static void mptsas_doneq_empty(mptsas_t *mpt); 312 static void mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg); 313 314 static mptsas_cmd_t *mptsas_waitq_rm(mptsas_t *mpt); 315 static void mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd); 316 static mptsas_cmd_t *mptsas_tx_waitq_rm(mptsas_t *mpt); 317 static void mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd); 318 319 320 static void mptsas_start_watch_reset_delay(); 321 static void mptsas_setup_bus_reset_delay(mptsas_t *mpt); 322 static void mptsas_watch_reset_delay(void *arg); 323 static int mptsas_watch_reset_delay_subr(mptsas_t *mpt); 324 325 /* 326 * helper functions 327 */ 328 static void mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd); 329 330 static dev_info_t *mptsas_find_child(dev_info_t *pdip, char *name); 331 static dev_info_t *mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy); 332 static dev_info_t *mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, 333 int lun); 334 static mdi_pathinfo_t *mptsas_find_path_addr(dev_info_t *pdip, uint64_t sasaddr, 335 int lun); 336 static mdi_pathinfo_t *mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy); 337 static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn); 338 339 static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, 340 int *lun); 341 static int mptsas_parse_smp_name(char *name, uint64_t *wwn); 342 343 static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt, 344 mptsas_phymask_t phymask, uint8_t phy); 345 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt, 346 mptsas_phymask_t phymask, uint64_t wwid); 347 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, 348 mptsas_phymask_t phymask, uint64_t wwid); 349 350 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, 351 uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd); 352 353 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address, 354 uint16_t *handle, mptsas_target_t **pptgt); 355 static void mptsas_update_phymask(mptsas_t *mpt); 356 357 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt, 358 uint32_t *status, uint8_t cmd); 359 static dev_info_t *mptsas_get_dip_from_dev(dev_t dev, 360 mptsas_phymask_t *phymask); 361 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, 362 mptsas_phymask_t phymask); 363 static int mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt); 364 365 366 /* 367 * Enumeration / DR functions 368 */ 369 static void mptsas_config_all(dev_info_t *pdip); 370 static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun, 371 dev_info_t **lundip); 372 static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun, 373 dev_info_t **lundip); 374 375 static int mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt); 376 static int mptsas_offline_target(dev_info_t *pdip, char *name); 377 378 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target, 379 dev_info_t **dip); 380 381 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt); 382 static int mptsas_probe_lun(dev_info_t *pdip, int lun, 383 dev_info_t **dip, mptsas_target_t *ptgt); 384 385 static int mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq, 386 dev_info_t **dip, mptsas_target_t *ptgt, int lun); 387 388 static int mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *sd, 389 char *guid, dev_info_t **dip, mptsas_target_t *ptgt, int lun); 390 static int mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *sd, 391 char *guid, dev_info_t **dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, 392 int lun); 393 394 static void mptsas_offline_missed_luns(dev_info_t *pdip, 395 uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt); 396 static int mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip, 397 mdi_pathinfo_t *rpip, uint_t flags); 398 399 static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, 400 dev_info_t **smp_dip); 401 static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 402 uint_t flags); 403 404 static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, 405 int mode, int *rval); 406 static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, 407 int mode, int *rval); 408 static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, 409 int mode, int *rval); 410 static void mptsas_record_event(void *args); 411 static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, 412 int mode); 413 414 mptsas_target_t *mptsas_tgt_alloc(refhash_t *, uint16_t, uint64_t, 415 uint32_t, mptsas_phymask_t, uint8_t); 416 static mptsas_smp_t *mptsas_smp_alloc(mptsas_t *, mptsas_smp_t *); 417 static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 418 dev_info_t **smp_dip); 419 420 /* 421 * Power management functions 422 */ 423 static int mptsas_get_pci_cap(mptsas_t *mpt); 424 static int mptsas_init_pm(mptsas_t *mpt); 425 426 /* 427 * MPT MSI tunable: 428 * 429 * By default MSI is enabled on all supported platforms. 430 */ 431 boolean_t mptsas_enable_msi = B_TRUE; 432 boolean_t mptsas_physical_bind_failed_page_83 = B_FALSE; 433 434 /* 435 * Global switch for use of MPI2.5 FAST PATH. 436 * We don't really know what FAST PATH actually does, so if it is suspected 437 * to cause problems it can be turned off by setting this variable to B_FALSE. 438 */ 439 boolean_t mptsas_use_fastpath = B_TRUE; 440 441 static int mptsas_register_intrs(mptsas_t *); 442 static void mptsas_unregister_intrs(mptsas_t *); 443 static int mptsas_add_intrs(mptsas_t *, int); 444 static void mptsas_rem_intrs(mptsas_t *); 445 446 /* 447 * FMA Prototypes 448 */ 449 static void mptsas_fm_init(mptsas_t *mpt); 450 static void mptsas_fm_fini(mptsas_t *mpt); 451 static int mptsas_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *); 452 453 extern pri_t minclsyspri, maxclsyspri; 454 455 /* 456 * This device is created by the SCSI pseudo nexus driver (SCSI vHCI). It is 457 * under this device that the paths to a physical device are created when 458 * MPxIO is used. 459 */ 460 extern dev_info_t *scsi_vhci_dip; 461 462 /* 463 * Tunable timeout value for Inquiry VPD page 0x83 464 * By default the value is 30 seconds. 465 */ 466 int mptsas_inq83_retry_timeout = 30; 467 468 /* 469 * This is used to allocate memory for message frame storage, not for 470 * data I/O DMA. All message frames must be stored in the first 4G of 471 * physical memory. 472 */ 473 ddi_dma_attr_t mptsas_dma_attrs = { 474 DMA_ATTR_V0, /* attribute layout version */ 475 0x0ull, /* address low - should be 0 (longlong) */ 476 0xffffffffull, /* address high - 32-bit max range */ 477 0x00ffffffull, /* count max - max DMA object size */ 478 4, /* allocation alignment requirements */ 479 0x78, /* burstsizes - binary encoded values */ 480 1, /* minxfer - gran. of DMA engine */ 481 0x00ffffffull, /* maxxfer - gran. of DMA engine */ 482 0xffffffffull, /* max segment size (DMA boundary) */ 483 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */ 484 512, /* granularity - device transfer size */ 485 0 /* flags, set to 0 */ 486 }; 487 488 /* 489 * This is used for data I/O DMA memory allocation. (full 64-bit DMA 490 * physical addresses are supported.) 491 */ 492 ddi_dma_attr_t mptsas_dma_attrs64 = { 493 DMA_ATTR_V0, /* attribute layout version */ 494 0x0ull, /* address low - should be 0 (longlong) */ 495 0xffffffffffffffffull, /* address high - 64-bit max */ 496 0x00ffffffull, /* count max - max DMA object size */ 497 4, /* allocation alignment requirements */ 498 0x78, /* burstsizes - binary encoded values */ 499 1, /* minxfer - gran. of DMA engine */ 500 0x00ffffffull, /* maxxfer - gran. of DMA engine */ 501 0xffffffffull, /* max segment size (DMA boundary) */ 502 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */ 503 512, /* granularity - device transfer size */ 504 0 /* flags, set to 0 */ 505 }; 506 507 ddi_device_acc_attr_t mptsas_dev_attr = { 508 DDI_DEVICE_ATTR_V1, 509 DDI_STRUCTURE_LE_ACC, 510 DDI_STRICTORDER_ACC, 511 DDI_DEFAULT_ACC 512 }; 513 514 static struct cb_ops mptsas_cb_ops = { 515 scsi_hba_open, /* open */ 516 scsi_hba_close, /* close */ 517 nodev, /* strategy */ 518 nodev, /* print */ 519 nodev, /* dump */ 520 nodev, /* read */ 521 nodev, /* write */ 522 mptsas_ioctl, /* ioctl */ 523 nodev, /* devmap */ 524 nodev, /* mmap */ 525 nodev, /* segmap */ 526 nochpoll, /* chpoll */ 527 ddi_prop_op, /* cb_prop_op */ 528 NULL, /* streamtab */ 529 D_MP, /* cb_flag */ 530 CB_REV, /* rev */ 531 nodev, /* aread */ 532 nodev /* awrite */ 533 }; 534 535 static struct dev_ops mptsas_ops = { 536 DEVO_REV, /* devo_rev, */ 537 0, /* refcnt */ 538 ddi_no_info, /* info */ 539 nulldev, /* identify */ 540 nulldev, /* probe */ 541 mptsas_attach, /* attach */ 542 mptsas_detach, /* detach */ 543 #ifdef __sparc 544 mptsas_reset, 545 #else 546 nodev, /* reset */ 547 #endif /* __sparc */ 548 &mptsas_cb_ops, /* driver operations */ 549 NULL, /* bus operations */ 550 mptsas_power, /* power management */ 551 #ifdef __sparc 552 ddi_quiesce_not_needed 553 #else 554 mptsas_quiesce /* quiesce */ 555 #endif /* __sparc */ 556 }; 557 558 559 #define MPTSAS_MOD_STRING "MPTSAS HBA Driver 00.00.00.24" 560 561 static struct modldrv modldrv = { 562 &mod_driverops, /* Type of module. This one is a driver */ 563 MPTSAS_MOD_STRING, /* Name of the module. */ 564 &mptsas_ops, /* driver ops */ 565 }; 566 567 static struct modlinkage modlinkage = { 568 MODREV_1, &modldrv, NULL 569 }; 570 #define TARGET_PROP "target" 571 #define LUN_PROP "lun" 572 #define LUN64_PROP "lun64" 573 #define SAS_PROP "sas-mpt" 574 #define MDI_GUID "wwn" 575 #define NDI_GUID "guid" 576 #define MPTSAS_DEV_GONE "mptsas_dev_gone" 577 578 /* 579 * Local static data 580 */ 581 #if defined(MPTSAS_DEBUG) 582 /* 583 * Flags to indicate which debug messages are to be printed and which go to the 584 * debug log ring buffer. Default is to not print anything, and to log 585 * everything except the watchsubr() output which normally happens every second. 586 */ 587 uint32_t mptsas_debugprt_flags = 0x0; 588 uint32_t mptsas_debuglog_flags = ~(1U << 30); 589 #endif /* defined(MPTSAS_DEBUG) */ 590 uint32_t mptsas_debug_resets = 0; 591 592 static kmutex_t mptsas_global_mutex; 593 static void *mptsas_state; /* soft state ptr */ 594 static krwlock_t mptsas_global_rwlock; 595 596 static kmutex_t mptsas_log_mutex; 597 static char mptsas_log_buf[256]; 598 _NOTE(MUTEX_PROTECTS_DATA(mptsas_log_mutex, mptsas_log_buf)) 599 600 static mptsas_t *mptsas_head, *mptsas_tail; 601 static clock_t mptsas_scsi_watchdog_tick; 602 static clock_t mptsas_tick; 603 static timeout_id_t mptsas_reset_watch; 604 static timeout_id_t mptsas_timeout_id; 605 static int mptsas_timeouts_enabled = 0; 606 607 /* 608 * Default length for extended auto request sense buffers. 609 * All sense buffers need to be under the same alloc because there 610 * is only one common top 32bits (of 64bits) address register. 611 * Most requests only require 32 bytes, but some request >256. 612 * We use rmalloc()/rmfree() on this additional memory to manage the 613 * "extended" requests. 614 */ 615 int mptsas_extreq_sense_bufsize = 256*64; 616 617 /* 618 * We believe that all software resrictions of having to run with DMA 619 * attributes to limit allocation to the first 4G are removed. 620 * However, this flag remains to enable quick switchback should suspicious 621 * problems emerge. 622 * Note that scsi_alloc_consistent_buf() does still adhere to allocating 623 * 32 bit addressable memory, but we can cope if that is changed now. 624 */ 625 int mptsas_use_64bit_msgaddr = 1; 626 627 /* 628 * warlock directives 629 */ 630 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt \ 631 mptsas_cmd NcrTableIndirect buf scsi_cdb scsi_status)) 632 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", smp_pkt)) 633 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address)) 634 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", mptsas_tgt_private)) 635 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_hba_tran::tran_tgt_private)) 636 637 /* 638 * SM - HBA statics 639 */ 640 char *mptsas_driver_rev = MPTSAS_MOD_STRING; 641 642 #ifdef MPTSAS_DEBUG 643 void debug_enter(char *); 644 #endif 645 646 /* 647 * Notes: 648 * - scsi_hba_init(9F) initializes SCSI HBA modules 649 * - must call scsi_hba_fini(9F) if modload() fails 650 */ 651 int 652 _init(void) 653 { 654 int status; 655 /* CONSTCOND */ 656 ASSERT(NO_COMPETING_THREADS); 657 658 NDBG0(("_init")); 659 660 status = ddi_soft_state_init(&mptsas_state, MPTSAS_SIZE, 661 MPTSAS_INITIAL_SOFT_SPACE); 662 if (status != 0) { 663 return (status); 664 } 665 666 if ((status = scsi_hba_init(&modlinkage)) != 0) { 667 ddi_soft_state_fini(&mptsas_state); 668 return (status); 669 } 670 671 mutex_init(&mptsas_global_mutex, NULL, MUTEX_DRIVER, NULL); 672 rw_init(&mptsas_global_rwlock, NULL, RW_DRIVER, NULL); 673 mutex_init(&mptsas_log_mutex, NULL, MUTEX_DRIVER, NULL); 674 675 if ((status = mod_install(&modlinkage)) != 0) { 676 mutex_destroy(&mptsas_log_mutex); 677 rw_destroy(&mptsas_global_rwlock); 678 mutex_destroy(&mptsas_global_mutex); 679 ddi_soft_state_fini(&mptsas_state); 680 scsi_hba_fini(&modlinkage); 681 } 682 683 return (status); 684 } 685 686 /* 687 * Notes: 688 * - scsi_hba_fini(9F) uninitializes SCSI HBA modules 689 */ 690 int 691 _fini(void) 692 { 693 int status; 694 /* CONSTCOND */ 695 ASSERT(NO_COMPETING_THREADS); 696 697 NDBG0(("_fini")); 698 699 if ((status = mod_remove(&modlinkage)) == 0) { 700 ddi_soft_state_fini(&mptsas_state); 701 scsi_hba_fini(&modlinkage); 702 mutex_destroy(&mptsas_global_mutex); 703 rw_destroy(&mptsas_global_rwlock); 704 mutex_destroy(&mptsas_log_mutex); 705 } 706 return (status); 707 } 708 709 /* 710 * The loadable-module _info(9E) entry point 711 */ 712 int 713 _info(struct modinfo *modinfop) 714 { 715 /* CONSTCOND */ 716 ASSERT(NO_COMPETING_THREADS); 717 NDBG0(("mptsas _info")); 718 719 return (mod_info(&modlinkage, modinfop)); 720 } 721 722 static int 723 mptsas_target_eval_devhdl(const void *op, void *arg) 724 { 725 uint16_t dh = *(uint16_t *)arg; 726 const mptsas_target_t *tp = op; 727 728 return ((int)tp->m_devhdl - (int)dh); 729 } 730 731 static int 732 mptsas_target_eval_slot(const void *op, void *arg) 733 { 734 mptsas_led_control_t *lcp = arg; 735 const mptsas_target_t *tp = op; 736 737 if (tp->m_enclosure != lcp->Enclosure) 738 return ((int)tp->m_enclosure - (int)lcp->Enclosure); 739 740 return ((int)tp->m_slot_num - (int)lcp->Slot); 741 } 742 743 static int 744 mptsas_target_eval_nowwn(const void *op, void *arg) 745 { 746 uint8_t phy = *(uint8_t *)arg; 747 const mptsas_target_t *tp = op; 748 749 if (tp->m_addr.mta_wwn != 0) 750 return (-1); 751 752 return ((int)tp->m_phynum - (int)phy); 753 } 754 755 static int 756 mptsas_smp_eval_devhdl(const void *op, void *arg) 757 { 758 uint16_t dh = *(uint16_t *)arg; 759 const mptsas_smp_t *sp = op; 760 761 return ((int)sp->m_devhdl - (int)dh); 762 } 763 764 static uint64_t 765 mptsas_target_addr_hash(const void *tp) 766 { 767 const mptsas_target_addr_t *tap = tp; 768 769 return ((tap->mta_wwn & 0xffffffffffffULL) | 770 ((uint64_t)tap->mta_phymask << 48)); 771 } 772 773 static int 774 mptsas_target_addr_cmp(const void *a, const void *b) 775 { 776 const mptsas_target_addr_t *aap = a; 777 const mptsas_target_addr_t *bap = b; 778 779 if (aap->mta_wwn < bap->mta_wwn) 780 return (-1); 781 if (aap->mta_wwn > bap->mta_wwn) 782 return (1); 783 return ((int)bap->mta_phymask - (int)aap->mta_phymask); 784 } 785 786 static uint64_t 787 mptsas_tmp_target_hash(const void *tp) 788 { 789 return ((uint64_t)(uintptr_t)tp); 790 } 791 792 static int 793 mptsas_tmp_target_cmp(const void *a, const void *b) 794 { 795 if (a > b) 796 return (1); 797 if (b < a) 798 return (-1); 799 800 return (0); 801 } 802 803 static void 804 mptsas_target_free(void *op) 805 { 806 kmem_free(op, sizeof (mptsas_target_t)); 807 } 808 809 static void 810 mptsas_smp_free(void *op) 811 { 812 kmem_free(op, sizeof (mptsas_smp_t)); 813 } 814 815 static void 816 mptsas_destroy_hashes(mptsas_t *mpt) 817 { 818 mptsas_target_t *tp; 819 mptsas_smp_t *sp; 820 821 for (tp = refhash_first(mpt->m_targets); tp != NULL; 822 tp = refhash_next(mpt->m_targets, tp)) { 823 refhash_remove(mpt->m_targets, tp); 824 } 825 for (sp = refhash_first(mpt->m_smp_targets); sp != NULL; 826 sp = refhash_next(mpt->m_smp_targets, sp)) { 827 refhash_remove(mpt->m_smp_targets, sp); 828 } 829 refhash_destroy(mpt->m_tmp_targets); 830 refhash_destroy(mpt->m_targets); 831 refhash_destroy(mpt->m_smp_targets); 832 mpt->m_targets = NULL; 833 mpt->m_smp_targets = NULL; 834 } 835 836 static int 837 mptsas_iport_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 838 { 839 dev_info_t *pdip; 840 mptsas_t *mpt; 841 scsi_hba_tran_t *hba_tran; 842 char *iport = NULL; 843 char phymask[MPTSAS_MAX_PHYS]; 844 mptsas_phymask_t phy_mask = 0; 845 int dynamic_port = 0; 846 uint32_t page_address; 847 char initiator_wwnstr[MPTSAS_WWN_STRLEN]; 848 int rval = DDI_FAILURE; 849 int i = 0; 850 uint8_t numphys = 0; 851 uint8_t phy_id; 852 uint8_t phy_port = 0; 853 uint16_t attached_devhdl = 0; 854 uint32_t dev_info; 855 uint64_t attached_sas_wwn; 856 uint16_t dev_hdl; 857 uint16_t pdev_hdl; 858 uint16_t bay_num, enclosure, io_flags; 859 char attached_wwnstr[MPTSAS_WWN_STRLEN]; 860 861 /* CONSTCOND */ 862 ASSERT(NO_COMPETING_THREADS); 863 864 switch (cmd) { 865 case DDI_ATTACH: 866 break; 867 868 case DDI_RESUME: 869 /* 870 * If this a scsi-iport node, nothing to do here. 871 */ 872 return (DDI_SUCCESS); 873 874 default: 875 return (DDI_FAILURE); 876 } 877 878 pdip = ddi_get_parent(dip); 879 880 if ((hba_tran = ndi_flavorv_get(pdip, SCSA_FLAVOR_SCSI_DEVICE)) == 881 NULL) { 882 cmn_err(CE_WARN, "Failed attach iport because fail to " 883 "get tran vector for the HBA node"); 884 return (DDI_FAILURE); 885 } 886 887 mpt = TRAN2MPT(hba_tran); 888 ASSERT(mpt != NULL); 889 if (mpt == NULL) 890 return (DDI_FAILURE); 891 892 if ((hba_tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == 893 NULL) { 894 mptsas_log(mpt, CE_WARN, "Failed attach iport because fail to " 895 "get tran vector for the iport node"); 896 return (DDI_FAILURE); 897 } 898 899 /* 900 * Overwrite parent's tran_hba_private to iport's tran vector 901 */ 902 hba_tran->tran_hba_private = mpt; 903 904 ddi_report_dev(dip); 905 906 /* 907 * Get SAS address for initiator port according dev_handle 908 */ 909 iport = ddi_get_name_addr(dip); 910 if (iport && strncmp(iport, "v0", 2) == 0) { 911 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 912 MPTSAS_VIRTUAL_PORT, 1) != 913 DDI_PROP_SUCCESS) { 914 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, 915 MPTSAS_VIRTUAL_PORT); 916 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 917 "prop update failed"); 918 return (DDI_FAILURE); 919 } 920 return (DDI_SUCCESS); 921 } 922 923 mutex_enter(&mpt->m_mutex); 924 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 925 bzero(phymask, sizeof (phymask)); 926 (void) sprintf(phymask, 927 "%x", mpt->m_phy_info[i].phy_mask); 928 if (strcmp(phymask, iport) == 0) { 929 break; 930 } 931 } 932 933 if (i == MPTSAS_MAX_PHYS) { 934 mptsas_log(mpt, CE_WARN, "Failed attach port %s because port" 935 "seems not exist", iport); 936 mutex_exit(&mpt->m_mutex); 937 return (DDI_FAILURE); 938 } 939 940 phy_mask = mpt->m_phy_info[i].phy_mask; 941 942 if (mpt->m_phy_info[i].port_flags & AUTO_PORT_CONFIGURATION) 943 dynamic_port = 1; 944 else 945 dynamic_port = 0; 946 947 /* 948 * Update PHY info for smhba 949 */ 950 if (mptsas_smhba_phy_init(mpt)) { 951 mutex_exit(&mpt->m_mutex); 952 mptsas_log(mpt, CE_WARN, "mptsas phy update " 953 "failed"); 954 return (DDI_FAILURE); 955 } 956 957 mutex_exit(&mpt->m_mutex); 958 959 numphys = 0; 960 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 961 if ((phy_mask >> i) & 0x01) { 962 numphys++; 963 } 964 } 965 966 bzero(initiator_wwnstr, sizeof (initiator_wwnstr)); 967 (void) sprintf(initiator_wwnstr, "w%016"PRIx64, 968 mpt->un.m_base_wwid); 969 970 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, 971 SCSI_ADDR_PROP_INITIATOR_PORT, initiator_wwnstr) != 972 DDI_PROP_SUCCESS) { 973 (void) ddi_prop_remove(DDI_DEV_T_NONE, 974 dip, SCSI_ADDR_PROP_INITIATOR_PORT); 975 mptsas_log(mpt, CE_WARN, "mptsas Initiator port " 976 "prop update failed"); 977 return (DDI_FAILURE); 978 } 979 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 980 MPTSAS_NUM_PHYS, numphys) != 981 DDI_PROP_SUCCESS) { 982 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, MPTSAS_NUM_PHYS); 983 return (DDI_FAILURE); 984 } 985 986 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 987 "phymask", phy_mask) != 988 DDI_PROP_SUCCESS) { 989 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "phymask"); 990 mptsas_log(mpt, CE_WARN, "mptsas phy mask " 991 "prop update failed"); 992 return (DDI_FAILURE); 993 } 994 995 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 996 "dynamic-port", dynamic_port) != 997 DDI_PROP_SUCCESS) { 998 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "dynamic-port"); 999 mptsas_log(mpt, CE_WARN, "mptsas dynamic port " 1000 "prop update failed"); 1001 return (DDI_FAILURE); 1002 } 1003 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 1004 MPTSAS_VIRTUAL_PORT, 0) != 1005 DDI_PROP_SUCCESS) { 1006 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, 1007 MPTSAS_VIRTUAL_PORT); 1008 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 1009 "prop update failed"); 1010 return (DDI_FAILURE); 1011 } 1012 mptsas_smhba_set_all_phy_props(mpt, dip, numphys, phy_mask, 1013 &attached_devhdl); 1014 1015 mutex_enter(&mpt->m_mutex); 1016 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 1017 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)attached_devhdl; 1018 rval = mptsas_get_sas_device_page0(mpt, page_address, &dev_hdl, 1019 &attached_sas_wwn, &dev_info, &phy_port, &phy_id, 1020 &pdev_hdl, &bay_num, &enclosure, &io_flags); 1021 if (rval != DDI_SUCCESS) { 1022 mptsas_log(mpt, CE_WARN, 1023 "Failed to get device page0 for handle:%d", 1024 attached_devhdl); 1025 mutex_exit(&mpt->m_mutex); 1026 return (DDI_FAILURE); 1027 } 1028 1029 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1030 bzero(phymask, sizeof (phymask)); 1031 (void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask); 1032 if (strcmp(phymask, iport) == 0) { 1033 (void) sprintf(&mpt->m_phy_info[i].smhba_info.path[0], 1034 "%x", 1035 mpt->m_phy_info[i].phy_mask); 1036 } 1037 } 1038 mutex_exit(&mpt->m_mutex); 1039 1040 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 1041 (void) sprintf(attached_wwnstr, "w%016"PRIx64, 1042 attached_sas_wwn); 1043 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, 1044 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 1045 DDI_PROP_SUCCESS) { 1046 (void) ddi_prop_remove(DDI_DEV_T_NONE, 1047 dip, SCSI_ADDR_PROP_ATTACHED_PORT); 1048 return (DDI_FAILURE); 1049 } 1050 1051 /* Create kstats for each phy on this iport */ 1052 1053 mptsas_create_phy_stats(mpt, iport, dip); 1054 1055 /* 1056 * register sas hba iport with mdi (MPxIO/vhci) 1057 */ 1058 if (mdi_phci_register(MDI_HCI_CLASS_SCSI, 1059 dip, 0) == MDI_SUCCESS) { 1060 mpt->m_mpxio_enable = TRUE; 1061 } 1062 return (DDI_SUCCESS); 1063 } 1064 1065 /* 1066 * Notes: 1067 * Set up all device state and allocate data structures, 1068 * mutexes, condition variables, etc. for device operation. 1069 * Add interrupts needed. 1070 * Return DDI_SUCCESS if device is ready, else return DDI_FAILURE. 1071 */ 1072 static int 1073 mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1074 { 1075 mptsas_t *mpt = NULL; 1076 int instance, i, j; 1077 int doneq_thread_num; 1078 char intr_added = 0; 1079 char map_setup = 0; 1080 char config_setup = 0; 1081 char hba_attach_setup = 0; 1082 char smp_attach_setup = 0; 1083 char mutex_init_done = 0; 1084 char event_taskq_create = 0; 1085 char dr_taskq_create = 0; 1086 char doneq_thread_create = 0; 1087 char added_watchdog = 0; 1088 scsi_hba_tran_t *hba_tran; 1089 uint_t mem_bar = MEM_SPACE; 1090 int rval = DDI_FAILURE; 1091 1092 /* CONSTCOND */ 1093 ASSERT(NO_COMPETING_THREADS); 1094 1095 if (scsi_hba_iport_unit_address(dip)) { 1096 return (mptsas_iport_attach(dip, cmd)); 1097 } 1098 1099 switch (cmd) { 1100 case DDI_ATTACH: 1101 break; 1102 1103 case DDI_RESUME: 1104 if ((hba_tran = ddi_get_driver_private(dip)) == NULL) 1105 return (DDI_FAILURE); 1106 1107 mpt = TRAN2MPT(hba_tran); 1108 1109 if (!mpt) { 1110 return (DDI_FAILURE); 1111 } 1112 1113 /* 1114 * Reset hardware and softc to "no outstanding commands" 1115 * Note that a check condition can result on first command 1116 * to a target. 1117 */ 1118 mutex_enter(&mpt->m_mutex); 1119 1120 /* 1121 * raise power. 1122 */ 1123 if (mpt->m_options & MPTSAS_OPT_PM) { 1124 mutex_exit(&mpt->m_mutex); 1125 (void) pm_busy_component(dip, 0); 1126 rval = pm_power_has_changed(dip, 0, PM_LEVEL_D0); 1127 if (rval == DDI_SUCCESS) { 1128 mutex_enter(&mpt->m_mutex); 1129 } else { 1130 /* 1131 * The pm_raise_power() call above failed, 1132 * and that can only occur if we were unable 1133 * to reset the hardware. This is probably 1134 * due to unhealty hardware, and because 1135 * important filesystems(such as the root 1136 * filesystem) could be on the attached disks, 1137 * it would not be a good idea to continue, 1138 * as we won't be entirely certain we are 1139 * writing correct data. So we panic() here 1140 * to not only prevent possible data corruption, 1141 * but to give developers or end users a hope 1142 * of identifying and correcting any problems. 1143 */ 1144 fm_panic("mptsas could not reset hardware " 1145 "during resume"); 1146 } 1147 } 1148 1149 mpt->m_suspended = 0; 1150 1151 /* 1152 * Reinitialize ioc 1153 */ 1154 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1155 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) { 1156 mutex_exit(&mpt->m_mutex); 1157 if (mpt->m_options & MPTSAS_OPT_PM) { 1158 (void) pm_idle_component(dip, 0); 1159 } 1160 fm_panic("mptsas init chip fail during resume"); 1161 } 1162 /* 1163 * mptsas_update_driver_data needs interrupts so enable them 1164 * first. 1165 */ 1166 MPTSAS_ENABLE_INTR(mpt); 1167 mptsas_update_driver_data(mpt); 1168 1169 /* start requests, if possible */ 1170 mptsas_restart_hba(mpt); 1171 1172 mutex_exit(&mpt->m_mutex); 1173 1174 /* 1175 * Restart watch thread 1176 */ 1177 mutex_enter(&mptsas_global_mutex); 1178 if (mptsas_timeout_id == 0) { 1179 mptsas_timeout_id = timeout(mptsas_watch, NULL, 1180 mptsas_tick); 1181 mptsas_timeouts_enabled = 1; 1182 } 1183 mutex_exit(&mptsas_global_mutex); 1184 1185 /* report idle status to pm framework */ 1186 if (mpt->m_options & MPTSAS_OPT_PM) { 1187 (void) pm_idle_component(dip, 0); 1188 } 1189 1190 return (DDI_SUCCESS); 1191 1192 default: 1193 return (DDI_FAILURE); 1194 1195 } 1196 1197 instance = ddi_get_instance(dip); 1198 1199 /* 1200 * Allocate softc information. 1201 */ 1202 if (ddi_soft_state_zalloc(mptsas_state, instance) != DDI_SUCCESS) { 1203 mptsas_log(NULL, CE_WARN, 1204 "mptsas%d: cannot allocate soft state", instance); 1205 goto fail; 1206 } 1207 1208 mpt = ddi_get_soft_state(mptsas_state, instance); 1209 1210 if (mpt == NULL) { 1211 mptsas_log(NULL, CE_WARN, 1212 "mptsas%d: cannot get soft state", instance); 1213 goto fail; 1214 } 1215 1216 /* Indicate that we are 'sizeof (scsi_*(9S))' clean. */ 1217 scsi_size_clean(dip); 1218 1219 mpt->m_dip = dip; 1220 mpt->m_instance = instance; 1221 1222 /* Make a per-instance copy of the structures */ 1223 mpt->m_io_dma_attr = mptsas_dma_attrs64; 1224 if (mptsas_use_64bit_msgaddr) { 1225 mpt->m_msg_dma_attr = mptsas_dma_attrs64; 1226 } else { 1227 mpt->m_msg_dma_attr = mptsas_dma_attrs; 1228 } 1229 mpt->m_reg_acc_attr = mptsas_dev_attr; 1230 mpt->m_dev_acc_attr = mptsas_dev_attr; 1231 1232 /* 1233 * Size of individual request sense buffer 1234 */ 1235 mpt->m_req_sense_size = EXTCMDS_STATUS_SIZE; 1236 1237 /* 1238 * Initialize FMA 1239 */ 1240 mpt->m_fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, mpt->m_dip, 1241 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable", 1242 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE | 1243 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE); 1244 1245 mptsas_fm_init(mpt); 1246 1247 if (mptsas_alloc_handshake_msg(mpt, 1248 sizeof (Mpi2SCSITaskManagementRequest_t)) == DDI_FAILURE) { 1249 mptsas_log(mpt, CE_WARN, "cannot initialize handshake msg."); 1250 goto fail; 1251 } 1252 1253 /* 1254 * Setup configuration space 1255 */ 1256 if (mptsas_config_space_init(mpt) == FALSE) { 1257 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init failed"); 1258 goto fail; 1259 } 1260 config_setup++; 1261 1262 if (ddi_regs_map_setup(dip, mem_bar, (caddr_t *)&mpt->m_reg, 1263 0, 0, &mpt->m_reg_acc_attr, &mpt->m_datap) != DDI_SUCCESS) { 1264 mptsas_log(mpt, CE_WARN, "map setup failed"); 1265 goto fail; 1266 } 1267 map_setup++; 1268 1269 /* 1270 * A taskq is created for dealing with the event handler 1271 */ 1272 if ((mpt->m_event_taskq = ddi_taskq_create(dip, "mptsas_event_taskq", 1273 1, TASKQ_DEFAULTPRI, 0)) == NULL) { 1274 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create failed"); 1275 goto fail; 1276 } 1277 event_taskq_create++; 1278 1279 /* 1280 * A taskq is created for dealing with dr events 1281 */ 1282 if ((mpt->m_dr_taskq = ddi_taskq_create(dip, 1283 "mptsas_dr_taskq", 1284 1, TASKQ_DEFAULTPRI, 0)) == NULL) { 1285 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create for discovery " 1286 "failed"); 1287 goto fail; 1288 } 1289 dr_taskq_create++; 1290 1291 mpt->m_doneq_thread_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1292 0, "mptsas_doneq_thread_threshold_prop", 10); 1293 mpt->m_doneq_length_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1294 0, "mptsas_doneq_length_threshold_prop", 8); 1295 mpt->m_doneq_thread_n = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1296 0, "mptsas_doneq_thread_n_prop", 8); 1297 1298 if (mpt->m_doneq_thread_n) { 1299 cv_init(&mpt->m_doneq_thread_cv, NULL, CV_DRIVER, NULL); 1300 mutex_init(&mpt->m_doneq_mutex, NULL, MUTEX_DRIVER, NULL); 1301 1302 mutex_enter(&mpt->m_doneq_mutex); 1303 mpt->m_doneq_thread_id = 1304 kmem_zalloc(sizeof (mptsas_doneq_thread_list_t) 1305 * mpt->m_doneq_thread_n, KM_SLEEP); 1306 1307 for (j = 0; j < mpt->m_doneq_thread_n; j++) { 1308 cv_init(&mpt->m_doneq_thread_id[j].cv, NULL, 1309 CV_DRIVER, NULL); 1310 mutex_init(&mpt->m_doneq_thread_id[j].mutex, NULL, 1311 MUTEX_DRIVER, NULL); 1312 mutex_enter(&mpt->m_doneq_thread_id[j].mutex); 1313 mpt->m_doneq_thread_id[j].flag |= 1314 MPTSAS_DONEQ_THREAD_ACTIVE; 1315 mpt->m_doneq_thread_id[j].arg.mpt = mpt; 1316 mpt->m_doneq_thread_id[j].arg.t = j; 1317 mpt->m_doneq_thread_id[j].threadp = 1318 thread_create(NULL, 0, mptsas_doneq_thread, 1319 &mpt->m_doneq_thread_id[j].arg, 1320 0, &p0, TS_RUN, minclsyspri); 1321 mpt->m_doneq_thread_id[j].donetail = 1322 &mpt->m_doneq_thread_id[j].doneq; 1323 mutex_exit(&mpt->m_doneq_thread_id[j].mutex); 1324 } 1325 mutex_exit(&mpt->m_doneq_mutex); 1326 doneq_thread_create++; 1327 } 1328 1329 /* 1330 * Disable hardware interrupt since we're not ready to 1331 * handle it yet. 1332 */ 1333 MPTSAS_DISABLE_INTR(mpt); 1334 if (mptsas_register_intrs(mpt) == FALSE) 1335 goto fail; 1336 intr_added++; 1337 1338 /* Initialize mutex used in interrupt handler */ 1339 mutex_init(&mpt->m_mutex, NULL, MUTEX_DRIVER, 1340 DDI_INTR_PRI(mpt->m_intr_pri)); 1341 mutex_init(&mpt->m_passthru_mutex, NULL, MUTEX_DRIVER, NULL); 1342 mutex_init(&mpt->m_tx_waitq_mutex, NULL, MUTEX_DRIVER, 1343 DDI_INTR_PRI(mpt->m_intr_pri)); 1344 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1345 mutex_init(&mpt->m_phy_info[i].smhba_info.phy_mutex, 1346 NULL, MUTEX_DRIVER, 1347 DDI_INTR_PRI(mpt->m_intr_pri)); 1348 } 1349 1350 cv_init(&mpt->m_cv, NULL, CV_DRIVER, NULL); 1351 cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL); 1352 cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL); 1353 cv_init(&mpt->m_config_cv, NULL, CV_DRIVER, NULL); 1354 cv_init(&mpt->m_fw_diag_cv, NULL, CV_DRIVER, NULL); 1355 cv_init(&mpt->m_extreq_sense_refcount_cv, NULL, CV_DRIVER, NULL); 1356 mutex_init_done++; 1357 1358 mutex_enter(&mpt->m_mutex); 1359 /* 1360 * Initialize power management component 1361 */ 1362 if (mpt->m_options & MPTSAS_OPT_PM) { 1363 if (mptsas_init_pm(mpt)) { 1364 mutex_exit(&mpt->m_mutex); 1365 mptsas_log(mpt, CE_WARN, "mptsas pm initialization " 1366 "failed"); 1367 goto fail; 1368 } 1369 } 1370 1371 /* 1372 * Initialize chip using Message Unit Reset, if allowed 1373 */ 1374 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1375 if (mptsas_init_chip(mpt, TRUE) == DDI_FAILURE) { 1376 mutex_exit(&mpt->m_mutex); 1377 mptsas_log(mpt, CE_WARN, "mptsas chip initialization failed"); 1378 goto fail; 1379 } 1380 1381 mpt->m_targets = refhash_create(MPTSAS_TARGET_BUCKET_COUNT, 1382 mptsas_target_addr_hash, mptsas_target_addr_cmp, 1383 mptsas_target_free, sizeof (mptsas_target_t), 1384 offsetof(mptsas_target_t, m_link), 1385 offsetof(mptsas_target_t, m_addr), KM_SLEEP); 1386 1387 /* 1388 * The refhash for temporary targets uses the address of the target 1389 * struct itself as tag, so the tag offset is 0. See the implementation 1390 * of mptsas_tmp_target_hash() and mptsas_tmp_target_cmp(). 1391 */ 1392 mpt->m_tmp_targets = refhash_create(MPTSAS_TMP_TARGET_BUCKET_COUNT, 1393 mptsas_tmp_target_hash, mptsas_tmp_target_cmp, 1394 mptsas_target_free, sizeof (mptsas_target_t), 1395 offsetof(mptsas_target_t, m_link), 0, KM_SLEEP); 1396 1397 /* 1398 * Fill in the phy_info structure and get the base WWID 1399 */ 1400 if (mptsas_get_manufacture_page5(mpt) == DDI_FAILURE) { 1401 mptsas_log(mpt, CE_WARN, 1402 "mptsas_get_manufacture_page5 failed!"); 1403 goto fail; 1404 } 1405 1406 if (mptsas_get_sas_io_unit_page_hndshk(mpt)) { 1407 mptsas_log(mpt, CE_WARN, 1408 "mptsas_get_sas_io_unit_page_hndshk failed!"); 1409 goto fail; 1410 } 1411 1412 if (mptsas_get_manufacture_page0(mpt) == DDI_FAILURE) { 1413 mptsas_log(mpt, CE_WARN, 1414 "mptsas_get_manufacture_page0 failed!"); 1415 goto fail; 1416 } 1417 1418 mutex_exit(&mpt->m_mutex); 1419 1420 /* 1421 * Register the iport for multiple port HBA 1422 */ 1423 mptsas_iport_register(mpt); 1424 1425 /* 1426 * initialize SCSI HBA transport structure 1427 */ 1428 if (mptsas_hba_setup(mpt) == FALSE) 1429 goto fail; 1430 hba_attach_setup++; 1431 1432 if (mptsas_smp_setup(mpt) == FALSE) 1433 goto fail; 1434 smp_attach_setup++; 1435 1436 if (mptsas_cache_create(mpt) == FALSE) 1437 goto fail; 1438 1439 mpt->m_scsi_reset_delay = ddi_prop_get_int(DDI_DEV_T_ANY, 1440 dip, 0, "scsi-reset-delay", SCSI_DEFAULT_RESET_DELAY); 1441 if (mpt->m_scsi_reset_delay == 0) { 1442 mptsas_log(mpt, CE_NOTE, 1443 "scsi_reset_delay of 0 is not recommended," 1444 " resetting to SCSI_DEFAULT_RESET_DELAY\n"); 1445 mpt->m_scsi_reset_delay = SCSI_DEFAULT_RESET_DELAY; 1446 } 1447 1448 /* 1449 * Initialize the wait and done FIFO queue 1450 */ 1451 mpt->m_donetail = &mpt->m_doneq; 1452 mpt->m_waitqtail = &mpt->m_waitq; 1453 mpt->m_tx_waitqtail = &mpt->m_tx_waitq; 1454 mpt->m_tx_draining = 0; 1455 1456 /* 1457 * ioc cmd queue initialize 1458 */ 1459 mpt->m_ioc_event_cmdtail = &mpt->m_ioc_event_cmdq; 1460 mpt->m_dev_handle = 0xFFFF; 1461 1462 MPTSAS_ENABLE_INTR(mpt); 1463 1464 /* 1465 * enable event notification 1466 */ 1467 mutex_enter(&mpt->m_mutex); 1468 if (mptsas_ioc_enable_event_notification(mpt)) { 1469 mutex_exit(&mpt->m_mutex); 1470 goto fail; 1471 } 1472 mutex_exit(&mpt->m_mutex); 1473 1474 /* 1475 * used for mptsas_watch 1476 */ 1477 mptsas_list_add(mpt); 1478 1479 mutex_enter(&mptsas_global_mutex); 1480 if (mptsas_timeouts_enabled == 0) { 1481 mptsas_scsi_watchdog_tick = ddi_prop_get_int(DDI_DEV_T_ANY, 1482 dip, 0, "scsi-watchdog-tick", DEFAULT_WD_TICK); 1483 1484 mptsas_tick = mptsas_scsi_watchdog_tick * 1485 drv_usectohz((clock_t)1000000); 1486 1487 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick); 1488 mptsas_timeouts_enabled = 1; 1489 } 1490 mutex_exit(&mptsas_global_mutex); 1491 added_watchdog++; 1492 1493 /* 1494 * Initialize PHY info for smhba. 1495 * This requires watchdog to be enabled otherwise if interrupts 1496 * don't work the system will hang. 1497 */ 1498 if (mptsas_smhba_setup(mpt)) { 1499 mptsas_log(mpt, CE_WARN, "mptsas phy initialization " 1500 "failed"); 1501 goto fail; 1502 } 1503 1504 /* Check all dma handles allocated in attach */ 1505 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) 1506 != DDI_SUCCESS) || 1507 (mptsas_check_dma_handle(mpt->m_dma_req_sense_hdl) 1508 != DDI_SUCCESS) || 1509 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) 1510 != DDI_SUCCESS) || 1511 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) 1512 != DDI_SUCCESS) || 1513 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) 1514 != DDI_SUCCESS) || 1515 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) 1516 != DDI_SUCCESS)) { 1517 goto fail; 1518 } 1519 1520 /* Check all acc handles allocated in attach */ 1521 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) || 1522 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) 1523 != DDI_SUCCESS) || 1524 (mptsas_check_acc_handle(mpt->m_acc_req_sense_hdl) 1525 != DDI_SUCCESS) || 1526 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) 1527 != DDI_SUCCESS) || 1528 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) 1529 != DDI_SUCCESS) || 1530 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) 1531 != DDI_SUCCESS) || 1532 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) 1533 != DDI_SUCCESS) || 1534 (mptsas_check_acc_handle(mpt->m_config_handle) 1535 != DDI_SUCCESS)) { 1536 goto fail; 1537 } 1538 1539 /* 1540 * After this point, we are not going to fail the attach. 1541 */ 1542 1543 /* Print message of HBA present */ 1544 ddi_report_dev(dip); 1545 1546 /* report idle status to pm framework */ 1547 if (mpt->m_options & MPTSAS_OPT_PM) { 1548 (void) pm_idle_component(dip, 0); 1549 } 1550 1551 return (DDI_SUCCESS); 1552 1553 fail: 1554 mptsas_log(mpt, CE_WARN, "attach failed"); 1555 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 1556 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 1557 if (mpt) { 1558 /* deallocate in reverse order */ 1559 if (added_watchdog) { 1560 mptsas_list_del(mpt); 1561 mutex_enter(&mptsas_global_mutex); 1562 1563 if (mptsas_timeout_id && (mptsas_head == NULL)) { 1564 timeout_id_t tid = mptsas_timeout_id; 1565 mptsas_timeouts_enabled = 0; 1566 mptsas_timeout_id = 0; 1567 mutex_exit(&mptsas_global_mutex); 1568 (void) untimeout(tid); 1569 mutex_enter(&mptsas_global_mutex); 1570 } 1571 mutex_exit(&mptsas_global_mutex); 1572 } 1573 1574 mptsas_cache_destroy(mpt); 1575 1576 if (smp_attach_setup) { 1577 mptsas_smp_teardown(mpt); 1578 } 1579 if (hba_attach_setup) { 1580 mptsas_hba_teardown(mpt); 1581 } 1582 1583 if (mpt->m_tmp_targets) 1584 refhash_destroy(mpt->m_tmp_targets); 1585 if (mpt->m_targets) 1586 refhash_destroy(mpt->m_targets); 1587 if (mpt->m_smp_targets) 1588 refhash_destroy(mpt->m_smp_targets); 1589 1590 if (mpt->m_active) { 1591 mptsas_free_active_slots(mpt); 1592 } 1593 if (intr_added) { 1594 mptsas_unregister_intrs(mpt); 1595 } 1596 1597 if (doneq_thread_create) { 1598 mutex_enter(&mpt->m_doneq_mutex); 1599 doneq_thread_num = mpt->m_doneq_thread_n; 1600 for (j = 0; j < mpt->m_doneq_thread_n; j++) { 1601 mutex_enter(&mpt->m_doneq_thread_id[j].mutex); 1602 mpt->m_doneq_thread_id[j].flag &= 1603 (~MPTSAS_DONEQ_THREAD_ACTIVE); 1604 cv_signal(&mpt->m_doneq_thread_id[j].cv); 1605 mutex_exit(&mpt->m_doneq_thread_id[j].mutex); 1606 } 1607 while (mpt->m_doneq_thread_n) { 1608 cv_wait(&mpt->m_doneq_thread_cv, 1609 &mpt->m_doneq_mutex); 1610 } 1611 for (j = 0; j < doneq_thread_num; j++) { 1612 cv_destroy(&mpt->m_doneq_thread_id[j].cv); 1613 mutex_destroy(&mpt->m_doneq_thread_id[j].mutex); 1614 } 1615 kmem_free(mpt->m_doneq_thread_id, 1616 sizeof (mptsas_doneq_thread_list_t) 1617 * doneq_thread_num); 1618 mutex_exit(&mpt->m_doneq_mutex); 1619 cv_destroy(&mpt->m_doneq_thread_cv); 1620 mutex_destroy(&mpt->m_doneq_mutex); 1621 } 1622 if (event_taskq_create) { 1623 ddi_taskq_destroy(mpt->m_event_taskq); 1624 } 1625 if (dr_taskq_create) { 1626 ddi_taskq_destroy(mpt->m_dr_taskq); 1627 } 1628 if (mutex_init_done) { 1629 mutex_destroy(&mpt->m_tx_waitq_mutex); 1630 mutex_destroy(&mpt->m_passthru_mutex); 1631 mutex_destroy(&mpt->m_mutex); 1632 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1633 mutex_destroy( 1634 &mpt->m_phy_info[i].smhba_info.phy_mutex); 1635 } 1636 cv_destroy(&mpt->m_cv); 1637 cv_destroy(&mpt->m_passthru_cv); 1638 cv_destroy(&mpt->m_fw_cv); 1639 cv_destroy(&mpt->m_config_cv); 1640 cv_destroy(&mpt->m_fw_diag_cv); 1641 cv_destroy(&mpt->m_extreq_sense_refcount_cv); 1642 } 1643 1644 if (map_setup) { 1645 mptsas_cfg_fini(mpt); 1646 } 1647 if (config_setup) { 1648 mptsas_config_space_fini(mpt); 1649 } 1650 mptsas_free_handshake_msg(mpt); 1651 mptsas_hba_fini(mpt); 1652 1653 mptsas_fm_fini(mpt); 1654 ddi_soft_state_free(mptsas_state, instance); 1655 ddi_prop_remove_all(dip); 1656 } 1657 return (DDI_FAILURE); 1658 } 1659 1660 static int 1661 mptsas_suspend(dev_info_t *devi) 1662 { 1663 mptsas_t *mpt, *g; 1664 scsi_hba_tran_t *tran; 1665 1666 if (scsi_hba_iport_unit_address(devi)) { 1667 return (DDI_SUCCESS); 1668 } 1669 1670 if ((tran = ddi_get_driver_private(devi)) == NULL) 1671 return (DDI_SUCCESS); 1672 1673 mpt = TRAN2MPT(tran); 1674 if (!mpt) { 1675 return (DDI_SUCCESS); 1676 } 1677 1678 mutex_enter(&mpt->m_mutex); 1679 1680 if (mpt->m_suspended++) { 1681 mutex_exit(&mpt->m_mutex); 1682 return (DDI_SUCCESS); 1683 } 1684 1685 /* 1686 * Cancel timeout threads for this mpt 1687 */ 1688 if (mpt->m_quiesce_timeid) { 1689 timeout_id_t tid = mpt->m_quiesce_timeid; 1690 mpt->m_quiesce_timeid = 0; 1691 mutex_exit(&mpt->m_mutex); 1692 (void) untimeout(tid); 1693 mutex_enter(&mpt->m_mutex); 1694 } 1695 1696 if (mpt->m_restart_cmd_timeid) { 1697 timeout_id_t tid = mpt->m_restart_cmd_timeid; 1698 mpt->m_restart_cmd_timeid = 0; 1699 mutex_exit(&mpt->m_mutex); 1700 (void) untimeout(tid); 1701 mutex_enter(&mpt->m_mutex); 1702 } 1703 1704 mutex_exit(&mpt->m_mutex); 1705 1706 (void) pm_idle_component(mpt->m_dip, 0); 1707 1708 /* 1709 * Cancel watch threads if all mpts suspended 1710 */ 1711 rw_enter(&mptsas_global_rwlock, RW_WRITER); 1712 for (g = mptsas_head; g != NULL; g = g->m_next) { 1713 if (!g->m_suspended) 1714 break; 1715 } 1716 rw_exit(&mptsas_global_rwlock); 1717 1718 mutex_enter(&mptsas_global_mutex); 1719 if (g == NULL) { 1720 timeout_id_t tid; 1721 1722 mptsas_timeouts_enabled = 0; 1723 if (mptsas_timeout_id) { 1724 tid = mptsas_timeout_id; 1725 mptsas_timeout_id = 0; 1726 mutex_exit(&mptsas_global_mutex); 1727 (void) untimeout(tid); 1728 mutex_enter(&mptsas_global_mutex); 1729 } 1730 if (mptsas_reset_watch) { 1731 tid = mptsas_reset_watch; 1732 mptsas_reset_watch = 0; 1733 mutex_exit(&mptsas_global_mutex); 1734 (void) untimeout(tid); 1735 mutex_enter(&mptsas_global_mutex); 1736 } 1737 } 1738 mutex_exit(&mptsas_global_mutex); 1739 1740 mutex_enter(&mpt->m_mutex); 1741 1742 /* 1743 * If this mpt is not in full power(PM_LEVEL_D0), just return. 1744 */ 1745 if ((mpt->m_options & MPTSAS_OPT_PM) && 1746 (mpt->m_power_level != PM_LEVEL_D0)) { 1747 mutex_exit(&mpt->m_mutex); 1748 return (DDI_SUCCESS); 1749 } 1750 1751 /* Disable HBA interrupts in hardware */ 1752 MPTSAS_DISABLE_INTR(mpt); 1753 /* 1754 * Send RAID action system shutdown to sync IR 1755 */ 1756 mptsas_raid_action_system_shutdown(mpt); 1757 1758 mutex_exit(&mpt->m_mutex); 1759 1760 /* drain the taskq */ 1761 ddi_taskq_wait(mpt->m_event_taskq); 1762 ddi_taskq_wait(mpt->m_dr_taskq); 1763 1764 return (DDI_SUCCESS); 1765 } 1766 1767 #ifdef __sparc 1768 /*ARGSUSED*/ 1769 static int 1770 mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd) 1771 { 1772 mptsas_t *mpt; 1773 scsi_hba_tran_t *tran; 1774 1775 /* 1776 * If this call is for iport, just return. 1777 */ 1778 if (scsi_hba_iport_unit_address(devi)) 1779 return (DDI_SUCCESS); 1780 1781 if ((tran = ddi_get_driver_private(devi)) == NULL) 1782 return (DDI_SUCCESS); 1783 1784 if ((mpt = TRAN2MPT(tran)) == NULL) 1785 return (DDI_SUCCESS); 1786 1787 /* 1788 * Send RAID action system shutdown to sync IR. Disable HBA 1789 * interrupts in hardware first. 1790 */ 1791 MPTSAS_DISABLE_INTR(mpt); 1792 mptsas_raid_action_system_shutdown(mpt); 1793 1794 return (DDI_SUCCESS); 1795 } 1796 #else /* __sparc */ 1797 /* 1798 * quiesce(9E) entry point. 1799 * 1800 * This function is called when the system is single-threaded at high 1801 * PIL with preemption disabled. Therefore, this function must not be 1802 * blocked. 1803 * 1804 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 1805 * DDI_FAILURE indicates an error condition and should almost never happen. 1806 */ 1807 static int 1808 mptsas_quiesce(dev_info_t *devi) 1809 { 1810 mptsas_t *mpt; 1811 scsi_hba_tran_t *tran; 1812 1813 /* 1814 * If this call is for iport, just return. 1815 */ 1816 if (scsi_hba_iport_unit_address(devi)) 1817 return (DDI_SUCCESS); 1818 1819 if ((tran = ddi_get_driver_private(devi)) == NULL) 1820 return (DDI_SUCCESS); 1821 1822 if ((mpt = TRAN2MPT(tran)) == NULL) 1823 return (DDI_SUCCESS); 1824 1825 /* Disable HBA interrupts in hardware */ 1826 MPTSAS_DISABLE_INTR(mpt); 1827 /* Send RAID action system shutdonw to sync IR */ 1828 mptsas_raid_action_system_shutdown(mpt); 1829 1830 return (DDI_SUCCESS); 1831 } 1832 #endif /* __sparc */ 1833 1834 /* 1835 * detach(9E). Remove all device allocations and system resources; 1836 * disable device interrupts. 1837 * Return DDI_SUCCESS if done; DDI_FAILURE if there's a problem. 1838 */ 1839 static int 1840 mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 1841 { 1842 /* CONSTCOND */ 1843 ASSERT(NO_COMPETING_THREADS); 1844 NDBG0(("mptsas_detach: dip=0x%p cmd=0x%p", (void *)devi, (void *)cmd)); 1845 1846 switch (cmd) { 1847 case DDI_DETACH: 1848 return (mptsas_do_detach(devi)); 1849 1850 case DDI_SUSPEND: 1851 return (mptsas_suspend(devi)); 1852 1853 default: 1854 return (DDI_FAILURE); 1855 } 1856 /* NOTREACHED */ 1857 } 1858 1859 static int 1860 mptsas_do_detach(dev_info_t *dip) 1861 { 1862 mptsas_t *mpt; 1863 scsi_hba_tran_t *tran; 1864 int circ = 0; 1865 int circ1 = 0; 1866 mdi_pathinfo_t *pip = NULL; 1867 int i; 1868 int doneq_thread_num = 0; 1869 1870 NDBG0(("mptsas_do_detach: dip=0x%p", (void *)dip)); 1871 1872 if ((tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == NULL) 1873 return (DDI_FAILURE); 1874 1875 mpt = TRAN2MPT(tran); 1876 if (!mpt) { 1877 return (DDI_FAILURE); 1878 } 1879 /* 1880 * Still have pathinfo child, should not detach mpt driver 1881 */ 1882 if (scsi_hba_iport_unit_address(dip)) { 1883 if (mpt->m_mpxio_enable) { 1884 /* 1885 * MPxIO enabled for the iport 1886 */ 1887 ndi_devi_enter(scsi_vhci_dip, &circ1); 1888 ndi_devi_enter(dip, &circ); 1889 while (pip = mdi_get_next_client_path(dip, NULL)) { 1890 if (mdi_pi_free(pip, 0) == MDI_SUCCESS) { 1891 continue; 1892 } 1893 ndi_devi_exit(dip, circ); 1894 ndi_devi_exit(scsi_vhci_dip, circ1); 1895 NDBG12(("detach failed because of " 1896 "outstanding path info")); 1897 return (DDI_FAILURE); 1898 } 1899 ndi_devi_exit(dip, circ); 1900 ndi_devi_exit(scsi_vhci_dip, circ1); 1901 (void) mdi_phci_unregister(dip, 0); 1902 } 1903 1904 ddi_prop_remove_all(dip); 1905 1906 return (DDI_SUCCESS); 1907 } 1908 1909 /* Make sure power level is D0 before accessing registers */ 1910 if (mpt->m_options & MPTSAS_OPT_PM) { 1911 (void) pm_busy_component(dip, 0); 1912 if (mpt->m_power_level != PM_LEVEL_D0) { 1913 if (pm_raise_power(dip, 0, PM_LEVEL_D0) != 1914 DDI_SUCCESS) { 1915 mptsas_log(mpt, CE_WARN, 1916 "mptsas%d: Raise power request failed.", 1917 mpt->m_instance); 1918 (void) pm_idle_component(dip, 0); 1919 return (DDI_FAILURE); 1920 } 1921 } 1922 } 1923 1924 /* 1925 * Send RAID action system shutdown to sync IR. After action, send a 1926 * Message Unit Reset. Since after that DMA resource will be freed, 1927 * set ioc to READY state will avoid HBA initiated DMA operation. 1928 */ 1929 mutex_enter(&mpt->m_mutex); 1930 MPTSAS_DISABLE_INTR(mpt); 1931 mptsas_raid_action_system_shutdown(mpt); 1932 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1933 (void) mptsas_ioc_reset(mpt, FALSE); 1934 mutex_exit(&mpt->m_mutex); 1935 mptsas_rem_intrs(mpt); 1936 ddi_taskq_destroy(mpt->m_event_taskq); 1937 ddi_taskq_destroy(mpt->m_dr_taskq); 1938 1939 if (mpt->m_doneq_thread_n) { 1940 mutex_enter(&mpt->m_doneq_mutex); 1941 doneq_thread_num = mpt->m_doneq_thread_n; 1942 for (i = 0; i < mpt->m_doneq_thread_n; i++) { 1943 mutex_enter(&mpt->m_doneq_thread_id[i].mutex); 1944 mpt->m_doneq_thread_id[i].flag &= 1945 (~MPTSAS_DONEQ_THREAD_ACTIVE); 1946 cv_signal(&mpt->m_doneq_thread_id[i].cv); 1947 mutex_exit(&mpt->m_doneq_thread_id[i].mutex); 1948 } 1949 while (mpt->m_doneq_thread_n) { 1950 cv_wait(&mpt->m_doneq_thread_cv, 1951 &mpt->m_doneq_mutex); 1952 } 1953 for (i = 0; i < doneq_thread_num; i++) { 1954 cv_destroy(&mpt->m_doneq_thread_id[i].cv); 1955 mutex_destroy(&mpt->m_doneq_thread_id[i].mutex); 1956 } 1957 kmem_free(mpt->m_doneq_thread_id, 1958 sizeof (mptsas_doneq_thread_list_t) 1959 * doneq_thread_num); 1960 mutex_exit(&mpt->m_doneq_mutex); 1961 cv_destroy(&mpt->m_doneq_thread_cv); 1962 mutex_destroy(&mpt->m_doneq_mutex); 1963 } 1964 1965 scsi_hba_reset_notify_tear_down(mpt->m_reset_notify_listf); 1966 1967 mptsas_list_del(mpt); 1968 1969 /* 1970 * Cancel timeout threads for this mpt 1971 */ 1972 mutex_enter(&mpt->m_mutex); 1973 if (mpt->m_quiesce_timeid) { 1974 timeout_id_t tid = mpt->m_quiesce_timeid; 1975 mpt->m_quiesce_timeid = 0; 1976 mutex_exit(&mpt->m_mutex); 1977 (void) untimeout(tid); 1978 mutex_enter(&mpt->m_mutex); 1979 } 1980 1981 if (mpt->m_restart_cmd_timeid) { 1982 timeout_id_t tid = mpt->m_restart_cmd_timeid; 1983 mpt->m_restart_cmd_timeid = 0; 1984 mutex_exit(&mpt->m_mutex); 1985 (void) untimeout(tid); 1986 mutex_enter(&mpt->m_mutex); 1987 } 1988 1989 mutex_exit(&mpt->m_mutex); 1990 1991 /* 1992 * last mpt? ... if active, CANCEL watch threads. 1993 */ 1994 mutex_enter(&mptsas_global_mutex); 1995 if (mptsas_head == NULL) { 1996 timeout_id_t tid; 1997 /* 1998 * Clear mptsas_timeouts_enable so that the watch thread 1999 * gets restarted on DDI_ATTACH 2000 */ 2001 mptsas_timeouts_enabled = 0; 2002 if (mptsas_timeout_id) { 2003 tid = mptsas_timeout_id; 2004 mptsas_timeout_id = 0; 2005 mutex_exit(&mptsas_global_mutex); 2006 (void) untimeout(tid); 2007 mutex_enter(&mptsas_global_mutex); 2008 } 2009 if (mptsas_reset_watch) { 2010 tid = mptsas_reset_watch; 2011 mptsas_reset_watch = 0; 2012 mutex_exit(&mptsas_global_mutex); 2013 (void) untimeout(tid); 2014 mutex_enter(&mptsas_global_mutex); 2015 } 2016 } 2017 mutex_exit(&mptsas_global_mutex); 2018 2019 /* 2020 * Delete Phy stats 2021 */ 2022 mptsas_destroy_phy_stats(mpt); 2023 2024 mptsas_destroy_hashes(mpt); 2025 2026 /* 2027 * Delete nt_active. 2028 */ 2029 mutex_enter(&mpt->m_mutex); 2030 mptsas_free_active_slots(mpt); 2031 mutex_exit(&mpt->m_mutex); 2032 2033 /* deallocate everything that was allocated in mptsas_attach */ 2034 mptsas_cache_destroy(mpt); 2035 2036 mptsas_hba_fini(mpt); 2037 mptsas_cfg_fini(mpt); 2038 2039 /* Lower the power informing PM Framework */ 2040 if (mpt->m_options & MPTSAS_OPT_PM) { 2041 if (pm_lower_power(dip, 0, PM_LEVEL_D3) != DDI_SUCCESS) 2042 mptsas_log(mpt, CE_WARN, 2043 "!mptsas%d: Lower power request failed " 2044 "during detach, ignoring.", 2045 mpt->m_instance); 2046 } 2047 2048 mutex_destroy(&mpt->m_tx_waitq_mutex); 2049 mutex_destroy(&mpt->m_passthru_mutex); 2050 mutex_destroy(&mpt->m_mutex); 2051 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 2052 mutex_destroy(&mpt->m_phy_info[i].smhba_info.phy_mutex); 2053 } 2054 cv_destroy(&mpt->m_cv); 2055 cv_destroy(&mpt->m_passthru_cv); 2056 cv_destroy(&mpt->m_fw_cv); 2057 cv_destroy(&mpt->m_config_cv); 2058 cv_destroy(&mpt->m_fw_diag_cv); 2059 cv_destroy(&mpt->m_extreq_sense_refcount_cv); 2060 2061 mptsas_smp_teardown(mpt); 2062 mptsas_hba_teardown(mpt); 2063 2064 mptsas_config_space_fini(mpt); 2065 2066 mptsas_free_handshake_msg(mpt); 2067 2068 mptsas_fm_fini(mpt); 2069 ddi_soft_state_free(mptsas_state, ddi_get_instance(dip)); 2070 ddi_prop_remove_all(dip); 2071 2072 return (DDI_SUCCESS); 2073 } 2074 2075 static void 2076 mptsas_list_add(mptsas_t *mpt) 2077 { 2078 rw_enter(&mptsas_global_rwlock, RW_WRITER); 2079 2080 if (mptsas_head == NULL) { 2081 mptsas_head = mpt; 2082 } else { 2083 mptsas_tail->m_next = mpt; 2084 } 2085 mptsas_tail = mpt; 2086 rw_exit(&mptsas_global_rwlock); 2087 } 2088 2089 static void 2090 mptsas_list_del(mptsas_t *mpt) 2091 { 2092 mptsas_t *m; 2093 /* 2094 * Remove device instance from the global linked list 2095 */ 2096 rw_enter(&mptsas_global_rwlock, RW_WRITER); 2097 if (mptsas_head == mpt) { 2098 m = mptsas_head = mpt->m_next; 2099 } else { 2100 for (m = mptsas_head; m != NULL; m = m->m_next) { 2101 if (m->m_next == mpt) { 2102 m->m_next = mpt->m_next; 2103 break; 2104 } 2105 } 2106 if (m == NULL) { 2107 mptsas_log(mpt, CE_PANIC, "Not in softc list!"); 2108 } 2109 } 2110 2111 if (mptsas_tail == mpt) { 2112 mptsas_tail = m; 2113 } 2114 rw_exit(&mptsas_global_rwlock); 2115 } 2116 2117 static int 2118 mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size) 2119 { 2120 ddi_dma_attr_t task_dma_attrs; 2121 2122 mpt->m_hshk_dma_size = 0; 2123 task_dma_attrs = mpt->m_msg_dma_attr; 2124 task_dma_attrs.dma_attr_sgllen = 1; 2125 task_dma_attrs.dma_attr_granular = (uint32_t)(alloc_size); 2126 2127 /* allocate Task Management ddi_dma resources */ 2128 if (mptsas_dma_addr_create(mpt, task_dma_attrs, 2129 &mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl, &mpt->m_hshk_memp, 2130 alloc_size, NULL) == FALSE) { 2131 return (DDI_FAILURE); 2132 } 2133 mpt->m_hshk_dma_size = alloc_size; 2134 2135 return (DDI_SUCCESS); 2136 } 2137 2138 static void 2139 mptsas_free_handshake_msg(mptsas_t *mpt) 2140 { 2141 if (mpt->m_hshk_dma_size == 0) 2142 return; 2143 mptsas_dma_addr_destroy(&mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl); 2144 mpt->m_hshk_dma_size = 0; 2145 } 2146 2147 static int 2148 mptsas_hba_setup(mptsas_t *mpt) 2149 { 2150 scsi_hba_tran_t *hba_tran; 2151 int tran_flags; 2152 2153 /* Allocate a transport structure */ 2154 hba_tran = mpt->m_tran = scsi_hba_tran_alloc(mpt->m_dip, 2155 SCSI_HBA_CANSLEEP); 2156 ASSERT(mpt->m_tran != NULL); 2157 2158 hba_tran->tran_hba_private = mpt; 2159 hba_tran->tran_tgt_private = NULL; 2160 2161 hba_tran->tran_tgt_init = mptsas_scsi_tgt_init; 2162 hba_tran->tran_tgt_free = mptsas_scsi_tgt_free; 2163 2164 hba_tran->tran_start = mptsas_scsi_start; 2165 hba_tran->tran_reset = mptsas_scsi_reset; 2166 hba_tran->tran_abort = mptsas_scsi_abort; 2167 hba_tran->tran_getcap = mptsas_scsi_getcap; 2168 hba_tran->tran_setcap = mptsas_scsi_setcap; 2169 hba_tran->tran_init_pkt = mptsas_scsi_init_pkt; 2170 hba_tran->tran_destroy_pkt = mptsas_scsi_destroy_pkt; 2171 2172 hba_tran->tran_dmafree = mptsas_scsi_dmafree; 2173 hba_tran->tran_sync_pkt = mptsas_scsi_sync_pkt; 2174 hba_tran->tran_reset_notify = mptsas_scsi_reset_notify; 2175 2176 hba_tran->tran_get_bus_addr = mptsas_get_bus_addr; 2177 hba_tran->tran_get_name = mptsas_get_name; 2178 2179 hba_tran->tran_quiesce = mptsas_scsi_quiesce; 2180 hba_tran->tran_unquiesce = mptsas_scsi_unquiesce; 2181 hba_tran->tran_bus_reset = NULL; 2182 2183 hba_tran->tran_add_eventcall = NULL; 2184 hba_tran->tran_get_eventcookie = NULL; 2185 hba_tran->tran_post_event = NULL; 2186 hba_tran->tran_remove_eventcall = NULL; 2187 2188 hba_tran->tran_bus_config = mptsas_bus_config; 2189 2190 hba_tran->tran_interconnect_type = INTERCONNECT_SAS; 2191 2192 /* 2193 * All children of the HBA are iports. We need tran was cloned. 2194 * So we pass the flags to SCSA. SCSI_HBA_TRAN_CLONE will be 2195 * inherited to iport's tran vector. 2196 */ 2197 tran_flags = (SCSI_HBA_HBA | SCSI_HBA_TRAN_CLONE); 2198 2199 if (scsi_hba_attach_setup(mpt->m_dip, &mpt->m_msg_dma_attr, 2200 hba_tran, tran_flags) != DDI_SUCCESS) { 2201 mptsas_log(mpt, CE_WARN, "hba attach setup failed"); 2202 scsi_hba_tran_free(hba_tran); 2203 mpt->m_tran = NULL; 2204 return (FALSE); 2205 } 2206 return (TRUE); 2207 } 2208 2209 static void 2210 mptsas_hba_teardown(mptsas_t *mpt) 2211 { 2212 (void) scsi_hba_detach(mpt->m_dip); 2213 if (mpt->m_tran != NULL) { 2214 scsi_hba_tran_free(mpt->m_tran); 2215 mpt->m_tran = NULL; 2216 } 2217 } 2218 2219 static void 2220 mptsas_iport_register(mptsas_t *mpt) 2221 { 2222 int i, j; 2223 mptsas_phymask_t mask = 0x0; 2224 /* 2225 * initial value of mask is 0 2226 */ 2227 mutex_enter(&mpt->m_mutex); 2228 for (i = 0; i < mpt->m_num_phys; i++) { 2229 mptsas_phymask_t phy_mask = 0x0; 2230 char phy_mask_name[MPTSAS_MAX_PHYS]; 2231 uint8_t current_port; 2232 2233 if (mpt->m_phy_info[i].attached_devhdl == 0) 2234 continue; 2235 2236 bzero(phy_mask_name, sizeof (phy_mask_name)); 2237 2238 current_port = mpt->m_phy_info[i].port_num; 2239 2240 if ((mask & (1 << i)) != 0) 2241 continue; 2242 2243 for (j = 0; j < mpt->m_num_phys; j++) { 2244 if (mpt->m_phy_info[j].attached_devhdl && 2245 (mpt->m_phy_info[j].port_num == current_port)) { 2246 phy_mask |= (1 << j); 2247 } 2248 } 2249 mask = mask | phy_mask; 2250 2251 for (j = 0; j < mpt->m_num_phys; j++) { 2252 if ((phy_mask >> j) & 0x01) { 2253 mpt->m_phy_info[j].phy_mask = phy_mask; 2254 } 2255 } 2256 2257 (void) sprintf(phy_mask_name, "%x", phy_mask); 2258 2259 mutex_exit(&mpt->m_mutex); 2260 /* 2261 * register a iport 2262 */ 2263 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name); 2264 mutex_enter(&mpt->m_mutex); 2265 } 2266 mutex_exit(&mpt->m_mutex); 2267 /* 2268 * register a virtual port for RAID volume always 2269 */ 2270 (void) scsi_hba_iport_register(mpt->m_dip, "v0"); 2271 2272 } 2273 2274 static int 2275 mptsas_smp_setup(mptsas_t *mpt) 2276 { 2277 mpt->m_smptran = smp_hba_tran_alloc(mpt->m_dip); 2278 ASSERT(mpt->m_smptran != NULL); 2279 mpt->m_smptran->smp_tran_hba_private = mpt; 2280 mpt->m_smptran->smp_tran_start = mptsas_smp_start; 2281 if (smp_hba_attach_setup(mpt->m_dip, mpt->m_smptran) != DDI_SUCCESS) { 2282 mptsas_log(mpt, CE_WARN, "smp attach setup failed"); 2283 smp_hba_tran_free(mpt->m_smptran); 2284 mpt->m_smptran = NULL; 2285 return (FALSE); 2286 } 2287 /* 2288 * Initialize smp hash table 2289 */ 2290 mpt->m_smp_targets = refhash_create(MPTSAS_SMP_BUCKET_COUNT, 2291 mptsas_target_addr_hash, mptsas_target_addr_cmp, 2292 mptsas_smp_free, sizeof (mptsas_smp_t), 2293 offsetof(mptsas_smp_t, m_link), offsetof(mptsas_smp_t, m_addr), 2294 KM_SLEEP); 2295 mpt->m_smp_devhdl = 0xFFFF; 2296 2297 return (TRUE); 2298 } 2299 2300 static void 2301 mptsas_smp_teardown(mptsas_t *mpt) 2302 { 2303 (void) smp_hba_detach(mpt->m_dip); 2304 if (mpt->m_smptran != NULL) { 2305 smp_hba_tran_free(mpt->m_smptran); 2306 mpt->m_smptran = NULL; 2307 } 2308 mpt->m_smp_devhdl = 0; 2309 } 2310 2311 static int 2312 mptsas_cache_create(mptsas_t *mpt) 2313 { 2314 int instance = mpt->m_instance; 2315 char buf[64]; 2316 2317 /* 2318 * create kmem cache for packets 2319 */ 2320 (void) sprintf(buf, "mptsas%d_cache", instance); 2321 mpt->m_kmem_cache = kmem_cache_create(buf, 2322 sizeof (struct mptsas_cmd) + scsi_pkt_size(), 8, 2323 mptsas_kmem_cache_constructor, mptsas_kmem_cache_destructor, 2324 NULL, (void *)mpt, NULL, 0); 2325 2326 if (mpt->m_kmem_cache == NULL) { 2327 mptsas_log(mpt, CE_WARN, "creating kmem cache failed"); 2328 return (FALSE); 2329 } 2330 2331 /* 2332 * create kmem cache for extra SGL frames if SGL cannot 2333 * be accomodated into main request frame. 2334 */ 2335 (void) sprintf(buf, "mptsas%d_cache_frames", instance); 2336 mpt->m_cache_frames = kmem_cache_create(buf, 2337 sizeof (mptsas_cache_frames_t), 8, 2338 mptsas_cache_frames_constructor, mptsas_cache_frames_destructor, 2339 NULL, (void *)mpt, NULL, 0); 2340 2341 if (mpt->m_cache_frames == NULL) { 2342 mptsas_log(mpt, CE_WARN, "creating cache for frames failed"); 2343 return (FALSE); 2344 } 2345 2346 return (TRUE); 2347 } 2348 2349 static void 2350 mptsas_cache_destroy(mptsas_t *mpt) 2351 { 2352 /* deallocate in reverse order */ 2353 if (mpt->m_cache_frames) { 2354 kmem_cache_destroy(mpt->m_cache_frames); 2355 mpt->m_cache_frames = NULL; 2356 } 2357 if (mpt->m_kmem_cache) { 2358 kmem_cache_destroy(mpt->m_kmem_cache); 2359 mpt->m_kmem_cache = NULL; 2360 } 2361 } 2362 2363 static int 2364 mptsas_power(dev_info_t *dip, int component, int level) 2365 { 2366 #ifndef __lock_lint 2367 _NOTE(ARGUNUSED(component)) 2368 #endif 2369 mptsas_t *mpt; 2370 int rval = DDI_SUCCESS; 2371 int polls = 0; 2372 uint32_t ioc_status; 2373 2374 if (scsi_hba_iport_unit_address(dip) != 0) 2375 return (DDI_SUCCESS); 2376 2377 mpt = ddi_get_soft_state(mptsas_state, ddi_get_instance(dip)); 2378 if (mpt == NULL) { 2379 return (DDI_FAILURE); 2380 } 2381 2382 mutex_enter(&mpt->m_mutex); 2383 2384 /* 2385 * If the device is busy, don't lower its power level 2386 */ 2387 if (mpt->m_busy && (mpt->m_power_level > level)) { 2388 mutex_exit(&mpt->m_mutex); 2389 return (DDI_FAILURE); 2390 } 2391 switch (level) { 2392 case PM_LEVEL_D0: 2393 NDBG11(("mptsas%d: turning power ON.", mpt->m_instance)); 2394 MPTSAS_POWER_ON(mpt); 2395 /* 2396 * Wait up to 30 seconds for IOC to come out of reset. 2397 */ 2398 while (((ioc_status = ddi_get32(mpt->m_datap, 2399 &mpt->m_reg->Doorbell)) & 2400 MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_RESET) { 2401 if (polls++ > 3000) { 2402 break; 2403 } 2404 delay(drv_usectohz(10000)); 2405 } 2406 /* 2407 * If IOC is not in operational state, try to hard reset it. 2408 */ 2409 if ((ioc_status & MPI2_IOC_STATE_MASK) != 2410 MPI2_IOC_STATE_OPERATIONAL) { 2411 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 2412 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) { 2413 mptsas_log(mpt, CE_WARN, 2414 "mptsas_power: hard reset failed"); 2415 mutex_exit(&mpt->m_mutex); 2416 return (DDI_FAILURE); 2417 } 2418 } 2419 mpt->m_power_level = PM_LEVEL_D0; 2420 break; 2421 case PM_LEVEL_D3: 2422 NDBG11(("mptsas%d: turning power OFF.", mpt->m_instance)); 2423 MPTSAS_POWER_OFF(mpt); 2424 break; 2425 default: 2426 mptsas_log(mpt, CE_WARN, "mptsas%d: unknown power level <%x>.", 2427 mpt->m_instance, level); 2428 rval = DDI_FAILURE; 2429 break; 2430 } 2431 mutex_exit(&mpt->m_mutex); 2432 return (rval); 2433 } 2434 2435 /* 2436 * Initialize configuration space and figure out which 2437 * chip and revison of the chip the mpt driver is using. 2438 */ 2439 static int 2440 mptsas_config_space_init(mptsas_t *mpt) 2441 { 2442 NDBG0(("mptsas_config_space_init")); 2443 2444 if (mpt->m_config_handle != NULL) 2445 return (TRUE); 2446 2447 if (pci_config_setup(mpt->m_dip, 2448 &mpt->m_config_handle) != DDI_SUCCESS) { 2449 mptsas_log(mpt, CE_WARN, "cannot map configuration space."); 2450 return (FALSE); 2451 } 2452 2453 /* 2454 * This is a workaround for a XMITS ASIC bug which does not 2455 * drive the CBE upper bits. 2456 */ 2457 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) & 2458 PCI_STAT_PERROR) { 2459 pci_config_put16(mpt->m_config_handle, PCI_CONF_STAT, 2460 PCI_STAT_PERROR); 2461 } 2462 2463 mptsas_setup_cmd_reg(mpt); 2464 2465 /* 2466 * Get the chip device id: 2467 */ 2468 mpt->m_devid = pci_config_get16(mpt->m_config_handle, PCI_CONF_DEVID); 2469 2470 /* 2471 * Save the revision. 2472 */ 2473 mpt->m_revid = pci_config_get8(mpt->m_config_handle, PCI_CONF_REVID); 2474 2475 /* 2476 * Save the SubSystem Vendor and Device IDs 2477 */ 2478 mpt->m_svid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBVENID); 2479 mpt->m_ssid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBSYSID); 2480 2481 /* 2482 * Set the latency timer to 0x40 as specified by the upa -> pci 2483 * bridge chip design team. This may be done by the sparc pci 2484 * bus nexus driver, but the driver should make sure the latency 2485 * timer is correct for performance reasons. 2486 */ 2487 pci_config_put8(mpt->m_config_handle, PCI_CONF_LATENCY_TIMER, 2488 MPTSAS_LATENCY_TIMER); 2489 2490 (void) mptsas_get_pci_cap(mpt); 2491 return (TRUE); 2492 } 2493 2494 static void 2495 mptsas_config_space_fini(mptsas_t *mpt) 2496 { 2497 if (mpt->m_config_handle != NULL) { 2498 mptsas_disable_bus_master(mpt); 2499 pci_config_teardown(&mpt->m_config_handle); 2500 mpt->m_config_handle = NULL; 2501 } 2502 } 2503 2504 static void 2505 mptsas_setup_cmd_reg(mptsas_t *mpt) 2506 { 2507 ushort_t cmdreg; 2508 2509 /* 2510 * Set the command register to the needed values. 2511 */ 2512 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM); 2513 cmdreg |= (PCI_COMM_ME | PCI_COMM_SERR_ENABLE | 2514 PCI_COMM_PARITY_DETECT | PCI_COMM_MAE); 2515 cmdreg &= ~PCI_COMM_IO; 2516 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg); 2517 } 2518 2519 static void 2520 mptsas_disable_bus_master(mptsas_t *mpt) 2521 { 2522 ushort_t cmdreg; 2523 2524 /* 2525 * Clear the master enable bit in the PCI command register. 2526 * This prevents any bus mastering activity like DMA. 2527 */ 2528 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM); 2529 cmdreg &= ~PCI_COMM_ME; 2530 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg); 2531 } 2532 2533 int 2534 mptsas_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep) 2535 { 2536 ddi_dma_attr_t attrs; 2537 2538 attrs = mpt->m_io_dma_attr; 2539 attrs.dma_attr_sgllen = 1; 2540 2541 ASSERT(dma_statep != NULL); 2542 2543 if (mptsas_dma_addr_create(mpt, attrs, &dma_statep->handle, 2544 &dma_statep->accessp, &dma_statep->memp, dma_statep->size, 2545 &dma_statep->cookie) == FALSE) { 2546 return (DDI_FAILURE); 2547 } 2548 2549 return (DDI_SUCCESS); 2550 } 2551 2552 void 2553 mptsas_dma_free(mptsas_dma_alloc_state_t *dma_statep) 2554 { 2555 ASSERT(dma_statep != NULL); 2556 mptsas_dma_addr_destroy(&dma_statep->handle, &dma_statep->accessp); 2557 dma_statep->size = 0; 2558 } 2559 2560 int 2561 mptsas_do_dma(mptsas_t *mpt, uint32_t size, int var, int (*callback)()) 2562 { 2563 ddi_dma_attr_t attrs; 2564 ddi_dma_handle_t dma_handle; 2565 caddr_t memp; 2566 ddi_acc_handle_t accessp; 2567 int rval; 2568 2569 ASSERT(mutex_owned(&mpt->m_mutex)); 2570 2571 attrs = mpt->m_msg_dma_attr; 2572 attrs.dma_attr_sgllen = 1; 2573 attrs.dma_attr_granular = size; 2574 2575 if (mptsas_dma_addr_create(mpt, attrs, &dma_handle, 2576 &accessp, &memp, size, NULL) == FALSE) { 2577 return (DDI_FAILURE); 2578 } 2579 2580 rval = (*callback) (mpt, memp, var, accessp); 2581 2582 if ((mptsas_check_dma_handle(dma_handle) != DDI_SUCCESS) || 2583 (mptsas_check_acc_handle(accessp) != DDI_SUCCESS)) { 2584 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 2585 rval = DDI_FAILURE; 2586 } 2587 2588 mptsas_dma_addr_destroy(&dma_handle, &accessp); 2589 return (rval); 2590 2591 } 2592 2593 static int 2594 mptsas_alloc_request_frames(mptsas_t *mpt) 2595 { 2596 ddi_dma_attr_t frame_dma_attrs; 2597 caddr_t memp; 2598 ddi_dma_cookie_t cookie; 2599 size_t mem_size; 2600 2601 /* 2602 * re-alloc when it has already alloced 2603 */ 2604 if (mpt->m_dma_req_frame_hdl) 2605 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl, 2606 &mpt->m_acc_req_frame_hdl); 2607 2608 /* 2609 * The size of the request frame pool is: 2610 * Number of Request Frames * Request Frame Size 2611 */ 2612 mem_size = mpt->m_max_requests * mpt->m_req_frame_size; 2613 2614 /* 2615 * set the DMA attributes. System Request Message Frames must be 2616 * aligned on a 16-byte boundry. 2617 */ 2618 frame_dma_attrs = mpt->m_msg_dma_attr; 2619 frame_dma_attrs.dma_attr_align = 16; 2620 frame_dma_attrs.dma_attr_sgllen = 1; 2621 2622 /* 2623 * allocate the request frame pool. 2624 */ 2625 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2626 &mpt->m_dma_req_frame_hdl, &mpt->m_acc_req_frame_hdl, &memp, 2627 mem_size, &cookie) == FALSE) { 2628 return (DDI_FAILURE); 2629 } 2630 2631 /* 2632 * Store the request frame memory address. This chip uses this 2633 * address to dma to and from the driver's frame. The second 2634 * address is the address mpt uses to fill in the frame. 2635 */ 2636 mpt->m_req_frame_dma_addr = cookie.dmac_laddress; 2637 mpt->m_req_frame = memp; 2638 2639 /* 2640 * Clear the request frame pool. 2641 */ 2642 bzero(mpt->m_req_frame, mem_size); 2643 2644 return (DDI_SUCCESS); 2645 } 2646 2647 static int 2648 mptsas_alloc_sense_bufs(mptsas_t *mpt) 2649 { 2650 ddi_dma_attr_t sense_dma_attrs; 2651 caddr_t memp; 2652 ddi_dma_cookie_t cookie; 2653 size_t mem_size; 2654 int num_extrqsense_bufs; 2655 2656 ASSERT(mpt->m_extreq_sense_refcount == 0); 2657 2658 /* 2659 * re-alloc when it has already alloced 2660 */ 2661 if (mpt->m_dma_req_sense_hdl) { 2662 rmfreemap(mpt->m_erqsense_map); 2663 mptsas_dma_addr_destroy(&mpt->m_dma_req_sense_hdl, 2664 &mpt->m_acc_req_sense_hdl); 2665 } 2666 2667 /* 2668 * The size of the request sense pool is: 2669 * (Number of Request Frames - 2 ) * Request Sense Size + 2670 * extra memory for extended sense requests. 2671 */ 2672 mem_size = ((mpt->m_max_requests - 2) * mpt->m_req_sense_size) + 2673 mptsas_extreq_sense_bufsize; 2674 2675 /* 2676 * set the DMA attributes. ARQ buffers 2677 * aligned on a 16-byte boundry. 2678 */ 2679 sense_dma_attrs = mpt->m_msg_dma_attr; 2680 sense_dma_attrs.dma_attr_align = 16; 2681 sense_dma_attrs.dma_attr_sgllen = 1; 2682 2683 /* 2684 * allocate the request sense buffer pool. 2685 */ 2686 if (mptsas_dma_addr_create(mpt, sense_dma_attrs, 2687 &mpt->m_dma_req_sense_hdl, &mpt->m_acc_req_sense_hdl, &memp, 2688 mem_size, &cookie) == FALSE) { 2689 return (DDI_FAILURE); 2690 } 2691 2692 /* 2693 * Store the request sense base memory address. This chip uses this 2694 * address to dma the request sense data. The second 2695 * address is the address mpt uses to access the data. 2696 * The third is the base for the extended rqsense buffers. 2697 */ 2698 mpt->m_req_sense_dma_addr = cookie.dmac_laddress; 2699 mpt->m_req_sense = memp; 2700 memp += (mpt->m_max_requests - 2) * mpt->m_req_sense_size; 2701 mpt->m_extreq_sense = memp; 2702 2703 /* 2704 * The extra memory is divided up into multiples of the base 2705 * buffer size in order to allocate via rmalloc(). 2706 * Note that the rmallocmap cannot start at zero! 2707 */ 2708 num_extrqsense_bufs = mptsas_extreq_sense_bufsize / 2709 mpt->m_req_sense_size; 2710 mpt->m_erqsense_map = rmallocmap_wait(num_extrqsense_bufs); 2711 rmfree(mpt->m_erqsense_map, num_extrqsense_bufs, 1); 2712 2713 /* 2714 * Clear the pool. 2715 */ 2716 bzero(mpt->m_req_sense, mem_size); 2717 2718 return (DDI_SUCCESS); 2719 } 2720 2721 static int 2722 mptsas_alloc_reply_frames(mptsas_t *mpt) 2723 { 2724 ddi_dma_attr_t frame_dma_attrs; 2725 caddr_t memp; 2726 ddi_dma_cookie_t cookie; 2727 size_t mem_size; 2728 2729 /* 2730 * re-alloc when it has already alloced 2731 */ 2732 if (mpt->m_dma_reply_frame_hdl) { 2733 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl, 2734 &mpt->m_acc_reply_frame_hdl); 2735 } 2736 2737 /* 2738 * The size of the reply frame pool is: 2739 * Number of Reply Frames * Reply Frame Size 2740 */ 2741 mem_size = mpt->m_max_replies * mpt->m_reply_frame_size; 2742 2743 /* 2744 * set the DMA attributes. System Reply Message Frames must be 2745 * aligned on a 4-byte boundry. This is the default. 2746 */ 2747 frame_dma_attrs = mpt->m_msg_dma_attr; 2748 frame_dma_attrs.dma_attr_sgllen = 1; 2749 2750 /* 2751 * allocate the reply frame pool 2752 */ 2753 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2754 &mpt->m_dma_reply_frame_hdl, &mpt->m_acc_reply_frame_hdl, &memp, 2755 mem_size, &cookie) == FALSE) { 2756 return (DDI_FAILURE); 2757 } 2758 2759 /* 2760 * Store the reply frame memory address. This chip uses this 2761 * address to dma to and from the driver's frame. The second 2762 * address is the address mpt uses to process the frame. 2763 */ 2764 mpt->m_reply_frame_dma_addr = cookie.dmac_laddress; 2765 mpt->m_reply_frame = memp; 2766 2767 /* 2768 * Clear the reply frame pool. 2769 */ 2770 bzero(mpt->m_reply_frame, mem_size); 2771 2772 return (DDI_SUCCESS); 2773 } 2774 2775 static int 2776 mptsas_alloc_free_queue(mptsas_t *mpt) 2777 { 2778 ddi_dma_attr_t frame_dma_attrs; 2779 caddr_t memp; 2780 ddi_dma_cookie_t cookie; 2781 size_t mem_size; 2782 2783 /* 2784 * re-alloc when it has already alloced 2785 */ 2786 if (mpt->m_dma_free_queue_hdl) { 2787 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl, 2788 &mpt->m_acc_free_queue_hdl); 2789 } 2790 2791 /* 2792 * The reply free queue size is: 2793 * Reply Free Queue Depth * 4 2794 * The "4" is the size of one 32 bit address (low part of 64-bit 2795 * address) 2796 */ 2797 mem_size = mpt->m_free_queue_depth * 4; 2798 2799 /* 2800 * set the DMA attributes The Reply Free Queue must be aligned on a 2801 * 16-byte boundry. 2802 */ 2803 frame_dma_attrs = mpt->m_msg_dma_attr; 2804 frame_dma_attrs.dma_attr_align = 16; 2805 frame_dma_attrs.dma_attr_sgllen = 1; 2806 2807 /* 2808 * allocate the reply free queue 2809 */ 2810 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2811 &mpt->m_dma_free_queue_hdl, &mpt->m_acc_free_queue_hdl, &memp, 2812 mem_size, &cookie) == FALSE) { 2813 return (DDI_FAILURE); 2814 } 2815 2816 /* 2817 * Store the reply free queue memory address. This chip uses this 2818 * address to read from the reply free queue. The second address 2819 * is the address mpt uses to manage the queue. 2820 */ 2821 mpt->m_free_queue_dma_addr = cookie.dmac_laddress; 2822 mpt->m_free_queue = memp; 2823 2824 /* 2825 * Clear the reply free queue memory. 2826 */ 2827 bzero(mpt->m_free_queue, mem_size); 2828 2829 return (DDI_SUCCESS); 2830 } 2831 2832 static int 2833 mptsas_alloc_post_queue(mptsas_t *mpt) 2834 { 2835 ddi_dma_attr_t frame_dma_attrs; 2836 caddr_t memp; 2837 ddi_dma_cookie_t cookie; 2838 size_t mem_size; 2839 2840 /* 2841 * re-alloc when it has already alloced 2842 */ 2843 if (mpt->m_dma_post_queue_hdl) { 2844 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl, 2845 &mpt->m_acc_post_queue_hdl); 2846 } 2847 2848 /* 2849 * The reply descriptor post queue size is: 2850 * Reply Descriptor Post Queue Depth * 8 2851 * The "8" is the size of each descriptor (8 bytes or 64 bits). 2852 */ 2853 mem_size = mpt->m_post_queue_depth * 8; 2854 2855 /* 2856 * set the DMA attributes. The Reply Descriptor Post Queue must be 2857 * aligned on a 16-byte boundry. 2858 */ 2859 frame_dma_attrs = mpt->m_msg_dma_attr; 2860 frame_dma_attrs.dma_attr_align = 16; 2861 frame_dma_attrs.dma_attr_sgllen = 1; 2862 2863 /* 2864 * allocate the reply post queue 2865 */ 2866 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2867 &mpt->m_dma_post_queue_hdl, &mpt->m_acc_post_queue_hdl, &memp, 2868 mem_size, &cookie) == FALSE) { 2869 return (DDI_FAILURE); 2870 } 2871 2872 /* 2873 * Store the reply descriptor post queue memory address. This chip 2874 * uses this address to write to the reply descriptor post queue. The 2875 * second address is the address mpt uses to manage the queue. 2876 */ 2877 mpt->m_post_queue_dma_addr = cookie.dmac_laddress; 2878 mpt->m_post_queue = memp; 2879 2880 /* 2881 * Clear the reply post queue memory. 2882 */ 2883 bzero(mpt->m_post_queue, mem_size); 2884 2885 return (DDI_SUCCESS); 2886 } 2887 2888 static void 2889 mptsas_alloc_reply_args(mptsas_t *mpt) 2890 { 2891 if (mpt->m_replyh_args == NULL) { 2892 mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) * 2893 mpt->m_max_replies, KM_SLEEP); 2894 } 2895 } 2896 2897 static int 2898 mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd) 2899 { 2900 mptsas_cache_frames_t *frames = NULL; 2901 if (cmd->cmd_extra_frames == NULL) { 2902 frames = kmem_cache_alloc(mpt->m_cache_frames, KM_NOSLEEP); 2903 if (frames == NULL) { 2904 return (DDI_FAILURE); 2905 } 2906 cmd->cmd_extra_frames = frames; 2907 } 2908 return (DDI_SUCCESS); 2909 } 2910 2911 static void 2912 mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd) 2913 { 2914 if (cmd->cmd_extra_frames) { 2915 kmem_cache_free(mpt->m_cache_frames, 2916 (void *)cmd->cmd_extra_frames); 2917 cmd->cmd_extra_frames = NULL; 2918 } 2919 } 2920 2921 static void 2922 mptsas_cfg_fini(mptsas_t *mpt) 2923 { 2924 NDBG0(("mptsas_cfg_fini")); 2925 ddi_regs_map_free(&mpt->m_datap); 2926 } 2927 2928 static void 2929 mptsas_hba_fini(mptsas_t *mpt) 2930 { 2931 NDBG0(("mptsas_hba_fini")); 2932 2933 /* 2934 * Free up any allocated memory 2935 */ 2936 if (mpt->m_dma_req_frame_hdl) { 2937 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl, 2938 &mpt->m_acc_req_frame_hdl); 2939 } 2940 2941 if (mpt->m_dma_req_sense_hdl) { 2942 rmfreemap(mpt->m_erqsense_map); 2943 mptsas_dma_addr_destroy(&mpt->m_dma_req_sense_hdl, 2944 &mpt->m_acc_req_sense_hdl); 2945 } 2946 2947 if (mpt->m_dma_reply_frame_hdl) { 2948 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl, 2949 &mpt->m_acc_reply_frame_hdl); 2950 } 2951 2952 if (mpt->m_dma_free_queue_hdl) { 2953 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl, 2954 &mpt->m_acc_free_queue_hdl); 2955 } 2956 2957 if (mpt->m_dma_post_queue_hdl) { 2958 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl, 2959 &mpt->m_acc_post_queue_hdl); 2960 } 2961 2962 if (mpt->m_replyh_args != NULL) { 2963 kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t) 2964 * mpt->m_max_replies); 2965 } 2966 } 2967 2968 static int 2969 mptsas_name_child(dev_info_t *lun_dip, char *name, int len) 2970 { 2971 int lun = 0; 2972 char *sas_wwn = NULL; 2973 int phynum = -1; 2974 int reallen = 0; 2975 2976 /* Get the target num */ 2977 lun = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, DDI_PROP_DONTPASS, 2978 LUN_PROP, 0); 2979 2980 if ((phynum = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, 2981 DDI_PROP_DONTPASS, "sata-phy", -1)) != -1) { 2982 /* 2983 * Stick in the address of form "pPHY,LUN" 2984 */ 2985 reallen = snprintf(name, len, "p%x,%x", phynum, lun); 2986 } else if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lun_dip, 2987 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &sas_wwn) 2988 == DDI_PROP_SUCCESS) { 2989 /* 2990 * Stick in the address of the form "wWWN,LUN" 2991 */ 2992 reallen = snprintf(name, len, "%s,%x", sas_wwn, lun); 2993 ddi_prop_free(sas_wwn); 2994 } else { 2995 return (DDI_FAILURE); 2996 } 2997 2998 ASSERT(reallen < len); 2999 if (reallen >= len) { 3000 mptsas_log(0, CE_WARN, "!mptsas_get_name: name parameter " 3001 "length too small, it needs to be %d bytes", reallen + 1); 3002 } 3003 return (DDI_SUCCESS); 3004 } 3005 3006 /* 3007 * tran_tgt_init(9E) - target device instance initialization 3008 */ 3009 static int 3010 mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 3011 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 3012 { 3013 #ifndef __lock_lint 3014 _NOTE(ARGUNUSED(hba_tran)) 3015 #endif 3016 3017 /* 3018 * At this point, the scsi_device structure already exists 3019 * and has been initialized. 3020 * 3021 * Use this function to allocate target-private data structures, 3022 * if needed by this HBA. Add revised flow-control and queue 3023 * properties for child here, if desired and if you can tell they 3024 * support tagged queueing by now. 3025 */ 3026 mptsas_t *mpt; 3027 int lun = sd->sd_address.a_lun; 3028 mdi_pathinfo_t *pip = NULL; 3029 mptsas_tgt_private_t *tgt_private = NULL; 3030 mptsas_target_t *ptgt = NULL; 3031 char *psas_wwn = NULL; 3032 mptsas_phymask_t phymask = 0; 3033 uint64_t sas_wwn = 0; 3034 mptsas_target_addr_t addr; 3035 mpt = SDEV2MPT(sd); 3036 3037 ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0); 3038 3039 NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d", 3040 (void *)hba_dip, (void *)tgt_dip, lun)); 3041 3042 if (ndi_dev_is_persistent_node(tgt_dip) == 0) { 3043 (void) ndi_merge_node(tgt_dip, mptsas_name_child); 3044 ddi_set_name_addr(tgt_dip, NULL); 3045 return (DDI_FAILURE); 3046 } 3047 /* 3048 * phymask is 0 means the virtual port for RAID 3049 */ 3050 phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0, 3051 "phymask", 0); 3052 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) { 3053 if ((pip = (void *)(sd->sd_private)) == NULL) { 3054 /* 3055 * Very bad news if this occurs. Somehow scsi_vhci has 3056 * lost the pathinfo node for this target. 3057 */ 3058 return (DDI_NOT_WELL_FORMED); 3059 } 3060 3061 if (mdi_prop_lookup_int(pip, LUN_PROP, &lun) != 3062 DDI_PROP_SUCCESS) { 3063 mptsas_log(mpt, CE_WARN, "Get lun property failed\n"); 3064 return (DDI_FAILURE); 3065 } 3066 3067 if (mdi_prop_lookup_string(pip, SCSI_ADDR_PROP_TARGET_PORT, 3068 &psas_wwn) == MDI_SUCCESS) { 3069 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) { 3070 sas_wwn = 0; 3071 } 3072 (void) mdi_prop_free(psas_wwn); 3073 } 3074 } else { 3075 lun = ddi_prop_get_int(DDI_DEV_T_ANY, tgt_dip, 3076 DDI_PROP_DONTPASS, LUN_PROP, 0); 3077 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, tgt_dip, 3078 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &psas_wwn) == 3079 DDI_PROP_SUCCESS) { 3080 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) { 3081 sas_wwn = 0; 3082 } 3083 ddi_prop_free(psas_wwn); 3084 } else { 3085 sas_wwn = 0; 3086 } 3087 } 3088 3089 ASSERT((sas_wwn != 0) || (phymask != 0)); 3090 addr.mta_wwn = sas_wwn; 3091 addr.mta_phymask = phymask; 3092 mutex_enter(&mpt->m_mutex); 3093 ptgt = refhash_lookup(mpt->m_targets, &addr); 3094 mutex_exit(&mpt->m_mutex); 3095 if (ptgt == NULL) { 3096 mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or " 3097 "gone already! phymask:%x, saswwn %"PRIx64, phymask, 3098 sas_wwn); 3099 return (DDI_FAILURE); 3100 } 3101 if (hba_tran->tran_tgt_private == NULL) { 3102 tgt_private = kmem_zalloc(sizeof (mptsas_tgt_private_t), 3103 KM_SLEEP); 3104 tgt_private->t_lun = lun; 3105 tgt_private->t_private = ptgt; 3106 hba_tran->tran_tgt_private = tgt_private; 3107 } 3108 3109 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) { 3110 return (DDI_SUCCESS); 3111 } 3112 mutex_enter(&mpt->m_mutex); 3113 3114 if (ptgt->m_deviceinfo & 3115 (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 3116 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 3117 uchar_t *inq89 = NULL; 3118 int inq89_len = 0x238; 3119 int reallen = 0; 3120 int rval = 0; 3121 struct sata_id *sid = NULL; 3122 char model[SATA_ID_MODEL_LEN + 1]; 3123 char fw[SATA_ID_FW_LEN + 1]; 3124 char *vid, *pid; 3125 3126 mutex_exit(&mpt->m_mutex); 3127 /* 3128 * According SCSI/ATA Translation -2 (SAT-2) revision 01a 3129 * chapter 12.4.2 VPD page 89h includes 512 bytes ATA IDENTIFY 3130 * DEVICE data or ATA IDENTIFY PACKET DEVICE data. 3131 */ 3132 inq89 = kmem_zalloc(inq89_len, KM_SLEEP); 3133 rval = mptsas_inquiry(mpt, ptgt, 0, 0x89, 3134 inq89, inq89_len, &reallen, 1); 3135 3136 if (rval != 0) { 3137 if (inq89 != NULL) { 3138 kmem_free(inq89, inq89_len); 3139 } 3140 3141 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 3142 "0x89 for SATA target:%x failed!", ptgt->m_devhdl); 3143 return (DDI_SUCCESS); 3144 } 3145 sid = (void *)(&inq89[60]); 3146 3147 swab(sid->ai_model, model, SATA_ID_MODEL_LEN); 3148 swab(sid->ai_fw, fw, SATA_ID_FW_LEN); 3149 3150 model[SATA_ID_MODEL_LEN] = 0; 3151 fw[SATA_ID_FW_LEN] = 0; 3152 3153 sata_split_model(model, &vid, &pid); 3154 3155 /* 3156 * override SCSA "inquiry-*" properties 3157 */ 3158 if (vid) 3159 (void) scsi_device_prop_update_inqstring(sd, 3160 INQUIRY_VENDOR_ID, vid, strlen(vid)); 3161 if (pid) 3162 (void) scsi_device_prop_update_inqstring(sd, 3163 INQUIRY_PRODUCT_ID, pid, strlen(pid)); 3164 (void) scsi_device_prop_update_inqstring(sd, 3165 INQUIRY_REVISION_ID, fw, strlen(fw)); 3166 3167 if (inq89 != NULL) { 3168 kmem_free(inq89, inq89_len); 3169 } 3170 } else { 3171 mutex_exit(&mpt->m_mutex); 3172 } 3173 3174 return (DDI_SUCCESS); 3175 } 3176 /* 3177 * tran_tgt_free(9E) - target device instance deallocation 3178 */ 3179 static void 3180 mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 3181 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 3182 { 3183 #ifndef __lock_lint 3184 _NOTE(ARGUNUSED(hba_dip, tgt_dip, hba_tran, sd)) 3185 #endif 3186 3187 mptsas_tgt_private_t *tgt_private = hba_tran->tran_tgt_private; 3188 3189 if (tgt_private != NULL) { 3190 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t)); 3191 hba_tran->tran_tgt_private = NULL; 3192 } 3193 } 3194 3195 /* 3196 * scsi_pkt handling 3197 * 3198 * Visible to the external world via the transport structure. 3199 */ 3200 3201 /* 3202 * Notes: 3203 * - transport the command to the addressed SCSI target/lun device 3204 * - normal operation is to schedule the command to be transported, 3205 * and return TRAN_ACCEPT if this is successful. 3206 * - if NO_INTR, tran_start must poll device for command completion 3207 */ 3208 static int 3209 mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt) 3210 { 3211 #ifndef __lock_lint 3212 _NOTE(ARGUNUSED(ap)) 3213 #endif 3214 mptsas_t *mpt = PKT2MPT(pkt); 3215 mptsas_cmd_t *cmd = PKT2CMD(pkt); 3216 int rval; 3217 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3218 3219 NDBG1(("mptsas_scsi_start: pkt=0x%p", (void *)pkt)); 3220 ASSERT(ptgt); 3221 if (ptgt == NULL) 3222 return (TRAN_FATAL_ERROR); 3223 3224 /* 3225 * prepare the pkt before taking mutex. 3226 */ 3227 rval = mptsas_prepare_pkt(cmd); 3228 if (rval != TRAN_ACCEPT) { 3229 return (rval); 3230 } 3231 3232 /* 3233 * Send the command to target/lun, however your HBA requires it. 3234 * If busy, return TRAN_BUSY; if there's some other formatting error 3235 * in the packet, return TRAN_BADPKT; otherwise, fall through to the 3236 * return of TRAN_ACCEPT. 3237 * 3238 * Remember that access to shared resources, including the mptsas_t 3239 * data structure and the HBA hardware registers, must be protected 3240 * with mutexes, here and everywhere. 3241 * 3242 * Also remember that at interrupt time, you'll get an argument 3243 * to the interrupt handler which is a pointer to your mptsas_t 3244 * structure; you'll have to remember which commands are outstanding 3245 * and which scsi_pkt is the currently-running command so the 3246 * interrupt handler can refer to the pkt to set completion 3247 * status, call the target driver back through pkt_comp, etc. 3248 * 3249 * If the instance lock is held by other thread, don't spin to wait 3250 * for it. Instead, queue the cmd and next time when the instance lock 3251 * is not held, accept all the queued cmd. A extra tx_waitq is 3252 * introduced to protect the queue. 3253 * 3254 * The polled cmd will not be queud and accepted as usual. 3255 * 3256 * Under the tx_waitq mutex, record whether a thread is draining 3257 * the tx_waitq. An IO requesting thread that finds the instance 3258 * mutex contended appends to the tx_waitq and while holding the 3259 * tx_wait mutex, if the draining flag is not set, sets it and then 3260 * proceeds to spin for the instance mutex. This scheme ensures that 3261 * the last cmd in a burst be processed. 3262 * 3263 * we enable this feature only when the helper threads are enabled, 3264 * at which we think the loads are heavy. 3265 * 3266 * per instance mutex m_tx_waitq_mutex is introduced to protect the 3267 * m_tx_waitqtail, m_tx_waitq, m_tx_draining. 3268 */ 3269 3270 if (mpt->m_doneq_thread_n) { 3271 if (mutex_tryenter(&mpt->m_mutex) != 0) { 3272 rval = mptsas_accept_txwq_and_pkt(mpt, cmd); 3273 mutex_exit(&mpt->m_mutex); 3274 } else if (cmd->cmd_pkt_flags & FLAG_NOINTR) { 3275 mutex_enter(&mpt->m_mutex); 3276 rval = mptsas_accept_txwq_and_pkt(mpt, cmd); 3277 mutex_exit(&mpt->m_mutex); 3278 } else { 3279 mutex_enter(&mpt->m_tx_waitq_mutex); 3280 /* 3281 * ptgt->m_dr_flag is protected by m_mutex or 3282 * m_tx_waitq_mutex. In this case, m_tx_waitq_mutex 3283 * is acquired. 3284 */ 3285 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3286 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3287 /* 3288 * The command should be allowed to 3289 * retry by returning TRAN_BUSY to 3290 * to stall the I/O's which come from 3291 * scsi_vhci since the device/path is 3292 * in unstable state now. 3293 */ 3294 mutex_exit(&mpt->m_tx_waitq_mutex); 3295 return (TRAN_BUSY); 3296 } else { 3297 /* 3298 * The device is offline, just fail the 3299 * command by returning 3300 * TRAN_FATAL_ERROR. 3301 */ 3302 mutex_exit(&mpt->m_tx_waitq_mutex); 3303 return (TRAN_FATAL_ERROR); 3304 } 3305 } 3306 if (mpt->m_tx_draining) { 3307 cmd->cmd_flags |= CFLAG_TXQ; 3308 *mpt->m_tx_waitqtail = cmd; 3309 mpt->m_tx_waitqtail = &cmd->cmd_linkp; 3310 mutex_exit(&mpt->m_tx_waitq_mutex); 3311 } else { /* drain the queue */ 3312 mpt->m_tx_draining = 1; 3313 mutex_exit(&mpt->m_tx_waitq_mutex); 3314 mutex_enter(&mpt->m_mutex); 3315 rval = mptsas_accept_txwq_and_pkt(mpt, cmd); 3316 mutex_exit(&mpt->m_mutex); 3317 } 3318 } 3319 } else { 3320 mutex_enter(&mpt->m_mutex); 3321 /* 3322 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex 3323 * in this case, m_mutex is acquired. 3324 */ 3325 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3326 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3327 /* 3328 * commands should be allowed to retry by 3329 * returning TRAN_BUSY to stall the I/O's 3330 * which come from scsi_vhci since the device/ 3331 * path is in unstable state now. 3332 */ 3333 mutex_exit(&mpt->m_mutex); 3334 return (TRAN_BUSY); 3335 } else { 3336 /* 3337 * The device is offline, just fail the 3338 * command by returning TRAN_FATAL_ERROR. 3339 */ 3340 mutex_exit(&mpt->m_mutex); 3341 return (TRAN_FATAL_ERROR); 3342 } 3343 } 3344 rval = mptsas_accept_pkt(mpt, cmd); 3345 mutex_exit(&mpt->m_mutex); 3346 } 3347 3348 return (rval); 3349 } 3350 3351 /* 3352 * Accept all the queued cmds(if any) before accept the current one. 3353 */ 3354 static int 3355 mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd) 3356 { 3357 int rval; 3358 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3359 3360 ASSERT(mutex_owned(&mpt->m_mutex)); 3361 /* 3362 * The call to mptsas_accept_tx_waitq() must always be performed 3363 * because that is where mpt->m_tx_draining is cleared. 3364 */ 3365 mutex_enter(&mpt->m_tx_waitq_mutex); 3366 mptsas_accept_tx_waitq(mpt); 3367 mutex_exit(&mpt->m_tx_waitq_mutex); 3368 /* 3369 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex 3370 * in this case, m_mutex is acquired. 3371 */ 3372 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3373 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3374 /* 3375 * The command should be allowed to retry by returning 3376 * TRAN_BUSY to stall the I/O's which come from 3377 * scsi_vhci since the device/path is in unstable state 3378 * now. 3379 */ 3380 return (TRAN_BUSY); 3381 } else { 3382 /* 3383 * The device is offline, just fail the command by 3384 * return TRAN_FATAL_ERROR. 3385 */ 3386 return (TRAN_FATAL_ERROR); 3387 } 3388 } 3389 rval = mptsas_accept_pkt(mpt, cmd); 3390 3391 return (rval); 3392 } 3393 3394 static int 3395 mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd) 3396 { 3397 int rval = TRAN_ACCEPT; 3398 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3399 3400 NDBG1(("mptsas_accept_pkt: cmd=0x%p", (void *)cmd)); 3401 3402 ASSERT(mutex_owned(&mpt->m_mutex)); 3403 3404 if ((cmd->cmd_flags & CFLAG_PREPARED) == 0) { 3405 rval = mptsas_prepare_pkt(cmd); 3406 if (rval != TRAN_ACCEPT) { 3407 cmd->cmd_flags &= ~CFLAG_TRANFLAG; 3408 return (rval); 3409 } 3410 } 3411 3412 /* 3413 * reset the throttle if we were draining 3414 */ 3415 if ((ptgt->m_t_ncmds == 0) && 3416 (ptgt->m_t_throttle == DRAIN_THROTTLE)) { 3417 NDBG23(("reset throttle")); 3418 ASSERT(ptgt->m_reset_delay == 0); 3419 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 3420 } 3421 3422 /* 3423 * If HBA is being reset, the DevHandles are being re-initialized, 3424 * which means that they could be invalid even if the target is still 3425 * attached. Check if being reset and if DevHandle is being 3426 * re-initialized. If this is the case, return BUSY so the I/O can be 3427 * retried later. 3428 */ 3429 if ((ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) && mpt->m_in_reset) { 3430 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 3431 if (cmd->cmd_flags & CFLAG_TXQ) { 3432 mptsas_doneq_add(mpt, cmd); 3433 mptsas_doneq_empty(mpt); 3434 return (rval); 3435 } else { 3436 return (TRAN_BUSY); 3437 } 3438 } 3439 3440 /* 3441 * If device handle has already been invalidated, just 3442 * fail the command. In theory, command from scsi_vhci 3443 * client is impossible send down command with invalid 3444 * devhdl since devhdl is set after path offline, target 3445 * driver is not suppose to select a offlined path. 3446 */ 3447 if (ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) { 3448 NDBG3(("rejecting command, it might because invalid devhdl " 3449 "request.")); 3450 mptsas_set_pkt_reason(mpt, cmd, CMD_DEV_GONE, STAT_TERMINATED); 3451 if (cmd->cmd_flags & CFLAG_TXQ) { 3452 mptsas_doneq_add(mpt, cmd); 3453 mptsas_doneq_empty(mpt); 3454 return (rval); 3455 } else { 3456 return (TRAN_FATAL_ERROR); 3457 } 3458 } 3459 /* 3460 * The first case is the normal case. mpt gets a command from the 3461 * target driver and starts it. 3462 * Since SMID 0 is reserved and the TM slot is reserved, the actual max 3463 * commands is m_max_requests - 2. 3464 */ 3465 if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) && 3466 (ptgt->m_t_throttle > HOLD_THROTTLE) && 3467 (ptgt->m_t_ncmds < ptgt->m_t_throttle) && 3468 (ptgt->m_reset_delay == 0) && 3469 (ptgt->m_t_nwait == 0) && 3470 ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0)) { 3471 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 3472 (void) mptsas_start_cmd(mpt, cmd); 3473 } else { 3474 mptsas_waitq_add(mpt, cmd); 3475 } 3476 } else { 3477 /* 3478 * Add this pkt to the work queue 3479 */ 3480 mptsas_waitq_add(mpt, cmd); 3481 3482 if (cmd->cmd_pkt_flags & FLAG_NOINTR) { 3483 (void) mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME); 3484 3485 /* 3486 * Only flush the doneq if this is not a TM 3487 * cmd. For TM cmds the flushing of the 3488 * doneq will be done in those routines. 3489 */ 3490 if ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) { 3491 mptsas_doneq_empty(mpt); 3492 } 3493 } 3494 } 3495 return (rval); 3496 } 3497 3498 int 3499 mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 3500 { 3501 mptsas_slots_t *slots = mpt->m_active; 3502 uint_t slot, start_rotor; 3503 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3504 3505 ASSERT(MUTEX_HELD(&mpt->m_mutex)); 3506 3507 /* 3508 * Account for reserved TM request slot and reserved SMID of 0. 3509 */ 3510 ASSERT(slots->m_n_normal == (mpt->m_max_requests - 2)); 3511 3512 /* 3513 * Find the next available slot, beginning at m_rotor. If no slot is 3514 * available, we'll return FALSE to indicate that. This mechanism 3515 * considers only the normal slots, not the reserved slot 0 nor the 3516 * task management slot m_n_normal + 1. The rotor is left to point to 3517 * the normal slot after the one we select, unless we select the last 3518 * normal slot in which case it returns to slot 1. 3519 */ 3520 start_rotor = slots->m_rotor; 3521 do { 3522 slot = slots->m_rotor++; 3523 if (slots->m_rotor > slots->m_n_normal) 3524 slots->m_rotor = 1; 3525 3526 if (slots->m_rotor == start_rotor) 3527 break; 3528 } while (slots->m_slot[slot] != NULL); 3529 3530 if (slots->m_slot[slot] != NULL) 3531 return (FALSE); 3532 3533 ASSERT(slot != 0 && slot <= slots->m_n_normal); 3534 3535 cmd->cmd_slot = slot; 3536 slots->m_slot[slot] = cmd; 3537 mpt->m_ncmds++; 3538 3539 /* 3540 * only increment per target ncmds if this is not a 3541 * command that has no target associated with it (i.e. a 3542 * event acknoledgment) 3543 */ 3544 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 3545 /* 3546 * Expiration time is set in mptsas_start_cmd 3547 */ 3548 ptgt->m_t_ncmds++; 3549 cmd->cmd_active_expiration = 0; 3550 } else { 3551 /* 3552 * Initialize expiration time for passthrough commands, 3553 */ 3554 cmd->cmd_active_expiration = gethrtime() + 3555 (hrtime_t)cmd->cmd_pkt->pkt_time * NANOSEC; 3556 } 3557 return (TRUE); 3558 } 3559 3560 /* 3561 * prepare the pkt: 3562 * the pkt may have been resubmitted or just reused so 3563 * initialize some fields and do some checks. 3564 */ 3565 static int 3566 mptsas_prepare_pkt(mptsas_cmd_t *cmd) 3567 { 3568 struct scsi_pkt *pkt = CMD2PKT(cmd); 3569 3570 NDBG1(("mptsas_prepare_pkt: cmd=0x%p", (void *)cmd)); 3571 3572 /* 3573 * Reinitialize some fields that need it; the packet may 3574 * have been resubmitted 3575 */ 3576 pkt->pkt_reason = CMD_CMPLT; 3577 pkt->pkt_state = 0; 3578 pkt->pkt_statistics = 0; 3579 pkt->pkt_resid = 0; 3580 cmd->cmd_age = 0; 3581 cmd->cmd_pkt_flags = pkt->pkt_flags; 3582 3583 /* 3584 * zero status byte. 3585 */ 3586 *(pkt->pkt_scbp) = 0; 3587 3588 if (cmd->cmd_flags & CFLAG_DMAVALID) { 3589 pkt->pkt_resid = cmd->cmd_dmacount; 3590 3591 /* 3592 * consistent packets need to be sync'ed first 3593 * (only for data going out) 3594 */ 3595 if ((cmd->cmd_flags & CFLAG_CMDIOPB) && 3596 (cmd->cmd_flags & CFLAG_DMASEND)) { 3597 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 3598 DDI_DMA_SYNC_FORDEV); 3599 } 3600 } 3601 3602 cmd->cmd_flags = 3603 (cmd->cmd_flags & ~(CFLAG_TRANFLAG)) | 3604 CFLAG_PREPARED | CFLAG_IN_TRANSPORT; 3605 3606 return (TRAN_ACCEPT); 3607 } 3608 3609 /* 3610 * tran_init_pkt(9E) - allocate scsi_pkt(9S) for command 3611 * 3612 * One of three possibilities: 3613 * - allocate scsi_pkt 3614 * - allocate scsi_pkt and DMA resources 3615 * - allocate DMA resources to an already-allocated pkt 3616 */ 3617 static struct scsi_pkt * 3618 mptsas_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt, 3619 struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags, 3620 int (*callback)(), caddr_t arg) 3621 { 3622 mptsas_cmd_t *cmd, *new_cmd; 3623 mptsas_t *mpt = ADDR2MPT(ap); 3624 uint_t oldcookiec; 3625 mptsas_target_t *ptgt = NULL; 3626 int rval; 3627 mptsas_tgt_private_t *tgt_private; 3628 int kf; 3629 3630 kf = (callback == SLEEP_FUNC)? KM_SLEEP: KM_NOSLEEP; 3631 3632 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran-> 3633 tran_tgt_private; 3634 ASSERT(tgt_private != NULL); 3635 if (tgt_private == NULL) { 3636 return (NULL); 3637 } 3638 ptgt = tgt_private->t_private; 3639 ASSERT(ptgt != NULL); 3640 if (ptgt == NULL) 3641 return (NULL); 3642 ap->a_target = ptgt->m_devhdl; 3643 ap->a_lun = tgt_private->t_lun; 3644 3645 ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC); 3646 #ifdef MPTSAS_TEST_EXTRN_ALLOC 3647 statuslen *= 100; tgtlen *= 4; 3648 #endif 3649 NDBG3(("mptsas_scsi_init_pkt:\n" 3650 "\ttgt=%d in=0x%p bp=0x%p clen=%d slen=%d tlen=%d flags=%x", 3651 ap->a_target, (void *)pkt, (void *)bp, 3652 cmdlen, statuslen, tgtlen, flags)); 3653 3654 /* 3655 * Allocate the new packet. 3656 */ 3657 if (pkt == NULL) { 3658 ddi_dma_handle_t save_dma_handle; 3659 3660 cmd = kmem_cache_alloc(mpt->m_kmem_cache, kf); 3661 if (cmd == NULL) 3662 return (NULL); 3663 3664 save_dma_handle = cmd->cmd_dmahandle; 3665 bzero(cmd, sizeof (*cmd) + scsi_pkt_size()); 3666 cmd->cmd_dmahandle = save_dma_handle; 3667 3668 pkt = (void *)((uchar_t *)cmd + 3669 sizeof (struct mptsas_cmd)); 3670 pkt->pkt_ha_private = (opaque_t)cmd; 3671 pkt->pkt_address = *ap; 3672 pkt->pkt_private = (opaque_t)cmd->cmd_pkt_private; 3673 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; 3674 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb; 3675 cmd->cmd_pkt = (struct scsi_pkt *)pkt; 3676 cmd->cmd_cdblen = (uchar_t)cmdlen; 3677 cmd->cmd_scblen = statuslen; 3678 cmd->cmd_rqslen = SENSE_LENGTH; 3679 cmd->cmd_tgt_addr = ptgt; 3680 3681 if ((cmdlen > sizeof (cmd->cmd_cdb)) || 3682 (tgtlen > PKT_PRIV_LEN) || 3683 (statuslen > EXTCMDS_STATUS_SIZE)) { 3684 int failure; 3685 3686 /* 3687 * We are going to allocate external packet space which 3688 * might include the sense data buffer for DMA so we 3689 * need to increase the reference counter here. In a 3690 * case the HBA is in reset we just simply free the 3691 * allocated packet and bail out. 3692 */ 3693 mutex_enter(&mpt->m_mutex); 3694 if (mpt->m_in_reset) { 3695 mutex_exit(&mpt->m_mutex); 3696 3697 cmd->cmd_flags = CFLAG_FREE; 3698 kmem_cache_free(mpt->m_kmem_cache, cmd); 3699 return (NULL); 3700 } 3701 mpt->m_extreq_sense_refcount++; 3702 ASSERT(mpt->m_extreq_sense_refcount > 0); 3703 mutex_exit(&mpt->m_mutex); 3704 3705 /* 3706 * if extern alloc fails, all will be 3707 * deallocated, including cmd 3708 */ 3709 failure = mptsas_pkt_alloc_extern(mpt, cmd, 3710 cmdlen, tgtlen, statuslen, kf); 3711 3712 if (failure != 0 || cmd->cmd_extrqslen == 0) { 3713 /* 3714 * If the external packet space allocation 3715 * failed, or we didn't allocated the sense 3716 * data buffer for DMA we need to decrease the 3717 * reference counter. 3718 */ 3719 mutex_enter(&mpt->m_mutex); 3720 ASSERT(mpt->m_extreq_sense_refcount > 0); 3721 mpt->m_extreq_sense_refcount--; 3722 if (mpt->m_extreq_sense_refcount == 0) 3723 cv_broadcast( 3724 &mpt->m_extreq_sense_refcount_cv); 3725 mutex_exit(&mpt->m_mutex); 3726 3727 if (failure != 0) { 3728 /* 3729 * if extern allocation fails, it will 3730 * deallocate the new pkt as well 3731 */ 3732 return (NULL); 3733 } 3734 } 3735 } 3736 new_cmd = cmd; 3737 3738 } else { 3739 cmd = PKT2CMD(pkt); 3740 new_cmd = NULL; 3741 } 3742 3743 3744 /* grab cmd->cmd_cookiec here as oldcookiec */ 3745 3746 oldcookiec = cmd->cmd_cookiec; 3747 3748 /* 3749 * If the dma was broken up into PARTIAL transfers cmd_nwin will be 3750 * greater than 0 and we'll need to grab the next dma window 3751 */ 3752 /* 3753 * SLM-not doing extra command frame right now; may add later 3754 */ 3755 3756 if (cmd->cmd_nwin > 0) { 3757 3758 /* 3759 * Make sure we havn't gone past the the total number 3760 * of windows 3761 */ 3762 if (++cmd->cmd_winindex >= cmd->cmd_nwin) { 3763 return (NULL); 3764 } 3765 if (ddi_dma_getwin(cmd->cmd_dmahandle, cmd->cmd_winindex, 3766 &cmd->cmd_dma_offset, &cmd->cmd_dma_len, 3767 &cmd->cmd_cookie, &cmd->cmd_cookiec) == DDI_FAILURE) { 3768 return (NULL); 3769 } 3770 goto get_dma_cookies; 3771 } 3772 3773 3774 if (flags & PKT_XARQ) { 3775 cmd->cmd_flags |= CFLAG_XARQ; 3776 } 3777 3778 /* 3779 * DMA resource allocation. This version assumes your 3780 * HBA has some sort of bus-mastering or onboard DMA capability, with a 3781 * scatter-gather list of length MPTSAS_MAX_DMA_SEGS, as given in the 3782 * ddi_dma_attr_t structure and passed to scsi_impl_dmaget. 3783 */ 3784 if (bp && (bp->b_bcount != 0) && 3785 (cmd->cmd_flags & CFLAG_DMAVALID) == 0) { 3786 3787 int cnt, dma_flags; 3788 mptti_t *dmap; /* ptr to the S/G list */ 3789 3790 /* 3791 * Set up DMA memory and position to the next DMA segment. 3792 */ 3793 ASSERT(cmd->cmd_dmahandle != NULL); 3794 3795 if (bp->b_flags & B_READ) { 3796 dma_flags = DDI_DMA_READ; 3797 cmd->cmd_flags &= ~CFLAG_DMASEND; 3798 } else { 3799 dma_flags = DDI_DMA_WRITE; 3800 cmd->cmd_flags |= CFLAG_DMASEND; 3801 } 3802 if (flags & PKT_CONSISTENT) { 3803 cmd->cmd_flags |= CFLAG_CMDIOPB; 3804 dma_flags |= DDI_DMA_CONSISTENT; 3805 } 3806 3807 if (flags & PKT_DMA_PARTIAL) { 3808 dma_flags |= DDI_DMA_PARTIAL; 3809 } 3810 3811 /* 3812 * workaround for byte hole issue on psycho and 3813 * schizo pre 2.1 3814 */ 3815 if ((bp->b_flags & B_READ) && ((bp->b_flags & 3816 (B_PAGEIO|B_REMAPPED)) != B_PAGEIO) && 3817 ((uintptr_t)bp->b_un.b_addr & 0x7)) { 3818 dma_flags |= DDI_DMA_CONSISTENT; 3819 } 3820 3821 rval = ddi_dma_buf_bind_handle(cmd->cmd_dmahandle, bp, 3822 dma_flags, callback, arg, 3823 &cmd->cmd_cookie, &cmd->cmd_cookiec); 3824 if (rval == DDI_DMA_PARTIAL_MAP) { 3825 (void) ddi_dma_numwin(cmd->cmd_dmahandle, 3826 &cmd->cmd_nwin); 3827 cmd->cmd_winindex = 0; 3828 (void) ddi_dma_getwin(cmd->cmd_dmahandle, 3829 cmd->cmd_winindex, &cmd->cmd_dma_offset, 3830 &cmd->cmd_dma_len, &cmd->cmd_cookie, 3831 &cmd->cmd_cookiec); 3832 } else if (rval && (rval != DDI_DMA_MAPPED)) { 3833 switch (rval) { 3834 case DDI_DMA_NORESOURCES: 3835 bioerror(bp, 0); 3836 break; 3837 case DDI_DMA_BADATTR: 3838 case DDI_DMA_NOMAPPING: 3839 bioerror(bp, EFAULT); 3840 break; 3841 case DDI_DMA_TOOBIG: 3842 default: 3843 bioerror(bp, EINVAL); 3844 break; 3845 } 3846 cmd->cmd_flags &= ~CFLAG_DMAVALID; 3847 if (new_cmd) { 3848 mptsas_scsi_destroy_pkt(ap, pkt); 3849 } 3850 return ((struct scsi_pkt *)NULL); 3851 } 3852 3853 get_dma_cookies: 3854 cmd->cmd_flags |= CFLAG_DMAVALID; 3855 ASSERT(cmd->cmd_cookiec > 0); 3856 3857 if (cmd->cmd_cookiec > MPTSAS_MAX_CMD_SEGS) { 3858 mptsas_log(mpt, CE_NOTE, "large cookiec received %d\n", 3859 cmd->cmd_cookiec); 3860 bioerror(bp, EINVAL); 3861 if (new_cmd) { 3862 mptsas_scsi_destroy_pkt(ap, pkt); 3863 } 3864 return ((struct scsi_pkt *)NULL); 3865 } 3866 3867 /* 3868 * Allocate extra SGL buffer if needed. 3869 */ 3870 if ((cmd->cmd_cookiec > MPTSAS_MAX_FRAME_SGES64(mpt)) && 3871 (cmd->cmd_extra_frames == NULL)) { 3872 if (mptsas_alloc_extra_sgl_frame(mpt, cmd) == 3873 DDI_FAILURE) { 3874 mptsas_log(mpt, CE_WARN, "MPT SGL mem alloc " 3875 "failed"); 3876 bioerror(bp, ENOMEM); 3877 if (new_cmd) { 3878 mptsas_scsi_destroy_pkt(ap, pkt); 3879 } 3880 return ((struct scsi_pkt *)NULL); 3881 } 3882 } 3883 3884 /* 3885 * Always use scatter-gather transfer 3886 * Use the loop below to store physical addresses of 3887 * DMA segments, from the DMA cookies, into your HBA's 3888 * scatter-gather list. 3889 * We need to ensure we have enough kmem alloc'd 3890 * for the sg entries since we are no longer using an 3891 * array inside mptsas_cmd_t. 3892 * 3893 * We check cmd->cmd_cookiec against oldcookiec so 3894 * the scatter-gather list is correctly allocated 3895 */ 3896 3897 if (oldcookiec != cmd->cmd_cookiec) { 3898 if (cmd->cmd_sg != (mptti_t *)NULL) { 3899 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * 3900 oldcookiec); 3901 cmd->cmd_sg = NULL; 3902 } 3903 } 3904 3905 if (cmd->cmd_sg == (mptti_t *)NULL) { 3906 cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)* 3907 cmd->cmd_cookiec), kf); 3908 3909 if (cmd->cmd_sg == (mptti_t *)NULL) { 3910 mptsas_log(mpt, CE_WARN, 3911 "unable to kmem_alloc enough memory " 3912 "for scatter/gather list"); 3913 /* 3914 * if we have an ENOMEM condition we need to behave 3915 * the same way as the rest of this routine 3916 */ 3917 3918 bioerror(bp, ENOMEM); 3919 if (new_cmd) { 3920 mptsas_scsi_destroy_pkt(ap, pkt); 3921 } 3922 return ((struct scsi_pkt *)NULL); 3923 } 3924 } 3925 3926 dmap = cmd->cmd_sg; 3927 3928 ASSERT(cmd->cmd_cookie.dmac_size != 0); 3929 3930 /* 3931 * store the first segment into the S/G list 3932 */ 3933 dmap->count = cmd->cmd_cookie.dmac_size; 3934 dmap->addr.address64.Low = (uint32_t) 3935 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull); 3936 dmap->addr.address64.High = (uint32_t) 3937 (cmd->cmd_cookie.dmac_laddress >> 32); 3938 3939 /* 3940 * dmacount counts the size of the dma for this window 3941 * (if partial dma is being used). totaldmacount 3942 * keeps track of the total amount of dma we have 3943 * transferred for all the windows (needed to calculate 3944 * the resid value below). 3945 */ 3946 cmd->cmd_dmacount = cmd->cmd_cookie.dmac_size; 3947 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size; 3948 3949 /* 3950 * We already stored the first DMA scatter gather segment, 3951 * start at 1 if we need to store more. 3952 */ 3953 for (cnt = 1; cnt < cmd->cmd_cookiec; cnt++) { 3954 /* 3955 * Get next DMA cookie 3956 */ 3957 ddi_dma_nextcookie(cmd->cmd_dmahandle, 3958 &cmd->cmd_cookie); 3959 dmap++; 3960 3961 cmd->cmd_dmacount += cmd->cmd_cookie.dmac_size; 3962 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size; 3963 3964 /* 3965 * store the segment parms into the S/G list 3966 */ 3967 dmap->count = cmd->cmd_cookie.dmac_size; 3968 dmap->addr.address64.Low = (uint32_t) 3969 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull); 3970 dmap->addr.address64.High = (uint32_t) 3971 (cmd->cmd_cookie.dmac_laddress >> 32); 3972 } 3973 3974 /* 3975 * If this was partially allocated we set the resid 3976 * the amount of data NOT transferred in this window 3977 * If there is only one window, the resid will be 0 3978 */ 3979 pkt->pkt_resid = (bp->b_bcount - cmd->cmd_totaldmacount); 3980 NDBG3(("mptsas_scsi_init_pkt: cmd_dmacount=%d.", 3981 cmd->cmd_dmacount)); 3982 } 3983 return (pkt); 3984 } 3985 3986 /* 3987 * tran_destroy_pkt(9E) - scsi_pkt(9s) deallocation 3988 * 3989 * Notes: 3990 * - also frees DMA resources if allocated 3991 * - implicit DMA synchonization 3992 */ 3993 static void 3994 mptsas_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 3995 { 3996 mptsas_cmd_t *cmd = PKT2CMD(pkt); 3997 mptsas_t *mpt = ADDR2MPT(ap); 3998 3999 NDBG3(("mptsas_scsi_destroy_pkt: target=%d pkt=0x%p", 4000 ap->a_target, (void *)pkt)); 4001 4002 if (cmd->cmd_flags & CFLAG_DMAVALID) { 4003 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle); 4004 cmd->cmd_flags &= ~CFLAG_DMAVALID; 4005 } 4006 4007 if (cmd->cmd_sg) { 4008 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * cmd->cmd_cookiec); 4009 cmd->cmd_sg = NULL; 4010 } 4011 4012 mptsas_free_extra_sgl_frame(mpt, cmd); 4013 4014 if ((cmd->cmd_flags & 4015 (CFLAG_FREE | CFLAG_CDBEXTERN | CFLAG_PRIVEXTERN | 4016 CFLAG_SCBEXTERN)) == 0) { 4017 cmd->cmd_flags = CFLAG_FREE; 4018 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd); 4019 } else { 4020 boolean_t extrqslen = cmd->cmd_extrqslen != 0; 4021 4022 mptsas_pkt_destroy_extern(mpt, cmd); 4023 4024 /* 4025 * If the packet had the sense data buffer for DMA allocated we 4026 * need to decrease the reference counter. 4027 */ 4028 if (extrqslen) { 4029 mutex_enter(&mpt->m_mutex); 4030 ASSERT(mpt->m_extreq_sense_refcount > 0); 4031 mpt->m_extreq_sense_refcount--; 4032 if (mpt->m_extreq_sense_refcount == 0) 4033 cv_broadcast(&mpt->m_extreq_sense_refcount_cv); 4034 mutex_exit(&mpt->m_mutex); 4035 } 4036 } 4037 } 4038 4039 /* 4040 * kmem cache constructor and destructor: 4041 * When constructing, we bzero the cmd and allocate the dma handle 4042 * When destructing, just free the dma handle 4043 */ 4044 static int 4045 mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags) 4046 { 4047 mptsas_cmd_t *cmd = buf; 4048 mptsas_t *mpt = cdrarg; 4049 int (*callback)(caddr_t); 4050 4051 callback = (kmflags == KM_SLEEP)? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT; 4052 4053 NDBG4(("mptsas_kmem_cache_constructor")); 4054 4055 /* 4056 * allocate a dma handle 4057 */ 4058 if ((ddi_dma_alloc_handle(mpt->m_dip, &mpt->m_io_dma_attr, callback, 4059 NULL, &cmd->cmd_dmahandle)) != DDI_SUCCESS) { 4060 cmd->cmd_dmahandle = NULL; 4061 return (-1); 4062 } 4063 return (0); 4064 } 4065 4066 static void 4067 mptsas_kmem_cache_destructor(void *buf, void *cdrarg) 4068 { 4069 #ifndef __lock_lint 4070 _NOTE(ARGUNUSED(cdrarg)) 4071 #endif 4072 mptsas_cmd_t *cmd = buf; 4073 4074 NDBG4(("mptsas_kmem_cache_destructor")); 4075 4076 if (cmd->cmd_dmahandle) { 4077 ddi_dma_free_handle(&cmd->cmd_dmahandle); 4078 cmd->cmd_dmahandle = NULL; 4079 } 4080 } 4081 4082 static int 4083 mptsas_cache_frames_constructor(void *buf, void *cdrarg, int kmflags) 4084 { 4085 mptsas_cache_frames_t *p = buf; 4086 mptsas_t *mpt = cdrarg; 4087 ddi_dma_attr_t frame_dma_attr; 4088 size_t mem_size, alloc_len; 4089 ddi_dma_cookie_t cookie; 4090 uint_t ncookie; 4091 int (*callback)(caddr_t) = (kmflags == KM_SLEEP) 4092 ? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT; 4093 4094 frame_dma_attr = mpt->m_msg_dma_attr; 4095 frame_dma_attr.dma_attr_align = 0x10; 4096 frame_dma_attr.dma_attr_sgllen = 1; 4097 4098 if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attr, callback, NULL, 4099 &p->m_dma_hdl) != DDI_SUCCESS) { 4100 mptsas_log(mpt, CE_WARN, "Unable to allocate dma handle for" 4101 " extra SGL."); 4102 return (DDI_FAILURE); 4103 } 4104 4105 mem_size = (mpt->m_max_request_frames - 1) * mpt->m_req_frame_size; 4106 4107 if (ddi_dma_mem_alloc(p->m_dma_hdl, mem_size, &mpt->m_dev_acc_attr, 4108 DDI_DMA_CONSISTENT, callback, NULL, (caddr_t *)&p->m_frames_addr, 4109 &alloc_len, &p->m_acc_hdl) != DDI_SUCCESS) { 4110 ddi_dma_free_handle(&p->m_dma_hdl); 4111 p->m_dma_hdl = NULL; 4112 mptsas_log(mpt, CE_WARN, "Unable to allocate dma memory for" 4113 " extra SGL."); 4114 return (DDI_FAILURE); 4115 } 4116 4117 if (ddi_dma_addr_bind_handle(p->m_dma_hdl, NULL, p->m_frames_addr, 4118 alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, callback, NULL, 4119 &cookie, &ncookie) != DDI_DMA_MAPPED) { 4120 (void) ddi_dma_mem_free(&p->m_acc_hdl); 4121 ddi_dma_free_handle(&p->m_dma_hdl); 4122 p->m_dma_hdl = NULL; 4123 mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources for" 4124 " extra SGL"); 4125 return (DDI_FAILURE); 4126 } 4127 4128 /* 4129 * Store the SGL memory address. This chip uses this 4130 * address to dma to and from the driver. The second 4131 * address is the address mpt uses to fill in the SGL. 4132 */ 4133 p->m_phys_addr = cookie.dmac_laddress; 4134 4135 return (DDI_SUCCESS); 4136 } 4137 4138 static void 4139 mptsas_cache_frames_destructor(void *buf, void *cdrarg) 4140 { 4141 #ifndef __lock_lint 4142 _NOTE(ARGUNUSED(cdrarg)) 4143 #endif 4144 mptsas_cache_frames_t *p = buf; 4145 if (p->m_dma_hdl != NULL) { 4146 (void) ddi_dma_unbind_handle(p->m_dma_hdl); 4147 (void) ddi_dma_mem_free(&p->m_acc_hdl); 4148 ddi_dma_free_handle(&p->m_dma_hdl); 4149 p->m_phys_addr = NULL; 4150 p->m_frames_addr = NULL; 4151 p->m_dma_hdl = NULL; 4152 p->m_acc_hdl = NULL; 4153 } 4154 4155 } 4156 4157 /* 4158 * Figure out if we need to use a different method for the request 4159 * sense buffer and allocate from the map if necessary. 4160 */ 4161 static boolean_t 4162 mptsas_cmdarqsize(mptsas_t *mpt, mptsas_cmd_t *cmd, size_t senselength, int kf) 4163 { 4164 if (senselength > mpt->m_req_sense_size) { 4165 unsigned long i; 4166 4167 /* Sense length is limited to an 8 bit value in MPI Spec. */ 4168 if (senselength > 255) 4169 senselength = 255; 4170 cmd->cmd_extrqschunks = (senselength + 4171 (mpt->m_req_sense_size - 1))/mpt->m_req_sense_size; 4172 i = (kf == KM_SLEEP ? rmalloc_wait : rmalloc) 4173 (mpt->m_erqsense_map, cmd->cmd_extrqschunks); 4174 4175 if (i == 0) 4176 return (B_FALSE); 4177 4178 cmd->cmd_extrqslen = (uint16_t)senselength; 4179 cmd->cmd_extrqsidx = i - 1; 4180 cmd->cmd_arq_buf = mpt->m_extreq_sense + 4181 (cmd->cmd_extrqsidx * mpt->m_req_sense_size); 4182 } else { 4183 cmd->cmd_rqslen = (uchar_t)senselength; 4184 } 4185 4186 return (B_TRUE); 4187 } 4188 4189 /* 4190 * allocate and deallocate external pkt space (ie. not part of mptsas_cmd) 4191 * for non-standard length cdb, pkt_private, status areas 4192 * if allocation fails, then deallocate all external space and the pkt 4193 */ 4194 /* ARGSUSED */ 4195 static int 4196 mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd, 4197 int cmdlen, int tgtlen, int statuslen, int kf) 4198 { 4199 caddr_t cdbp, scbp, tgt; 4200 4201 NDBG3(("mptsas_pkt_alloc_extern: " 4202 "cmd=0x%p cmdlen=%d tgtlen=%d statuslen=%d kf=%x", 4203 (void *)cmd, cmdlen, tgtlen, statuslen, kf)); 4204 4205 tgt = cdbp = scbp = NULL; 4206 cmd->cmd_scblen = statuslen; 4207 cmd->cmd_privlen = (uchar_t)tgtlen; 4208 4209 if (cmdlen > sizeof (cmd->cmd_cdb)) { 4210 if ((cdbp = kmem_zalloc((size_t)cmdlen, kf)) == NULL) { 4211 goto fail; 4212 } 4213 cmd->cmd_pkt->pkt_cdbp = (opaque_t)cdbp; 4214 cmd->cmd_flags |= CFLAG_CDBEXTERN; 4215 } 4216 if (tgtlen > PKT_PRIV_LEN) { 4217 if ((tgt = kmem_zalloc((size_t)tgtlen, kf)) == NULL) { 4218 goto fail; 4219 } 4220 cmd->cmd_flags |= CFLAG_PRIVEXTERN; 4221 cmd->cmd_pkt->pkt_private = tgt; 4222 } 4223 if (statuslen > EXTCMDS_STATUS_SIZE) { 4224 if ((scbp = kmem_zalloc((size_t)statuslen, kf)) == NULL) { 4225 goto fail; 4226 } 4227 cmd->cmd_flags |= CFLAG_SCBEXTERN; 4228 cmd->cmd_pkt->pkt_scbp = (opaque_t)scbp; 4229 4230 /* allocate sense data buf for DMA */ 4231 if (mptsas_cmdarqsize(mpt, cmd, statuslen - 4232 MPTSAS_GET_ITEM_OFF(struct scsi_arq_status, sts_sensedata), 4233 kf) == B_FALSE) 4234 goto fail; 4235 } 4236 return (0); 4237 fail: 4238 mptsas_pkt_destroy_extern(mpt, cmd); 4239 return (1); 4240 } 4241 4242 /* 4243 * deallocate external pkt space and deallocate the pkt 4244 */ 4245 static void 4246 mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd) 4247 { 4248 NDBG3(("mptsas_pkt_destroy_extern: cmd=0x%p", (void *)cmd)); 4249 4250 if (cmd->cmd_flags & CFLAG_FREE) { 4251 mptsas_log(mpt, CE_PANIC, 4252 "mptsas_pkt_destroy_extern: freeing free packet"); 4253 _NOTE(NOT_REACHED) 4254 /* NOTREACHED */ 4255 } 4256 if (cmd->cmd_extrqslen != 0) { 4257 rmfree(mpt->m_erqsense_map, cmd->cmd_extrqschunks, 4258 cmd->cmd_extrqsidx + 1); 4259 } 4260 if (cmd->cmd_flags & CFLAG_CDBEXTERN) { 4261 kmem_free(cmd->cmd_pkt->pkt_cdbp, (size_t)cmd->cmd_cdblen); 4262 } 4263 if (cmd->cmd_flags & CFLAG_SCBEXTERN) { 4264 kmem_free(cmd->cmd_pkt->pkt_scbp, (size_t)cmd->cmd_scblen); 4265 } 4266 if (cmd->cmd_flags & CFLAG_PRIVEXTERN) { 4267 kmem_free(cmd->cmd_pkt->pkt_private, (size_t)cmd->cmd_privlen); 4268 } 4269 cmd->cmd_flags = CFLAG_FREE; 4270 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd); 4271 } 4272 4273 /* 4274 * tran_sync_pkt(9E) - explicit DMA synchronization 4275 */ 4276 /*ARGSUSED*/ 4277 static void 4278 mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 4279 { 4280 mptsas_cmd_t *cmd = PKT2CMD(pkt); 4281 4282 NDBG3(("mptsas_scsi_sync_pkt: target=%d, pkt=0x%p", 4283 ap->a_target, (void *)pkt)); 4284 4285 if (cmd->cmd_dmahandle) { 4286 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 4287 (cmd->cmd_flags & CFLAG_DMASEND) ? 4288 DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU); 4289 } 4290 } 4291 4292 /* 4293 * tran_dmafree(9E) - deallocate DMA resources allocated for command 4294 */ 4295 /*ARGSUSED*/ 4296 static void 4297 mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt) 4298 { 4299 mptsas_cmd_t *cmd = PKT2CMD(pkt); 4300 mptsas_t *mpt = ADDR2MPT(ap); 4301 4302 NDBG3(("mptsas_scsi_dmafree: target=%d pkt=0x%p", 4303 ap->a_target, (void *)pkt)); 4304 4305 if (cmd->cmd_flags & CFLAG_DMAVALID) { 4306 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle); 4307 cmd->cmd_flags &= ~CFLAG_DMAVALID; 4308 } 4309 4310 mptsas_free_extra_sgl_frame(mpt, cmd); 4311 } 4312 4313 static void 4314 mptsas_pkt_comp(struct scsi_pkt *pkt, mptsas_cmd_t *cmd) 4315 { 4316 if ((cmd->cmd_flags & CFLAG_CMDIOPB) && 4317 (!(cmd->cmd_flags & CFLAG_DMASEND))) { 4318 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 4319 DDI_DMA_SYNC_FORCPU); 4320 } 4321 (*pkt->pkt_comp)(pkt); 4322 } 4323 4324 static void 4325 mptsas_sge_mainframe(mptsas_cmd_t *cmd, pMpi2SCSIIORequest_t frame, 4326 ddi_acc_handle_t acc_hdl, uint_t cookiec, uint32_t end_flags) 4327 { 4328 pMpi2SGESimple64_t sge; 4329 mptti_t *dmap; 4330 uint32_t flags; 4331 4332 dmap = cmd->cmd_sg; 4333 4334 sge = (pMpi2SGESimple64_t)(&frame->SGL); 4335 while (cookiec--) { 4336 ddi_put32(acc_hdl, 4337 &sge->Address.Low, dmap->addr.address64.Low); 4338 ddi_put32(acc_hdl, 4339 &sge->Address.High, dmap->addr.address64.High); 4340 ddi_put32(acc_hdl, &sge->FlagsLength, 4341 dmap->count); 4342 flags = ddi_get32(acc_hdl, &sge->FlagsLength); 4343 flags |= ((uint32_t) 4344 (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4345 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4346 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4347 MPI2_SGE_FLAGS_SHIFT); 4348 4349 /* 4350 * If this is the last cookie, we set the flags 4351 * to indicate so 4352 */ 4353 if (cookiec == 0) { 4354 flags |= end_flags; 4355 } 4356 if (cmd->cmd_flags & CFLAG_DMASEND) { 4357 flags |= (MPI2_SGE_FLAGS_HOST_TO_IOC << 4358 MPI2_SGE_FLAGS_SHIFT); 4359 } else { 4360 flags |= (MPI2_SGE_FLAGS_IOC_TO_HOST << 4361 MPI2_SGE_FLAGS_SHIFT); 4362 } 4363 ddi_put32(acc_hdl, &sge->FlagsLength, flags); 4364 dmap++; 4365 sge++; 4366 } 4367 } 4368 4369 static void 4370 mptsas_sge_chain(mptsas_t *mpt, mptsas_cmd_t *cmd, 4371 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl) 4372 { 4373 pMpi2SGESimple64_t sge; 4374 pMpi2SGEChain64_t sgechain; 4375 uint64_t nframe_phys_addr; 4376 uint_t cookiec; 4377 mptti_t *dmap; 4378 uint32_t flags; 4379 4380 /* 4381 * Save the number of entries in the DMA 4382 * Scatter/Gather list 4383 */ 4384 cookiec = cmd->cmd_cookiec; 4385 4386 /* 4387 * Hereby we start to deal with multiple frames. 4388 * The process is as follows: 4389 * 1. Determine how many frames are needed for SGL element 4390 * storage; Note that all frames are stored in contiguous 4391 * memory space and in 64-bit DMA mode each element is 4392 * 3 double-words (12 bytes) long. 4393 * 2. Fill up the main frame. We need to do this separately 4394 * since it contains the SCSI IO request header and needs 4395 * dedicated processing. Note that the last 4 double-words 4396 * of the SCSI IO header is for SGL element storage 4397 * (MPI2_SGE_IO_UNION). 4398 * 3. Fill the chain element in the main frame, so the DMA 4399 * engine can use the following frames. 4400 * 4. Enter a loop to fill the remaining frames. Note that the 4401 * last frame contains no chain element. The remaining 4402 * frames go into the mpt SGL buffer allocated on the fly, 4403 * not immediately following the main message frame, as in 4404 * Gen1. 4405 * Some restrictions: 4406 * 1. For 64-bit DMA, the simple element and chain element 4407 * are both of 3 double-words (12 bytes) in size, even 4408 * though all frames are stored in the first 4G of mem 4409 * range and the higher 32-bits of the address are always 0. 4410 * 2. On some controllers (like the 1064/1068), a frame can 4411 * hold SGL elements with the last 1 or 2 double-words 4412 * (4 or 8 bytes) un-used. On these controllers, we should 4413 * recognize that there's not enough room for another SGL 4414 * element and move the sge pointer to the next frame. 4415 */ 4416 int i, j, k, l, frames, sgemax; 4417 int temp; 4418 uint8_t chainflags; 4419 uint16_t chainlength; 4420 mptsas_cache_frames_t *p; 4421 4422 /* 4423 * Sgemax is the number of SGE's that will fit 4424 * each extra frame and frames is total 4425 * number of frames we'll need. 1 sge entry per 4426 * frame is reseverd for the chain element thus the -1 below. 4427 */ 4428 sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_SGE_SIMPLE64)) 4429 - 1); 4430 temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax; 4431 4432 /* 4433 * A little check to see if we need to round up the number 4434 * of frames we need 4435 */ 4436 if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp * 4437 sgemax) > 1) { 4438 frames = (temp + 1); 4439 } else { 4440 frames = temp; 4441 } 4442 dmap = cmd->cmd_sg; 4443 sge = (pMpi2SGESimple64_t)(&frame->SGL); 4444 4445 /* 4446 * First fill in the main frame 4447 */ 4448 j = MPTSAS_MAX_FRAME_SGES64(mpt) - 1; 4449 mptsas_sge_mainframe(cmd, frame, acc_hdl, j, 4450 ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT) << 4451 MPI2_SGE_FLAGS_SHIFT)); 4452 dmap += j; 4453 sge += j; 4454 j++; 4455 4456 /* 4457 * Fill in the chain element in the main frame. 4458 * About calculation on ChainOffset: 4459 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes) 4460 * in the end reserved for SGL element storage 4461 * (MPI2_SGE_IO_UNION); we should count it in our 4462 * calculation. See its definition in the header file. 4463 * 2. Constant j is the counter of the current SGL element 4464 * that will be processed, and (j - 1) is the number of 4465 * SGL elements that have been processed (stored in the 4466 * main frame). 4467 * 3. ChainOffset value should be in units of double-words (4 4468 * bytes) so the last value should be divided by 4. 4469 */ 4470 ddi_put8(acc_hdl, &frame->ChainOffset, 4471 (sizeof (MPI2_SCSI_IO_REQUEST) - 4472 sizeof (MPI2_SGE_IO_UNION) + 4473 (j - 1) * sizeof (MPI2_SGE_SIMPLE64)) >> 2); 4474 sgechain = (pMpi2SGEChain64_t)sge; 4475 chainflags = (MPI2_SGE_FLAGS_CHAIN_ELEMENT | 4476 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4477 MPI2_SGE_FLAGS_64_BIT_ADDRESSING); 4478 ddi_put8(acc_hdl, &sgechain->Flags, chainflags); 4479 4480 /* 4481 * The size of the next frame is the accurate size of space 4482 * (in bytes) used to store the SGL elements. j is the counter 4483 * of SGL elements. (j - 1) is the number of SGL elements that 4484 * have been processed (stored in frames). 4485 */ 4486 if (frames >= 2) { 4487 ASSERT(mpt->m_req_frame_size >= sizeof (MPI2_SGE_SIMPLE64)); 4488 chainlength = mpt->m_req_frame_size / 4489 sizeof (MPI2_SGE_SIMPLE64) * 4490 sizeof (MPI2_SGE_SIMPLE64); 4491 } else { 4492 chainlength = ((cookiec - (j - 1)) * 4493 sizeof (MPI2_SGE_SIMPLE64)); 4494 } 4495 4496 p = cmd->cmd_extra_frames; 4497 4498 ddi_put16(acc_hdl, &sgechain->Length, chainlength); 4499 ddi_put32(acc_hdl, &sgechain->Address.Low, p->m_phys_addr); 4500 ddi_put32(acc_hdl, &sgechain->Address.High, p->m_phys_addr >> 32); 4501 4502 /* 4503 * If there are more than 2 frames left we have to 4504 * fill in the next chain offset to the location of 4505 * the chain element in the next frame. 4506 * sgemax is the number of simple elements in an extra 4507 * frame. Note that the value NextChainOffset should be 4508 * in double-words (4 bytes). 4509 */ 4510 if (frames >= 2) { 4511 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 4512 (sgemax * sizeof (MPI2_SGE_SIMPLE64)) >> 2); 4513 } else { 4514 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 0); 4515 } 4516 4517 /* 4518 * Jump to next frame; 4519 * Starting here, chain buffers go into the per command SGL. 4520 * This buffer is allocated when chain buffers are needed. 4521 */ 4522 sge = (pMpi2SGESimple64_t)p->m_frames_addr; 4523 i = cookiec; 4524 4525 /* 4526 * Start filling in frames with SGE's. If we 4527 * reach the end of frame and still have SGE's 4528 * to fill we need to add a chain element and 4529 * use another frame. j will be our counter 4530 * for what cookie we are at and i will be 4531 * the total cookiec. k is the current frame 4532 */ 4533 for (k = 1; k <= frames; k++) { 4534 for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) { 4535 4536 /* 4537 * If we have reached the end of frame 4538 * and we have more SGE's to fill in 4539 * we have to fill the final entry 4540 * with a chain element and then 4541 * continue to the next frame 4542 */ 4543 if ((l == (sgemax + 1)) && (k != frames)) { 4544 sgechain = (pMpi2SGEChain64_t)sge; 4545 j--; 4546 chainflags = ( 4547 MPI2_SGE_FLAGS_CHAIN_ELEMENT | 4548 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4549 MPI2_SGE_FLAGS_64_BIT_ADDRESSING); 4550 ddi_put8(p->m_acc_hdl, 4551 &sgechain->Flags, chainflags); 4552 /* 4553 * k is the frame counter and (k + 1) 4554 * is the number of the next frame. 4555 * Note that frames are in contiguous 4556 * memory space. 4557 */ 4558 nframe_phys_addr = p->m_phys_addr + 4559 (mpt->m_req_frame_size * k); 4560 ddi_put32(p->m_acc_hdl, 4561 &sgechain->Address.Low, 4562 nframe_phys_addr); 4563 ddi_put32(p->m_acc_hdl, 4564 &sgechain->Address.High, 4565 nframe_phys_addr >> 32); 4566 4567 /* 4568 * If there are more than 2 frames left 4569 * we have to next chain offset to 4570 * the location of the chain element 4571 * in the next frame and fill in the 4572 * length of the next chain 4573 */ 4574 if ((frames - k) >= 2) { 4575 ddi_put8(p->m_acc_hdl, 4576 &sgechain->NextChainOffset, 4577 (sgemax * 4578 sizeof (MPI2_SGE_SIMPLE64)) 4579 >> 2); 4580 ddi_put16(p->m_acc_hdl, 4581 &sgechain->Length, 4582 mpt->m_req_frame_size / 4583 sizeof (MPI2_SGE_SIMPLE64) * 4584 sizeof (MPI2_SGE_SIMPLE64)); 4585 } else { 4586 /* 4587 * This is the last frame. Set 4588 * the NextChainOffset to 0 and 4589 * Length is the total size of 4590 * all remaining simple elements 4591 */ 4592 ddi_put8(p->m_acc_hdl, 4593 &sgechain->NextChainOffset, 4594 0); 4595 ddi_put16(p->m_acc_hdl, 4596 &sgechain->Length, 4597 (cookiec - j) * 4598 sizeof (MPI2_SGE_SIMPLE64)); 4599 } 4600 4601 /* Jump to the next frame */ 4602 sge = (pMpi2SGESimple64_t) 4603 ((char *)p->m_frames_addr + 4604 (int)mpt->m_req_frame_size * k); 4605 4606 continue; 4607 } 4608 4609 ddi_put32(p->m_acc_hdl, 4610 &sge->Address.Low, 4611 dmap->addr.address64.Low); 4612 ddi_put32(p->m_acc_hdl, 4613 &sge->Address.High, 4614 dmap->addr.address64.High); 4615 ddi_put32(p->m_acc_hdl, 4616 &sge->FlagsLength, dmap->count); 4617 flags = ddi_get32(p->m_acc_hdl, 4618 &sge->FlagsLength); 4619 flags |= ((uint32_t)( 4620 MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4621 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4622 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4623 MPI2_SGE_FLAGS_SHIFT); 4624 4625 /* 4626 * If we are at the end of the frame and 4627 * there is another frame to fill in 4628 * we set the last simple element as last 4629 * element 4630 */ 4631 if ((l == sgemax) && (k != frames)) { 4632 flags |= ((uint32_t) 4633 (MPI2_SGE_FLAGS_LAST_ELEMENT) << 4634 MPI2_SGE_FLAGS_SHIFT); 4635 } 4636 4637 /* 4638 * If this is the final cookie we 4639 * indicate it by setting the flags 4640 */ 4641 if (j == i) { 4642 flags |= ((uint32_t) 4643 (MPI2_SGE_FLAGS_LAST_ELEMENT | 4644 MPI2_SGE_FLAGS_END_OF_BUFFER | 4645 MPI2_SGE_FLAGS_END_OF_LIST) << 4646 MPI2_SGE_FLAGS_SHIFT); 4647 } 4648 if (cmd->cmd_flags & CFLAG_DMASEND) { 4649 flags |= 4650 (MPI2_SGE_FLAGS_HOST_TO_IOC << 4651 MPI2_SGE_FLAGS_SHIFT); 4652 } else { 4653 flags |= 4654 (MPI2_SGE_FLAGS_IOC_TO_HOST << 4655 MPI2_SGE_FLAGS_SHIFT); 4656 } 4657 ddi_put32(p->m_acc_hdl, 4658 &sge->FlagsLength, flags); 4659 dmap++; 4660 sge++; 4661 } 4662 } 4663 4664 /* 4665 * Sync DMA with the chain buffers that were just created 4666 */ 4667 (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 4668 } 4669 4670 static void 4671 mptsas_ieee_sge_mainframe(mptsas_cmd_t *cmd, pMpi2SCSIIORequest_t frame, 4672 ddi_acc_handle_t acc_hdl, uint_t cookiec, uint8_t end_flag) 4673 { 4674 pMpi2IeeeSgeSimple64_t ieeesge; 4675 mptti_t *dmap; 4676 uint8_t flags; 4677 4678 dmap = cmd->cmd_sg; 4679 4680 NDBG1(("mptsas_ieee_sge_mainframe: cookiec=%d, %s", cookiec, 4681 cmd->cmd_flags & CFLAG_DMASEND?"Out":"In")); 4682 4683 ieeesge = (pMpi2IeeeSgeSimple64_t)(&frame->SGL); 4684 while (cookiec--) { 4685 ddi_put32(acc_hdl, 4686 &ieeesge->Address.Low, dmap->addr.address64.Low); 4687 ddi_put32(acc_hdl, 4688 &ieeesge->Address.High, dmap->addr.address64.High); 4689 ddi_put32(acc_hdl, &ieeesge->Length, 4690 dmap->count); 4691 NDBG1(("mptsas_ieee_sge_mainframe: len=%d", dmap->count)); 4692 flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | 4693 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR); 4694 4695 /* 4696 * If this is the last cookie, we set the flags 4697 * to indicate so 4698 */ 4699 if (cookiec == 0) { 4700 flags |= end_flag; 4701 } 4702 4703 ddi_put8(acc_hdl, &ieeesge->Flags, flags); 4704 dmap++; 4705 ieeesge++; 4706 } 4707 } 4708 4709 static void 4710 mptsas_ieee_sge_chain(mptsas_t *mpt, mptsas_cmd_t *cmd, 4711 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl) 4712 { 4713 pMpi2IeeeSgeSimple64_t ieeesge; 4714 pMpi25IeeeSgeChain64_t ieeesgechain; 4715 uint64_t nframe_phys_addr; 4716 uint_t cookiec; 4717 mptti_t *dmap; 4718 uint8_t flags; 4719 4720 /* 4721 * Save the number of entries in the DMA 4722 * Scatter/Gather list 4723 */ 4724 cookiec = cmd->cmd_cookiec; 4725 4726 NDBG1(("mptsas_ieee_sge_chain: cookiec=%d", cookiec)); 4727 4728 /* 4729 * Hereby we start to deal with multiple frames. 4730 * The process is as follows: 4731 * 1. Determine how many frames are needed for SGL element 4732 * storage; Note that all frames are stored in contiguous 4733 * memory space and in 64-bit DMA mode each element is 4734 * 4 double-words (16 bytes) long. 4735 * 2. Fill up the main frame. We need to do this separately 4736 * since it contains the SCSI IO request header and needs 4737 * dedicated processing. Note that the last 4 double-words 4738 * of the SCSI IO header is for SGL element storage 4739 * (MPI2_SGE_IO_UNION). 4740 * 3. Fill the chain element in the main frame, so the DMA 4741 * engine can use the following frames. 4742 * 4. Enter a loop to fill the remaining frames. Note that the 4743 * last frame contains no chain element. The remaining 4744 * frames go into the mpt SGL buffer allocated on the fly, 4745 * not immediately following the main message frame, as in 4746 * Gen1. 4747 * Restrictions: 4748 * For 64-bit DMA, the simple element and chain element 4749 * are both of 4 double-words (16 bytes) in size, even 4750 * though all frames are stored in the first 4G of mem 4751 * range and the higher 32-bits of the address are always 0. 4752 */ 4753 int i, j, k, l, frames, sgemax; 4754 int temp; 4755 uint8_t chainflags; 4756 uint32_t chainlength; 4757 mptsas_cache_frames_t *p; 4758 4759 /* 4760 * Sgemax is the number of SGE's that will fit 4761 * each extra frame and frames is total 4762 * number of frames we'll need. 1 sge entry per 4763 * frame is reseverd for the chain element thus the -1 below. 4764 */ 4765 sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_IEEE_SGE_SIMPLE64)) 4766 - 1); 4767 temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax; 4768 4769 /* 4770 * A little check to see if we need to round up the number 4771 * of frames we need 4772 */ 4773 if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp * 4774 sgemax) > 1) { 4775 frames = (temp + 1); 4776 } else { 4777 frames = temp; 4778 } 4779 NDBG1(("mptsas_ieee_sge_chain: temp=%d, frames=%d", temp, frames)); 4780 dmap = cmd->cmd_sg; 4781 ieeesge = (pMpi2IeeeSgeSimple64_t)(&frame->SGL); 4782 4783 /* 4784 * First fill in the main frame 4785 */ 4786 j = MPTSAS_MAX_FRAME_SGES64(mpt) - 1; 4787 mptsas_ieee_sge_mainframe(cmd, frame, acc_hdl, j, 0); 4788 dmap += j; 4789 ieeesge += j; 4790 j++; 4791 4792 /* 4793 * Fill in the chain element in the main frame. 4794 * About calculation on ChainOffset: 4795 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes) 4796 * in the end reserved for SGL element storage 4797 * (MPI2_SGE_IO_UNION); we should count it in our 4798 * calculation. See its definition in the header file. 4799 * 2. Constant j is the counter of the current SGL element 4800 * that will be processed, and (j - 1) is the number of 4801 * SGL elements that have been processed (stored in the 4802 * main frame). 4803 * 3. ChainOffset value should be in units of quad-words (16 4804 * bytes) so the last value should be divided by 16. 4805 */ 4806 ddi_put8(acc_hdl, &frame->ChainOffset, 4807 (sizeof (MPI2_SCSI_IO_REQUEST) - 4808 sizeof (MPI2_SGE_IO_UNION) + 4809 (j - 1) * sizeof (MPI2_IEEE_SGE_SIMPLE64)) >> 4); 4810 ieeesgechain = (pMpi25IeeeSgeChain64_t)ieeesge; 4811 chainflags = (MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT | 4812 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR); 4813 ddi_put8(acc_hdl, &ieeesgechain->Flags, chainflags); 4814 4815 /* 4816 * The size of the next frame is the accurate size of space 4817 * (in bytes) used to store the SGL elements. j is the counter 4818 * of SGL elements. (j - 1) is the number of SGL elements that 4819 * have been processed (stored in frames). 4820 */ 4821 if (frames >= 2) { 4822 ASSERT(mpt->m_req_frame_size >= 4823 sizeof (MPI2_IEEE_SGE_SIMPLE64)); 4824 chainlength = mpt->m_req_frame_size / 4825 sizeof (MPI2_IEEE_SGE_SIMPLE64) * 4826 sizeof (MPI2_IEEE_SGE_SIMPLE64); 4827 } else { 4828 chainlength = ((cookiec - (j - 1)) * 4829 sizeof (MPI2_IEEE_SGE_SIMPLE64)); 4830 } 4831 4832 p = cmd->cmd_extra_frames; 4833 4834 ddi_put32(acc_hdl, &ieeesgechain->Length, chainlength); 4835 ddi_put32(acc_hdl, &ieeesgechain->Address.Low, p->m_phys_addr); 4836 ddi_put32(acc_hdl, &ieeesgechain->Address.High, p->m_phys_addr >> 32); 4837 4838 /* 4839 * If there are more than 2 frames left we have to 4840 * fill in the next chain offset to the location of 4841 * the chain element in the next frame. 4842 * sgemax is the number of simple elements in an extra 4843 * frame. Note that the value NextChainOffset should be 4844 * in double-words (4 bytes). 4845 */ 4846 if (frames >= 2) { 4847 ddi_put8(acc_hdl, &ieeesgechain->NextChainOffset, 4848 (sgemax * sizeof (MPI2_IEEE_SGE_SIMPLE64)) >> 4); 4849 } else { 4850 ddi_put8(acc_hdl, &ieeesgechain->NextChainOffset, 0); 4851 } 4852 4853 /* 4854 * Jump to next frame; 4855 * Starting here, chain buffers go into the per command SGL. 4856 * This buffer is allocated when chain buffers are needed. 4857 */ 4858 ieeesge = (pMpi2IeeeSgeSimple64_t)p->m_frames_addr; 4859 i = cookiec; 4860 4861 /* 4862 * Start filling in frames with SGE's. If we 4863 * reach the end of frame and still have SGE's 4864 * to fill we need to add a chain element and 4865 * use another frame. j will be our counter 4866 * for what cookie we are at and i will be 4867 * the total cookiec. k is the current frame 4868 */ 4869 for (k = 1; k <= frames; k++) { 4870 for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) { 4871 4872 /* 4873 * If we have reached the end of frame 4874 * and we have more SGE's to fill in 4875 * we have to fill the final entry 4876 * with a chain element and then 4877 * continue to the next frame 4878 */ 4879 if ((l == (sgemax + 1)) && (k != frames)) { 4880 ieeesgechain = (pMpi25IeeeSgeChain64_t)ieeesge; 4881 j--; 4882 chainflags = 4883 MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT | 4884 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR; 4885 ddi_put8(p->m_acc_hdl, 4886 &ieeesgechain->Flags, chainflags); 4887 /* 4888 * k is the frame counter and (k + 1) 4889 * is the number of the next frame. 4890 * Note that frames are in contiguous 4891 * memory space. 4892 */ 4893 nframe_phys_addr = p->m_phys_addr + 4894 (mpt->m_req_frame_size * k); 4895 ddi_put32(p->m_acc_hdl, 4896 &ieeesgechain->Address.Low, 4897 nframe_phys_addr); 4898 ddi_put32(p->m_acc_hdl, 4899 &ieeesgechain->Address.High, 4900 nframe_phys_addr >> 32); 4901 4902 /* 4903 * If there are more than 2 frames left 4904 * we have to next chain offset to 4905 * the location of the chain element 4906 * in the next frame and fill in the 4907 * length of the next chain 4908 */ 4909 if ((frames - k) >= 2) { 4910 ddi_put8(p->m_acc_hdl, 4911 &ieeesgechain->NextChainOffset, 4912 (sgemax * 4913 sizeof (MPI2_IEEE_SGE_SIMPLE64)) 4914 >> 4); 4915 ASSERT(mpt->m_req_frame_size >= 4916 sizeof (MPI2_IEEE_SGE_SIMPLE64)); 4917 ddi_put32(p->m_acc_hdl, 4918 &ieeesgechain->Length, 4919 mpt->m_req_frame_size / 4920 sizeof (MPI2_IEEE_SGE_SIMPLE64) * 4921 sizeof (MPI2_IEEE_SGE_SIMPLE64)); 4922 } else { 4923 /* 4924 * This is the last frame. Set 4925 * the NextChainOffset to 0 and 4926 * Length is the total size of 4927 * all remaining simple elements 4928 */ 4929 ddi_put8(p->m_acc_hdl, 4930 &ieeesgechain->NextChainOffset, 4931 0); 4932 ddi_put32(p->m_acc_hdl, 4933 &ieeesgechain->Length, 4934 (cookiec - j) * 4935 sizeof (MPI2_IEEE_SGE_SIMPLE64)); 4936 } 4937 4938 /* Jump to the next frame */ 4939 ieeesge = (pMpi2IeeeSgeSimple64_t) 4940 ((char *)p->m_frames_addr + 4941 (int)mpt->m_req_frame_size * k); 4942 4943 continue; 4944 } 4945 4946 ddi_put32(p->m_acc_hdl, 4947 &ieeesge->Address.Low, 4948 dmap->addr.address64.Low); 4949 ddi_put32(p->m_acc_hdl, 4950 &ieeesge->Address.High, 4951 dmap->addr.address64.High); 4952 ddi_put32(p->m_acc_hdl, 4953 &ieeesge->Length, dmap->count); 4954 flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | 4955 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR); 4956 4957 /* 4958 * If we are at the end of the frame and 4959 * there is another frame to fill in 4960 * do we need to do anything? 4961 * if ((l == sgemax) && (k != frames)) { 4962 * } 4963 */ 4964 4965 /* 4966 * If this is the final cookie set end of list. 4967 */ 4968 if (j == i) { 4969 flags |= MPI25_IEEE_SGE_FLAGS_END_OF_LIST; 4970 } 4971 4972 ddi_put8(p->m_acc_hdl, &ieeesge->Flags, flags); 4973 dmap++; 4974 ieeesge++; 4975 } 4976 } 4977 4978 /* 4979 * Sync DMA with the chain buffers that were just created 4980 */ 4981 (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 4982 } 4983 4984 static void 4985 mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, uint32_t *control, 4986 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl) 4987 { 4988 ASSERT(cmd->cmd_flags & CFLAG_DMAVALID); 4989 4990 NDBG1(("mptsas_sge_setup: cookiec=%d", cmd->cmd_cookiec)); 4991 4992 /* 4993 * Set read/write bit in control. 4994 */ 4995 if (cmd->cmd_flags & CFLAG_DMASEND) { 4996 *control |= MPI2_SCSIIO_CONTROL_WRITE; 4997 } else { 4998 *control |= MPI2_SCSIIO_CONTROL_READ; 4999 } 5000 5001 ddi_put32(acc_hdl, &frame->DataLength, cmd->cmd_dmacount); 5002 5003 /* 5004 * We have 4 cases here. First where we can fit all the 5005 * SG elements into the main frame, and the case 5006 * where we can't. The SG element is also different when using 5007 * MPI2.5 interface. 5008 * If we have more cookies than we can attach to a frame 5009 * we will need to use a chain element to point 5010 * a location of memory where the rest of the S/G 5011 * elements reside. 5012 */ 5013 if (cmd->cmd_cookiec <= MPTSAS_MAX_FRAME_SGES64(mpt)) { 5014 if (mpt->m_MPI25) { 5015 mptsas_ieee_sge_mainframe(cmd, frame, acc_hdl, 5016 cmd->cmd_cookiec, 5017 MPI25_IEEE_SGE_FLAGS_END_OF_LIST); 5018 } else { 5019 mptsas_sge_mainframe(cmd, frame, acc_hdl, 5020 cmd->cmd_cookiec, 5021 ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT 5022 | MPI2_SGE_FLAGS_END_OF_BUFFER 5023 | MPI2_SGE_FLAGS_END_OF_LIST) << 5024 MPI2_SGE_FLAGS_SHIFT)); 5025 } 5026 } else { 5027 if (mpt->m_MPI25) { 5028 mptsas_ieee_sge_chain(mpt, cmd, frame, acc_hdl); 5029 } else { 5030 mptsas_sge_chain(mpt, cmd, frame, acc_hdl); 5031 } 5032 } 5033 } 5034 5035 /* 5036 * Interrupt handling 5037 * Utility routine. Poll for status of a command sent to HBA 5038 * without interrupts (a FLAG_NOINTR command). 5039 */ 5040 int 5041 mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime) 5042 { 5043 int rval = TRUE; 5044 5045 NDBG5(("mptsas_poll: cmd=0x%p", (void *)poll_cmd)); 5046 5047 if ((poll_cmd->cmd_flags & CFLAG_TM_CMD) == 0) { 5048 mptsas_restart_hba(mpt); 5049 } 5050 5051 /* 5052 * Wait, using drv_usecwait(), long enough for the command to 5053 * reasonably return from the target if the target isn't 5054 * "dead". A polled command may well be sent from scsi_poll, and 5055 * there are retries built in to scsi_poll if the transport 5056 * accepted the packet (TRAN_ACCEPT). scsi_poll waits 1 second 5057 * and retries the transport up to scsi_poll_busycnt times 5058 * (currently 60) if 5059 * 1. pkt_reason is CMD_INCOMPLETE and pkt_state is 0, or 5060 * 2. pkt_reason is CMD_CMPLT and *pkt_scbp has STATUS_BUSY 5061 * 5062 * limit the waiting to avoid a hang in the event that the 5063 * cmd never gets started but we are still receiving interrupts 5064 */ 5065 while (!(poll_cmd->cmd_flags & CFLAG_FINISHED)) { 5066 if (mptsas_wait_intr(mpt, polltime) == FALSE) { 5067 NDBG5(("mptsas_poll: command incomplete")); 5068 rval = FALSE; 5069 break; 5070 } 5071 } 5072 5073 if (rval == FALSE) { 5074 5075 /* 5076 * this isn't supposed to happen, the hba must be wedged 5077 * Mark this cmd as a timeout. 5078 */ 5079 mptsas_set_pkt_reason(mpt, poll_cmd, CMD_TIMEOUT, 5080 (STAT_TIMEOUT|STAT_ABORTED)); 5081 5082 if (poll_cmd->cmd_queued == FALSE) { 5083 5084 NDBG5(("mptsas_poll: not on waitq")); 5085 5086 poll_cmd->cmd_pkt->pkt_state |= 5087 (STATE_GOT_BUS|STATE_GOT_TARGET|STATE_SENT_CMD); 5088 } else { 5089 5090 /* find and remove it from the waitq */ 5091 NDBG5(("mptsas_poll: delete from waitq")); 5092 mptsas_waitq_delete(mpt, poll_cmd); 5093 } 5094 5095 } 5096 mptsas_fma_check(mpt, poll_cmd); 5097 NDBG5(("mptsas_poll: done")); 5098 return (rval); 5099 } 5100 5101 /* 5102 * Used for polling cmds and TM function 5103 */ 5104 static int 5105 mptsas_wait_intr(mptsas_t *mpt, int polltime) 5106 { 5107 int cnt; 5108 pMpi2ReplyDescriptorsUnion_t reply_desc_union; 5109 uint32_t int_mask; 5110 5111 NDBG5(("mptsas_wait_intr")); 5112 5113 mpt->m_polled_intr = 1; 5114 5115 /* 5116 * Get the current interrupt mask and disable interrupts. When 5117 * re-enabling ints, set mask to saved value. 5118 */ 5119 int_mask = ddi_get32(mpt->m_datap, &mpt->m_reg->HostInterruptMask); 5120 MPTSAS_DISABLE_INTR(mpt); 5121 5122 /* 5123 * Keep polling for at least (polltime * 1000) seconds 5124 */ 5125 for (cnt = 0; cnt < polltime; cnt++) { 5126 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 5127 DDI_DMA_SYNC_FORCPU); 5128 5129 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t) 5130 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index); 5131 5132 if (ddi_get32(mpt->m_acc_post_queue_hdl, 5133 &reply_desc_union->Words.Low) == 0xFFFFFFFF || 5134 ddi_get32(mpt->m_acc_post_queue_hdl, 5135 &reply_desc_union->Words.High) == 0xFFFFFFFF) { 5136 drv_usecwait(1000); 5137 continue; 5138 } 5139 5140 /* 5141 * The reply is valid, process it according to its 5142 * type. 5143 */ 5144 mptsas_process_intr(mpt, reply_desc_union); 5145 5146 if (++mpt->m_post_index == mpt->m_post_queue_depth) { 5147 mpt->m_post_index = 0; 5148 } 5149 5150 /* 5151 * Update the global reply index 5152 */ 5153 ddi_put32(mpt->m_datap, 5154 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); 5155 mpt->m_polled_intr = 0; 5156 5157 /* 5158 * Re-enable interrupts and quit. 5159 */ 5160 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, 5161 int_mask); 5162 return (TRUE); 5163 5164 } 5165 5166 /* 5167 * Clear polling flag, re-enable interrupts and quit. 5168 */ 5169 mpt->m_polled_intr = 0; 5170 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, int_mask); 5171 return (FALSE); 5172 } 5173 5174 static void 5175 mptsas_handle_scsi_io_success(mptsas_t *mpt, 5176 pMpi2ReplyDescriptorsUnion_t reply_desc) 5177 { 5178 pMpi2SCSIIOSuccessReplyDescriptor_t scsi_io_success; 5179 uint16_t SMID; 5180 mptsas_slots_t *slots = mpt->m_active; 5181 mptsas_cmd_t *cmd = NULL; 5182 struct scsi_pkt *pkt; 5183 5184 ASSERT(mutex_owned(&mpt->m_mutex)); 5185 5186 scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc; 5187 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &scsi_io_success->SMID); 5188 5189 /* 5190 * This is a success reply so just complete the IO. First, do a sanity 5191 * check on the SMID. The final slot is used for TM requests, which 5192 * would not come into this reply handler. 5193 */ 5194 if ((SMID == 0) || (SMID > slots->m_n_normal)) { 5195 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n", 5196 SMID); 5197 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 5198 return; 5199 } 5200 5201 cmd = slots->m_slot[SMID]; 5202 5203 /* 5204 * print warning and return if the slot is empty 5205 */ 5206 if (cmd == NULL) { 5207 mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO " 5208 "in slot %d", SMID); 5209 return; 5210 } 5211 5212 pkt = CMD2PKT(cmd); 5213 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD | 5214 STATE_GOT_STATUS); 5215 if (cmd->cmd_flags & CFLAG_DMAVALID) { 5216 pkt->pkt_state |= STATE_XFERRED_DATA; 5217 } 5218 pkt->pkt_resid = 0; 5219 5220 if (cmd->cmd_flags & CFLAG_PASSTHRU) { 5221 cmd->cmd_flags |= CFLAG_FINISHED; 5222 cv_broadcast(&mpt->m_passthru_cv); 5223 return; 5224 } else { 5225 mptsas_remove_cmd(mpt, cmd); 5226 } 5227 5228 if (cmd->cmd_flags & CFLAG_RETRY) { 5229 /* 5230 * The target returned QFULL or busy, do not add tihs 5231 * pkt to the doneq since the hba will retry 5232 * this cmd. 5233 * 5234 * The pkt has already been resubmitted in 5235 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error(). 5236 * Remove this cmd_flag here. 5237 */ 5238 cmd->cmd_flags &= ~CFLAG_RETRY; 5239 } else { 5240 mptsas_doneq_add(mpt, cmd); 5241 } 5242 } 5243 5244 static void 5245 mptsas_handle_address_reply(mptsas_t *mpt, 5246 pMpi2ReplyDescriptorsUnion_t reply_desc) 5247 { 5248 pMpi2AddressReplyDescriptor_t address_reply; 5249 pMPI2DefaultReply_t reply; 5250 mptsas_fw_diagnostic_buffer_t *pBuffer; 5251 uint32_t reply_addr, reply_frame_dma_baseaddr; 5252 uint16_t SMID, iocstatus; 5253 mptsas_slots_t *slots = mpt->m_active; 5254 mptsas_cmd_t *cmd = NULL; 5255 uint8_t function, buffer_type; 5256 m_replyh_arg_t *args; 5257 int reply_frame_no; 5258 5259 ASSERT(mutex_owned(&mpt->m_mutex)); 5260 5261 address_reply = (pMpi2AddressReplyDescriptor_t)reply_desc; 5262 reply_addr = ddi_get32(mpt->m_acc_post_queue_hdl, 5263 &address_reply->ReplyFrameAddress); 5264 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &address_reply->SMID); 5265 5266 /* 5267 * If reply frame is not in the proper range we should ignore this 5268 * message and exit the interrupt handler. 5269 */ 5270 reply_frame_dma_baseaddr = mpt->m_reply_frame_dma_addr & 0xffffffffu; 5271 if ((reply_addr < reply_frame_dma_baseaddr) || 5272 (reply_addr >= (reply_frame_dma_baseaddr + 5273 (mpt->m_reply_frame_size * mpt->m_max_replies))) || 5274 ((reply_addr - reply_frame_dma_baseaddr) % 5275 mpt->m_reply_frame_size != 0)) { 5276 mptsas_log(mpt, CE_WARN, "?Received invalid reply frame " 5277 "address 0x%x\n", reply_addr); 5278 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 5279 return; 5280 } 5281 5282 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 5283 DDI_DMA_SYNC_FORCPU); 5284 reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame + (reply_addr - 5285 reply_frame_dma_baseaddr)); 5286 function = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Function); 5287 5288 NDBG31(("mptsas_handle_address_reply: function 0x%x, reply_addr=0x%x", 5289 function, reply_addr)); 5290 5291 /* 5292 * don't get slot information and command for events since these values 5293 * don't exist 5294 */ 5295 if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) && 5296 (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) { 5297 /* 5298 * This could be a TM reply, which use the last allocated SMID, 5299 * so allow for that. 5300 */ 5301 if ((SMID == 0) || (SMID > (slots->m_n_normal + 1))) { 5302 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of " 5303 "%d\n", SMID); 5304 ddi_fm_service_impact(mpt->m_dip, 5305 DDI_SERVICE_UNAFFECTED); 5306 return; 5307 } 5308 5309 cmd = slots->m_slot[SMID]; 5310 5311 /* 5312 * print warning and return if the slot is empty 5313 */ 5314 if (cmd == NULL) { 5315 mptsas_log(mpt, CE_WARN, "?NULL command for address " 5316 "reply in slot %d", SMID); 5317 return; 5318 } 5319 if ((cmd->cmd_flags & 5320 (CFLAG_PASSTHRU | CFLAG_CONFIG | CFLAG_FW_DIAG))) { 5321 cmd->cmd_rfm = reply_addr; 5322 cmd->cmd_flags |= CFLAG_FINISHED; 5323 cv_broadcast(&mpt->m_passthru_cv); 5324 cv_broadcast(&mpt->m_config_cv); 5325 cv_broadcast(&mpt->m_fw_diag_cv); 5326 return; 5327 } else if (!(cmd->cmd_flags & CFLAG_FW_CMD)) { 5328 mptsas_remove_cmd(mpt, cmd); 5329 } 5330 NDBG31(("\t\tmptsas_process_intr: slot=%d", SMID)); 5331 } 5332 /* 5333 * Depending on the function, we need to handle 5334 * the reply frame (and cmd) differently. 5335 */ 5336 switch (function) { 5337 case MPI2_FUNCTION_SCSI_IO_REQUEST: 5338 mptsas_check_scsi_io_error(mpt, (pMpi2SCSIIOReply_t)reply, cmd); 5339 break; 5340 case MPI2_FUNCTION_SCSI_TASK_MGMT: 5341 cmd->cmd_rfm = reply_addr; 5342 mptsas_check_task_mgt(mpt, (pMpi2SCSIManagementReply_t)reply, 5343 cmd); 5344 break; 5345 case MPI2_FUNCTION_FW_DOWNLOAD: 5346 cmd->cmd_flags |= CFLAG_FINISHED; 5347 cv_signal(&mpt->m_fw_cv); 5348 break; 5349 case MPI2_FUNCTION_EVENT_NOTIFICATION: 5350 reply_frame_no = (reply_addr - reply_frame_dma_baseaddr) / 5351 mpt->m_reply_frame_size; 5352 args = &mpt->m_replyh_args[reply_frame_no]; 5353 args->mpt = (void *)mpt; 5354 args->rfm = reply_addr; 5355 5356 /* 5357 * Record the event if its type is enabled in 5358 * this mpt instance by ioctl. 5359 */ 5360 mptsas_record_event(args); 5361 5362 /* 5363 * Handle time critical events 5364 * NOT_RESPONDING/ADDED only now 5365 */ 5366 if (mptsas_handle_event_sync(args) == DDI_SUCCESS) { 5367 /* 5368 * Would not return main process, 5369 * just let taskq resolve ack action 5370 * and ack would be sent in taskq thread 5371 */ 5372 NDBG20(("send mptsas_handle_event_sync success")); 5373 } 5374 5375 if (mpt->m_in_reset) { 5376 NDBG20(("dropping event received during reset")); 5377 return; 5378 } 5379 5380 if ((ddi_taskq_dispatch(mpt->m_event_taskq, mptsas_handle_event, 5381 (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) { 5382 mptsas_log(mpt, CE_WARN, "No memory available" 5383 "for dispatch taskq"); 5384 /* 5385 * Return the reply frame to the free queue. 5386 */ 5387 ddi_put32(mpt->m_acc_free_queue_hdl, 5388 &((uint32_t *)(void *) 5389 mpt->m_free_queue)[mpt->m_free_index], reply_addr); 5390 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 5391 DDI_DMA_SYNC_FORDEV); 5392 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 5393 mpt->m_free_index = 0; 5394 } 5395 5396 ddi_put32(mpt->m_datap, 5397 &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index); 5398 } 5399 return; 5400 case MPI2_FUNCTION_DIAG_BUFFER_POST: 5401 /* 5402 * If SMID is 0, this implies that the reply is due to a 5403 * release function with a status that the buffer has been 5404 * released. Set the buffer flags accordingly. 5405 */ 5406 if (SMID == 0) { 5407 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 5408 &reply->IOCStatus); 5409 buffer_type = ddi_get8(mpt->m_acc_reply_frame_hdl, 5410 &(((pMpi2DiagBufferPostReply_t)reply)->BufferType)); 5411 if (iocstatus == MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED) { 5412 pBuffer = 5413 &mpt->m_fw_diag_buffer_list[buffer_type]; 5414 pBuffer->valid_data = TRUE; 5415 pBuffer->owned_by_firmware = FALSE; 5416 pBuffer->immediate = FALSE; 5417 } 5418 } else { 5419 /* 5420 * Normal handling of diag post reply with SMID. 5421 */ 5422 cmd = slots->m_slot[SMID]; 5423 5424 /* 5425 * print warning and return if the slot is empty 5426 */ 5427 if (cmd == NULL) { 5428 mptsas_log(mpt, CE_WARN, "?NULL command for " 5429 "address reply in slot %d", SMID); 5430 return; 5431 } 5432 cmd->cmd_rfm = reply_addr; 5433 cmd->cmd_flags |= CFLAG_FINISHED; 5434 cv_broadcast(&mpt->m_fw_diag_cv); 5435 } 5436 return; 5437 default: 5438 mptsas_log(mpt, CE_WARN, "Unknown function 0x%x ", function); 5439 break; 5440 } 5441 5442 /* 5443 * Return the reply frame to the free queue. 5444 */ 5445 ddi_put32(mpt->m_acc_free_queue_hdl, 5446 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 5447 reply_addr); 5448 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 5449 DDI_DMA_SYNC_FORDEV); 5450 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 5451 mpt->m_free_index = 0; 5452 } 5453 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 5454 mpt->m_free_index); 5455 5456 if (cmd->cmd_flags & CFLAG_FW_CMD) 5457 return; 5458 5459 if (cmd->cmd_flags & CFLAG_RETRY) { 5460 /* 5461 * The target returned QFULL or busy, do not add this 5462 * pkt to the doneq since the hba will retry 5463 * this cmd. 5464 * 5465 * The pkt has already been resubmitted in 5466 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error(). 5467 * Remove this cmd_flag here. 5468 */ 5469 cmd->cmd_flags &= ~CFLAG_RETRY; 5470 } else { 5471 mptsas_doneq_add(mpt, cmd); 5472 } 5473 } 5474 5475 #ifdef MPTSAS_DEBUG 5476 static uint8_t mptsas_last_sense[256]; 5477 #endif 5478 5479 static void 5480 mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, 5481 mptsas_cmd_t *cmd) 5482 { 5483 uint8_t scsi_status, scsi_state; 5484 uint16_t ioc_status, cmd_rqs_len; 5485 uint32_t xferred, sensecount, responsedata, loginfo = 0; 5486 struct scsi_pkt *pkt; 5487 struct scsi_arq_status *arqstat; 5488 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 5489 uint8_t *sensedata = NULL; 5490 uint64_t sas_wwn; 5491 uint8_t phy; 5492 char wwn_str[MPTSAS_WWN_STRLEN]; 5493 5494 scsi_status = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIStatus); 5495 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus); 5496 scsi_state = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIState); 5497 xferred = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->TransferCount); 5498 sensecount = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->SenseCount); 5499 responsedata = ddi_get32(mpt->m_acc_reply_frame_hdl, 5500 &reply->ResponseInfo); 5501 5502 if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 5503 sas_wwn = ptgt->m_addr.mta_wwn; 5504 phy = ptgt->m_phynum; 5505 if (sas_wwn == 0) { 5506 (void) sprintf(wwn_str, "p%x", phy); 5507 } else { 5508 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 5509 } 5510 loginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 5511 &reply->IOCLogInfo); 5512 mptsas_log(mpt, CE_NOTE, 5513 "?Log info 0x%x received for target %d %s.\n" 5514 "\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x", 5515 loginfo, Tgt(cmd), wwn_str, scsi_status, ioc_status, 5516 scsi_state); 5517 } 5518 5519 NDBG31(("\t\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x", 5520 scsi_status, ioc_status, scsi_state)); 5521 5522 pkt = CMD2PKT(cmd); 5523 *(pkt->pkt_scbp) = scsi_status; 5524 5525 if (loginfo == 0x31170000) { 5526 /* 5527 * if loginfo PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY 5528 * 0x31170000 comes, that means the device missing delay 5529 * is in progressing, the command need retry later. 5530 */ 5531 *(pkt->pkt_scbp) = STATUS_BUSY; 5532 return; 5533 } 5534 5535 if ((scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS) && 5536 ((ioc_status & MPI2_IOCSTATUS_MASK) == 5537 MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE)) { 5538 pkt->pkt_reason = CMD_INCOMPLETE; 5539 pkt->pkt_state |= STATE_GOT_BUS; 5540 if (ptgt->m_reset_delay == 0) { 5541 mptsas_set_throttle(mpt, ptgt, 5542 DRAIN_THROTTLE); 5543 } 5544 return; 5545 } 5546 5547 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) { 5548 responsedata &= 0x000000FF; 5549 if (responsedata & MPTSAS_SCSI_RESPONSE_CODE_TLR_OFF) { 5550 mptsas_log(mpt, CE_NOTE, "Do not support the TLR\n"); 5551 pkt->pkt_reason = CMD_TLR_OFF; 5552 return; 5553 } 5554 } 5555 5556 5557 switch (scsi_status) { 5558 case MPI2_SCSI_STATUS_CHECK_CONDITION: 5559 pkt->pkt_resid = (cmd->cmd_dmacount - xferred); 5560 arqstat = (void*)(pkt->pkt_scbp); 5561 arqstat->sts_rqpkt_status = *((struct scsi_status *) 5562 (pkt->pkt_scbp)); 5563 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 5564 STATE_SENT_CMD | STATE_GOT_STATUS | STATE_ARQ_DONE); 5565 if (cmd->cmd_flags & CFLAG_XARQ) { 5566 pkt->pkt_state |= STATE_XARQ_DONE; 5567 } 5568 if (pkt->pkt_resid != cmd->cmd_dmacount) { 5569 pkt->pkt_state |= STATE_XFERRED_DATA; 5570 } 5571 arqstat->sts_rqpkt_reason = pkt->pkt_reason; 5572 arqstat->sts_rqpkt_state = pkt->pkt_state; 5573 arqstat->sts_rqpkt_state |= STATE_XFERRED_DATA; 5574 arqstat->sts_rqpkt_statistics = pkt->pkt_statistics; 5575 sensedata = (uint8_t *)&arqstat->sts_sensedata; 5576 cmd_rqs_len = cmd->cmd_extrqslen ? 5577 cmd->cmd_extrqslen : cmd->cmd_rqslen; 5578 (void) ddi_dma_sync(mpt->m_dma_req_sense_hdl, 0, 0, 5579 DDI_DMA_SYNC_FORKERNEL); 5580 #ifdef MPTSAS_DEBUG 5581 bcopy(cmd->cmd_arq_buf, mptsas_last_sense, 5582 ((cmd_rqs_len >= sizeof (mptsas_last_sense)) ? 5583 sizeof (mptsas_last_sense):cmd_rqs_len)); 5584 #endif 5585 bcopy((uchar_t *)cmd->cmd_arq_buf, sensedata, 5586 ((cmd_rqs_len >= sensecount) ? sensecount : 5587 cmd_rqs_len)); 5588 arqstat->sts_rqpkt_resid = (cmd_rqs_len - sensecount); 5589 cmd->cmd_flags |= CFLAG_CMDARQ; 5590 /* 5591 * Set proper status for pkt if autosense was valid 5592 */ 5593 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) { 5594 struct scsi_status zero_status = { 0 }; 5595 arqstat->sts_rqpkt_status = zero_status; 5596 } 5597 5598 /* 5599 * ASC=0x47 is parity error 5600 * ASC=0x48 is initiator detected error received 5601 */ 5602 if ((scsi_sense_key(sensedata) == KEY_ABORTED_COMMAND) && 5603 ((scsi_sense_asc(sensedata) == 0x47) || 5604 (scsi_sense_asc(sensedata) == 0x48))) { 5605 mptsas_log(mpt, CE_NOTE, "Aborted_command!"); 5606 } 5607 5608 /* 5609 * ASC/ASCQ=0x3F/0x0E means report_luns data changed 5610 * ASC/ASCQ=0x25/0x00 means invalid lun 5611 */ 5612 if (((scsi_sense_key(sensedata) == KEY_UNIT_ATTENTION) && 5613 (scsi_sense_asc(sensedata) == 0x3F) && 5614 (scsi_sense_ascq(sensedata) == 0x0E)) || 5615 ((scsi_sense_key(sensedata) == KEY_ILLEGAL_REQUEST) && 5616 (scsi_sense_asc(sensedata) == 0x25) && 5617 (scsi_sense_ascq(sensedata) == 0x00))) { 5618 mptsas_topo_change_list_t *topo_node = NULL; 5619 5620 topo_node = kmem_zalloc( 5621 sizeof (mptsas_topo_change_list_t), 5622 KM_NOSLEEP); 5623 if (topo_node == NULL) { 5624 mptsas_log(mpt, CE_NOTE, "No memory" 5625 "resource for handle SAS dynamic" 5626 "reconfigure.\n"); 5627 break; 5628 } 5629 topo_node->mpt = mpt; 5630 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET; 5631 topo_node->un.phymask = ptgt->m_addr.mta_phymask; 5632 topo_node->devhdl = ptgt->m_devhdl; 5633 topo_node->object = (void *)ptgt; 5634 topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED; 5635 5636 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 5637 mptsas_handle_dr, 5638 (void *)topo_node, 5639 DDI_NOSLEEP)) != DDI_SUCCESS) { 5640 kmem_free(topo_node, 5641 sizeof (mptsas_topo_change_list_t)); 5642 mptsas_log(mpt, CE_NOTE, "mptsas start taskq" 5643 "for handle SAS dynamic reconfigure" 5644 "failed. \n"); 5645 } 5646 } 5647 break; 5648 case MPI2_SCSI_STATUS_GOOD: 5649 switch (ioc_status & MPI2_IOCSTATUS_MASK) { 5650 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 5651 pkt->pkt_reason = CMD_DEV_GONE; 5652 pkt->pkt_state |= STATE_GOT_BUS; 5653 if (ptgt->m_reset_delay == 0) { 5654 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5655 } 5656 NDBG31(("lost disk for target%d, command:%x", 5657 Tgt(cmd), pkt->pkt_cdbp[0])); 5658 break; 5659 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN: 5660 NDBG31(("data overrun: xferred=%d", xferred)); 5661 NDBG31(("dmacount=%d", cmd->cmd_dmacount)); 5662 pkt->pkt_reason = CMD_DATA_OVR; 5663 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET 5664 | STATE_SENT_CMD | STATE_GOT_STATUS 5665 | STATE_XFERRED_DATA); 5666 pkt->pkt_resid = 0; 5667 break; 5668 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: 5669 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN: 5670 NDBG31(("data underrun: xferred=%d", xferred)); 5671 NDBG31(("dmacount=%d", cmd->cmd_dmacount)); 5672 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET 5673 | STATE_SENT_CMD | STATE_GOT_STATUS); 5674 pkt->pkt_resid = (cmd->cmd_dmacount - xferred); 5675 if (pkt->pkt_resid != cmd->cmd_dmacount) { 5676 pkt->pkt_state |= STATE_XFERRED_DATA; 5677 } 5678 break; 5679 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: 5680 if (cmd->cmd_active_expiration <= gethrtime()) { 5681 /* 5682 * When timeout requested, propagate 5683 * proper reason and statistics to 5684 * target drivers. 5685 */ 5686 mptsas_set_pkt_reason(mpt, cmd, CMD_TIMEOUT, 5687 STAT_BUS_RESET | STAT_TIMEOUT); 5688 } else { 5689 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, 5690 STAT_BUS_RESET); 5691 } 5692 break; 5693 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: 5694 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: 5695 mptsas_set_pkt_reason(mpt, 5696 cmd, CMD_RESET, STAT_DEV_RESET); 5697 break; 5698 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR: 5699 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR: 5700 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET); 5701 mptsas_set_pkt_reason(mpt, 5702 cmd, CMD_TERMINATED, STAT_TERMINATED); 5703 break; 5704 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: 5705 case MPI2_IOCSTATUS_BUSY: 5706 /* 5707 * set throttles to drain 5708 */ 5709 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 5710 ptgt = refhash_next(mpt->m_targets, ptgt)) { 5711 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5712 } 5713 5714 /* 5715 * retry command 5716 */ 5717 cmd->cmd_flags |= CFLAG_RETRY; 5718 cmd->cmd_pkt_flags |= FLAG_HEAD; 5719 5720 (void) mptsas_accept_pkt(mpt, cmd); 5721 break; 5722 default: 5723 mptsas_log(mpt, CE_WARN, 5724 "unknown ioc_status = %x\n", ioc_status); 5725 mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer " 5726 "count = %x, scsi_status = %x", scsi_state, 5727 xferred, scsi_status); 5728 break; 5729 } 5730 break; 5731 case MPI2_SCSI_STATUS_TASK_SET_FULL: 5732 mptsas_handle_qfull(mpt, cmd); 5733 break; 5734 case MPI2_SCSI_STATUS_BUSY: 5735 NDBG31(("scsi_status busy received")); 5736 break; 5737 case MPI2_SCSI_STATUS_RESERVATION_CONFLICT: 5738 NDBG31(("scsi_status reservation conflict received")); 5739 break; 5740 default: 5741 mptsas_log(mpt, CE_WARN, "scsi_status=%x, ioc_status=%x\n", 5742 scsi_status, ioc_status); 5743 mptsas_log(mpt, CE_WARN, 5744 "mptsas_process_intr: invalid scsi status\n"); 5745 break; 5746 } 5747 } 5748 5749 static void 5750 mptsas_check_task_mgt(mptsas_t *mpt, pMpi2SCSIManagementReply_t reply, 5751 mptsas_cmd_t *cmd) 5752 { 5753 uint8_t task_type; 5754 uint16_t ioc_status; 5755 uint32_t log_info; 5756 uint16_t dev_handle; 5757 struct scsi_pkt *pkt = CMD2PKT(cmd); 5758 5759 task_type = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->TaskType); 5760 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus); 5761 log_info = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo); 5762 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->DevHandle); 5763 5764 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 5765 mptsas_log(mpt, CE_WARN, "mptsas_check_task_mgt: Task 0x%x " 5766 "failed. IOCStatus=0x%x IOCLogInfo=0x%x target=%d\n", 5767 task_type, ioc_status, log_info, dev_handle); 5768 pkt->pkt_reason = CMD_INCOMPLETE; 5769 return; 5770 } 5771 5772 switch (task_type) { 5773 case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK: 5774 case MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET: 5775 case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK: 5776 case MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA: 5777 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET: 5778 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION: 5779 break; 5780 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 5781 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 5782 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 5783 /* 5784 * Check for invalid DevHandle of 0 in case application 5785 * sends bad command. DevHandle of 0 could cause problems. 5786 */ 5787 if (dev_handle == 0) { 5788 mptsas_log(mpt, CE_WARN, "!Can't flush target with" 5789 " DevHandle of 0."); 5790 } else { 5791 mptsas_flush_target(mpt, dev_handle, Lun(cmd), 5792 task_type); 5793 } 5794 break; 5795 default: 5796 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.", 5797 task_type); 5798 mptsas_log(mpt, CE_WARN, "ioc status = %x", ioc_status); 5799 break; 5800 } 5801 } 5802 5803 static void 5804 mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg) 5805 { 5806 mptsas_t *mpt = arg->mpt; 5807 uint64_t t = arg->t; 5808 mptsas_cmd_t *cmd; 5809 struct scsi_pkt *pkt; 5810 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 5811 5812 mutex_enter(&item->mutex); 5813 while (item->flag & MPTSAS_DONEQ_THREAD_ACTIVE) { 5814 if (!item->doneq) { 5815 cv_wait(&item->cv, &item->mutex); 5816 } 5817 pkt = NULL; 5818 if ((cmd = mptsas_doneq_thread_rm(mpt, t)) != NULL) { 5819 cmd->cmd_flags |= CFLAG_COMPLETED; 5820 pkt = CMD2PKT(cmd); 5821 } 5822 mutex_exit(&item->mutex); 5823 if (pkt) { 5824 mptsas_pkt_comp(pkt, cmd); 5825 } 5826 mutex_enter(&item->mutex); 5827 } 5828 mutex_exit(&item->mutex); 5829 mutex_enter(&mpt->m_doneq_mutex); 5830 mpt->m_doneq_thread_n--; 5831 cv_broadcast(&mpt->m_doneq_thread_cv); 5832 mutex_exit(&mpt->m_doneq_mutex); 5833 } 5834 5835 5836 /* 5837 * mpt interrupt handler. 5838 */ 5839 static uint_t 5840 mptsas_intr(caddr_t arg1, caddr_t arg2) 5841 { 5842 mptsas_t *mpt = (void *)arg1; 5843 pMpi2ReplyDescriptorsUnion_t reply_desc_union; 5844 uchar_t did_reply = FALSE; 5845 5846 NDBG1(("mptsas_intr: arg1 0x%p arg2 0x%p", (void *)arg1, (void *)arg2)); 5847 5848 mutex_enter(&mpt->m_mutex); 5849 5850 /* 5851 * If interrupts are shared by two channels then check whether this 5852 * interrupt is genuinely for this channel by making sure first the 5853 * chip is in high power state. 5854 */ 5855 if ((mpt->m_options & MPTSAS_OPT_PM) && 5856 (mpt->m_power_level != PM_LEVEL_D0)) { 5857 mutex_exit(&mpt->m_mutex); 5858 return (DDI_INTR_UNCLAIMED); 5859 } 5860 5861 /* 5862 * If polling, interrupt was triggered by some shared interrupt because 5863 * IOC interrupts are disabled during polling, so polling routine will 5864 * handle any replies. Considering this, if polling is happening, 5865 * return with interrupt unclaimed. 5866 */ 5867 if (mpt->m_polled_intr) { 5868 mutex_exit(&mpt->m_mutex); 5869 mptsas_log(mpt, CE_WARN, "mpt_sas: Unclaimed interrupt"); 5870 return (DDI_INTR_UNCLAIMED); 5871 } 5872 5873 /* 5874 * Read the istat register. 5875 */ 5876 if ((INTPENDING(mpt)) != 0) { 5877 /* 5878 * read fifo until empty. 5879 */ 5880 #ifndef __lock_lint 5881 _NOTE(CONSTCOND) 5882 #endif 5883 while (TRUE) { 5884 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 5885 DDI_DMA_SYNC_FORCPU); 5886 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t) 5887 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index); 5888 5889 if (ddi_get32(mpt->m_acc_post_queue_hdl, 5890 &reply_desc_union->Words.Low) == 0xFFFFFFFF || 5891 ddi_get32(mpt->m_acc_post_queue_hdl, 5892 &reply_desc_union->Words.High) == 0xFFFFFFFF) { 5893 break; 5894 } 5895 5896 /* 5897 * The reply is valid, process it according to its 5898 * type. Also, set a flag for updating the reply index 5899 * after they've all been processed. 5900 */ 5901 did_reply = TRUE; 5902 5903 mptsas_process_intr(mpt, reply_desc_union); 5904 5905 /* 5906 * Increment post index and roll over if needed. 5907 */ 5908 if (++mpt->m_post_index == mpt->m_post_queue_depth) { 5909 mpt->m_post_index = 0; 5910 } 5911 } 5912 5913 /* 5914 * Update the global reply index if at least one reply was 5915 * processed. 5916 */ 5917 if (did_reply) { 5918 ddi_put32(mpt->m_datap, 5919 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); 5920 } 5921 } else { 5922 mutex_exit(&mpt->m_mutex); 5923 return (DDI_INTR_UNCLAIMED); 5924 } 5925 NDBG1(("mptsas_intr complete")); 5926 5927 /* 5928 * If no helper threads are created, process the doneq in ISR. If 5929 * helpers are created, use the doneq length as a metric to measure the 5930 * load on the interrupt CPU. If it is long enough, which indicates the 5931 * load is heavy, then we deliver the IO completions to the helpers. 5932 * This measurement has some limitations, although it is simple and 5933 * straightforward and works well for most of the cases at present. 5934 */ 5935 if (!mpt->m_doneq_thread_n || 5936 (mpt->m_doneq_len <= mpt->m_doneq_length_threshold)) { 5937 mptsas_doneq_empty(mpt); 5938 } else { 5939 mptsas_deliver_doneq_thread(mpt); 5940 } 5941 5942 /* 5943 * If there are queued cmd, start them now. 5944 */ 5945 if (mpt->m_waitq != NULL) { 5946 mptsas_restart_waitq(mpt); 5947 } 5948 5949 mutex_exit(&mpt->m_mutex); 5950 return (DDI_INTR_CLAIMED); 5951 } 5952 5953 static void 5954 mptsas_process_intr(mptsas_t *mpt, 5955 pMpi2ReplyDescriptorsUnion_t reply_desc_union) 5956 { 5957 uint8_t reply_type; 5958 5959 ASSERT(mutex_owned(&mpt->m_mutex)); 5960 5961 /* 5962 * The reply is valid, process it according to its 5963 * type. Also, set a flag for updated the reply index 5964 * after they've all been processed. 5965 */ 5966 reply_type = ddi_get8(mpt->m_acc_post_queue_hdl, 5967 &reply_desc_union->Default.ReplyFlags); 5968 reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; 5969 if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS || 5970 reply_type == MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS) { 5971 mptsas_handle_scsi_io_success(mpt, reply_desc_union); 5972 } else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { 5973 mptsas_handle_address_reply(mpt, reply_desc_union); 5974 } else { 5975 mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type); 5976 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 5977 } 5978 5979 /* 5980 * Clear the reply descriptor for re-use and increment 5981 * index. 5982 */ 5983 ddi_put64(mpt->m_acc_post_queue_hdl, 5984 &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index], 5985 0xFFFFFFFFFFFFFFFF); 5986 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 5987 DDI_DMA_SYNC_FORDEV); 5988 } 5989 5990 /* 5991 * handle qfull condition 5992 */ 5993 static void 5994 mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd) 5995 { 5996 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 5997 5998 if ((++cmd->cmd_qfull_retries > ptgt->m_qfull_retries) || 5999 (ptgt->m_qfull_retries == 0)) { 6000 /* 6001 * We have exhausted the retries on QFULL, or, 6002 * the target driver has indicated that it 6003 * wants to handle QFULL itself by setting 6004 * qfull-retries capability to 0. In either case 6005 * we want the target driver's QFULL handling 6006 * to kick in. We do this by having pkt_reason 6007 * as CMD_CMPLT and pkt_scbp as STATUS_QFULL. 6008 */ 6009 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 6010 } else { 6011 if (ptgt->m_reset_delay == 0) { 6012 ptgt->m_t_throttle = 6013 max((ptgt->m_t_ncmds - 2), 0); 6014 } 6015 6016 cmd->cmd_pkt_flags |= FLAG_HEAD; 6017 cmd->cmd_flags &= ~(CFLAG_TRANFLAG); 6018 cmd->cmd_flags |= CFLAG_RETRY; 6019 6020 (void) mptsas_accept_pkt(mpt, cmd); 6021 6022 /* 6023 * when target gives queue full status with no commands 6024 * outstanding (m_t_ncmds == 0), throttle is set to 0 6025 * (HOLD_THROTTLE), and the queue full handling start 6026 * (see psarc/1994/313); if there are commands outstanding, 6027 * throttle is set to (m_t_ncmds - 2) 6028 */ 6029 if (ptgt->m_t_throttle == HOLD_THROTTLE) { 6030 /* 6031 * By setting throttle to QFULL_THROTTLE, we 6032 * avoid submitting new commands and in 6033 * mptsas_restart_cmd find out slots which need 6034 * their throttles to be cleared. 6035 */ 6036 mptsas_set_throttle(mpt, ptgt, QFULL_THROTTLE); 6037 if (mpt->m_restart_cmd_timeid == 0) { 6038 mpt->m_restart_cmd_timeid = 6039 timeout(mptsas_restart_cmd, mpt, 6040 ptgt->m_qfull_retry_interval); 6041 } 6042 } 6043 } 6044 } 6045 6046 mptsas_phymask_t 6047 mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport) 6048 { 6049 mptsas_phymask_t phy_mask = 0; 6050 uint8_t i = 0; 6051 6052 NDBG20(("mptsas%d physport_to_phymask enter", mpt->m_instance)); 6053 6054 ASSERT(mutex_owned(&mpt->m_mutex)); 6055 6056 /* 6057 * If physport is 0xFF, this is a RAID volume. Use phymask of 0. 6058 */ 6059 if (physport == 0xFF) { 6060 return (0); 6061 } 6062 6063 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 6064 if (mpt->m_phy_info[i].attached_devhdl && 6065 (mpt->m_phy_info[i].phy_mask != 0) && 6066 (mpt->m_phy_info[i].port_num == physport)) { 6067 phy_mask = mpt->m_phy_info[i].phy_mask; 6068 break; 6069 } 6070 } 6071 NDBG20(("mptsas%d physport_to_phymask:physport :%x phymask :%x, ", 6072 mpt->m_instance, physport, phy_mask)); 6073 return (phy_mask); 6074 } 6075 6076 /* 6077 * mpt free device handle after device gone, by use of passthrough 6078 */ 6079 static int 6080 mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl) 6081 { 6082 Mpi2SasIoUnitControlRequest_t req; 6083 Mpi2SasIoUnitControlReply_t rep; 6084 int ret; 6085 6086 ASSERT(mutex_owned(&mpt->m_mutex)); 6087 6088 /* 6089 * Need to compose a SAS IO Unit Control request message 6090 * and call mptsas_do_passthru() function 6091 */ 6092 bzero(&req, sizeof (req)); 6093 bzero(&rep, sizeof (rep)); 6094 6095 req.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 6096 req.Operation = MPI2_SAS_OP_REMOVE_DEVICE; 6097 req.DevHandle = LE_16(devhdl); 6098 6099 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL, 6100 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL); 6101 if (ret != 0) { 6102 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit " 6103 "Control error %d", ret); 6104 return (DDI_FAILURE); 6105 } 6106 6107 /* do passthrough success, check the ioc status */ 6108 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 6109 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit " 6110 "Control IOCStatus %d", LE_16(rep.IOCStatus)); 6111 return (DDI_FAILURE); 6112 } 6113 6114 return (DDI_SUCCESS); 6115 } 6116 6117 static void 6118 mptsas_update_phymask(mptsas_t *mpt) 6119 { 6120 mptsas_phymask_t mask = 0, phy_mask; 6121 char *phy_mask_name; 6122 uint8_t current_port; 6123 int i, j; 6124 6125 NDBG20(("mptsas%d update phymask ", mpt->m_instance)); 6126 6127 ASSERT(mutex_owned(&mpt->m_mutex)); 6128 6129 (void) mptsas_get_sas_io_unit_page(mpt); 6130 6131 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 6132 6133 for (i = 0; i < mpt->m_num_phys; i++) { 6134 phy_mask = 0x00; 6135 6136 if (mpt->m_phy_info[i].attached_devhdl == 0) 6137 continue; 6138 6139 bzero(phy_mask_name, sizeof (phy_mask_name)); 6140 6141 current_port = mpt->m_phy_info[i].port_num; 6142 6143 if ((mask & (1 << i)) != 0) 6144 continue; 6145 6146 for (j = 0; j < mpt->m_num_phys; j++) { 6147 if (mpt->m_phy_info[j].attached_devhdl && 6148 (mpt->m_phy_info[j].port_num == current_port)) { 6149 phy_mask |= (1 << j); 6150 } 6151 } 6152 mask = mask | phy_mask; 6153 6154 for (j = 0; j < mpt->m_num_phys; j++) { 6155 if ((phy_mask >> j) & 0x01) { 6156 mpt->m_phy_info[j].phy_mask = phy_mask; 6157 } 6158 } 6159 6160 (void) sprintf(phy_mask_name, "%x", phy_mask); 6161 6162 mutex_exit(&mpt->m_mutex); 6163 /* 6164 * register a iport, if the port has already been existed 6165 * SCSA will do nothing and just return. 6166 */ 6167 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name); 6168 mutex_enter(&mpt->m_mutex); 6169 } 6170 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 6171 NDBG20(("mptsas%d update phymask return", mpt->m_instance)); 6172 } 6173 6174 /* 6175 * mptsas_handle_dr is a task handler for DR, the DR action includes: 6176 * 1. Directly attched Device Added/Removed. 6177 * 2. Expander Device Added/Removed. 6178 * 3. Indirectly Attached Device Added/Expander. 6179 * 4. LUNs of a existing device status change. 6180 * 5. RAID volume created/deleted. 6181 * 6. Member of RAID volume is released because of RAID deletion. 6182 * 7. Physical disks are removed because of RAID creation. 6183 */ 6184 static void 6185 mptsas_handle_dr(void *args) 6186 { 6187 mptsas_topo_change_list_t *topo_node = NULL; 6188 mptsas_topo_change_list_t *save_node = NULL; 6189 mptsas_t *mpt; 6190 dev_info_t *parent = NULL; 6191 mptsas_phymask_t phymask = 0; 6192 char *phy_mask_name; 6193 uint8_t flags = 0, physport = 0xff; 6194 uint8_t port_update = 0; 6195 uint_t event; 6196 6197 topo_node = (mptsas_topo_change_list_t *)args; 6198 6199 mpt = topo_node->mpt; 6200 event = topo_node->event; 6201 flags = topo_node->flags; 6202 6203 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 6204 6205 NDBG20(("mptsas%d handle_dr enter", mpt->m_instance)); 6206 6207 switch (event) { 6208 case MPTSAS_DR_EVENT_RECONFIG_TARGET: 6209 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 6210 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE) || 6211 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) { 6212 /* 6213 * Direct attached or expander attached device added 6214 * into system or a Phys Disk that is being unhidden. 6215 */ 6216 port_update = 1; 6217 } 6218 break; 6219 case MPTSAS_DR_EVENT_RECONFIG_SMP: 6220 /* 6221 * New expander added into system, it must be the head 6222 * of topo_change_list_t 6223 */ 6224 port_update = 1; 6225 break; 6226 default: 6227 port_update = 0; 6228 break; 6229 } 6230 /* 6231 * All cases port_update == 1 may cause initiator port form change 6232 */ 6233 mutex_enter(&mpt->m_mutex); 6234 if (mpt->m_port_chng && port_update) { 6235 /* 6236 * mpt->m_port_chng flag indicates some PHYs of initiator 6237 * port have changed to online. So when expander added or 6238 * directly attached device online event come, we force to 6239 * update port information by issueing SAS IO Unit Page and 6240 * update PHYMASKs. 6241 */ 6242 (void) mptsas_update_phymask(mpt); 6243 mpt->m_port_chng = 0; 6244 6245 } 6246 mutex_exit(&mpt->m_mutex); 6247 while (topo_node) { 6248 phymask = 0; 6249 if (parent == NULL) { 6250 physport = topo_node->un.physport; 6251 event = topo_node->event; 6252 flags = topo_node->flags; 6253 if (event & (MPTSAS_DR_EVENT_OFFLINE_TARGET | 6254 MPTSAS_DR_EVENT_OFFLINE_SMP)) { 6255 /* 6256 * For all offline events, phymask is known 6257 */ 6258 phymask = topo_node->un.phymask; 6259 goto find_parent; 6260 } 6261 if (event & MPTSAS_TOPO_FLAG_REMOVE_HANDLE) { 6262 goto handle_topo_change; 6263 } 6264 if (flags & MPTSAS_TOPO_FLAG_LUN_ASSOCIATED) { 6265 phymask = topo_node->un.phymask; 6266 goto find_parent; 6267 } 6268 6269 if ((flags == 6270 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) && 6271 (event == MPTSAS_DR_EVENT_RECONFIG_TARGET)) { 6272 /* 6273 * There is no any field in IR_CONFIG_CHANGE 6274 * event indicate physport/phynum, let's get 6275 * parent after SAS Device Page0 request. 6276 */ 6277 goto handle_topo_change; 6278 } 6279 6280 mutex_enter(&mpt->m_mutex); 6281 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 6282 /* 6283 * If the direct attached device added or a 6284 * phys disk is being unhidden, argument 6285 * physport actually is PHY#, so we have to get 6286 * phymask according PHY#. 6287 */ 6288 physport = mpt->m_phy_info[physport].port_num; 6289 } 6290 6291 /* 6292 * Translate physport to phymask so that we can search 6293 * parent dip. 6294 */ 6295 phymask = mptsas_physport_to_phymask(mpt, 6296 physport); 6297 mutex_exit(&mpt->m_mutex); 6298 6299 find_parent: 6300 bzero(phy_mask_name, MPTSAS_MAX_PHYS); 6301 /* 6302 * For RAID topology change node, write the iport name 6303 * as v0. 6304 */ 6305 if (flags & MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 6306 (void) sprintf(phy_mask_name, "v0"); 6307 } else { 6308 /* 6309 * phymask can bo 0 if the drive has been 6310 * pulled by the time an add event is 6311 * processed. If phymask is 0, just skip this 6312 * event and continue. 6313 */ 6314 if (phymask == 0) { 6315 mutex_enter(&mpt->m_mutex); 6316 save_node = topo_node; 6317 topo_node = topo_node->next; 6318 ASSERT(save_node); 6319 kmem_free(save_node, 6320 sizeof (mptsas_topo_change_list_t)); 6321 mutex_exit(&mpt->m_mutex); 6322 6323 parent = NULL; 6324 continue; 6325 } 6326 (void) sprintf(phy_mask_name, "%x", phymask); 6327 } 6328 parent = scsi_hba_iport_find(mpt->m_dip, 6329 phy_mask_name); 6330 if (parent == NULL) { 6331 mptsas_log(mpt, CE_WARN, "Failed to find an " 6332 "iport, should not happen!"); 6333 goto out; 6334 } 6335 6336 } 6337 ASSERT(parent); 6338 handle_topo_change: 6339 6340 mutex_enter(&mpt->m_mutex); 6341 /* 6342 * If HBA is being reset, don't perform operations depending 6343 * on the IOC. We must free the topo list, however. 6344 */ 6345 if (!mpt->m_in_reset) 6346 mptsas_handle_topo_change(topo_node, parent); 6347 else 6348 NDBG20(("skipping topo change received during reset")); 6349 save_node = topo_node; 6350 topo_node = topo_node->next; 6351 ASSERT(save_node); 6352 kmem_free(save_node, sizeof (mptsas_topo_change_list_t)); 6353 mutex_exit(&mpt->m_mutex); 6354 6355 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 6356 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) || 6357 (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) { 6358 /* 6359 * If direct attached device associated, make sure 6360 * reset the parent before start the next one. But 6361 * all devices associated with expander shares the 6362 * parent. Also, reset parent if this is for RAID. 6363 */ 6364 parent = NULL; 6365 } 6366 } 6367 out: 6368 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 6369 } 6370 6371 static void 6372 mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node, 6373 dev_info_t *parent) 6374 { 6375 mptsas_target_t *ptgt = NULL; 6376 mptsas_smp_t *psmp = NULL; 6377 mptsas_t *mpt = (void *)topo_node->mpt; 6378 uint16_t devhdl; 6379 uint16_t attached_devhdl; 6380 uint64_t sas_wwn = 0; 6381 int rval = 0; 6382 uint32_t page_address; 6383 uint8_t phy, flags; 6384 char *addr = NULL; 6385 dev_info_t *lundip; 6386 int circ = 0, circ1 = 0; 6387 char attached_wwnstr[MPTSAS_WWN_STRLEN]; 6388 6389 NDBG20(("mptsas%d handle_topo_change enter, devhdl 0x%x," 6390 "event 0x%x, flags 0x%x", mpt->m_instance, topo_node->devhdl, 6391 topo_node->event, topo_node->flags)); 6392 6393 ASSERT(mutex_owned(&mpt->m_mutex)); 6394 6395 switch (topo_node->event) { 6396 case MPTSAS_DR_EVENT_RECONFIG_TARGET: 6397 { 6398 char *phy_mask_name; 6399 mptsas_phymask_t phymask = 0; 6400 6401 if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 6402 /* 6403 * Get latest RAID info. 6404 */ 6405 (void) mptsas_get_raid_info(mpt); 6406 ptgt = refhash_linear_search(mpt->m_targets, 6407 mptsas_target_eval_devhdl, &topo_node->devhdl); 6408 if (ptgt == NULL) 6409 break; 6410 } else { 6411 ptgt = (void *)topo_node->object; 6412 } 6413 6414 if (ptgt == NULL) { 6415 /* 6416 * If a Phys Disk was deleted, RAID info needs to be 6417 * updated to reflect the new topology. 6418 */ 6419 (void) mptsas_get_raid_info(mpt); 6420 6421 /* 6422 * Get sas device page 0 by DevHandle to make sure if 6423 * SSP/SATA end device exist. 6424 */ 6425 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 6426 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 6427 topo_node->devhdl; 6428 6429 rval = mptsas_get_target_device_info(mpt, page_address, 6430 &devhdl, &ptgt); 6431 if (rval == DEV_INFO_WRONG_DEVICE_TYPE) { 6432 mptsas_log(mpt, CE_NOTE, 6433 "mptsas_handle_topo_change: target %d is " 6434 "not a SAS/SATA device. \n", 6435 topo_node->devhdl); 6436 } else if (rval == DEV_INFO_FAIL_ALLOC) { 6437 mptsas_log(mpt, CE_NOTE, 6438 "mptsas_handle_topo_change: could not " 6439 "allocate memory. \n"); 6440 } else if (rval == DEV_INFO_FAIL_GUID) { 6441 mptsas_log(mpt, CE_NOTE, 6442 "mptsas_handle_topo_change: could not " 6443 "get SATA GUID for target %d. \n", 6444 topo_node->devhdl); 6445 } 6446 /* 6447 * If rval is DEV_INFO_PHYS_DISK or indicates failure 6448 * then there is nothing else to do, just leave. 6449 */ 6450 if (rval != DEV_INFO_SUCCESS) { 6451 return; 6452 } 6453 } 6454 6455 ASSERT(ptgt->m_devhdl == topo_node->devhdl); 6456 6457 mutex_exit(&mpt->m_mutex); 6458 flags = topo_node->flags; 6459 6460 if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) { 6461 phymask = ptgt->m_addr.mta_phymask; 6462 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 6463 (void) sprintf(phy_mask_name, "%x", phymask); 6464 parent = scsi_hba_iport_find(mpt->m_dip, 6465 phy_mask_name); 6466 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 6467 if (parent == NULL) { 6468 mptsas_log(mpt, CE_WARN, "Failed to find a " 6469 "iport for PD, should not happen!"); 6470 mutex_enter(&mpt->m_mutex); 6471 break; 6472 } 6473 } 6474 6475 if (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 6476 ndi_devi_enter(parent, &circ1); 6477 (void) mptsas_config_raid(parent, topo_node->devhdl, 6478 &lundip); 6479 ndi_devi_exit(parent, circ1); 6480 } else { 6481 /* 6482 * hold nexus for bus configure 6483 */ 6484 ndi_devi_enter(scsi_vhci_dip, &circ); 6485 ndi_devi_enter(parent, &circ1); 6486 rval = mptsas_config_target(parent, ptgt); 6487 /* 6488 * release nexus for bus configure 6489 */ 6490 ndi_devi_exit(parent, circ1); 6491 ndi_devi_exit(scsi_vhci_dip, circ); 6492 6493 /* 6494 * Add parent's props for SMHBA support 6495 */ 6496 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 6497 bzero(attached_wwnstr, 6498 sizeof (attached_wwnstr)); 6499 (void) sprintf(attached_wwnstr, "w%016"PRIx64, 6500 ptgt->m_addr.mta_wwn); 6501 if (ddi_prop_update_string(DDI_DEV_T_NONE, 6502 parent, 6503 SCSI_ADDR_PROP_ATTACHED_PORT, 6504 attached_wwnstr) 6505 != DDI_PROP_SUCCESS) { 6506 (void) ddi_prop_remove(DDI_DEV_T_NONE, 6507 parent, 6508 SCSI_ADDR_PROP_ATTACHED_PORT); 6509 mptsas_log(mpt, CE_WARN, "Failed to" 6510 "attached-port props"); 6511 return; 6512 } 6513 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6514 MPTSAS_NUM_PHYS, 1) != 6515 DDI_PROP_SUCCESS) { 6516 (void) ddi_prop_remove(DDI_DEV_T_NONE, 6517 parent, MPTSAS_NUM_PHYS); 6518 mptsas_log(mpt, CE_WARN, "Failed to" 6519 " create num-phys props"); 6520 return; 6521 } 6522 6523 /* 6524 * Update PHY info for smhba 6525 */ 6526 mutex_enter(&mpt->m_mutex); 6527 if (mptsas_smhba_phy_init(mpt)) { 6528 mutex_exit(&mpt->m_mutex); 6529 mptsas_log(mpt, CE_WARN, "mptsas phy" 6530 " update failed"); 6531 return; 6532 } 6533 mutex_exit(&mpt->m_mutex); 6534 6535 /* 6536 * topo_node->un.physport is really the PHY# 6537 * for direct attached devices 6538 */ 6539 mptsas_smhba_set_one_phy_props(mpt, parent, 6540 topo_node->un.physport, &attached_devhdl); 6541 6542 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6543 MPTSAS_VIRTUAL_PORT, 0) != 6544 DDI_PROP_SUCCESS) { 6545 (void) ddi_prop_remove(DDI_DEV_T_NONE, 6546 parent, MPTSAS_VIRTUAL_PORT); 6547 mptsas_log(mpt, CE_WARN, 6548 "mptsas virtual-port" 6549 "port prop update failed"); 6550 return; 6551 } 6552 } 6553 } 6554 mutex_enter(&mpt->m_mutex); 6555 6556 NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, " 6557 "phymask:%x.", mpt->m_instance, ptgt->m_devhdl, 6558 ptgt->m_addr.mta_phymask)); 6559 break; 6560 } 6561 case MPTSAS_DR_EVENT_OFFLINE_TARGET: 6562 { 6563 devhdl = topo_node->devhdl; 6564 ptgt = refhash_linear_search(mpt->m_targets, 6565 mptsas_target_eval_devhdl, &devhdl); 6566 if (ptgt == NULL) 6567 break; 6568 6569 sas_wwn = ptgt->m_addr.mta_wwn; 6570 phy = ptgt->m_phynum; 6571 6572 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 6573 6574 if (sas_wwn) { 6575 (void) sprintf(addr, "w%016"PRIx64, sas_wwn); 6576 } else { 6577 (void) sprintf(addr, "p%x", phy); 6578 } 6579 ASSERT(ptgt->m_devhdl == devhdl); 6580 6581 if ((topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) || 6582 (topo_node->flags == 6583 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) { 6584 /* 6585 * Get latest RAID info if RAID volume status changes 6586 * or Phys Disk status changes 6587 */ 6588 (void) mptsas_get_raid_info(mpt); 6589 } 6590 /* 6591 * Abort all outstanding command on the device 6592 */ 6593 rval = mptsas_do_scsi_reset(mpt, devhdl); 6594 if (rval) { 6595 NDBG20(("mptsas%d handle_topo_change to reset target " 6596 "before offline devhdl:%x, phymask:%x, rval:%x", 6597 mpt->m_instance, ptgt->m_devhdl, 6598 ptgt->m_addr.mta_phymask, rval)); 6599 } 6600 6601 mutex_exit(&mpt->m_mutex); 6602 6603 ndi_devi_enter(scsi_vhci_dip, &circ); 6604 ndi_devi_enter(parent, &circ1); 6605 rval = mptsas_offline_target(parent, addr); 6606 ndi_devi_exit(parent, circ1); 6607 ndi_devi_exit(scsi_vhci_dip, circ); 6608 NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, " 6609 "phymask:%x, rval:%x", mpt->m_instance, 6610 ptgt->m_devhdl, ptgt->m_addr.mta_phymask, rval)); 6611 6612 kmem_free(addr, SCSI_MAXNAMELEN); 6613 6614 /* 6615 * Clear parent's props for SMHBA support 6616 */ 6617 flags = topo_node->flags; 6618 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 6619 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6620 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent, 6621 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 6622 DDI_PROP_SUCCESS) { 6623 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6624 SCSI_ADDR_PROP_ATTACHED_PORT); 6625 mptsas_log(mpt, CE_WARN, "mptsas attached port " 6626 "prop update failed"); 6627 break; 6628 } 6629 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6630 MPTSAS_NUM_PHYS, 0) != 6631 DDI_PROP_SUCCESS) { 6632 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6633 MPTSAS_NUM_PHYS); 6634 mptsas_log(mpt, CE_WARN, "mptsas num phys " 6635 "prop update failed"); 6636 break; 6637 } 6638 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6639 MPTSAS_VIRTUAL_PORT, 1) != 6640 DDI_PROP_SUCCESS) { 6641 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6642 MPTSAS_VIRTUAL_PORT); 6643 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 6644 "prop update failed"); 6645 break; 6646 } 6647 } 6648 6649 mutex_enter(&mpt->m_mutex); 6650 ptgt->m_led_status = 0; 6651 (void) mptsas_flush_led_status(mpt, ptgt); 6652 if (rval == DDI_SUCCESS) { 6653 refhash_remove(mpt->m_targets, ptgt); 6654 ptgt = NULL; 6655 } else { 6656 /* 6657 * clean DR_INTRANSITION flag to allow I/O down to 6658 * PHCI driver since failover finished. 6659 * Invalidate the devhdl 6660 */ 6661 ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL; 6662 ptgt->m_tgt_unconfigured = 0; 6663 mutex_enter(&mpt->m_tx_waitq_mutex); 6664 ptgt->m_dr_flag = MPTSAS_DR_INACTIVE; 6665 mutex_exit(&mpt->m_tx_waitq_mutex); 6666 } 6667 6668 /* 6669 * Send SAS IO Unit Control to free the dev handle 6670 */ 6671 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 6672 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE)) { 6673 rval = mptsas_free_devhdl(mpt, devhdl); 6674 6675 NDBG20(("mptsas%d handle_topo_change to remove " 6676 "devhdl:%x, rval:%x", mpt->m_instance, devhdl, 6677 rval)); 6678 } 6679 6680 break; 6681 } 6682 case MPTSAS_TOPO_FLAG_REMOVE_HANDLE: 6683 { 6684 devhdl = topo_node->devhdl; 6685 /* 6686 * If this is the remove handle event, do a reset first. 6687 */ 6688 if (topo_node->event == MPTSAS_TOPO_FLAG_REMOVE_HANDLE) { 6689 rval = mptsas_do_scsi_reset(mpt, devhdl); 6690 if (rval) { 6691 NDBG20(("mpt%d reset target before remove " 6692 "devhdl:%x, rval:%x", mpt->m_instance, 6693 devhdl, rval)); 6694 } 6695 } 6696 6697 /* 6698 * Send SAS IO Unit Control to free the dev handle 6699 */ 6700 rval = mptsas_free_devhdl(mpt, devhdl); 6701 NDBG20(("mptsas%d handle_topo_change to remove " 6702 "devhdl:%x, rval:%x", mpt->m_instance, devhdl, 6703 rval)); 6704 break; 6705 } 6706 case MPTSAS_DR_EVENT_RECONFIG_SMP: 6707 { 6708 mptsas_smp_t smp; 6709 dev_info_t *smpdip; 6710 6711 devhdl = topo_node->devhdl; 6712 6713 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL & 6714 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl; 6715 rval = mptsas_get_sas_expander_page0(mpt, page_address, &smp); 6716 if (rval != DDI_SUCCESS) { 6717 mptsas_log(mpt, CE_WARN, "failed to online smp, " 6718 "handle %x", devhdl); 6719 return; 6720 } 6721 6722 psmp = mptsas_smp_alloc(mpt, &smp); 6723 if (psmp == NULL) { 6724 return; 6725 } 6726 6727 mutex_exit(&mpt->m_mutex); 6728 ndi_devi_enter(parent, &circ1); 6729 (void) mptsas_online_smp(parent, psmp, &smpdip); 6730 ndi_devi_exit(parent, circ1); 6731 6732 mutex_enter(&mpt->m_mutex); 6733 break; 6734 } 6735 case MPTSAS_DR_EVENT_OFFLINE_SMP: 6736 { 6737 devhdl = topo_node->devhdl; 6738 uint32_t dev_info; 6739 6740 psmp = refhash_linear_search(mpt->m_smp_targets, 6741 mptsas_smp_eval_devhdl, &devhdl); 6742 if (psmp == NULL) 6743 break; 6744 /* 6745 * The mptsas_smp_t data is released only if the dip is offlined 6746 * successfully. 6747 */ 6748 mutex_exit(&mpt->m_mutex); 6749 6750 ndi_devi_enter(parent, &circ1); 6751 rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE); 6752 ndi_devi_exit(parent, circ1); 6753 6754 dev_info = psmp->m_deviceinfo; 6755 if ((dev_info & DEVINFO_DIRECT_ATTACHED) == 6756 DEVINFO_DIRECT_ATTACHED) { 6757 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6758 MPTSAS_VIRTUAL_PORT, 1) != 6759 DDI_PROP_SUCCESS) { 6760 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6761 MPTSAS_VIRTUAL_PORT); 6762 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 6763 "prop update failed"); 6764 return; 6765 } 6766 /* 6767 * Check whether the smp connected to the iport, 6768 */ 6769 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6770 MPTSAS_NUM_PHYS, 0) != 6771 DDI_PROP_SUCCESS) { 6772 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6773 MPTSAS_NUM_PHYS); 6774 mptsas_log(mpt, CE_WARN, "mptsas num phys" 6775 "prop update failed"); 6776 return; 6777 } 6778 /* 6779 * Clear parent's attached-port props 6780 */ 6781 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6782 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent, 6783 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 6784 DDI_PROP_SUCCESS) { 6785 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6786 SCSI_ADDR_PROP_ATTACHED_PORT); 6787 mptsas_log(mpt, CE_WARN, "mptsas attached port " 6788 "prop update failed"); 6789 return; 6790 } 6791 } 6792 6793 mutex_enter(&mpt->m_mutex); 6794 NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, " 6795 "rval:%x", mpt->m_instance, psmp->m_devhdl, rval)); 6796 if (rval == DDI_SUCCESS) { 6797 refhash_remove(mpt->m_smp_targets, psmp); 6798 } else { 6799 psmp->m_devhdl = MPTSAS_INVALID_DEVHDL; 6800 } 6801 6802 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6803 6804 break; 6805 } 6806 default: 6807 return; 6808 } 6809 } 6810 6811 /* 6812 * Record the event if its type is enabled in mpt instance by ioctl. 6813 */ 6814 static void 6815 mptsas_record_event(void *args) 6816 { 6817 m_replyh_arg_t *replyh_arg; 6818 pMpi2EventNotificationReply_t eventreply; 6819 uint32_t event, rfm; 6820 mptsas_t *mpt; 6821 int i, j; 6822 uint16_t event_data_len; 6823 boolean_t sendAEN = FALSE; 6824 6825 replyh_arg = (m_replyh_arg_t *)args; 6826 rfm = replyh_arg->rfm; 6827 mpt = replyh_arg->mpt; 6828 6829 eventreply = (pMpi2EventNotificationReply_t) 6830 (mpt->m_reply_frame + (rfm - 6831 (mpt->m_reply_frame_dma_addr & 0xffffffffu))); 6832 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 6833 6834 6835 /* 6836 * Generate a system event to let anyone who cares know that a 6837 * LOG_ENTRY_ADDED event has occurred. This is sent no matter what the 6838 * event mask is set to. 6839 */ 6840 if (event == MPI2_EVENT_LOG_ENTRY_ADDED) { 6841 sendAEN = TRUE; 6842 } 6843 6844 /* 6845 * Record the event only if it is not masked. Determine which dword 6846 * and bit of event mask to test. 6847 */ 6848 i = (uint8_t)(event / 32); 6849 j = (uint8_t)(event % 32); 6850 if ((i < 4) && ((1 << j) & mpt->m_event_mask[i])) { 6851 i = mpt->m_event_index; 6852 mpt->m_events[i].Type = event; 6853 mpt->m_events[i].Number = ++mpt->m_event_number; 6854 bzero(mpt->m_events[i].Data, MPTSAS_MAX_EVENT_DATA_LENGTH * 4); 6855 event_data_len = ddi_get16(mpt->m_acc_reply_frame_hdl, 6856 &eventreply->EventDataLength); 6857 6858 if (event_data_len > 0) { 6859 /* 6860 * Limit data to size in m_event entry 6861 */ 6862 if (event_data_len > MPTSAS_MAX_EVENT_DATA_LENGTH) { 6863 event_data_len = MPTSAS_MAX_EVENT_DATA_LENGTH; 6864 } 6865 for (j = 0; j < event_data_len; j++) { 6866 mpt->m_events[i].Data[j] = 6867 ddi_get32(mpt->m_acc_reply_frame_hdl, 6868 &(eventreply->EventData[j])); 6869 } 6870 6871 /* 6872 * check for index wrap-around 6873 */ 6874 if (++i == MPTSAS_EVENT_QUEUE_SIZE) { 6875 i = 0; 6876 } 6877 mpt->m_event_index = (uint8_t)i; 6878 6879 /* 6880 * Set flag to send the event. 6881 */ 6882 sendAEN = TRUE; 6883 } 6884 } 6885 6886 /* 6887 * Generate a system event if flag is set to let anyone who cares know 6888 * that an event has occurred. 6889 */ 6890 if (sendAEN) { 6891 (void) ddi_log_sysevent(mpt->m_dip, DDI_VENDOR_LSI, "MPT_SAS", 6892 "SAS", NULL, NULL, DDI_NOSLEEP); 6893 } 6894 } 6895 6896 #define SMP_RESET_IN_PROGRESS MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS 6897 /* 6898 * handle sync events from ioc in interrupt 6899 * return value: 6900 * DDI_SUCCESS: The event is handled by this func 6901 * DDI_FAILURE: Event is not handled 6902 */ 6903 static int 6904 mptsas_handle_event_sync(void *args) 6905 { 6906 m_replyh_arg_t *replyh_arg; 6907 pMpi2EventNotificationReply_t eventreply; 6908 uint32_t event, rfm; 6909 mptsas_t *mpt; 6910 uint_t iocstatus; 6911 6912 replyh_arg = (m_replyh_arg_t *)args; 6913 rfm = replyh_arg->rfm; 6914 mpt = replyh_arg->mpt; 6915 6916 ASSERT(mutex_owned(&mpt->m_mutex)); 6917 6918 eventreply = (pMpi2EventNotificationReply_t) 6919 (mpt->m_reply_frame + (rfm - 6920 (mpt->m_reply_frame_dma_addr & 0xffffffffu))); 6921 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 6922 6923 if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 6924 &eventreply->IOCStatus)) { 6925 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 6926 mptsas_log(mpt, CE_WARN, 6927 "!mptsas_handle_event_sync: event 0x%x, " 6928 "IOCStatus=0x%x, " 6929 "IOCLogInfo=0x%x", event, iocstatus, 6930 ddi_get32(mpt->m_acc_reply_frame_hdl, 6931 &eventreply->IOCLogInfo)); 6932 } else { 6933 mptsas_log(mpt, CE_WARN, 6934 "mptsas_handle_event_sync: event 0x%x, " 6935 "IOCStatus=0x%x, " 6936 "(IOCLogInfo=0x%x)", event, iocstatus, 6937 ddi_get32(mpt->m_acc_reply_frame_hdl, 6938 &eventreply->IOCLogInfo)); 6939 } 6940 } 6941 6942 /* 6943 * figure out what kind of event we got and handle accordingly 6944 */ 6945 switch (event) { 6946 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 6947 { 6948 pMpi2EventDataSasTopologyChangeList_t sas_topo_change_list; 6949 uint8_t num_entries, expstatus, phy; 6950 uint8_t phystatus, physport, state, i; 6951 uint8_t start_phy_num, link_rate; 6952 uint16_t dev_handle, reason_code; 6953 uint16_t enc_handle, expd_handle; 6954 char string[80], curr[80], prev[80]; 6955 mptsas_topo_change_list_t *topo_head = NULL; 6956 mptsas_topo_change_list_t *topo_tail = NULL; 6957 mptsas_topo_change_list_t *topo_node = NULL; 6958 mptsas_target_t *ptgt; 6959 mptsas_smp_t *psmp; 6960 uint8_t flags = 0, exp_flag; 6961 smhba_info_t *pSmhba = NULL; 6962 6963 NDBG20(("mptsas_handle_event_sync: SAS topology change")); 6964 6965 sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t) 6966 eventreply->EventData; 6967 6968 enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6969 &sas_topo_change_list->EnclosureHandle); 6970 expd_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6971 &sas_topo_change_list->ExpanderDevHandle); 6972 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl, 6973 &sas_topo_change_list->NumEntries); 6974 start_phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl, 6975 &sas_topo_change_list->StartPhyNum); 6976 expstatus = ddi_get8(mpt->m_acc_reply_frame_hdl, 6977 &sas_topo_change_list->ExpStatus); 6978 physport = ddi_get8(mpt->m_acc_reply_frame_hdl, 6979 &sas_topo_change_list->PhysicalPort); 6980 6981 string[0] = 0; 6982 if (expd_handle) { 6983 flags = MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED; 6984 switch (expstatus) { 6985 case MPI2_EVENT_SAS_TOPO_ES_ADDED: 6986 (void) sprintf(string, " added"); 6987 /* 6988 * New expander device added 6989 */ 6990 mpt->m_port_chng = 1; 6991 topo_node = kmem_zalloc( 6992 sizeof (mptsas_topo_change_list_t), 6993 KM_SLEEP); 6994 topo_node->mpt = mpt; 6995 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_SMP; 6996 topo_node->un.physport = physport; 6997 topo_node->devhdl = expd_handle; 6998 topo_node->flags = flags; 6999 topo_node->object = NULL; 7000 if (topo_head == NULL) { 7001 topo_head = topo_tail = topo_node; 7002 } else { 7003 topo_tail->next = topo_node; 7004 topo_tail = topo_node; 7005 } 7006 break; 7007 case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING: 7008 (void) sprintf(string, " not responding, " 7009 "removed"); 7010 psmp = refhash_linear_search(mpt->m_smp_targets, 7011 mptsas_smp_eval_devhdl, &expd_handle); 7012 if (psmp == NULL) 7013 break; 7014 7015 topo_node = kmem_zalloc( 7016 sizeof (mptsas_topo_change_list_t), 7017 KM_SLEEP); 7018 topo_node->mpt = mpt; 7019 topo_node->un.phymask = 7020 psmp->m_addr.mta_phymask; 7021 topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP; 7022 topo_node->devhdl = expd_handle; 7023 topo_node->flags = flags; 7024 topo_node->object = NULL; 7025 if (topo_head == NULL) { 7026 topo_head = topo_tail = topo_node; 7027 } else { 7028 topo_tail->next = topo_node; 7029 topo_tail = topo_node; 7030 } 7031 break; 7032 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING: 7033 break; 7034 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING: 7035 (void) sprintf(string, " not responding, " 7036 "delaying removal"); 7037 break; 7038 default: 7039 break; 7040 } 7041 } else { 7042 flags = MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE; 7043 } 7044 7045 NDBG20(("SAS TOPOLOGY CHANGE for enclosure %x expander %x%s\n", 7046 enc_handle, expd_handle, string)); 7047 for (i = 0; i < num_entries; i++) { 7048 phy = i + start_phy_num; 7049 phystatus = ddi_get8(mpt->m_acc_reply_frame_hdl, 7050 &sas_topo_change_list->PHY[i].PhyStatus); 7051 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7052 &sas_topo_change_list->PHY[i].AttachedDevHandle); 7053 reason_code = phystatus & MPI2_EVENT_SAS_TOPO_RC_MASK; 7054 /* 7055 * Filter out processing of Phy Vacant Status unless 7056 * the reason code is "Not Responding". Process all 7057 * other combinations of Phy Status and Reason Codes. 7058 */ 7059 if ((phystatus & 7060 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) && 7061 (reason_code != 7062 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) { 7063 continue; 7064 } 7065 curr[0] = 0; 7066 prev[0] = 0; 7067 string[0] = 0; 7068 switch (reason_code) { 7069 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 7070 { 7071 NDBG20(("mptsas%d phy %d physical_port %d " 7072 "dev_handle %d added", mpt->m_instance, phy, 7073 physport, dev_handle)); 7074 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl, 7075 &sas_topo_change_list->PHY[i].LinkRate); 7076 state = (link_rate & 7077 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >> 7078 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT; 7079 switch (state) { 7080 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 7081 (void) sprintf(curr, "is disabled"); 7082 break; 7083 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 7084 (void) sprintf(curr, "is offline, " 7085 "failed speed negotiation"); 7086 break; 7087 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 7088 (void) sprintf(curr, "SATA OOB " 7089 "complete"); 7090 break; 7091 case SMP_RESET_IN_PROGRESS: 7092 (void) sprintf(curr, "SMP reset in " 7093 "progress"); 7094 break; 7095 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 7096 (void) sprintf(curr, "is online at " 7097 "1.5 Gbps"); 7098 break; 7099 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 7100 (void) sprintf(curr, "is online at 3.0 " 7101 "Gbps"); 7102 break; 7103 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 7104 (void) sprintf(curr, "is online at 6.0 " 7105 "Gbps"); 7106 break; 7107 case MPI25_EVENT_SAS_TOPO_LR_RATE_12_0: 7108 (void) sprintf(curr, 7109 "is online at 12.0 Gbps"); 7110 break; 7111 default: 7112 (void) sprintf(curr, "state is " 7113 "unknown"); 7114 break; 7115 } 7116 /* 7117 * New target device added into the system. 7118 * Set association flag according to if an 7119 * expander is used or not. 7120 */ 7121 exp_flag = 7122 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE; 7123 if (flags == 7124 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) { 7125 flags = exp_flag; 7126 } 7127 topo_node = kmem_zalloc( 7128 sizeof (mptsas_topo_change_list_t), 7129 KM_SLEEP); 7130 topo_node->mpt = mpt; 7131 topo_node->event = 7132 MPTSAS_DR_EVENT_RECONFIG_TARGET; 7133 if (expd_handle == 0) { 7134 /* 7135 * Per MPI 2, if expander dev handle 7136 * is 0, it's a directly attached 7137 * device. So driver use PHY to decide 7138 * which iport is associated 7139 */ 7140 physport = phy; 7141 mpt->m_port_chng = 1; 7142 } 7143 topo_node->un.physport = physport; 7144 topo_node->devhdl = dev_handle; 7145 topo_node->flags = flags; 7146 topo_node->object = NULL; 7147 if (topo_head == NULL) { 7148 topo_head = topo_tail = topo_node; 7149 } else { 7150 topo_tail->next = topo_node; 7151 topo_tail = topo_node; 7152 } 7153 break; 7154 } 7155 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 7156 { 7157 NDBG20(("mptsas%d phy %d physical_port %d " 7158 "dev_handle %d removed", mpt->m_instance, 7159 phy, physport, dev_handle)); 7160 /* 7161 * Set association flag according to if an 7162 * expander is used or not. 7163 */ 7164 exp_flag = 7165 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE; 7166 if (flags == 7167 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) { 7168 flags = exp_flag; 7169 } 7170 /* 7171 * Target device is removed from the system 7172 * Before the device is really offline from 7173 * from system. 7174 */ 7175 ptgt = refhash_linear_search(mpt->m_targets, 7176 mptsas_target_eval_devhdl, &dev_handle); 7177 /* 7178 * If ptgt is NULL here, it means that the 7179 * DevHandle is not in the hash table. This is 7180 * reasonable sometimes. For example, if a 7181 * disk was pulled, then added, then pulled 7182 * again, the disk will not have been put into 7183 * the hash table because the add event will 7184 * have an invalid phymask. BUT, this does not 7185 * mean that the DevHandle is invalid. The 7186 * controller will still have a valid DevHandle 7187 * that must be removed. To do this, use the 7188 * MPTSAS_TOPO_FLAG_REMOVE_HANDLE event. 7189 */ 7190 if (ptgt == NULL) { 7191 topo_node = kmem_zalloc( 7192 sizeof (mptsas_topo_change_list_t), 7193 KM_SLEEP); 7194 topo_node->mpt = mpt; 7195 topo_node->un.phymask = 0; 7196 topo_node->event = 7197 MPTSAS_TOPO_FLAG_REMOVE_HANDLE; 7198 topo_node->devhdl = dev_handle; 7199 topo_node->flags = flags; 7200 topo_node->object = NULL; 7201 if (topo_head == NULL) { 7202 topo_head = topo_tail = 7203 topo_node; 7204 } else { 7205 topo_tail->next = topo_node; 7206 topo_tail = topo_node; 7207 } 7208 break; 7209 } 7210 7211 /* 7212 * Update DR flag immediately avoid I/O failure 7213 * before failover finish. Pay attention to the 7214 * mutex protect, we need grab m_tx_waitq_mutex 7215 * during set m_dr_flag because we won't add 7216 * the following command into waitq, instead, 7217 * we need return TRAN_BUSY in the tran_start 7218 * context. 7219 */ 7220 mutex_enter(&mpt->m_tx_waitq_mutex); 7221 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 7222 mutex_exit(&mpt->m_tx_waitq_mutex); 7223 7224 topo_node = kmem_zalloc( 7225 sizeof (mptsas_topo_change_list_t), 7226 KM_SLEEP); 7227 topo_node->mpt = mpt; 7228 topo_node->un.phymask = 7229 ptgt->m_addr.mta_phymask; 7230 topo_node->event = 7231 MPTSAS_DR_EVENT_OFFLINE_TARGET; 7232 topo_node->devhdl = dev_handle; 7233 topo_node->flags = flags; 7234 topo_node->object = NULL; 7235 if (topo_head == NULL) { 7236 topo_head = topo_tail = topo_node; 7237 } else { 7238 topo_tail->next = topo_node; 7239 topo_tail = topo_node; 7240 } 7241 break; 7242 } 7243 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 7244 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl, 7245 &sas_topo_change_list->PHY[i].LinkRate); 7246 state = (link_rate & 7247 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >> 7248 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT; 7249 pSmhba = &mpt->m_phy_info[i].smhba_info; 7250 pSmhba->negotiated_link_rate = state; 7251 switch (state) { 7252 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 7253 (void) sprintf(curr, "is disabled"); 7254 mptsas_smhba_log_sysevent(mpt, 7255 ESC_SAS_PHY_EVENT, 7256 SAS_PHY_REMOVE, 7257 &mpt->m_phy_info[i].smhba_info); 7258 mpt->m_phy_info[i].smhba_info. 7259 negotiated_link_rate 7260 = 0x1; 7261 break; 7262 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 7263 (void) sprintf(curr, "is offline, " 7264 "failed speed negotiation"); 7265 mptsas_smhba_log_sysevent(mpt, 7266 ESC_SAS_PHY_EVENT, 7267 SAS_PHY_OFFLINE, 7268 &mpt->m_phy_info[i].smhba_info); 7269 break; 7270 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 7271 (void) sprintf(curr, "SATA OOB " 7272 "complete"); 7273 break; 7274 case SMP_RESET_IN_PROGRESS: 7275 (void) sprintf(curr, "SMP reset in " 7276 "progress"); 7277 break; 7278 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 7279 (void) sprintf(curr, "is online at " 7280 "1.5 Gbps"); 7281 if ((expd_handle == 0) && 7282 (enc_handle == 1)) { 7283 mpt->m_port_chng = 1; 7284 } 7285 mptsas_smhba_log_sysevent(mpt, 7286 ESC_SAS_PHY_EVENT, 7287 SAS_PHY_ONLINE, 7288 &mpt->m_phy_info[i].smhba_info); 7289 break; 7290 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 7291 (void) sprintf(curr, "is online at 3.0 " 7292 "Gbps"); 7293 if ((expd_handle == 0) && 7294 (enc_handle == 1)) { 7295 mpt->m_port_chng = 1; 7296 } 7297 mptsas_smhba_log_sysevent(mpt, 7298 ESC_SAS_PHY_EVENT, 7299 SAS_PHY_ONLINE, 7300 &mpt->m_phy_info[i].smhba_info); 7301 break; 7302 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 7303 (void) sprintf(curr, "is online at " 7304 "6.0 Gbps"); 7305 if ((expd_handle == 0) && 7306 (enc_handle == 1)) { 7307 mpt->m_port_chng = 1; 7308 } 7309 mptsas_smhba_log_sysevent(mpt, 7310 ESC_SAS_PHY_EVENT, 7311 SAS_PHY_ONLINE, 7312 &mpt->m_phy_info[i].smhba_info); 7313 break; 7314 case MPI25_EVENT_SAS_TOPO_LR_RATE_12_0: 7315 (void) sprintf(curr, "is online at " 7316 "12.0 Gbps"); 7317 if ((expd_handle == 0) && 7318 (enc_handle == 1)) { 7319 mpt->m_port_chng = 1; 7320 } 7321 mptsas_smhba_log_sysevent(mpt, 7322 ESC_SAS_PHY_EVENT, 7323 SAS_PHY_ONLINE, 7324 &mpt->m_phy_info[i].smhba_info); 7325 break; 7326 default: 7327 (void) sprintf(curr, "state is " 7328 "unknown"); 7329 break; 7330 } 7331 7332 state = (link_rate & 7333 MPI2_EVENT_SAS_TOPO_LR_PREV_MASK) >> 7334 MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT; 7335 switch (state) { 7336 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 7337 (void) sprintf(prev, ", was disabled"); 7338 break; 7339 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 7340 (void) sprintf(prev, ", was offline, " 7341 "failed speed negotiation"); 7342 break; 7343 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 7344 (void) sprintf(prev, ", was SATA OOB " 7345 "complete"); 7346 break; 7347 case SMP_RESET_IN_PROGRESS: 7348 (void) sprintf(prev, ", was SMP reset " 7349 "in progress"); 7350 break; 7351 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 7352 (void) sprintf(prev, ", was online at " 7353 "1.5 Gbps"); 7354 break; 7355 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 7356 (void) sprintf(prev, ", was online at " 7357 "3.0 Gbps"); 7358 break; 7359 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 7360 (void) sprintf(prev, ", was online at " 7361 "6.0 Gbps"); 7362 break; 7363 case MPI25_EVENT_SAS_TOPO_LR_RATE_12_0: 7364 (void) sprintf(prev, ", was online at " 7365 "12.0 Gbps"); 7366 break; 7367 default: 7368 break; 7369 } 7370 (void) sprintf(&string[strlen(string)], "link " 7371 "changed, "); 7372 break; 7373 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE: 7374 continue; 7375 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING: 7376 (void) sprintf(&string[strlen(string)], 7377 "target not responding, delaying " 7378 "removal"); 7379 break; 7380 } 7381 NDBG20(("mptsas%d phy %d DevHandle %x, %s%s%s\n", 7382 mpt->m_instance, phy, dev_handle, string, curr, 7383 prev)); 7384 } 7385 if (topo_head != NULL) { 7386 /* 7387 * Launch DR taskq to handle topology change 7388 */ 7389 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 7390 mptsas_handle_dr, (void *)topo_head, 7391 DDI_NOSLEEP)) != DDI_SUCCESS) { 7392 while (topo_head != NULL) { 7393 topo_node = topo_head; 7394 topo_head = topo_head->next; 7395 kmem_free(topo_node, 7396 sizeof (mptsas_topo_change_list_t)); 7397 } 7398 mptsas_log(mpt, CE_NOTE, "mptsas start taskq " 7399 "for handle SAS DR event failed. \n"); 7400 } 7401 } 7402 break; 7403 } 7404 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 7405 { 7406 Mpi2EventDataIrConfigChangeList_t *irChangeList; 7407 mptsas_topo_change_list_t *topo_head = NULL; 7408 mptsas_topo_change_list_t *topo_tail = NULL; 7409 mptsas_topo_change_list_t *topo_node = NULL; 7410 mptsas_target_t *ptgt; 7411 uint8_t num_entries, i, reason; 7412 uint16_t volhandle, diskhandle; 7413 7414 irChangeList = (pMpi2EventDataIrConfigChangeList_t) 7415 eventreply->EventData; 7416 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl, 7417 &irChangeList->NumElements); 7418 7419 NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received", 7420 mpt->m_instance)); 7421 7422 for (i = 0; i < num_entries; i++) { 7423 reason = ddi_get8(mpt->m_acc_reply_frame_hdl, 7424 &irChangeList->ConfigElement[i].ReasonCode); 7425 volhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7426 &irChangeList->ConfigElement[i].VolDevHandle); 7427 diskhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7428 &irChangeList->ConfigElement[i].PhysDiskDevHandle); 7429 7430 switch (reason) { 7431 case MPI2_EVENT_IR_CHANGE_RC_ADDED: 7432 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: 7433 { 7434 NDBG20(("mptsas %d volume added\n", 7435 mpt->m_instance)); 7436 7437 topo_node = kmem_zalloc( 7438 sizeof (mptsas_topo_change_list_t), 7439 KM_SLEEP); 7440 7441 topo_node->mpt = mpt; 7442 topo_node->event = 7443 MPTSAS_DR_EVENT_RECONFIG_TARGET; 7444 topo_node->un.physport = 0xff; 7445 topo_node->devhdl = volhandle; 7446 topo_node->flags = 7447 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED; 7448 topo_node->object = NULL; 7449 if (topo_head == NULL) { 7450 topo_head = topo_tail = topo_node; 7451 } else { 7452 topo_tail->next = topo_node; 7453 topo_tail = topo_node; 7454 } 7455 break; 7456 } 7457 case MPI2_EVENT_IR_CHANGE_RC_REMOVED: 7458 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: 7459 { 7460 NDBG20(("mptsas %d volume deleted\n", 7461 mpt->m_instance)); 7462 ptgt = refhash_linear_search(mpt->m_targets, 7463 mptsas_target_eval_devhdl, &volhandle); 7464 if (ptgt == NULL) 7465 break; 7466 7467 /* 7468 * Clear any flags related to volume 7469 */ 7470 (void) mptsas_delete_volume(mpt, volhandle); 7471 7472 /* 7473 * Update DR flag immediately avoid I/O failure 7474 */ 7475 mutex_enter(&mpt->m_tx_waitq_mutex); 7476 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 7477 mutex_exit(&mpt->m_tx_waitq_mutex); 7478 7479 topo_node = kmem_zalloc( 7480 sizeof (mptsas_topo_change_list_t), 7481 KM_SLEEP); 7482 topo_node->mpt = mpt; 7483 topo_node->un.phymask = 7484 ptgt->m_addr.mta_phymask; 7485 topo_node->event = 7486 MPTSAS_DR_EVENT_OFFLINE_TARGET; 7487 topo_node->devhdl = volhandle; 7488 topo_node->flags = 7489 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED; 7490 topo_node->object = (void *)ptgt; 7491 if (topo_head == NULL) { 7492 topo_head = topo_tail = topo_node; 7493 } else { 7494 topo_tail->next = topo_node; 7495 topo_tail = topo_node; 7496 } 7497 break; 7498 } 7499 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: 7500 case MPI2_EVENT_IR_CHANGE_RC_HIDE: 7501 { 7502 ptgt = refhash_linear_search(mpt->m_targets, 7503 mptsas_target_eval_devhdl, &diskhandle); 7504 if (ptgt == NULL) 7505 break; 7506 7507 /* 7508 * Update DR flag immediately avoid I/O failure 7509 */ 7510 mutex_enter(&mpt->m_tx_waitq_mutex); 7511 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 7512 mutex_exit(&mpt->m_tx_waitq_mutex); 7513 7514 topo_node = kmem_zalloc( 7515 sizeof (mptsas_topo_change_list_t), 7516 KM_SLEEP); 7517 topo_node->mpt = mpt; 7518 topo_node->un.phymask = 7519 ptgt->m_addr.mta_phymask; 7520 topo_node->event = 7521 MPTSAS_DR_EVENT_OFFLINE_TARGET; 7522 topo_node->devhdl = diskhandle; 7523 topo_node->flags = 7524 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED; 7525 topo_node->object = (void *)ptgt; 7526 if (topo_head == NULL) { 7527 topo_head = topo_tail = topo_node; 7528 } else { 7529 topo_tail->next = topo_node; 7530 topo_tail = topo_node; 7531 } 7532 break; 7533 } 7534 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: 7535 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: 7536 { 7537 /* 7538 * The physical drive is released by a IR 7539 * volume. But we cannot get the the physport 7540 * or phynum from the event data, so we only 7541 * can get the physport/phynum after SAS 7542 * Device Page0 request for the devhdl. 7543 */ 7544 topo_node = kmem_zalloc( 7545 sizeof (mptsas_topo_change_list_t), 7546 KM_SLEEP); 7547 topo_node->mpt = mpt; 7548 topo_node->un.phymask = 0; 7549 topo_node->event = 7550 MPTSAS_DR_EVENT_RECONFIG_TARGET; 7551 topo_node->devhdl = diskhandle; 7552 topo_node->flags = 7553 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED; 7554 topo_node->object = NULL; 7555 mpt->m_port_chng = 1; 7556 if (topo_head == NULL) { 7557 topo_head = topo_tail = topo_node; 7558 } else { 7559 topo_tail->next = topo_node; 7560 topo_tail = topo_node; 7561 } 7562 break; 7563 } 7564 default: 7565 break; 7566 } 7567 } 7568 7569 if (topo_head != NULL) { 7570 /* 7571 * Launch DR taskq to handle topology change 7572 */ 7573 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 7574 mptsas_handle_dr, (void *)topo_head, 7575 DDI_NOSLEEP)) != DDI_SUCCESS) { 7576 while (topo_head != NULL) { 7577 topo_node = topo_head; 7578 topo_head = topo_head->next; 7579 kmem_free(topo_node, 7580 sizeof (mptsas_topo_change_list_t)); 7581 } 7582 mptsas_log(mpt, CE_NOTE, "mptsas start taskq " 7583 "for handle SAS DR event failed. \n"); 7584 } 7585 } 7586 break; 7587 } 7588 default: 7589 return (DDI_FAILURE); 7590 } 7591 7592 return (DDI_SUCCESS); 7593 } 7594 7595 /* 7596 * handle events from ioc 7597 */ 7598 static void 7599 mptsas_handle_event(void *args) 7600 { 7601 m_replyh_arg_t *replyh_arg; 7602 pMpi2EventNotificationReply_t eventreply; 7603 uint32_t event, iocloginfo, rfm; 7604 uint32_t status; 7605 uint8_t port; 7606 mptsas_t *mpt; 7607 uint_t iocstatus; 7608 7609 replyh_arg = (m_replyh_arg_t *)args; 7610 rfm = replyh_arg->rfm; 7611 mpt = replyh_arg->mpt; 7612 7613 mutex_enter(&mpt->m_mutex); 7614 /* 7615 * If HBA is being reset, drop incoming event. 7616 */ 7617 if (mpt->m_in_reset) { 7618 NDBG20(("dropping event received prior to reset")); 7619 mutex_exit(&mpt->m_mutex); 7620 return; 7621 } 7622 7623 eventreply = (pMpi2EventNotificationReply_t) 7624 (mpt->m_reply_frame + (rfm - 7625 (mpt->m_reply_frame_dma_addr & 0xffffffffu))); 7626 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 7627 7628 if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 7629 &eventreply->IOCStatus)) { 7630 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 7631 mptsas_log(mpt, CE_WARN, 7632 "!mptsas_handle_event: IOCStatus=0x%x, " 7633 "IOCLogInfo=0x%x", iocstatus, 7634 ddi_get32(mpt->m_acc_reply_frame_hdl, 7635 &eventreply->IOCLogInfo)); 7636 } else { 7637 mptsas_log(mpt, CE_WARN, 7638 "mptsas_handle_event: IOCStatus=0x%x, " 7639 "IOCLogInfo=0x%x", iocstatus, 7640 ddi_get32(mpt->m_acc_reply_frame_hdl, 7641 &eventreply->IOCLogInfo)); 7642 } 7643 } 7644 7645 /* 7646 * figure out what kind of event we got and handle accordingly 7647 */ 7648 switch (event) { 7649 case MPI2_EVENT_LOG_ENTRY_ADDED: 7650 break; 7651 case MPI2_EVENT_LOG_DATA: 7652 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 7653 &eventreply->IOCLogInfo); 7654 NDBG20(("mptsas %d log info %x received.\n", mpt->m_instance, 7655 iocloginfo)); 7656 break; 7657 case MPI2_EVENT_STATE_CHANGE: 7658 NDBG20(("mptsas%d state change.", mpt->m_instance)); 7659 break; 7660 case MPI2_EVENT_HARD_RESET_RECEIVED: 7661 NDBG20(("mptsas%d event change.", mpt->m_instance)); 7662 break; 7663 case MPI2_EVENT_SAS_DISCOVERY: 7664 { 7665 MPI2_EVENT_DATA_SAS_DISCOVERY *sasdiscovery; 7666 char string[80]; 7667 uint8_t rc; 7668 7669 sasdiscovery = 7670 (pMpi2EventDataSasDiscovery_t)eventreply->EventData; 7671 7672 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7673 &sasdiscovery->ReasonCode); 7674 port = ddi_get8(mpt->m_acc_reply_frame_hdl, 7675 &sasdiscovery->PhysicalPort); 7676 status = ddi_get32(mpt->m_acc_reply_frame_hdl, 7677 &sasdiscovery->DiscoveryStatus); 7678 7679 string[0] = 0; 7680 switch (rc) { 7681 case MPI2_EVENT_SAS_DISC_RC_STARTED: 7682 (void) sprintf(string, "STARTING"); 7683 break; 7684 case MPI2_EVENT_SAS_DISC_RC_COMPLETED: 7685 (void) sprintf(string, "COMPLETED"); 7686 break; 7687 default: 7688 (void) sprintf(string, "UNKNOWN"); 7689 break; 7690 } 7691 7692 NDBG20(("SAS DISCOVERY is %s for port %d, status %x", string, 7693 port, status)); 7694 7695 break; 7696 } 7697 case MPI2_EVENT_EVENT_CHANGE: 7698 NDBG20(("mptsas%d event change.", mpt->m_instance)); 7699 break; 7700 case MPI2_EVENT_TASK_SET_FULL: 7701 { 7702 pMpi2EventDataTaskSetFull_t taskfull; 7703 7704 taskfull = (pMpi2EventDataTaskSetFull_t)eventreply->EventData; 7705 7706 NDBG20(("TASK_SET_FULL received for mptsas%d, depth %d\n", 7707 mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl, 7708 &taskfull->CurrentDepth))); 7709 break; 7710 } 7711 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 7712 { 7713 /* 7714 * SAS TOPOLOGY CHANGE LIST Event has already been handled 7715 * in mptsas_handle_event_sync() of interrupt context 7716 */ 7717 break; 7718 } 7719 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: 7720 { 7721 pMpi2EventDataSasEnclDevStatusChange_t encstatus; 7722 uint8_t rc; 7723 char string[80]; 7724 7725 encstatus = (pMpi2EventDataSasEnclDevStatusChange_t) 7726 eventreply->EventData; 7727 7728 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7729 &encstatus->ReasonCode); 7730 switch (rc) { 7731 case MPI2_EVENT_SAS_ENCL_RC_ADDED: 7732 (void) sprintf(string, "added"); 7733 break; 7734 case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING: 7735 (void) sprintf(string, ", not responding"); 7736 break; 7737 default: 7738 break; 7739 } 7740 NDBG20(("mptsas%d ENCLOSURE STATUS CHANGE for enclosure " 7741 "%x%s\n", mpt->m_instance, 7742 ddi_get16(mpt->m_acc_reply_frame_hdl, 7743 &encstatus->EnclosureHandle), string)); 7744 break; 7745 } 7746 7747 /* 7748 * MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE is handled by 7749 * mptsas_handle_event_sync,in here just send ack message. 7750 */ 7751 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: 7752 { 7753 pMpi2EventDataSasDeviceStatusChange_t statuschange; 7754 uint8_t rc; 7755 uint16_t devhdl; 7756 uint64_t wwn = 0; 7757 uint32_t wwn_lo, wwn_hi; 7758 7759 statuschange = (pMpi2EventDataSasDeviceStatusChange_t) 7760 eventreply->EventData; 7761 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7762 &statuschange->ReasonCode); 7763 wwn_lo = ddi_get32(mpt->m_acc_reply_frame_hdl, 7764 (uint32_t *)(void *)&statuschange->SASAddress); 7765 wwn_hi = ddi_get32(mpt->m_acc_reply_frame_hdl, 7766 (uint32_t *)(void *)&statuschange->SASAddress + 1); 7767 wwn = ((uint64_t)wwn_hi << 32) | wwn_lo; 7768 devhdl = ddi_get16(mpt->m_acc_reply_frame_hdl, 7769 &statuschange->DevHandle); 7770 7771 NDBG13(("MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE wwn is %"PRIx64, 7772 wwn)); 7773 7774 switch (rc) { 7775 case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA: 7776 NDBG20(("SMART data received, ASC/ASCQ = %02x/%02x", 7777 ddi_get8(mpt->m_acc_reply_frame_hdl, 7778 &statuschange->ASC), 7779 ddi_get8(mpt->m_acc_reply_frame_hdl, 7780 &statuschange->ASCQ))); 7781 break; 7782 7783 case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED: 7784 NDBG20(("Device not supported")); 7785 break; 7786 7787 case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: 7788 NDBG20(("IOC internally generated the Target Reset " 7789 "for devhdl:%x", devhdl)); 7790 break; 7791 7792 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET: 7793 NDBG20(("IOC's internally generated Target Reset " 7794 "completed for devhdl:%x", devhdl)); 7795 break; 7796 7797 case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: 7798 NDBG20(("IOC internally generated Abort Task")); 7799 break; 7800 7801 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL: 7802 NDBG20(("IOC's internally generated Abort Task " 7803 "completed")); 7804 break; 7805 7806 case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: 7807 NDBG20(("IOC internally generated Abort Task Set")); 7808 break; 7809 7810 case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: 7811 NDBG20(("IOC internally generated Clear Task Set")); 7812 break; 7813 7814 case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: 7815 NDBG20(("IOC internally generated Query Task")); 7816 break; 7817 7818 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION: 7819 NDBG20(("Device sent an Asynchronous Notification")); 7820 break; 7821 7822 default: 7823 break; 7824 } 7825 break; 7826 } 7827 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 7828 { 7829 /* 7830 * IR TOPOLOGY CHANGE LIST Event has already been handled 7831 * in mpt_handle_event_sync() of interrupt context 7832 */ 7833 break; 7834 } 7835 case MPI2_EVENT_IR_OPERATION_STATUS: 7836 { 7837 Mpi2EventDataIrOperationStatus_t *irOpStatus; 7838 char reason_str[80]; 7839 uint8_t rc, percent; 7840 uint16_t handle; 7841 7842 irOpStatus = (pMpi2EventDataIrOperationStatus_t) 7843 eventreply->EventData; 7844 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7845 &irOpStatus->RAIDOperation); 7846 percent = ddi_get8(mpt->m_acc_reply_frame_hdl, 7847 &irOpStatus->PercentComplete); 7848 handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7849 &irOpStatus->VolDevHandle); 7850 7851 switch (rc) { 7852 case MPI2_EVENT_IR_RAIDOP_RESYNC: 7853 (void) sprintf(reason_str, "resync"); 7854 break; 7855 case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION: 7856 (void) sprintf(reason_str, "online capacity " 7857 "expansion"); 7858 break; 7859 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK: 7860 (void) sprintf(reason_str, "consistency check"); 7861 break; 7862 default: 7863 (void) sprintf(reason_str, "unknown reason %x", 7864 rc); 7865 } 7866 7867 NDBG20(("mptsas%d raid operational status: (%s)" 7868 "\thandle(0x%04x), percent complete(%d)\n", 7869 mpt->m_instance, reason_str, handle, percent)); 7870 break; 7871 } 7872 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: 7873 { 7874 pMpi2EventDataSasBroadcastPrimitive_t sas_broadcast; 7875 uint8_t phy_num; 7876 uint8_t primitive; 7877 7878 sas_broadcast = (pMpi2EventDataSasBroadcastPrimitive_t) 7879 eventreply->EventData; 7880 7881 phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl, 7882 &sas_broadcast->PhyNum); 7883 primitive = ddi_get8(mpt->m_acc_reply_frame_hdl, 7884 &sas_broadcast->Primitive); 7885 7886 switch (primitive) { 7887 case MPI2_EVENT_PRIMITIVE_CHANGE: 7888 mptsas_smhba_log_sysevent(mpt, 7889 ESC_SAS_HBA_PORT_BROADCAST, 7890 SAS_PORT_BROADCAST_CHANGE, 7891 &mpt->m_phy_info[phy_num].smhba_info); 7892 break; 7893 case MPI2_EVENT_PRIMITIVE_SES: 7894 mptsas_smhba_log_sysevent(mpt, 7895 ESC_SAS_HBA_PORT_BROADCAST, 7896 SAS_PORT_BROADCAST_SES, 7897 &mpt->m_phy_info[phy_num].smhba_info); 7898 break; 7899 case MPI2_EVENT_PRIMITIVE_EXPANDER: 7900 mptsas_smhba_log_sysevent(mpt, 7901 ESC_SAS_HBA_PORT_BROADCAST, 7902 SAS_PORT_BROADCAST_D01_4, 7903 &mpt->m_phy_info[phy_num].smhba_info); 7904 break; 7905 case MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT: 7906 mptsas_smhba_log_sysevent(mpt, 7907 ESC_SAS_HBA_PORT_BROADCAST, 7908 SAS_PORT_BROADCAST_D04_7, 7909 &mpt->m_phy_info[phy_num].smhba_info); 7910 break; 7911 case MPI2_EVENT_PRIMITIVE_RESERVED3: 7912 mptsas_smhba_log_sysevent(mpt, 7913 ESC_SAS_HBA_PORT_BROADCAST, 7914 SAS_PORT_BROADCAST_D16_7, 7915 &mpt->m_phy_info[phy_num].smhba_info); 7916 break; 7917 case MPI2_EVENT_PRIMITIVE_RESERVED4: 7918 mptsas_smhba_log_sysevent(mpt, 7919 ESC_SAS_HBA_PORT_BROADCAST, 7920 SAS_PORT_BROADCAST_D29_7, 7921 &mpt->m_phy_info[phy_num].smhba_info); 7922 break; 7923 case MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED: 7924 mptsas_smhba_log_sysevent(mpt, 7925 ESC_SAS_HBA_PORT_BROADCAST, 7926 SAS_PORT_BROADCAST_D24_0, 7927 &mpt->m_phy_info[phy_num].smhba_info); 7928 break; 7929 case MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED: 7930 mptsas_smhba_log_sysevent(mpt, 7931 ESC_SAS_HBA_PORT_BROADCAST, 7932 SAS_PORT_BROADCAST_D27_4, 7933 &mpt->m_phy_info[phy_num].smhba_info); 7934 break; 7935 default: 7936 NDBG16(("mptsas%d: unknown BROADCAST PRIMITIVE" 7937 " %x received", 7938 mpt->m_instance, primitive)); 7939 break; 7940 } 7941 NDBG16(("mptsas%d sas broadcast primitive: " 7942 "\tprimitive(0x%04x), phy(%d) complete\n", 7943 mpt->m_instance, primitive, phy_num)); 7944 break; 7945 } 7946 case MPI2_EVENT_IR_VOLUME: 7947 { 7948 Mpi2EventDataIrVolume_t *irVolume; 7949 uint16_t devhandle; 7950 uint32_t state; 7951 int config, vol; 7952 uint8_t found = FALSE; 7953 7954 irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData; 7955 state = ddi_get32(mpt->m_acc_reply_frame_hdl, 7956 &irVolume->NewValue); 7957 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7958 &irVolume->VolDevHandle); 7959 7960 NDBG20(("EVENT_IR_VOLUME event is received")); 7961 7962 /* 7963 * Get latest RAID info and then find the DevHandle for this 7964 * event in the configuration. If the DevHandle is not found 7965 * just exit the event. 7966 */ 7967 (void) mptsas_get_raid_info(mpt); 7968 for (config = 0; (config < mpt->m_num_raid_configs) && 7969 (!found); config++) { 7970 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) { 7971 if (mpt->m_raidconfig[config].m_raidvol[vol]. 7972 m_raidhandle == devhandle) { 7973 found = TRUE; 7974 break; 7975 } 7976 } 7977 } 7978 if (!found) { 7979 break; 7980 } 7981 7982 switch (irVolume->ReasonCode) { 7983 case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED: 7984 { 7985 uint32_t i; 7986 mpt->m_raidconfig[config].m_raidvol[vol].m_settings = 7987 state; 7988 7989 i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING; 7990 mptsas_log(mpt, CE_NOTE, " Volume %d settings changed" 7991 ", auto-config of hot-swap drives is %s" 7992 ", write caching is %s" 7993 ", hot-spare pool mask is %02x\n", 7994 vol, state & 7995 MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE 7996 ? "disabled" : "enabled", 7997 i == MPI2_RAIDVOL0_SETTING_UNCHANGED 7998 ? "controlled by member disks" : 7999 i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING 8000 ? "disabled" : 8001 i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING 8002 ? "enabled" : 8003 "incorrectly set", 8004 (state >> 16) & 0xff); 8005 break; 8006 } 8007 case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED: 8008 { 8009 mpt->m_raidconfig[config].m_raidvol[vol].m_state = 8010 (uint8_t)state; 8011 8012 mptsas_log(mpt, CE_NOTE, 8013 "Volume %d is now %s\n", vol, 8014 state == MPI2_RAID_VOL_STATE_OPTIMAL 8015 ? "optimal" : 8016 state == MPI2_RAID_VOL_STATE_DEGRADED 8017 ? "degraded" : 8018 state == MPI2_RAID_VOL_STATE_ONLINE 8019 ? "online" : 8020 state == MPI2_RAID_VOL_STATE_INITIALIZING 8021 ? "initializing" : 8022 state == MPI2_RAID_VOL_STATE_FAILED 8023 ? "failed" : 8024 state == MPI2_RAID_VOL_STATE_MISSING 8025 ? "missing" : 8026 "state unknown"); 8027 break; 8028 } 8029 case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED: 8030 { 8031 mpt->m_raidconfig[config].m_raidvol[vol]. 8032 m_statusflags = state; 8033 8034 mptsas_log(mpt, CE_NOTE, 8035 " Volume %d is now %s%s%s%s%s%s%s%s%s\n", 8036 vol, 8037 state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED 8038 ? ", enabled" : ", disabled", 8039 state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED 8040 ? ", quiesced" : "", 8041 state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE 8042 ? ", inactive" : ", active", 8043 state & 8044 MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL 8045 ? ", bad block table is full" : "", 8046 state & 8047 MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS 8048 ? ", resync in progress" : "", 8049 state & MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT 8050 ? ", background initialization in progress" : "", 8051 state & 8052 MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION 8053 ? ", capacity expansion in progress" : "", 8054 state & 8055 MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK 8056 ? ", consistency check in progress" : "", 8057 state & MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB 8058 ? ", data scrub in progress" : ""); 8059 break; 8060 } 8061 default: 8062 break; 8063 } 8064 break; 8065 } 8066 case MPI2_EVENT_IR_PHYSICAL_DISK: 8067 { 8068 Mpi2EventDataIrPhysicalDisk_t *irPhysDisk; 8069 uint16_t devhandle, enchandle, slot; 8070 uint32_t status, state; 8071 uint8_t physdisknum, reason; 8072 8073 irPhysDisk = (Mpi2EventDataIrPhysicalDisk_t *) 8074 eventreply->EventData; 8075 physdisknum = ddi_get8(mpt->m_acc_reply_frame_hdl, 8076 &irPhysDisk->PhysDiskNum); 8077 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 8078 &irPhysDisk->PhysDiskDevHandle); 8079 enchandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 8080 &irPhysDisk->EnclosureHandle); 8081 slot = ddi_get16(mpt->m_acc_reply_frame_hdl, 8082 &irPhysDisk->Slot); 8083 state = ddi_get32(mpt->m_acc_reply_frame_hdl, 8084 &irPhysDisk->NewValue); 8085 reason = ddi_get8(mpt->m_acc_reply_frame_hdl, 8086 &irPhysDisk->ReasonCode); 8087 8088 NDBG20(("EVENT_IR_PHYSICAL_DISK event is received")); 8089 8090 switch (reason) { 8091 case MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED: 8092 mptsas_log(mpt, CE_NOTE, 8093 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 8094 "for enclosure with handle 0x%x is now in hot " 8095 "spare pool %d", 8096 physdisknum, devhandle, slot, enchandle, 8097 (state >> 16) & 0xff); 8098 break; 8099 8100 case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED: 8101 status = state; 8102 mptsas_log(mpt, CE_NOTE, 8103 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 8104 "for enclosure with handle 0x%x is now " 8105 "%s%s%s%s%s\n", physdisknum, devhandle, slot, 8106 enchandle, 8107 status & MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME 8108 ? ", inactive" : ", active", 8109 status & MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC 8110 ? ", out of sync" : "", 8111 status & MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED 8112 ? ", quiesced" : "", 8113 status & 8114 MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED 8115 ? ", write cache enabled" : "", 8116 status & MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET 8117 ? ", capacity expansion target" : ""); 8118 break; 8119 8120 case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED: 8121 mptsas_log(mpt, CE_NOTE, 8122 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 8123 "for enclosure with handle 0x%x is now %s\n", 8124 physdisknum, devhandle, slot, enchandle, 8125 state == MPI2_RAID_PD_STATE_OPTIMAL 8126 ? "optimal" : 8127 state == MPI2_RAID_PD_STATE_REBUILDING 8128 ? "rebuilding" : 8129 state == MPI2_RAID_PD_STATE_DEGRADED 8130 ? "degraded" : 8131 state == MPI2_RAID_PD_STATE_HOT_SPARE 8132 ? "a hot spare" : 8133 state == MPI2_RAID_PD_STATE_ONLINE 8134 ? "online" : 8135 state == MPI2_RAID_PD_STATE_OFFLINE 8136 ? "offline" : 8137 state == MPI2_RAID_PD_STATE_NOT_COMPATIBLE 8138 ? "not compatible" : 8139 state == MPI2_RAID_PD_STATE_NOT_CONFIGURED 8140 ? "not configured" : 8141 "state unknown"); 8142 break; 8143 } 8144 break; 8145 } 8146 default: 8147 NDBG20(("mptsas%d: unknown event %x received", 8148 mpt->m_instance, event)); 8149 break; 8150 } 8151 8152 /* 8153 * Return the reply frame to the free queue. 8154 */ 8155 ddi_put32(mpt->m_acc_free_queue_hdl, 8156 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], rfm); 8157 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 8158 DDI_DMA_SYNC_FORDEV); 8159 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 8160 mpt->m_free_index = 0; 8161 } 8162 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 8163 mpt->m_free_index); 8164 mutex_exit(&mpt->m_mutex); 8165 } 8166 8167 /* 8168 * invoked from timeout() to restart qfull cmds with throttle == 0 8169 */ 8170 static void 8171 mptsas_restart_cmd(void *arg) 8172 { 8173 mptsas_t *mpt = arg; 8174 mptsas_target_t *ptgt = NULL; 8175 8176 mutex_enter(&mpt->m_mutex); 8177 8178 mpt->m_restart_cmd_timeid = 0; 8179 8180 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 8181 ptgt = refhash_next(mpt->m_targets, ptgt)) { 8182 if (ptgt->m_reset_delay == 0) { 8183 if (ptgt->m_t_throttle == QFULL_THROTTLE) { 8184 mptsas_set_throttle(mpt, ptgt, 8185 MAX_THROTTLE); 8186 } 8187 } 8188 } 8189 mptsas_restart_hba(mpt); 8190 mutex_exit(&mpt->m_mutex); 8191 } 8192 8193 void 8194 mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 8195 { 8196 int slot; 8197 mptsas_slots_t *slots = mpt->m_active; 8198 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8199 8200 ASSERT(cmd != NULL); 8201 ASSERT(cmd->cmd_queued == FALSE); 8202 8203 /* 8204 * Task Management cmds are removed in their own routines. Also, 8205 * we don't want to modify timeout based on TM cmds. 8206 */ 8207 if (cmd->cmd_flags & CFLAG_TM_CMD) { 8208 return; 8209 } 8210 8211 slot = cmd->cmd_slot; 8212 8213 /* 8214 * remove the cmd. 8215 */ 8216 if (cmd == slots->m_slot[slot]) { 8217 NDBG31(("mptsas_remove_cmd: removing cmd=0x%p, flags " 8218 "0x%x", (void *)cmd, cmd->cmd_flags)); 8219 slots->m_slot[slot] = NULL; 8220 mpt->m_ncmds--; 8221 8222 /* 8223 * only decrement per target ncmds if command 8224 * has a target associated with it. 8225 */ 8226 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 8227 ptgt->m_t_ncmds--; 8228 /* 8229 * reset throttle if we just ran an untagged command 8230 * to a tagged target 8231 */ 8232 if ((ptgt->m_t_ncmds == 0) && 8233 ((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0)) { 8234 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 8235 } 8236 8237 /* 8238 * Remove this command from the active queue. 8239 */ 8240 if (cmd->cmd_active_expiration != 0) { 8241 TAILQ_REMOVE(&ptgt->m_active_cmdq, cmd, 8242 cmd_active_link); 8243 cmd->cmd_active_expiration = 0; 8244 } 8245 } 8246 } 8247 8248 /* 8249 * This is all we need to do for ioc commands. 8250 */ 8251 if (cmd->cmd_flags & CFLAG_CMDIOC) { 8252 mptsas_return_to_pool(mpt, cmd); 8253 return; 8254 } 8255 8256 ASSERT(cmd != slots->m_slot[cmd->cmd_slot]); 8257 } 8258 8259 /* 8260 * accept all cmds on the tx_waitq if any and then 8261 * start a fresh request from the top of the device queue. 8262 * 8263 * since there are always cmds queued on the tx_waitq, and rare cmds on 8264 * the instance waitq, so this function should not be invoked in the ISR, 8265 * the mptsas_restart_waitq() is invoked in the ISR instead. otherwise, the 8266 * burden belongs to the IO dispatch CPUs is moved the interrupt CPU. 8267 */ 8268 static void 8269 mptsas_restart_hba(mptsas_t *mpt) 8270 { 8271 ASSERT(mutex_owned(&mpt->m_mutex)); 8272 8273 mutex_enter(&mpt->m_tx_waitq_mutex); 8274 if (mpt->m_tx_waitq) { 8275 mptsas_accept_tx_waitq(mpt); 8276 } 8277 mutex_exit(&mpt->m_tx_waitq_mutex); 8278 mptsas_restart_waitq(mpt); 8279 } 8280 8281 /* 8282 * start a fresh request from the top of the device queue 8283 */ 8284 static void 8285 mptsas_restart_waitq(mptsas_t *mpt) 8286 { 8287 mptsas_cmd_t *cmd, *next_cmd; 8288 mptsas_target_t *ptgt = NULL; 8289 8290 NDBG1(("mptsas_restart_waitq: mpt=0x%p", (void *)mpt)); 8291 8292 ASSERT(mutex_owned(&mpt->m_mutex)); 8293 8294 /* 8295 * If there is a reset delay, don't start any cmds. Otherwise, start 8296 * as many cmds as possible. 8297 * Since SMID 0 is reserved and the TM slot is reserved, the actual max 8298 * commands is m_max_requests - 2. 8299 */ 8300 cmd = mpt->m_waitq; 8301 8302 while (cmd != NULL) { 8303 next_cmd = cmd->cmd_linkp; 8304 if (cmd->cmd_flags & CFLAG_PASSTHRU) { 8305 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 8306 /* 8307 * passthru command get slot need 8308 * set CFLAG_PREPARED. 8309 */ 8310 cmd->cmd_flags |= CFLAG_PREPARED; 8311 mptsas_waitq_delete(mpt, cmd); 8312 mptsas_start_passthru(mpt, cmd); 8313 } 8314 cmd = next_cmd; 8315 continue; 8316 } 8317 if (cmd->cmd_flags & CFLAG_CONFIG) { 8318 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 8319 /* 8320 * Send the config page request and delete it 8321 * from the waitq. 8322 */ 8323 cmd->cmd_flags |= CFLAG_PREPARED; 8324 mptsas_waitq_delete(mpt, cmd); 8325 mptsas_start_config_page_access(mpt, cmd); 8326 } 8327 cmd = next_cmd; 8328 continue; 8329 } 8330 if (cmd->cmd_flags & CFLAG_FW_DIAG) { 8331 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 8332 /* 8333 * Send the FW Diag request and delete if from 8334 * the waitq. 8335 */ 8336 cmd->cmd_flags |= CFLAG_PREPARED; 8337 mptsas_waitq_delete(mpt, cmd); 8338 mptsas_start_diag(mpt, cmd); 8339 } 8340 cmd = next_cmd; 8341 continue; 8342 } 8343 8344 ptgt = cmd->cmd_tgt_addr; 8345 if (ptgt && (ptgt->m_t_throttle == DRAIN_THROTTLE) && 8346 (ptgt->m_t_ncmds == 0)) { 8347 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 8348 } 8349 if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) && 8350 (ptgt && (ptgt->m_reset_delay == 0)) && 8351 (ptgt && (ptgt->m_t_ncmds < 8352 ptgt->m_t_throttle))) { 8353 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 8354 mptsas_waitq_delete(mpt, cmd); 8355 (void) mptsas_start_cmd(mpt, cmd); 8356 } 8357 } 8358 cmd = next_cmd; 8359 } 8360 } 8361 /* 8362 * Cmds are queued if tran_start() doesn't get the m_mutexlock(no wait). 8363 * Accept all those queued cmds before new cmd is accept so that the 8364 * cmds are sent in order. 8365 */ 8366 static void 8367 mptsas_accept_tx_waitq(mptsas_t *mpt) 8368 { 8369 mptsas_cmd_t *cmd; 8370 8371 ASSERT(mutex_owned(&mpt->m_mutex)); 8372 ASSERT(mutex_owned(&mpt->m_tx_waitq_mutex)); 8373 8374 /* 8375 * A Bus Reset could occur at any time and flush the tx_waitq, 8376 * so we cannot count on the tx_waitq to contain even one cmd. 8377 * And when the m_tx_waitq_mutex is released and run 8378 * mptsas_accept_pkt(), the tx_waitq may be flushed. 8379 */ 8380 cmd = mpt->m_tx_waitq; 8381 for (;;) { 8382 if ((cmd = mpt->m_tx_waitq) == NULL) { 8383 mpt->m_tx_draining = 0; 8384 break; 8385 } 8386 if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) { 8387 mpt->m_tx_waitqtail = &mpt->m_tx_waitq; 8388 } 8389 cmd->cmd_linkp = NULL; 8390 mutex_exit(&mpt->m_tx_waitq_mutex); 8391 if (mptsas_accept_pkt(mpt, cmd) != TRAN_ACCEPT) 8392 cmn_err(CE_WARN, "mpt: mptsas_accept_tx_waitq: failed " 8393 "to accept cmd on queue\n"); 8394 mutex_enter(&mpt->m_tx_waitq_mutex); 8395 } 8396 } 8397 8398 8399 /* 8400 * mpt tag type lookup 8401 */ 8402 static char mptsas_tag_lookup[] = 8403 {0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG}; 8404 8405 static int 8406 mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 8407 { 8408 struct scsi_pkt *pkt = CMD2PKT(cmd); 8409 uint32_t control = 0; 8410 caddr_t mem, arsbuf; 8411 pMpi2SCSIIORequest_t io_request; 8412 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; 8413 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl; 8414 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8415 uint16_t SMID, io_flags = 0; 8416 uint8_t ars_size; 8417 uint64_t request_desc; 8418 uint32_t ars_dmaaddrlow; 8419 mptsas_cmd_t *c; 8420 8421 NDBG1(("mptsas_start_cmd: cmd=0x%p, flags 0x%x", (void *)cmd, 8422 cmd->cmd_flags)); 8423 8424 /* 8425 * Set SMID and increment index. Rollover to 1 instead of 0 if index 8426 * is at the max. 0 is an invalid SMID, so we call the first index 1. 8427 */ 8428 SMID = cmd->cmd_slot; 8429 8430 /* 8431 * It is possible for back to back device reset to 8432 * happen before the reset delay has expired. That's 8433 * ok, just let the device reset go out on the bus. 8434 */ 8435 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 8436 ASSERT(ptgt->m_reset_delay == 0); 8437 } 8438 8439 /* 8440 * if a non-tagged cmd is submitted to an active tagged target 8441 * then drain before submitting this cmd; SCSI-2 allows RQSENSE 8442 * to be untagged 8443 */ 8444 if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) && 8445 (ptgt->m_t_ncmds > 1) && 8446 ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) && 8447 (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) { 8448 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 8449 NDBG23(("target=%d, untagged cmd, start draining\n", 8450 ptgt->m_devhdl)); 8451 8452 if (ptgt->m_reset_delay == 0) { 8453 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 8454 } 8455 8456 mptsas_remove_cmd(mpt, cmd); 8457 cmd->cmd_pkt_flags |= FLAG_HEAD; 8458 mptsas_waitq_add(mpt, cmd); 8459 } 8460 return (DDI_FAILURE); 8461 } 8462 8463 /* 8464 * Set correct tag bits. 8465 */ 8466 if (cmd->cmd_pkt_flags & FLAG_TAGMASK) { 8467 switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags & 8468 FLAG_TAGMASK) >> 12)]) { 8469 case MSG_SIMPLE_QTAG: 8470 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 8471 break; 8472 case MSG_HEAD_QTAG: 8473 control |= MPI2_SCSIIO_CONTROL_HEADOFQ; 8474 break; 8475 case MSG_ORDERED_QTAG: 8476 control |= MPI2_SCSIIO_CONTROL_ORDEREDQ; 8477 break; 8478 default: 8479 mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n"); 8480 break; 8481 } 8482 } else { 8483 if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) { 8484 ptgt->m_t_throttle = 1; 8485 } 8486 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 8487 } 8488 8489 if (cmd->cmd_pkt_flags & FLAG_TLR) { 8490 control |= MPI2_SCSIIO_CONTROL_TLR_ON; 8491 } 8492 8493 mem = mpt->m_req_frame + (mpt->m_req_frame_size * SMID); 8494 io_request = (pMpi2SCSIIORequest_t)mem; 8495 if (cmd->cmd_extrqslen != 0) { 8496 /* 8497 * Mapping of the buffer was done in mptsas_pkt_alloc_extern(). 8498 * Calculate the DMA address with the same offset. 8499 */ 8500 arsbuf = cmd->cmd_arq_buf; 8501 ars_size = cmd->cmd_extrqslen; 8502 ars_dmaaddrlow = (mpt->m_req_sense_dma_addr + 8503 ((uintptr_t)arsbuf - (uintptr_t)mpt->m_req_sense)) & 8504 0xffffffffu; 8505 } else { 8506 arsbuf = mpt->m_req_sense + (mpt->m_req_sense_size * (SMID-1)); 8507 cmd->cmd_arq_buf = arsbuf; 8508 ars_size = mpt->m_req_sense_size; 8509 ars_dmaaddrlow = (mpt->m_req_sense_dma_addr + 8510 (mpt->m_req_sense_size * (SMID-1))) & 8511 0xffffffffu; 8512 } 8513 bzero(io_request, sizeof (Mpi2SCSIIORequest_t)); 8514 bzero(arsbuf, ars_size); 8515 8516 ddi_put8(acc_hdl, &io_request->SGLOffset0, offsetof 8517 (MPI2_SCSI_IO_REQUEST, SGL) / 4); 8518 mptsas_init_std_hdr(acc_hdl, io_request, ptgt->m_devhdl, Lun(cmd), 0, 8519 MPI2_FUNCTION_SCSI_IO_REQUEST); 8520 8521 (void) ddi_rep_put8(acc_hdl, (uint8_t *)pkt->pkt_cdbp, 8522 io_request->CDB.CDB32, cmd->cmd_cdblen, DDI_DEV_AUTOINCR); 8523 8524 io_flags = cmd->cmd_cdblen; 8525 if (mptsas_use_fastpath && 8526 ptgt->m_io_flags & MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) { 8527 io_flags |= MPI25_SCSIIO_IOFLAGS_FAST_PATH; 8528 request_desc = MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO; 8529 } else { 8530 request_desc = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 8531 } 8532 ddi_put16(acc_hdl, &io_request->IoFlags, io_flags); 8533 /* 8534 * setup the Scatter/Gather DMA list for this request 8535 */ 8536 if (cmd->cmd_cookiec > 0) { 8537 mptsas_sge_setup(mpt, cmd, &control, io_request, acc_hdl); 8538 } else { 8539 ddi_put32(acc_hdl, &io_request->SGL.MpiSimple.FlagsLength, 8540 ((uint32_t)MPI2_SGE_FLAGS_LAST_ELEMENT | 8541 MPI2_SGE_FLAGS_END_OF_BUFFER | 8542 MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 8543 MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); 8544 } 8545 8546 /* 8547 * save ARQ information 8548 */ 8549 ddi_put8(acc_hdl, &io_request->SenseBufferLength, ars_size); 8550 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, ars_dmaaddrlow); 8551 8552 ddi_put32(acc_hdl, &io_request->Control, control); 8553 8554 NDBG31(("starting message=%d(0x%p), with cmd=0x%p", 8555 SMID, (void *)io_request, (void *)cmd)); 8556 8557 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 8558 (void) ddi_dma_sync(mpt->m_dma_req_sense_hdl, 0, 0, 8559 DDI_DMA_SYNC_FORDEV); 8560 8561 /* 8562 * Build request descriptor and write it to the request desc post reg. 8563 */ 8564 request_desc |= (SMID << 16); 8565 request_desc |= (uint64_t)ptgt->m_devhdl << 48; 8566 MPTSAS_START_CMD(mpt, request_desc); 8567 8568 /* 8569 * Start timeout. 8570 */ 8571 cmd->cmd_active_expiration = 8572 gethrtime() + (hrtime_t)pkt->pkt_time * NANOSEC; 8573 #ifdef MPTSAS_TEST 8574 /* 8575 * Force timeouts to happen immediately. 8576 */ 8577 if (mptsas_test_timeouts) 8578 cmd->cmd_active_expiration = gethrtime(); 8579 #endif 8580 c = TAILQ_FIRST(&ptgt->m_active_cmdq); 8581 if (c == NULL || 8582 c->cmd_active_expiration < cmd->cmd_active_expiration) { 8583 /* 8584 * Common case is that this is the last pending expiration 8585 * (or queue is empty). Insert at head of the queue. 8586 */ 8587 TAILQ_INSERT_HEAD(&ptgt->m_active_cmdq, cmd, cmd_active_link); 8588 } else { 8589 /* 8590 * Queue is not empty and first element expires later than 8591 * this command. Search for element expiring sooner. 8592 */ 8593 while ((c = TAILQ_NEXT(c, cmd_active_link)) != NULL) { 8594 if (c->cmd_active_expiration < 8595 cmd->cmd_active_expiration) { 8596 TAILQ_INSERT_BEFORE(c, cmd, cmd_active_link); 8597 break; 8598 } 8599 } 8600 if (c == NULL) { 8601 /* 8602 * No element found expiring sooner, append to 8603 * non-empty queue. 8604 */ 8605 TAILQ_INSERT_TAIL(&ptgt->m_active_cmdq, cmd, 8606 cmd_active_link); 8607 } 8608 } 8609 8610 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || 8611 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { 8612 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8613 return (DDI_FAILURE); 8614 } 8615 return (DDI_SUCCESS); 8616 } 8617 8618 /* 8619 * Select a helper thread to handle current doneq 8620 */ 8621 static void 8622 mptsas_deliver_doneq_thread(mptsas_t *mpt) 8623 { 8624 uint64_t t, i; 8625 uint32_t min = 0xffffffff; 8626 mptsas_doneq_thread_list_t *item; 8627 8628 for (i = 0; i < mpt->m_doneq_thread_n; i++) { 8629 item = &mpt->m_doneq_thread_id[i]; 8630 /* 8631 * If the completed command on help thread[i] less than 8632 * doneq_thread_threshold, then pick the thread[i]. Otherwise 8633 * pick a thread which has least completed command. 8634 */ 8635 8636 mutex_enter(&item->mutex); 8637 if (item->len < mpt->m_doneq_thread_threshold) { 8638 t = i; 8639 mutex_exit(&item->mutex); 8640 break; 8641 } 8642 if (item->len < min) { 8643 min = item->len; 8644 t = i; 8645 } 8646 mutex_exit(&item->mutex); 8647 } 8648 mutex_enter(&mpt->m_doneq_thread_id[t].mutex); 8649 mptsas_doneq_mv(mpt, t); 8650 cv_signal(&mpt->m_doneq_thread_id[t].cv); 8651 mutex_exit(&mpt->m_doneq_thread_id[t].mutex); 8652 } 8653 8654 /* 8655 * move the current global doneq to the doneq of thead[t] 8656 */ 8657 static void 8658 mptsas_doneq_mv(mptsas_t *mpt, uint64_t t) 8659 { 8660 mptsas_cmd_t *cmd; 8661 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 8662 8663 ASSERT(mutex_owned(&item->mutex)); 8664 while ((cmd = mpt->m_doneq) != NULL) { 8665 if ((mpt->m_doneq = cmd->cmd_linkp) == NULL) { 8666 mpt->m_donetail = &mpt->m_doneq; 8667 } 8668 cmd->cmd_linkp = NULL; 8669 *item->donetail = cmd; 8670 item->donetail = &cmd->cmd_linkp; 8671 mpt->m_doneq_len--; 8672 item->len++; 8673 } 8674 } 8675 8676 void 8677 mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd) 8678 { 8679 struct scsi_pkt *pkt = CMD2PKT(cmd); 8680 8681 /* Check all acc and dma handles */ 8682 if ((mptsas_check_acc_handle(mpt->m_datap) != 8683 DDI_SUCCESS) || 8684 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 8685 DDI_SUCCESS) || 8686 (mptsas_check_acc_handle(mpt->m_acc_req_sense_hdl) != 8687 DDI_SUCCESS) || 8688 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) != 8689 DDI_SUCCESS) || 8690 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) != 8691 DDI_SUCCESS) || 8692 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) != 8693 DDI_SUCCESS) || 8694 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) != 8695 DDI_SUCCESS) || 8696 (mptsas_check_acc_handle(mpt->m_config_handle) != 8697 DDI_SUCCESS)) { 8698 ddi_fm_service_impact(mpt->m_dip, 8699 DDI_SERVICE_UNAFFECTED); 8700 ddi_fm_acc_err_clear(mpt->m_config_handle, 8701 DDI_FME_VER0); 8702 pkt->pkt_reason = CMD_TRAN_ERR; 8703 pkt->pkt_statistics = 0; 8704 } 8705 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 8706 DDI_SUCCESS) || 8707 (mptsas_check_dma_handle(mpt->m_dma_req_sense_hdl) != 8708 DDI_SUCCESS) || 8709 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) != 8710 DDI_SUCCESS) || 8711 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) != 8712 DDI_SUCCESS) || 8713 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) != 8714 DDI_SUCCESS) || 8715 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) != 8716 DDI_SUCCESS)) { 8717 ddi_fm_service_impact(mpt->m_dip, 8718 DDI_SERVICE_UNAFFECTED); 8719 pkt->pkt_reason = CMD_TRAN_ERR; 8720 pkt->pkt_statistics = 0; 8721 } 8722 if (cmd->cmd_dmahandle && 8723 (mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS)) { 8724 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8725 pkt->pkt_reason = CMD_TRAN_ERR; 8726 pkt->pkt_statistics = 0; 8727 } 8728 if ((cmd->cmd_extra_frames && 8729 ((mptsas_check_dma_handle(cmd->cmd_extra_frames->m_dma_hdl) != 8730 DDI_SUCCESS) || 8731 (mptsas_check_acc_handle(cmd->cmd_extra_frames->m_acc_hdl) != 8732 DDI_SUCCESS)))) { 8733 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8734 pkt->pkt_reason = CMD_TRAN_ERR; 8735 pkt->pkt_statistics = 0; 8736 } 8737 } 8738 8739 /* 8740 * These routines manipulate the queue of commands that 8741 * are waiting for their completion routines to be called. 8742 * The queue is usually in FIFO order but on an MP system 8743 * it's possible for the completion routines to get out 8744 * of order. If that's a problem you need to add a global 8745 * mutex around the code that calls the completion routine 8746 * in the interrupt handler. 8747 */ 8748 static void 8749 mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd) 8750 { 8751 struct scsi_pkt *pkt = CMD2PKT(cmd); 8752 8753 NDBG31(("mptsas_doneq_add: cmd=0x%p", (void *)cmd)); 8754 8755 ASSERT((cmd->cmd_flags & CFLAG_COMPLETED) == 0); 8756 cmd->cmd_linkp = NULL; 8757 cmd->cmd_flags |= CFLAG_FINISHED; 8758 cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT; 8759 8760 mptsas_fma_check(mpt, cmd); 8761 8762 /* 8763 * only add scsi pkts that have completion routines to 8764 * the doneq. no intr cmds do not have callbacks. 8765 */ 8766 if (pkt && (pkt->pkt_comp)) { 8767 *mpt->m_donetail = cmd; 8768 mpt->m_donetail = &cmd->cmd_linkp; 8769 mpt->m_doneq_len++; 8770 } 8771 } 8772 8773 static mptsas_cmd_t * 8774 mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t) 8775 { 8776 mptsas_cmd_t *cmd; 8777 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 8778 8779 /* pop one off the done queue */ 8780 if ((cmd = item->doneq) != NULL) { 8781 /* if the queue is now empty fix the tail pointer */ 8782 NDBG31(("mptsas_doneq_thread_rm: cmd=0x%p", (void *)cmd)); 8783 if ((item->doneq = cmd->cmd_linkp) == NULL) { 8784 item->donetail = &item->doneq; 8785 } 8786 cmd->cmd_linkp = NULL; 8787 item->len--; 8788 } 8789 return (cmd); 8790 } 8791 8792 static void 8793 mptsas_doneq_empty(mptsas_t *mpt) 8794 { 8795 if (mpt->m_doneq && !mpt->m_in_callback) { 8796 mptsas_cmd_t *cmd, *next; 8797 struct scsi_pkt *pkt; 8798 8799 mpt->m_in_callback = 1; 8800 cmd = mpt->m_doneq; 8801 mpt->m_doneq = NULL; 8802 mpt->m_donetail = &mpt->m_doneq; 8803 mpt->m_doneq_len = 0; 8804 8805 mutex_exit(&mpt->m_mutex); 8806 /* 8807 * run the completion routines of all the 8808 * completed commands 8809 */ 8810 while (cmd != NULL) { 8811 next = cmd->cmd_linkp; 8812 cmd->cmd_linkp = NULL; 8813 /* run this command's completion routine */ 8814 cmd->cmd_flags |= CFLAG_COMPLETED; 8815 pkt = CMD2PKT(cmd); 8816 mptsas_pkt_comp(pkt, cmd); 8817 cmd = next; 8818 } 8819 mutex_enter(&mpt->m_mutex); 8820 mpt->m_in_callback = 0; 8821 } 8822 } 8823 8824 /* 8825 * These routines manipulate the target's queue of pending requests 8826 */ 8827 void 8828 mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd) 8829 { 8830 NDBG7(("mptsas_waitq_add: cmd=0x%p", (void *)cmd)); 8831 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8832 cmd->cmd_queued = TRUE; 8833 if (ptgt) 8834 ptgt->m_t_nwait++; 8835 if (cmd->cmd_pkt_flags & FLAG_HEAD) { 8836 if ((cmd->cmd_linkp = mpt->m_waitq) == NULL) { 8837 mpt->m_waitqtail = &cmd->cmd_linkp; 8838 } 8839 mpt->m_waitq = cmd; 8840 } else { 8841 cmd->cmd_linkp = NULL; 8842 *(mpt->m_waitqtail) = cmd; 8843 mpt->m_waitqtail = &cmd->cmd_linkp; 8844 } 8845 } 8846 8847 static mptsas_cmd_t * 8848 mptsas_waitq_rm(mptsas_t *mpt) 8849 { 8850 mptsas_cmd_t *cmd; 8851 mptsas_target_t *ptgt; 8852 NDBG7(("mptsas_waitq_rm")); 8853 8854 MPTSAS_WAITQ_RM(mpt, cmd); 8855 8856 NDBG7(("mptsas_waitq_rm: cmd=0x%p", (void *)cmd)); 8857 if (cmd) { 8858 ptgt = cmd->cmd_tgt_addr; 8859 if (ptgt) { 8860 ptgt->m_t_nwait--; 8861 ASSERT(ptgt->m_t_nwait >= 0); 8862 } 8863 } 8864 return (cmd); 8865 } 8866 8867 /* 8868 * remove specified cmd from the middle of the wait queue. 8869 */ 8870 static void 8871 mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd) 8872 { 8873 mptsas_cmd_t *prevp = mpt->m_waitq; 8874 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8875 8876 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8877 (void *)mpt, (void *)cmd)); 8878 if (ptgt) { 8879 ptgt->m_t_nwait--; 8880 ASSERT(ptgt->m_t_nwait >= 0); 8881 } 8882 8883 if (prevp == cmd) { 8884 if ((mpt->m_waitq = cmd->cmd_linkp) == NULL) 8885 mpt->m_waitqtail = &mpt->m_waitq; 8886 8887 cmd->cmd_linkp = NULL; 8888 cmd->cmd_queued = FALSE; 8889 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8890 (void *)mpt, (void *)cmd)); 8891 return; 8892 } 8893 8894 while (prevp != NULL) { 8895 if (prevp->cmd_linkp == cmd) { 8896 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL) 8897 mpt->m_waitqtail = &prevp->cmd_linkp; 8898 8899 cmd->cmd_linkp = NULL; 8900 cmd->cmd_queued = FALSE; 8901 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8902 (void *)mpt, (void *)cmd)); 8903 return; 8904 } 8905 prevp = prevp->cmd_linkp; 8906 } 8907 cmn_err(CE_PANIC, "mpt: mptsas_waitq_delete: queue botch"); 8908 } 8909 8910 static mptsas_cmd_t * 8911 mptsas_tx_waitq_rm(mptsas_t *mpt) 8912 { 8913 mptsas_cmd_t *cmd; 8914 NDBG7(("mptsas_tx_waitq_rm")); 8915 8916 MPTSAS_TX_WAITQ_RM(mpt, cmd); 8917 8918 NDBG7(("mptsas_tx_waitq_rm: cmd=0x%p", (void *)cmd)); 8919 8920 return (cmd); 8921 } 8922 8923 /* 8924 * remove specified cmd from the middle of the tx_waitq. 8925 */ 8926 static void 8927 mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd) 8928 { 8929 mptsas_cmd_t *prevp = mpt->m_tx_waitq; 8930 8931 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p", 8932 (void *)mpt, (void *)cmd)); 8933 8934 if (prevp == cmd) { 8935 if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) 8936 mpt->m_tx_waitqtail = &mpt->m_tx_waitq; 8937 8938 cmd->cmd_linkp = NULL; 8939 cmd->cmd_queued = FALSE; 8940 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p", 8941 (void *)mpt, (void *)cmd)); 8942 return; 8943 } 8944 8945 while (prevp != NULL) { 8946 if (prevp->cmd_linkp == cmd) { 8947 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL) 8948 mpt->m_tx_waitqtail = &prevp->cmd_linkp; 8949 8950 cmd->cmd_linkp = NULL; 8951 cmd->cmd_queued = FALSE; 8952 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p", 8953 (void *)mpt, (void *)cmd)); 8954 return; 8955 } 8956 prevp = prevp->cmd_linkp; 8957 } 8958 cmn_err(CE_PANIC, "mpt: mptsas_tx_waitq_delete: queue botch"); 8959 } 8960 8961 /* 8962 * device and bus reset handling 8963 * 8964 * Notes: 8965 * - RESET_ALL: reset the controller 8966 * - RESET_TARGET: reset the target specified in scsi_address 8967 */ 8968 static int 8969 mptsas_scsi_reset(struct scsi_address *ap, int level) 8970 { 8971 mptsas_t *mpt = ADDR2MPT(ap); 8972 int rval; 8973 mptsas_tgt_private_t *tgt_private; 8974 mptsas_target_t *ptgt = NULL; 8975 8976 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->tran_tgt_private; 8977 ptgt = tgt_private->t_private; 8978 if (ptgt == NULL) { 8979 return (FALSE); 8980 } 8981 NDBG22(("mptsas_scsi_reset: target=%d level=%d", ptgt->m_devhdl, 8982 level)); 8983 8984 mutex_enter(&mpt->m_mutex); 8985 /* 8986 * if we are not in panic set up a reset delay for this target 8987 */ 8988 if (!ddi_in_panic()) { 8989 mptsas_setup_bus_reset_delay(mpt); 8990 } else { 8991 drv_usecwait(mpt->m_scsi_reset_delay * 1000); 8992 } 8993 rval = mptsas_do_scsi_reset(mpt, ptgt->m_devhdl); 8994 mutex_exit(&mpt->m_mutex); 8995 8996 /* 8997 * The transport layer expect to only see TRUE and 8998 * FALSE. Therefore, we will adjust the return value 8999 * if mptsas_do_scsi_reset returns FAILED. 9000 */ 9001 if (rval == FAILED) 9002 rval = FALSE; 9003 return (rval); 9004 } 9005 9006 static int 9007 mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl) 9008 { 9009 int rval = FALSE; 9010 uint8_t config, disk; 9011 9012 ASSERT(mutex_owned(&mpt->m_mutex)); 9013 9014 if (mptsas_debug_resets) { 9015 mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d", 9016 devhdl); 9017 } 9018 9019 /* 9020 * Issue a Target Reset message to the target specified but not to a 9021 * disk making up a raid volume. Just look through the RAID config 9022 * Phys Disk list of DevHandles. If the target's DevHandle is in this 9023 * list, then don't reset this target. 9024 */ 9025 for (config = 0; config < mpt->m_num_raid_configs; config++) { 9026 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) { 9027 if (devhdl == mpt->m_raidconfig[config]. 9028 m_physdisk_devhdl[disk]) { 9029 return (TRUE); 9030 } 9031 } 9032 } 9033 9034 rval = mptsas_ioc_task_management(mpt, 9035 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, devhdl, 0, NULL, 0, 0); 9036 9037 mptsas_doneq_empty(mpt); 9038 return (rval); 9039 } 9040 9041 static int 9042 mptsas_scsi_reset_notify(struct scsi_address *ap, int flag, 9043 void (*callback)(caddr_t), caddr_t arg) 9044 { 9045 mptsas_t *mpt = ADDR2MPT(ap); 9046 9047 NDBG22(("mptsas_scsi_reset_notify: tgt=%d", ap->a_target)); 9048 9049 return (scsi_hba_reset_notify_setup(ap, flag, callback, arg, 9050 &mpt->m_mutex, &mpt->m_reset_notify_listf)); 9051 } 9052 9053 static int 9054 mptsas_get_name(struct scsi_device *sd, char *name, int len) 9055 { 9056 dev_info_t *lun_dip = NULL; 9057 9058 ASSERT(sd != NULL); 9059 ASSERT(name != NULL); 9060 lun_dip = sd->sd_dev; 9061 ASSERT(lun_dip != NULL); 9062 9063 if (mptsas_name_child(lun_dip, name, len) == DDI_SUCCESS) { 9064 return (1); 9065 } else { 9066 return (0); 9067 } 9068 } 9069 9070 static int 9071 mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len) 9072 { 9073 return (mptsas_get_name(sd, name, len)); 9074 } 9075 9076 void 9077 mptsas_set_throttle(mptsas_t *mpt, mptsas_target_t *ptgt, int what) 9078 { 9079 9080 NDBG25(("mptsas_set_throttle: throttle=%x", what)); 9081 9082 /* 9083 * if the bus is draining/quiesced, no changes to the throttles 9084 * are allowed. Not allowing change of throttles during draining 9085 * limits error recovery but will reduce draining time 9086 * 9087 * all throttles should have been set to HOLD_THROTTLE 9088 */ 9089 if (mpt->m_softstate & (MPTSAS_SS_QUIESCED | MPTSAS_SS_DRAINING)) { 9090 return; 9091 } 9092 9093 if (what == HOLD_THROTTLE) { 9094 ptgt->m_t_throttle = HOLD_THROTTLE; 9095 } else if (ptgt->m_reset_delay == 0) { 9096 ptgt->m_t_throttle = what; 9097 } 9098 } 9099 9100 /* 9101 * Clean up from a device reset. 9102 * For the case of target reset, this function clears the waitq of all 9103 * commands for a particular target. For the case of abort task set, this 9104 * function clears the waitq of all commonds for a particular target/lun. 9105 */ 9106 static void 9107 mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype) 9108 { 9109 mptsas_slots_t *slots = mpt->m_active; 9110 mptsas_cmd_t *cmd, *next_cmd; 9111 int slot; 9112 uchar_t reason; 9113 uint_t stat; 9114 hrtime_t timestamp; 9115 9116 NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun)); 9117 9118 timestamp = gethrtime(); 9119 9120 /* 9121 * Make sure the I/O Controller has flushed all cmds 9122 * that are associated with this target for a target reset 9123 * and target/lun for abort task set. 9124 * Account for TM requests, which use the last SMID. 9125 */ 9126 for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) { 9127 if ((cmd = slots->m_slot[slot]) == NULL) 9128 continue; 9129 reason = CMD_RESET; 9130 stat = STAT_DEV_RESET; 9131 switch (tasktype) { 9132 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 9133 if (Tgt(cmd) == target) { 9134 if (cmd->cmd_active_expiration <= timestamp) { 9135 /* 9136 * When timeout requested, propagate 9137 * proper reason and statistics to 9138 * target drivers. 9139 */ 9140 reason = CMD_TIMEOUT; 9141 stat |= STAT_TIMEOUT; 9142 } 9143 NDBG25(("mptsas_flush_target discovered non-" 9144 "NULL cmd in slot %d, tasktype 0x%x", slot, 9145 tasktype)); 9146 mptsas_dump_cmd(mpt, cmd); 9147 mptsas_remove_cmd(mpt, cmd); 9148 mptsas_set_pkt_reason(mpt, cmd, reason, stat); 9149 mptsas_doneq_add(mpt, cmd); 9150 } 9151 break; 9152 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 9153 reason = CMD_ABORTED; 9154 stat = STAT_ABORTED; 9155 /*FALLTHROUGH*/ 9156 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 9157 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 9158 9159 NDBG25(("mptsas_flush_target discovered non-" 9160 "NULL cmd in slot %d, tasktype 0x%x", slot, 9161 tasktype)); 9162 mptsas_dump_cmd(mpt, cmd); 9163 mptsas_remove_cmd(mpt, cmd); 9164 mptsas_set_pkt_reason(mpt, cmd, reason, 9165 stat); 9166 mptsas_doneq_add(mpt, cmd); 9167 } 9168 break; 9169 default: 9170 break; 9171 } 9172 } 9173 9174 /* 9175 * Flush the waitq and tx_waitq of this target's cmds 9176 */ 9177 cmd = mpt->m_waitq; 9178 9179 reason = CMD_RESET; 9180 stat = STAT_DEV_RESET; 9181 9182 switch (tasktype) { 9183 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 9184 while (cmd != NULL) { 9185 next_cmd = cmd->cmd_linkp; 9186 if (Tgt(cmd) == target) { 9187 mptsas_waitq_delete(mpt, cmd); 9188 mptsas_set_pkt_reason(mpt, cmd, 9189 reason, stat); 9190 mptsas_doneq_add(mpt, cmd); 9191 } 9192 cmd = next_cmd; 9193 } 9194 mutex_enter(&mpt->m_tx_waitq_mutex); 9195 cmd = mpt->m_tx_waitq; 9196 while (cmd != NULL) { 9197 next_cmd = cmd->cmd_linkp; 9198 if (Tgt(cmd) == target) { 9199 mptsas_tx_waitq_delete(mpt, cmd); 9200 mutex_exit(&mpt->m_tx_waitq_mutex); 9201 mptsas_set_pkt_reason(mpt, cmd, 9202 reason, stat); 9203 mptsas_doneq_add(mpt, cmd); 9204 mutex_enter(&mpt->m_tx_waitq_mutex); 9205 } 9206 cmd = next_cmd; 9207 } 9208 mutex_exit(&mpt->m_tx_waitq_mutex); 9209 break; 9210 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 9211 reason = CMD_ABORTED; 9212 stat = STAT_ABORTED; 9213 /*FALLTHROUGH*/ 9214 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 9215 while (cmd != NULL) { 9216 next_cmd = cmd->cmd_linkp; 9217 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 9218 mptsas_waitq_delete(mpt, cmd); 9219 mptsas_set_pkt_reason(mpt, cmd, 9220 reason, stat); 9221 mptsas_doneq_add(mpt, cmd); 9222 } 9223 cmd = next_cmd; 9224 } 9225 mutex_enter(&mpt->m_tx_waitq_mutex); 9226 cmd = mpt->m_tx_waitq; 9227 while (cmd != NULL) { 9228 next_cmd = cmd->cmd_linkp; 9229 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 9230 mptsas_tx_waitq_delete(mpt, cmd); 9231 mutex_exit(&mpt->m_tx_waitq_mutex); 9232 mptsas_set_pkt_reason(mpt, cmd, 9233 reason, stat); 9234 mptsas_doneq_add(mpt, cmd); 9235 mutex_enter(&mpt->m_tx_waitq_mutex); 9236 } 9237 cmd = next_cmd; 9238 } 9239 mutex_exit(&mpt->m_tx_waitq_mutex); 9240 break; 9241 default: 9242 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.", 9243 tasktype); 9244 break; 9245 } 9246 } 9247 9248 /* 9249 * Clean up hba state, abort all outstanding command and commands in waitq 9250 * reset timeout of all targets. 9251 */ 9252 static void 9253 mptsas_flush_hba(mptsas_t *mpt) 9254 { 9255 mptsas_slots_t *slots = mpt->m_active; 9256 mptsas_cmd_t *cmd; 9257 int slot; 9258 9259 NDBG25(("mptsas_flush_hba")); 9260 9261 /* 9262 * The I/O Controller should have already sent back 9263 * all commands via the scsi I/O reply frame. Make 9264 * sure all commands have been flushed. 9265 * Account for TM request, which use the last SMID. 9266 */ 9267 for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) { 9268 if ((cmd = slots->m_slot[slot]) == NULL) 9269 continue; 9270 9271 if (cmd->cmd_flags & CFLAG_CMDIOC) { 9272 /* 9273 * Need to make sure to tell everyone that might be 9274 * waiting on this command that it's going to fail. If 9275 * we get here, this command will never timeout because 9276 * the active command table is going to be re-allocated, 9277 * so there will be nothing to check against a time out. 9278 * Instead, mark the command as failed due to reset. 9279 */ 9280 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, 9281 STAT_BUS_RESET); 9282 if ((cmd->cmd_flags & 9283 (CFLAG_PASSTHRU | CFLAG_CONFIG | CFLAG_FW_DIAG))) { 9284 cmd->cmd_flags |= CFLAG_FINISHED; 9285 cv_broadcast(&mpt->m_passthru_cv); 9286 cv_broadcast(&mpt->m_config_cv); 9287 cv_broadcast(&mpt->m_fw_diag_cv); 9288 } 9289 continue; 9290 } 9291 9292 NDBG25(("mptsas_flush_hba discovered non-NULL cmd in slot %d", 9293 slot)); 9294 mptsas_dump_cmd(mpt, cmd); 9295 9296 mptsas_remove_cmd(mpt, cmd); 9297 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 9298 mptsas_doneq_add(mpt, cmd); 9299 } 9300 9301 /* 9302 * Flush the waitq. 9303 */ 9304 while ((cmd = mptsas_waitq_rm(mpt)) != NULL) { 9305 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 9306 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 9307 (cmd->cmd_flags & CFLAG_CONFIG) || 9308 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 9309 cmd->cmd_flags |= CFLAG_FINISHED; 9310 cv_broadcast(&mpt->m_passthru_cv); 9311 cv_broadcast(&mpt->m_config_cv); 9312 cv_broadcast(&mpt->m_fw_diag_cv); 9313 } else { 9314 mptsas_doneq_add(mpt, cmd); 9315 } 9316 } 9317 9318 /* 9319 * Flush the tx_waitq 9320 */ 9321 mutex_enter(&mpt->m_tx_waitq_mutex); 9322 while ((cmd = mptsas_tx_waitq_rm(mpt)) != NULL) { 9323 mutex_exit(&mpt->m_tx_waitq_mutex); 9324 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 9325 mptsas_doneq_add(mpt, cmd); 9326 mutex_enter(&mpt->m_tx_waitq_mutex); 9327 } 9328 mutex_exit(&mpt->m_tx_waitq_mutex); 9329 9330 /* 9331 * Drain the taskqs prior to reallocating resources. The thread 9332 * passing through here could be launched from either (dr) 9333 * or (event) taskqs so only wait on the 'other' queue since 9334 * waiting on 'this' queue is a deadlock condition. 9335 */ 9336 mutex_exit(&mpt->m_mutex); 9337 if (!taskq_member((taskq_t *)mpt->m_event_taskq, curthread)) 9338 ddi_taskq_wait(mpt->m_event_taskq); 9339 if (!taskq_member((taskq_t *)mpt->m_dr_taskq, curthread)) 9340 ddi_taskq_wait(mpt->m_dr_taskq); 9341 9342 mutex_enter(&mpt->m_mutex); 9343 } 9344 9345 /* 9346 * set pkt_reason and OR in pkt_statistics flag 9347 */ 9348 static void 9349 mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, uchar_t reason, 9350 uint_t stat) 9351 { 9352 #ifndef __lock_lint 9353 _NOTE(ARGUNUSED(mpt)) 9354 #endif 9355 9356 NDBG25(("mptsas_set_pkt_reason: cmd=0x%p reason=%x stat=%x", 9357 (void *)cmd, reason, stat)); 9358 9359 if (cmd) { 9360 if (cmd->cmd_pkt->pkt_reason == CMD_CMPLT) { 9361 cmd->cmd_pkt->pkt_reason = reason; 9362 } 9363 cmd->cmd_pkt->pkt_statistics |= stat; 9364 } 9365 } 9366 9367 static void 9368 mptsas_start_watch_reset_delay() 9369 { 9370 NDBG22(("mptsas_start_watch_reset_delay")); 9371 9372 mutex_enter(&mptsas_global_mutex); 9373 if (mptsas_reset_watch == NULL && mptsas_timeouts_enabled) { 9374 mptsas_reset_watch = timeout(mptsas_watch_reset_delay, NULL, 9375 drv_usectohz((clock_t) 9376 MPTSAS_WATCH_RESET_DELAY_TICK * 1000)); 9377 ASSERT(mptsas_reset_watch != NULL); 9378 } 9379 mutex_exit(&mptsas_global_mutex); 9380 } 9381 9382 static void 9383 mptsas_setup_bus_reset_delay(mptsas_t *mpt) 9384 { 9385 mptsas_target_t *ptgt = NULL; 9386 9387 ASSERT(MUTEX_HELD(&mpt->m_mutex)); 9388 9389 NDBG22(("mptsas_setup_bus_reset_delay")); 9390 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 9391 ptgt = refhash_next(mpt->m_targets, ptgt)) { 9392 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 9393 ptgt->m_reset_delay = mpt->m_scsi_reset_delay; 9394 } 9395 9396 mptsas_start_watch_reset_delay(); 9397 } 9398 9399 /* 9400 * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every 9401 * mpt instance for active reset delays 9402 */ 9403 static void 9404 mptsas_watch_reset_delay(void *arg) 9405 { 9406 #ifndef __lock_lint 9407 _NOTE(ARGUNUSED(arg)) 9408 #endif 9409 9410 mptsas_t *mpt; 9411 int not_done = 0; 9412 9413 NDBG22(("mptsas_watch_reset_delay")); 9414 9415 mutex_enter(&mptsas_global_mutex); 9416 mptsas_reset_watch = 0; 9417 mutex_exit(&mptsas_global_mutex); 9418 rw_enter(&mptsas_global_rwlock, RW_READER); 9419 for (mpt = mptsas_head; mpt != NULL; mpt = mpt->m_next) { 9420 if (mpt->m_tran == 0) { 9421 continue; 9422 } 9423 mutex_enter(&mpt->m_mutex); 9424 not_done += mptsas_watch_reset_delay_subr(mpt); 9425 mutex_exit(&mpt->m_mutex); 9426 } 9427 rw_exit(&mptsas_global_rwlock); 9428 9429 if (not_done) { 9430 mptsas_start_watch_reset_delay(); 9431 } 9432 } 9433 9434 static int 9435 mptsas_watch_reset_delay_subr(mptsas_t *mpt) 9436 { 9437 int done = 0; 9438 int restart = 0; 9439 mptsas_target_t *ptgt = NULL; 9440 9441 NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt)); 9442 9443 ASSERT(mutex_owned(&mpt->m_mutex)); 9444 9445 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 9446 ptgt = refhash_next(mpt->m_targets, ptgt)) { 9447 if (ptgt->m_reset_delay != 0) { 9448 ptgt->m_reset_delay -= 9449 MPTSAS_WATCH_RESET_DELAY_TICK; 9450 if (ptgt->m_reset_delay <= 0) { 9451 ptgt->m_reset_delay = 0; 9452 mptsas_set_throttle(mpt, ptgt, 9453 MAX_THROTTLE); 9454 restart++; 9455 } else { 9456 done = -1; 9457 } 9458 } 9459 } 9460 9461 if (restart > 0) { 9462 mptsas_restart_hba(mpt); 9463 } 9464 return (done); 9465 } 9466 9467 #ifdef MPTSAS_TEST 9468 static void 9469 mptsas_test_reset(mptsas_t *mpt, int target) 9470 { 9471 mptsas_target_t *ptgt = NULL; 9472 9473 if (mptsas_rtest == target) { 9474 if (mptsas_do_scsi_reset(mpt, target) == TRUE) { 9475 mptsas_rtest = -1; 9476 } 9477 if (mptsas_rtest == -1) { 9478 NDBG22(("mptsas_test_reset success")); 9479 } 9480 } 9481 } 9482 #endif 9483 9484 /* 9485 * abort handling: 9486 * 9487 * Notes: 9488 * - if pkt is not NULL, abort just that command 9489 * - if pkt is NULL, abort all outstanding commands for target 9490 */ 9491 static int 9492 mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt) 9493 { 9494 mptsas_t *mpt = ADDR2MPT(ap); 9495 int rval; 9496 mptsas_tgt_private_t *tgt_private; 9497 int target, lun; 9498 9499 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran-> 9500 tran_tgt_private; 9501 ASSERT(tgt_private != NULL); 9502 target = tgt_private->t_private->m_devhdl; 9503 lun = tgt_private->t_lun; 9504 9505 NDBG23(("mptsas_scsi_abort: target=%d.%d", target, lun)); 9506 9507 mutex_enter(&mpt->m_mutex); 9508 rval = mptsas_do_scsi_abort(mpt, target, lun, pkt); 9509 mutex_exit(&mpt->m_mutex); 9510 return (rval); 9511 } 9512 9513 static int 9514 mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, struct scsi_pkt *pkt) 9515 { 9516 mptsas_cmd_t *sp = NULL; 9517 mptsas_slots_t *slots = mpt->m_active; 9518 int rval = FALSE; 9519 9520 ASSERT(mutex_owned(&mpt->m_mutex)); 9521 9522 /* 9523 * Abort the command pkt on the target/lun in ap. If pkt is 9524 * NULL, abort all outstanding commands on that target/lun. 9525 * If you can abort them, return 1, else return 0. 9526 * Each packet that's aborted should be sent back to the target 9527 * driver through the callback routine, with pkt_reason set to 9528 * CMD_ABORTED. 9529 * 9530 * abort cmd pkt on HBA hardware; clean out of outstanding 9531 * command lists, etc. 9532 */ 9533 if (pkt != NULL) { 9534 /* abort the specified packet */ 9535 sp = PKT2CMD(pkt); 9536 9537 if (sp->cmd_queued) { 9538 NDBG23(("mptsas_do_scsi_abort: queued sp=0x%p aborted", 9539 (void *)sp)); 9540 mptsas_waitq_delete(mpt, sp); 9541 mptsas_set_pkt_reason(mpt, sp, CMD_ABORTED, 9542 STAT_ABORTED); 9543 mptsas_doneq_add(mpt, sp); 9544 rval = TRUE; 9545 goto done; 9546 } 9547 9548 /* 9549 * Have mpt firmware abort this command 9550 */ 9551 9552 if (slots->m_slot[sp->cmd_slot] != NULL) { 9553 rval = mptsas_ioc_task_management(mpt, 9554 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, target, 9555 lun, NULL, 0, 0); 9556 9557 /* 9558 * The transport layer expects only TRUE and FALSE. 9559 * Therefore, if mptsas_ioc_task_management returns 9560 * FAILED we will return FALSE. 9561 */ 9562 if (rval == FAILED) 9563 rval = FALSE; 9564 goto done; 9565 } 9566 } 9567 9568 /* 9569 * If pkt is NULL then abort task set 9570 */ 9571 rval = mptsas_ioc_task_management(mpt, 9572 MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, target, lun, NULL, 0, 0); 9573 9574 /* 9575 * The transport layer expects only TRUE and FALSE. 9576 * Therefore, if mptsas_ioc_task_management returns 9577 * FAILED we will return FALSE. 9578 */ 9579 if (rval == FAILED) 9580 rval = FALSE; 9581 9582 #ifdef MPTSAS_TEST 9583 if (rval && mptsas_test_stop) { 9584 debug_enter("mptsas_do_scsi_abort"); 9585 } 9586 #endif 9587 9588 done: 9589 mptsas_doneq_empty(mpt); 9590 return (rval); 9591 } 9592 9593 /* 9594 * capability handling: 9595 * (*tran_getcap). Get the capability named, and return its value. 9596 */ 9597 static int 9598 mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly) 9599 { 9600 mptsas_t *mpt = ADDR2MPT(ap); 9601 int ckey; 9602 int rval = FALSE; 9603 9604 NDBG24(("mptsas_scsi_getcap: target=%d, cap=%s tgtonly=%x", 9605 ap->a_target, cap, tgtonly)); 9606 9607 mutex_enter(&mpt->m_mutex); 9608 9609 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) { 9610 mutex_exit(&mpt->m_mutex); 9611 return (UNDEFINED); 9612 } 9613 9614 switch (ckey) { 9615 case SCSI_CAP_DMA_MAX: 9616 rval = (int)mpt->m_msg_dma_attr.dma_attr_maxxfer; 9617 break; 9618 case SCSI_CAP_ARQ: 9619 rval = TRUE; 9620 break; 9621 case SCSI_CAP_MSG_OUT: 9622 case SCSI_CAP_PARITY: 9623 case SCSI_CAP_UNTAGGED_QING: 9624 rval = TRUE; 9625 break; 9626 case SCSI_CAP_TAGGED_QING: 9627 rval = TRUE; 9628 break; 9629 case SCSI_CAP_RESET_NOTIFICATION: 9630 rval = TRUE; 9631 break; 9632 case SCSI_CAP_LINKED_CMDS: 9633 rval = FALSE; 9634 break; 9635 case SCSI_CAP_QFULL_RETRIES: 9636 rval = ((mptsas_tgt_private_t *)(ap->a_hba_tran-> 9637 tran_tgt_private))->t_private->m_qfull_retries; 9638 break; 9639 case SCSI_CAP_QFULL_RETRY_INTERVAL: 9640 rval = drv_hztousec(((mptsas_tgt_private_t *) 9641 (ap->a_hba_tran->tran_tgt_private))-> 9642 t_private->m_qfull_retry_interval) / 1000; 9643 break; 9644 case SCSI_CAP_CDB_LEN: 9645 rval = CDB_GROUP4; 9646 break; 9647 case SCSI_CAP_INTERCONNECT_TYPE: 9648 rval = INTERCONNECT_SAS; 9649 break; 9650 case SCSI_CAP_TRAN_LAYER_RETRIES: 9651 if (mpt->m_ioc_capabilities & 9652 MPI2_IOCFACTS_CAPABILITY_TLR) 9653 rval = TRUE; 9654 else 9655 rval = FALSE; 9656 break; 9657 default: 9658 rval = UNDEFINED; 9659 break; 9660 } 9661 9662 NDBG24(("mptsas_scsi_getcap: %s, rval=%x", cap, rval)); 9663 9664 mutex_exit(&mpt->m_mutex); 9665 return (rval); 9666 } 9667 9668 /* 9669 * (*tran_setcap). Set the capability named to the value given. 9670 */ 9671 static int 9672 mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, int tgtonly) 9673 { 9674 mptsas_t *mpt = ADDR2MPT(ap); 9675 int ckey; 9676 int rval = FALSE; 9677 9678 NDBG24(("mptsas_scsi_setcap: target=%d, cap=%s value=%x tgtonly=%x", 9679 ap->a_target, cap, value, tgtonly)); 9680 9681 if (!tgtonly) { 9682 return (rval); 9683 } 9684 9685 mutex_enter(&mpt->m_mutex); 9686 9687 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) { 9688 mutex_exit(&mpt->m_mutex); 9689 return (UNDEFINED); 9690 } 9691 9692 switch (ckey) { 9693 case SCSI_CAP_DMA_MAX: 9694 case SCSI_CAP_MSG_OUT: 9695 case SCSI_CAP_PARITY: 9696 case SCSI_CAP_INITIATOR_ID: 9697 case SCSI_CAP_LINKED_CMDS: 9698 case SCSI_CAP_UNTAGGED_QING: 9699 case SCSI_CAP_RESET_NOTIFICATION: 9700 /* 9701 * None of these are settable via 9702 * the capability interface. 9703 */ 9704 break; 9705 case SCSI_CAP_ARQ: 9706 /* 9707 * We cannot turn off arq so return false if asked to 9708 */ 9709 if (value) { 9710 rval = TRUE; 9711 } else { 9712 rval = FALSE; 9713 } 9714 break; 9715 case SCSI_CAP_TAGGED_QING: 9716 mptsas_set_throttle(mpt, ((mptsas_tgt_private_t *) 9717 (ap->a_hba_tran->tran_tgt_private))->t_private, 9718 MAX_THROTTLE); 9719 rval = TRUE; 9720 break; 9721 case SCSI_CAP_QFULL_RETRIES: 9722 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))-> 9723 t_private->m_qfull_retries = (uchar_t)value; 9724 rval = TRUE; 9725 break; 9726 case SCSI_CAP_QFULL_RETRY_INTERVAL: 9727 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))-> 9728 t_private->m_qfull_retry_interval = 9729 drv_usectohz(value * 1000); 9730 rval = TRUE; 9731 break; 9732 default: 9733 rval = UNDEFINED; 9734 break; 9735 } 9736 mutex_exit(&mpt->m_mutex); 9737 return (rval); 9738 } 9739 9740 /* 9741 * Utility routine for mptsas_ifsetcap/ifgetcap 9742 */ 9743 /*ARGSUSED*/ 9744 static int 9745 mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp) 9746 { 9747 NDBG24(("mptsas_scsi_capchk: cap=%s", cap)); 9748 9749 if (!cap) 9750 return (FALSE); 9751 9752 *cidxp = scsi_hba_lookup_capstr(cap); 9753 return (TRUE); 9754 } 9755 9756 static int 9757 mptsas_alloc_active_slots(mptsas_t *mpt, int flag) 9758 { 9759 mptsas_slots_t *old_active = mpt->m_active; 9760 mptsas_slots_t *new_active; 9761 size_t size; 9762 9763 /* 9764 * if there are active commands, then we cannot 9765 * change size of active slots array. 9766 */ 9767 ASSERT(mpt->m_ncmds == 0); 9768 9769 size = MPTSAS_SLOTS_SIZE(mpt); 9770 new_active = kmem_zalloc(size, flag); 9771 if (new_active == NULL) { 9772 NDBG1(("new active alloc failed")); 9773 return (-1); 9774 } 9775 /* 9776 * Since SMID 0 is reserved and the TM slot is reserved, the 9777 * number of slots that can be used at any one time is 9778 * m_max_requests - 2. 9779 */ 9780 new_active->m_n_normal = (mpt->m_max_requests - 2); 9781 new_active->m_size = size; 9782 new_active->m_rotor = 1; 9783 if (old_active) 9784 mptsas_free_active_slots(mpt); 9785 mpt->m_active = new_active; 9786 9787 return (0); 9788 } 9789 9790 static void 9791 mptsas_free_active_slots(mptsas_t *mpt) 9792 { 9793 mptsas_slots_t *active = mpt->m_active; 9794 size_t size; 9795 9796 if (active == NULL) 9797 return; 9798 size = active->m_size; 9799 kmem_free(active, size); 9800 mpt->m_active = NULL; 9801 } 9802 9803 /* 9804 * Error logging, printing, and debug print routines. 9805 */ 9806 static char *mptsas_label = "mpt_sas"; 9807 9808 /*PRINTFLIKE3*/ 9809 void 9810 mptsas_log(mptsas_t *mpt, int level, char *fmt, ...) 9811 { 9812 dev_info_t *dev; 9813 va_list ap; 9814 9815 if (mpt) { 9816 dev = mpt->m_dip; 9817 } else { 9818 dev = 0; 9819 } 9820 9821 mutex_enter(&mptsas_log_mutex); 9822 9823 va_start(ap, fmt); 9824 (void) vsprintf(mptsas_log_buf, fmt, ap); 9825 va_end(ap); 9826 9827 if (level == CE_CONT) { 9828 scsi_log(dev, mptsas_label, level, "%s\n", mptsas_log_buf); 9829 } else { 9830 scsi_log(dev, mptsas_label, level, "%s", mptsas_log_buf); 9831 } 9832 9833 mutex_exit(&mptsas_log_mutex); 9834 } 9835 9836 #ifdef MPTSAS_DEBUG 9837 /* 9838 * Use a circular buffer to log messages to private memory. 9839 * Increment idx atomically to minimize risk to miss lines. 9840 * It's fast and does not hold up the proceedings too much. 9841 */ 9842 static const size_t mptsas_dbglog_linecnt = MPTSAS_DBGLOG_LINECNT; 9843 static const size_t mptsas_dbglog_linelen = MPTSAS_DBGLOG_LINELEN; 9844 static char mptsas_dbglog_bufs[MPTSAS_DBGLOG_LINECNT][MPTSAS_DBGLOG_LINELEN]; 9845 static uint32_t mptsas_dbglog_idx = 0; 9846 9847 /*PRINTFLIKE1*/ 9848 void 9849 mptsas_debug_log(char *fmt, ...) 9850 { 9851 va_list ap; 9852 uint32_t idx; 9853 9854 idx = atomic_inc_32_nv(&mptsas_dbglog_idx) & 9855 (mptsas_dbglog_linecnt - 1); 9856 9857 va_start(ap, fmt); 9858 (void) vsnprintf(mptsas_dbglog_bufs[idx], 9859 mptsas_dbglog_linelen, fmt, ap); 9860 va_end(ap); 9861 } 9862 9863 /*PRINTFLIKE1*/ 9864 void 9865 mptsas_printf(char *fmt, ...) 9866 { 9867 dev_info_t *dev = 0; 9868 va_list ap; 9869 9870 mutex_enter(&mptsas_log_mutex); 9871 9872 va_start(ap, fmt); 9873 (void) vsprintf(mptsas_log_buf, fmt, ap); 9874 va_end(ap); 9875 9876 #ifdef PROM_PRINTF 9877 prom_printf("%s:\t%s\n", mptsas_label, mptsas_log_buf); 9878 #else 9879 scsi_log(dev, mptsas_label, CE_CONT, "!%s\n", mptsas_log_buf); 9880 #endif 9881 mutex_exit(&mptsas_log_mutex); 9882 } 9883 #endif 9884 9885 /* 9886 * timeout handling 9887 */ 9888 static void 9889 mptsas_watch(void *arg) 9890 { 9891 #ifndef __lock_lint 9892 _NOTE(ARGUNUSED(arg)) 9893 #endif 9894 9895 mptsas_t *mpt; 9896 uint32_t doorbell; 9897 9898 NDBG30(("mptsas_watch")); 9899 9900 rw_enter(&mptsas_global_rwlock, RW_READER); 9901 for (mpt = mptsas_head; mpt != (mptsas_t *)NULL; mpt = mpt->m_next) { 9902 9903 mutex_enter(&mpt->m_mutex); 9904 9905 /* Skip device if not powered on */ 9906 if (mpt->m_options & MPTSAS_OPT_PM) { 9907 if (mpt->m_power_level == PM_LEVEL_D0) { 9908 (void) pm_busy_component(mpt->m_dip, 0); 9909 mpt->m_busy = 1; 9910 } else { 9911 mutex_exit(&mpt->m_mutex); 9912 continue; 9913 } 9914 } 9915 9916 /* 9917 * Check if controller is in a FAULT state. If so, reset it. 9918 */ 9919 doorbell = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell); 9920 if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { 9921 doorbell &= MPI2_DOORBELL_DATA_MASK; 9922 mptsas_log(mpt, CE_WARN, "MPT Firmware Fault, " 9923 "code: %04x", doorbell); 9924 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 9925 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 9926 mptsas_log(mpt, CE_WARN, "Reset failed" 9927 "after fault was detected"); 9928 } 9929 } 9930 9931 /* 9932 * For now, always call mptsas_watchsubr. 9933 */ 9934 mptsas_watchsubr(mpt); 9935 9936 if (mpt->m_options & MPTSAS_OPT_PM) { 9937 mpt->m_busy = 0; 9938 (void) pm_idle_component(mpt->m_dip, 0); 9939 } 9940 9941 mutex_exit(&mpt->m_mutex); 9942 } 9943 rw_exit(&mptsas_global_rwlock); 9944 9945 mutex_enter(&mptsas_global_mutex); 9946 if (mptsas_timeouts_enabled) 9947 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick); 9948 mutex_exit(&mptsas_global_mutex); 9949 } 9950 9951 static void 9952 mptsas_watchsubr_tgt(mptsas_t *mpt, mptsas_target_t *ptgt, hrtime_t timestamp) 9953 { 9954 mptsas_cmd_t *cmd; 9955 9956 /* 9957 * If we were draining due to a qfull condition, 9958 * go back to full throttle. 9959 */ 9960 if ((ptgt->m_t_throttle < MAX_THROTTLE) && 9961 (ptgt->m_t_throttle > HOLD_THROTTLE) && 9962 (ptgt->m_t_ncmds < ptgt->m_t_throttle)) { 9963 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 9964 mptsas_restart_hba(mpt); 9965 } 9966 9967 cmd = TAILQ_LAST(&ptgt->m_active_cmdq, mptsas_active_cmdq); 9968 if (cmd == NULL) 9969 return; 9970 9971 if (cmd->cmd_active_expiration <= timestamp) { 9972 /* 9973 * Earliest command timeout expired. Drain throttle. 9974 */ 9975 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 9976 9977 /* 9978 * Check for remaining commands. 9979 */ 9980 cmd = TAILQ_FIRST(&ptgt->m_active_cmdq); 9981 if (cmd->cmd_active_expiration > timestamp) { 9982 /* 9983 * Wait for remaining commands to complete or 9984 * time out. 9985 */ 9986 NDBG23(("command timed out, pending drain")); 9987 return; 9988 } 9989 9990 /* 9991 * All command timeouts expired. 9992 */ 9993 mptsas_log(mpt, CE_NOTE, "Timeout of %d seconds " 9994 "expired with %d commands on target %d lun %d.", 9995 cmd->cmd_pkt->pkt_time, ptgt->m_t_ncmds, 9996 ptgt->m_devhdl, Lun(cmd)); 9997 9998 mptsas_cmd_timeout(mpt, ptgt); 9999 } else if (cmd->cmd_active_expiration <= 10000 timestamp + (hrtime_t)mptsas_scsi_watchdog_tick * NANOSEC) { 10001 NDBG23(("pending timeout")); 10002 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 10003 } 10004 } 10005 10006 static void 10007 mptsas_watchsubr(mptsas_t *mpt) 10008 { 10009 int i; 10010 mptsas_cmd_t *cmd; 10011 mptsas_target_t *ptgt = NULL; 10012 hrtime_t timestamp = gethrtime(); 10013 10014 ASSERT(MUTEX_HELD(&mpt->m_mutex)); 10015 10016 NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt)); 10017 10018 #ifdef MPTSAS_TEST 10019 if (mptsas_enable_untagged) { 10020 mptsas_test_untagged++; 10021 } 10022 #endif 10023 10024 /* 10025 * Check for commands stuck in active slot 10026 * Account for TM requests, which use the last SMID. 10027 */ 10028 for (i = 0; i <= mpt->m_active->m_n_normal; i++) { 10029 if ((cmd = mpt->m_active->m_slot[i]) != NULL) { 10030 if (cmd->cmd_active_expiration <= timestamp) { 10031 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 10032 /* 10033 * There seems to be a command stuck 10034 * in the active slot. Drain throttle. 10035 */ 10036 mptsas_set_throttle(mpt, 10037 cmd->cmd_tgt_addr, 10038 DRAIN_THROTTLE); 10039 } else if (cmd->cmd_flags & 10040 (CFLAG_PASSTHRU | CFLAG_CONFIG | 10041 CFLAG_FW_DIAG)) { 10042 /* 10043 * passthrough command timeout 10044 */ 10045 cmd->cmd_flags |= (CFLAG_FINISHED | 10046 CFLAG_TIMEOUT); 10047 cv_broadcast(&mpt->m_passthru_cv); 10048 cv_broadcast(&mpt->m_config_cv); 10049 cv_broadcast(&mpt->m_fw_diag_cv); 10050 } 10051 } 10052 } 10053 } 10054 10055 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 10056 ptgt = refhash_next(mpt->m_targets, ptgt)) { 10057 mptsas_watchsubr_tgt(mpt, ptgt, timestamp); 10058 } 10059 10060 for (ptgt = refhash_first(mpt->m_tmp_targets); ptgt != NULL; 10061 ptgt = refhash_next(mpt->m_tmp_targets, ptgt)) { 10062 mptsas_watchsubr_tgt(mpt, ptgt, timestamp); 10063 } 10064 } 10065 10066 /* 10067 * timeout recovery 10068 */ 10069 static void 10070 mptsas_cmd_timeout(mptsas_t *mpt, mptsas_target_t *ptgt) 10071 { 10072 uint16_t devhdl; 10073 uint64_t sas_wwn; 10074 uint8_t phy; 10075 char wwn_str[MPTSAS_WWN_STRLEN]; 10076 10077 devhdl = ptgt->m_devhdl; 10078 sas_wwn = ptgt->m_addr.mta_wwn; 10079 phy = ptgt->m_phynum; 10080 if (sas_wwn == 0) { 10081 (void) sprintf(wwn_str, "p%x", phy); 10082 } else { 10083 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 10084 } 10085 10086 NDBG29(("mptsas_cmd_timeout: target=%d", devhdl)); 10087 mptsas_log(mpt, CE_WARN, "Disconnected command timeout for " 10088 "target %d %s, enclosure %u", devhdl, wwn_str, 10089 ptgt->m_enclosure); 10090 10091 /* 10092 * Abort all outstanding commands on the device. 10093 */ 10094 NDBG29(("mptsas_cmd_timeout: device reset")); 10095 if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) { 10096 mptsas_log(mpt, CE_WARN, "Target %d reset for command timeout " 10097 "recovery failed!", devhdl); 10098 } 10099 } 10100 10101 /* 10102 * Device / Hotplug control 10103 */ 10104 static int 10105 mptsas_scsi_quiesce(dev_info_t *dip) 10106 { 10107 mptsas_t *mpt; 10108 scsi_hba_tran_t *tran; 10109 10110 tran = ddi_get_driver_private(dip); 10111 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL) 10112 return (-1); 10113 10114 return (mptsas_quiesce_bus(mpt)); 10115 } 10116 10117 static int 10118 mptsas_scsi_unquiesce(dev_info_t *dip) 10119 { 10120 mptsas_t *mpt; 10121 scsi_hba_tran_t *tran; 10122 10123 tran = ddi_get_driver_private(dip); 10124 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL) 10125 return (-1); 10126 10127 return (mptsas_unquiesce_bus(mpt)); 10128 } 10129 10130 static int 10131 mptsas_quiesce_bus(mptsas_t *mpt) 10132 { 10133 mptsas_target_t *ptgt = NULL; 10134 10135 NDBG28(("mptsas_quiesce_bus")); 10136 mutex_enter(&mpt->m_mutex); 10137 10138 /* Set all the throttles to zero */ 10139 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 10140 ptgt = refhash_next(mpt->m_targets, ptgt)) { 10141 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 10142 } 10143 10144 /* If there are any outstanding commands in the queue */ 10145 if (mpt->m_ncmds) { 10146 mpt->m_softstate |= MPTSAS_SS_DRAINING; 10147 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain, 10148 mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000))); 10149 if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) { 10150 /* 10151 * Quiesce has been interrupted 10152 */ 10153 mpt->m_softstate &= ~MPTSAS_SS_DRAINING; 10154 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 10155 ptgt = refhash_next(mpt->m_targets, ptgt)) { 10156 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 10157 } 10158 mptsas_restart_hba(mpt); 10159 if (mpt->m_quiesce_timeid != 0) { 10160 timeout_id_t tid = mpt->m_quiesce_timeid; 10161 mpt->m_quiesce_timeid = 0; 10162 mutex_exit(&mpt->m_mutex); 10163 (void) untimeout(tid); 10164 return (-1); 10165 } 10166 mutex_exit(&mpt->m_mutex); 10167 return (-1); 10168 } else { 10169 /* Bus has been quiesced */ 10170 ASSERT(mpt->m_quiesce_timeid == 0); 10171 mpt->m_softstate &= ~MPTSAS_SS_DRAINING; 10172 mpt->m_softstate |= MPTSAS_SS_QUIESCED; 10173 mutex_exit(&mpt->m_mutex); 10174 return (0); 10175 } 10176 } 10177 /* Bus was not busy - QUIESCED */ 10178 mutex_exit(&mpt->m_mutex); 10179 10180 return (0); 10181 } 10182 10183 static int 10184 mptsas_unquiesce_bus(mptsas_t *mpt) 10185 { 10186 mptsas_target_t *ptgt = NULL; 10187 10188 NDBG28(("mptsas_unquiesce_bus")); 10189 mutex_enter(&mpt->m_mutex); 10190 mpt->m_softstate &= ~MPTSAS_SS_QUIESCED; 10191 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 10192 ptgt = refhash_next(mpt->m_targets, ptgt)) { 10193 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 10194 } 10195 mptsas_restart_hba(mpt); 10196 mutex_exit(&mpt->m_mutex); 10197 return (0); 10198 } 10199 10200 static void 10201 mptsas_ncmds_checkdrain(void *arg) 10202 { 10203 mptsas_t *mpt = arg; 10204 mptsas_target_t *ptgt = NULL; 10205 10206 mutex_enter(&mpt->m_mutex); 10207 if (mpt->m_softstate & MPTSAS_SS_DRAINING) { 10208 mpt->m_quiesce_timeid = 0; 10209 if (mpt->m_ncmds == 0) { 10210 /* Command queue has been drained */ 10211 cv_signal(&mpt->m_cv); 10212 } else { 10213 /* 10214 * The throttle may have been reset because 10215 * of a SCSI bus reset 10216 */ 10217 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 10218 ptgt = refhash_next(mpt->m_targets, ptgt)) { 10219 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 10220 } 10221 10222 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain, 10223 mpt, (MPTSAS_QUIESCE_TIMEOUT * 10224 drv_usectohz(1000000))); 10225 } 10226 } 10227 mutex_exit(&mpt->m_mutex); 10228 } 10229 10230 /*ARGSUSED*/ 10231 static void 10232 mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 10233 { 10234 int i; 10235 uint8_t *cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp; 10236 char buf[128]; 10237 10238 buf[0] = '\0'; 10239 NDBG25(("?Cmd (0x%p) dump for Target %d Lun %d:\n", (void *)cmd, 10240 Tgt(cmd), Lun(cmd))); 10241 (void) sprintf(&buf[0], "\tcdb=["); 10242 for (i = 0; i < (int)cmd->cmd_cdblen; i++) { 10243 (void) sprintf(&buf[strlen(buf)], " 0x%x", *cp++); 10244 } 10245 (void) sprintf(&buf[strlen(buf)], " ]"); 10246 NDBG25(("?%s\n", buf)); 10247 NDBG25(("?pkt_flags=0x%x pkt_statistics=0x%x pkt_state=0x%x\n", 10248 cmd->cmd_pkt->pkt_flags, cmd->cmd_pkt->pkt_statistics, 10249 cmd->cmd_pkt->pkt_state)); 10250 NDBG25(("?pkt_scbp=0x%x cmd_flags=0x%x\n", cmd->cmd_pkt->pkt_scbp ? 10251 *(cmd->cmd_pkt->pkt_scbp) : 0, cmd->cmd_flags)); 10252 } 10253 10254 static void 10255 mptsas_passthru_sge(ddi_acc_handle_t acc_hdl, mptsas_pt_request_t *pt, 10256 pMpi2SGESimple64_t sgep) 10257 { 10258 uint32_t sge_flags; 10259 uint32_t data_size, dataout_size; 10260 ddi_dma_cookie_t data_cookie; 10261 ddi_dma_cookie_t dataout_cookie; 10262 10263 data_size = pt->data_size; 10264 dataout_size = pt->dataout_size; 10265 data_cookie = pt->data_cookie; 10266 dataout_cookie = pt->dataout_cookie; 10267 10268 if (dataout_size) { 10269 sge_flags = dataout_size | 10270 ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 10271 MPI2_SGE_FLAGS_END_OF_BUFFER | 10272 MPI2_SGE_FLAGS_HOST_TO_IOC | 10273 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 10274 MPI2_SGE_FLAGS_SHIFT); 10275 ddi_put32(acc_hdl, &sgep->FlagsLength, sge_flags); 10276 ddi_put32(acc_hdl, &sgep->Address.Low, 10277 (uint32_t)(dataout_cookie.dmac_laddress & 10278 0xffffffffull)); 10279 ddi_put32(acc_hdl, &sgep->Address.High, 10280 (uint32_t)(dataout_cookie.dmac_laddress 10281 >> 32)); 10282 sgep++; 10283 } 10284 sge_flags = data_size; 10285 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 10286 MPI2_SGE_FLAGS_LAST_ELEMENT | 10287 MPI2_SGE_FLAGS_END_OF_BUFFER | 10288 MPI2_SGE_FLAGS_END_OF_LIST | 10289 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 10290 MPI2_SGE_FLAGS_SHIFT); 10291 if (pt->direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) { 10292 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_HOST_TO_IOC) << 10293 MPI2_SGE_FLAGS_SHIFT); 10294 } else { 10295 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_IOC_TO_HOST) << 10296 MPI2_SGE_FLAGS_SHIFT); 10297 } 10298 ddi_put32(acc_hdl, &sgep->FlagsLength, 10299 sge_flags); 10300 ddi_put32(acc_hdl, &sgep->Address.Low, 10301 (uint32_t)(data_cookie.dmac_laddress & 10302 0xffffffffull)); 10303 ddi_put32(acc_hdl, &sgep->Address.High, 10304 (uint32_t)(data_cookie.dmac_laddress >> 32)); 10305 } 10306 10307 static void 10308 mptsas_passthru_ieee_sge(ddi_acc_handle_t acc_hdl, mptsas_pt_request_t *pt, 10309 pMpi2IeeeSgeSimple64_t ieeesgep) 10310 { 10311 uint8_t sge_flags; 10312 uint32_t data_size, dataout_size; 10313 ddi_dma_cookie_t data_cookie; 10314 ddi_dma_cookie_t dataout_cookie; 10315 10316 data_size = pt->data_size; 10317 dataout_size = pt->dataout_size; 10318 data_cookie = pt->data_cookie; 10319 dataout_cookie = pt->dataout_cookie; 10320 10321 sge_flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | 10322 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR); 10323 if (dataout_size) { 10324 ddi_put32(acc_hdl, &ieeesgep->Length, dataout_size); 10325 ddi_put32(acc_hdl, &ieeesgep->Address.Low, 10326 (uint32_t)(dataout_cookie.dmac_laddress & 10327 0xffffffffull)); 10328 ddi_put32(acc_hdl, &ieeesgep->Address.High, 10329 (uint32_t)(dataout_cookie.dmac_laddress >> 32)); 10330 ddi_put8(acc_hdl, &ieeesgep->Flags, sge_flags); 10331 ieeesgep++; 10332 } 10333 sge_flags |= MPI25_IEEE_SGE_FLAGS_END_OF_LIST; 10334 ddi_put32(acc_hdl, &ieeesgep->Length, data_size); 10335 ddi_put32(acc_hdl, &ieeesgep->Address.Low, 10336 (uint32_t)(data_cookie.dmac_laddress & 0xffffffffull)); 10337 ddi_put32(acc_hdl, &ieeesgep->Address.High, 10338 (uint32_t)(data_cookie.dmac_laddress >> 32)); 10339 ddi_put8(acc_hdl, &ieeesgep->Flags, sge_flags); 10340 } 10341 10342 static void 10343 mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd) 10344 { 10345 caddr_t memp; 10346 pMPI2RequestHeader_t request_hdrp; 10347 struct scsi_pkt *pkt = cmd->cmd_pkt; 10348 mptsas_pt_request_t *pt = pkt->pkt_ha_private; 10349 uint32_t request_size; 10350 uint32_t i; 10351 uint64_t request_desc = 0; 10352 uint8_t desc_type; 10353 uint16_t SMID; 10354 uint8_t *request, function; 10355 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; 10356 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl; 10357 10358 desc_type = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 10359 10360 request = pt->request; 10361 request_size = pt->request_size; 10362 10363 SMID = cmd->cmd_slot; 10364 10365 /* 10366 * Store the passthrough message in memory location 10367 * corresponding to our slot number 10368 */ 10369 memp = mpt->m_req_frame + (mpt->m_req_frame_size * SMID); 10370 request_hdrp = (pMPI2RequestHeader_t)memp; 10371 bzero(memp, mpt->m_req_frame_size); 10372 10373 for (i = 0; i < request_size; i++) { 10374 bcopy(request + i, memp + i, 1); 10375 } 10376 10377 NDBG15(("mptsas_start_passthru: Func 0x%x, MsgFlags 0x%x, " 10378 "size=%d, in %d, out %d, SMID %d", request_hdrp->Function, 10379 request_hdrp->MsgFlags, request_size, 10380 pt->data_size, pt->dataout_size, SMID)); 10381 10382 /* 10383 * Add an SGE, even if the length is zero. 10384 */ 10385 if (mpt->m_MPI25 && pt->simple == 0) { 10386 mptsas_passthru_ieee_sge(acc_hdl, pt, 10387 (pMpi2IeeeSgeSimple64_t) 10388 ((uint8_t *)request_hdrp + pt->sgl_offset)); 10389 } else { 10390 mptsas_passthru_sge(acc_hdl, pt, 10391 (pMpi2SGESimple64_t) 10392 ((uint8_t *)request_hdrp + pt->sgl_offset)); 10393 } 10394 10395 function = request_hdrp->Function; 10396 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) || 10397 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 10398 pMpi2SCSIIORequest_t scsi_io_req; 10399 caddr_t arsbuf; 10400 uint8_t ars_size; 10401 uint32_t ars_dmaaddrlow; 10402 10403 NDBG15(("mptsas_start_passthru: Is SCSI IO Req")); 10404 scsi_io_req = (pMpi2SCSIIORequest_t)request_hdrp; 10405 10406 if (cmd->cmd_extrqslen != 0) { 10407 /* 10408 * Mapping of the buffer was done in 10409 * mptsas_do_passthru(). 10410 * Calculate the DMA address with the same offset. 10411 */ 10412 arsbuf = cmd->cmd_arq_buf; 10413 ars_size = cmd->cmd_extrqslen; 10414 ars_dmaaddrlow = (mpt->m_req_sense_dma_addr + 10415 ((uintptr_t)arsbuf - (uintptr_t)mpt->m_req_sense)) & 10416 0xffffffffu; 10417 } else { 10418 arsbuf = mpt->m_req_sense + 10419 (mpt->m_req_sense_size * (SMID-1)); 10420 cmd->cmd_arq_buf = arsbuf; 10421 ars_size = mpt->m_req_sense_size; 10422 ars_dmaaddrlow = (mpt->m_req_sense_dma_addr + 10423 (mpt->m_req_sense_size * (SMID-1))) & 10424 0xffffffffu; 10425 } 10426 bzero(arsbuf, ars_size); 10427 10428 ddi_put8(acc_hdl, &scsi_io_req->SenseBufferLength, ars_size); 10429 ddi_put32(acc_hdl, &scsi_io_req->SenseBufferLowAddress, 10430 ars_dmaaddrlow); 10431 10432 /* 10433 * Put SGE for data and data_out buffer at the end of 10434 * scsi_io_request message header.(64 bytes in total) 10435 * Set SGLOffset0 value 10436 */ 10437 ddi_put8(acc_hdl, &scsi_io_req->SGLOffset0, 10438 offsetof(MPI2_SCSI_IO_REQUEST, SGL) / 4); 10439 10440 /* 10441 * Setup descriptor info. RAID passthrough must use the 10442 * default request descriptor which is already set, so if this 10443 * is a SCSI IO request, change the descriptor to SCSI IO. 10444 */ 10445 if (function == MPI2_FUNCTION_SCSI_IO_REQUEST) { 10446 desc_type = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 10447 request_desc = ((uint64_t)ddi_get16(acc_hdl, 10448 &scsi_io_req->DevHandle) << 48); 10449 } 10450 (void) ddi_dma_sync(mpt->m_dma_req_sense_hdl, 0, 0, 10451 DDI_DMA_SYNC_FORDEV); 10452 } 10453 10454 /* 10455 * We must wait till the message has been completed before 10456 * beginning the next message so we wait for this one to 10457 * finish. 10458 */ 10459 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 10460 request_desc |= (SMID << 16) + desc_type; 10461 cmd->cmd_rfm = NULL; 10462 MPTSAS_START_CMD(mpt, request_desc); 10463 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || 10464 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { 10465 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 10466 } 10467 } 10468 10469 typedef void (mptsas_pre_f)(mptsas_t *, mptsas_pt_request_t *); 10470 static mptsas_pre_f mpi_pre_ioc_facts; 10471 static mptsas_pre_f mpi_pre_port_facts; 10472 static mptsas_pre_f mpi_pre_fw_download; 10473 static mptsas_pre_f mpi_pre_fw_25_download; 10474 static mptsas_pre_f mpi_pre_fw_upload; 10475 static mptsas_pre_f mpi_pre_fw_25_upload; 10476 static mptsas_pre_f mpi_pre_sata_passthrough; 10477 static mptsas_pre_f mpi_pre_smp_passthrough; 10478 static mptsas_pre_f mpi_pre_config; 10479 static mptsas_pre_f mpi_pre_sas_io_unit_control; 10480 static mptsas_pre_f mpi_pre_scsi_io_req; 10481 10482 /* 10483 * Prepare the pt for a SAS2 FW_DOWNLOAD request. 10484 */ 10485 static void 10486 mpi_pre_fw_download(mptsas_t *mpt, mptsas_pt_request_t *pt) 10487 { 10488 pMpi2FWDownloadTCSGE_t tcsge; 10489 pMpi2FWDownloadRequest req; 10490 10491 /* 10492 * If SAS3, call separate function. 10493 */ 10494 if (mpt->m_MPI25) { 10495 mpi_pre_fw_25_download(mpt, pt); 10496 return; 10497 } 10498 10499 /* 10500 * User requests should come in with the Transaction 10501 * context element where the SGL will go. Putting the 10502 * SGL after that seems to work, but don't really know 10503 * why. Other drivers tend to create an extra SGL and 10504 * refer to the TCE through that. 10505 */ 10506 req = (pMpi2FWDownloadRequest)pt->request; 10507 tcsge = (pMpi2FWDownloadTCSGE_t)&req->SGL; 10508 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 || 10509 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) { 10510 mptsas_log(mpt, CE_WARN, "FW Download tce invalid!"); 10511 } 10512 10513 pt->sgl_offset = offsetof(MPI2_FW_DOWNLOAD_REQUEST, SGL) + 10514 sizeof (*tcsge); 10515 if (pt->request_size != pt->sgl_offset) 10516 NDBG15(("mpi_pre_fw_download(): Incorrect req size, " 10517 "0x%x, should be 0x%x, dataoutsz 0x%x", 10518 (int)pt->request_size, (int)pt->sgl_offset, 10519 (int)pt->dataout_size)); 10520 if (pt->data_size < sizeof (MPI2_FW_DOWNLOAD_REPLY)) 10521 NDBG15(("mpi_pre_fw_download(): Incorrect rep size, " 10522 "0x%x, should be 0x%x", pt->data_size, 10523 (int)sizeof (MPI2_FW_DOWNLOAD_REPLY))); 10524 } 10525 10526 /* 10527 * Prepare the pt for a SAS3 FW_DOWNLOAD request. 10528 */ 10529 static void 10530 mpi_pre_fw_25_download(mptsas_t *mpt, mptsas_pt_request_t *pt) 10531 { 10532 pMpi2FWDownloadTCSGE_t tcsge; 10533 pMpi2FWDownloadRequest req2; 10534 pMpi25FWDownloadRequest req25; 10535 10536 /* 10537 * User requests should come in with the Transaction 10538 * context element where the SGL will go. The new firmware 10539 * Doesn't use TCE and has space in the main request for 10540 * this information. So move to the right place. 10541 */ 10542 req2 = (pMpi2FWDownloadRequest)pt->request; 10543 req25 = (pMpi25FWDownloadRequest)pt->request; 10544 tcsge = (pMpi2FWDownloadTCSGE_t)&req2->SGL; 10545 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 || 10546 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) { 10547 mptsas_log(mpt, CE_WARN, "FW Download tce invalid!"); 10548 } 10549 req25->ImageOffset = tcsge->ImageOffset; 10550 req25->ImageSize = tcsge->ImageSize; 10551 10552 pt->sgl_offset = offsetof(MPI25_FW_DOWNLOAD_REQUEST, SGL); 10553 if (pt->request_size != pt->sgl_offset) 10554 NDBG15(("mpi_pre_fw_25_download(): Incorrect req size, " 10555 "0x%x, should be 0x%x, dataoutsz 0x%x", 10556 pt->request_size, pt->sgl_offset, 10557 pt->dataout_size)); 10558 if (pt->data_size < sizeof (MPI2_FW_DOWNLOAD_REPLY)) 10559 NDBG15(("mpi_pre_fw_25_download(): Incorrect rep size, " 10560 "0x%x, should be 0x%x", pt->data_size, 10561 (int)sizeof (MPI2_FW_UPLOAD_REPLY))); 10562 } 10563 10564 /* 10565 * Prepare the pt for a SAS2 FW_UPLOAD request. 10566 */ 10567 static void 10568 mpi_pre_fw_upload(mptsas_t *mpt, mptsas_pt_request_t *pt) 10569 { 10570 pMpi2FWUploadTCSGE_t tcsge; 10571 pMpi2FWUploadRequest_t req; 10572 10573 /* 10574 * If SAS3, call separate function. 10575 */ 10576 if (mpt->m_MPI25) { 10577 mpi_pre_fw_25_upload(mpt, pt); 10578 return; 10579 } 10580 10581 /* 10582 * User requests should come in with the Transaction 10583 * context element where the SGL will go. Putting the 10584 * SGL after that seems to work, but don't really know 10585 * why. Other drivers tend to create an extra SGL and 10586 * refer to the TCE through that. 10587 */ 10588 req = (pMpi2FWUploadRequest_t)pt->request; 10589 tcsge = (pMpi2FWUploadTCSGE_t)&req->SGL; 10590 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 || 10591 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) { 10592 mptsas_log(mpt, CE_WARN, "FW Upload tce invalid!"); 10593 } 10594 10595 pt->sgl_offset = offsetof(MPI2_FW_UPLOAD_REQUEST, SGL) + 10596 sizeof (*tcsge); 10597 if (pt->request_size != pt->sgl_offset) 10598 NDBG15(("mpi_pre_fw_upload(): Incorrect req size, " 10599 "0x%x, should be 0x%x, dataoutsz 0x%x", 10600 pt->request_size, pt->sgl_offset, 10601 pt->dataout_size)); 10602 if (pt->data_size < sizeof (MPI2_FW_UPLOAD_REPLY)) 10603 NDBG15(("mpi_pre_fw_upload(): Incorrect rep size, " 10604 "0x%x, should be 0x%x", pt->data_size, 10605 (int)sizeof (MPI2_FW_UPLOAD_REPLY))); 10606 } 10607 10608 /* 10609 * Prepare the pt a SAS3 FW_UPLOAD request. 10610 */ 10611 static void 10612 mpi_pre_fw_25_upload(mptsas_t *mpt, mptsas_pt_request_t *pt) 10613 { 10614 pMpi2FWUploadTCSGE_t tcsge; 10615 pMpi2FWUploadRequest_t req2; 10616 pMpi25FWUploadRequest_t req25; 10617 10618 /* 10619 * User requests should come in with the Transaction 10620 * context element where the SGL will go. The new firmware 10621 * Doesn't use TCE and has space in the main request for 10622 * this information. So move to the right place. 10623 */ 10624 req2 = (pMpi2FWUploadRequest_t)pt->request; 10625 req25 = (pMpi25FWUploadRequest_t)pt->request; 10626 tcsge = (pMpi2FWUploadTCSGE_t)&req2->SGL; 10627 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 || 10628 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) { 10629 mptsas_log(mpt, CE_WARN, "FW Upload tce invalid!"); 10630 } 10631 req25->ImageOffset = tcsge->ImageOffset; 10632 req25->ImageSize = tcsge->ImageSize; 10633 10634 pt->sgl_offset = offsetof(MPI25_FW_UPLOAD_REQUEST, SGL); 10635 if (pt->request_size != pt->sgl_offset) 10636 NDBG15(("mpi_pre_fw_25_upload(): Incorrect req size, " 10637 "0x%x, should be 0x%x, dataoutsz 0x%x", 10638 pt->request_size, pt->sgl_offset, 10639 pt->dataout_size)); 10640 if (pt->data_size < sizeof (MPI2_FW_UPLOAD_REPLY)) 10641 NDBG15(("mpi_pre_fw_25_upload(): Incorrect rep size, " 10642 "0x%x, should be 0x%x", pt->data_size, 10643 (int)sizeof (MPI2_FW_UPLOAD_REPLY))); 10644 } 10645 10646 /* 10647 * Prepare the pt for an IOC_FACTS request. 10648 */ 10649 static void 10650 mpi_pre_ioc_facts(mptsas_t *mpt, mptsas_pt_request_t *pt) 10651 { 10652 #ifndef __lock_lint 10653 _NOTE(ARGUNUSED(mpt)) 10654 #endif 10655 if (pt->request_size != sizeof (MPI2_IOC_FACTS_REQUEST)) 10656 NDBG15(("mpi_pre_ioc_facts(): Incorrect req size, " 10657 "0x%x, should be 0x%x, dataoutsz 0x%x", 10658 pt->request_size, 10659 (int)sizeof (MPI2_IOC_FACTS_REQUEST), 10660 pt->dataout_size)); 10661 if (pt->data_size != sizeof (MPI2_IOC_FACTS_REPLY)) 10662 NDBG15(("mpi_pre_ioc_facts(): Incorrect rep size, " 10663 "0x%x, should be 0x%x", pt->data_size, 10664 (int)sizeof (MPI2_IOC_FACTS_REPLY))); 10665 pt->sgl_offset = (uint16_t)pt->request_size; 10666 } 10667 10668 /* 10669 * Prepare the pt for a PORT_FACTS request. 10670 */ 10671 static void 10672 mpi_pre_port_facts(mptsas_t *mpt, mptsas_pt_request_t *pt) 10673 { 10674 #ifndef __lock_lint 10675 _NOTE(ARGUNUSED(mpt)) 10676 #endif 10677 if (pt->request_size != sizeof (MPI2_PORT_FACTS_REQUEST)) 10678 NDBG15(("mpi_pre_port_facts(): Incorrect req size, " 10679 "0x%x, should be 0x%x, dataoutsz 0x%x", 10680 pt->request_size, 10681 (int)sizeof (MPI2_PORT_FACTS_REQUEST), 10682 pt->dataout_size)); 10683 if (pt->data_size != sizeof (MPI2_PORT_FACTS_REPLY)) 10684 NDBG15(("mpi_pre_port_facts(): Incorrect rep size, " 10685 "0x%x, should be 0x%x", pt->data_size, 10686 (int)sizeof (MPI2_PORT_FACTS_REPLY))); 10687 pt->sgl_offset = (uint16_t)pt->request_size; 10688 } 10689 10690 /* 10691 * Prepare pt for a SATA_PASSTHROUGH request. 10692 */ 10693 static void 10694 mpi_pre_sata_passthrough(mptsas_t *mpt, mptsas_pt_request_t *pt) 10695 { 10696 #ifndef __lock_lint 10697 _NOTE(ARGUNUSED(mpt)) 10698 #endif 10699 pt->sgl_offset = offsetof(MPI2_SATA_PASSTHROUGH_REQUEST, SGL); 10700 if (pt->request_size != pt->sgl_offset) 10701 NDBG15(("mpi_pre_sata_passthrough(): Incorrect req size, " 10702 "0x%x, should be 0x%x, dataoutsz 0x%x", 10703 pt->request_size, pt->sgl_offset, 10704 pt->dataout_size)); 10705 if (pt->data_size != sizeof (MPI2_SATA_PASSTHROUGH_REPLY)) 10706 NDBG15(("mpi_pre_sata_passthrough(): Incorrect rep size, " 10707 "0x%x, should be 0x%x", pt->data_size, 10708 (int)sizeof (MPI2_SATA_PASSTHROUGH_REPLY))); 10709 } 10710 10711 static void 10712 mpi_pre_smp_passthrough(mptsas_t *mpt, mptsas_pt_request_t *pt) 10713 { 10714 #ifndef __lock_lint 10715 _NOTE(ARGUNUSED(mpt)) 10716 #endif 10717 pt->sgl_offset = offsetof(MPI2_SMP_PASSTHROUGH_REQUEST, SGL); 10718 if (pt->request_size != pt->sgl_offset) 10719 NDBG15(("mpi_pre_smp_passthrough(): Incorrect req size, " 10720 "0x%x, should be 0x%x, dataoutsz 0x%x", 10721 pt->request_size, pt->sgl_offset, 10722 pt->dataout_size)); 10723 if (pt->data_size != sizeof (MPI2_SMP_PASSTHROUGH_REPLY)) 10724 NDBG15(("mpi_pre_smp_passthrough(): Incorrect rep size, " 10725 "0x%x, should be 0x%x", pt->data_size, 10726 (int)sizeof (MPI2_SMP_PASSTHROUGH_REPLY))); 10727 } 10728 10729 /* 10730 * Prepare pt for a CONFIG request. 10731 */ 10732 static void 10733 mpi_pre_config(mptsas_t *mpt, mptsas_pt_request_t *pt) 10734 { 10735 #ifndef __lock_lint 10736 _NOTE(ARGUNUSED(mpt)) 10737 #endif 10738 pt->sgl_offset = offsetof(MPI2_CONFIG_REQUEST, PageBufferSGE); 10739 if (pt->request_size != pt->sgl_offset) 10740 NDBG15(("mpi_pre_config(): Incorrect req size, 0x%x, " 10741 "should be 0x%x, dataoutsz 0x%x", pt->request_size, 10742 pt->sgl_offset, pt->dataout_size)); 10743 if (pt->data_size != sizeof (MPI2_CONFIG_REPLY)) 10744 NDBG15(("mpi_pre_config(): Incorrect rep size, 0x%x, " 10745 "should be 0x%x", pt->data_size, 10746 (int)sizeof (MPI2_CONFIG_REPLY))); 10747 pt->simple = 1; 10748 } 10749 10750 /* 10751 * Prepare pt for a SCSI_IO_REQ request. 10752 */ 10753 static void 10754 mpi_pre_scsi_io_req(mptsas_t *mpt, mptsas_pt_request_t *pt) 10755 { 10756 #ifndef __lock_lint 10757 _NOTE(ARGUNUSED(mpt)) 10758 #endif 10759 pt->sgl_offset = offsetof(MPI2_SCSI_IO_REQUEST, SGL); 10760 if (pt->request_size != pt->sgl_offset) 10761 NDBG15(("mpi_pre_config(): Incorrect req size, 0x%x, " 10762 "should be 0x%x, dataoutsz 0x%x", pt->request_size, 10763 pt->sgl_offset, 10764 pt->dataout_size)); 10765 if (pt->data_size != sizeof (MPI2_SCSI_IO_REPLY)) 10766 NDBG15(("mpi_pre_config(): Incorrect rep size, 0x%x, " 10767 "should be 0x%x", pt->data_size, 10768 (int)sizeof (MPI2_SCSI_IO_REPLY))); 10769 } 10770 10771 /* 10772 * Prepare the mptsas_cmd for a SAS_IO_UNIT_CONTROL request. 10773 */ 10774 static void 10775 mpi_pre_sas_io_unit_control(mptsas_t *mpt, mptsas_pt_request_t *pt) 10776 { 10777 #ifndef __lock_lint 10778 _NOTE(ARGUNUSED(mpt)) 10779 #endif 10780 pt->sgl_offset = (uint16_t)pt->request_size; 10781 } 10782 10783 /* 10784 * A set of functions to prepare an mptsas_cmd for the various 10785 * supported requests. 10786 */ 10787 static struct mptsas_func { 10788 U8 Function; 10789 char *Name; 10790 mptsas_pre_f *f_pre; 10791 } mptsas_func_list[] = { 10792 { MPI2_FUNCTION_IOC_FACTS, "IOC_FACTS", mpi_pre_ioc_facts }, 10793 { MPI2_FUNCTION_PORT_FACTS, "PORT_FACTS", mpi_pre_port_facts }, 10794 { MPI2_FUNCTION_FW_DOWNLOAD, "FW_DOWNLOAD", mpi_pre_fw_download }, 10795 { MPI2_FUNCTION_FW_UPLOAD, "FW_UPLOAD", mpi_pre_fw_upload }, 10796 { MPI2_FUNCTION_SATA_PASSTHROUGH, "SATA_PASSTHROUGH", 10797 mpi_pre_sata_passthrough }, 10798 { MPI2_FUNCTION_SMP_PASSTHROUGH, "SMP_PASSTHROUGH", 10799 mpi_pre_smp_passthrough}, 10800 { MPI2_FUNCTION_SCSI_IO_REQUEST, "SCSI_IO_REQUEST", 10801 mpi_pre_scsi_io_req}, 10802 { MPI2_FUNCTION_CONFIG, "CONFIG", mpi_pre_config}, 10803 { MPI2_FUNCTION_SAS_IO_UNIT_CONTROL, "SAS_IO_UNIT_CONTROL", 10804 mpi_pre_sas_io_unit_control }, 10805 { 0xFF, NULL, NULL } /* list end */ 10806 }; 10807 10808 static void 10809 mptsas_prep_sgl_offset(mptsas_t *mpt, mptsas_pt_request_t *pt) 10810 { 10811 pMPI2RequestHeader_t hdr; 10812 struct mptsas_func *f; 10813 10814 hdr = (pMPI2RequestHeader_t)pt->request; 10815 10816 for (f = mptsas_func_list; f->f_pre != NULL; f++) { 10817 if (hdr->Function == f->Function) { 10818 f->f_pre(mpt, pt); 10819 NDBG15(("mptsas_prep_sgl_offset: Function %s," 10820 " sgl_offset 0x%x", f->Name, 10821 pt->sgl_offset)); 10822 return; 10823 } 10824 } 10825 NDBG15(("mptsas_prep_sgl_offset: Unknown Function 0x%02x," 10826 " returning req_size 0x%x for sgl_offset", 10827 hdr->Function, pt->request_size)); 10828 pt->sgl_offset = (uint16_t)pt->request_size; 10829 } 10830 10831 10832 static int 10833 mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply, 10834 uint8_t *data, uint32_t request_size, uint32_t reply_size, 10835 uint32_t data_size, uint32_t direction, uint8_t *dataout, 10836 uint32_t dataout_size, short timeout, int mode) 10837 { 10838 mptsas_pt_request_t pt; 10839 mptsas_dma_alloc_state_t data_dma_state; 10840 mptsas_dma_alloc_state_t dataout_dma_state; 10841 caddr_t memp; 10842 mptsas_cmd_t *cmd = NULL; 10843 struct scsi_pkt *pkt; 10844 uint32_t reply_len = 0, sense_len = 0; 10845 pMPI2RequestHeader_t request_hdrp; 10846 pMPI2RequestHeader_t request_msg; 10847 pMPI2DefaultReply_t reply_msg; 10848 Mpi2SCSIIOReply_t rep_msg; 10849 int rvalue; 10850 int i, status = 0, pt_flags = 0, rv = 0; 10851 uint8_t function; 10852 10853 ASSERT(mutex_owned(&mpt->m_mutex)); 10854 10855 reply_msg = (pMPI2DefaultReply_t)(&rep_msg); 10856 bzero(reply_msg, sizeof (MPI2_DEFAULT_REPLY)); 10857 request_msg = kmem_zalloc(request_size, KM_SLEEP); 10858 10859 mutex_exit(&mpt->m_mutex); 10860 /* 10861 * copy in the request buffer since it could be used by 10862 * another thread when the pt request into waitq 10863 */ 10864 if (ddi_copyin(request, request_msg, request_size, mode)) { 10865 mutex_enter(&mpt->m_mutex); 10866 status = EFAULT; 10867 mptsas_log(mpt, CE_WARN, "failed to copy request data"); 10868 goto out; 10869 } 10870 NDBG27(("mptsas_do_passthru: mode 0x%x, size 0x%x, Func 0x%x", 10871 mode, request_size, request_msg->Function)); 10872 mutex_enter(&mpt->m_mutex); 10873 10874 function = request_msg->Function; 10875 if (function == MPI2_FUNCTION_SCSI_TASK_MGMT) { 10876 pMpi2SCSITaskManagementRequest_t task; 10877 task = (pMpi2SCSITaskManagementRequest_t)request_msg; 10878 mptsas_setup_bus_reset_delay(mpt); 10879 rv = mptsas_ioc_task_management(mpt, task->TaskType, 10880 task->DevHandle, (int)task->LUN[1], reply, reply_size, 10881 mode); 10882 10883 if (rv != TRUE) { 10884 status = EIO; 10885 mptsas_log(mpt, CE_WARN, "task management failed"); 10886 } 10887 goto out; 10888 } 10889 10890 if (data_size != 0) { 10891 data_dma_state.size = data_size; 10892 if (mptsas_dma_alloc(mpt, &data_dma_state) != DDI_SUCCESS) { 10893 status = ENOMEM; 10894 mptsas_log(mpt, CE_WARN, "failed to alloc DMA " 10895 "resource"); 10896 goto out; 10897 } 10898 pt_flags |= MPTSAS_DATA_ALLOCATED; 10899 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) { 10900 mutex_exit(&mpt->m_mutex); 10901 for (i = 0; i < data_size; i++) { 10902 if (ddi_copyin(data + i, (uint8_t *) 10903 data_dma_state.memp + i, 1, mode)) { 10904 mutex_enter(&mpt->m_mutex); 10905 status = EFAULT; 10906 mptsas_log(mpt, CE_WARN, "failed to " 10907 "copy read data"); 10908 goto out; 10909 } 10910 } 10911 mutex_enter(&mpt->m_mutex); 10912 } 10913 } else { 10914 bzero(&data_dma_state, sizeof (data_dma_state)); 10915 } 10916 10917 if (dataout_size != 0) { 10918 dataout_dma_state.size = dataout_size; 10919 if (mptsas_dma_alloc(mpt, &dataout_dma_state) != DDI_SUCCESS) { 10920 status = ENOMEM; 10921 mptsas_log(mpt, CE_WARN, "failed to alloc DMA " 10922 "resource"); 10923 goto out; 10924 } 10925 pt_flags |= MPTSAS_DATAOUT_ALLOCATED; 10926 mutex_exit(&mpt->m_mutex); 10927 for (i = 0; i < dataout_size; i++) { 10928 if (ddi_copyin(dataout + i, (uint8_t *) 10929 dataout_dma_state.memp + i, 1, mode)) { 10930 mutex_enter(&mpt->m_mutex); 10931 mptsas_log(mpt, CE_WARN, "failed to copy out" 10932 " data"); 10933 status = EFAULT; 10934 goto out; 10935 } 10936 } 10937 mutex_enter(&mpt->m_mutex); 10938 } else { 10939 bzero(&dataout_dma_state, sizeof (dataout_dma_state)); 10940 } 10941 10942 if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 10943 status = EAGAIN; 10944 mptsas_log(mpt, CE_NOTE, "event ack command pool is full"); 10945 goto out; 10946 } 10947 pt_flags |= MPTSAS_REQUEST_POOL_CMD; 10948 10949 bzero((caddr_t)cmd, sizeof (*cmd)); 10950 bzero((caddr_t)pkt, scsi_pkt_size()); 10951 bzero((caddr_t)&pt, sizeof (pt)); 10952 10953 cmd->ioc_cmd_slot = (uint32_t)(rvalue); 10954 10955 pt.request = (uint8_t *)request_msg; 10956 pt.direction = direction; 10957 pt.simple = 0; 10958 pt.request_size = request_size; 10959 pt.data_size = data_size; 10960 pt.dataout_size = dataout_size; 10961 pt.data_cookie = data_dma_state.cookie; 10962 pt.dataout_cookie = dataout_dma_state.cookie; 10963 mptsas_prep_sgl_offset(mpt, &pt); 10964 10965 /* 10966 * Form a blank cmd/pkt to store the acknowledgement message 10967 */ 10968 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb[0]; 10969 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; 10970 pkt->pkt_ha_private = (opaque_t)&pt; 10971 pkt->pkt_flags = FLAG_HEAD; 10972 pkt->pkt_time = timeout; 10973 cmd->cmd_pkt = pkt; 10974 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_PASSTHRU; 10975 10976 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) || 10977 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 10978 uint8_t com, cdb_group_id; 10979 boolean_t ret; 10980 10981 pkt->pkt_cdbp = ((pMpi2SCSIIORequest_t)request_msg)->CDB.CDB32; 10982 com = pkt->pkt_cdbp[0]; 10983 cdb_group_id = CDB_GROUPID(com); 10984 switch (cdb_group_id) { 10985 case CDB_GROUPID_0: cmd->cmd_cdblen = CDB_GROUP0; break; 10986 case CDB_GROUPID_1: cmd->cmd_cdblen = CDB_GROUP1; break; 10987 case CDB_GROUPID_2: cmd->cmd_cdblen = CDB_GROUP2; break; 10988 case CDB_GROUPID_4: cmd->cmd_cdblen = CDB_GROUP4; break; 10989 case CDB_GROUPID_5: cmd->cmd_cdblen = CDB_GROUP5; break; 10990 default: 10991 NDBG27(("mptsas_do_passthru: SCSI_IO, reserved " 10992 "CDBGROUP 0x%x requested!", cdb_group_id)); 10993 break; 10994 } 10995 10996 reply_len = sizeof (MPI2_SCSI_IO_REPLY); 10997 sense_len = reply_size - reply_len; 10998 ret = mptsas_cmdarqsize(mpt, cmd, sense_len, KM_SLEEP); 10999 VERIFY(ret == B_TRUE); 11000 } else { 11001 reply_len = reply_size; 11002 sense_len = 0; 11003 } 11004 11005 NDBG27(("mptsas_do_passthru: %s, dsz 0x%x, dosz 0x%x, replen 0x%x, " 11006 "snslen 0x%x", 11007 (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE)?"Write":"Read", 11008 data_size, dataout_size, reply_len, sense_len)); 11009 11010 /* 11011 * Save the command in a slot 11012 */ 11013 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 11014 /* 11015 * Once passthru command get slot, set cmd_flags 11016 * CFLAG_PREPARED. 11017 */ 11018 cmd->cmd_flags |= CFLAG_PREPARED; 11019 mptsas_start_passthru(mpt, cmd); 11020 } else { 11021 mptsas_waitq_add(mpt, cmd); 11022 } 11023 11024 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 11025 cv_wait(&mpt->m_passthru_cv, &mpt->m_mutex); 11026 } 11027 11028 NDBG27(("mptsas_do_passthru: Cmd complete, flags 0x%x, rfm 0x%x " 11029 "pktreason 0x%x", cmd->cmd_flags, cmd->cmd_rfm, 11030 pkt->pkt_reason)); 11031 11032 if (cmd->cmd_flags & CFLAG_PREPARED) { 11033 memp = mpt->m_req_frame + (mpt->m_req_frame_size * 11034 cmd->cmd_slot); 11035 request_hdrp = (pMPI2RequestHeader_t)memp; 11036 } 11037 11038 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 11039 status = ETIMEDOUT; 11040 mptsas_log(mpt, CE_WARN, "passthrough command timeout"); 11041 pt_flags |= MPTSAS_CMD_TIMEOUT; 11042 goto out; 11043 } 11044 11045 if (cmd->cmd_rfm) { 11046 /* 11047 * cmd_rfm is zero means the command reply is a CONTEXT 11048 * reply and no PCI Write to post the free reply SMFA 11049 * because no reply message frame is used. 11050 * cmd_rfm is non-zero means the reply is a ADDRESS 11051 * reply and reply message frame is used. 11052 */ 11053 pt_flags |= MPTSAS_ADDRESS_REPLY; 11054 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 11055 DDI_DMA_SYNC_FORCPU); 11056 reply_msg = (pMPI2DefaultReply_t) 11057 (mpt->m_reply_frame + (cmd->cmd_rfm - 11058 (mpt->m_reply_frame_dma_addr & 0xffffffffu))); 11059 } 11060 11061 mptsas_fma_check(mpt, cmd); 11062 if (pkt->pkt_reason == CMD_TRAN_ERR) { 11063 status = EAGAIN; 11064 mptsas_log(mpt, CE_WARN, "passthru fma error"); 11065 goto out; 11066 } 11067 if (pkt->pkt_reason == CMD_RESET) { 11068 status = EAGAIN; 11069 mptsas_log(mpt, CE_WARN, "ioc reset abort passthru"); 11070 goto out; 11071 } 11072 11073 if (pkt->pkt_reason == CMD_INCOMPLETE) { 11074 status = EIO; 11075 mptsas_log(mpt, CE_WARN, "passthrough command incomplete"); 11076 goto out; 11077 } 11078 11079 mutex_exit(&mpt->m_mutex); 11080 if (cmd->cmd_flags & CFLAG_PREPARED) { 11081 function = request_hdrp->Function; 11082 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) || 11083 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 11084 reply_len = sizeof (MPI2_SCSI_IO_REPLY); 11085 sense_len = cmd->cmd_extrqslen ? 11086 min(sense_len, cmd->cmd_extrqslen) : 11087 min(sense_len, cmd->cmd_rqslen); 11088 } else { 11089 reply_len = reply_size; 11090 sense_len = 0; 11091 } 11092 11093 for (i = 0; i < reply_len; i++) { 11094 if (ddi_copyout((uint8_t *)reply_msg + i, reply + i, 1, 11095 mode)) { 11096 mutex_enter(&mpt->m_mutex); 11097 status = EFAULT; 11098 mptsas_log(mpt, CE_WARN, "failed to copy out " 11099 "reply data"); 11100 goto out; 11101 } 11102 } 11103 for (i = 0; i < sense_len; i++) { 11104 if (ddi_copyout((uint8_t *)request_hdrp + 64 + i, 11105 reply + reply_len + i, 1, mode)) { 11106 mutex_enter(&mpt->m_mutex); 11107 status = EFAULT; 11108 mptsas_log(mpt, CE_WARN, "failed to copy out " 11109 "sense data"); 11110 goto out; 11111 } 11112 } 11113 } 11114 11115 if (data_size) { 11116 if (direction != MPTSAS_PASS_THRU_DIRECTION_WRITE) { 11117 (void) ddi_dma_sync(data_dma_state.handle, 0, 0, 11118 DDI_DMA_SYNC_FORCPU); 11119 for (i = 0; i < data_size; i++) { 11120 if (ddi_copyout((uint8_t *)( 11121 data_dma_state.memp + i), data + i, 1, 11122 mode)) { 11123 mutex_enter(&mpt->m_mutex); 11124 status = EFAULT; 11125 mptsas_log(mpt, CE_WARN, "failed to " 11126 "copy out the reply data"); 11127 goto out; 11128 } 11129 } 11130 } 11131 } 11132 mutex_enter(&mpt->m_mutex); 11133 out: 11134 /* 11135 * Put the reply frame back on the free queue, increment the free 11136 * index, and write the new index to the free index register. But only 11137 * if this reply is an ADDRESS reply. 11138 */ 11139 if (pt_flags & MPTSAS_ADDRESS_REPLY) { 11140 ddi_put32(mpt->m_acc_free_queue_hdl, 11141 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 11142 cmd->cmd_rfm); 11143 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 11144 DDI_DMA_SYNC_FORDEV); 11145 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 11146 mpt->m_free_index = 0; 11147 } 11148 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 11149 mpt->m_free_index); 11150 } 11151 if (cmd) { 11152 if (cmd->cmd_extrqslen != 0) { 11153 rmfree(mpt->m_erqsense_map, cmd->cmd_extrqschunks, 11154 cmd->cmd_extrqsidx + 1); 11155 } 11156 if (cmd->cmd_flags & CFLAG_PREPARED) { 11157 mptsas_remove_cmd(mpt, cmd); 11158 pt_flags &= (~MPTSAS_REQUEST_POOL_CMD); 11159 } 11160 } 11161 if (pt_flags & MPTSAS_REQUEST_POOL_CMD) 11162 mptsas_return_to_pool(mpt, cmd); 11163 if (pt_flags & MPTSAS_DATA_ALLOCATED) { 11164 if (mptsas_check_dma_handle(data_dma_state.handle) != 11165 DDI_SUCCESS) { 11166 ddi_fm_service_impact(mpt->m_dip, 11167 DDI_SERVICE_UNAFFECTED); 11168 status = EFAULT; 11169 } 11170 mptsas_dma_free(&data_dma_state); 11171 } 11172 if (pt_flags & MPTSAS_DATAOUT_ALLOCATED) { 11173 if (mptsas_check_dma_handle(dataout_dma_state.handle) != 11174 DDI_SUCCESS) { 11175 ddi_fm_service_impact(mpt->m_dip, 11176 DDI_SERVICE_UNAFFECTED); 11177 status = EFAULT; 11178 } 11179 mptsas_dma_free(&dataout_dma_state); 11180 } 11181 if (pt_flags & MPTSAS_CMD_TIMEOUT) { 11182 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 11183 mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed"); 11184 } 11185 } 11186 if (request_msg) 11187 kmem_free(request_msg, request_size); 11188 NDBG27(("mptsas_do_passthru: Done status 0x%x", status)); 11189 11190 return (status); 11191 } 11192 11193 static int 11194 mptsas_pass_thru(mptsas_t *mpt, mptsas_pass_thru_t *data, int mode) 11195 { 11196 /* 11197 * If timeout is 0, set timeout to default of 60 seconds. 11198 */ 11199 if (data->Timeout == 0) { 11200 data->Timeout = MPTSAS_PASS_THRU_TIME_DEFAULT; 11201 } 11202 11203 if (((data->DataSize == 0) && 11204 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_NONE)) || 11205 ((data->DataSize != 0) && 11206 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_READ) || 11207 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_WRITE) || 11208 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) && 11209 (data->DataOutSize != 0))))) { 11210 if (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) { 11211 data->DataDirection = MPTSAS_PASS_THRU_DIRECTION_READ; 11212 } else { 11213 data->DataOutSize = 0; 11214 } 11215 /* 11216 * Send passthru request messages 11217 */ 11218 return (mptsas_do_passthru(mpt, 11219 (uint8_t *)((uintptr_t)data->PtrRequest), 11220 (uint8_t *)((uintptr_t)data->PtrReply), 11221 (uint8_t *)((uintptr_t)data->PtrData), 11222 data->RequestSize, data->ReplySize, 11223 data->DataSize, data->DataDirection, 11224 (uint8_t *)((uintptr_t)data->PtrDataOut), 11225 data->DataOutSize, data->Timeout, mode)); 11226 } else { 11227 return (EINVAL); 11228 } 11229 } 11230 11231 static uint8_t 11232 mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, uint32_t unique_id) 11233 { 11234 uint8_t index; 11235 11236 for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) { 11237 if (mpt->m_fw_diag_buffer_list[index].unique_id == unique_id) { 11238 return (index); 11239 } 11240 } 11241 11242 return (MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND); 11243 } 11244 11245 static void 11246 mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd) 11247 { 11248 pMpi2DiagBufferPostRequest_t pDiag_post_msg; 11249 pMpi2DiagReleaseRequest_t pDiag_release_msg; 11250 struct scsi_pkt *pkt = cmd->cmd_pkt; 11251 mptsas_diag_request_t *diag = pkt->pkt_ha_private; 11252 uint32_t i; 11253 uint64_t request_desc; 11254 11255 ASSERT(mutex_owned(&mpt->m_mutex)); 11256 11257 /* 11258 * Form the diag message depending on the post or release function. 11259 */ 11260 if (diag->function == MPI2_FUNCTION_DIAG_BUFFER_POST) { 11261 pDiag_post_msg = (pMpi2DiagBufferPostRequest_t) 11262 (mpt->m_req_frame + (mpt->m_req_frame_size * 11263 cmd->cmd_slot)); 11264 bzero(pDiag_post_msg, mpt->m_req_frame_size); 11265 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->Function, 11266 diag->function); 11267 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->BufferType, 11268 diag->pBuffer->buffer_type); 11269 ddi_put8(mpt->m_acc_req_frame_hdl, 11270 &pDiag_post_msg->ExtendedType, 11271 diag->pBuffer->extended_type); 11272 ddi_put32(mpt->m_acc_req_frame_hdl, 11273 &pDiag_post_msg->BufferLength, 11274 diag->pBuffer->buffer_data.size); 11275 for (i = 0; i < (sizeof (pDiag_post_msg->ProductSpecific) / 4); 11276 i++) { 11277 ddi_put32(mpt->m_acc_req_frame_hdl, 11278 &pDiag_post_msg->ProductSpecific[i], 11279 diag->pBuffer->product_specific[i]); 11280 } 11281 ddi_put32(mpt->m_acc_req_frame_hdl, 11282 &pDiag_post_msg->BufferAddress.Low, 11283 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress 11284 & 0xffffffffull)); 11285 ddi_put32(mpt->m_acc_req_frame_hdl, 11286 &pDiag_post_msg->BufferAddress.High, 11287 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress 11288 >> 32)); 11289 } else { 11290 pDiag_release_msg = (pMpi2DiagReleaseRequest_t) 11291 (mpt->m_req_frame + (mpt->m_req_frame_size * 11292 cmd->cmd_slot)); 11293 bzero(pDiag_release_msg, mpt->m_req_frame_size); 11294 ddi_put8(mpt->m_acc_req_frame_hdl, 11295 &pDiag_release_msg->Function, diag->function); 11296 ddi_put8(mpt->m_acc_req_frame_hdl, 11297 &pDiag_release_msg->BufferType, 11298 diag->pBuffer->buffer_type); 11299 } 11300 11301 /* 11302 * Send the message 11303 */ 11304 (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0, 11305 DDI_DMA_SYNC_FORDEV); 11306 request_desc = (cmd->cmd_slot << 16) + 11307 MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 11308 cmd->cmd_rfm = NULL; 11309 MPTSAS_START_CMD(mpt, request_desc); 11310 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 11311 DDI_SUCCESS) || 11312 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 11313 DDI_SUCCESS)) { 11314 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 11315 } 11316 } 11317 11318 static int 11319 mptsas_post_fw_diag_buffer(mptsas_t *mpt, 11320 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code) 11321 { 11322 mptsas_diag_request_t diag; 11323 int status, slot_num, post_flags = 0; 11324 mptsas_cmd_t *cmd = NULL; 11325 struct scsi_pkt *pkt; 11326 pMpi2DiagBufferPostReply_t reply; 11327 uint16_t iocstatus; 11328 uint32_t iocloginfo, transfer_length; 11329 11330 /* 11331 * If buffer is not enabled, just leave. 11332 */ 11333 *return_code = MPTSAS_FW_DIAG_ERROR_POST_FAILED; 11334 if (!pBuffer->enabled) { 11335 status = DDI_FAILURE; 11336 goto out; 11337 } 11338 11339 /* 11340 * Clear some flags initially. 11341 */ 11342 pBuffer->force_release = FALSE; 11343 pBuffer->valid_data = FALSE; 11344 pBuffer->owned_by_firmware = FALSE; 11345 11346 /* 11347 * Get a cmd buffer from the cmd buffer pool 11348 */ 11349 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 11350 status = DDI_FAILURE; 11351 mptsas_log(mpt, CE_NOTE, "command pool is full: Post FW Diag"); 11352 goto out; 11353 } 11354 post_flags |= MPTSAS_REQUEST_POOL_CMD; 11355 11356 bzero((caddr_t)cmd, sizeof (*cmd)); 11357 bzero((caddr_t)pkt, scsi_pkt_size()); 11358 11359 cmd->ioc_cmd_slot = (uint32_t)(slot_num); 11360 11361 diag.pBuffer = pBuffer; 11362 diag.function = MPI2_FUNCTION_DIAG_BUFFER_POST; 11363 11364 /* 11365 * Form a blank cmd/pkt to store the acknowledgement message 11366 */ 11367 pkt->pkt_ha_private = (opaque_t)&diag; 11368 pkt->pkt_flags = FLAG_HEAD; 11369 pkt->pkt_time = 60; 11370 cmd->cmd_pkt = pkt; 11371 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG; 11372 11373 /* 11374 * Save the command in a slot 11375 */ 11376 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 11377 /* 11378 * Once passthru command get slot, set cmd_flags 11379 * CFLAG_PREPARED. 11380 */ 11381 cmd->cmd_flags |= CFLAG_PREPARED; 11382 mptsas_start_diag(mpt, cmd); 11383 } else { 11384 mptsas_waitq_add(mpt, cmd); 11385 } 11386 11387 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 11388 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex); 11389 } 11390 11391 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 11392 status = DDI_FAILURE; 11393 mptsas_log(mpt, CE_WARN, "Post FW Diag command timeout"); 11394 goto out; 11395 } 11396 11397 /* 11398 * cmd_rfm points to the reply message if a reply was given. Check the 11399 * IOCStatus to make sure everything went OK with the FW diag request 11400 * and set buffer flags. 11401 */ 11402 if (cmd->cmd_rfm) { 11403 post_flags |= MPTSAS_ADDRESS_REPLY; 11404 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 11405 DDI_DMA_SYNC_FORCPU); 11406 reply = (pMpi2DiagBufferPostReply_t)(mpt->m_reply_frame + 11407 (cmd->cmd_rfm - 11408 (mpt->m_reply_frame_dma_addr & 0xffffffffu))); 11409 11410 /* 11411 * Get the reply message data 11412 */ 11413 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 11414 &reply->IOCStatus); 11415 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 11416 &reply->IOCLogInfo); 11417 transfer_length = ddi_get32(mpt->m_acc_reply_frame_hdl, 11418 &reply->TransferLength); 11419 11420 /* 11421 * If post failed quit. 11422 */ 11423 if (iocstatus != MPI2_IOCSTATUS_SUCCESS) { 11424 status = DDI_FAILURE; 11425 NDBG13(("post FW Diag Buffer failed: IOCStatus=0x%x, " 11426 "IOCLogInfo=0x%x, TransferLength=0x%x", iocstatus, 11427 iocloginfo, transfer_length)); 11428 goto out; 11429 } 11430 11431 /* 11432 * Post was successful. 11433 */ 11434 pBuffer->valid_data = TRUE; 11435 pBuffer->owned_by_firmware = TRUE; 11436 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 11437 status = DDI_SUCCESS; 11438 } 11439 11440 out: 11441 /* 11442 * Put the reply frame back on the free queue, increment the free 11443 * index, and write the new index to the free index register. But only 11444 * if this reply is an ADDRESS reply. 11445 */ 11446 if (post_flags & MPTSAS_ADDRESS_REPLY) { 11447 ddi_put32(mpt->m_acc_free_queue_hdl, 11448 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 11449 cmd->cmd_rfm); 11450 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 11451 DDI_DMA_SYNC_FORDEV); 11452 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 11453 mpt->m_free_index = 0; 11454 } 11455 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 11456 mpt->m_free_index); 11457 } 11458 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 11459 mptsas_remove_cmd(mpt, cmd); 11460 post_flags &= (~MPTSAS_REQUEST_POOL_CMD); 11461 } 11462 if (post_flags & MPTSAS_REQUEST_POOL_CMD) { 11463 mptsas_return_to_pool(mpt, cmd); 11464 } 11465 11466 return (status); 11467 } 11468 11469 static int 11470 mptsas_release_fw_diag_buffer(mptsas_t *mpt, 11471 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code, 11472 uint32_t diag_type) 11473 { 11474 mptsas_diag_request_t diag; 11475 int status, slot_num, rel_flags = 0; 11476 mptsas_cmd_t *cmd = NULL; 11477 struct scsi_pkt *pkt; 11478 pMpi2DiagReleaseReply_t reply; 11479 uint16_t iocstatus; 11480 uint32_t iocloginfo; 11481 11482 /* 11483 * If buffer is not enabled, just leave. 11484 */ 11485 *return_code = MPTSAS_FW_DIAG_ERROR_RELEASE_FAILED; 11486 if (!pBuffer->enabled) { 11487 mptsas_log(mpt, CE_NOTE, "This buffer type is not supported " 11488 "by the IOC"); 11489 status = DDI_FAILURE; 11490 goto out; 11491 } 11492 11493 /* 11494 * Clear some flags initially. 11495 */ 11496 pBuffer->force_release = FALSE; 11497 pBuffer->valid_data = FALSE; 11498 pBuffer->owned_by_firmware = FALSE; 11499 11500 /* 11501 * Get a cmd buffer from the cmd buffer pool 11502 */ 11503 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 11504 status = DDI_FAILURE; 11505 mptsas_log(mpt, CE_NOTE, "command pool is full: Release FW " 11506 "Diag"); 11507 goto out; 11508 } 11509 rel_flags |= MPTSAS_REQUEST_POOL_CMD; 11510 11511 bzero((caddr_t)cmd, sizeof (*cmd)); 11512 bzero((caddr_t)pkt, scsi_pkt_size()); 11513 11514 cmd->ioc_cmd_slot = (uint32_t)(slot_num); 11515 11516 diag.pBuffer = pBuffer; 11517 diag.function = MPI2_FUNCTION_DIAG_RELEASE; 11518 11519 /* 11520 * Form a blank cmd/pkt to store the acknowledgement message 11521 */ 11522 pkt->pkt_ha_private = (opaque_t)&diag; 11523 pkt->pkt_flags = FLAG_HEAD; 11524 pkt->pkt_time = 60; 11525 cmd->cmd_pkt = pkt; 11526 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG; 11527 11528 /* 11529 * Save the command in a slot 11530 */ 11531 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 11532 /* 11533 * Once passthru command get slot, set cmd_flags 11534 * CFLAG_PREPARED. 11535 */ 11536 cmd->cmd_flags |= CFLAG_PREPARED; 11537 mptsas_start_diag(mpt, cmd); 11538 } else { 11539 mptsas_waitq_add(mpt, cmd); 11540 } 11541 11542 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 11543 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex); 11544 } 11545 11546 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 11547 status = DDI_FAILURE; 11548 mptsas_log(mpt, CE_WARN, "Release FW Diag command timeout"); 11549 goto out; 11550 } 11551 11552 /* 11553 * cmd_rfm points to the reply message if a reply was given. Check the 11554 * IOCStatus to make sure everything went OK with the FW diag request 11555 * and set buffer flags. 11556 */ 11557 if (cmd->cmd_rfm) { 11558 rel_flags |= MPTSAS_ADDRESS_REPLY; 11559 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 11560 DDI_DMA_SYNC_FORCPU); 11561 reply = (pMpi2DiagReleaseReply_t)(mpt->m_reply_frame + 11562 (cmd->cmd_rfm - 11563 (mpt->m_reply_frame_dma_addr & 0xffffffffu))); 11564 11565 /* 11566 * Get the reply message data 11567 */ 11568 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 11569 &reply->IOCStatus); 11570 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 11571 &reply->IOCLogInfo); 11572 11573 /* 11574 * If release failed quit. 11575 */ 11576 if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) || 11577 pBuffer->owned_by_firmware) { 11578 status = DDI_FAILURE; 11579 NDBG13(("release FW Diag Buffer failed: " 11580 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus, 11581 iocloginfo)); 11582 goto out; 11583 } 11584 11585 /* 11586 * Release was successful. 11587 */ 11588 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 11589 status = DDI_SUCCESS; 11590 11591 /* 11592 * If this was for an UNREGISTER diag type command, clear the 11593 * unique ID. 11594 */ 11595 if (diag_type == MPTSAS_FW_DIAG_TYPE_UNREGISTER) { 11596 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID; 11597 } 11598 } 11599 11600 out: 11601 /* 11602 * Put the reply frame back on the free queue, increment the free 11603 * index, and write the new index to the free index register. But only 11604 * if this reply is an ADDRESS reply. 11605 */ 11606 if (rel_flags & MPTSAS_ADDRESS_REPLY) { 11607 ddi_put32(mpt->m_acc_free_queue_hdl, 11608 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 11609 cmd->cmd_rfm); 11610 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 11611 DDI_DMA_SYNC_FORDEV); 11612 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 11613 mpt->m_free_index = 0; 11614 } 11615 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 11616 mpt->m_free_index); 11617 } 11618 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 11619 mptsas_remove_cmd(mpt, cmd); 11620 rel_flags &= (~MPTSAS_REQUEST_POOL_CMD); 11621 } 11622 if (rel_flags & MPTSAS_REQUEST_POOL_CMD) { 11623 mptsas_return_to_pool(mpt, cmd); 11624 } 11625 11626 return (status); 11627 } 11628 11629 static int 11630 mptsas_diag_register(mptsas_t *mpt, mptsas_fw_diag_register_t *diag_register, 11631 uint32_t *return_code) 11632 { 11633 mptsas_fw_diagnostic_buffer_t *pBuffer; 11634 uint8_t extended_type, buffer_type, i; 11635 uint32_t buffer_size; 11636 uint32_t unique_id; 11637 int status; 11638 11639 ASSERT(mutex_owned(&mpt->m_mutex)); 11640 11641 extended_type = diag_register->ExtendedType; 11642 buffer_type = diag_register->BufferType; 11643 buffer_size = diag_register->RequestedBufferSize; 11644 unique_id = diag_register->UniqueId; 11645 11646 /* 11647 * Check for valid buffer type 11648 */ 11649 if (buffer_type >= MPI2_DIAG_BUF_TYPE_COUNT) { 11650 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11651 return (DDI_FAILURE); 11652 } 11653 11654 /* 11655 * Get the current buffer and look up the unique ID. The unique ID 11656 * should not be found. If it is, the ID is already in use. 11657 */ 11658 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 11659 pBuffer = &mpt->m_fw_diag_buffer_list[buffer_type]; 11660 if (i != MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 11661 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11662 return (DDI_FAILURE); 11663 } 11664 11665 /* 11666 * The buffer's unique ID should not be registered yet, and the given 11667 * unique ID cannot be 0. 11668 */ 11669 if ((pBuffer->unique_id != MPTSAS_FW_DIAG_INVALID_UID) || 11670 (unique_id == MPTSAS_FW_DIAG_INVALID_UID)) { 11671 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11672 return (DDI_FAILURE); 11673 } 11674 11675 /* 11676 * If this buffer is already posted as immediate, just change owner. 11677 */ 11678 if (pBuffer->immediate && pBuffer->owned_by_firmware && 11679 (pBuffer->unique_id == MPTSAS_FW_DIAG_INVALID_UID)) { 11680 pBuffer->immediate = FALSE; 11681 pBuffer->unique_id = unique_id; 11682 return (DDI_SUCCESS); 11683 } 11684 11685 /* 11686 * Post a new buffer after checking if it's enabled. The DMA buffer 11687 * that is allocated will be contiguous (sgl_len = 1). 11688 */ 11689 if (!pBuffer->enabled) { 11690 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER; 11691 return (DDI_FAILURE); 11692 } 11693 bzero(&pBuffer->buffer_data, sizeof (mptsas_dma_alloc_state_t)); 11694 pBuffer->buffer_data.size = buffer_size; 11695 if (mptsas_dma_alloc(mpt, &pBuffer->buffer_data) != DDI_SUCCESS) { 11696 mptsas_log(mpt, CE_WARN, "failed to alloc DMA resource for " 11697 "diag buffer: size = %d bytes", buffer_size); 11698 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER; 11699 return (DDI_FAILURE); 11700 } 11701 11702 /* 11703 * Copy the given info to the diag buffer and post the buffer. 11704 */ 11705 pBuffer->buffer_type = buffer_type; 11706 pBuffer->immediate = FALSE; 11707 if (buffer_type == MPI2_DIAG_BUF_TYPE_TRACE) { 11708 for (i = 0; i < (sizeof (pBuffer->product_specific) / 4); 11709 i++) { 11710 pBuffer->product_specific[i] = 11711 diag_register->ProductSpecific[i]; 11712 } 11713 } 11714 pBuffer->extended_type = extended_type; 11715 pBuffer->unique_id = unique_id; 11716 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, return_code); 11717 11718 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) != 11719 DDI_SUCCESS) { 11720 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed in " 11721 "mptsas_diag_register."); 11722 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 11723 status = DDI_FAILURE; 11724 } 11725 11726 /* 11727 * In case there was a failure, free the DMA buffer. 11728 */ 11729 if (status == DDI_FAILURE) { 11730 mptsas_dma_free(&pBuffer->buffer_data); 11731 } 11732 11733 return (status); 11734 } 11735 11736 static int 11737 mptsas_diag_unregister(mptsas_t *mpt, 11738 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code) 11739 { 11740 mptsas_fw_diagnostic_buffer_t *pBuffer; 11741 uint8_t i; 11742 uint32_t unique_id; 11743 int status; 11744 11745 ASSERT(mutex_owned(&mpt->m_mutex)); 11746 11747 unique_id = diag_unregister->UniqueId; 11748 11749 /* 11750 * Get the current buffer and look up the unique ID. The unique ID 11751 * should be there. 11752 */ 11753 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 11754 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 11755 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11756 return (DDI_FAILURE); 11757 } 11758 11759 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 11760 11761 /* 11762 * Try to release the buffer from FW before freeing it. If release 11763 * fails, don't free the DMA buffer in case FW tries to access it 11764 * later. If buffer is not owned by firmware, can't release it. 11765 */ 11766 if (!pBuffer->owned_by_firmware) { 11767 status = DDI_SUCCESS; 11768 } else { 11769 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, 11770 return_code, MPTSAS_FW_DIAG_TYPE_UNREGISTER); 11771 } 11772 11773 /* 11774 * At this point, return the current status no matter what happens with 11775 * the DMA buffer. 11776 */ 11777 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID; 11778 if (status == DDI_SUCCESS) { 11779 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) != 11780 DDI_SUCCESS) { 11781 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed " 11782 "in mptsas_diag_unregister."); 11783 ddi_fm_service_impact(mpt->m_dip, 11784 DDI_SERVICE_UNAFFECTED); 11785 } 11786 mptsas_dma_free(&pBuffer->buffer_data); 11787 } 11788 11789 return (status); 11790 } 11791 11792 static int 11793 mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query, 11794 uint32_t *return_code) 11795 { 11796 mptsas_fw_diagnostic_buffer_t *pBuffer; 11797 uint8_t i; 11798 uint32_t unique_id; 11799 11800 ASSERT(mutex_owned(&mpt->m_mutex)); 11801 11802 unique_id = diag_query->UniqueId; 11803 11804 /* 11805 * If ID is valid, query on ID. 11806 * If ID is invalid, query on buffer type. 11807 */ 11808 if (unique_id == MPTSAS_FW_DIAG_INVALID_UID) { 11809 i = diag_query->BufferType; 11810 if (i >= MPI2_DIAG_BUF_TYPE_COUNT) { 11811 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11812 return (DDI_FAILURE); 11813 } 11814 } else { 11815 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 11816 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 11817 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11818 return (DDI_FAILURE); 11819 } 11820 } 11821 11822 /* 11823 * Fill query structure with the diag buffer info. 11824 */ 11825 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 11826 diag_query->BufferType = pBuffer->buffer_type; 11827 diag_query->ExtendedType = pBuffer->extended_type; 11828 if (diag_query->BufferType == MPI2_DIAG_BUF_TYPE_TRACE) { 11829 for (i = 0; i < (sizeof (diag_query->ProductSpecific) / 4); 11830 i++) { 11831 diag_query->ProductSpecific[i] = 11832 pBuffer->product_specific[i]; 11833 } 11834 } 11835 diag_query->TotalBufferSize = pBuffer->buffer_data.size; 11836 diag_query->DriverAddedBufferSize = 0; 11837 diag_query->UniqueId = pBuffer->unique_id; 11838 diag_query->ApplicationFlags = 0; 11839 diag_query->DiagnosticFlags = 0; 11840 11841 /* 11842 * Set/Clear application flags 11843 */ 11844 if (pBuffer->immediate) { 11845 diag_query->ApplicationFlags &= ~MPTSAS_FW_DIAG_FLAG_APP_OWNED; 11846 } else { 11847 diag_query->ApplicationFlags |= MPTSAS_FW_DIAG_FLAG_APP_OWNED; 11848 } 11849 if (pBuffer->valid_data || pBuffer->owned_by_firmware) { 11850 diag_query->ApplicationFlags |= 11851 MPTSAS_FW_DIAG_FLAG_BUFFER_VALID; 11852 } else { 11853 diag_query->ApplicationFlags &= 11854 ~MPTSAS_FW_DIAG_FLAG_BUFFER_VALID; 11855 } 11856 if (pBuffer->owned_by_firmware) { 11857 diag_query->ApplicationFlags |= 11858 MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS; 11859 } else { 11860 diag_query->ApplicationFlags &= 11861 ~MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS; 11862 } 11863 11864 return (DDI_SUCCESS); 11865 } 11866 11867 static int 11868 mptsas_diag_read_buffer(mptsas_t *mpt, 11869 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf, 11870 uint32_t *return_code, int ioctl_mode) 11871 { 11872 mptsas_fw_diagnostic_buffer_t *pBuffer; 11873 uint8_t i, *pData; 11874 uint32_t unique_id, byte; 11875 int status; 11876 11877 ASSERT(mutex_owned(&mpt->m_mutex)); 11878 11879 unique_id = diag_read_buffer->UniqueId; 11880 11881 /* 11882 * Get the current buffer and look up the unique ID. The unique ID 11883 * should be there. 11884 */ 11885 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 11886 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 11887 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11888 return (DDI_FAILURE); 11889 } 11890 11891 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 11892 11893 /* 11894 * Make sure requested read is within limits 11895 */ 11896 if (diag_read_buffer->StartingOffset + diag_read_buffer->BytesToRead > 11897 pBuffer->buffer_data.size) { 11898 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11899 return (DDI_FAILURE); 11900 } 11901 11902 /* 11903 * Copy the requested data from DMA to the diag_read_buffer. The DMA 11904 * buffer that was allocated is one contiguous buffer. 11905 */ 11906 pData = (uint8_t *)(pBuffer->buffer_data.memp + 11907 diag_read_buffer->StartingOffset); 11908 (void) ddi_dma_sync(pBuffer->buffer_data.handle, 0, 0, 11909 DDI_DMA_SYNC_FORCPU); 11910 for (byte = 0; byte < diag_read_buffer->BytesToRead; byte++) { 11911 if (ddi_copyout(pData + byte, ioctl_buf + byte, 1, ioctl_mode) 11912 != 0) { 11913 return (DDI_FAILURE); 11914 } 11915 } 11916 diag_read_buffer->Status = 0; 11917 11918 /* 11919 * Set or clear the Force Release flag. 11920 */ 11921 if (pBuffer->force_release) { 11922 diag_read_buffer->Flags |= MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE; 11923 } else { 11924 diag_read_buffer->Flags &= ~MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE; 11925 } 11926 11927 /* 11928 * If buffer is to be reregistered, make sure it's not already owned by 11929 * firmware first. 11930 */ 11931 status = DDI_SUCCESS; 11932 if (!pBuffer->owned_by_firmware) { 11933 if (diag_read_buffer->Flags & MPTSAS_FW_DIAG_FLAG_REREGISTER) { 11934 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, 11935 return_code); 11936 } 11937 } 11938 11939 return (status); 11940 } 11941 11942 static int 11943 mptsas_diag_release(mptsas_t *mpt, mptsas_fw_diag_release_t *diag_release, 11944 uint32_t *return_code) 11945 { 11946 mptsas_fw_diagnostic_buffer_t *pBuffer; 11947 uint8_t i; 11948 uint32_t unique_id; 11949 int status; 11950 11951 ASSERT(mutex_owned(&mpt->m_mutex)); 11952 11953 unique_id = diag_release->UniqueId; 11954 11955 /* 11956 * Get the current buffer and look up the unique ID. The unique ID 11957 * should be there. 11958 */ 11959 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 11960 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 11961 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11962 return (DDI_FAILURE); 11963 } 11964 11965 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 11966 11967 /* 11968 * If buffer is not owned by firmware, it's already been released. 11969 */ 11970 if (!pBuffer->owned_by_firmware) { 11971 *return_code = MPTSAS_FW_DIAG_ERROR_ALREADY_RELEASED; 11972 return (DDI_FAILURE); 11973 } 11974 11975 /* 11976 * Release the buffer. 11977 */ 11978 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, return_code, 11979 MPTSAS_FW_DIAG_TYPE_RELEASE); 11980 return (status); 11981 } 11982 11983 static int 11984 mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, uint8_t *diag_action, 11985 uint32_t length, uint32_t *return_code, int ioctl_mode) 11986 { 11987 mptsas_fw_diag_register_t diag_register; 11988 mptsas_fw_diag_unregister_t diag_unregister; 11989 mptsas_fw_diag_query_t diag_query; 11990 mptsas_diag_read_buffer_t diag_read_buffer; 11991 mptsas_fw_diag_release_t diag_release; 11992 int status = DDI_SUCCESS; 11993 uint32_t original_return_code, read_buf_len; 11994 11995 ASSERT(mutex_owned(&mpt->m_mutex)); 11996 11997 original_return_code = *return_code; 11998 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 11999 12000 switch (action) { 12001 case MPTSAS_FW_DIAG_TYPE_REGISTER: 12002 if (!length) { 12003 *return_code = 12004 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 12005 status = DDI_FAILURE; 12006 break; 12007 } 12008 if (ddi_copyin(diag_action, &diag_register, 12009 sizeof (diag_register), ioctl_mode) != 0) { 12010 return (DDI_FAILURE); 12011 } 12012 status = mptsas_diag_register(mpt, &diag_register, 12013 return_code); 12014 break; 12015 12016 case MPTSAS_FW_DIAG_TYPE_UNREGISTER: 12017 if (length < sizeof (diag_unregister)) { 12018 *return_code = 12019 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 12020 status = DDI_FAILURE; 12021 break; 12022 } 12023 if (ddi_copyin(diag_action, &diag_unregister, 12024 sizeof (diag_unregister), ioctl_mode) != 0) { 12025 return (DDI_FAILURE); 12026 } 12027 status = mptsas_diag_unregister(mpt, &diag_unregister, 12028 return_code); 12029 break; 12030 12031 case MPTSAS_FW_DIAG_TYPE_QUERY: 12032 if (length < sizeof (diag_query)) { 12033 *return_code = 12034 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 12035 status = DDI_FAILURE; 12036 break; 12037 } 12038 if (ddi_copyin(diag_action, &diag_query, 12039 sizeof (diag_query), ioctl_mode) != 0) { 12040 return (DDI_FAILURE); 12041 } 12042 status = mptsas_diag_query(mpt, &diag_query, 12043 return_code); 12044 if (status == DDI_SUCCESS) { 12045 if (ddi_copyout(&diag_query, diag_action, 12046 sizeof (diag_query), ioctl_mode) != 0) { 12047 return (DDI_FAILURE); 12048 } 12049 } 12050 break; 12051 12052 case MPTSAS_FW_DIAG_TYPE_READ_BUFFER: 12053 if (ddi_copyin(diag_action, &diag_read_buffer, 12054 sizeof (diag_read_buffer) - 4, ioctl_mode) != 0) { 12055 return (DDI_FAILURE); 12056 } 12057 read_buf_len = sizeof (diag_read_buffer) - 12058 sizeof (diag_read_buffer.DataBuffer) + 12059 diag_read_buffer.BytesToRead; 12060 if (length < read_buf_len) { 12061 *return_code = 12062 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 12063 status = DDI_FAILURE; 12064 break; 12065 } 12066 status = mptsas_diag_read_buffer(mpt, 12067 &diag_read_buffer, diag_action + 12068 sizeof (diag_read_buffer) - 4, return_code, 12069 ioctl_mode); 12070 if (status == DDI_SUCCESS) { 12071 if (ddi_copyout(&diag_read_buffer, diag_action, 12072 sizeof (diag_read_buffer) - 4, ioctl_mode) 12073 != 0) { 12074 return (DDI_FAILURE); 12075 } 12076 } 12077 break; 12078 12079 case MPTSAS_FW_DIAG_TYPE_RELEASE: 12080 if (length < sizeof (diag_release)) { 12081 *return_code = 12082 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 12083 status = DDI_FAILURE; 12084 break; 12085 } 12086 if (ddi_copyin(diag_action, &diag_release, 12087 sizeof (diag_release), ioctl_mode) != 0) { 12088 return (DDI_FAILURE); 12089 } 12090 status = mptsas_diag_release(mpt, &diag_release, 12091 return_code); 12092 break; 12093 12094 default: 12095 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 12096 status = DDI_FAILURE; 12097 break; 12098 } 12099 12100 if ((status == DDI_FAILURE) && 12101 (original_return_code == MPTSAS_FW_DIAG_NEW) && 12102 (*return_code != MPTSAS_FW_DIAG_ERROR_SUCCESS)) { 12103 status = DDI_SUCCESS; 12104 } 12105 12106 return (status); 12107 } 12108 12109 static int 12110 mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *user_data, int mode) 12111 { 12112 int status; 12113 mptsas_diag_action_t driver_data; 12114 12115 ASSERT(mutex_owned(&mpt->m_mutex)); 12116 12117 /* 12118 * Copy the user data to a driver data buffer. 12119 */ 12120 if (ddi_copyin(user_data, &driver_data, sizeof (mptsas_diag_action_t), 12121 mode) == 0) { 12122 /* 12123 * Send diag action request if Action is valid 12124 */ 12125 if (driver_data.Action == MPTSAS_FW_DIAG_TYPE_REGISTER || 12126 driver_data.Action == MPTSAS_FW_DIAG_TYPE_UNREGISTER || 12127 driver_data.Action == MPTSAS_FW_DIAG_TYPE_QUERY || 12128 driver_data.Action == MPTSAS_FW_DIAG_TYPE_READ_BUFFER || 12129 driver_data.Action == MPTSAS_FW_DIAG_TYPE_RELEASE) { 12130 status = mptsas_do_diag_action(mpt, driver_data.Action, 12131 (void *)(uintptr_t)driver_data.PtrDiagAction, 12132 driver_data.Length, &driver_data.ReturnCode, 12133 mode); 12134 if (status == DDI_SUCCESS) { 12135 if (ddi_copyout(&driver_data.ReturnCode, 12136 &user_data->ReturnCode, 12137 sizeof (user_data->ReturnCode), mode) 12138 != 0) { 12139 status = EFAULT; 12140 } else { 12141 status = 0; 12142 } 12143 } else { 12144 status = EIO; 12145 } 12146 } else { 12147 status = EINVAL; 12148 } 12149 } else { 12150 status = EFAULT; 12151 } 12152 12153 return (status); 12154 } 12155 12156 /* 12157 * This routine handles the "event query" ioctl. 12158 */ 12159 static int 12160 mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, int mode, 12161 int *rval) 12162 { 12163 int status; 12164 mptsas_event_query_t driverdata; 12165 uint8_t i; 12166 12167 driverdata.Entries = MPTSAS_EVENT_QUEUE_SIZE; 12168 12169 mutex_enter(&mpt->m_mutex); 12170 for (i = 0; i < 4; i++) { 12171 driverdata.Types[i] = mpt->m_event_mask[i]; 12172 } 12173 mutex_exit(&mpt->m_mutex); 12174 12175 if (ddi_copyout(&driverdata, data, sizeof (driverdata), mode) != 0) { 12176 status = EFAULT; 12177 } else { 12178 *rval = MPTIOCTL_STATUS_GOOD; 12179 status = 0; 12180 } 12181 12182 return (status); 12183 } 12184 12185 /* 12186 * This routine handles the "event enable" ioctl. 12187 */ 12188 static int 12189 mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, int mode, 12190 int *rval) 12191 { 12192 int status; 12193 mptsas_event_enable_t driverdata; 12194 uint8_t i; 12195 12196 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) { 12197 mutex_enter(&mpt->m_mutex); 12198 for (i = 0; i < 4; i++) { 12199 mpt->m_event_mask[i] = driverdata.Types[i]; 12200 } 12201 mutex_exit(&mpt->m_mutex); 12202 12203 *rval = MPTIOCTL_STATUS_GOOD; 12204 status = 0; 12205 } else { 12206 status = EFAULT; 12207 } 12208 return (status); 12209 } 12210 12211 /* 12212 * This routine handles the "event report" ioctl. 12213 */ 12214 static int 12215 mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, int mode, 12216 int *rval) 12217 { 12218 int status; 12219 mptsas_event_report_t driverdata; 12220 12221 mutex_enter(&mpt->m_mutex); 12222 12223 if (ddi_copyin(&data->Size, &driverdata.Size, sizeof (driverdata.Size), 12224 mode) == 0) { 12225 if (driverdata.Size >= sizeof (mpt->m_events)) { 12226 if (ddi_copyout(mpt->m_events, data->Events, 12227 sizeof (mpt->m_events), mode) != 0) { 12228 status = EFAULT; 12229 } else { 12230 if (driverdata.Size > sizeof (mpt->m_events)) { 12231 driverdata.Size = 12232 sizeof (mpt->m_events); 12233 if (ddi_copyout(&driverdata.Size, 12234 &data->Size, 12235 sizeof (driverdata.Size), 12236 mode) != 0) { 12237 status = EFAULT; 12238 } else { 12239 *rval = MPTIOCTL_STATUS_GOOD; 12240 status = 0; 12241 } 12242 } else { 12243 *rval = MPTIOCTL_STATUS_GOOD; 12244 status = 0; 12245 } 12246 } 12247 } else { 12248 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT; 12249 status = 0; 12250 } 12251 } else { 12252 status = EFAULT; 12253 } 12254 12255 mutex_exit(&mpt->m_mutex); 12256 return (status); 12257 } 12258 12259 static void 12260 mptsas_lookup_pci_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data) 12261 { 12262 int *reg_data; 12263 uint_t reglen; 12264 12265 /* 12266 * Lookup the 'reg' property and extract the other data 12267 */ 12268 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip, 12269 DDI_PROP_DONTPASS, "reg", ®_data, ®len) == 12270 DDI_PROP_SUCCESS) { 12271 /* 12272 * Extract the PCI data from the 'reg' property first DWORD. 12273 * The entry looks like the following: 12274 * First DWORD: 12275 * Bits 0 - 7 8-bit Register number 12276 * Bits 8 - 10 3-bit Function number 12277 * Bits 11 - 15 5-bit Device number 12278 * Bits 16 - 23 8-bit Bus number 12279 * Bits 24 - 25 2-bit Address Space type identifier 12280 * 12281 */ 12282 adapter_data->PciInformation.u.bits.BusNumber = 12283 (reg_data[0] & 0x00FF0000) >> 16; 12284 adapter_data->PciInformation.u.bits.DeviceNumber = 12285 (reg_data[0] & 0x0000F800) >> 11; 12286 adapter_data->PciInformation.u.bits.FunctionNumber = 12287 (reg_data[0] & 0x00000700) >> 8; 12288 ddi_prop_free((void *)reg_data); 12289 } else { 12290 /* 12291 * If we can't determine the PCI data then we fill in FF's for 12292 * the data to indicate this. 12293 */ 12294 adapter_data->PCIDeviceHwId = 0xFFFFFFFF; 12295 adapter_data->MpiPortNumber = 0xFFFFFFFF; 12296 adapter_data->PciInformation.u.AsDWORD = 0xFFFFFFFF; 12297 } 12298 12299 /* 12300 * Saved in the mpt->m_fwversion 12301 */ 12302 adapter_data->MpiFirmwareVersion = mpt->m_fwversion; 12303 } 12304 12305 static void 12306 mptsas_read_adapter_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data) 12307 { 12308 char *driver_verstr = MPTSAS_MOD_STRING; 12309 12310 mptsas_lookup_pci_data(mpt, adapter_data); 12311 adapter_data->AdapterType = mpt->m_MPI25 ? 12312 MPTIOCTL_ADAPTER_TYPE_SAS3 : 12313 MPTIOCTL_ADAPTER_TYPE_SAS2; 12314 adapter_data->PCIDeviceHwId = (uint32_t)mpt->m_devid; 12315 adapter_data->PCIDeviceHwRev = (uint32_t)mpt->m_revid; 12316 adapter_data->SubSystemId = (uint32_t)mpt->m_ssid; 12317 adapter_data->SubsystemVendorId = (uint32_t)mpt->m_svid; 12318 (void) strcpy((char *)&adapter_data->DriverVersion[0], driver_verstr); 12319 adapter_data->BiosVersion = 0; 12320 (void) mptsas_get_bios_page3(mpt, &adapter_data->BiosVersion); 12321 } 12322 12323 static void 12324 mptsas_read_pci_info(mptsas_t *mpt, mptsas_pci_info_t *pci_info) 12325 { 12326 int *reg_data, i; 12327 uint_t reglen; 12328 12329 /* 12330 * Lookup the 'reg' property and extract the other data 12331 */ 12332 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip, 12333 DDI_PROP_DONTPASS, "reg", ®_data, ®len) == 12334 DDI_PROP_SUCCESS) { 12335 /* 12336 * Extract the PCI data from the 'reg' property first DWORD. 12337 * The entry looks like the following: 12338 * First DWORD: 12339 * Bits 8 - 10 3-bit Function number 12340 * Bits 11 - 15 5-bit Device number 12341 * Bits 16 - 23 8-bit Bus number 12342 */ 12343 pci_info->BusNumber = (reg_data[0] & 0x00FF0000) >> 16; 12344 pci_info->DeviceNumber = (reg_data[0] & 0x0000F800) >> 11; 12345 pci_info->FunctionNumber = (reg_data[0] & 0x00000700) >> 8; 12346 ddi_prop_free((void *)reg_data); 12347 } else { 12348 /* 12349 * If we can't determine the PCI info then we fill in FF's for 12350 * the data to indicate this. 12351 */ 12352 pci_info->BusNumber = 0xFFFFFFFF; 12353 pci_info->DeviceNumber = 0xFF; 12354 pci_info->FunctionNumber = 0xFF; 12355 } 12356 12357 /* 12358 * Now get the interrupt vector and the pci header. The vector can 12359 * only be 0 right now. The header is the first 256 bytes of config 12360 * space. 12361 */ 12362 pci_info->InterruptVector = 0; 12363 for (i = 0; i < sizeof (pci_info->PciHeader); i++) { 12364 pci_info->PciHeader[i] = pci_config_get8(mpt->m_config_handle, 12365 i); 12366 } 12367 } 12368 12369 static int 12370 mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, int mode) 12371 { 12372 int status = 0; 12373 mptsas_reg_access_t driverdata; 12374 12375 mutex_enter(&mpt->m_mutex); 12376 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) { 12377 switch (driverdata.Command) { 12378 /* 12379 * IO access is not supported. 12380 */ 12381 case REG_IO_READ: 12382 case REG_IO_WRITE: 12383 mptsas_log(mpt, CE_WARN, "IO access is not " 12384 "supported. Use memory access."); 12385 status = EINVAL; 12386 break; 12387 12388 case REG_MEM_READ: 12389 driverdata.RegData = ddi_get32(mpt->m_datap, 12390 (uint32_t *)(void *)mpt->m_reg + 12391 driverdata.RegOffset); 12392 if (ddi_copyout(&driverdata.RegData, 12393 &data->RegData, 12394 sizeof (driverdata.RegData), mode) != 0) { 12395 mptsas_log(mpt, CE_WARN, "Register " 12396 "Read Failed"); 12397 status = EFAULT; 12398 } 12399 break; 12400 12401 case REG_MEM_WRITE: 12402 ddi_put32(mpt->m_datap, 12403 (uint32_t *)(void *)mpt->m_reg + 12404 driverdata.RegOffset, 12405 driverdata.RegData); 12406 break; 12407 12408 default: 12409 status = EINVAL; 12410 break; 12411 } 12412 } else { 12413 status = EFAULT; 12414 } 12415 12416 mutex_exit(&mpt->m_mutex); 12417 return (status); 12418 } 12419 12420 static int 12421 led_control(mptsas_t *mpt, intptr_t data, int mode) 12422 { 12423 int ret = 0; 12424 mptsas_led_control_t lc; 12425 mptsas_target_t *ptgt; 12426 12427 if (ddi_copyin((void *)data, &lc, sizeof (lc), mode) != 0) { 12428 return (EFAULT); 12429 } 12430 12431 if ((lc.Command != MPTSAS_LEDCTL_FLAG_SET && 12432 lc.Command != MPTSAS_LEDCTL_FLAG_GET) || 12433 lc.Led < MPTSAS_LEDCTL_LED_MIN || 12434 lc.Led > MPTSAS_LEDCTL_LED_MAX || 12435 (lc.Command == MPTSAS_LEDCTL_FLAG_SET && lc.LedStatus != 0 && 12436 lc.LedStatus != 1)) { 12437 return (EINVAL); 12438 } 12439 12440 if ((lc.Command == MPTSAS_LEDCTL_FLAG_SET && (mode & FWRITE) == 0) || 12441 (lc.Command == MPTSAS_LEDCTL_FLAG_GET && (mode & FREAD) == 0)) 12442 return (EACCES); 12443 12444 /* Locate the target we're interrogating... */ 12445 mutex_enter(&mpt->m_mutex); 12446 ptgt = refhash_linear_search(mpt->m_targets, 12447 mptsas_target_eval_slot, &lc); 12448 if (ptgt == NULL) { 12449 /* We could not find a target for that enclosure/slot. */ 12450 mutex_exit(&mpt->m_mutex); 12451 return (ENOENT); 12452 } 12453 12454 if (lc.Command == MPTSAS_LEDCTL_FLAG_SET) { 12455 /* Update our internal LED state. */ 12456 ptgt->m_led_status &= ~(1 << (lc.Led - 1)); 12457 ptgt->m_led_status |= lc.LedStatus << (lc.Led - 1); 12458 12459 /* Flush it to the controller. */ 12460 ret = mptsas_flush_led_status(mpt, ptgt); 12461 mutex_exit(&mpt->m_mutex); 12462 return (ret); 12463 } 12464 12465 /* Return our internal LED state. */ 12466 lc.LedStatus = (ptgt->m_led_status >> (lc.Led - 1)) & 1; 12467 mutex_exit(&mpt->m_mutex); 12468 12469 if (ddi_copyout(&lc, (void *)data, sizeof (lc), mode) != 0) { 12470 return (EFAULT); 12471 } 12472 12473 return (0); 12474 } 12475 12476 static int 12477 get_disk_info(mptsas_t *mpt, intptr_t data, int mode) 12478 { 12479 uint16_t i = 0; 12480 uint16_t count = 0; 12481 int ret = 0; 12482 mptsas_target_t *ptgt; 12483 mptsas_disk_info_t *di; 12484 STRUCT_DECL(mptsas_get_disk_info, gdi); 12485 12486 if ((mode & FREAD) == 0) 12487 return (EACCES); 12488 12489 STRUCT_INIT(gdi, get_udatamodel()); 12490 12491 if (ddi_copyin((void *)data, STRUCT_BUF(gdi), STRUCT_SIZE(gdi), 12492 mode) != 0) { 12493 return (EFAULT); 12494 } 12495 12496 /* Find out how many targets there are. */ 12497 mutex_enter(&mpt->m_mutex); 12498 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 12499 ptgt = refhash_next(mpt->m_targets, ptgt)) { 12500 count++; 12501 } 12502 mutex_exit(&mpt->m_mutex); 12503 12504 /* 12505 * If we haven't been asked to copy out information on each target, 12506 * then just return the count. 12507 */ 12508 STRUCT_FSET(gdi, DiskCount, count); 12509 if (STRUCT_FGETP(gdi, PtrDiskInfoArray) == NULL) 12510 goto copy_out; 12511 12512 /* 12513 * If we haven't been given a large enough buffer to copy out into, 12514 * let the caller know. 12515 */ 12516 if (STRUCT_FGET(gdi, DiskInfoArraySize) < 12517 count * sizeof (mptsas_disk_info_t)) { 12518 ret = ENOSPC; 12519 goto copy_out; 12520 } 12521 12522 di = kmem_zalloc(count * sizeof (mptsas_disk_info_t), KM_SLEEP); 12523 12524 mutex_enter(&mpt->m_mutex); 12525 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 12526 ptgt = refhash_next(mpt->m_targets, ptgt)) { 12527 if (i >= count) { 12528 /* 12529 * The number of targets changed while we weren't 12530 * looking, so give up. 12531 */ 12532 refhash_rele(mpt->m_targets, ptgt); 12533 mutex_exit(&mpt->m_mutex); 12534 kmem_free(di, count * sizeof (mptsas_disk_info_t)); 12535 return (EAGAIN); 12536 } 12537 di[i].Instance = mpt->m_instance; 12538 di[i].Enclosure = ptgt->m_enclosure; 12539 di[i].Slot = ptgt->m_slot_num; 12540 di[i].SasAddress = ptgt->m_addr.mta_wwn; 12541 i++; 12542 } 12543 mutex_exit(&mpt->m_mutex); 12544 STRUCT_FSET(gdi, DiskCount, i); 12545 12546 /* Copy out the disk information to the caller. */ 12547 if (ddi_copyout((void *)di, STRUCT_FGETP(gdi, PtrDiskInfoArray), 12548 i * sizeof (mptsas_disk_info_t), mode) != 0) { 12549 ret = EFAULT; 12550 } 12551 12552 kmem_free(di, count * sizeof (mptsas_disk_info_t)); 12553 12554 copy_out: 12555 if (ddi_copyout(STRUCT_BUF(gdi), (void *)data, STRUCT_SIZE(gdi), 12556 mode) != 0) { 12557 ret = EFAULT; 12558 } 12559 12560 return (ret); 12561 } 12562 12563 static int 12564 mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp, 12565 int *rval) 12566 { 12567 int status = 0; 12568 mptsas_t *mpt; 12569 mptsas_update_flash_t flashdata; 12570 mptsas_pass_thru_t passthru_data; 12571 mptsas_adapter_data_t adapter_data; 12572 mptsas_pci_info_t pci_info; 12573 int copylen; 12574 12575 int iport_flag = 0; 12576 dev_info_t *dip = NULL; 12577 mptsas_phymask_t phymask = 0; 12578 struct devctl_iocdata *dcp = NULL; 12579 char *addr = NULL; 12580 mptsas_target_t *ptgt = NULL; 12581 12582 *rval = MPTIOCTL_STATUS_GOOD; 12583 if (secpolicy_sys_config(credp, B_FALSE) != 0) { 12584 return (EPERM); 12585 } 12586 12587 mpt = ddi_get_soft_state(mptsas_state, MINOR2INST(getminor(dev))); 12588 if (mpt == NULL) { 12589 /* 12590 * Called from iport node, get the states 12591 */ 12592 iport_flag = 1; 12593 dip = mptsas_get_dip_from_dev(dev, &phymask); 12594 if (dip == NULL) { 12595 return (ENXIO); 12596 } 12597 mpt = DIP2MPT(dip); 12598 } 12599 /* Make sure power level is D0 before accessing registers */ 12600 mutex_enter(&mpt->m_mutex); 12601 if (mpt->m_options & MPTSAS_OPT_PM) { 12602 (void) pm_busy_component(mpt->m_dip, 0); 12603 if (mpt->m_power_level != PM_LEVEL_D0) { 12604 mutex_exit(&mpt->m_mutex); 12605 if (pm_raise_power(mpt->m_dip, 0, PM_LEVEL_D0) != 12606 DDI_SUCCESS) { 12607 mptsas_log(mpt, CE_WARN, 12608 "mptsas%d: mptsas_ioctl: Raise power " 12609 "request failed.", mpt->m_instance); 12610 (void) pm_idle_component(mpt->m_dip, 0); 12611 return (ENXIO); 12612 } 12613 } else { 12614 mutex_exit(&mpt->m_mutex); 12615 } 12616 } else { 12617 mutex_exit(&mpt->m_mutex); 12618 } 12619 12620 if (iport_flag) { 12621 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, rval); 12622 if (status != 0) { 12623 goto out; 12624 } 12625 /* 12626 * The following code control the OK2RM LED, it doesn't affect 12627 * the ioctl return status. 12628 */ 12629 if ((cmd == DEVCTL_DEVICE_ONLINE) || 12630 (cmd == DEVCTL_DEVICE_OFFLINE)) { 12631 if (ndi_dc_allochdl((void *)data, &dcp) != 12632 NDI_SUCCESS) { 12633 goto out; 12634 } 12635 addr = ndi_dc_getaddr(dcp); 12636 ptgt = mptsas_addr_to_ptgt(mpt, addr, phymask); 12637 if (ptgt == NULL) { 12638 NDBG14(("mptsas_ioctl led control: tgt %s not " 12639 "found", addr)); 12640 ndi_dc_freehdl(dcp); 12641 goto out; 12642 } 12643 mutex_enter(&mpt->m_mutex); 12644 if (cmd == DEVCTL_DEVICE_ONLINE) { 12645 ptgt->m_tgt_unconfigured = 0; 12646 } else if (cmd == DEVCTL_DEVICE_OFFLINE) { 12647 ptgt->m_tgt_unconfigured = 1; 12648 } 12649 if (cmd == DEVCTL_DEVICE_OFFLINE) { 12650 ptgt->m_led_status |= 12651 (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1)); 12652 } else { 12653 ptgt->m_led_status &= 12654 ~(1 << (MPTSAS_LEDCTL_LED_OK2RM - 1)); 12655 } 12656 (void) mptsas_flush_led_status(mpt, ptgt); 12657 mutex_exit(&mpt->m_mutex); 12658 ndi_dc_freehdl(dcp); 12659 } 12660 goto out; 12661 } 12662 switch (cmd) { 12663 case MPTIOCTL_GET_DISK_INFO: 12664 status = get_disk_info(mpt, data, mode); 12665 break; 12666 case MPTIOCTL_LED_CONTROL: 12667 status = led_control(mpt, data, mode); 12668 break; 12669 case MPTIOCTL_UPDATE_FLASH: 12670 if (ddi_copyin((void *)data, &flashdata, 12671 sizeof (struct mptsas_update_flash), mode)) { 12672 status = EFAULT; 12673 break; 12674 } 12675 12676 mutex_enter(&mpt->m_mutex); 12677 if (mptsas_update_flash(mpt, 12678 (caddr_t)(long)flashdata.PtrBuffer, 12679 flashdata.ImageSize, flashdata.ImageType, mode)) { 12680 status = EFAULT; 12681 } 12682 12683 /* 12684 * Reset the chip to start using the new 12685 * firmware. Reset if failed also. 12686 */ 12687 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 12688 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) { 12689 status = EFAULT; 12690 } 12691 mutex_exit(&mpt->m_mutex); 12692 break; 12693 case MPTIOCTL_PASS_THRU: 12694 /* 12695 * The user has requested to pass through a command to 12696 * be executed by the MPT firmware. Call our routine 12697 * which does this. Only allow one passthru IOCTL at 12698 * one time. Other threads will block on 12699 * m_passthru_mutex, which is of adaptive variant. 12700 */ 12701 if (ddi_copyin((void *)data, &passthru_data, 12702 sizeof (mptsas_pass_thru_t), mode)) { 12703 status = EFAULT; 12704 break; 12705 } 12706 mutex_enter(&mpt->m_passthru_mutex); 12707 mutex_enter(&mpt->m_mutex); 12708 status = mptsas_pass_thru(mpt, &passthru_data, mode); 12709 mutex_exit(&mpt->m_mutex); 12710 mutex_exit(&mpt->m_passthru_mutex); 12711 12712 break; 12713 case MPTIOCTL_GET_ADAPTER_DATA: 12714 /* 12715 * The user has requested to read adapter data. Call 12716 * our routine which does this. 12717 */ 12718 bzero(&adapter_data, sizeof (mptsas_adapter_data_t)); 12719 if (ddi_copyin((void *)data, (void *)&adapter_data, 12720 sizeof (mptsas_adapter_data_t), mode)) { 12721 status = EFAULT; 12722 break; 12723 } 12724 if (adapter_data.StructureLength >= 12725 sizeof (mptsas_adapter_data_t)) { 12726 adapter_data.StructureLength = (uint32_t) 12727 sizeof (mptsas_adapter_data_t); 12728 copylen = sizeof (mptsas_adapter_data_t); 12729 mutex_enter(&mpt->m_mutex); 12730 mptsas_read_adapter_data(mpt, &adapter_data); 12731 mutex_exit(&mpt->m_mutex); 12732 } else { 12733 adapter_data.StructureLength = (uint32_t) 12734 sizeof (mptsas_adapter_data_t); 12735 copylen = sizeof (adapter_data.StructureLength); 12736 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT; 12737 } 12738 if (ddi_copyout((void *)(&adapter_data), (void *)data, 12739 copylen, mode) != 0) { 12740 status = EFAULT; 12741 } 12742 break; 12743 case MPTIOCTL_GET_PCI_INFO: 12744 /* 12745 * The user has requested to read pci info. Call 12746 * our routine which does this. 12747 */ 12748 bzero(&pci_info, sizeof (mptsas_pci_info_t)); 12749 mutex_enter(&mpt->m_mutex); 12750 mptsas_read_pci_info(mpt, &pci_info); 12751 mutex_exit(&mpt->m_mutex); 12752 if (ddi_copyout((void *)(&pci_info), (void *)data, 12753 sizeof (mptsas_pci_info_t), mode) != 0) { 12754 status = EFAULT; 12755 } 12756 break; 12757 case MPTIOCTL_RESET_ADAPTER: 12758 mutex_enter(&mpt->m_mutex); 12759 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 12760 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 12761 mptsas_log(mpt, CE_WARN, "reset adapter IOCTL " 12762 "failed"); 12763 status = EFAULT; 12764 } 12765 mutex_exit(&mpt->m_mutex); 12766 break; 12767 case MPTIOCTL_DIAG_ACTION: 12768 /* 12769 * The user has done a diag buffer action. Call our 12770 * routine which does this. Only allow one diag action 12771 * at one time. 12772 */ 12773 mutex_enter(&mpt->m_mutex); 12774 if (mpt->m_diag_action_in_progress) { 12775 mutex_exit(&mpt->m_mutex); 12776 return (EBUSY); 12777 } 12778 mpt->m_diag_action_in_progress = 1; 12779 status = mptsas_diag_action(mpt, 12780 (mptsas_diag_action_t *)data, mode); 12781 mpt->m_diag_action_in_progress = 0; 12782 mutex_exit(&mpt->m_mutex); 12783 break; 12784 case MPTIOCTL_EVENT_QUERY: 12785 /* 12786 * The user has done an event query. Call our routine 12787 * which does this. 12788 */ 12789 status = mptsas_event_query(mpt, 12790 (mptsas_event_query_t *)data, mode, rval); 12791 break; 12792 case MPTIOCTL_EVENT_ENABLE: 12793 /* 12794 * The user has done an event enable. Call our routine 12795 * which does this. 12796 */ 12797 status = mptsas_event_enable(mpt, 12798 (mptsas_event_enable_t *)data, mode, rval); 12799 break; 12800 case MPTIOCTL_EVENT_REPORT: 12801 /* 12802 * The user has done an event report. Call our routine 12803 * which does this. 12804 */ 12805 status = mptsas_event_report(mpt, 12806 (mptsas_event_report_t *)data, mode, rval); 12807 break; 12808 case MPTIOCTL_REG_ACCESS: 12809 /* 12810 * The user has requested register access. Call our 12811 * routine which does this. 12812 */ 12813 status = mptsas_reg_access(mpt, 12814 (mptsas_reg_access_t *)data, mode); 12815 break; 12816 default: 12817 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, 12818 rval); 12819 break; 12820 } 12821 12822 out: 12823 return (status); 12824 } 12825 12826 int 12827 mptsas_restart_ioc(mptsas_t *mpt) 12828 { 12829 int rval = DDI_SUCCESS; 12830 mptsas_target_t *ptgt = NULL; 12831 12832 ASSERT(mutex_owned(&mpt->m_mutex)); 12833 12834 /* 12835 * Set a flag telling I/O path that we're processing a reset. This is 12836 * needed because after the reset is complete, the hash table still 12837 * needs to be rebuilt. If I/Os are started before the hash table is 12838 * rebuilt, I/O errors will occur. This flag allows I/Os to be marked 12839 * so that they can be retried. 12840 */ 12841 mpt->m_in_reset = TRUE; 12842 12843 /* 12844 * Wait until all the allocated sense data buffers for DMA are freed. 12845 */ 12846 while (mpt->m_extreq_sense_refcount > 0) 12847 cv_wait(&mpt->m_extreq_sense_refcount_cv, &mpt->m_mutex); 12848 12849 /* 12850 * Set all throttles to HOLD 12851 */ 12852 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 12853 ptgt = refhash_next(mpt->m_targets, ptgt)) { 12854 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 12855 } 12856 12857 /* 12858 * Disable interrupts 12859 */ 12860 MPTSAS_DISABLE_INTR(mpt); 12861 12862 /* 12863 * Abort all commands: outstanding commands, commands in waitq and 12864 * tx_waitq. 12865 */ 12866 mptsas_flush_hba(mpt); 12867 12868 /* 12869 * Reinitialize the chip. 12870 */ 12871 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) { 12872 rval = DDI_FAILURE; 12873 } 12874 12875 /* 12876 * Enable interrupts again 12877 */ 12878 MPTSAS_ENABLE_INTR(mpt); 12879 12880 /* 12881 * If mptsas_init_chip was successful, update the driver data. 12882 */ 12883 if (rval == DDI_SUCCESS) { 12884 mptsas_update_driver_data(mpt); 12885 } 12886 12887 /* 12888 * Reset the throttles 12889 */ 12890 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 12891 ptgt = refhash_next(mpt->m_targets, ptgt)) { 12892 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 12893 } 12894 12895 mptsas_doneq_empty(mpt); 12896 mptsas_restart_hba(mpt); 12897 12898 if (rval != DDI_SUCCESS) { 12899 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 12900 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 12901 } 12902 12903 /* 12904 * Clear the reset flag so that I/Os can continue. 12905 */ 12906 mpt->m_in_reset = FALSE; 12907 12908 return (rval); 12909 } 12910 12911 static int 12912 mptsas_init_chip(mptsas_t *mpt, int first_time) 12913 { 12914 ddi_dma_cookie_t cookie; 12915 uint32_t i; 12916 int rval; 12917 12918 /* 12919 * Check to see if the firmware image is valid 12920 */ 12921 if (ddi_get32(mpt->m_datap, &mpt->m_reg->HostDiagnostic) & 12922 MPI2_DIAG_FLASH_BAD_SIG) { 12923 mptsas_log(mpt, CE_WARN, "mptsas bad flash signature!"); 12924 goto fail; 12925 } 12926 12927 /* 12928 * Reset the chip 12929 */ 12930 rval = mptsas_ioc_reset(mpt, first_time); 12931 if (rval == MPTSAS_RESET_FAIL) { 12932 mptsas_log(mpt, CE_WARN, "hard reset failed!"); 12933 goto fail; 12934 } 12935 12936 if ((rval == MPTSAS_SUCCESS_MUR) && (!first_time)) { 12937 goto mur; 12938 } 12939 /* 12940 * Setup configuration space 12941 */ 12942 if (mptsas_config_space_init(mpt) == FALSE) { 12943 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init " 12944 "failed!"); 12945 goto fail; 12946 } 12947 12948 /* 12949 * IOC facts can change after a diag reset so all buffers that are 12950 * based on these numbers must be de-allocated and re-allocated. Get 12951 * new IOC facts each time chip is initialized. 12952 */ 12953 if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) { 12954 mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed"); 12955 goto fail; 12956 } 12957 12958 if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) { 12959 goto fail; 12960 } 12961 /* 12962 * Allocate request message frames, reply free queue, reply descriptor 12963 * post queue, and reply message frames using latest IOC facts. 12964 */ 12965 if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) { 12966 mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed"); 12967 goto fail; 12968 } 12969 if (mptsas_alloc_sense_bufs(mpt) == DDI_FAILURE) { 12970 mptsas_log(mpt, CE_WARN, "mptsas_alloc_sense_bufs failed"); 12971 goto fail; 12972 } 12973 if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) { 12974 mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue failed!"); 12975 goto fail; 12976 } 12977 if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) { 12978 mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue failed!"); 12979 goto fail; 12980 } 12981 if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) { 12982 mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames failed!"); 12983 goto fail; 12984 } 12985 12986 mur: 12987 /* 12988 * Re-Initialize ioc to operational state 12989 */ 12990 if (mptsas_ioc_init(mpt) == DDI_FAILURE) { 12991 mptsas_log(mpt, CE_WARN, "mptsas_ioc_init failed"); 12992 goto fail; 12993 } 12994 12995 mptsas_alloc_reply_args(mpt); 12996 12997 /* 12998 * Initialize reply post index. Reply free index is initialized after 12999 * the next loop. 13000 */ 13001 mpt->m_post_index = 0; 13002 13003 /* 13004 * Initialize the Reply Free Queue with the physical addresses of our 13005 * reply frames. 13006 */ 13007 cookie.dmac_address = mpt->m_reply_frame_dma_addr & 0xffffffffu; 13008 for (i = 0; i < mpt->m_max_replies; i++) { 13009 ddi_put32(mpt->m_acc_free_queue_hdl, 13010 &((uint32_t *)(void *)mpt->m_free_queue)[i], 13011 cookie.dmac_address); 13012 cookie.dmac_address += mpt->m_reply_frame_size; 13013 } 13014 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 13015 DDI_DMA_SYNC_FORDEV); 13016 13017 /* 13018 * Initialize the reply free index to one past the last frame on the 13019 * queue. This will signify that the queue is empty to start with. 13020 */ 13021 mpt->m_free_index = i; 13022 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, i); 13023 13024 /* 13025 * Initialize the reply post queue to 0xFFFFFFFF,0xFFFFFFFF's. 13026 */ 13027 for (i = 0; i < mpt->m_post_queue_depth; i++) { 13028 ddi_put64(mpt->m_acc_post_queue_hdl, 13029 &((uint64_t *)(void *)mpt->m_post_queue)[i], 13030 0xFFFFFFFFFFFFFFFF); 13031 } 13032 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 13033 DDI_DMA_SYNC_FORDEV); 13034 13035 /* 13036 * Enable ports 13037 */ 13038 if (mptsas_ioc_enable_port(mpt) == DDI_FAILURE) { 13039 mptsas_log(mpt, CE_WARN, "mptsas_ioc_enable_port failed"); 13040 goto fail; 13041 } 13042 13043 /* 13044 * enable events 13045 */ 13046 if (mptsas_ioc_enable_event_notification(mpt)) { 13047 mptsas_log(mpt, CE_WARN, 13048 "mptsas_ioc_enable_event_notification failed"); 13049 goto fail; 13050 } 13051 13052 /* 13053 * We need checks in attach and these. 13054 * chip_init is called in mult. places 13055 */ 13056 13057 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 13058 DDI_SUCCESS) || 13059 (mptsas_check_dma_handle(mpt->m_dma_req_sense_hdl) != 13060 DDI_SUCCESS) || 13061 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) != 13062 DDI_SUCCESS) || 13063 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) != 13064 DDI_SUCCESS) || 13065 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) != 13066 DDI_SUCCESS) || 13067 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) != 13068 DDI_SUCCESS)) { 13069 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 13070 goto fail; 13071 } 13072 13073 /* Check all acc handles */ 13074 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) || 13075 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 13076 DDI_SUCCESS) || 13077 (mptsas_check_acc_handle(mpt->m_acc_req_sense_hdl) != 13078 DDI_SUCCESS) || 13079 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) != 13080 DDI_SUCCESS) || 13081 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) != 13082 DDI_SUCCESS) || 13083 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) != 13084 DDI_SUCCESS) || 13085 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) != 13086 DDI_SUCCESS) || 13087 (mptsas_check_acc_handle(mpt->m_config_handle) != 13088 DDI_SUCCESS)) { 13089 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 13090 goto fail; 13091 } 13092 13093 return (DDI_SUCCESS); 13094 13095 fail: 13096 return (DDI_FAILURE); 13097 } 13098 13099 static int 13100 mptsas_get_pci_cap(mptsas_t *mpt) 13101 { 13102 ushort_t caps_ptr, cap, cap_count; 13103 13104 if (mpt->m_config_handle == NULL) 13105 return (FALSE); 13106 /* 13107 * Check if capabilities list is supported and if so, 13108 * get initial capabilities pointer and clear bits 0,1. 13109 */ 13110 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) 13111 & PCI_STAT_CAP) { 13112 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle, 13113 PCI_CONF_CAP_PTR), 4); 13114 } else { 13115 caps_ptr = PCI_CAP_NEXT_PTR_NULL; 13116 } 13117 13118 /* 13119 * Walk capabilities if supported. 13120 */ 13121 for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) { 13122 13123 /* 13124 * Check that we haven't exceeded the maximum number of 13125 * capabilities and that the pointer is in a valid range. 13126 */ 13127 if (++cap_count > 48) { 13128 mptsas_log(mpt, CE_WARN, 13129 "too many device capabilities.\n"); 13130 break; 13131 } 13132 if (caps_ptr < 64) { 13133 mptsas_log(mpt, CE_WARN, 13134 "capabilities pointer 0x%x out of range.\n", 13135 caps_ptr); 13136 break; 13137 } 13138 13139 /* 13140 * Get next capability and check that it is valid. 13141 * For now, we only support power management. 13142 */ 13143 cap = pci_config_get8(mpt->m_config_handle, caps_ptr); 13144 switch (cap) { 13145 case PCI_CAP_ID_PM: 13146 mptsas_log(mpt, CE_NOTE, 13147 "?mptsas%d supports power management.\n", 13148 mpt->m_instance); 13149 mpt->m_options |= MPTSAS_OPT_PM; 13150 13151 /* Save PMCSR offset */ 13152 mpt->m_pmcsr_offset = caps_ptr + PCI_PMCSR; 13153 break; 13154 /* 13155 * The following capabilities are valid. Any others 13156 * will cause a message to be logged. 13157 */ 13158 case PCI_CAP_ID_VPD: 13159 case PCI_CAP_ID_MSI: 13160 case PCI_CAP_ID_PCIX: 13161 case PCI_CAP_ID_PCI_E: 13162 case PCI_CAP_ID_MSI_X: 13163 break; 13164 default: 13165 mptsas_log(mpt, CE_NOTE, 13166 "?mptsas%d unrecognized capability " 13167 "0x%x.\n", mpt->m_instance, cap); 13168 break; 13169 } 13170 13171 /* 13172 * Get next capabilities pointer and clear bits 0,1. 13173 */ 13174 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle, 13175 (caps_ptr + PCI_CAP_NEXT_PTR)), 4); 13176 } 13177 return (TRUE); 13178 } 13179 13180 static int 13181 mptsas_init_pm(mptsas_t *mpt) 13182 { 13183 char pmc_name[16]; 13184 char *pmc[] = { 13185 NULL, 13186 "0=Off (PCI D3 State)", 13187 "3=On (PCI D0 State)", 13188 NULL 13189 }; 13190 uint16_t pmcsr_stat; 13191 13192 if (mptsas_get_pci_cap(mpt) == FALSE) { 13193 return (DDI_FAILURE); 13194 } 13195 /* 13196 * If PCI's capability does not support PM, then don't need 13197 * to registe the pm-components 13198 */ 13199 if (!(mpt->m_options & MPTSAS_OPT_PM)) 13200 return (DDI_SUCCESS); 13201 /* 13202 * If power management is supported by this chip, create 13203 * pm-components property for the power management framework 13204 */ 13205 (void) sprintf(pmc_name, "NAME=mptsas%d", mpt->m_instance); 13206 pmc[0] = pmc_name; 13207 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, mpt->m_dip, 13208 "pm-components", pmc, 3) != DDI_PROP_SUCCESS) { 13209 mpt->m_options &= ~MPTSAS_OPT_PM; 13210 mptsas_log(mpt, CE_WARN, 13211 "mptsas%d: pm-component property creation failed.", 13212 mpt->m_instance); 13213 return (DDI_FAILURE); 13214 } 13215 13216 /* 13217 * Power on device. 13218 */ 13219 (void) pm_busy_component(mpt->m_dip, 0); 13220 pmcsr_stat = pci_config_get16(mpt->m_config_handle, 13221 mpt->m_pmcsr_offset); 13222 if ((pmcsr_stat & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_D0) { 13223 mptsas_log(mpt, CE_WARN, "mptsas%d: Power up the device", 13224 mpt->m_instance); 13225 pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset, 13226 PCI_PMCSR_D0); 13227 } 13228 if (pm_power_has_changed(mpt->m_dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) { 13229 mptsas_log(mpt, CE_WARN, "pm_power_has_changed failed"); 13230 return (DDI_FAILURE); 13231 } 13232 mpt->m_power_level = PM_LEVEL_D0; 13233 /* 13234 * Set pm idle delay. 13235 */ 13236 mpt->m_pm_idle_delay = ddi_prop_get_int(DDI_DEV_T_ANY, 13237 mpt->m_dip, 0, "mptsas-pm-idle-delay", MPTSAS_PM_IDLE_TIMEOUT); 13238 13239 return (DDI_SUCCESS); 13240 } 13241 13242 static int 13243 mptsas_register_intrs(mptsas_t *mpt) 13244 { 13245 dev_info_t *dip; 13246 int intr_types; 13247 13248 dip = mpt->m_dip; 13249 13250 /* Get supported interrupt types */ 13251 if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) { 13252 mptsas_log(mpt, CE_WARN, "ddi_intr_get_supported_types " 13253 "failed\n"); 13254 return (FALSE); 13255 } 13256 13257 NDBG6(("ddi_intr_get_supported_types() returned: 0x%x", intr_types)); 13258 13259 /* 13260 * Try MSI, but fall back to FIXED 13261 */ 13262 if (mptsas_enable_msi && (intr_types & DDI_INTR_TYPE_MSI)) { 13263 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_MSI) == DDI_SUCCESS) { 13264 NDBG0(("Using MSI interrupt type")); 13265 mpt->m_intr_type = DDI_INTR_TYPE_MSI; 13266 return (TRUE); 13267 } 13268 } 13269 if (intr_types & DDI_INTR_TYPE_FIXED) { 13270 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_FIXED) == DDI_SUCCESS) { 13271 NDBG0(("Using FIXED interrupt type")); 13272 mpt->m_intr_type = DDI_INTR_TYPE_FIXED; 13273 return (TRUE); 13274 } else { 13275 NDBG0(("FIXED interrupt registration failed")); 13276 return (FALSE); 13277 } 13278 } 13279 13280 return (FALSE); 13281 } 13282 13283 static void 13284 mptsas_unregister_intrs(mptsas_t *mpt) 13285 { 13286 mptsas_rem_intrs(mpt); 13287 } 13288 13289 /* 13290 * mptsas_add_intrs: 13291 * 13292 * Register FIXED or MSI interrupts. 13293 */ 13294 static int 13295 mptsas_add_intrs(mptsas_t *mpt, int intr_type) 13296 { 13297 dev_info_t *dip = mpt->m_dip; 13298 int avail, actual, count = 0; 13299 int i, flag, ret; 13300 13301 NDBG6(("mptsas_add_intrs:interrupt type 0x%x", intr_type)); 13302 13303 /* Get number of interrupts */ 13304 ret = ddi_intr_get_nintrs(dip, intr_type, &count); 13305 if ((ret != DDI_SUCCESS) || (count <= 0)) { 13306 mptsas_log(mpt, CE_WARN, "ddi_intr_get_nintrs() failed, " 13307 "ret %d count %d\n", ret, count); 13308 13309 return (DDI_FAILURE); 13310 } 13311 13312 /* Get number of available interrupts */ 13313 ret = ddi_intr_get_navail(dip, intr_type, &avail); 13314 if ((ret != DDI_SUCCESS) || (avail == 0)) { 13315 mptsas_log(mpt, CE_WARN, "ddi_intr_get_navail() failed, " 13316 "ret %d avail %d\n", ret, avail); 13317 13318 return (DDI_FAILURE); 13319 } 13320 13321 if (avail < count) { 13322 mptsas_log(mpt, CE_NOTE, "ddi_intr_get_nvail returned %d, " 13323 "navail() returned %d", count, avail); 13324 } 13325 13326 /* Mpt only have one interrupt routine */ 13327 if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) { 13328 count = 1; 13329 } 13330 13331 /* Allocate an array of interrupt handles */ 13332 mpt->m_intr_size = count * sizeof (ddi_intr_handle_t); 13333 mpt->m_htable = kmem_alloc(mpt->m_intr_size, KM_SLEEP); 13334 13335 flag = DDI_INTR_ALLOC_NORMAL; 13336 13337 /* call ddi_intr_alloc() */ 13338 ret = ddi_intr_alloc(dip, mpt->m_htable, intr_type, 0, 13339 count, &actual, flag); 13340 13341 if ((ret != DDI_SUCCESS) || (actual == 0)) { 13342 mptsas_log(mpt, CE_WARN, "ddi_intr_alloc() failed, ret %d\n", 13343 ret); 13344 kmem_free(mpt->m_htable, mpt->m_intr_size); 13345 return (DDI_FAILURE); 13346 } 13347 13348 /* use interrupt count returned or abort? */ 13349 if (actual < count) { 13350 mptsas_log(mpt, CE_NOTE, "Requested: %d, Received: %d\n", 13351 count, actual); 13352 } 13353 13354 mpt->m_intr_cnt = actual; 13355 13356 /* 13357 * Get priority for first msi, assume remaining are all the same 13358 */ 13359 if ((ret = ddi_intr_get_pri(mpt->m_htable[0], 13360 &mpt->m_intr_pri)) != DDI_SUCCESS) { 13361 mptsas_log(mpt, CE_WARN, "ddi_intr_get_pri() failed %d\n", ret); 13362 13363 /* Free already allocated intr */ 13364 for (i = 0; i < actual; i++) { 13365 (void) ddi_intr_free(mpt->m_htable[i]); 13366 } 13367 13368 kmem_free(mpt->m_htable, mpt->m_intr_size); 13369 return (DDI_FAILURE); 13370 } 13371 13372 /* Test for high level mutex */ 13373 if (mpt->m_intr_pri >= ddi_intr_get_hilevel_pri()) { 13374 mptsas_log(mpt, CE_WARN, "mptsas_add_intrs: " 13375 "Hi level interrupt not supported\n"); 13376 13377 /* Free already allocated intr */ 13378 for (i = 0; i < actual; i++) { 13379 (void) ddi_intr_free(mpt->m_htable[i]); 13380 } 13381 13382 kmem_free(mpt->m_htable, mpt->m_intr_size); 13383 return (DDI_FAILURE); 13384 } 13385 13386 /* Call ddi_intr_add_handler() */ 13387 for (i = 0; i < actual; i++) { 13388 if ((ret = ddi_intr_add_handler(mpt->m_htable[i], mptsas_intr, 13389 (caddr_t)mpt, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) { 13390 mptsas_log(mpt, CE_WARN, "ddi_intr_add_handler() " 13391 "failed %d\n", ret); 13392 13393 /* Free already allocated intr */ 13394 for (i = 0; i < actual; i++) { 13395 (void) ddi_intr_free(mpt->m_htable[i]); 13396 } 13397 13398 kmem_free(mpt->m_htable, mpt->m_intr_size); 13399 return (DDI_FAILURE); 13400 } 13401 } 13402 13403 if ((ret = ddi_intr_get_cap(mpt->m_htable[0], &mpt->m_intr_cap)) 13404 != DDI_SUCCESS) { 13405 mptsas_log(mpt, CE_WARN, "ddi_intr_get_cap() failed %d\n", ret); 13406 13407 /* Free already allocated intr */ 13408 for (i = 0; i < actual; i++) { 13409 (void) ddi_intr_free(mpt->m_htable[i]); 13410 } 13411 13412 kmem_free(mpt->m_htable, mpt->m_intr_size); 13413 return (DDI_FAILURE); 13414 } 13415 13416 /* 13417 * Enable interrupts 13418 */ 13419 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) { 13420 /* Call ddi_intr_block_enable() for MSI interrupts */ 13421 (void) ddi_intr_block_enable(mpt->m_htable, mpt->m_intr_cnt); 13422 } else { 13423 /* Call ddi_intr_enable for MSI or FIXED interrupts */ 13424 for (i = 0; i < mpt->m_intr_cnt; i++) { 13425 (void) ddi_intr_enable(mpt->m_htable[i]); 13426 } 13427 } 13428 return (DDI_SUCCESS); 13429 } 13430 13431 /* 13432 * mptsas_rem_intrs: 13433 * 13434 * Unregister FIXED or MSI interrupts 13435 */ 13436 static void 13437 mptsas_rem_intrs(mptsas_t *mpt) 13438 { 13439 int i; 13440 13441 NDBG6(("mptsas_rem_intrs")); 13442 13443 /* Disable all interrupts */ 13444 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) { 13445 /* Call ddi_intr_block_disable() */ 13446 (void) ddi_intr_block_disable(mpt->m_htable, mpt->m_intr_cnt); 13447 } else { 13448 for (i = 0; i < mpt->m_intr_cnt; i++) { 13449 (void) ddi_intr_disable(mpt->m_htable[i]); 13450 } 13451 } 13452 13453 /* Call ddi_intr_remove_handler() */ 13454 for (i = 0; i < mpt->m_intr_cnt; i++) { 13455 (void) ddi_intr_remove_handler(mpt->m_htable[i]); 13456 (void) ddi_intr_free(mpt->m_htable[i]); 13457 } 13458 13459 kmem_free(mpt->m_htable, mpt->m_intr_size); 13460 } 13461 13462 /* 13463 * The IO fault service error handling callback function 13464 */ 13465 /*ARGSUSED*/ 13466 static int 13467 mptsas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data) 13468 { 13469 /* 13470 * as the driver can always deal with an error in any dma or 13471 * access handle, we can just return the fme_status value. 13472 */ 13473 pci_ereport_post(dip, err, NULL); 13474 return (err->fme_status); 13475 } 13476 13477 /* 13478 * mptsas_fm_init - initialize fma capabilities and register with IO 13479 * fault services. 13480 */ 13481 static void 13482 mptsas_fm_init(mptsas_t *mpt) 13483 { 13484 /* 13485 * Need to change iblock to priority for new MSI intr 13486 */ 13487 ddi_iblock_cookie_t fm_ibc; 13488 13489 /* Only register with IO Fault Services if we have some capability */ 13490 if (mpt->m_fm_capabilities) { 13491 /* Adjust access and dma attributes for FMA */ 13492 mpt->m_reg_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC; 13493 mpt->m_msg_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 13494 mpt->m_io_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 13495 13496 /* 13497 * Register capabilities with IO Fault Services. 13498 * mpt->m_fm_capabilities will be updated to indicate 13499 * capabilities actually supported (not requested.) 13500 */ 13501 ddi_fm_init(mpt->m_dip, &mpt->m_fm_capabilities, &fm_ibc); 13502 13503 /* 13504 * Initialize pci ereport capabilities if ereport 13505 * capable (should always be.) 13506 */ 13507 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) || 13508 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 13509 pci_ereport_setup(mpt->m_dip); 13510 } 13511 13512 /* 13513 * Register error callback if error callback capable. 13514 */ 13515 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 13516 ddi_fm_handler_register(mpt->m_dip, 13517 mptsas_fm_error_cb, (void *) mpt); 13518 } 13519 } 13520 } 13521 13522 /* 13523 * mptsas_fm_fini - Releases fma capabilities and un-registers with IO 13524 * fault services. 13525 * 13526 */ 13527 static void 13528 mptsas_fm_fini(mptsas_t *mpt) 13529 { 13530 /* Only unregister FMA capabilities if registered */ 13531 if (mpt->m_fm_capabilities) { 13532 13533 /* 13534 * Un-register error callback if error callback capable. 13535 */ 13536 13537 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 13538 ddi_fm_handler_unregister(mpt->m_dip); 13539 } 13540 13541 /* 13542 * Release any resources allocated by pci_ereport_setup() 13543 */ 13544 13545 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) || 13546 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 13547 pci_ereport_teardown(mpt->m_dip); 13548 } 13549 13550 /* Unregister from IO Fault Services */ 13551 ddi_fm_fini(mpt->m_dip); 13552 13553 /* Adjust access and dma attributes for FMA */ 13554 mpt->m_reg_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC; 13555 mpt->m_msg_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 13556 mpt->m_io_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 13557 13558 } 13559 } 13560 13561 int 13562 mptsas_check_acc_handle(ddi_acc_handle_t handle) 13563 { 13564 ddi_fm_error_t de; 13565 13566 if (handle == NULL) 13567 return (DDI_FAILURE); 13568 ddi_fm_acc_err_get(handle, &de, DDI_FME_VER0); 13569 return (de.fme_status); 13570 } 13571 13572 int 13573 mptsas_check_dma_handle(ddi_dma_handle_t handle) 13574 { 13575 ddi_fm_error_t de; 13576 13577 if (handle == NULL) 13578 return (DDI_FAILURE); 13579 ddi_fm_dma_err_get(handle, &de, DDI_FME_VER0); 13580 return (de.fme_status); 13581 } 13582 13583 void 13584 mptsas_fm_ereport(mptsas_t *mpt, char *detail) 13585 { 13586 uint64_t ena; 13587 char buf[FM_MAX_CLASS]; 13588 13589 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail); 13590 ena = fm_ena_generate(0, FM_ENA_FMT1); 13591 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities)) { 13592 ddi_fm_ereport_post(mpt->m_dip, buf, ena, DDI_NOSLEEP, 13593 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL); 13594 } 13595 } 13596 13597 static int 13598 mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address, 13599 uint16_t *dev_handle, mptsas_target_t **pptgt) 13600 { 13601 int rval; 13602 uint32_t dev_info; 13603 uint64_t sas_wwn; 13604 mptsas_phymask_t phymask; 13605 uint8_t physport, phynum, config, disk; 13606 uint64_t devicename; 13607 uint16_t pdev_hdl; 13608 mptsas_target_t *tmp_tgt = NULL; 13609 uint16_t bay_num, enclosure, io_flags; 13610 13611 ASSERT(*pptgt == NULL); 13612 13613 rval = mptsas_get_sas_device_page0(mpt, page_address, dev_handle, 13614 &sas_wwn, &dev_info, &physport, &phynum, &pdev_hdl, 13615 &bay_num, &enclosure, &io_flags); 13616 if (rval != DDI_SUCCESS) { 13617 rval = DEV_INFO_FAIL_PAGE0; 13618 return (rval); 13619 } 13620 13621 if ((dev_info & (MPI2_SAS_DEVICE_INFO_SSP_TARGET | 13622 MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 13623 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) == NULL) { 13624 rval = DEV_INFO_WRONG_DEVICE_TYPE; 13625 return (rval); 13626 } 13627 13628 /* 13629 * Check if the dev handle is for a Phys Disk. If so, set return value 13630 * and exit. Don't add Phys Disks to hash. 13631 */ 13632 for (config = 0; config < mpt->m_num_raid_configs; config++) { 13633 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) { 13634 if (*dev_handle == mpt->m_raidconfig[config]. 13635 m_physdisk_devhdl[disk]) { 13636 rval = DEV_INFO_PHYS_DISK; 13637 return (rval); 13638 } 13639 } 13640 } 13641 13642 /* 13643 * Get SATA Device Name from SAS device page0 for 13644 * sata device, if device name doesn't exist, set mta_wwn to 13645 * 0 for direct attached SATA. For the device behind the expander 13646 * we still can use STP address assigned by expander. 13647 */ 13648 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 13649 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 13650 /* alloc a temporary target to send the cmd to */ 13651 tmp_tgt = mptsas_tgt_alloc(mpt->m_tmp_targets, *dev_handle, 13652 0, dev_info, 0, 0); 13653 mutex_exit(&mpt->m_mutex); 13654 13655 devicename = mptsas_get_sata_guid(mpt, tmp_tgt, 0); 13656 13657 if (devicename == -1) { 13658 mutex_enter(&mpt->m_mutex); 13659 refhash_remove(mpt->m_tmp_targets, tmp_tgt); 13660 rval = DEV_INFO_FAIL_GUID; 13661 return (rval); 13662 } 13663 13664 if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) { 13665 sas_wwn = devicename; 13666 } else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) { 13667 sas_wwn = 0; 13668 } 13669 13670 mutex_enter(&mpt->m_mutex); 13671 refhash_remove(mpt->m_tmp_targets, tmp_tgt); 13672 } 13673 13674 phymask = mptsas_physport_to_phymask(mpt, physport); 13675 *pptgt = mptsas_tgt_alloc(mpt->m_targets, *dev_handle, sas_wwn, 13676 dev_info, phymask, phynum); 13677 if (*pptgt == NULL) { 13678 mptsas_log(mpt, CE_WARN, "Failed to allocated target" 13679 "structure!"); 13680 rval = DEV_INFO_FAIL_ALLOC; 13681 return (rval); 13682 } 13683 (*pptgt)->m_io_flags = io_flags; 13684 (*pptgt)->m_enclosure = enclosure; 13685 (*pptgt)->m_slot_num = bay_num; 13686 return (DEV_INFO_SUCCESS); 13687 } 13688 13689 uint64_t 13690 mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun) 13691 { 13692 uint64_t sata_guid = 0, *pwwn = NULL; 13693 int target = ptgt->m_devhdl; 13694 uchar_t *inq83 = NULL; 13695 int inq83_len = 0xFF; 13696 uchar_t *dblk = NULL; 13697 int inq83_retry = 3; 13698 int rval = DDI_FAILURE; 13699 13700 inq83 = kmem_zalloc(inq83_len, KM_SLEEP); 13701 13702 inq83_retry: 13703 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83, 13704 inq83_len, NULL, 1); 13705 if (rval != DDI_SUCCESS) { 13706 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 13707 "0x83 for target:%x, lun:%x failed!", target, lun); 13708 sata_guid = -1; 13709 goto out; 13710 } 13711 /* According to SAT2, the first descriptor is logic unit name */ 13712 dblk = &inq83[4]; 13713 if ((dblk[1] & 0x30) != 0) { 13714 mptsas_log(mpt, CE_WARN, "!Descriptor is not lun associated."); 13715 goto out; 13716 } 13717 pwwn = (uint64_t *)(void *)(&dblk[4]); 13718 if ((dblk[4] & 0xf0) == 0x50) { 13719 sata_guid = BE_64(*pwwn); 13720 goto out; 13721 } else if (dblk[4] == 'A') { 13722 NDBG20(("SATA drive has no NAA format GUID.")); 13723 goto out; 13724 } else { 13725 /* The data is not ready, wait and retry */ 13726 inq83_retry--; 13727 if (inq83_retry <= 0) { 13728 goto out; 13729 } 13730 NDBG20(("The GUID is not ready, retry...")); 13731 delay(1 * drv_usectohz(1000000)); 13732 goto inq83_retry; 13733 } 13734 out: 13735 kmem_free(inq83, inq83_len); 13736 return (sata_guid); 13737 } 13738 13739 static int 13740 mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, uchar_t page, 13741 unsigned char *buf, int len, int *reallen, uchar_t evpd) 13742 { 13743 uchar_t cdb[CDB_GROUP0]; 13744 struct scsi_address ap; 13745 struct buf *data_bp = NULL; 13746 int resid = 0; 13747 int ret = DDI_FAILURE; 13748 13749 ASSERT(len <= 0xffff); 13750 13751 ap.a_target = MPTSAS_INVALID_DEVHDL; 13752 ap.a_lun = (uchar_t)(lun); 13753 ap.a_hba_tran = mpt->m_tran; 13754 13755 data_bp = scsi_alloc_consistent_buf(&ap, 13756 (struct buf *)NULL, len, B_READ, NULL_FUNC, NULL); 13757 if (data_bp == NULL) { 13758 return (ret); 13759 } 13760 bzero(cdb, CDB_GROUP0); 13761 cdb[0] = SCMD_INQUIRY; 13762 cdb[1] = evpd; 13763 cdb[2] = page; 13764 cdb[3] = (len & 0xff00) >> 8; 13765 cdb[4] = (len & 0x00ff); 13766 cdb[5] = 0; 13767 13768 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP0, data_bp, 13769 &resid); 13770 if (ret == DDI_SUCCESS) { 13771 if (reallen) { 13772 *reallen = len - resid; 13773 } 13774 bcopy((caddr_t)data_bp->b_un.b_addr, buf, len); 13775 } 13776 if (data_bp) { 13777 scsi_free_consistent_buf(data_bp); 13778 } 13779 return (ret); 13780 } 13781 13782 static int 13783 mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap, 13784 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp, 13785 int *resid) 13786 { 13787 struct scsi_pkt *pktp = NULL; 13788 scsi_hba_tran_t *tran_clone = NULL; 13789 mptsas_tgt_private_t *tgt_private = NULL; 13790 int ret = DDI_FAILURE; 13791 13792 /* 13793 * scsi_hba_tran_t->tran_tgt_private is used to pass the address 13794 * information to scsi_init_pkt, allocate a scsi_hba_tran structure 13795 * to simulate the cmds from sd 13796 */ 13797 tran_clone = kmem_alloc( 13798 sizeof (scsi_hba_tran_t), KM_SLEEP); 13799 if (tran_clone == NULL) { 13800 goto out; 13801 } 13802 bcopy((caddr_t)mpt->m_tran, 13803 (caddr_t)tran_clone, sizeof (scsi_hba_tran_t)); 13804 tgt_private = kmem_alloc( 13805 sizeof (mptsas_tgt_private_t), KM_SLEEP); 13806 if (tgt_private == NULL) { 13807 goto out; 13808 } 13809 tgt_private->t_lun = ap->a_lun; 13810 tgt_private->t_private = ptgt; 13811 tran_clone->tran_tgt_private = tgt_private; 13812 ap->a_hba_tran = tran_clone; 13813 13814 pktp = scsi_init_pkt(ap, (struct scsi_pkt *)NULL, 13815 data_bp, cdblen, sizeof (struct scsi_arq_status), 13816 0, PKT_CONSISTENT, NULL, NULL); 13817 if (pktp == NULL) { 13818 goto out; 13819 } 13820 bcopy(cdb, pktp->pkt_cdbp, cdblen); 13821 pktp->pkt_flags = FLAG_NOPARITY; 13822 if (scsi_poll(pktp) < 0) { 13823 goto out; 13824 } 13825 if (((struct scsi_status *)pktp->pkt_scbp)->sts_chk) { 13826 goto out; 13827 } 13828 if (resid != NULL) { 13829 *resid = pktp->pkt_resid; 13830 } 13831 13832 ret = DDI_SUCCESS; 13833 out: 13834 if (pktp) { 13835 scsi_destroy_pkt(pktp); 13836 } 13837 if (tran_clone) { 13838 kmem_free(tran_clone, sizeof (scsi_hba_tran_t)); 13839 } 13840 if (tgt_private) { 13841 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t)); 13842 } 13843 return (ret); 13844 } 13845 static int 13846 mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, int *lun) 13847 { 13848 char *cp = NULL; 13849 char *ptr = NULL; 13850 size_t s = 0; 13851 char *wwid_str = NULL; 13852 char *lun_str = NULL; 13853 long lunnum; 13854 long phyid = -1; 13855 int rc = DDI_FAILURE; 13856 13857 ptr = name; 13858 ASSERT(ptr[0] == 'w' || ptr[0] == 'p'); 13859 ptr++; 13860 if ((cp = strchr(ptr, ',')) == NULL) { 13861 return (DDI_FAILURE); 13862 } 13863 13864 wwid_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13865 s = (uintptr_t)cp - (uintptr_t)ptr; 13866 13867 bcopy(ptr, wwid_str, s); 13868 wwid_str[s] = '\0'; 13869 13870 ptr = ++cp; 13871 13872 if ((cp = strchr(ptr, '\0')) == NULL) { 13873 goto out; 13874 } 13875 lun_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13876 s = (uintptr_t)cp - (uintptr_t)ptr; 13877 13878 bcopy(ptr, lun_str, s); 13879 lun_str[s] = '\0'; 13880 13881 if (name[0] == 'p') { 13882 rc = ddi_strtol(wwid_str, NULL, 0x10, &phyid); 13883 } else { 13884 rc = scsi_wwnstr_to_wwn(wwid_str, wwid); 13885 } 13886 if (rc != DDI_SUCCESS) 13887 goto out; 13888 13889 if (phyid != -1) { 13890 ASSERT(phyid < MPTSAS_MAX_PHYS); 13891 *phy = (uint8_t)phyid; 13892 } 13893 rc = ddi_strtol(lun_str, NULL, 0x10, &lunnum); 13894 if (rc != 0) 13895 goto out; 13896 13897 *lun = (int)lunnum; 13898 rc = DDI_SUCCESS; 13899 out: 13900 if (wwid_str) 13901 kmem_free(wwid_str, SCSI_MAXNAMELEN); 13902 if (lun_str) 13903 kmem_free(lun_str, SCSI_MAXNAMELEN); 13904 13905 return (rc); 13906 } 13907 13908 /* 13909 * mptsas_parse_smp_name() is to parse sas wwn string 13910 * which format is "wWWN" 13911 */ 13912 static int 13913 mptsas_parse_smp_name(char *name, uint64_t *wwn) 13914 { 13915 char *ptr = name; 13916 13917 if (*ptr != 'w') { 13918 return (DDI_FAILURE); 13919 } 13920 13921 ptr++; 13922 if (scsi_wwnstr_to_wwn(ptr, wwn)) { 13923 return (DDI_FAILURE); 13924 } 13925 return (DDI_SUCCESS); 13926 } 13927 13928 static int 13929 mptsas_bus_config(dev_info_t *pdip, uint_t flag, 13930 ddi_bus_config_op_t op, void *arg, dev_info_t **childp) 13931 { 13932 int ret = NDI_FAILURE; 13933 int circ = 0; 13934 int circ1 = 0; 13935 mptsas_t *mpt; 13936 char *ptr = NULL; 13937 char *devnm = NULL; 13938 uint64_t wwid = 0; 13939 uint8_t phy = 0xFF; 13940 int lun = 0; 13941 uint_t mflags = flag; 13942 int bconfig = TRUE; 13943 13944 if (scsi_hba_iport_unit_address(pdip) == 0) { 13945 return (DDI_FAILURE); 13946 } 13947 13948 mpt = DIP2MPT(pdip); 13949 if (!mpt) { 13950 return (DDI_FAILURE); 13951 } 13952 /* 13953 * Hold the nexus across the bus_config 13954 */ 13955 ndi_devi_enter(scsi_vhci_dip, &circ); 13956 ndi_devi_enter(pdip, &circ1); 13957 switch (op) { 13958 case BUS_CONFIG_ONE: 13959 /* parse wwid/target name out of name given */ 13960 if ((ptr = strchr((char *)arg, '@')) == NULL) { 13961 ret = NDI_FAILURE; 13962 break; 13963 } 13964 ptr++; 13965 if (strncmp((char *)arg, "smp", 3) == 0) { 13966 /* 13967 * This is a SMP target device 13968 */ 13969 ret = mptsas_parse_smp_name(ptr, &wwid); 13970 if (ret != DDI_SUCCESS) { 13971 ret = NDI_FAILURE; 13972 break; 13973 } 13974 ret = mptsas_config_smp(pdip, wwid, childp); 13975 } else if ((ptr[0] == 'w') || (ptr[0] == 'p')) { 13976 /* 13977 * OBP could pass down a non-canonical form 13978 * bootpath without LUN part when LUN is 0. 13979 * So driver need adjust the string. 13980 */ 13981 if (strchr(ptr, ',') == NULL) { 13982 devnm = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13983 (void) sprintf(devnm, "%s,0", (char *)arg); 13984 ptr = strchr(devnm, '@'); 13985 ptr++; 13986 } 13987 13988 /* 13989 * The device path is wWWID format and the device 13990 * is not SMP target device. 13991 */ 13992 ret = mptsas_parse_address(ptr, &wwid, &phy, &lun); 13993 if (ret != DDI_SUCCESS) { 13994 ret = NDI_FAILURE; 13995 break; 13996 } 13997 *childp = NULL; 13998 if (ptr[0] == 'w') { 13999 ret = mptsas_config_one_addr(pdip, wwid, 14000 lun, childp); 14001 } else if (ptr[0] == 'p') { 14002 ret = mptsas_config_one_phy(pdip, phy, lun, 14003 childp); 14004 } 14005 14006 /* 14007 * If this is CD/DVD device in OBP path, the 14008 * ndi_busop_bus_config can be skipped as config one 14009 * operation is done above. 14010 */ 14011 if ((ret == NDI_SUCCESS) && (*childp != NULL) && 14012 (strcmp(ddi_node_name(*childp), "cdrom") == 0) && 14013 (strncmp((char *)arg, "disk", 4) == 0)) { 14014 bconfig = FALSE; 14015 ndi_hold_devi(*childp); 14016 } 14017 } else { 14018 ret = NDI_FAILURE; 14019 break; 14020 } 14021 14022 /* 14023 * DDI group instructed us to use this flag. 14024 */ 14025 mflags |= NDI_MDI_FALLBACK; 14026 break; 14027 case BUS_CONFIG_DRIVER: 14028 case BUS_CONFIG_ALL: 14029 mptsas_config_all(pdip); 14030 ret = NDI_SUCCESS; 14031 break; 14032 } 14033 14034 if ((ret == NDI_SUCCESS) && bconfig) { 14035 ret = ndi_busop_bus_config(pdip, mflags, op, 14036 (devnm == NULL) ? arg : devnm, childp, 0); 14037 } 14038 14039 ndi_devi_exit(pdip, circ1); 14040 ndi_devi_exit(scsi_vhci_dip, circ); 14041 if (devnm != NULL) 14042 kmem_free(devnm, SCSI_MAXNAMELEN); 14043 return (ret); 14044 } 14045 14046 static int 14047 mptsas_probe_lun(dev_info_t *pdip, int lun, dev_info_t **dip, 14048 mptsas_target_t *ptgt) 14049 { 14050 int rval = DDI_FAILURE; 14051 struct scsi_inquiry *sd_inq = NULL; 14052 mptsas_t *mpt = DIP2MPT(pdip); 14053 14054 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP); 14055 14056 rval = mptsas_inquiry(mpt, ptgt, lun, 0, (uchar_t *)sd_inq, 14057 SUN_INQSIZE, 0, (uchar_t)0); 14058 14059 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) { 14060 rval = mptsas_create_lun(pdip, sd_inq, dip, ptgt, lun); 14061 } else { 14062 rval = DDI_FAILURE; 14063 } 14064 14065 kmem_free(sd_inq, SUN_INQSIZE); 14066 return (rval); 14067 } 14068 14069 static int 14070 mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun, 14071 dev_info_t **lundip) 14072 { 14073 int rval; 14074 mptsas_t *mpt = DIP2MPT(pdip); 14075 int phymask; 14076 mptsas_target_t *ptgt = NULL; 14077 14078 /* 14079 * Get the physical port associated to the iport 14080 */ 14081 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 14082 "phymask", 0); 14083 14084 ptgt = mptsas_wwid_to_ptgt(mpt, phymask, sasaddr); 14085 if (ptgt == NULL) { 14086 /* 14087 * didn't match any device by searching 14088 */ 14089 return (DDI_FAILURE); 14090 } 14091 /* 14092 * If the LUN already exists and the status is online, 14093 * we just return the pointer to dev_info_t directly. 14094 * For the mdi_pathinfo node, we'll handle it in 14095 * mptsas_create_virt_lun() 14096 * TODO should be also in mptsas_handle_dr 14097 */ 14098 14099 *lundip = mptsas_find_child_addr(pdip, sasaddr, lun); 14100 if (*lundip != NULL) { 14101 /* 14102 * TODO Another senario is, we hotplug the same disk 14103 * on the same slot, the devhdl changed, is this 14104 * possible? 14105 * tgt_private->t_private != ptgt 14106 */ 14107 if (sasaddr != ptgt->m_addr.mta_wwn) { 14108 /* 14109 * The device has changed although the devhdl is the 14110 * same (Enclosure mapping mode, change drive on the 14111 * same slot) 14112 */ 14113 return (DDI_FAILURE); 14114 } 14115 return (DDI_SUCCESS); 14116 } 14117 14118 if (phymask == 0) { 14119 /* 14120 * Configure IR volume 14121 */ 14122 rval = mptsas_config_raid(pdip, ptgt->m_devhdl, lundip); 14123 return (rval); 14124 } 14125 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt); 14126 14127 return (rval); 14128 } 14129 14130 static int 14131 mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun, 14132 dev_info_t **lundip) 14133 { 14134 int rval; 14135 mptsas_t *mpt = DIP2MPT(pdip); 14136 mptsas_phymask_t phymask; 14137 mptsas_target_t *ptgt = NULL; 14138 14139 /* 14140 * Get the physical port associated to the iport 14141 */ 14142 phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 14143 "phymask", 0); 14144 14145 ptgt = mptsas_phy_to_tgt(mpt, phymask, phy); 14146 if (ptgt == NULL) { 14147 /* 14148 * didn't match any device by searching 14149 */ 14150 return (DDI_FAILURE); 14151 } 14152 14153 /* 14154 * If the LUN already exists and the status is online, 14155 * we just return the pointer to dev_info_t directly. 14156 * For the mdi_pathinfo node, we'll handle it in 14157 * mptsas_create_virt_lun(). 14158 */ 14159 14160 *lundip = mptsas_find_child_phy(pdip, phy); 14161 if (*lundip != NULL) { 14162 return (DDI_SUCCESS); 14163 } 14164 14165 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt); 14166 14167 return (rval); 14168 } 14169 14170 static int 14171 mptsas_retrieve_lundata(int lun_cnt, uint8_t *buf, uint16_t *lun_num, 14172 uint8_t *lun_addr_type) 14173 { 14174 uint32_t lun_idx = 0; 14175 14176 ASSERT(lun_num != NULL); 14177 ASSERT(lun_addr_type != NULL); 14178 14179 lun_idx = (lun_cnt + 1) * MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE; 14180 /* determine report luns addressing type */ 14181 switch (buf[lun_idx] & MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) { 14182 /* 14183 * Vendors in the field have been found to be concatenating 14184 * bus/target/lun to equal the complete lun value instead 14185 * of switching to flat space addressing 14186 */ 14187 /* 00b - peripheral device addressing method */ 14188 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_PERIPHERAL: 14189 /* FALLTHRU */ 14190 /* 10b - logical unit addressing method */ 14191 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT: 14192 /* FALLTHRU */ 14193 /* 01b - flat space addressing method */ 14194 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE: 14195 /* byte0 bit0-5=msb lun byte1 bit0-7=lsb lun */ 14196 *lun_addr_type = (buf[lun_idx] & 14197 MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) >> 6; 14198 *lun_num = (buf[lun_idx] & 0x3F) << 8; 14199 *lun_num |= buf[lun_idx + 1]; 14200 return (DDI_SUCCESS); 14201 default: 14202 return (DDI_FAILURE); 14203 } 14204 } 14205 14206 static int 14207 mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt) 14208 { 14209 struct buf *repluns_bp = NULL; 14210 struct scsi_address ap; 14211 uchar_t cdb[CDB_GROUP5]; 14212 int ret = DDI_FAILURE; 14213 int retry = 0; 14214 int lun_list_len = 0; 14215 uint16_t lun_num = 0; 14216 uint8_t lun_addr_type = 0; 14217 uint32_t lun_cnt = 0; 14218 uint32_t lun_total = 0; 14219 dev_info_t *cdip = NULL; 14220 uint16_t *saved_repluns = NULL; 14221 char *buffer = NULL; 14222 int buf_len = 128; 14223 mptsas_t *mpt = DIP2MPT(pdip); 14224 uint64_t sas_wwn = 0; 14225 uint8_t phy = 0xFF; 14226 uint32_t dev_info = 0; 14227 14228 mutex_enter(&mpt->m_mutex); 14229 sas_wwn = ptgt->m_addr.mta_wwn; 14230 phy = ptgt->m_phynum; 14231 dev_info = ptgt->m_deviceinfo; 14232 mutex_exit(&mpt->m_mutex); 14233 14234 if (sas_wwn == 0) { 14235 /* 14236 * It's a SATA without Device Name 14237 * So don't try multi-LUNs 14238 */ 14239 if (mptsas_find_child_phy(pdip, phy)) { 14240 return (DDI_SUCCESS); 14241 } else { 14242 /* 14243 * need configure and create node 14244 */ 14245 return (DDI_FAILURE); 14246 } 14247 } 14248 14249 /* 14250 * WWN (SAS address or Device Name exist) 14251 */ 14252 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 14253 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 14254 /* 14255 * SATA device with Device Name 14256 * So don't try multi-LUNs 14257 */ 14258 if (mptsas_find_child_addr(pdip, sas_wwn, 0)) { 14259 return (DDI_SUCCESS); 14260 } else { 14261 return (DDI_FAILURE); 14262 } 14263 } 14264 14265 do { 14266 ap.a_target = MPTSAS_INVALID_DEVHDL; 14267 ap.a_lun = 0; 14268 ap.a_hba_tran = mpt->m_tran; 14269 repluns_bp = scsi_alloc_consistent_buf(&ap, 14270 (struct buf *)NULL, buf_len, B_READ, NULL_FUNC, NULL); 14271 if (repluns_bp == NULL) { 14272 retry++; 14273 continue; 14274 } 14275 bzero(cdb, CDB_GROUP5); 14276 cdb[0] = SCMD_REPORT_LUNS; 14277 cdb[6] = (buf_len & 0xff000000) >> 24; 14278 cdb[7] = (buf_len & 0x00ff0000) >> 16; 14279 cdb[8] = (buf_len & 0x0000ff00) >> 8; 14280 cdb[9] = (buf_len & 0x000000ff); 14281 14282 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP5, 14283 repluns_bp, NULL); 14284 if (ret != DDI_SUCCESS) { 14285 scsi_free_consistent_buf(repluns_bp); 14286 retry++; 14287 continue; 14288 } 14289 lun_list_len = BE_32(*(int *)((void *)( 14290 repluns_bp->b_un.b_addr))); 14291 if (buf_len >= lun_list_len + 8) { 14292 ret = DDI_SUCCESS; 14293 break; 14294 } 14295 scsi_free_consistent_buf(repluns_bp); 14296 buf_len = lun_list_len + 8; 14297 14298 } while (retry < 3); 14299 14300 if (ret != DDI_SUCCESS) 14301 return (ret); 14302 buffer = (char *)repluns_bp->b_un.b_addr; 14303 /* 14304 * find out the number of luns returned by the SCSI ReportLun call 14305 * and allocate buffer space 14306 */ 14307 lun_total = lun_list_len / MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE; 14308 saved_repluns = kmem_zalloc(sizeof (uint16_t) * lun_total, KM_SLEEP); 14309 if (saved_repluns == NULL) { 14310 scsi_free_consistent_buf(repluns_bp); 14311 return (DDI_FAILURE); 14312 } 14313 for (lun_cnt = 0; lun_cnt < lun_total; lun_cnt++) { 14314 if (mptsas_retrieve_lundata(lun_cnt, (uint8_t *)(buffer), 14315 &lun_num, &lun_addr_type) != DDI_SUCCESS) { 14316 continue; 14317 } 14318 saved_repluns[lun_cnt] = lun_num; 14319 if (cdip = mptsas_find_child_addr(pdip, sas_wwn, lun_num)) 14320 ret = DDI_SUCCESS; 14321 else 14322 ret = mptsas_probe_lun(pdip, lun_num, &cdip, 14323 ptgt); 14324 if ((ret == DDI_SUCCESS) && (cdip != NULL)) { 14325 (void) ndi_prop_remove(DDI_DEV_T_NONE, cdip, 14326 MPTSAS_DEV_GONE); 14327 } 14328 } 14329 mptsas_offline_missed_luns(pdip, saved_repluns, lun_total, ptgt); 14330 kmem_free(saved_repluns, sizeof (uint16_t) * lun_total); 14331 scsi_free_consistent_buf(repluns_bp); 14332 return (DDI_SUCCESS); 14333 } 14334 14335 static int 14336 mptsas_config_raid(dev_info_t *pdip, uint16_t target, dev_info_t **dip) 14337 { 14338 int rval = DDI_FAILURE; 14339 struct scsi_inquiry *sd_inq = NULL; 14340 mptsas_t *mpt = DIP2MPT(pdip); 14341 mptsas_target_t *ptgt = NULL; 14342 14343 mutex_enter(&mpt->m_mutex); 14344 ptgt = refhash_linear_search(mpt->m_targets, 14345 mptsas_target_eval_devhdl, &target); 14346 mutex_exit(&mpt->m_mutex); 14347 if (ptgt == NULL) { 14348 mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x " 14349 "not found.", target); 14350 return (rval); 14351 } 14352 14353 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP); 14354 rval = mptsas_inquiry(mpt, ptgt, 0, 0, (uchar_t *)sd_inq, 14355 SUN_INQSIZE, 0, (uchar_t)0); 14356 14357 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) { 14358 rval = mptsas_create_phys_lun(pdip, sd_inq, NULL, dip, ptgt, 14359 0); 14360 } else { 14361 rval = DDI_FAILURE; 14362 } 14363 14364 kmem_free(sd_inq, SUN_INQSIZE); 14365 return (rval); 14366 } 14367 14368 /* 14369 * configure all RAID volumes for virtual iport 14370 */ 14371 static void 14372 mptsas_config_all_viport(dev_info_t *pdip) 14373 { 14374 mptsas_t *mpt = DIP2MPT(pdip); 14375 int config, vol; 14376 int target; 14377 dev_info_t *lundip = NULL; 14378 14379 /* 14380 * Get latest RAID info and search for any Volume DevHandles. If any 14381 * are found, configure the volume. 14382 */ 14383 mutex_enter(&mpt->m_mutex); 14384 for (config = 0; config < mpt->m_num_raid_configs; config++) { 14385 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) { 14386 if (mpt->m_raidconfig[config].m_raidvol[vol].m_israid 14387 == 1) { 14388 target = mpt->m_raidconfig[config]. 14389 m_raidvol[vol].m_raidhandle; 14390 mutex_exit(&mpt->m_mutex); 14391 (void) mptsas_config_raid(pdip, target, 14392 &lundip); 14393 mutex_enter(&mpt->m_mutex); 14394 } 14395 } 14396 } 14397 mutex_exit(&mpt->m_mutex); 14398 } 14399 14400 static void 14401 mptsas_offline_missed_luns(dev_info_t *pdip, uint16_t *repluns, 14402 int lun_cnt, mptsas_target_t *ptgt) 14403 { 14404 dev_info_t *child = NULL, *savechild = NULL; 14405 mdi_pathinfo_t *pip = NULL, *savepip = NULL; 14406 uint64_t sas_wwn, wwid; 14407 uint8_t phy; 14408 int lun; 14409 int i; 14410 int find; 14411 char *addr; 14412 char *nodename; 14413 mptsas_t *mpt = DIP2MPT(pdip); 14414 14415 mutex_enter(&mpt->m_mutex); 14416 wwid = ptgt->m_addr.mta_wwn; 14417 mutex_exit(&mpt->m_mutex); 14418 14419 child = ddi_get_child(pdip); 14420 while (child) { 14421 find = 0; 14422 savechild = child; 14423 child = ddi_get_next_sibling(child); 14424 14425 nodename = ddi_node_name(savechild); 14426 if (strcmp(nodename, "smp") == 0) { 14427 continue; 14428 } 14429 14430 addr = ddi_get_name_addr(savechild); 14431 if (addr == NULL) { 14432 continue; 14433 } 14434 14435 if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) != 14436 DDI_SUCCESS) { 14437 continue; 14438 } 14439 14440 if (wwid == sas_wwn) { 14441 for (i = 0; i < lun_cnt; i++) { 14442 if (repluns[i] == lun) { 14443 find = 1; 14444 break; 14445 } 14446 } 14447 } else { 14448 continue; 14449 } 14450 if (find == 0) { 14451 /* 14452 * The lun has not been there already 14453 */ 14454 (void) mptsas_offline_lun(pdip, savechild, NULL, 14455 NDI_DEVI_REMOVE); 14456 } 14457 } 14458 14459 pip = mdi_get_next_client_path(pdip, NULL); 14460 while (pip) { 14461 find = 0; 14462 savepip = pip; 14463 addr = MDI_PI(pip)->pi_addr; 14464 14465 pip = mdi_get_next_client_path(pdip, pip); 14466 14467 if (addr == NULL) { 14468 continue; 14469 } 14470 14471 if (mptsas_parse_address(addr, &sas_wwn, &phy, 14472 &lun) != DDI_SUCCESS) { 14473 continue; 14474 } 14475 14476 if (sas_wwn == wwid) { 14477 for (i = 0; i < lun_cnt; i++) { 14478 if (repluns[i] == lun) { 14479 find = 1; 14480 break; 14481 } 14482 } 14483 } else { 14484 continue; 14485 } 14486 14487 if (find == 0) { 14488 /* 14489 * The lun has not been there already 14490 */ 14491 (void) mptsas_offline_lun(pdip, NULL, savepip, 14492 NDI_DEVI_REMOVE); 14493 } 14494 } 14495 } 14496 14497 void 14498 mptsas_update_hashtab(struct mptsas *mpt) 14499 { 14500 uint32_t page_address; 14501 int rval = 0; 14502 uint16_t dev_handle; 14503 mptsas_target_t *ptgt = NULL; 14504 mptsas_smp_t smp_node; 14505 14506 /* 14507 * Get latest RAID info. 14508 */ 14509 (void) mptsas_get_raid_info(mpt); 14510 14511 dev_handle = mpt->m_smp_devhdl; 14512 for (; mpt->m_done_traverse_smp == 0; ) { 14513 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL & 14514 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)dev_handle; 14515 if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node) 14516 != DDI_SUCCESS) { 14517 break; 14518 } 14519 mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl; 14520 (void) mptsas_smp_alloc(mpt, &smp_node); 14521 } 14522 14523 /* 14524 * Config target devices 14525 */ 14526 dev_handle = mpt->m_dev_handle; 14527 14528 /* 14529 * Do loop to get sas device page 0 by GetNextHandle till the 14530 * the last handle. If the sas device is a SATA/SSP target, 14531 * we try to config it. 14532 */ 14533 for (; mpt->m_done_traverse_dev == 0; ) { 14534 ptgt = NULL; 14535 page_address = 14536 (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 14537 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14538 (uint32_t)dev_handle; 14539 rval = mptsas_get_target_device_info(mpt, page_address, 14540 &dev_handle, &ptgt); 14541 if ((rval == DEV_INFO_FAIL_PAGE0) || 14542 (rval == DEV_INFO_FAIL_ALLOC) || 14543 (rval == DEV_INFO_FAIL_GUID)) { 14544 break; 14545 } 14546 14547 mpt->m_dev_handle = dev_handle; 14548 } 14549 14550 } 14551 14552 void 14553 mptsas_update_driver_data(struct mptsas *mpt) 14554 { 14555 mptsas_target_t *tp; 14556 mptsas_smp_t *sp; 14557 14558 ASSERT(MUTEX_HELD(&mpt->m_mutex)); 14559 14560 /* 14561 * TODO after hard reset, update the driver data structures 14562 * 1. update port/phymask mapping table mpt->m_phy_info 14563 * 2. invalid all the entries in hash table 14564 * m_devhdl = 0xffff and m_deviceinfo = 0 14565 * 3. call sas_device_page/expander_page to update hash table 14566 */ 14567 mptsas_update_phymask(mpt); 14568 14569 /* 14570 * Remove all the devhdls for existing entries but leave their 14571 * addresses alone. In update_hashtab() below, we'll find all 14572 * targets that are still present and reassociate them with 14573 * their potentially new devhdls. Leaving the targets around in 14574 * this fashion allows them to be used on the tx waitq even 14575 * while IOC reset is occurring. 14576 */ 14577 for (tp = refhash_first(mpt->m_targets); tp != NULL; 14578 tp = refhash_next(mpt->m_targets, tp)) { 14579 tp->m_devhdl = MPTSAS_INVALID_DEVHDL; 14580 tp->m_deviceinfo = 0; 14581 tp->m_dr_flag = MPTSAS_DR_INACTIVE; 14582 } 14583 for (sp = refhash_first(mpt->m_smp_targets); sp != NULL; 14584 sp = refhash_next(mpt->m_smp_targets, sp)) { 14585 sp->m_devhdl = MPTSAS_INVALID_DEVHDL; 14586 sp->m_deviceinfo = 0; 14587 } 14588 mpt->m_done_traverse_dev = 0; 14589 mpt->m_done_traverse_smp = 0; 14590 mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL; 14591 mptsas_update_hashtab(mpt); 14592 } 14593 14594 static void 14595 mptsas_config_all(dev_info_t *pdip) 14596 { 14597 dev_info_t *smpdip = NULL; 14598 mptsas_t *mpt = DIP2MPT(pdip); 14599 int phymask = 0; 14600 mptsas_phymask_t phy_mask; 14601 mptsas_target_t *ptgt = NULL; 14602 mptsas_smp_t *psmp; 14603 14604 /* 14605 * Get the phymask associated to the iport 14606 */ 14607 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 14608 "phymask", 0); 14609 14610 /* 14611 * Enumerate RAID volumes here (phymask == 0). 14612 */ 14613 if (phymask == 0) { 14614 mptsas_config_all_viport(pdip); 14615 return; 14616 } 14617 14618 mutex_enter(&mpt->m_mutex); 14619 14620 if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp) { 14621 mptsas_update_hashtab(mpt); 14622 } 14623 14624 for (psmp = refhash_first(mpt->m_smp_targets); psmp != NULL; 14625 psmp = refhash_next(mpt->m_smp_targets, psmp)) { 14626 phy_mask = psmp->m_addr.mta_phymask; 14627 if (phy_mask == phymask) { 14628 smpdip = NULL; 14629 mutex_exit(&mpt->m_mutex); 14630 (void) mptsas_online_smp(pdip, psmp, &smpdip); 14631 mutex_enter(&mpt->m_mutex); 14632 } 14633 } 14634 14635 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 14636 ptgt = refhash_next(mpt->m_targets, ptgt)) { 14637 phy_mask = ptgt->m_addr.mta_phymask; 14638 if (phy_mask == phymask) { 14639 mutex_exit(&mpt->m_mutex); 14640 (void) mptsas_config_target(pdip, ptgt); 14641 mutex_enter(&mpt->m_mutex); 14642 } 14643 } 14644 mutex_exit(&mpt->m_mutex); 14645 } 14646 14647 static int 14648 mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt) 14649 { 14650 int rval = DDI_FAILURE; 14651 dev_info_t *tdip; 14652 14653 rval = mptsas_config_luns(pdip, ptgt); 14654 if (rval != DDI_SUCCESS) { 14655 /* 14656 * The return value means the SCMD_REPORT_LUNS 14657 * did not execute successfully. The target maybe 14658 * doesn't support such command. 14659 */ 14660 rval = mptsas_probe_lun(pdip, 0, &tdip, ptgt); 14661 } 14662 return (rval); 14663 } 14664 14665 /* 14666 * Return fail if not all the childs/paths are freed. 14667 * if there is any path under the HBA, the return value will be always fail 14668 * because we didn't call mdi_pi_free for path 14669 */ 14670 static int 14671 mptsas_offline_target(dev_info_t *pdip, char *name) 14672 { 14673 dev_info_t *child = NULL, *prechild = NULL; 14674 mdi_pathinfo_t *pip = NULL, *savepip = NULL; 14675 int tmp_rval, rval = DDI_SUCCESS; 14676 char *addr, *cp; 14677 size_t s; 14678 mptsas_t *mpt = DIP2MPT(pdip); 14679 14680 child = ddi_get_child(pdip); 14681 while (child) { 14682 addr = ddi_get_name_addr(child); 14683 prechild = child; 14684 child = ddi_get_next_sibling(child); 14685 14686 if (addr == NULL) { 14687 continue; 14688 } 14689 if ((cp = strchr(addr, ',')) == NULL) { 14690 continue; 14691 } 14692 14693 s = (uintptr_t)cp - (uintptr_t)addr; 14694 14695 if (strncmp(addr, name, s) != 0) { 14696 continue; 14697 } 14698 14699 tmp_rval = mptsas_offline_lun(pdip, prechild, NULL, 14700 NDI_DEVI_REMOVE); 14701 if (tmp_rval != DDI_SUCCESS) { 14702 rval = DDI_FAILURE; 14703 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 14704 prechild, MPTSAS_DEV_GONE) != 14705 DDI_PROP_SUCCESS) { 14706 mptsas_log(mpt, CE_WARN, "mptsas driver " 14707 "unable to create property for " 14708 "SAS %s (MPTSAS_DEV_GONE)", addr); 14709 } 14710 } 14711 } 14712 14713 pip = mdi_get_next_client_path(pdip, NULL); 14714 while (pip) { 14715 addr = MDI_PI(pip)->pi_addr; 14716 savepip = pip; 14717 pip = mdi_get_next_client_path(pdip, pip); 14718 if (addr == NULL) { 14719 continue; 14720 } 14721 14722 if ((cp = strchr(addr, ',')) == NULL) { 14723 continue; 14724 } 14725 14726 s = (uintptr_t)cp - (uintptr_t)addr; 14727 14728 if (strncmp(addr, name, s) != 0) { 14729 continue; 14730 } 14731 14732 (void) mptsas_offline_lun(pdip, NULL, savepip, 14733 NDI_DEVI_REMOVE); 14734 /* 14735 * driver will not invoke mdi_pi_free, so path will not 14736 * be freed forever, return DDI_FAILURE. 14737 */ 14738 rval = DDI_FAILURE; 14739 } 14740 return (rval); 14741 } 14742 14743 static int 14744 mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip, 14745 mdi_pathinfo_t *rpip, uint_t flags) 14746 { 14747 int rval = DDI_FAILURE; 14748 char *devname; 14749 dev_info_t *cdip, *parent; 14750 14751 if (rpip != NULL) { 14752 parent = scsi_vhci_dip; 14753 cdip = mdi_pi_get_client(rpip); 14754 } else if (rdip != NULL) { 14755 parent = pdip; 14756 cdip = rdip; 14757 } else { 14758 return (DDI_FAILURE); 14759 } 14760 14761 /* 14762 * Make sure node is attached otherwise 14763 * it won't have related cache nodes to 14764 * clean up. i_ddi_devi_attached is 14765 * similiar to i_ddi_node_state(cdip) >= 14766 * DS_ATTACHED. 14767 */ 14768 if (i_ddi_devi_attached(cdip)) { 14769 14770 /* Get full devname */ 14771 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 14772 (void) ddi_deviname(cdip, devname); 14773 /* Clean cache */ 14774 (void) devfs_clean(parent, devname + 1, 14775 DV_CLEAN_FORCE); 14776 kmem_free(devname, MAXNAMELEN + 1); 14777 } 14778 if (rpip != NULL) { 14779 if (MDI_PI_IS_OFFLINE(rpip)) { 14780 rval = DDI_SUCCESS; 14781 } else { 14782 rval = mdi_pi_offline(rpip, 0); 14783 } 14784 } else { 14785 rval = ndi_devi_offline(cdip, flags); 14786 } 14787 14788 return (rval); 14789 } 14790 14791 static dev_info_t * 14792 mptsas_find_smp_child(dev_info_t *parent, char *str_wwn) 14793 { 14794 dev_info_t *child = NULL; 14795 char *smp_wwn = NULL; 14796 14797 child = ddi_get_child(parent); 14798 while (child) { 14799 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child, 14800 DDI_PROP_DONTPASS, SMP_WWN, &smp_wwn) 14801 != DDI_SUCCESS) { 14802 child = ddi_get_next_sibling(child); 14803 continue; 14804 } 14805 14806 if (strcmp(smp_wwn, str_wwn) == 0) { 14807 ddi_prop_free(smp_wwn); 14808 break; 14809 } 14810 child = ddi_get_next_sibling(child); 14811 ddi_prop_free(smp_wwn); 14812 } 14813 return (child); 14814 } 14815 14816 static int 14817 mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags) 14818 { 14819 int rval = DDI_FAILURE; 14820 char *devname; 14821 char wwn_str[MPTSAS_WWN_STRLEN]; 14822 dev_info_t *cdip; 14823 14824 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn); 14825 14826 cdip = mptsas_find_smp_child(pdip, wwn_str); 14827 14828 if (cdip == NULL) 14829 return (DDI_SUCCESS); 14830 14831 /* 14832 * Make sure node is attached otherwise 14833 * it won't have related cache nodes to 14834 * clean up. i_ddi_devi_attached is 14835 * similiar to i_ddi_node_state(cdip) >= 14836 * DS_ATTACHED. 14837 */ 14838 if (i_ddi_devi_attached(cdip)) { 14839 14840 /* Get full devname */ 14841 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 14842 (void) ddi_deviname(cdip, devname); 14843 /* Clean cache */ 14844 (void) devfs_clean(pdip, devname + 1, 14845 DV_CLEAN_FORCE); 14846 kmem_free(devname, MAXNAMELEN + 1); 14847 } 14848 14849 rval = ndi_devi_offline(cdip, flags); 14850 14851 return (rval); 14852 } 14853 14854 static dev_info_t * 14855 mptsas_find_child(dev_info_t *pdip, char *name) 14856 { 14857 dev_info_t *child = NULL; 14858 char *rname = NULL; 14859 int rval = DDI_FAILURE; 14860 14861 rname = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14862 14863 child = ddi_get_child(pdip); 14864 while (child) { 14865 rval = mptsas_name_child(child, rname, SCSI_MAXNAMELEN); 14866 if (rval != DDI_SUCCESS) { 14867 child = ddi_get_next_sibling(child); 14868 bzero(rname, SCSI_MAXNAMELEN); 14869 continue; 14870 } 14871 14872 if (strcmp(rname, name) == 0) { 14873 break; 14874 } 14875 child = ddi_get_next_sibling(child); 14876 bzero(rname, SCSI_MAXNAMELEN); 14877 } 14878 14879 kmem_free(rname, SCSI_MAXNAMELEN); 14880 14881 return (child); 14882 } 14883 14884 14885 static dev_info_t * 14886 mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, int lun) 14887 { 14888 dev_info_t *child = NULL; 14889 char *name = NULL; 14890 char *addr = NULL; 14891 14892 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14893 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14894 (void) sprintf(name, "%016"PRIx64, sasaddr); 14895 (void) sprintf(addr, "w%s,%x", name, lun); 14896 child = mptsas_find_child(pdip, addr); 14897 kmem_free(name, SCSI_MAXNAMELEN); 14898 kmem_free(addr, SCSI_MAXNAMELEN); 14899 return (child); 14900 } 14901 14902 static dev_info_t * 14903 mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy) 14904 { 14905 dev_info_t *child; 14906 char *addr; 14907 14908 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14909 (void) sprintf(addr, "p%x,0", phy); 14910 child = mptsas_find_child(pdip, addr); 14911 kmem_free(addr, SCSI_MAXNAMELEN); 14912 return (child); 14913 } 14914 14915 static mdi_pathinfo_t * 14916 mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy) 14917 { 14918 mdi_pathinfo_t *path; 14919 char *addr = NULL; 14920 14921 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14922 (void) sprintf(addr, "p%x,0", phy); 14923 path = mdi_pi_find(pdip, NULL, addr); 14924 kmem_free(addr, SCSI_MAXNAMELEN); 14925 return (path); 14926 } 14927 14928 static mdi_pathinfo_t * 14929 mptsas_find_path_addr(dev_info_t *parent, uint64_t sasaddr, int lun) 14930 { 14931 mdi_pathinfo_t *path; 14932 char *name = NULL; 14933 char *addr = NULL; 14934 14935 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14936 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14937 (void) sprintf(name, "%016"PRIx64, sasaddr); 14938 (void) sprintf(addr, "w%s,%x", name, lun); 14939 path = mdi_pi_find(parent, NULL, addr); 14940 kmem_free(name, SCSI_MAXNAMELEN); 14941 kmem_free(addr, SCSI_MAXNAMELEN); 14942 14943 return (path); 14944 } 14945 14946 static int 14947 mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq, 14948 dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun) 14949 { 14950 int i = 0; 14951 uchar_t *inq83 = NULL; 14952 int inq83_len1 = 0xFF; 14953 int inq83_len = 0; 14954 int rval = DDI_FAILURE; 14955 ddi_devid_t devid; 14956 char *guid = NULL; 14957 int target = ptgt->m_devhdl; 14958 mdi_pathinfo_t *pip = NULL; 14959 mptsas_t *mpt = DIP2MPT(pdip); 14960 14961 /* 14962 * For DVD/CD ROM and tape devices and optical 14963 * devices, we won't try to enumerate them under 14964 * scsi_vhci, so no need to try page83 14965 */ 14966 if (sd_inq && (sd_inq->inq_dtype == DTYPE_RODIRECT || 14967 sd_inq->inq_dtype == DTYPE_OPTICAL || 14968 sd_inq->inq_dtype == DTYPE_ESI)) 14969 goto create_lun; 14970 14971 /* 14972 * The LCA returns good SCSI status, but corrupt page 83 data the first 14973 * time it is queried. The solution is to keep trying to request page83 14974 * and verify the GUID is not (DDI_NOT_WELL_FORMED) in 14975 * mptsas_inq83_retry_timeout seconds. If the timeout expires, driver 14976 * give up to get VPD page at this stage and fail the enumeration. 14977 */ 14978 14979 inq83 = kmem_zalloc(inq83_len1, KM_SLEEP); 14980 14981 for (i = 0; i < mptsas_inq83_retry_timeout; i++) { 14982 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83, 14983 inq83_len1, &inq83_len, 1); 14984 if (rval != 0) { 14985 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 14986 "0x83 for target:%x, lun:%x failed!", target, lun); 14987 if (mptsas_physical_bind_failed_page_83 != B_FALSE) 14988 goto create_lun; 14989 goto out; 14990 } 14991 /* 14992 * create DEVID from inquiry data 14993 */ 14994 if ((rval = ddi_devid_scsi_encode( 14995 DEVID_SCSI_ENCODE_VERSION_LATEST, NULL, (uchar_t *)sd_inq, 14996 sizeof (struct scsi_inquiry), NULL, 0, inq83, 14997 (size_t)inq83_len, &devid)) == DDI_SUCCESS) { 14998 /* 14999 * extract GUID from DEVID 15000 */ 15001 guid = ddi_devid_to_guid(devid); 15002 15003 /* 15004 * Do not enable MPXIO if the strlen(guid) is greater 15005 * than MPTSAS_MAX_GUID_LEN, this constrain would be 15006 * handled by framework later. 15007 */ 15008 if (guid && (strlen(guid) > MPTSAS_MAX_GUID_LEN)) { 15009 ddi_devid_free_guid(guid); 15010 guid = NULL; 15011 if (mpt->m_mpxio_enable == TRUE) { 15012 mptsas_log(mpt, CE_NOTE, "!Target:%x, " 15013 "lun:%x doesn't have a valid GUID, " 15014 "multipathing for this drive is " 15015 "not enabled", target, lun); 15016 } 15017 } 15018 15019 /* 15020 * devid no longer needed 15021 */ 15022 ddi_devid_free(devid); 15023 break; 15024 } else if (rval == DDI_NOT_WELL_FORMED) { 15025 /* 15026 * return value of ddi_devid_scsi_encode equal to 15027 * DDI_NOT_WELL_FORMED means DEVID_RETRY, it worth 15028 * to retry inquiry page 0x83 and get GUID. 15029 */ 15030 NDBG20(("Not well formed devid, retry...")); 15031 delay(1 * drv_usectohz(1000000)); 15032 continue; 15033 } else { 15034 mptsas_log(mpt, CE_WARN, "!Encode devid failed for " 15035 "path target:%x, lun:%x", target, lun); 15036 rval = DDI_FAILURE; 15037 goto create_lun; 15038 } 15039 } 15040 15041 if (i == mptsas_inq83_retry_timeout) { 15042 mptsas_log(mpt, CE_WARN, "!Repeated page83 requests timeout " 15043 "for path target:%x, lun:%x", target, lun); 15044 } 15045 15046 rval = DDI_FAILURE; 15047 15048 create_lun: 15049 if ((guid != NULL) && (mpt->m_mpxio_enable == TRUE)) { 15050 rval = mptsas_create_virt_lun(pdip, sd_inq, guid, lun_dip, &pip, 15051 ptgt, lun); 15052 } 15053 if (rval != DDI_SUCCESS) { 15054 rval = mptsas_create_phys_lun(pdip, sd_inq, guid, lun_dip, 15055 ptgt, lun); 15056 15057 } 15058 out: 15059 if (guid != NULL) { 15060 /* 15061 * guid no longer needed 15062 */ 15063 ddi_devid_free_guid(guid); 15064 } 15065 if (inq83 != NULL) 15066 kmem_free(inq83, inq83_len1); 15067 return (rval); 15068 } 15069 15070 static int 15071 mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *inq, char *guid, 15072 dev_info_t **lun_dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, int lun) 15073 { 15074 int target; 15075 char *nodename = NULL; 15076 char **compatible = NULL; 15077 int ncompatible = 0; 15078 int mdi_rtn = MDI_FAILURE; 15079 int rval = DDI_FAILURE; 15080 char *old_guid = NULL; 15081 mptsas_t *mpt = DIP2MPT(pdip); 15082 char *lun_addr = NULL; 15083 char *wwn_str = NULL; 15084 char *attached_wwn_str = NULL; 15085 char *component = NULL; 15086 uint8_t phy = 0xFF; 15087 uint64_t sas_wwn; 15088 int64_t lun64 = 0; 15089 uint32_t devinfo; 15090 uint16_t dev_hdl; 15091 uint16_t pdev_hdl; 15092 uint64_t dev_sas_wwn; 15093 uint64_t pdev_sas_wwn; 15094 uint32_t pdev_info; 15095 uint8_t physport; 15096 uint8_t phy_id; 15097 uint32_t page_address; 15098 uint16_t bay_num, enclosure, io_flags; 15099 char pdev_wwn_str[MPTSAS_WWN_STRLEN]; 15100 uint32_t dev_info; 15101 15102 mutex_enter(&mpt->m_mutex); 15103 target = ptgt->m_devhdl; 15104 sas_wwn = ptgt->m_addr.mta_wwn; 15105 devinfo = ptgt->m_deviceinfo; 15106 phy = ptgt->m_phynum; 15107 mutex_exit(&mpt->m_mutex); 15108 15109 if (sas_wwn) { 15110 *pip = mptsas_find_path_addr(pdip, sas_wwn, lun); 15111 } else { 15112 *pip = mptsas_find_path_phy(pdip, phy); 15113 } 15114 15115 if (*pip != NULL) { 15116 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip; 15117 ASSERT(*lun_dip != NULL); 15118 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip, 15119 (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM), 15120 MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) { 15121 if (strncmp(guid, old_guid, strlen(guid)) == 0) { 15122 /* 15123 * Same path back online again. 15124 */ 15125 (void) ddi_prop_free(old_guid); 15126 if ((!MDI_PI_IS_ONLINE(*pip)) && 15127 (!MDI_PI_IS_STANDBY(*pip)) && 15128 (ptgt->m_tgt_unconfigured == 0)) { 15129 rval = mdi_pi_online(*pip, 0); 15130 mutex_enter(&mpt->m_mutex); 15131 ptgt->m_led_status = 0; 15132 (void) mptsas_flush_led_status(mpt, 15133 ptgt); 15134 mutex_exit(&mpt->m_mutex); 15135 } else { 15136 rval = DDI_SUCCESS; 15137 } 15138 if (rval != DDI_SUCCESS) { 15139 mptsas_log(mpt, CE_WARN, "path:target: " 15140 "%x, lun:%x online failed!", target, 15141 lun); 15142 *pip = NULL; 15143 *lun_dip = NULL; 15144 } 15145 return (rval); 15146 } else { 15147 /* 15148 * The GUID of the LUN has changed which maybe 15149 * because customer mapped another volume to the 15150 * same LUN. 15151 */ 15152 mptsas_log(mpt, CE_WARN, "The GUID of the " 15153 "target:%x, lun:%x was changed, maybe " 15154 "because someone mapped another volume " 15155 "to the same LUN", target, lun); 15156 (void) ddi_prop_free(old_guid); 15157 if (!MDI_PI_IS_OFFLINE(*pip)) { 15158 rval = mdi_pi_offline(*pip, 0); 15159 if (rval != MDI_SUCCESS) { 15160 mptsas_log(mpt, CE_WARN, "path:" 15161 "target:%x, lun:%x offline " 15162 "failed!", target, lun); 15163 *pip = NULL; 15164 *lun_dip = NULL; 15165 return (DDI_FAILURE); 15166 } 15167 } 15168 if (mdi_pi_free(*pip, 0) != MDI_SUCCESS) { 15169 mptsas_log(mpt, CE_WARN, "path:target:" 15170 "%x, lun:%x free failed!", target, 15171 lun); 15172 *pip = NULL; 15173 *lun_dip = NULL; 15174 return (DDI_FAILURE); 15175 } 15176 } 15177 } else { 15178 mptsas_log(mpt, CE_WARN, "Can't get client-guid " 15179 "property for path:target:%x, lun:%x", target, lun); 15180 *pip = NULL; 15181 *lun_dip = NULL; 15182 return (DDI_FAILURE); 15183 } 15184 } 15185 scsi_hba_nodename_compatible_get(inq, NULL, 15186 inq->inq_dtype, NULL, &nodename, &compatible, &ncompatible); 15187 15188 /* 15189 * if nodename can't be determined then print a message and skip it 15190 */ 15191 if (nodename == NULL) { 15192 mptsas_log(mpt, CE_WARN, "mptsas driver found no compatible " 15193 "driver for target%d lun %d dtype:0x%02x", target, lun, 15194 inq->inq_dtype); 15195 return (DDI_FAILURE); 15196 } 15197 15198 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP); 15199 /* The property is needed by MPAPI */ 15200 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn); 15201 15202 lun_addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 15203 if (guid) { 15204 (void) sprintf(lun_addr, "w%s,%x", wwn_str, lun); 15205 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 15206 } else { 15207 (void) sprintf(lun_addr, "p%x,%x", phy, lun); 15208 (void) sprintf(wwn_str, "p%x", phy); 15209 } 15210 15211 mdi_rtn = mdi_pi_alloc_compatible(pdip, nodename, 15212 guid, lun_addr, compatible, ncompatible, 15213 0, pip); 15214 if (mdi_rtn == MDI_SUCCESS) { 15215 15216 if (mdi_prop_update_string(*pip, MDI_GUID, 15217 guid) != DDI_SUCCESS) { 15218 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 15219 "create prop for target %d lun %d (MDI_GUID)", 15220 target, lun); 15221 mdi_rtn = MDI_FAILURE; 15222 goto virt_create_done; 15223 } 15224 15225 if (mdi_prop_update_int(*pip, LUN_PROP, 15226 lun) != DDI_SUCCESS) { 15227 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 15228 "create prop for target %d lun %d (LUN_PROP)", 15229 target, lun); 15230 mdi_rtn = MDI_FAILURE; 15231 goto virt_create_done; 15232 } 15233 lun64 = (int64_t)lun; 15234 if (mdi_prop_update_int64(*pip, LUN64_PROP, 15235 lun64) != DDI_SUCCESS) { 15236 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 15237 "create prop for target %d (LUN64_PROP)", 15238 target); 15239 mdi_rtn = MDI_FAILURE; 15240 goto virt_create_done; 15241 } 15242 if (mdi_prop_update_string_array(*pip, "compatible", 15243 compatible, ncompatible) != 15244 DDI_PROP_SUCCESS) { 15245 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 15246 "create prop for target %d lun %d (COMPATIBLE)", 15247 target, lun); 15248 mdi_rtn = MDI_FAILURE; 15249 goto virt_create_done; 15250 } 15251 if (sas_wwn && (mdi_prop_update_string(*pip, 15252 SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != DDI_PROP_SUCCESS)) { 15253 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 15254 "create prop for target %d lun %d " 15255 "(target-port)", target, lun); 15256 mdi_rtn = MDI_FAILURE; 15257 goto virt_create_done; 15258 } else if ((sas_wwn == 0) && (mdi_prop_update_int(*pip, 15259 "sata-phy", phy) != DDI_PROP_SUCCESS)) { 15260 /* 15261 * Direct attached SATA device without DeviceName 15262 */ 15263 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 15264 "create prop for SAS target %d lun %d " 15265 "(sata-phy)", target, lun); 15266 mdi_rtn = MDI_FAILURE; 15267 goto virt_create_done; 15268 } 15269 mutex_enter(&mpt->m_mutex); 15270 15271 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 15272 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 15273 (uint32_t)ptgt->m_devhdl; 15274 rval = mptsas_get_sas_device_page0(mpt, page_address, 15275 &dev_hdl, &dev_sas_wwn, &dev_info, &physport, 15276 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags); 15277 if (rval != DDI_SUCCESS) { 15278 mutex_exit(&mpt->m_mutex); 15279 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 15280 "parent device for handle %d", page_address); 15281 mdi_rtn = MDI_FAILURE; 15282 goto virt_create_done; 15283 } 15284 15285 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 15286 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl; 15287 rval = mptsas_get_sas_device_page0(mpt, page_address, 15288 &dev_hdl, &pdev_sas_wwn, &pdev_info, &physport, 15289 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags); 15290 if (rval != DDI_SUCCESS) { 15291 mutex_exit(&mpt->m_mutex); 15292 mptsas_log(mpt, CE_WARN, "mptsas unable to get" 15293 "device info for handle %d", page_address); 15294 mdi_rtn = MDI_FAILURE; 15295 goto virt_create_done; 15296 } 15297 15298 mutex_exit(&mpt->m_mutex); 15299 15300 /* 15301 * If this device direct attached to the controller 15302 * set the attached-port to the base wwid 15303 */ 15304 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 15305 != DEVINFO_DIRECT_ATTACHED) { 15306 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 15307 pdev_sas_wwn); 15308 } else { 15309 /* 15310 * Update the iport's attached-port to guid 15311 */ 15312 if (sas_wwn == 0) { 15313 (void) sprintf(wwn_str, "p%x", phy); 15314 } else { 15315 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 15316 } 15317 if (ddi_prop_update_string(DDI_DEV_T_NONE, 15318 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 15319 DDI_PROP_SUCCESS) { 15320 mptsas_log(mpt, CE_WARN, 15321 "mptsas unable to create " 15322 "property for iport target-port" 15323 " %s (sas_wwn)", 15324 wwn_str); 15325 mdi_rtn = MDI_FAILURE; 15326 goto virt_create_done; 15327 } 15328 15329 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 15330 mpt->un.m_base_wwid); 15331 } 15332 15333 if (mdi_prop_update_string(*pip, 15334 SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) != 15335 DDI_PROP_SUCCESS) { 15336 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15337 "property for iport attached-port %s (sas_wwn)", 15338 attached_wwn_str); 15339 mdi_rtn = MDI_FAILURE; 15340 goto virt_create_done; 15341 } 15342 15343 15344 if (inq->inq_dtype == 0) { 15345 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 15346 /* 15347 * set obp path for pathinfo 15348 */ 15349 (void) snprintf(component, MAXPATHLEN, 15350 "disk@%s", lun_addr); 15351 15352 if (mdi_pi_pathname_obp_set(*pip, component) != 15353 DDI_SUCCESS) { 15354 mptsas_log(mpt, CE_WARN, "mpt_sas driver " 15355 "unable to set obp-path for object %s", 15356 component); 15357 mdi_rtn = MDI_FAILURE; 15358 goto virt_create_done; 15359 } 15360 } 15361 15362 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip; 15363 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 15364 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 15365 if ((ndi_prop_update_int(DDI_DEV_T_NONE, *lun_dip, 15366 "pm-capable", 1)) != 15367 DDI_PROP_SUCCESS) { 15368 mptsas_log(mpt, CE_WARN, "mptsas driver" 15369 "failed to create pm-capable " 15370 "property, target %d", target); 15371 mdi_rtn = MDI_FAILURE; 15372 goto virt_create_done; 15373 } 15374 } 15375 /* 15376 * Create the phy-num property 15377 */ 15378 if (mdi_prop_update_int(*pip, "phy-num", 15379 ptgt->m_phynum) != DDI_SUCCESS) { 15380 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 15381 "create phy-num property for target %d lun %d", 15382 target, lun); 15383 mdi_rtn = MDI_FAILURE; 15384 goto virt_create_done; 15385 } 15386 NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr)); 15387 mdi_rtn = mdi_pi_online(*pip, 0); 15388 if (mdi_rtn == MDI_SUCCESS) { 15389 mutex_enter(&mpt->m_mutex); 15390 ptgt->m_led_status = 0; 15391 (void) mptsas_flush_led_status(mpt, ptgt); 15392 mutex_exit(&mpt->m_mutex); 15393 } 15394 if (mdi_rtn == MDI_NOT_SUPPORTED) { 15395 mdi_rtn = MDI_FAILURE; 15396 } 15397 virt_create_done: 15398 if (*pip && mdi_rtn != MDI_SUCCESS) { 15399 (void) mdi_pi_free(*pip, 0); 15400 *pip = NULL; 15401 *lun_dip = NULL; 15402 } 15403 } 15404 15405 scsi_hba_nodename_compatible_free(nodename, compatible); 15406 if (lun_addr != NULL) { 15407 kmem_free(lun_addr, SCSI_MAXNAMELEN); 15408 } 15409 if (wwn_str != NULL) { 15410 kmem_free(wwn_str, MPTSAS_WWN_STRLEN); 15411 } 15412 if (component != NULL) { 15413 kmem_free(component, MAXPATHLEN); 15414 } 15415 15416 return ((mdi_rtn == MDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 15417 } 15418 15419 static int 15420 mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *inq, 15421 char *guid, dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun) 15422 { 15423 int target; 15424 int rval; 15425 int ndi_rtn = NDI_FAILURE; 15426 uint64_t be_sas_wwn; 15427 char *nodename = NULL; 15428 char **compatible = NULL; 15429 int ncompatible = 0; 15430 int instance = 0; 15431 mptsas_t *mpt = DIP2MPT(pdip); 15432 char *wwn_str = NULL; 15433 char *component = NULL; 15434 char *attached_wwn_str = NULL; 15435 uint8_t phy = 0xFF; 15436 uint64_t sas_wwn; 15437 uint32_t devinfo; 15438 uint16_t dev_hdl; 15439 uint16_t pdev_hdl; 15440 uint64_t pdev_sas_wwn; 15441 uint64_t dev_sas_wwn; 15442 uint32_t pdev_info; 15443 uint8_t physport; 15444 uint8_t phy_id; 15445 uint32_t page_address; 15446 uint16_t bay_num, enclosure, io_flags; 15447 char pdev_wwn_str[MPTSAS_WWN_STRLEN]; 15448 uint32_t dev_info; 15449 int64_t lun64 = 0; 15450 15451 mutex_enter(&mpt->m_mutex); 15452 target = ptgt->m_devhdl; 15453 sas_wwn = ptgt->m_addr.mta_wwn; 15454 devinfo = ptgt->m_deviceinfo; 15455 phy = ptgt->m_phynum; 15456 mutex_exit(&mpt->m_mutex); 15457 15458 /* 15459 * generate compatible property with binding-set "mpt" 15460 */ 15461 scsi_hba_nodename_compatible_get(inq, NULL, inq->inq_dtype, NULL, 15462 &nodename, &compatible, &ncompatible); 15463 15464 /* 15465 * if nodename can't be determined then print a message and skip it 15466 */ 15467 if (nodename == NULL) { 15468 mptsas_log(mpt, CE_WARN, "mptsas found no compatible driver " 15469 "for target %d lun %d", target, lun); 15470 return (DDI_FAILURE); 15471 } 15472 15473 ndi_rtn = ndi_devi_alloc(pdip, nodename, 15474 DEVI_SID_NODEID, lun_dip); 15475 15476 /* 15477 * if lun alloc success, set props 15478 */ 15479 if (ndi_rtn == NDI_SUCCESS) { 15480 15481 if (ndi_prop_update_int(DDI_DEV_T_NONE, 15482 *lun_dip, LUN_PROP, lun) != 15483 DDI_PROP_SUCCESS) { 15484 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15485 "property for target %d lun %d (LUN_PROP)", 15486 target, lun); 15487 ndi_rtn = NDI_FAILURE; 15488 goto phys_create_done; 15489 } 15490 15491 lun64 = (int64_t)lun; 15492 if (ndi_prop_update_int64(DDI_DEV_T_NONE, 15493 *lun_dip, LUN64_PROP, lun64) != 15494 DDI_PROP_SUCCESS) { 15495 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15496 "property for target %d lun64 %d (LUN64_PROP)", 15497 target, lun); 15498 ndi_rtn = NDI_FAILURE; 15499 goto phys_create_done; 15500 } 15501 if (ndi_prop_update_string_array(DDI_DEV_T_NONE, 15502 *lun_dip, "compatible", compatible, ncompatible) 15503 != DDI_PROP_SUCCESS) { 15504 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15505 "property for target %d lun %d (COMPATIBLE)", 15506 target, lun); 15507 ndi_rtn = NDI_FAILURE; 15508 goto phys_create_done; 15509 } 15510 15511 /* 15512 * We need the SAS WWN for non-multipath devices, so 15513 * we'll use the same property as that multipathing 15514 * devices need to present for MPAPI. If we don't have 15515 * a WWN (e.g. parallel SCSI), don't create the prop. 15516 */ 15517 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP); 15518 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 15519 if (sas_wwn && ndi_prop_update_string(DDI_DEV_T_NONE, 15520 *lun_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) 15521 != DDI_PROP_SUCCESS) { 15522 mptsas_log(mpt, CE_WARN, "mptsas unable to " 15523 "create property for SAS target %d lun %d " 15524 "(target-port)", target, lun); 15525 ndi_rtn = NDI_FAILURE; 15526 goto phys_create_done; 15527 } 15528 15529 be_sas_wwn = BE_64(sas_wwn); 15530 if (sas_wwn && ndi_prop_update_byte_array( 15531 DDI_DEV_T_NONE, *lun_dip, "port-wwn", 15532 (uchar_t *)&be_sas_wwn, 8) != DDI_PROP_SUCCESS) { 15533 mptsas_log(mpt, CE_WARN, "mptsas unable to " 15534 "create property for SAS target %d lun %d " 15535 "(port-wwn)", target, lun); 15536 ndi_rtn = NDI_FAILURE; 15537 goto phys_create_done; 15538 } else if ((sas_wwn == 0) && (ndi_prop_update_int( 15539 DDI_DEV_T_NONE, *lun_dip, "sata-phy", phy) != 15540 DDI_PROP_SUCCESS)) { 15541 /* 15542 * Direct attached SATA device without DeviceName 15543 */ 15544 mptsas_log(mpt, CE_WARN, "mptsas unable to " 15545 "create property for SAS target %d lun %d " 15546 "(sata-phy)", target, lun); 15547 ndi_rtn = NDI_FAILURE; 15548 goto phys_create_done; 15549 } 15550 15551 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 15552 *lun_dip, SAS_PROP) != DDI_PROP_SUCCESS) { 15553 mptsas_log(mpt, CE_WARN, "mptsas unable to" 15554 "create property for SAS target %d lun %d" 15555 " (SAS_PROP)", target, lun); 15556 ndi_rtn = NDI_FAILURE; 15557 goto phys_create_done; 15558 } 15559 if (guid && (ndi_prop_update_string(DDI_DEV_T_NONE, 15560 *lun_dip, NDI_GUID, guid) != DDI_SUCCESS)) { 15561 mptsas_log(mpt, CE_WARN, "mptsas unable " 15562 "to create guid property for target %d " 15563 "lun %d", target, lun); 15564 ndi_rtn = NDI_FAILURE; 15565 goto phys_create_done; 15566 } 15567 15568 /* 15569 * The following code is to set properties for SM-HBA support, 15570 * it doesn't apply to RAID volumes 15571 */ 15572 if (ptgt->m_addr.mta_phymask == 0) 15573 goto phys_raid_lun; 15574 15575 mutex_enter(&mpt->m_mutex); 15576 15577 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 15578 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 15579 (uint32_t)ptgt->m_devhdl; 15580 rval = mptsas_get_sas_device_page0(mpt, page_address, 15581 &dev_hdl, &dev_sas_wwn, &dev_info, 15582 &physport, &phy_id, &pdev_hdl, 15583 &bay_num, &enclosure, &io_flags); 15584 if (rval != DDI_SUCCESS) { 15585 mutex_exit(&mpt->m_mutex); 15586 mptsas_log(mpt, CE_WARN, "mptsas unable to get" 15587 "parent device for handle %d.", page_address); 15588 ndi_rtn = NDI_FAILURE; 15589 goto phys_create_done; 15590 } 15591 15592 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 15593 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl; 15594 rval = mptsas_get_sas_device_page0(mpt, page_address, 15595 &dev_hdl, &pdev_sas_wwn, &pdev_info, &physport, 15596 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags); 15597 if (rval != DDI_SUCCESS) { 15598 mutex_exit(&mpt->m_mutex); 15599 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15600 "device for handle %d.", page_address); 15601 ndi_rtn = NDI_FAILURE; 15602 goto phys_create_done; 15603 } 15604 15605 mutex_exit(&mpt->m_mutex); 15606 15607 /* 15608 * If this device direct attached to the controller 15609 * set the attached-port to the base wwid 15610 */ 15611 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 15612 != DEVINFO_DIRECT_ATTACHED) { 15613 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 15614 pdev_sas_wwn); 15615 } else { 15616 /* 15617 * Update the iport's attached-port to guid 15618 */ 15619 if (sas_wwn == 0) { 15620 (void) sprintf(wwn_str, "p%x", phy); 15621 } else { 15622 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 15623 } 15624 if (ddi_prop_update_string(DDI_DEV_T_NONE, 15625 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 15626 DDI_PROP_SUCCESS) { 15627 mptsas_log(mpt, CE_WARN, 15628 "mptsas unable to create " 15629 "property for iport target-port" 15630 " %s (sas_wwn)", 15631 wwn_str); 15632 ndi_rtn = NDI_FAILURE; 15633 goto phys_create_done; 15634 } 15635 15636 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 15637 mpt->un.m_base_wwid); 15638 } 15639 15640 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15641 *lun_dip, SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) != 15642 DDI_PROP_SUCCESS) { 15643 mptsas_log(mpt, CE_WARN, 15644 "mptsas unable to create " 15645 "property for iport attached-port %s (sas_wwn)", 15646 attached_wwn_str); 15647 ndi_rtn = NDI_FAILURE; 15648 goto phys_create_done; 15649 } 15650 15651 if (IS_SATA_DEVICE(dev_info)) { 15652 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15653 *lun_dip, MPTSAS_VARIANT, "sata") != 15654 DDI_PROP_SUCCESS) { 15655 mptsas_log(mpt, CE_WARN, 15656 "mptsas unable to create " 15657 "property for device variant "); 15658 ndi_rtn = NDI_FAILURE; 15659 goto phys_create_done; 15660 } 15661 } 15662 15663 if (IS_ATAPI_DEVICE(dev_info)) { 15664 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15665 *lun_dip, MPTSAS_VARIANT, "atapi") != 15666 DDI_PROP_SUCCESS) { 15667 mptsas_log(mpt, CE_WARN, 15668 "mptsas unable to create " 15669 "property for device variant "); 15670 ndi_rtn = NDI_FAILURE; 15671 goto phys_create_done; 15672 } 15673 } 15674 15675 phys_raid_lun: 15676 /* 15677 * if this is a SAS controller, and the target is a SATA 15678 * drive, set the 'pm-capable' property for sd and if on 15679 * an OPL platform, also check if this is an ATAPI 15680 * device. 15681 */ 15682 instance = ddi_get_instance(mpt->m_dip); 15683 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 15684 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 15685 NDBG2(("mptsas%d: creating pm-capable property, " 15686 "target %d", instance, target)); 15687 15688 if ((ndi_prop_update_int(DDI_DEV_T_NONE, 15689 *lun_dip, "pm-capable", 1)) != 15690 DDI_PROP_SUCCESS) { 15691 mptsas_log(mpt, CE_WARN, "mptsas " 15692 "failed to create pm-capable " 15693 "property, target %d", target); 15694 ndi_rtn = NDI_FAILURE; 15695 goto phys_create_done; 15696 } 15697 15698 } 15699 15700 if ((inq->inq_dtype == 0) || (inq->inq_dtype == 5)) { 15701 /* 15702 * add 'obp-path' properties for devinfo 15703 */ 15704 bzero(wwn_str, sizeof (wwn_str)); 15705 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn); 15706 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 15707 if (guid) { 15708 (void) snprintf(component, MAXPATHLEN, 15709 "disk@w%s,%x", wwn_str, lun); 15710 } else { 15711 (void) snprintf(component, MAXPATHLEN, 15712 "disk@p%x,%x", phy, lun); 15713 } 15714 if (ddi_pathname_obp_set(*lun_dip, component) 15715 != DDI_SUCCESS) { 15716 mptsas_log(mpt, CE_WARN, "mpt_sas driver " 15717 "unable to set obp-path for SAS " 15718 "object %s", component); 15719 ndi_rtn = NDI_FAILURE; 15720 goto phys_create_done; 15721 } 15722 } 15723 /* 15724 * Create the phy-num property for non-raid disk 15725 */ 15726 if (ptgt->m_addr.mta_phymask != 0) { 15727 if (ndi_prop_update_int(DDI_DEV_T_NONE, 15728 *lun_dip, "phy-num", ptgt->m_phynum) != 15729 DDI_PROP_SUCCESS) { 15730 mptsas_log(mpt, CE_WARN, "mptsas driver " 15731 "failed to create phy-num property for " 15732 "target %d", target); 15733 ndi_rtn = NDI_FAILURE; 15734 goto phys_create_done; 15735 } 15736 } 15737 phys_create_done: 15738 /* 15739 * If props were setup ok, online the lun 15740 */ 15741 if (ndi_rtn == NDI_SUCCESS) { 15742 /* 15743 * Try to online the new node 15744 */ 15745 ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH); 15746 } 15747 if (ndi_rtn == NDI_SUCCESS) { 15748 mutex_enter(&mpt->m_mutex); 15749 ptgt->m_led_status = 0; 15750 (void) mptsas_flush_led_status(mpt, ptgt); 15751 mutex_exit(&mpt->m_mutex); 15752 } 15753 15754 /* 15755 * If success set rtn flag, else unwire alloc'd lun 15756 */ 15757 if (ndi_rtn != NDI_SUCCESS) { 15758 NDBG12(("mptsas driver unable to online " 15759 "target %d lun %d", target, lun)); 15760 ndi_prop_remove_all(*lun_dip); 15761 (void) ndi_devi_free(*lun_dip); 15762 *lun_dip = NULL; 15763 } 15764 } 15765 15766 scsi_hba_nodename_compatible_free(nodename, compatible); 15767 15768 if (wwn_str != NULL) { 15769 kmem_free(wwn_str, MPTSAS_WWN_STRLEN); 15770 } 15771 if (component != NULL) { 15772 kmem_free(component, MAXPATHLEN); 15773 } 15774 15775 15776 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 15777 } 15778 15779 static int 15780 mptsas_probe_smp(dev_info_t *pdip, uint64_t wwn) 15781 { 15782 mptsas_t *mpt = DIP2MPT(pdip); 15783 struct smp_device smp_sd; 15784 15785 /* XXX An HBA driver should not be allocating an smp_device. */ 15786 bzero(&smp_sd, sizeof (struct smp_device)); 15787 smp_sd.smp_sd_address.smp_a_hba_tran = mpt->m_smptran; 15788 bcopy(&wwn, smp_sd.smp_sd_address.smp_a_wwn, SAS_WWN_BYTE_SIZE); 15789 15790 if (smp_probe(&smp_sd) != DDI_PROBE_SUCCESS) 15791 return (NDI_FAILURE); 15792 return (NDI_SUCCESS); 15793 } 15794 15795 static int 15796 mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, dev_info_t **smp_dip) 15797 { 15798 mptsas_t *mpt = DIP2MPT(pdip); 15799 mptsas_smp_t *psmp = NULL; 15800 int rval; 15801 int phymask; 15802 15803 /* 15804 * Get the physical port associated to the iport 15805 * PHYMASK TODO 15806 */ 15807 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 15808 "phymask", 0); 15809 /* 15810 * Find the smp node in hash table with specified sas address and 15811 * physical port 15812 */ 15813 psmp = mptsas_wwid_to_psmp(mpt, phymask, sas_wwn); 15814 if (psmp == NULL) { 15815 return (DDI_FAILURE); 15816 } 15817 15818 rval = mptsas_online_smp(pdip, psmp, smp_dip); 15819 15820 return (rval); 15821 } 15822 15823 static int 15824 mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 15825 dev_info_t **smp_dip) 15826 { 15827 char wwn_str[MPTSAS_WWN_STRLEN]; 15828 char attached_wwn_str[MPTSAS_WWN_STRLEN]; 15829 int ndi_rtn = NDI_FAILURE; 15830 int rval = 0; 15831 mptsas_smp_t dev_info; 15832 uint32_t page_address; 15833 mptsas_t *mpt = DIP2MPT(pdip); 15834 uint16_t dev_hdl; 15835 uint64_t sas_wwn; 15836 uint64_t smp_sas_wwn; 15837 uint8_t physport; 15838 uint8_t phy_id; 15839 uint16_t pdev_hdl; 15840 uint8_t numphys = 0; 15841 uint16_t i = 0; 15842 char phymask[MPTSAS_MAX_PHYS]; 15843 char *iport = NULL; 15844 mptsas_phymask_t phy_mask = 0; 15845 uint16_t attached_devhdl; 15846 uint16_t bay_num, enclosure, io_flags; 15847 15848 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn); 15849 15850 /* 15851 * Probe smp device, prevent the node of removed device from being 15852 * configured succesfully 15853 */ 15854 if (mptsas_probe_smp(pdip, smp_node->m_addr.mta_wwn) != NDI_SUCCESS) { 15855 return (DDI_FAILURE); 15856 } 15857 15858 if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) { 15859 return (DDI_SUCCESS); 15860 } 15861 15862 ndi_rtn = ndi_devi_alloc(pdip, "smp", DEVI_SID_NODEID, smp_dip); 15863 15864 /* 15865 * if lun alloc success, set props 15866 */ 15867 if (ndi_rtn == NDI_SUCCESS) { 15868 /* 15869 * Set the flavor of the child to be SMP flavored 15870 */ 15871 ndi_flavor_set(*smp_dip, SCSA_FLAVOR_SMP); 15872 15873 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15874 *smp_dip, SMP_WWN, wwn_str) != 15875 DDI_PROP_SUCCESS) { 15876 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15877 "property for smp device %s (sas_wwn)", 15878 wwn_str); 15879 ndi_rtn = NDI_FAILURE; 15880 goto smp_create_done; 15881 } 15882 (void) sprintf(wwn_str, "w%"PRIx64, smp_node->m_addr.mta_wwn); 15883 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15884 *smp_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != 15885 DDI_PROP_SUCCESS) { 15886 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15887 "property for iport target-port %s (sas_wwn)", 15888 wwn_str); 15889 ndi_rtn = NDI_FAILURE; 15890 goto smp_create_done; 15891 } 15892 15893 mutex_enter(&mpt->m_mutex); 15894 15895 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL & 15896 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | smp_node->m_devhdl; 15897 rval = mptsas_get_sas_expander_page0(mpt, page_address, 15898 &dev_info); 15899 if (rval != DDI_SUCCESS) { 15900 mutex_exit(&mpt->m_mutex); 15901 mptsas_log(mpt, CE_WARN, 15902 "mptsas unable to get expander " 15903 "parent device info for %x", page_address); 15904 ndi_rtn = NDI_FAILURE; 15905 goto smp_create_done; 15906 } 15907 15908 smp_node->m_pdevhdl = dev_info.m_pdevhdl; 15909 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 15910 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 15911 (uint32_t)dev_info.m_pdevhdl; 15912 rval = mptsas_get_sas_device_page0(mpt, page_address, 15913 &dev_hdl, &sas_wwn, &smp_node->m_pdevinfo, &physport, 15914 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags); 15915 if (rval != DDI_SUCCESS) { 15916 mutex_exit(&mpt->m_mutex); 15917 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 15918 "device info for %x", page_address); 15919 ndi_rtn = NDI_FAILURE; 15920 goto smp_create_done; 15921 } 15922 15923 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 15924 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 15925 (uint32_t)dev_info.m_devhdl; 15926 rval = mptsas_get_sas_device_page0(mpt, page_address, 15927 &dev_hdl, &smp_sas_wwn, &smp_node->m_deviceinfo, 15928 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure, 15929 &io_flags); 15930 if (rval != DDI_SUCCESS) { 15931 mutex_exit(&mpt->m_mutex); 15932 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 15933 "device info for %x", page_address); 15934 ndi_rtn = NDI_FAILURE; 15935 goto smp_create_done; 15936 } 15937 mutex_exit(&mpt->m_mutex); 15938 15939 /* 15940 * If this smp direct attached to the controller 15941 * set the attached-port to the base wwid 15942 */ 15943 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 15944 != DEVINFO_DIRECT_ATTACHED) { 15945 (void) sprintf(attached_wwn_str, "w%016"PRIx64, 15946 sas_wwn); 15947 } else { 15948 (void) sprintf(attached_wwn_str, "w%016"PRIx64, 15949 mpt->un.m_base_wwid); 15950 } 15951 15952 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15953 *smp_dip, SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwn_str) != 15954 DDI_PROP_SUCCESS) { 15955 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15956 "property for smp attached-port %s (sas_wwn)", 15957 attached_wwn_str); 15958 ndi_rtn = NDI_FAILURE; 15959 goto smp_create_done; 15960 } 15961 15962 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 15963 *smp_dip, SMP_PROP) != DDI_PROP_SUCCESS) { 15964 mptsas_log(mpt, CE_WARN, "mptsas unable to " 15965 "create property for SMP %s (SMP_PROP) ", 15966 wwn_str); 15967 ndi_rtn = NDI_FAILURE; 15968 goto smp_create_done; 15969 } 15970 15971 /* 15972 * check the smp to see whether it direct 15973 * attached to the controller 15974 */ 15975 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 15976 != DEVINFO_DIRECT_ATTACHED) { 15977 goto smp_create_done; 15978 } 15979 numphys = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 15980 DDI_PROP_DONTPASS, MPTSAS_NUM_PHYS, -1); 15981 if (numphys > 0) { 15982 goto smp_create_done; 15983 } 15984 /* 15985 * this iport is an old iport, we need to 15986 * reconfig the props for it. 15987 */ 15988 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip, 15989 MPTSAS_VIRTUAL_PORT, 0) != 15990 DDI_PROP_SUCCESS) { 15991 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 15992 MPTSAS_VIRTUAL_PORT); 15993 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 15994 "prop update failed"); 15995 goto smp_create_done; 15996 } 15997 15998 mutex_enter(&mpt->m_mutex); 15999 numphys = 0; 16000 iport = ddi_get_name_addr(pdip); 16001 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 16002 bzero(phymask, sizeof (phymask)); 16003 (void) sprintf(phymask, 16004 "%x", mpt->m_phy_info[i].phy_mask); 16005 if (strcmp(phymask, iport) == 0) { 16006 phy_mask = mpt->m_phy_info[i].phy_mask; 16007 break; 16008 } 16009 } 16010 16011 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 16012 if ((phy_mask >> i) & 0x01) { 16013 numphys++; 16014 } 16015 } 16016 /* 16017 * Update PHY info for smhba 16018 */ 16019 if (mptsas_smhba_phy_init(mpt)) { 16020 mutex_exit(&mpt->m_mutex); 16021 mptsas_log(mpt, CE_WARN, "mptsas phy update " 16022 "failed"); 16023 goto smp_create_done; 16024 } 16025 mutex_exit(&mpt->m_mutex); 16026 16027 mptsas_smhba_set_all_phy_props(mpt, pdip, numphys, phy_mask, 16028 &attached_devhdl); 16029 16030 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip, 16031 MPTSAS_NUM_PHYS, numphys) != 16032 DDI_PROP_SUCCESS) { 16033 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 16034 MPTSAS_NUM_PHYS); 16035 mptsas_log(mpt, CE_WARN, "mptsas update " 16036 "num phys props failed"); 16037 goto smp_create_done; 16038 } 16039 /* 16040 * Add parent's props for SMHBA support 16041 */ 16042 if (ddi_prop_update_string(DDI_DEV_T_NONE, pdip, 16043 SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 16044 DDI_PROP_SUCCESS) { 16045 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 16046 SCSI_ADDR_PROP_ATTACHED_PORT); 16047 mptsas_log(mpt, CE_WARN, "mptsas update iport" 16048 "attached-port failed"); 16049 goto smp_create_done; 16050 } 16051 16052 smp_create_done: 16053 /* 16054 * If props were setup ok, online the lun 16055 */ 16056 if (ndi_rtn == NDI_SUCCESS) { 16057 /* 16058 * Try to online the new node 16059 */ 16060 ndi_rtn = ndi_devi_online(*smp_dip, NDI_ONLINE_ATTACH); 16061 } 16062 16063 /* 16064 * If success set rtn flag, else unwire alloc'd lun 16065 */ 16066 if (ndi_rtn != NDI_SUCCESS) { 16067 NDBG12(("mptsas unable to online " 16068 "SMP target %s", wwn_str)); 16069 ndi_prop_remove_all(*smp_dip); 16070 (void) ndi_devi_free(*smp_dip); 16071 } 16072 } 16073 16074 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 16075 } 16076 16077 /* smp transport routine */ 16078 static int mptsas_smp_start(struct smp_pkt *smp_pkt) 16079 { 16080 uint64_t wwn; 16081 Mpi2SmpPassthroughRequest_t req; 16082 Mpi2SmpPassthroughReply_t rep; 16083 uint32_t direction = 0; 16084 mptsas_t *mpt; 16085 int ret; 16086 uint64_t tmp64; 16087 16088 mpt = (mptsas_t *)smp_pkt->smp_pkt_address-> 16089 smp_a_hba_tran->smp_tran_hba_private; 16090 16091 bcopy(smp_pkt->smp_pkt_address->smp_a_wwn, &wwn, SAS_WWN_BYTE_SIZE); 16092 /* 16093 * Need to compose a SMP request message 16094 * and call mptsas_do_passthru() function 16095 */ 16096 bzero(&req, sizeof (req)); 16097 bzero(&rep, sizeof (rep)); 16098 req.PassthroughFlags = 0; 16099 req.PhysicalPort = 0xff; 16100 req.ChainOffset = 0; 16101 req.Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 16102 16103 if ((smp_pkt->smp_pkt_reqsize & 0xffff0000ul) != 0) { 16104 smp_pkt->smp_pkt_reason = ERANGE; 16105 return (DDI_FAILURE); 16106 } 16107 req.RequestDataLength = LE_16((uint16_t)(smp_pkt->smp_pkt_reqsize - 4)); 16108 16109 req.MsgFlags = 0; 16110 tmp64 = LE_64(wwn); 16111 bcopy(&tmp64, &req.SASAddress, SAS_WWN_BYTE_SIZE); 16112 if (smp_pkt->smp_pkt_rspsize > 0) { 16113 direction |= MPTSAS_PASS_THRU_DIRECTION_READ; 16114 } 16115 if (smp_pkt->smp_pkt_reqsize > 0) { 16116 direction |= MPTSAS_PASS_THRU_DIRECTION_WRITE; 16117 } 16118 16119 mutex_enter(&mpt->m_mutex); 16120 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, 16121 (uint8_t *)smp_pkt->smp_pkt_rsp, 16122 offsetof(Mpi2SmpPassthroughRequest_t, SGL), sizeof (rep), 16123 smp_pkt->smp_pkt_rspsize - 4, direction, 16124 (uint8_t *)smp_pkt->smp_pkt_req, smp_pkt->smp_pkt_reqsize - 4, 16125 smp_pkt->smp_pkt_timeout, FKIOCTL); 16126 mutex_exit(&mpt->m_mutex); 16127 if (ret != 0) { 16128 cmn_err(CE_WARN, "smp_start do passthru error %d", ret); 16129 smp_pkt->smp_pkt_reason = (uchar_t)(ret); 16130 return (DDI_FAILURE); 16131 } 16132 /* do passthrough success, check the smp status */ 16133 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 16134 switch (LE_16(rep.IOCStatus)) { 16135 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 16136 smp_pkt->smp_pkt_reason = ENODEV; 16137 break; 16138 case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN: 16139 smp_pkt->smp_pkt_reason = EOVERFLOW; 16140 break; 16141 case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED: 16142 smp_pkt->smp_pkt_reason = EIO; 16143 break; 16144 default: 16145 mptsas_log(mpt, CE_NOTE, "smp_start: get unknown ioc" 16146 "status:%x", LE_16(rep.IOCStatus)); 16147 smp_pkt->smp_pkt_reason = EIO; 16148 break; 16149 } 16150 return (DDI_FAILURE); 16151 } 16152 if (rep.SASStatus != MPI2_SASSTATUS_SUCCESS) { 16153 mptsas_log(mpt, CE_NOTE, "smp_start: get error SAS status:%x", 16154 rep.SASStatus); 16155 smp_pkt->smp_pkt_reason = EIO; 16156 return (DDI_FAILURE); 16157 } 16158 16159 return (DDI_SUCCESS); 16160 } 16161 16162 /* 16163 * If we didn't get a match, we need to get sas page0 for each device, and 16164 * untill we get a match. If failed, return NULL 16165 */ 16166 static mptsas_target_t * 16167 mptsas_phy_to_tgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint8_t phy) 16168 { 16169 int i, j = 0; 16170 int rval = 0; 16171 uint16_t cur_handle; 16172 uint32_t page_address; 16173 mptsas_target_t *ptgt = NULL; 16174 16175 /* 16176 * PHY named device must be direct attached and attaches to 16177 * narrow port, if the iport is not parent of the device which 16178 * we are looking for. 16179 */ 16180 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 16181 if ((1 << i) & phymask) 16182 j++; 16183 } 16184 16185 if (j > 1) 16186 return (NULL); 16187 16188 /* 16189 * Must be a narrow port and single device attached to the narrow port 16190 * So the physical port num of device which is equal to the iport's 16191 * port num is the device what we are looking for. 16192 */ 16193 16194 if (mpt->m_phy_info[phy].phy_mask != phymask) 16195 return (NULL); 16196 16197 mutex_enter(&mpt->m_mutex); 16198 16199 ptgt = refhash_linear_search(mpt->m_targets, mptsas_target_eval_nowwn, 16200 &phy); 16201 if (ptgt != NULL) { 16202 mutex_exit(&mpt->m_mutex); 16203 return (ptgt); 16204 } 16205 16206 if (mpt->m_done_traverse_dev) { 16207 mutex_exit(&mpt->m_mutex); 16208 return (NULL); 16209 } 16210 16211 /* If didn't get a match, come here */ 16212 cur_handle = mpt->m_dev_handle; 16213 for (; ; ) { 16214 ptgt = NULL; 16215 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 16216 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)cur_handle; 16217 rval = mptsas_get_target_device_info(mpt, page_address, 16218 &cur_handle, &ptgt); 16219 if ((rval == DEV_INFO_FAIL_PAGE0) || 16220 (rval == DEV_INFO_FAIL_ALLOC) || 16221 (rval == DEV_INFO_FAIL_GUID)) { 16222 break; 16223 } 16224 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) || 16225 (rval == DEV_INFO_PHYS_DISK)) { 16226 continue; 16227 } 16228 mpt->m_dev_handle = cur_handle; 16229 16230 if ((ptgt->m_addr.mta_wwn == 0) && (ptgt->m_phynum == phy)) { 16231 break; 16232 } 16233 } 16234 16235 mutex_exit(&mpt->m_mutex); 16236 return (ptgt); 16237 } 16238 16239 /* 16240 * The ptgt->m_addr.mta_wwn contains the wwid for each disk. 16241 * For Raid volumes, we need to check m_raidvol[x].m_raidwwid 16242 * If we didn't get a match, we need to get sas page0 for each device, and 16243 * untill we get a match 16244 * If failed, return NULL 16245 */ 16246 static mptsas_target_t * 16247 mptsas_wwid_to_ptgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid) 16248 { 16249 int rval = 0; 16250 uint16_t cur_handle; 16251 uint32_t page_address; 16252 mptsas_target_t *tmp_tgt = NULL; 16253 mptsas_target_addr_t addr; 16254 16255 addr.mta_wwn = wwid; 16256 addr.mta_phymask = phymask; 16257 mutex_enter(&mpt->m_mutex); 16258 tmp_tgt = refhash_lookup(mpt->m_targets, &addr); 16259 if (tmp_tgt != NULL) { 16260 mutex_exit(&mpt->m_mutex); 16261 return (tmp_tgt); 16262 } 16263 16264 if (phymask == 0) { 16265 /* 16266 * It's IR volume 16267 */ 16268 rval = mptsas_get_raid_info(mpt); 16269 if (rval) { 16270 tmp_tgt = refhash_lookup(mpt->m_targets, &addr); 16271 } 16272 mutex_exit(&mpt->m_mutex); 16273 return (tmp_tgt); 16274 } 16275 16276 if (mpt->m_done_traverse_dev) { 16277 mutex_exit(&mpt->m_mutex); 16278 return (NULL); 16279 } 16280 16281 /* If didn't get a match, come here */ 16282 cur_handle = mpt->m_dev_handle; 16283 for (;;) { 16284 tmp_tgt = NULL; 16285 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 16286 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle; 16287 rval = mptsas_get_target_device_info(mpt, page_address, 16288 &cur_handle, &tmp_tgt); 16289 if ((rval == DEV_INFO_FAIL_PAGE0) || 16290 (rval == DEV_INFO_FAIL_ALLOC) || 16291 (rval == DEV_INFO_FAIL_GUID)) { 16292 tmp_tgt = NULL; 16293 break; 16294 } 16295 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) || 16296 (rval == DEV_INFO_PHYS_DISK)) { 16297 continue; 16298 } 16299 mpt->m_dev_handle = cur_handle; 16300 if ((tmp_tgt->m_addr.mta_wwn) && 16301 (tmp_tgt->m_addr.mta_wwn == wwid) && 16302 (tmp_tgt->m_addr.mta_phymask == phymask)) { 16303 break; 16304 } 16305 } 16306 16307 mutex_exit(&mpt->m_mutex); 16308 return (tmp_tgt); 16309 } 16310 16311 static mptsas_smp_t * 16312 mptsas_wwid_to_psmp(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid) 16313 { 16314 int rval = 0; 16315 uint16_t cur_handle; 16316 uint32_t page_address; 16317 mptsas_smp_t smp_node, *psmp = NULL; 16318 mptsas_target_addr_t addr; 16319 16320 addr.mta_wwn = wwid; 16321 addr.mta_phymask = phymask; 16322 mutex_enter(&mpt->m_mutex); 16323 psmp = refhash_lookup(mpt->m_smp_targets, &addr); 16324 if (psmp != NULL) { 16325 mutex_exit(&mpt->m_mutex); 16326 return (psmp); 16327 } 16328 16329 if (mpt->m_done_traverse_smp) { 16330 mutex_exit(&mpt->m_mutex); 16331 return (NULL); 16332 } 16333 16334 /* If didn't get a match, come here */ 16335 cur_handle = mpt->m_smp_devhdl; 16336 for (;;) { 16337 psmp = NULL; 16338 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL & 16339 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle; 16340 rval = mptsas_get_sas_expander_page0(mpt, page_address, 16341 &smp_node); 16342 if (rval != DDI_SUCCESS) { 16343 break; 16344 } 16345 mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl; 16346 psmp = mptsas_smp_alloc(mpt, &smp_node); 16347 ASSERT(psmp); 16348 if ((psmp->m_addr.mta_wwn) && (psmp->m_addr.mta_wwn == wwid) && 16349 (psmp->m_addr.mta_phymask == phymask)) { 16350 break; 16351 } 16352 } 16353 16354 mutex_exit(&mpt->m_mutex); 16355 return (psmp); 16356 } 16357 16358 mptsas_target_t * 16359 mptsas_tgt_alloc(refhash_t *refhash, uint16_t devhdl, uint64_t wwid, 16360 uint32_t devinfo, mptsas_phymask_t phymask, uint8_t phynum) 16361 { 16362 mptsas_target_t *tmp_tgt = NULL; 16363 mptsas_target_addr_t addr; 16364 16365 addr.mta_wwn = wwid; 16366 addr.mta_phymask = phymask; 16367 tmp_tgt = refhash_lookup(refhash, &addr); 16368 if (tmp_tgt != NULL) { 16369 NDBG20(("Hash item already exist")); 16370 tmp_tgt->m_deviceinfo = devinfo; 16371 tmp_tgt->m_devhdl = devhdl; /* XXX - duplicate? */ 16372 return (tmp_tgt); 16373 } 16374 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP); 16375 if (tmp_tgt == NULL) { 16376 cmn_err(CE_WARN, "Fatal, allocated tgt failed"); 16377 return (NULL); 16378 } 16379 tmp_tgt->m_devhdl = devhdl; 16380 tmp_tgt->m_addr.mta_wwn = wwid; 16381 tmp_tgt->m_deviceinfo = devinfo; 16382 tmp_tgt->m_addr.mta_phymask = phymask; 16383 tmp_tgt->m_phynum = phynum; 16384 /* Initialized the tgt structure */ 16385 tmp_tgt->m_qfull_retries = QFULL_RETRIES; 16386 tmp_tgt->m_qfull_retry_interval = 16387 drv_usectohz(QFULL_RETRY_INTERVAL * 1000); 16388 tmp_tgt->m_t_throttle = MAX_THROTTLE; 16389 TAILQ_INIT(&tmp_tgt->m_active_cmdq); 16390 16391 refhash_insert(refhash, tmp_tgt); 16392 16393 return (tmp_tgt); 16394 } 16395 16396 static void 16397 mptsas_smp_target_copy(mptsas_smp_t *src, mptsas_smp_t *dst) 16398 { 16399 dst->m_devhdl = src->m_devhdl; 16400 dst->m_deviceinfo = src->m_deviceinfo; 16401 dst->m_pdevhdl = src->m_pdevhdl; 16402 dst->m_pdevinfo = src->m_pdevinfo; 16403 } 16404 16405 static mptsas_smp_t * 16406 mptsas_smp_alloc(mptsas_t *mpt, mptsas_smp_t *data) 16407 { 16408 mptsas_target_addr_t addr; 16409 mptsas_smp_t *ret_data; 16410 16411 addr.mta_wwn = data->m_addr.mta_wwn; 16412 addr.mta_phymask = data->m_addr.mta_phymask; 16413 ret_data = refhash_lookup(mpt->m_smp_targets, &addr); 16414 /* 16415 * If there's already a matching SMP target, update its fields 16416 * in place. Since the address is not changing, it's safe to do 16417 * this. We cannot just bcopy() here because the structure we've 16418 * been given has invalid hash links. 16419 */ 16420 if (ret_data != NULL) { 16421 mptsas_smp_target_copy(data, ret_data); 16422 return (ret_data); 16423 } 16424 16425 ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP); 16426 bcopy(data, ret_data, sizeof (mptsas_smp_t)); 16427 refhash_insert(mpt->m_smp_targets, ret_data); 16428 return (ret_data); 16429 } 16430 16431 /* 16432 * Functions for SGPIO LED support 16433 */ 16434 static dev_info_t * 16435 mptsas_get_dip_from_dev(dev_t dev, mptsas_phymask_t *phymask) 16436 { 16437 dev_info_t *dip; 16438 int prop; 16439 dip = e_ddi_hold_devi_by_dev(dev, 0); 16440 if (dip == NULL) 16441 return (dip); 16442 prop = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 16443 "phymask", 0); 16444 *phymask = (mptsas_phymask_t)prop; 16445 ddi_release_devi(dip); 16446 return (dip); 16447 } 16448 static mptsas_target_t * 16449 mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask) 16450 { 16451 uint8_t phynum; 16452 uint64_t wwn; 16453 int lun; 16454 mptsas_target_t *ptgt = NULL; 16455 16456 if (mptsas_parse_address(addr, &wwn, &phynum, &lun) != DDI_SUCCESS) { 16457 return (NULL); 16458 } 16459 if (addr[0] == 'w') { 16460 ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn); 16461 } else { 16462 ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum); 16463 } 16464 return (ptgt); 16465 } 16466 16467 static int 16468 mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt) 16469 { 16470 uint32_t slotstatus = 0; 16471 16472 /* Build an MPI2 Slot Status based on our view of the world */ 16473 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_IDENT - 1))) 16474 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST; 16475 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_FAIL - 1))) 16476 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT; 16477 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1))) 16478 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE; 16479 16480 /* Write it to the controller */ 16481 NDBG14(("mptsas_ioctl: set LED status %x for slot %x", 16482 slotstatus, ptgt->m_slot_num)); 16483 return (mptsas_send_sep(mpt, ptgt, &slotstatus, 16484 MPI2_SEP_REQ_ACTION_WRITE_STATUS)); 16485 } 16486 16487 /* 16488 * send sep request, use enclosure/slot addressing 16489 */ 16490 static int 16491 mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt, 16492 uint32_t *status, uint8_t act) 16493 { 16494 Mpi2SepRequest_t req; 16495 Mpi2SepReply_t rep; 16496 int ret; 16497 16498 ASSERT(mutex_owned(&mpt->m_mutex)); 16499 16500 /* 16501 * We only support SEP control of directly-attached targets, in which 16502 * case the "SEP" we're talking to is a virtual one contained within 16503 * the HBA itself. This is necessary because DA targets typically have 16504 * no other mechanism for LED control. Targets for which a separate 16505 * enclosure service processor exists should be controlled via ses(7d) 16506 * or sgen(7d). Furthermore, since such requests can time out, they 16507 * should be made in user context rather than in response to 16508 * asynchronous fabric changes. 16509 * 16510 * In addition, we do not support this operation for RAID volumes, 16511 * since there is no slot associated with them. 16512 */ 16513 if (!(ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) || 16514 ptgt->m_addr.mta_phymask == 0) { 16515 return (ENOTTY); 16516 } 16517 16518 bzero(&req, sizeof (req)); 16519 bzero(&rep, sizeof (rep)); 16520 16521 req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; 16522 req.Action = act; 16523 req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS; 16524 req.EnclosureHandle = LE_16(ptgt->m_enclosure); 16525 req.Slot = LE_16(ptgt->m_slot_num); 16526 if (act == MPI2_SEP_REQ_ACTION_WRITE_STATUS) { 16527 req.SlotStatus = LE_32(*status); 16528 } 16529 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL, 16530 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL); 16531 if (ret != 0) { 16532 mptsas_log(mpt, CE_NOTE, "mptsas_send_sep: passthru SEP " 16533 "Processor Request message error %d", ret); 16534 return (ret); 16535 } 16536 /* do passthrough success, check the ioc status */ 16537 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 16538 mptsas_log(mpt, CE_NOTE, "send_sep act %x: ioc " 16539 "status:%x loginfo %x", act, LE_16(rep.IOCStatus), 16540 LE_32(rep.IOCLogInfo)); 16541 switch (LE_16(rep.IOCStatus) & MPI2_IOCSTATUS_MASK) { 16542 case MPI2_IOCSTATUS_INVALID_FUNCTION: 16543 case MPI2_IOCSTATUS_INVALID_VPID: 16544 case MPI2_IOCSTATUS_INVALID_FIELD: 16545 case MPI2_IOCSTATUS_INVALID_STATE: 16546 case MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED: 16547 case MPI2_IOCSTATUS_CONFIG_INVALID_ACTION: 16548 case MPI2_IOCSTATUS_CONFIG_INVALID_TYPE: 16549 case MPI2_IOCSTATUS_CONFIG_INVALID_PAGE: 16550 case MPI2_IOCSTATUS_CONFIG_INVALID_DATA: 16551 case MPI2_IOCSTATUS_CONFIG_NO_DEFAULTS: 16552 return (EINVAL); 16553 case MPI2_IOCSTATUS_BUSY: 16554 return (EBUSY); 16555 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: 16556 return (EAGAIN); 16557 case MPI2_IOCSTATUS_INVALID_SGL: 16558 case MPI2_IOCSTATUS_INTERNAL_ERROR: 16559 case MPI2_IOCSTATUS_CONFIG_CANT_COMMIT: 16560 default: 16561 return (EIO); 16562 } 16563 } 16564 if (act != MPI2_SEP_REQ_ACTION_WRITE_STATUS) { 16565 *status = LE_32(rep.SlotStatus); 16566 } 16567 16568 return (0); 16569 } 16570 16571 int 16572 mptsas_dma_addr_create(mptsas_t *mpt, ddi_dma_attr_t dma_attr, 16573 ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp, caddr_t *dma_memp, 16574 uint32_t alloc_size, ddi_dma_cookie_t *cookiep) 16575 { 16576 ddi_dma_cookie_t new_cookie; 16577 size_t alloc_len; 16578 uint_t ncookie; 16579 16580 if (cookiep == NULL) 16581 cookiep = &new_cookie; 16582 16583 if (ddi_dma_alloc_handle(mpt->m_dip, &dma_attr, DDI_DMA_SLEEP, 16584 NULL, dma_hdp) != DDI_SUCCESS) { 16585 return (FALSE); 16586 } 16587 16588 if (ddi_dma_mem_alloc(*dma_hdp, alloc_size, &mpt->m_dev_acc_attr, 16589 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, dma_memp, &alloc_len, 16590 acc_hdp) != DDI_SUCCESS) { 16591 ddi_dma_free_handle(dma_hdp); 16592 *dma_hdp = NULL; 16593 return (FALSE); 16594 } 16595 16596 if (ddi_dma_addr_bind_handle(*dma_hdp, NULL, *dma_memp, alloc_len, 16597 (DDI_DMA_RDWR | DDI_DMA_CONSISTENT), DDI_DMA_SLEEP, NULL, 16598 cookiep, &ncookie) != DDI_DMA_MAPPED) { 16599 (void) ddi_dma_mem_free(acc_hdp); 16600 ddi_dma_free_handle(dma_hdp); 16601 *dma_hdp = NULL; 16602 return (FALSE); 16603 } 16604 16605 return (TRUE); 16606 } 16607 16608 void 16609 mptsas_dma_addr_destroy(ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp) 16610 { 16611 if (*dma_hdp == NULL) 16612 return; 16613 16614 (void) ddi_dma_unbind_handle(*dma_hdp); 16615 (void) ddi_dma_mem_free(acc_hdp); 16616 ddi_dma_free_handle(dma_hdp); 16617 *dma_hdp = NULL; 16618 }