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 2014 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 */ 28 29 /* 30 * Copyright (c) 2000 to 2010, LSI Corporation. 31 * All rights reserved. 32 * 33 * Redistribution and use in source and binary forms of all code within 34 * this file that is exclusively owned by LSI, with or without 35 * modification, is permitted provided that, in addition to the CDDL 1.0 36 * License requirements, the following conditions are met: 37 * 38 * Neither the name of the author nor the names of its contributors may be 39 * used to endorse or promote products derived from this software without 40 * specific prior written permission. 41 * 42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 45 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 46 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 47 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 48 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 49 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 50 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 51 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 52 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 53 * DAMAGE. 54 */ 55 56 /* 57 * mptsas - This is a driver based on LSI Logic's MPT2.0 interface. 58 * 59 */ 60 61 #if defined(lint) || defined(DEBUG) 62 #define MPTSAS_DEBUG 63 #endif 64 65 /* 66 * standard header files. 67 */ 68 #include <sys/note.h> 69 #include <sys/scsi/scsi.h> 70 #include <sys/pci.h> 71 #include <sys/file.h> 72 #include <sys/policy.h> 73 #include <sys/model.h> 74 #include <sys/sysevent.h> 75 #include <sys/sysevent/eventdefs.h> 76 #include <sys/sysevent/dr.h> 77 #include <sys/sata/sata_defs.h> 78 #include <sys/scsi/generic/sas.h> 79 #include <sys/scsi/impl/scsi_sas.h> 80 81 #pragma pack(1) 82 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h> 83 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h> 84 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h> 85 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h> 86 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h> 87 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h> 88 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h> 89 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h> 90 #pragma pack() 91 92 /* 93 * private header files. 94 * 95 */ 96 #include <sys/scsi/impl/scsi_reset_notify.h> 97 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h> 98 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h> 99 #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h> 100 #include <sys/scsi/adapters/mpt_sas/mptsas_hash.h> 101 #include <sys/raidioctl.h> 102 103 #include <sys/fs/dv_node.h> /* devfs_clean */ 104 105 /* 106 * FMA header files 107 */ 108 #include <sys/ddifm.h> 109 #include <sys/fm/protocol.h> 110 #include <sys/fm/util.h> 111 #include <sys/fm/io/ddi.h> 112 113 /* 114 * autoconfiguration data and routines. 115 */ 116 static int mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 117 static int mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd); 118 static int mptsas_power(dev_info_t *dip, int component, int level); 119 120 /* 121 * cb_ops function 122 */ 123 static int mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, 124 cred_t *credp, int *rval); 125 #ifdef __sparc 126 static int mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd); 127 #else /* __sparc */ 128 static int mptsas_quiesce(dev_info_t *devi); 129 #endif /* __sparc */ 130 131 /* 132 * Resource initilaization for hardware 133 */ 134 static void mptsas_setup_cmd_reg(mptsas_t *mpt); 135 static void mptsas_disable_bus_master(mptsas_t *mpt); 136 static void mptsas_hba_fini(mptsas_t *mpt); 137 static void mptsas_cfg_fini(mptsas_t *mptsas_blkp); 138 static int mptsas_hba_setup(mptsas_t *mpt); 139 static void mptsas_hba_teardown(mptsas_t *mpt); 140 static int mptsas_config_space_init(mptsas_t *mpt); 141 static void mptsas_config_space_fini(mptsas_t *mpt); 142 static void mptsas_iport_register(mptsas_t *mpt); 143 static int mptsas_smp_setup(mptsas_t *mpt); 144 static void mptsas_smp_teardown(mptsas_t *mpt); 145 static int mptsas_cache_create(mptsas_t *mpt); 146 static void mptsas_cache_destroy(mptsas_t *mpt); 147 static int mptsas_alloc_request_frames(mptsas_t *mpt); 148 static int mptsas_alloc_reply_frames(mptsas_t *mpt); 149 static int mptsas_alloc_free_queue(mptsas_t *mpt); 150 static int mptsas_alloc_post_queue(mptsas_t *mpt); 151 static void mptsas_alloc_reply_args(mptsas_t *mpt); 152 static int mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd); 153 static void mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd); 154 static int mptsas_init_chip(mptsas_t *mpt, int first_time); 155 156 /* 157 * SCSA function prototypes 158 */ 159 static int mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt); 160 static int mptsas_scsi_reset(struct scsi_address *ap, int level); 161 static int mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt); 162 static int mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly); 163 static int mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, 164 int tgtonly); 165 static void mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt); 166 static struct scsi_pkt *mptsas_scsi_init_pkt(struct scsi_address *ap, 167 struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen, 168 int tgtlen, int flags, int (*callback)(), caddr_t arg); 169 static void mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt); 170 static void mptsas_scsi_destroy_pkt(struct scsi_address *ap, 171 struct scsi_pkt *pkt); 172 static int mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 173 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 174 static void mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 175 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 176 static int mptsas_scsi_reset_notify(struct scsi_address *ap, int flag, 177 void (*callback)(caddr_t), caddr_t arg); 178 static int mptsas_get_name(struct scsi_device *sd, char *name, int len); 179 static int mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len); 180 static int mptsas_scsi_quiesce(dev_info_t *dip); 181 static int mptsas_scsi_unquiesce(dev_info_t *dip); 182 static int mptsas_bus_config(dev_info_t *pdip, uint_t flags, 183 ddi_bus_config_op_t op, void *arg, dev_info_t **childp); 184 185 /* 186 * SMP functions 187 */ 188 static int mptsas_smp_start(struct smp_pkt *smp_pkt); 189 190 /* 191 * internal function prototypes. 192 */ 193 static void mptsas_list_add(mptsas_t *mpt); 194 static void mptsas_list_del(mptsas_t *mpt); 195 196 static int mptsas_quiesce_bus(mptsas_t *mpt); 197 static int mptsas_unquiesce_bus(mptsas_t *mpt); 198 199 static int mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size); 200 static void mptsas_free_handshake_msg(mptsas_t *mpt); 201 202 static void mptsas_ncmds_checkdrain(void *arg); 203 204 static int mptsas_prepare_pkt(mptsas_cmd_t *cmd); 205 static int mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *sp); 206 static int mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *sp); 207 static void mptsas_accept_tx_waitq(mptsas_t *mpt); 208 209 static int mptsas_do_detach(dev_info_t *dev); 210 static int mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl); 211 static int mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, 212 struct scsi_pkt *pkt); 213 static int mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp); 214 215 static void mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd); 216 static void mptsas_handle_event(void *args); 217 static int mptsas_handle_event_sync(void *args); 218 static void mptsas_handle_dr(void *args); 219 static void mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node, 220 dev_info_t *pdip); 221 222 static void mptsas_restart_cmd(void *); 223 224 static void mptsas_flush_hba(mptsas_t *mpt); 225 static void mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, 226 uint8_t tasktype); 227 static void mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, 228 uchar_t reason, uint_t stat); 229 230 static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2); 231 static void mptsas_process_intr(mptsas_t *mpt, 232 pMpi2ReplyDescriptorsUnion_t reply_desc_union); 233 static void mptsas_handle_scsi_io_success(mptsas_t *mpt, 234 pMpi2ReplyDescriptorsUnion_t reply_desc); 235 static void mptsas_handle_address_reply(mptsas_t *mpt, 236 pMpi2ReplyDescriptorsUnion_t reply_desc); 237 static int mptsas_wait_intr(mptsas_t *mpt, int polltime); 238 static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, 239 uint32_t *control, pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl); 240 241 static void mptsas_watch(void *arg); 242 static void mptsas_watchsubr(mptsas_t *mpt); 243 static void mptsas_cmd_timeout(mptsas_t *mpt, mptsas_target_t *ptgt); 244 245 static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd); 246 static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply, 247 uint8_t *data, uint32_t request_size, uint32_t reply_size, 248 uint32_t data_size, uint32_t direction, uint8_t *dataout, 249 uint32_t dataout_size, short timeout, int mode); 250 static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl); 251 252 static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, 253 uint32_t unique_id); 254 static void mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd); 255 static int mptsas_post_fw_diag_buffer(mptsas_t *mpt, 256 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code); 257 static int mptsas_release_fw_diag_buffer(mptsas_t *mpt, 258 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code, 259 uint32_t diag_type); 260 static int mptsas_diag_register(mptsas_t *mpt, 261 mptsas_fw_diag_register_t *diag_register, uint32_t *return_code); 262 static int mptsas_diag_unregister(mptsas_t *mpt, 263 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code); 264 static int mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query, 265 uint32_t *return_code); 266 static int mptsas_diag_read_buffer(mptsas_t *mpt, 267 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf, 268 uint32_t *return_code, int ioctl_mode); 269 static int mptsas_diag_release(mptsas_t *mpt, 270 mptsas_fw_diag_release_t *diag_release, uint32_t *return_code); 271 static int mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, 272 uint8_t *diag_action, uint32_t length, uint32_t *return_code, 273 int ioctl_mode); 274 static int mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *data, 275 int mode); 276 277 static int mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd, 278 int cmdlen, int tgtlen, int statuslen, int kf); 279 static void mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd); 280 281 static int mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags); 282 static void mptsas_kmem_cache_destructor(void *buf, void *cdrarg); 283 284 static int mptsas_cache_frames_constructor(void *buf, void *cdrarg, 285 int kmflags); 286 static void mptsas_cache_frames_destructor(void *buf, void *cdrarg); 287 288 static void mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, 289 mptsas_cmd_t *cmd); 290 static void mptsas_check_task_mgt(mptsas_t *mpt, 291 pMpi2SCSIManagementReply_t reply, mptsas_cmd_t *cmd); 292 static int mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap, 293 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp, 294 int *resid); 295 296 static int mptsas_alloc_active_slots(mptsas_t *mpt, int flag); 297 static void mptsas_free_active_slots(mptsas_t *mpt); 298 static int mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd); 299 300 static void mptsas_restart_hba(mptsas_t *mpt); 301 static void mptsas_restart_waitq(mptsas_t *mpt); 302 303 static void mptsas_deliver_doneq_thread(mptsas_t *mpt); 304 static void mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd); 305 static void mptsas_doneq_mv(mptsas_t *mpt, uint64_t t); 306 307 static mptsas_cmd_t *mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t); 308 static void mptsas_doneq_empty(mptsas_t *mpt); 309 static void mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg); 310 311 static mptsas_cmd_t *mptsas_waitq_rm(mptsas_t *mpt); 312 static void mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd); 313 static mptsas_cmd_t *mptsas_tx_waitq_rm(mptsas_t *mpt); 314 static void mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd); 315 316 317 static void mptsas_start_watch_reset_delay(); 318 static void mptsas_setup_bus_reset_delay(mptsas_t *mpt); 319 static void mptsas_watch_reset_delay(void *arg); 320 static int mptsas_watch_reset_delay_subr(mptsas_t *mpt); 321 322 /* 323 * helper functions 324 */ 325 static void mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd); 326 327 static dev_info_t *mptsas_find_child(dev_info_t *pdip, char *name); 328 static dev_info_t *mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy); 329 static dev_info_t *mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, 330 int lun); 331 static mdi_pathinfo_t *mptsas_find_path_addr(dev_info_t *pdip, uint64_t sasaddr, 332 int lun); 333 static mdi_pathinfo_t *mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy); 334 static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn); 335 336 static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, 337 int *lun); 338 static int mptsas_parse_smp_name(char *name, uint64_t *wwn); 339 340 static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt, 341 mptsas_phymask_t phymask, uint8_t phy); 342 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt, 343 mptsas_phymask_t phymask, uint64_t wwid); 344 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, 345 mptsas_phymask_t phymask, uint64_t wwid); 346 347 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, 348 uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd); 349 350 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address, 351 uint16_t *handle, mptsas_target_t **pptgt); 352 static void mptsas_update_phymask(mptsas_t *mpt); 353 354 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt, 355 uint32_t *status, uint8_t cmd); 356 static dev_info_t *mptsas_get_dip_from_dev(dev_t dev, 357 mptsas_phymask_t *phymask); 358 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, 359 mptsas_phymask_t phymask); 360 static int mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt); 361 362 363 /* 364 * Enumeration / DR functions 365 */ 366 static void mptsas_config_all(dev_info_t *pdip); 367 static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun, 368 dev_info_t **lundip); 369 static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun, 370 dev_info_t **lundip); 371 372 static int mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt); 373 static int mptsas_offline_target(dev_info_t *pdip, char *name); 374 375 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target, 376 dev_info_t **dip); 377 378 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt); 379 static int mptsas_probe_lun(dev_info_t *pdip, int lun, 380 dev_info_t **dip, mptsas_target_t *ptgt); 381 382 static int mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq, 383 dev_info_t **dip, mptsas_target_t *ptgt, int lun); 384 385 static int mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *sd, 386 char *guid, dev_info_t **dip, mptsas_target_t *ptgt, int lun); 387 static int mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *sd, 388 char *guid, dev_info_t **dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, 389 int lun); 390 391 static void mptsas_offline_missed_luns(dev_info_t *pdip, 392 uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt); 393 static int mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip, 394 mdi_pathinfo_t *rpip, uint_t flags); 395 396 static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, 397 dev_info_t **smp_dip); 398 static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 399 uint_t flags); 400 401 static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, 402 int mode, int *rval); 403 static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, 404 int mode, int *rval); 405 static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, 406 int mode, int *rval); 407 static void mptsas_record_event(void *args); 408 static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, 409 int mode); 410 411 mptsas_target_t *mptsas_tgt_alloc(mptsas_t *, uint16_t, uint64_t, 412 uint32_t, mptsas_phymask_t, uint8_t); 413 static mptsas_smp_t *mptsas_smp_alloc(mptsas_t *, mptsas_smp_t *); 414 static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 415 dev_info_t **smp_dip); 416 417 /* 418 * Power management functions 419 */ 420 static int mptsas_get_pci_cap(mptsas_t *mpt); 421 static int mptsas_init_pm(mptsas_t *mpt); 422 423 /* 424 * MPT MSI tunable: 425 * 426 * By default MSI is enabled on all supported platforms. 427 */ 428 boolean_t mptsas_enable_msi = B_TRUE; 429 boolean_t mptsas_physical_bind_failed_page_83 = B_FALSE; 430 431 static int mptsas_register_intrs(mptsas_t *); 432 static void mptsas_unregister_intrs(mptsas_t *); 433 static int mptsas_add_intrs(mptsas_t *, int); 434 static void mptsas_rem_intrs(mptsas_t *); 435 436 /* 437 * FMA Prototypes 438 */ 439 static void mptsas_fm_init(mptsas_t *mpt); 440 static void mptsas_fm_fini(mptsas_t *mpt); 441 static int mptsas_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *); 442 443 extern pri_t minclsyspri, maxclsyspri; 444 445 /* 446 * This device is created by the SCSI pseudo nexus driver (SCSI vHCI). It is 447 * under this device that the paths to a physical device are created when 448 * MPxIO is used. 449 */ 450 extern dev_info_t *scsi_vhci_dip; 451 452 /* 453 * Tunable timeout value for Inquiry VPD page 0x83 454 * By default the value is 30 seconds. 455 */ 456 int mptsas_inq83_retry_timeout = 30; 457 458 /* 459 * This is used to allocate memory for message frame storage, not for 460 * data I/O DMA. All message frames must be stored in the first 4G of 461 * physical memory. 462 */ 463 ddi_dma_attr_t mptsas_dma_attrs = { 464 DMA_ATTR_V0, /* attribute layout version */ 465 0x0ull, /* address low - should be 0 (longlong) */ 466 0xffffffffull, /* address high - 32-bit max range */ 467 0x00ffffffull, /* count max - max DMA object size */ 468 4, /* allocation alignment requirements */ 469 0x78, /* burstsizes - binary encoded values */ 470 1, /* minxfer - gran. of DMA engine */ 471 0x00ffffffull, /* maxxfer - gran. of DMA engine */ 472 0xffffffffull, /* max segment size (DMA boundary) */ 473 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */ 474 512, /* granularity - device transfer size */ 475 0 /* flags, set to 0 */ 476 }; 477 478 /* 479 * This is used for data I/O DMA memory allocation. (full 64-bit DMA 480 * physical addresses are supported.) 481 */ 482 ddi_dma_attr_t mptsas_dma_attrs64 = { 483 DMA_ATTR_V0, /* attribute layout version */ 484 0x0ull, /* address low - should be 0 (longlong) */ 485 0xffffffffffffffffull, /* address high - 64-bit max */ 486 0x00ffffffull, /* count max - max DMA object size */ 487 4, /* allocation alignment requirements */ 488 0x78, /* burstsizes - binary encoded values */ 489 1, /* minxfer - gran. of DMA engine */ 490 0x00ffffffull, /* maxxfer - gran. of DMA engine */ 491 0xffffffffull, /* max segment size (DMA boundary) */ 492 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */ 493 512, /* granularity - device transfer size */ 494 DDI_DMA_RELAXED_ORDERING /* flags, enable relaxed ordering */ 495 }; 496 497 ddi_device_acc_attr_t mptsas_dev_attr = { 498 DDI_DEVICE_ATTR_V1, 499 DDI_STRUCTURE_LE_ACC, 500 DDI_STRICTORDER_ACC, 501 DDI_DEFAULT_ACC 502 }; 503 504 static struct cb_ops mptsas_cb_ops = { 505 scsi_hba_open, /* open */ 506 scsi_hba_close, /* close */ 507 nodev, /* strategy */ 508 nodev, /* print */ 509 nodev, /* dump */ 510 nodev, /* read */ 511 nodev, /* write */ 512 mptsas_ioctl, /* ioctl */ 513 nodev, /* devmap */ 514 nodev, /* mmap */ 515 nodev, /* segmap */ 516 nochpoll, /* chpoll */ 517 ddi_prop_op, /* cb_prop_op */ 518 NULL, /* streamtab */ 519 D_MP, /* cb_flag */ 520 CB_REV, /* rev */ 521 nodev, /* aread */ 522 nodev /* awrite */ 523 }; 524 525 static struct dev_ops mptsas_ops = { 526 DEVO_REV, /* devo_rev, */ 527 0, /* refcnt */ 528 ddi_no_info, /* info */ 529 nulldev, /* identify */ 530 nulldev, /* probe */ 531 mptsas_attach, /* attach */ 532 mptsas_detach, /* detach */ 533 #ifdef __sparc 534 mptsas_reset, 535 #else 536 nodev, /* reset */ 537 #endif /* __sparc */ 538 &mptsas_cb_ops, /* driver operations */ 539 NULL, /* bus operations */ 540 mptsas_power, /* power management */ 541 #ifdef __sparc 542 ddi_quiesce_not_needed 543 #else 544 mptsas_quiesce /* quiesce */ 545 #endif /* __sparc */ 546 }; 547 548 549 #define MPTSAS_MOD_STRING "MPTSAS HBA Driver 00.00.00.24" 550 551 static struct modldrv modldrv = { 552 &mod_driverops, /* Type of module. This one is a driver */ 553 MPTSAS_MOD_STRING, /* Name of the module. */ 554 &mptsas_ops, /* driver ops */ 555 }; 556 557 static struct modlinkage modlinkage = { 558 MODREV_1, &modldrv, NULL 559 }; 560 #define TARGET_PROP "target" 561 #define LUN_PROP "lun" 562 #define LUN64_PROP "lun64" 563 #define SAS_PROP "sas-mpt" 564 #define MDI_GUID "wwn" 565 #define NDI_GUID "guid" 566 #define MPTSAS_DEV_GONE "mptsas_dev_gone" 567 568 /* 569 * Local static data 570 */ 571 #if defined(MPTSAS_DEBUG) 572 uint32_t mptsas_debug_flags = 0; 573 #endif /* defined(MPTSAS_DEBUG) */ 574 uint32_t mptsas_debug_resets = 0; 575 576 static kmutex_t mptsas_global_mutex; 577 static void *mptsas_state; /* soft state ptr */ 578 static krwlock_t mptsas_global_rwlock; 579 580 static kmutex_t mptsas_log_mutex; 581 static char mptsas_log_buf[256]; 582 _NOTE(MUTEX_PROTECTS_DATA(mptsas_log_mutex, mptsas_log_buf)) 583 584 static mptsas_t *mptsas_head, *mptsas_tail; 585 static clock_t mptsas_scsi_watchdog_tick; 586 static clock_t mptsas_tick; 587 static timeout_id_t mptsas_reset_watch; 588 static timeout_id_t mptsas_timeout_id; 589 static int mptsas_timeouts_enabled = 0; 590 /* 591 * warlock directives 592 */ 593 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt \ 594 mptsas_cmd NcrTableIndirect buf scsi_cdb scsi_status)) 595 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", smp_pkt)) 596 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address)) 597 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", mptsas_tgt_private)) 598 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_hba_tran::tran_tgt_private)) 599 600 /* 601 * SM - HBA statics 602 */ 603 char *mptsas_driver_rev = MPTSAS_MOD_STRING; 604 605 #ifdef MPTSAS_DEBUG 606 void debug_enter(char *); 607 #endif 608 609 /* 610 * Notes: 611 * - scsi_hba_init(9F) initializes SCSI HBA modules 612 * - must call scsi_hba_fini(9F) if modload() fails 613 */ 614 int 615 _init(void) 616 { 617 int status; 618 /* CONSTCOND */ 619 ASSERT(NO_COMPETING_THREADS); 620 621 NDBG0(("_init")); 622 623 status = ddi_soft_state_init(&mptsas_state, MPTSAS_SIZE, 624 MPTSAS_INITIAL_SOFT_SPACE); 625 if (status != 0) { 626 return (status); 627 } 628 629 if ((status = scsi_hba_init(&modlinkage)) != 0) { 630 ddi_soft_state_fini(&mptsas_state); 631 return (status); 632 } 633 634 mutex_init(&mptsas_global_mutex, NULL, MUTEX_DRIVER, NULL); 635 rw_init(&mptsas_global_rwlock, NULL, RW_DRIVER, NULL); 636 mutex_init(&mptsas_log_mutex, NULL, MUTEX_DRIVER, NULL); 637 638 if ((status = mod_install(&modlinkage)) != 0) { 639 mutex_destroy(&mptsas_log_mutex); 640 rw_destroy(&mptsas_global_rwlock); 641 mutex_destroy(&mptsas_global_mutex); 642 ddi_soft_state_fini(&mptsas_state); 643 scsi_hba_fini(&modlinkage); 644 } 645 646 return (status); 647 } 648 649 /* 650 * Notes: 651 * - scsi_hba_fini(9F) uninitializes SCSI HBA modules 652 */ 653 int 654 _fini(void) 655 { 656 int status; 657 /* CONSTCOND */ 658 ASSERT(NO_COMPETING_THREADS); 659 660 NDBG0(("_fini")); 661 662 if ((status = mod_remove(&modlinkage)) == 0) { 663 ddi_soft_state_fini(&mptsas_state); 664 scsi_hba_fini(&modlinkage); 665 mutex_destroy(&mptsas_global_mutex); 666 rw_destroy(&mptsas_global_rwlock); 667 mutex_destroy(&mptsas_log_mutex); 668 } 669 return (status); 670 } 671 672 /* 673 * The loadable-module _info(9E) entry point 674 */ 675 int 676 _info(struct modinfo *modinfop) 677 { 678 /* CONSTCOND */ 679 ASSERT(NO_COMPETING_THREADS); 680 NDBG0(("mptsas _info")); 681 682 return (mod_info(&modlinkage, modinfop)); 683 } 684 685 static int 686 mptsas_target_eval_devhdl(const void *op, void *arg) 687 { 688 uint16_t dh = *(uint16_t *)arg; 689 const mptsas_target_t *tp = op; 690 691 return ((int)tp->m_devhdl - (int)dh); 692 } 693 694 static int 695 mptsas_target_eval_slot(const void *op, void *arg) 696 { 697 mptsas_led_control_t *lcp = arg; 698 const mptsas_target_t *tp = op; 699 700 if (tp->m_enclosure != lcp->Enclosure) 701 return ((int)tp->m_enclosure - (int)lcp->Enclosure); 702 703 return ((int)tp->m_slot_num - (int)lcp->Slot); 704 } 705 706 static int 707 mptsas_target_eval_nowwn(const void *op, void *arg) 708 { 709 uint8_t phy = *(uint8_t *)arg; 710 const mptsas_target_t *tp = op; 711 712 if (tp->m_addr.mta_wwn != 0) 713 return (-1); 714 715 return ((int)tp->m_phynum - (int)phy); 716 } 717 718 static int 719 mptsas_smp_eval_devhdl(const void *op, void *arg) 720 { 721 uint16_t dh = *(uint16_t *)arg; 722 const mptsas_smp_t *sp = op; 723 724 return ((int)sp->m_devhdl - (int)dh); 725 } 726 727 static uint64_t 728 mptsas_target_addr_hash(const void *tp) 729 { 730 const mptsas_target_addr_t *tap = tp; 731 732 return ((tap->mta_wwn & 0xffffffffffffULL) | 733 ((uint64_t)tap->mta_phymask << 48)); 734 } 735 736 static int 737 mptsas_target_addr_cmp(const void *a, const void *b) 738 { 739 const mptsas_target_addr_t *aap = a; 740 const mptsas_target_addr_t *bap = b; 741 742 if (aap->mta_wwn < bap->mta_wwn) 743 return (-1); 744 if (aap->mta_wwn > bap->mta_wwn) 745 return (1); 746 return ((int)bap->mta_phymask - (int)aap->mta_phymask); 747 } 748 749 static void 750 mptsas_target_free(void *op) 751 { 752 kmem_free(op, sizeof (mptsas_target_t)); 753 } 754 755 static void 756 mptsas_smp_free(void *op) 757 { 758 kmem_free(op, sizeof (mptsas_smp_t)); 759 } 760 761 static void 762 mptsas_destroy_hashes(mptsas_t *mpt) 763 { 764 mptsas_target_t *tp; 765 mptsas_smp_t *sp; 766 767 for (tp = refhash_first(mpt->m_targets); tp != NULL; 768 tp = refhash_next(mpt->m_targets, tp)) { 769 refhash_remove(mpt->m_targets, tp); 770 } 771 for (sp = refhash_first(mpt->m_smp_targets); sp != NULL; 772 sp = refhash_next(mpt->m_smp_targets, sp)) { 773 refhash_remove(mpt->m_smp_targets, sp); 774 } 775 refhash_destroy(mpt->m_targets); 776 refhash_destroy(mpt->m_smp_targets); 777 mpt->m_targets = NULL; 778 mpt->m_smp_targets = NULL; 779 } 780 781 static int 782 mptsas_iport_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 783 { 784 dev_info_t *pdip; 785 mptsas_t *mpt; 786 scsi_hba_tran_t *hba_tran; 787 char *iport = NULL; 788 char phymask[MPTSAS_MAX_PHYS]; 789 mptsas_phymask_t phy_mask = 0; 790 int dynamic_port = 0; 791 uint32_t page_address; 792 char initiator_wwnstr[MPTSAS_WWN_STRLEN]; 793 int rval = DDI_FAILURE; 794 int i = 0; 795 uint8_t numphys = 0; 796 uint8_t phy_id; 797 uint8_t phy_port = 0; 798 uint16_t attached_devhdl = 0; 799 uint32_t dev_info; 800 uint64_t attached_sas_wwn; 801 uint16_t dev_hdl; 802 uint16_t pdev_hdl; 803 uint16_t bay_num, enclosure; 804 char attached_wwnstr[MPTSAS_WWN_STRLEN]; 805 806 /* CONSTCOND */ 807 ASSERT(NO_COMPETING_THREADS); 808 809 switch (cmd) { 810 case DDI_ATTACH: 811 break; 812 813 case DDI_RESUME: 814 /* 815 * If this a scsi-iport node, nothing to do here. 816 */ 817 return (DDI_SUCCESS); 818 819 default: 820 return (DDI_FAILURE); 821 } 822 823 pdip = ddi_get_parent(dip); 824 825 if ((hba_tran = ndi_flavorv_get(pdip, SCSA_FLAVOR_SCSI_DEVICE)) == 826 NULL) { 827 cmn_err(CE_WARN, "Failed attach iport because fail to " 828 "get tran vector for the HBA node"); 829 return (DDI_FAILURE); 830 } 831 832 mpt = TRAN2MPT(hba_tran); 833 ASSERT(mpt != NULL); 834 if (mpt == NULL) 835 return (DDI_FAILURE); 836 837 if ((hba_tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == 838 NULL) { 839 mptsas_log(mpt, CE_WARN, "Failed attach iport because fail to " 840 "get tran vector for the iport node"); 841 return (DDI_FAILURE); 842 } 843 844 /* 845 * Overwrite parent's tran_hba_private to iport's tran vector 846 */ 847 hba_tran->tran_hba_private = mpt; 848 849 ddi_report_dev(dip); 850 851 /* 852 * Get SAS address for initiator port according dev_handle 853 */ 854 iport = ddi_get_name_addr(dip); 855 if (iport && strncmp(iport, "v0", 2) == 0) { 856 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 857 MPTSAS_VIRTUAL_PORT, 1) != 858 DDI_PROP_SUCCESS) { 859 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, 860 MPTSAS_VIRTUAL_PORT); 861 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 862 "prop update failed"); 863 return (DDI_FAILURE); 864 } 865 return (DDI_SUCCESS); 866 } 867 868 mutex_enter(&mpt->m_mutex); 869 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 870 bzero(phymask, sizeof (phymask)); 871 (void) sprintf(phymask, 872 "%x", mpt->m_phy_info[i].phy_mask); 873 if (strcmp(phymask, iport) == 0) { 874 break; 875 } 876 } 877 878 if (i == MPTSAS_MAX_PHYS) { 879 mptsas_log(mpt, CE_WARN, "Failed attach port %s because port" 880 "seems not exist", iport); 881 mutex_exit(&mpt->m_mutex); 882 return (DDI_FAILURE); 883 } 884 885 phy_mask = mpt->m_phy_info[i].phy_mask; 886 887 if (mpt->m_phy_info[i].port_flags & AUTO_PORT_CONFIGURATION) 888 dynamic_port = 1; 889 else 890 dynamic_port = 0; 891 892 /* 893 * Update PHY info for smhba 894 */ 895 if (mptsas_smhba_phy_init(mpt)) { 896 mutex_exit(&mpt->m_mutex); 897 mptsas_log(mpt, CE_WARN, "mptsas phy update " 898 "failed"); 899 return (DDI_FAILURE); 900 } 901 902 mutex_exit(&mpt->m_mutex); 903 904 numphys = 0; 905 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 906 if ((phy_mask >> i) & 0x01) { 907 numphys++; 908 } 909 } 910 911 bzero(initiator_wwnstr, sizeof (initiator_wwnstr)); 912 (void) sprintf(initiator_wwnstr, "w%016"PRIx64, 913 mpt->un.m_base_wwid); 914 915 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, 916 SCSI_ADDR_PROP_INITIATOR_PORT, initiator_wwnstr) != 917 DDI_PROP_SUCCESS) { 918 (void) ddi_prop_remove(DDI_DEV_T_NONE, 919 dip, SCSI_ADDR_PROP_INITIATOR_PORT); 920 mptsas_log(mpt, CE_WARN, "mptsas Initiator port " 921 "prop update failed"); 922 return (DDI_FAILURE); 923 } 924 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 925 MPTSAS_NUM_PHYS, numphys) != 926 DDI_PROP_SUCCESS) { 927 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, MPTSAS_NUM_PHYS); 928 return (DDI_FAILURE); 929 } 930 931 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 932 "phymask", phy_mask) != 933 DDI_PROP_SUCCESS) { 934 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "phymask"); 935 mptsas_log(mpt, CE_WARN, "mptsas phy mask " 936 "prop update failed"); 937 return (DDI_FAILURE); 938 } 939 940 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 941 "dynamic-port", dynamic_port) != 942 DDI_PROP_SUCCESS) { 943 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "dynamic-port"); 944 mptsas_log(mpt, CE_WARN, "mptsas dynamic port " 945 "prop update failed"); 946 return (DDI_FAILURE); 947 } 948 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 949 MPTSAS_VIRTUAL_PORT, 0) != 950 DDI_PROP_SUCCESS) { 951 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, 952 MPTSAS_VIRTUAL_PORT); 953 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 954 "prop update failed"); 955 return (DDI_FAILURE); 956 } 957 mptsas_smhba_set_all_phy_props(mpt, dip, numphys, phy_mask, 958 &attached_devhdl); 959 960 mutex_enter(&mpt->m_mutex); 961 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 962 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)attached_devhdl; 963 rval = mptsas_get_sas_device_page0(mpt, page_address, &dev_hdl, 964 &attached_sas_wwn, &dev_info, &phy_port, &phy_id, 965 &pdev_hdl, &bay_num, &enclosure); 966 if (rval != DDI_SUCCESS) { 967 mptsas_log(mpt, CE_WARN, 968 "Failed to get device page0 for handle:%d", 969 attached_devhdl); 970 mutex_exit(&mpt->m_mutex); 971 return (DDI_FAILURE); 972 } 973 974 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 975 bzero(phymask, sizeof (phymask)); 976 (void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask); 977 if (strcmp(phymask, iport) == 0) { 978 (void) sprintf(&mpt->m_phy_info[i].smhba_info.path[0], 979 "%x", 980 mpt->m_phy_info[i].phy_mask); 981 } 982 } 983 mutex_exit(&mpt->m_mutex); 984 985 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 986 (void) sprintf(attached_wwnstr, "w%016"PRIx64, 987 attached_sas_wwn); 988 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, 989 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 990 DDI_PROP_SUCCESS) { 991 (void) ddi_prop_remove(DDI_DEV_T_NONE, 992 dip, SCSI_ADDR_PROP_ATTACHED_PORT); 993 return (DDI_FAILURE); 994 } 995 996 /* Create kstats for each phy on this iport */ 997 998 mptsas_create_phy_stats(mpt, iport, dip); 999 1000 /* 1001 * register sas hba iport with mdi (MPxIO/vhci) 1002 */ 1003 if (mdi_phci_register(MDI_HCI_CLASS_SCSI, 1004 dip, 0) == MDI_SUCCESS) { 1005 mpt->m_mpxio_enable = TRUE; 1006 } 1007 return (DDI_SUCCESS); 1008 } 1009 1010 /* 1011 * Notes: 1012 * Set up all device state and allocate data structures, 1013 * mutexes, condition variables, etc. for device operation. 1014 * Add interrupts needed. 1015 * Return DDI_SUCCESS if device is ready, else return DDI_FAILURE. 1016 */ 1017 static int 1018 mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1019 { 1020 mptsas_t *mpt = NULL; 1021 int instance, i, j; 1022 int doneq_thread_num; 1023 char intr_added = 0; 1024 char map_setup = 0; 1025 char config_setup = 0; 1026 char hba_attach_setup = 0; 1027 char smp_attach_setup = 0; 1028 char mutex_init_done = 0; 1029 char event_taskq_create = 0; 1030 char dr_taskq_create = 0; 1031 char doneq_thread_create = 0; 1032 scsi_hba_tran_t *hba_tran; 1033 uint_t mem_bar = MEM_SPACE; 1034 int rval = DDI_FAILURE; 1035 1036 /* CONSTCOND */ 1037 ASSERT(NO_COMPETING_THREADS); 1038 1039 if (scsi_hba_iport_unit_address(dip)) { 1040 return (mptsas_iport_attach(dip, cmd)); 1041 } 1042 1043 switch (cmd) { 1044 case DDI_ATTACH: 1045 break; 1046 1047 case DDI_RESUME: 1048 if ((hba_tran = ddi_get_driver_private(dip)) == NULL) 1049 return (DDI_FAILURE); 1050 1051 mpt = TRAN2MPT(hba_tran); 1052 1053 if (!mpt) { 1054 return (DDI_FAILURE); 1055 } 1056 1057 /* 1058 * Reset hardware and softc to "no outstanding commands" 1059 * Note that a check condition can result on first command 1060 * to a target. 1061 */ 1062 mutex_enter(&mpt->m_mutex); 1063 1064 /* 1065 * raise power. 1066 */ 1067 if (mpt->m_options & MPTSAS_OPT_PM) { 1068 mutex_exit(&mpt->m_mutex); 1069 (void) pm_busy_component(dip, 0); 1070 rval = pm_power_has_changed(dip, 0, PM_LEVEL_D0); 1071 if (rval == DDI_SUCCESS) { 1072 mutex_enter(&mpt->m_mutex); 1073 } else { 1074 /* 1075 * The pm_raise_power() call above failed, 1076 * and that can only occur if we were unable 1077 * to reset the hardware. This is probably 1078 * due to unhealty hardware, and because 1079 * important filesystems(such as the root 1080 * filesystem) could be on the attached disks, 1081 * it would not be a good idea to continue, 1082 * as we won't be entirely certain we are 1083 * writing correct data. So we panic() here 1084 * to not only prevent possible data corruption, 1085 * but to give developers or end users a hope 1086 * of identifying and correcting any problems. 1087 */ 1088 fm_panic("mptsas could not reset hardware " 1089 "during resume"); 1090 } 1091 } 1092 1093 mpt->m_suspended = 0; 1094 1095 /* 1096 * Reinitialize ioc 1097 */ 1098 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1099 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) { 1100 mutex_exit(&mpt->m_mutex); 1101 if (mpt->m_options & MPTSAS_OPT_PM) { 1102 (void) pm_idle_component(dip, 0); 1103 } 1104 fm_panic("mptsas init chip fail during resume"); 1105 } 1106 /* 1107 * mptsas_update_driver_data needs interrupts so enable them 1108 * first. 1109 */ 1110 MPTSAS_ENABLE_INTR(mpt); 1111 mptsas_update_driver_data(mpt); 1112 1113 /* start requests, if possible */ 1114 mptsas_restart_hba(mpt); 1115 1116 mutex_exit(&mpt->m_mutex); 1117 1118 /* 1119 * Restart watch thread 1120 */ 1121 mutex_enter(&mptsas_global_mutex); 1122 if (mptsas_timeout_id == 0) { 1123 mptsas_timeout_id = timeout(mptsas_watch, NULL, 1124 mptsas_tick); 1125 mptsas_timeouts_enabled = 1; 1126 } 1127 mutex_exit(&mptsas_global_mutex); 1128 1129 /* report idle status to pm framework */ 1130 if (mpt->m_options & MPTSAS_OPT_PM) { 1131 (void) pm_idle_component(dip, 0); 1132 } 1133 1134 return (DDI_SUCCESS); 1135 1136 default: 1137 return (DDI_FAILURE); 1138 1139 } 1140 1141 instance = ddi_get_instance(dip); 1142 1143 /* 1144 * Allocate softc information. 1145 */ 1146 if (ddi_soft_state_zalloc(mptsas_state, instance) != DDI_SUCCESS) { 1147 mptsas_log(NULL, CE_WARN, 1148 "mptsas%d: cannot allocate soft state", instance); 1149 goto fail; 1150 } 1151 1152 mpt = ddi_get_soft_state(mptsas_state, instance); 1153 1154 if (mpt == NULL) { 1155 mptsas_log(NULL, CE_WARN, 1156 "mptsas%d: cannot get soft state", instance); 1157 goto fail; 1158 } 1159 1160 /* Indicate that we are 'sizeof (scsi_*(9S))' clean. */ 1161 scsi_size_clean(dip); 1162 1163 mpt->m_dip = dip; 1164 mpt->m_instance = instance; 1165 1166 /* Make a per-instance copy of the structures */ 1167 mpt->m_io_dma_attr = mptsas_dma_attrs64; 1168 mpt->m_msg_dma_attr = mptsas_dma_attrs; 1169 mpt->m_reg_acc_attr = mptsas_dev_attr; 1170 mpt->m_dev_acc_attr = mptsas_dev_attr; 1171 1172 /* 1173 * Initialize FMA 1174 */ 1175 mpt->m_fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, mpt->m_dip, 1176 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable", 1177 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE | 1178 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE); 1179 1180 mptsas_fm_init(mpt); 1181 1182 if (mptsas_alloc_handshake_msg(mpt, 1183 sizeof (Mpi2SCSITaskManagementRequest_t)) == DDI_FAILURE) { 1184 mptsas_log(mpt, CE_WARN, "cannot initialize handshake msg."); 1185 goto fail; 1186 } 1187 1188 /* 1189 * Setup configuration space 1190 */ 1191 if (mptsas_config_space_init(mpt) == FALSE) { 1192 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init failed"); 1193 goto fail; 1194 } 1195 config_setup++; 1196 1197 if (ddi_regs_map_setup(dip, mem_bar, (caddr_t *)&mpt->m_reg, 1198 0, 0, &mpt->m_reg_acc_attr, &mpt->m_datap) != DDI_SUCCESS) { 1199 mptsas_log(mpt, CE_WARN, "map setup failed"); 1200 goto fail; 1201 } 1202 map_setup++; 1203 1204 /* 1205 * A taskq is created for dealing with the event handler 1206 */ 1207 if ((mpt->m_event_taskq = ddi_taskq_create(dip, "mptsas_event_taskq", 1208 1, TASKQ_DEFAULTPRI, 0)) == NULL) { 1209 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create failed"); 1210 goto fail; 1211 } 1212 event_taskq_create++; 1213 1214 /* 1215 * A taskq is created for dealing with dr events 1216 */ 1217 if ((mpt->m_dr_taskq = ddi_taskq_create(dip, 1218 "mptsas_dr_taskq", 1219 1, TASKQ_DEFAULTPRI, 0)) == NULL) { 1220 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create for discovery " 1221 "failed"); 1222 goto fail; 1223 } 1224 dr_taskq_create++; 1225 1226 mpt->m_doneq_thread_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1227 0, "mptsas_doneq_thread_threshold_prop", 10); 1228 mpt->m_doneq_length_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1229 0, "mptsas_doneq_length_threshold_prop", 8); 1230 mpt->m_doneq_thread_n = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1231 0, "mptsas_doneq_thread_n_prop", 8); 1232 1233 if (mpt->m_doneq_thread_n) { 1234 cv_init(&mpt->m_doneq_thread_cv, NULL, CV_DRIVER, NULL); 1235 mutex_init(&mpt->m_doneq_mutex, NULL, MUTEX_DRIVER, NULL); 1236 1237 mutex_enter(&mpt->m_doneq_mutex); 1238 mpt->m_doneq_thread_id = 1239 kmem_zalloc(sizeof (mptsas_doneq_thread_list_t) 1240 * mpt->m_doneq_thread_n, KM_SLEEP); 1241 1242 for (j = 0; j < mpt->m_doneq_thread_n; j++) { 1243 cv_init(&mpt->m_doneq_thread_id[j].cv, NULL, 1244 CV_DRIVER, NULL); 1245 mutex_init(&mpt->m_doneq_thread_id[j].mutex, NULL, 1246 MUTEX_DRIVER, NULL); 1247 mutex_enter(&mpt->m_doneq_thread_id[j].mutex); 1248 mpt->m_doneq_thread_id[j].flag |= 1249 MPTSAS_DONEQ_THREAD_ACTIVE; 1250 mpt->m_doneq_thread_id[j].arg.mpt = mpt; 1251 mpt->m_doneq_thread_id[j].arg.t = j; 1252 mpt->m_doneq_thread_id[j].threadp = 1253 thread_create(NULL, 0, mptsas_doneq_thread, 1254 &mpt->m_doneq_thread_id[j].arg, 1255 0, &p0, TS_RUN, minclsyspri); 1256 mpt->m_doneq_thread_id[j].donetail = 1257 &mpt->m_doneq_thread_id[j].doneq; 1258 mutex_exit(&mpt->m_doneq_thread_id[j].mutex); 1259 } 1260 mutex_exit(&mpt->m_doneq_mutex); 1261 doneq_thread_create++; 1262 } 1263 1264 /* Initialize mutex used in interrupt handler */ 1265 mutex_init(&mpt->m_mutex, NULL, MUTEX_DRIVER, 1266 DDI_INTR_PRI(mpt->m_intr_pri)); 1267 mutex_init(&mpt->m_passthru_mutex, NULL, MUTEX_DRIVER, NULL); 1268 mutex_init(&mpt->m_tx_waitq_mutex, NULL, MUTEX_DRIVER, 1269 DDI_INTR_PRI(mpt->m_intr_pri)); 1270 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1271 mutex_init(&mpt->m_phy_info[i].smhba_info.phy_mutex, 1272 NULL, MUTEX_DRIVER, 1273 DDI_INTR_PRI(mpt->m_intr_pri)); 1274 } 1275 1276 cv_init(&mpt->m_cv, NULL, CV_DRIVER, NULL); 1277 cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL); 1278 cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL); 1279 cv_init(&mpt->m_config_cv, NULL, CV_DRIVER, NULL); 1280 cv_init(&mpt->m_fw_diag_cv, NULL, CV_DRIVER, NULL); 1281 mutex_init_done++; 1282 1283 /* 1284 * Disable hardware interrupt since we're not ready to 1285 * handle it yet. 1286 */ 1287 MPTSAS_DISABLE_INTR(mpt); 1288 if (mptsas_register_intrs(mpt) == FALSE) 1289 goto fail; 1290 intr_added++; 1291 1292 mutex_enter(&mpt->m_mutex); 1293 /* 1294 * Initialize power management component 1295 */ 1296 if (mpt->m_options & MPTSAS_OPT_PM) { 1297 if (mptsas_init_pm(mpt)) { 1298 mutex_exit(&mpt->m_mutex); 1299 mptsas_log(mpt, CE_WARN, "mptsas pm initialization " 1300 "failed"); 1301 goto fail; 1302 } 1303 } 1304 1305 /* 1306 * Initialize chip using Message Unit Reset, if allowed 1307 */ 1308 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1309 if (mptsas_init_chip(mpt, TRUE) == DDI_FAILURE) { 1310 mutex_exit(&mpt->m_mutex); 1311 mptsas_log(mpt, CE_WARN, "mptsas chip initialization failed"); 1312 goto fail; 1313 } 1314 1315 /* 1316 * Fill in the phy_info structure and get the base WWID 1317 */ 1318 if (mptsas_get_manufacture_page5(mpt) == DDI_FAILURE) { 1319 mptsas_log(mpt, CE_WARN, 1320 "mptsas_get_manufacture_page5 failed!"); 1321 goto fail; 1322 } 1323 1324 if (mptsas_get_sas_io_unit_page_hndshk(mpt)) { 1325 mptsas_log(mpt, CE_WARN, 1326 "mptsas_get_sas_io_unit_page_hndshk failed!"); 1327 goto fail; 1328 } 1329 1330 if (mptsas_get_manufacture_page0(mpt) == DDI_FAILURE) { 1331 mptsas_log(mpt, CE_WARN, 1332 "mptsas_get_manufacture_page0 failed!"); 1333 goto fail; 1334 } 1335 1336 mutex_exit(&mpt->m_mutex); 1337 1338 /* 1339 * Register the iport for multiple port HBA 1340 */ 1341 mptsas_iport_register(mpt); 1342 1343 /* 1344 * initialize SCSI HBA transport structure 1345 */ 1346 if (mptsas_hba_setup(mpt) == FALSE) 1347 goto fail; 1348 hba_attach_setup++; 1349 1350 if (mptsas_smp_setup(mpt) == FALSE) 1351 goto fail; 1352 smp_attach_setup++; 1353 1354 if (mptsas_cache_create(mpt) == FALSE) 1355 goto fail; 1356 1357 mpt->m_scsi_reset_delay = ddi_prop_get_int(DDI_DEV_T_ANY, 1358 dip, 0, "scsi-reset-delay", SCSI_DEFAULT_RESET_DELAY); 1359 if (mpt->m_scsi_reset_delay == 0) { 1360 mptsas_log(mpt, CE_NOTE, 1361 "scsi_reset_delay of 0 is not recommended," 1362 " resetting to SCSI_DEFAULT_RESET_DELAY\n"); 1363 mpt->m_scsi_reset_delay = SCSI_DEFAULT_RESET_DELAY; 1364 } 1365 1366 /* 1367 * Initialize the wait and done FIFO queue 1368 */ 1369 mpt->m_donetail = &mpt->m_doneq; 1370 mpt->m_waitqtail = &mpt->m_waitq; 1371 mpt->m_tx_waitqtail = &mpt->m_tx_waitq; 1372 mpt->m_tx_draining = 0; 1373 1374 /* 1375 * ioc cmd queue initialize 1376 */ 1377 mpt->m_ioc_event_cmdtail = &mpt->m_ioc_event_cmdq; 1378 mpt->m_dev_handle = 0xFFFF; 1379 1380 MPTSAS_ENABLE_INTR(mpt); 1381 1382 /* 1383 * enable event notification 1384 */ 1385 mutex_enter(&mpt->m_mutex); 1386 if (mptsas_ioc_enable_event_notification(mpt)) { 1387 mutex_exit(&mpt->m_mutex); 1388 goto fail; 1389 } 1390 mutex_exit(&mpt->m_mutex); 1391 1392 /* 1393 * Initialize PHY info for smhba 1394 */ 1395 if (mptsas_smhba_setup(mpt)) { 1396 mptsas_log(mpt, CE_WARN, "mptsas phy initialization " 1397 "failed"); 1398 goto fail; 1399 } 1400 1401 /* Check all dma handles allocated in attach */ 1402 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) 1403 != DDI_SUCCESS) || 1404 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) 1405 != DDI_SUCCESS) || 1406 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) 1407 != DDI_SUCCESS) || 1408 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) 1409 != DDI_SUCCESS) || 1410 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) 1411 != DDI_SUCCESS)) { 1412 goto fail; 1413 } 1414 1415 /* Check all acc handles allocated in attach */ 1416 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) || 1417 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) 1418 != DDI_SUCCESS) || 1419 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) 1420 != DDI_SUCCESS) || 1421 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) 1422 != DDI_SUCCESS) || 1423 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) 1424 != DDI_SUCCESS) || 1425 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) 1426 != DDI_SUCCESS) || 1427 (mptsas_check_acc_handle(mpt->m_config_handle) 1428 != DDI_SUCCESS)) { 1429 goto fail; 1430 } 1431 1432 /* 1433 * After this point, we are not going to fail the attach. 1434 */ 1435 /* 1436 * used for mptsas_watch 1437 */ 1438 mptsas_list_add(mpt); 1439 1440 mutex_enter(&mptsas_global_mutex); 1441 if (mptsas_timeouts_enabled == 0) { 1442 mptsas_scsi_watchdog_tick = ddi_prop_get_int(DDI_DEV_T_ANY, 1443 dip, 0, "scsi-watchdog-tick", DEFAULT_WD_TICK); 1444 1445 mptsas_tick = mptsas_scsi_watchdog_tick * 1446 drv_usectohz((clock_t)1000000); 1447 1448 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick); 1449 mptsas_timeouts_enabled = 1; 1450 } 1451 mutex_exit(&mptsas_global_mutex); 1452 1453 /* Print message of HBA present */ 1454 ddi_report_dev(dip); 1455 1456 /* report idle status to pm framework */ 1457 if (mpt->m_options & MPTSAS_OPT_PM) { 1458 (void) pm_idle_component(dip, 0); 1459 } 1460 1461 return (DDI_SUCCESS); 1462 1463 fail: 1464 mptsas_log(mpt, CE_WARN, "attach failed"); 1465 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 1466 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 1467 if (mpt) { 1468 mutex_enter(&mptsas_global_mutex); 1469 1470 if (mptsas_timeout_id && (mptsas_head == NULL)) { 1471 timeout_id_t tid = mptsas_timeout_id; 1472 mptsas_timeouts_enabled = 0; 1473 mptsas_timeout_id = 0; 1474 mutex_exit(&mptsas_global_mutex); 1475 (void) untimeout(tid); 1476 mutex_enter(&mptsas_global_mutex); 1477 } 1478 mutex_exit(&mptsas_global_mutex); 1479 /* deallocate in reverse order */ 1480 mptsas_cache_destroy(mpt); 1481 1482 if (smp_attach_setup) { 1483 mptsas_smp_teardown(mpt); 1484 } 1485 if (hba_attach_setup) { 1486 mptsas_hba_teardown(mpt); 1487 } 1488 1489 if (mpt->m_targets) 1490 refhash_destroy(mpt->m_targets); 1491 if (mpt->m_smp_targets) 1492 refhash_destroy(mpt->m_smp_targets); 1493 1494 if (mpt->m_active) { 1495 mptsas_free_active_slots(mpt); 1496 } 1497 if (intr_added) { 1498 mptsas_unregister_intrs(mpt); 1499 } 1500 1501 if (doneq_thread_create) { 1502 mutex_enter(&mpt->m_doneq_mutex); 1503 doneq_thread_num = mpt->m_doneq_thread_n; 1504 for (j = 0; j < mpt->m_doneq_thread_n; j++) { 1505 mutex_enter(&mpt->m_doneq_thread_id[j].mutex); 1506 mpt->m_doneq_thread_id[j].flag &= 1507 (~MPTSAS_DONEQ_THREAD_ACTIVE); 1508 cv_signal(&mpt->m_doneq_thread_id[j].cv); 1509 mutex_exit(&mpt->m_doneq_thread_id[j].mutex); 1510 } 1511 while (mpt->m_doneq_thread_n) { 1512 cv_wait(&mpt->m_doneq_thread_cv, 1513 &mpt->m_doneq_mutex); 1514 } 1515 for (j = 0; j < doneq_thread_num; j++) { 1516 cv_destroy(&mpt->m_doneq_thread_id[j].cv); 1517 mutex_destroy(&mpt->m_doneq_thread_id[j].mutex); 1518 } 1519 kmem_free(mpt->m_doneq_thread_id, 1520 sizeof (mptsas_doneq_thread_list_t) 1521 * doneq_thread_num); 1522 mutex_exit(&mpt->m_doneq_mutex); 1523 cv_destroy(&mpt->m_doneq_thread_cv); 1524 mutex_destroy(&mpt->m_doneq_mutex); 1525 } 1526 if (event_taskq_create) { 1527 ddi_taskq_destroy(mpt->m_event_taskq); 1528 } 1529 if (dr_taskq_create) { 1530 ddi_taskq_destroy(mpt->m_dr_taskq); 1531 } 1532 if (mutex_init_done) { 1533 mutex_destroy(&mpt->m_tx_waitq_mutex); 1534 mutex_destroy(&mpt->m_passthru_mutex); 1535 mutex_destroy(&mpt->m_mutex); 1536 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1537 mutex_destroy( 1538 &mpt->m_phy_info[i].smhba_info.phy_mutex); 1539 } 1540 cv_destroy(&mpt->m_cv); 1541 cv_destroy(&mpt->m_passthru_cv); 1542 cv_destroy(&mpt->m_fw_cv); 1543 cv_destroy(&mpt->m_config_cv); 1544 cv_destroy(&mpt->m_fw_diag_cv); 1545 } 1546 1547 if (map_setup) { 1548 mptsas_cfg_fini(mpt); 1549 } 1550 if (config_setup) { 1551 mptsas_config_space_fini(mpt); 1552 } 1553 mptsas_free_handshake_msg(mpt); 1554 mptsas_hba_fini(mpt); 1555 1556 mptsas_fm_fini(mpt); 1557 ddi_soft_state_free(mptsas_state, instance); 1558 ddi_prop_remove_all(dip); 1559 } 1560 return (DDI_FAILURE); 1561 } 1562 1563 static int 1564 mptsas_suspend(dev_info_t *devi) 1565 { 1566 mptsas_t *mpt, *g; 1567 scsi_hba_tran_t *tran; 1568 1569 if (scsi_hba_iport_unit_address(devi)) { 1570 return (DDI_SUCCESS); 1571 } 1572 1573 if ((tran = ddi_get_driver_private(devi)) == NULL) 1574 return (DDI_SUCCESS); 1575 1576 mpt = TRAN2MPT(tran); 1577 if (!mpt) { 1578 return (DDI_SUCCESS); 1579 } 1580 1581 mutex_enter(&mpt->m_mutex); 1582 1583 if (mpt->m_suspended++) { 1584 mutex_exit(&mpt->m_mutex); 1585 return (DDI_SUCCESS); 1586 } 1587 1588 /* 1589 * Cancel timeout threads for this mpt 1590 */ 1591 if (mpt->m_quiesce_timeid) { 1592 timeout_id_t tid = mpt->m_quiesce_timeid; 1593 mpt->m_quiesce_timeid = 0; 1594 mutex_exit(&mpt->m_mutex); 1595 (void) untimeout(tid); 1596 mutex_enter(&mpt->m_mutex); 1597 } 1598 1599 if (mpt->m_restart_cmd_timeid) { 1600 timeout_id_t tid = mpt->m_restart_cmd_timeid; 1601 mpt->m_restart_cmd_timeid = 0; 1602 mutex_exit(&mpt->m_mutex); 1603 (void) untimeout(tid); 1604 mutex_enter(&mpt->m_mutex); 1605 } 1606 1607 mutex_exit(&mpt->m_mutex); 1608 1609 (void) pm_idle_component(mpt->m_dip, 0); 1610 1611 /* 1612 * Cancel watch threads if all mpts suspended 1613 */ 1614 rw_enter(&mptsas_global_rwlock, RW_WRITER); 1615 for (g = mptsas_head; g != NULL; g = g->m_next) { 1616 if (!g->m_suspended) 1617 break; 1618 } 1619 rw_exit(&mptsas_global_rwlock); 1620 1621 mutex_enter(&mptsas_global_mutex); 1622 if (g == NULL) { 1623 timeout_id_t tid; 1624 1625 mptsas_timeouts_enabled = 0; 1626 if (mptsas_timeout_id) { 1627 tid = mptsas_timeout_id; 1628 mptsas_timeout_id = 0; 1629 mutex_exit(&mptsas_global_mutex); 1630 (void) untimeout(tid); 1631 mutex_enter(&mptsas_global_mutex); 1632 } 1633 if (mptsas_reset_watch) { 1634 tid = mptsas_reset_watch; 1635 mptsas_reset_watch = 0; 1636 mutex_exit(&mptsas_global_mutex); 1637 (void) untimeout(tid); 1638 mutex_enter(&mptsas_global_mutex); 1639 } 1640 } 1641 mutex_exit(&mptsas_global_mutex); 1642 1643 mutex_enter(&mpt->m_mutex); 1644 1645 /* 1646 * If this mpt is not in full power(PM_LEVEL_D0), just return. 1647 */ 1648 if ((mpt->m_options & MPTSAS_OPT_PM) && 1649 (mpt->m_power_level != PM_LEVEL_D0)) { 1650 mutex_exit(&mpt->m_mutex); 1651 return (DDI_SUCCESS); 1652 } 1653 1654 /* Disable HBA interrupts in hardware */ 1655 MPTSAS_DISABLE_INTR(mpt); 1656 /* 1657 * Send RAID action system shutdown to sync IR 1658 */ 1659 mptsas_raid_action_system_shutdown(mpt); 1660 1661 mutex_exit(&mpt->m_mutex); 1662 1663 /* drain the taskq */ 1664 ddi_taskq_wait(mpt->m_event_taskq); 1665 ddi_taskq_wait(mpt->m_dr_taskq); 1666 1667 return (DDI_SUCCESS); 1668 } 1669 1670 #ifdef __sparc 1671 /*ARGSUSED*/ 1672 static int 1673 mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd) 1674 { 1675 mptsas_t *mpt; 1676 scsi_hba_tran_t *tran; 1677 1678 /* 1679 * If this call is for iport, just return. 1680 */ 1681 if (scsi_hba_iport_unit_address(devi)) 1682 return (DDI_SUCCESS); 1683 1684 if ((tran = ddi_get_driver_private(devi)) == NULL) 1685 return (DDI_SUCCESS); 1686 1687 if ((mpt = TRAN2MPT(tran)) == NULL) 1688 return (DDI_SUCCESS); 1689 1690 /* 1691 * Send RAID action system shutdown to sync IR. Disable HBA 1692 * interrupts in hardware first. 1693 */ 1694 MPTSAS_DISABLE_INTR(mpt); 1695 mptsas_raid_action_system_shutdown(mpt); 1696 1697 return (DDI_SUCCESS); 1698 } 1699 #else /* __sparc */ 1700 /* 1701 * quiesce(9E) entry point. 1702 * 1703 * This function is called when the system is single-threaded at high 1704 * PIL with preemption disabled. Therefore, this function must not be 1705 * blocked. 1706 * 1707 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 1708 * DDI_FAILURE indicates an error condition and should almost never happen. 1709 */ 1710 static int 1711 mptsas_quiesce(dev_info_t *devi) 1712 { 1713 mptsas_t *mpt; 1714 scsi_hba_tran_t *tran; 1715 1716 /* 1717 * If this call is for iport, just return. 1718 */ 1719 if (scsi_hba_iport_unit_address(devi)) 1720 return (DDI_SUCCESS); 1721 1722 if ((tran = ddi_get_driver_private(devi)) == NULL) 1723 return (DDI_SUCCESS); 1724 1725 if ((mpt = TRAN2MPT(tran)) == NULL) 1726 return (DDI_SUCCESS); 1727 1728 /* Disable HBA interrupts in hardware */ 1729 MPTSAS_DISABLE_INTR(mpt); 1730 /* Send RAID action system shutdonw to sync IR */ 1731 mptsas_raid_action_system_shutdown(mpt); 1732 1733 return (DDI_SUCCESS); 1734 } 1735 #endif /* __sparc */ 1736 1737 /* 1738 * detach(9E). Remove all device allocations and system resources; 1739 * disable device interrupts. 1740 * Return DDI_SUCCESS if done; DDI_FAILURE if there's a problem. 1741 */ 1742 static int 1743 mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 1744 { 1745 /* CONSTCOND */ 1746 ASSERT(NO_COMPETING_THREADS); 1747 NDBG0(("mptsas_detach: dip=0x%p cmd=0x%p", (void *)devi, (void *)cmd)); 1748 1749 switch (cmd) { 1750 case DDI_DETACH: 1751 return (mptsas_do_detach(devi)); 1752 1753 case DDI_SUSPEND: 1754 return (mptsas_suspend(devi)); 1755 1756 default: 1757 return (DDI_FAILURE); 1758 } 1759 /* NOTREACHED */ 1760 } 1761 1762 static int 1763 mptsas_do_detach(dev_info_t *dip) 1764 { 1765 mptsas_t *mpt; 1766 scsi_hba_tran_t *tran; 1767 int circ = 0; 1768 int circ1 = 0; 1769 mdi_pathinfo_t *pip = NULL; 1770 int i; 1771 int doneq_thread_num = 0; 1772 1773 NDBG0(("mptsas_do_detach: dip=0x%p", (void *)dip)); 1774 1775 if ((tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == NULL) 1776 return (DDI_FAILURE); 1777 1778 mpt = TRAN2MPT(tran); 1779 if (!mpt) { 1780 return (DDI_FAILURE); 1781 } 1782 /* 1783 * Still have pathinfo child, should not detach mpt driver 1784 */ 1785 if (scsi_hba_iport_unit_address(dip)) { 1786 if (mpt->m_mpxio_enable) { 1787 /* 1788 * MPxIO enabled for the iport 1789 */ 1790 ndi_devi_enter(scsi_vhci_dip, &circ1); 1791 ndi_devi_enter(dip, &circ); 1792 while (pip = mdi_get_next_client_path(dip, NULL)) { 1793 if (mdi_pi_free(pip, 0) == MDI_SUCCESS) { 1794 continue; 1795 } 1796 ndi_devi_exit(dip, circ); 1797 ndi_devi_exit(scsi_vhci_dip, circ1); 1798 NDBG12(("detach failed because of " 1799 "outstanding path info")); 1800 return (DDI_FAILURE); 1801 } 1802 ndi_devi_exit(dip, circ); 1803 ndi_devi_exit(scsi_vhci_dip, circ1); 1804 (void) mdi_phci_unregister(dip, 0); 1805 } 1806 1807 ddi_prop_remove_all(dip); 1808 1809 return (DDI_SUCCESS); 1810 } 1811 1812 /* Make sure power level is D0 before accessing registers */ 1813 if (mpt->m_options & MPTSAS_OPT_PM) { 1814 (void) pm_busy_component(dip, 0); 1815 if (mpt->m_power_level != PM_LEVEL_D0) { 1816 if (pm_raise_power(dip, 0, PM_LEVEL_D0) != 1817 DDI_SUCCESS) { 1818 mptsas_log(mpt, CE_WARN, 1819 "mptsas%d: Raise power request failed.", 1820 mpt->m_instance); 1821 (void) pm_idle_component(dip, 0); 1822 return (DDI_FAILURE); 1823 } 1824 } 1825 } 1826 1827 /* 1828 * Send RAID action system shutdown to sync IR. After action, send a 1829 * Message Unit Reset. Since after that DMA resource will be freed, 1830 * set ioc to READY state will avoid HBA initiated DMA operation. 1831 */ 1832 mutex_enter(&mpt->m_mutex); 1833 MPTSAS_DISABLE_INTR(mpt); 1834 mptsas_raid_action_system_shutdown(mpt); 1835 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1836 (void) mptsas_ioc_reset(mpt, FALSE); 1837 mutex_exit(&mpt->m_mutex); 1838 mptsas_rem_intrs(mpt); 1839 ddi_taskq_destroy(mpt->m_event_taskq); 1840 ddi_taskq_destroy(mpt->m_dr_taskq); 1841 1842 if (mpt->m_doneq_thread_n) { 1843 mutex_enter(&mpt->m_doneq_mutex); 1844 doneq_thread_num = mpt->m_doneq_thread_n; 1845 for (i = 0; i < mpt->m_doneq_thread_n; i++) { 1846 mutex_enter(&mpt->m_doneq_thread_id[i].mutex); 1847 mpt->m_doneq_thread_id[i].flag &= 1848 (~MPTSAS_DONEQ_THREAD_ACTIVE); 1849 cv_signal(&mpt->m_doneq_thread_id[i].cv); 1850 mutex_exit(&mpt->m_doneq_thread_id[i].mutex); 1851 } 1852 while (mpt->m_doneq_thread_n) { 1853 cv_wait(&mpt->m_doneq_thread_cv, 1854 &mpt->m_doneq_mutex); 1855 } 1856 for (i = 0; i < doneq_thread_num; i++) { 1857 cv_destroy(&mpt->m_doneq_thread_id[i].cv); 1858 mutex_destroy(&mpt->m_doneq_thread_id[i].mutex); 1859 } 1860 kmem_free(mpt->m_doneq_thread_id, 1861 sizeof (mptsas_doneq_thread_list_t) 1862 * doneq_thread_num); 1863 mutex_exit(&mpt->m_doneq_mutex); 1864 cv_destroy(&mpt->m_doneq_thread_cv); 1865 mutex_destroy(&mpt->m_doneq_mutex); 1866 } 1867 1868 scsi_hba_reset_notify_tear_down(mpt->m_reset_notify_listf); 1869 1870 mptsas_list_del(mpt); 1871 1872 /* 1873 * Cancel timeout threads for this mpt 1874 */ 1875 mutex_enter(&mpt->m_mutex); 1876 if (mpt->m_quiesce_timeid) { 1877 timeout_id_t tid = mpt->m_quiesce_timeid; 1878 mpt->m_quiesce_timeid = 0; 1879 mutex_exit(&mpt->m_mutex); 1880 (void) untimeout(tid); 1881 mutex_enter(&mpt->m_mutex); 1882 } 1883 1884 if (mpt->m_restart_cmd_timeid) { 1885 timeout_id_t tid = mpt->m_restart_cmd_timeid; 1886 mpt->m_restart_cmd_timeid = 0; 1887 mutex_exit(&mpt->m_mutex); 1888 (void) untimeout(tid); 1889 mutex_enter(&mpt->m_mutex); 1890 } 1891 1892 mutex_exit(&mpt->m_mutex); 1893 1894 /* 1895 * last mpt? ... if active, CANCEL watch threads. 1896 */ 1897 mutex_enter(&mptsas_global_mutex); 1898 if (mptsas_head == NULL) { 1899 timeout_id_t tid; 1900 /* 1901 * Clear mptsas_timeouts_enable so that the watch thread 1902 * gets restarted on DDI_ATTACH 1903 */ 1904 mptsas_timeouts_enabled = 0; 1905 if (mptsas_timeout_id) { 1906 tid = mptsas_timeout_id; 1907 mptsas_timeout_id = 0; 1908 mutex_exit(&mptsas_global_mutex); 1909 (void) untimeout(tid); 1910 mutex_enter(&mptsas_global_mutex); 1911 } 1912 if (mptsas_reset_watch) { 1913 tid = mptsas_reset_watch; 1914 mptsas_reset_watch = 0; 1915 mutex_exit(&mptsas_global_mutex); 1916 (void) untimeout(tid); 1917 mutex_enter(&mptsas_global_mutex); 1918 } 1919 } 1920 mutex_exit(&mptsas_global_mutex); 1921 1922 /* 1923 * Delete Phy stats 1924 */ 1925 mptsas_destroy_phy_stats(mpt); 1926 1927 mptsas_destroy_hashes(mpt); 1928 1929 /* 1930 * Delete nt_active. 1931 */ 1932 mutex_enter(&mpt->m_mutex); 1933 mptsas_free_active_slots(mpt); 1934 mutex_exit(&mpt->m_mutex); 1935 1936 /* deallocate everything that was allocated in mptsas_attach */ 1937 mptsas_cache_destroy(mpt); 1938 1939 mptsas_hba_fini(mpt); 1940 mptsas_cfg_fini(mpt); 1941 1942 /* Lower the power informing PM Framework */ 1943 if (mpt->m_options & MPTSAS_OPT_PM) { 1944 if (pm_lower_power(dip, 0, PM_LEVEL_D3) != DDI_SUCCESS) 1945 mptsas_log(mpt, CE_WARN, 1946 "!mptsas%d: Lower power request failed " 1947 "during detach, ignoring.", 1948 mpt->m_instance); 1949 } 1950 1951 mutex_destroy(&mpt->m_tx_waitq_mutex); 1952 mutex_destroy(&mpt->m_passthru_mutex); 1953 mutex_destroy(&mpt->m_mutex); 1954 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1955 mutex_destroy(&mpt->m_phy_info[i].smhba_info.phy_mutex); 1956 } 1957 cv_destroy(&mpt->m_cv); 1958 cv_destroy(&mpt->m_passthru_cv); 1959 cv_destroy(&mpt->m_fw_cv); 1960 cv_destroy(&mpt->m_config_cv); 1961 cv_destroy(&mpt->m_fw_diag_cv); 1962 1963 1964 mptsas_smp_teardown(mpt); 1965 mptsas_hba_teardown(mpt); 1966 1967 mptsas_config_space_fini(mpt); 1968 1969 mptsas_free_handshake_msg(mpt); 1970 1971 mptsas_fm_fini(mpt); 1972 ddi_soft_state_free(mptsas_state, ddi_get_instance(dip)); 1973 ddi_prop_remove_all(dip); 1974 1975 return (DDI_SUCCESS); 1976 } 1977 1978 static void 1979 mptsas_list_add(mptsas_t *mpt) 1980 { 1981 rw_enter(&mptsas_global_rwlock, RW_WRITER); 1982 1983 if (mptsas_head == NULL) { 1984 mptsas_head = mpt; 1985 } else { 1986 mptsas_tail->m_next = mpt; 1987 } 1988 mptsas_tail = mpt; 1989 rw_exit(&mptsas_global_rwlock); 1990 } 1991 1992 static void 1993 mptsas_list_del(mptsas_t *mpt) 1994 { 1995 mptsas_t *m; 1996 /* 1997 * Remove device instance from the global linked list 1998 */ 1999 rw_enter(&mptsas_global_rwlock, RW_WRITER); 2000 if (mptsas_head == mpt) { 2001 m = mptsas_head = mpt->m_next; 2002 } else { 2003 for (m = mptsas_head; m != NULL; m = m->m_next) { 2004 if (m->m_next == mpt) { 2005 m->m_next = mpt->m_next; 2006 break; 2007 } 2008 } 2009 if (m == NULL) { 2010 mptsas_log(mpt, CE_PANIC, "Not in softc list!"); 2011 } 2012 } 2013 2014 if (mptsas_tail == mpt) { 2015 mptsas_tail = m; 2016 } 2017 rw_exit(&mptsas_global_rwlock); 2018 } 2019 2020 static int 2021 mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size) 2022 { 2023 ddi_dma_attr_t task_dma_attrs; 2024 2025 mpt->m_hshk_dma_size = 0; 2026 task_dma_attrs = mpt->m_msg_dma_attr; 2027 task_dma_attrs.dma_attr_sgllen = 1; 2028 task_dma_attrs.dma_attr_granular = (uint32_t)(alloc_size); 2029 2030 /* allocate Task Management ddi_dma resources */ 2031 if (mptsas_dma_addr_create(mpt, task_dma_attrs, 2032 &mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl, &mpt->m_hshk_memp, 2033 alloc_size, NULL) == FALSE) { 2034 return (DDI_FAILURE); 2035 } 2036 mpt->m_hshk_dma_size = alloc_size; 2037 2038 return (DDI_SUCCESS); 2039 } 2040 2041 static void 2042 mptsas_free_handshake_msg(mptsas_t *mpt) 2043 { 2044 if (mpt->m_hshk_dma_size == 0) 2045 return; 2046 mptsas_dma_addr_destroy(&mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl); 2047 mpt->m_hshk_dma_size = 0; 2048 } 2049 2050 static int 2051 mptsas_hba_setup(mptsas_t *mpt) 2052 { 2053 scsi_hba_tran_t *hba_tran; 2054 int tran_flags; 2055 2056 /* Allocate a transport structure */ 2057 hba_tran = mpt->m_tran = scsi_hba_tran_alloc(mpt->m_dip, 2058 SCSI_HBA_CANSLEEP); 2059 ASSERT(mpt->m_tran != NULL); 2060 2061 hba_tran->tran_hba_private = mpt; 2062 hba_tran->tran_tgt_private = NULL; 2063 2064 hba_tran->tran_tgt_init = mptsas_scsi_tgt_init; 2065 hba_tran->tran_tgt_free = mptsas_scsi_tgt_free; 2066 2067 hba_tran->tran_start = mptsas_scsi_start; 2068 hba_tran->tran_reset = mptsas_scsi_reset; 2069 hba_tran->tran_abort = mptsas_scsi_abort; 2070 hba_tran->tran_getcap = mptsas_scsi_getcap; 2071 hba_tran->tran_setcap = mptsas_scsi_setcap; 2072 hba_tran->tran_init_pkt = mptsas_scsi_init_pkt; 2073 hba_tran->tran_destroy_pkt = mptsas_scsi_destroy_pkt; 2074 2075 hba_tran->tran_dmafree = mptsas_scsi_dmafree; 2076 hba_tran->tran_sync_pkt = mptsas_scsi_sync_pkt; 2077 hba_tran->tran_reset_notify = mptsas_scsi_reset_notify; 2078 2079 hba_tran->tran_get_bus_addr = mptsas_get_bus_addr; 2080 hba_tran->tran_get_name = mptsas_get_name; 2081 2082 hba_tran->tran_quiesce = mptsas_scsi_quiesce; 2083 hba_tran->tran_unquiesce = mptsas_scsi_unquiesce; 2084 hba_tran->tran_bus_reset = NULL; 2085 2086 hba_tran->tran_add_eventcall = NULL; 2087 hba_tran->tran_get_eventcookie = NULL; 2088 hba_tran->tran_post_event = NULL; 2089 hba_tran->tran_remove_eventcall = NULL; 2090 2091 hba_tran->tran_bus_config = mptsas_bus_config; 2092 2093 hba_tran->tran_interconnect_type = INTERCONNECT_SAS; 2094 2095 /* 2096 * All children of the HBA are iports. We need tran was cloned. 2097 * So we pass the flags to SCSA. SCSI_HBA_TRAN_CLONE will be 2098 * inherited to iport's tran vector. 2099 */ 2100 tran_flags = (SCSI_HBA_HBA | SCSI_HBA_TRAN_CLONE); 2101 2102 if (scsi_hba_attach_setup(mpt->m_dip, &mpt->m_msg_dma_attr, 2103 hba_tran, tran_flags) != DDI_SUCCESS) { 2104 mptsas_log(mpt, CE_WARN, "hba attach setup failed"); 2105 scsi_hba_tran_free(hba_tran); 2106 mpt->m_tran = NULL; 2107 return (FALSE); 2108 } 2109 return (TRUE); 2110 } 2111 2112 static void 2113 mptsas_hba_teardown(mptsas_t *mpt) 2114 { 2115 (void) scsi_hba_detach(mpt->m_dip); 2116 if (mpt->m_tran != NULL) { 2117 scsi_hba_tran_free(mpt->m_tran); 2118 mpt->m_tran = NULL; 2119 } 2120 } 2121 2122 static void 2123 mptsas_iport_register(mptsas_t *mpt) 2124 { 2125 int i, j; 2126 mptsas_phymask_t mask = 0x0; 2127 /* 2128 * initial value of mask is 0 2129 */ 2130 mutex_enter(&mpt->m_mutex); 2131 for (i = 0; i < mpt->m_num_phys; i++) { 2132 mptsas_phymask_t phy_mask = 0x0; 2133 char phy_mask_name[MPTSAS_MAX_PHYS]; 2134 uint8_t current_port; 2135 2136 if (mpt->m_phy_info[i].attached_devhdl == 0) 2137 continue; 2138 2139 bzero(phy_mask_name, sizeof (phy_mask_name)); 2140 2141 current_port = mpt->m_phy_info[i].port_num; 2142 2143 if ((mask & (1 << i)) != 0) 2144 continue; 2145 2146 for (j = 0; j < mpt->m_num_phys; j++) { 2147 if (mpt->m_phy_info[j].attached_devhdl && 2148 (mpt->m_phy_info[j].port_num == current_port)) { 2149 phy_mask |= (1 << j); 2150 } 2151 } 2152 mask = mask | phy_mask; 2153 2154 for (j = 0; j < mpt->m_num_phys; j++) { 2155 if ((phy_mask >> j) & 0x01) { 2156 mpt->m_phy_info[j].phy_mask = phy_mask; 2157 } 2158 } 2159 2160 (void) sprintf(phy_mask_name, "%x", phy_mask); 2161 2162 mutex_exit(&mpt->m_mutex); 2163 /* 2164 * register a iport 2165 */ 2166 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name); 2167 mutex_enter(&mpt->m_mutex); 2168 } 2169 mutex_exit(&mpt->m_mutex); 2170 /* 2171 * register a virtual port for RAID volume always 2172 */ 2173 (void) scsi_hba_iport_register(mpt->m_dip, "v0"); 2174 2175 } 2176 2177 static int 2178 mptsas_smp_setup(mptsas_t *mpt) 2179 { 2180 mpt->m_smptran = smp_hba_tran_alloc(mpt->m_dip); 2181 ASSERT(mpt->m_smptran != NULL); 2182 mpt->m_smptran->smp_tran_hba_private = mpt; 2183 mpt->m_smptran->smp_tran_start = mptsas_smp_start; 2184 if (smp_hba_attach_setup(mpt->m_dip, mpt->m_smptran) != DDI_SUCCESS) { 2185 mptsas_log(mpt, CE_WARN, "smp attach setup failed"); 2186 smp_hba_tran_free(mpt->m_smptran); 2187 mpt->m_smptran = NULL; 2188 return (FALSE); 2189 } 2190 /* 2191 * Initialize smp hash table 2192 */ 2193 mpt->m_smp_targets = refhash_create(MPTSAS_SMP_BUCKET_COUNT, 2194 mptsas_target_addr_hash, mptsas_target_addr_cmp, 2195 mptsas_smp_free, sizeof (mptsas_smp_t), 2196 offsetof(mptsas_smp_t, m_link), offsetof(mptsas_smp_t, m_addr), 2197 KM_SLEEP); 2198 mpt->m_smp_devhdl = 0xFFFF; 2199 2200 return (TRUE); 2201 } 2202 2203 static void 2204 mptsas_smp_teardown(mptsas_t *mpt) 2205 { 2206 (void) smp_hba_detach(mpt->m_dip); 2207 if (mpt->m_smptran != NULL) { 2208 smp_hba_tran_free(mpt->m_smptran); 2209 mpt->m_smptran = NULL; 2210 } 2211 mpt->m_smp_devhdl = 0; 2212 } 2213 2214 static int 2215 mptsas_cache_create(mptsas_t *mpt) 2216 { 2217 int instance = mpt->m_instance; 2218 char buf[64]; 2219 2220 /* 2221 * create kmem cache for packets 2222 */ 2223 (void) sprintf(buf, "mptsas%d_cache", instance); 2224 mpt->m_kmem_cache = kmem_cache_create(buf, 2225 sizeof (struct mptsas_cmd) + scsi_pkt_size(), 8, 2226 mptsas_kmem_cache_constructor, mptsas_kmem_cache_destructor, 2227 NULL, (void *)mpt, NULL, 0); 2228 2229 if (mpt->m_kmem_cache == NULL) { 2230 mptsas_log(mpt, CE_WARN, "creating kmem cache failed"); 2231 return (FALSE); 2232 } 2233 2234 /* 2235 * create kmem cache for extra SGL frames if SGL cannot 2236 * be accomodated into main request frame. 2237 */ 2238 (void) sprintf(buf, "mptsas%d_cache_frames", instance); 2239 mpt->m_cache_frames = kmem_cache_create(buf, 2240 sizeof (mptsas_cache_frames_t), 8, 2241 mptsas_cache_frames_constructor, mptsas_cache_frames_destructor, 2242 NULL, (void *)mpt, NULL, 0); 2243 2244 if (mpt->m_cache_frames == NULL) { 2245 mptsas_log(mpt, CE_WARN, "creating cache for frames failed"); 2246 return (FALSE); 2247 } 2248 2249 return (TRUE); 2250 } 2251 2252 static void 2253 mptsas_cache_destroy(mptsas_t *mpt) 2254 { 2255 /* deallocate in reverse order */ 2256 if (mpt->m_cache_frames) { 2257 kmem_cache_destroy(mpt->m_cache_frames); 2258 mpt->m_cache_frames = NULL; 2259 } 2260 if (mpt->m_kmem_cache) { 2261 kmem_cache_destroy(mpt->m_kmem_cache); 2262 mpt->m_kmem_cache = NULL; 2263 } 2264 } 2265 2266 static int 2267 mptsas_power(dev_info_t *dip, int component, int level) 2268 { 2269 #ifndef __lock_lint 2270 _NOTE(ARGUNUSED(component)) 2271 #endif 2272 mptsas_t *mpt; 2273 int rval = DDI_SUCCESS; 2274 int polls = 0; 2275 uint32_t ioc_status; 2276 2277 if (scsi_hba_iport_unit_address(dip) != 0) 2278 return (DDI_SUCCESS); 2279 2280 mpt = ddi_get_soft_state(mptsas_state, ddi_get_instance(dip)); 2281 if (mpt == NULL) { 2282 return (DDI_FAILURE); 2283 } 2284 2285 mutex_enter(&mpt->m_mutex); 2286 2287 /* 2288 * If the device is busy, don't lower its power level 2289 */ 2290 if (mpt->m_busy && (mpt->m_power_level > level)) { 2291 mutex_exit(&mpt->m_mutex); 2292 return (DDI_FAILURE); 2293 } 2294 switch (level) { 2295 case PM_LEVEL_D0: 2296 NDBG11(("mptsas%d: turning power ON.", mpt->m_instance)); 2297 MPTSAS_POWER_ON(mpt); 2298 /* 2299 * Wait up to 30 seconds for IOC to come out of reset. 2300 */ 2301 while (((ioc_status = ddi_get32(mpt->m_datap, 2302 &mpt->m_reg->Doorbell)) & 2303 MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_RESET) { 2304 if (polls++ > 3000) { 2305 break; 2306 } 2307 delay(drv_usectohz(10000)); 2308 } 2309 /* 2310 * If IOC is not in operational state, try to hard reset it. 2311 */ 2312 if ((ioc_status & MPI2_IOC_STATE_MASK) != 2313 MPI2_IOC_STATE_OPERATIONAL) { 2314 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 2315 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) { 2316 mptsas_log(mpt, CE_WARN, 2317 "mptsas_power: hard reset failed"); 2318 mutex_exit(&mpt->m_mutex); 2319 return (DDI_FAILURE); 2320 } 2321 } 2322 mpt->m_power_level = PM_LEVEL_D0; 2323 break; 2324 case PM_LEVEL_D3: 2325 NDBG11(("mptsas%d: turning power OFF.", mpt->m_instance)); 2326 MPTSAS_POWER_OFF(mpt); 2327 break; 2328 default: 2329 mptsas_log(mpt, CE_WARN, "mptsas%d: unknown power level <%x>.", 2330 mpt->m_instance, level); 2331 rval = DDI_FAILURE; 2332 break; 2333 } 2334 mutex_exit(&mpt->m_mutex); 2335 return (rval); 2336 } 2337 2338 /* 2339 * Initialize configuration space and figure out which 2340 * chip and revison of the chip the mpt driver is using. 2341 */ 2342 static int 2343 mptsas_config_space_init(mptsas_t *mpt) 2344 { 2345 NDBG0(("mptsas_config_space_init")); 2346 2347 if (mpt->m_config_handle != NULL) 2348 return (TRUE); 2349 2350 if (pci_config_setup(mpt->m_dip, 2351 &mpt->m_config_handle) != DDI_SUCCESS) { 2352 mptsas_log(mpt, CE_WARN, "cannot map configuration space."); 2353 return (FALSE); 2354 } 2355 2356 /* 2357 * This is a workaround for a XMITS ASIC bug which does not 2358 * drive the CBE upper bits. 2359 */ 2360 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) & 2361 PCI_STAT_PERROR) { 2362 pci_config_put16(mpt->m_config_handle, PCI_CONF_STAT, 2363 PCI_STAT_PERROR); 2364 } 2365 2366 mptsas_setup_cmd_reg(mpt); 2367 2368 /* 2369 * Get the chip device id: 2370 */ 2371 mpt->m_devid = pci_config_get16(mpt->m_config_handle, PCI_CONF_DEVID); 2372 2373 /* 2374 * Save the revision. 2375 */ 2376 mpt->m_revid = pci_config_get8(mpt->m_config_handle, PCI_CONF_REVID); 2377 2378 /* 2379 * Save the SubSystem Vendor and Device IDs 2380 */ 2381 mpt->m_svid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBVENID); 2382 mpt->m_ssid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBSYSID); 2383 2384 /* 2385 * Set the latency timer to 0x40 as specified by the upa -> pci 2386 * bridge chip design team. This may be done by the sparc pci 2387 * bus nexus driver, but the driver should make sure the latency 2388 * timer is correct for performance reasons. 2389 */ 2390 pci_config_put8(mpt->m_config_handle, PCI_CONF_LATENCY_TIMER, 2391 MPTSAS_LATENCY_TIMER); 2392 2393 (void) mptsas_get_pci_cap(mpt); 2394 return (TRUE); 2395 } 2396 2397 static void 2398 mptsas_config_space_fini(mptsas_t *mpt) 2399 { 2400 if (mpt->m_config_handle != NULL) { 2401 mptsas_disable_bus_master(mpt); 2402 pci_config_teardown(&mpt->m_config_handle); 2403 mpt->m_config_handle = NULL; 2404 } 2405 } 2406 2407 static void 2408 mptsas_setup_cmd_reg(mptsas_t *mpt) 2409 { 2410 ushort_t cmdreg; 2411 2412 /* 2413 * Set the command register to the needed values. 2414 */ 2415 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM); 2416 cmdreg |= (PCI_COMM_ME | PCI_COMM_SERR_ENABLE | 2417 PCI_COMM_PARITY_DETECT | PCI_COMM_MAE); 2418 cmdreg &= ~PCI_COMM_IO; 2419 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg); 2420 } 2421 2422 static void 2423 mptsas_disable_bus_master(mptsas_t *mpt) 2424 { 2425 ushort_t cmdreg; 2426 2427 /* 2428 * Clear the master enable bit in the PCI command register. 2429 * This prevents any bus mastering activity like DMA. 2430 */ 2431 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM); 2432 cmdreg &= ~PCI_COMM_ME; 2433 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg); 2434 } 2435 2436 int 2437 mptsas_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep) 2438 { 2439 ddi_dma_attr_t attrs; 2440 2441 attrs = mpt->m_io_dma_attr; 2442 attrs.dma_attr_sgllen = 1; 2443 2444 ASSERT(dma_statep != NULL); 2445 2446 if (mptsas_dma_addr_create(mpt, attrs, &dma_statep->handle, 2447 &dma_statep->accessp, &dma_statep->memp, dma_statep->size, 2448 &dma_statep->cookie) == FALSE) { 2449 return (DDI_FAILURE); 2450 } 2451 2452 return (DDI_SUCCESS); 2453 } 2454 2455 void 2456 mptsas_dma_free(mptsas_dma_alloc_state_t *dma_statep) 2457 { 2458 ASSERT(dma_statep != NULL); 2459 mptsas_dma_addr_destroy(&dma_statep->handle, &dma_statep->accessp); 2460 dma_statep->size = 0; 2461 } 2462 2463 int 2464 mptsas_do_dma(mptsas_t *mpt, uint32_t size, int var, int (*callback)()) 2465 { 2466 ddi_dma_attr_t attrs; 2467 ddi_dma_handle_t dma_handle; 2468 caddr_t memp; 2469 ddi_acc_handle_t accessp; 2470 int rval; 2471 2472 ASSERT(mutex_owned(&mpt->m_mutex)); 2473 2474 attrs = mpt->m_msg_dma_attr; 2475 attrs.dma_attr_sgllen = 1; 2476 attrs.dma_attr_granular = size; 2477 2478 if (mptsas_dma_addr_create(mpt, attrs, &dma_handle, 2479 &accessp, &memp, size, NULL) == FALSE) { 2480 return (DDI_FAILURE); 2481 } 2482 2483 rval = (*callback) (mpt, memp, var, accessp); 2484 2485 if ((mptsas_check_dma_handle(dma_handle) != DDI_SUCCESS) || 2486 (mptsas_check_acc_handle(accessp) != DDI_SUCCESS)) { 2487 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 2488 rval = DDI_FAILURE; 2489 } 2490 2491 mptsas_dma_addr_destroy(&dma_handle, &accessp); 2492 return (rval); 2493 2494 } 2495 2496 static int 2497 mptsas_alloc_request_frames(mptsas_t *mpt) 2498 { 2499 ddi_dma_attr_t frame_dma_attrs; 2500 caddr_t memp; 2501 ddi_dma_cookie_t cookie; 2502 size_t mem_size; 2503 2504 /* 2505 * re-alloc when it has already alloced 2506 */ 2507 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl, 2508 &mpt->m_acc_req_frame_hdl); 2509 2510 /* 2511 * The size of the request frame pool is: 2512 * Number of Request Frames * Request Frame Size 2513 */ 2514 mem_size = mpt->m_max_requests * mpt->m_req_frame_size; 2515 2516 /* 2517 * set the DMA attributes. System Request Message Frames must be 2518 * aligned on a 16-byte boundry. 2519 */ 2520 frame_dma_attrs = mpt->m_msg_dma_attr; 2521 frame_dma_attrs.dma_attr_align = 16; 2522 frame_dma_attrs.dma_attr_sgllen = 1; 2523 2524 /* 2525 * allocate the request frame pool. 2526 */ 2527 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2528 &mpt->m_dma_req_frame_hdl, &mpt->m_acc_req_frame_hdl, &memp, 2529 mem_size, &cookie) == FALSE) { 2530 return (DDI_FAILURE); 2531 } 2532 2533 /* 2534 * Store the request frame memory address. This chip uses this 2535 * address to dma to and from the driver's frame. The second 2536 * address is the address mpt uses to fill in the frame. 2537 */ 2538 mpt->m_req_frame_dma_addr = cookie.dmac_laddress; 2539 mpt->m_req_frame = memp; 2540 2541 /* 2542 * Clear the request frame pool. 2543 */ 2544 bzero(mpt->m_req_frame, mem_size); 2545 2546 return (DDI_SUCCESS); 2547 } 2548 2549 static int 2550 mptsas_alloc_reply_frames(mptsas_t *mpt) 2551 { 2552 ddi_dma_attr_t frame_dma_attrs; 2553 caddr_t memp; 2554 ddi_dma_cookie_t cookie; 2555 size_t mem_size; 2556 2557 /* 2558 * re-alloc when it has already alloced 2559 */ 2560 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl, 2561 &mpt->m_acc_reply_frame_hdl); 2562 2563 /* 2564 * The size of the reply frame pool is: 2565 * Number of Reply Frames * Reply Frame Size 2566 */ 2567 mem_size = mpt->m_max_replies * mpt->m_reply_frame_size; 2568 2569 /* 2570 * set the DMA attributes. System Reply Message Frames must be 2571 * aligned on a 4-byte boundry. This is the default. 2572 */ 2573 frame_dma_attrs = mpt->m_msg_dma_attr; 2574 frame_dma_attrs.dma_attr_sgllen = 1; 2575 2576 /* 2577 * allocate the reply frame pool 2578 */ 2579 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2580 &mpt->m_dma_reply_frame_hdl, &mpt->m_acc_reply_frame_hdl, &memp, 2581 mem_size, &cookie) == FALSE) { 2582 return (DDI_FAILURE); 2583 } 2584 2585 /* 2586 * Store the reply frame memory address. This chip uses this 2587 * address to dma to and from the driver's frame. The second 2588 * address is the address mpt uses to process the frame. 2589 */ 2590 mpt->m_reply_frame_dma_addr = cookie.dmac_laddress; 2591 mpt->m_reply_frame = memp; 2592 2593 /* 2594 * Clear the reply frame pool. 2595 */ 2596 bzero(mpt->m_reply_frame, mem_size); 2597 2598 return (DDI_SUCCESS); 2599 } 2600 2601 static int 2602 mptsas_alloc_free_queue(mptsas_t *mpt) 2603 { 2604 ddi_dma_attr_t frame_dma_attrs; 2605 caddr_t memp; 2606 ddi_dma_cookie_t cookie; 2607 size_t mem_size; 2608 2609 /* 2610 * re-alloc when it has already alloced 2611 */ 2612 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl, 2613 &mpt->m_acc_free_queue_hdl); 2614 2615 /* 2616 * The reply free queue size is: 2617 * Reply Free Queue Depth * 4 2618 * The "4" is the size of one 32 bit address (low part of 64-bit 2619 * address) 2620 */ 2621 mem_size = mpt->m_free_queue_depth * 4; 2622 2623 /* 2624 * set the DMA attributes The Reply Free Queue must be aligned on a 2625 * 16-byte boundry. 2626 */ 2627 frame_dma_attrs = mpt->m_msg_dma_attr; 2628 frame_dma_attrs.dma_attr_align = 16; 2629 frame_dma_attrs.dma_attr_sgllen = 1; 2630 2631 /* 2632 * allocate the reply free queue 2633 */ 2634 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2635 &mpt->m_dma_free_queue_hdl, &mpt->m_acc_free_queue_hdl, &memp, 2636 mem_size, &cookie) == FALSE) { 2637 return (DDI_FAILURE); 2638 } 2639 2640 /* 2641 * Store the reply free queue memory address. This chip uses this 2642 * address to read from the reply free queue. The second address 2643 * is the address mpt uses to manage the queue. 2644 */ 2645 mpt->m_free_queue_dma_addr = cookie.dmac_laddress; 2646 mpt->m_free_queue = memp; 2647 2648 /* 2649 * Clear the reply free queue memory. 2650 */ 2651 bzero(mpt->m_free_queue, mem_size); 2652 2653 return (DDI_SUCCESS); 2654 } 2655 2656 static int 2657 mptsas_alloc_post_queue(mptsas_t *mpt) 2658 { 2659 ddi_dma_attr_t frame_dma_attrs; 2660 caddr_t memp; 2661 ddi_dma_cookie_t cookie; 2662 size_t mem_size; 2663 2664 /* 2665 * re-alloc when it has already alloced 2666 */ 2667 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl, 2668 &mpt->m_acc_post_queue_hdl); 2669 2670 /* 2671 * The reply descriptor post queue size is: 2672 * Reply Descriptor Post Queue Depth * 8 2673 * The "8" is the size of each descriptor (8 bytes or 64 bits). 2674 */ 2675 mem_size = mpt->m_post_queue_depth * 8; 2676 2677 /* 2678 * set the DMA attributes. The Reply Descriptor Post Queue must be 2679 * aligned on a 16-byte boundry. 2680 */ 2681 frame_dma_attrs = mpt->m_msg_dma_attr; 2682 frame_dma_attrs.dma_attr_align = 16; 2683 frame_dma_attrs.dma_attr_sgllen = 1; 2684 2685 /* 2686 * allocate the reply post queue 2687 */ 2688 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2689 &mpt->m_dma_post_queue_hdl, &mpt->m_acc_post_queue_hdl, &memp, 2690 mem_size, &cookie) == FALSE) { 2691 return (DDI_FAILURE); 2692 } 2693 2694 /* 2695 * Store the reply descriptor post queue memory address. This chip 2696 * uses this address to write to the reply descriptor post queue. The 2697 * second address is the address mpt uses to manage the queue. 2698 */ 2699 mpt->m_post_queue_dma_addr = cookie.dmac_laddress; 2700 mpt->m_post_queue = memp; 2701 2702 /* 2703 * Clear the reply post queue memory. 2704 */ 2705 bzero(mpt->m_post_queue, mem_size); 2706 2707 return (DDI_SUCCESS); 2708 } 2709 2710 static void 2711 mptsas_alloc_reply_args(mptsas_t *mpt) 2712 { 2713 if (mpt->m_replyh_args == NULL) { 2714 mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) * 2715 mpt->m_max_replies, KM_SLEEP); 2716 } 2717 } 2718 2719 static int 2720 mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd) 2721 { 2722 mptsas_cache_frames_t *frames = NULL; 2723 if (cmd->cmd_extra_frames == NULL) { 2724 frames = kmem_cache_alloc(mpt->m_cache_frames, KM_NOSLEEP); 2725 if (frames == NULL) { 2726 return (DDI_FAILURE); 2727 } 2728 cmd->cmd_extra_frames = frames; 2729 } 2730 return (DDI_SUCCESS); 2731 } 2732 2733 static void 2734 mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd) 2735 { 2736 if (cmd->cmd_extra_frames) { 2737 kmem_cache_free(mpt->m_cache_frames, 2738 (void *)cmd->cmd_extra_frames); 2739 cmd->cmd_extra_frames = NULL; 2740 } 2741 } 2742 2743 static void 2744 mptsas_cfg_fini(mptsas_t *mpt) 2745 { 2746 NDBG0(("mptsas_cfg_fini")); 2747 ddi_regs_map_free(&mpt->m_datap); 2748 } 2749 2750 static void 2751 mptsas_hba_fini(mptsas_t *mpt) 2752 { 2753 NDBG0(("mptsas_hba_fini")); 2754 2755 /* 2756 * Free up any allocated memory 2757 */ 2758 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl, 2759 &mpt->m_acc_req_frame_hdl); 2760 2761 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl, 2762 &mpt->m_acc_reply_frame_hdl); 2763 2764 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl, 2765 &mpt->m_acc_free_queue_hdl); 2766 2767 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl, 2768 &mpt->m_acc_post_queue_hdl); 2769 2770 if (mpt->m_replyh_args != NULL) { 2771 kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t) 2772 * mpt->m_max_replies); 2773 } 2774 } 2775 2776 static int 2777 mptsas_name_child(dev_info_t *lun_dip, char *name, int len) 2778 { 2779 int lun = 0; 2780 char *sas_wwn = NULL; 2781 int phynum = -1; 2782 int reallen = 0; 2783 2784 /* Get the target num */ 2785 lun = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, DDI_PROP_DONTPASS, 2786 LUN_PROP, 0); 2787 2788 if ((phynum = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, 2789 DDI_PROP_DONTPASS, "sata-phy", -1)) != -1) { 2790 /* 2791 * Stick in the address of form "pPHY,LUN" 2792 */ 2793 reallen = snprintf(name, len, "p%x,%x", phynum, lun); 2794 } else if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lun_dip, 2795 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &sas_wwn) 2796 == DDI_PROP_SUCCESS) { 2797 /* 2798 * Stick in the address of the form "wWWN,LUN" 2799 */ 2800 reallen = snprintf(name, len, "%s,%x", sas_wwn, lun); 2801 ddi_prop_free(sas_wwn); 2802 } else { 2803 return (DDI_FAILURE); 2804 } 2805 2806 ASSERT(reallen < len); 2807 if (reallen >= len) { 2808 mptsas_log(0, CE_WARN, "!mptsas_get_name: name parameter " 2809 "length too small, it needs to be %d bytes", reallen + 1); 2810 } 2811 return (DDI_SUCCESS); 2812 } 2813 2814 /* 2815 * tran_tgt_init(9E) - target device instance initialization 2816 */ 2817 static int 2818 mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 2819 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 2820 { 2821 #ifndef __lock_lint 2822 _NOTE(ARGUNUSED(hba_tran)) 2823 #endif 2824 2825 /* 2826 * At this point, the scsi_device structure already exists 2827 * and has been initialized. 2828 * 2829 * Use this function to allocate target-private data structures, 2830 * if needed by this HBA. Add revised flow-control and queue 2831 * properties for child here, if desired and if you can tell they 2832 * support tagged queueing by now. 2833 */ 2834 mptsas_t *mpt; 2835 int lun = sd->sd_address.a_lun; 2836 mdi_pathinfo_t *pip = NULL; 2837 mptsas_tgt_private_t *tgt_private = NULL; 2838 mptsas_target_t *ptgt = NULL; 2839 char *psas_wwn = NULL; 2840 mptsas_phymask_t phymask = 0; 2841 uint64_t sas_wwn = 0; 2842 mptsas_target_addr_t addr; 2843 mpt = SDEV2MPT(sd); 2844 2845 ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0); 2846 2847 NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d", 2848 (void *)hba_dip, (void *)tgt_dip, lun)); 2849 2850 if (ndi_dev_is_persistent_node(tgt_dip) == 0) { 2851 (void) ndi_merge_node(tgt_dip, mptsas_name_child); 2852 ddi_set_name_addr(tgt_dip, NULL); 2853 return (DDI_FAILURE); 2854 } 2855 /* 2856 * phymask is 0 means the virtual port for RAID 2857 */ 2858 phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0, 2859 "phymask", 0); 2860 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) { 2861 if ((pip = (void *)(sd->sd_private)) == NULL) { 2862 /* 2863 * Very bad news if this occurs. Somehow scsi_vhci has 2864 * lost the pathinfo node for this target. 2865 */ 2866 return (DDI_NOT_WELL_FORMED); 2867 } 2868 2869 if (mdi_prop_lookup_int(pip, LUN_PROP, &lun) != 2870 DDI_PROP_SUCCESS) { 2871 mptsas_log(mpt, CE_WARN, "Get lun property failed\n"); 2872 return (DDI_FAILURE); 2873 } 2874 2875 if (mdi_prop_lookup_string(pip, SCSI_ADDR_PROP_TARGET_PORT, 2876 &psas_wwn) == MDI_SUCCESS) { 2877 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) { 2878 sas_wwn = 0; 2879 } 2880 (void) mdi_prop_free(psas_wwn); 2881 } 2882 } else { 2883 lun = ddi_prop_get_int(DDI_DEV_T_ANY, tgt_dip, 2884 DDI_PROP_DONTPASS, LUN_PROP, 0); 2885 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, tgt_dip, 2886 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &psas_wwn) == 2887 DDI_PROP_SUCCESS) { 2888 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) { 2889 sas_wwn = 0; 2890 } 2891 ddi_prop_free(psas_wwn); 2892 } else { 2893 sas_wwn = 0; 2894 } 2895 } 2896 2897 ASSERT((sas_wwn != 0) || (phymask != 0)); 2898 addr.mta_wwn = sas_wwn; 2899 addr.mta_phymask = phymask; 2900 mutex_enter(&mpt->m_mutex); 2901 ptgt = refhash_lookup(mpt->m_targets, &addr); 2902 mutex_exit(&mpt->m_mutex); 2903 if (ptgt == NULL) { 2904 mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or " 2905 "gone already! phymask:%x, saswwn %"PRIx64, phymask, 2906 sas_wwn); 2907 return (DDI_FAILURE); 2908 } 2909 if (hba_tran->tran_tgt_private == NULL) { 2910 tgt_private = kmem_zalloc(sizeof (mptsas_tgt_private_t), 2911 KM_SLEEP); 2912 tgt_private->t_lun = lun; 2913 tgt_private->t_private = ptgt; 2914 hba_tran->tran_tgt_private = tgt_private; 2915 } 2916 2917 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) { 2918 return (DDI_SUCCESS); 2919 } 2920 mutex_enter(&mpt->m_mutex); 2921 2922 if (ptgt->m_deviceinfo & 2923 (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 2924 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 2925 uchar_t *inq89 = NULL; 2926 int inq89_len = 0x238; 2927 int reallen = 0; 2928 int rval = 0; 2929 struct sata_id *sid = NULL; 2930 char model[SATA_ID_MODEL_LEN + 1]; 2931 char fw[SATA_ID_FW_LEN + 1]; 2932 char *vid, *pid; 2933 int i; 2934 2935 mutex_exit(&mpt->m_mutex); 2936 /* 2937 * According SCSI/ATA Translation -2 (SAT-2) revision 01a 2938 * chapter 12.4.2 VPD page 89h includes 512 bytes ATA IDENTIFY 2939 * DEVICE data or ATA IDENTIFY PACKET DEVICE data. 2940 */ 2941 inq89 = kmem_zalloc(inq89_len, KM_SLEEP); 2942 rval = mptsas_inquiry(mpt, ptgt, 0, 0x89, 2943 inq89, inq89_len, &reallen, 1); 2944 2945 if (rval != 0) { 2946 if (inq89 != NULL) { 2947 kmem_free(inq89, inq89_len); 2948 } 2949 2950 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 2951 "0x89 for SATA target:%x failed!", ptgt->m_devhdl); 2952 return (DDI_SUCCESS); 2953 } 2954 sid = (void *)(&inq89[60]); 2955 2956 swab(sid->ai_model, model, SATA_ID_MODEL_LEN); 2957 swab(sid->ai_fw, fw, SATA_ID_FW_LEN); 2958 2959 model[SATA_ID_MODEL_LEN] = 0; 2960 fw[SATA_ID_FW_LEN] = 0; 2961 2962 /* 2963 * split model into into vid/pid 2964 */ 2965 for (i = 0, pid = model; i < SATA_ID_MODEL_LEN; i++, pid++) 2966 if ((*pid == ' ') || (*pid == '\t')) 2967 break; 2968 if (i < SATA_ID_MODEL_LEN) { 2969 vid = model; 2970 /* 2971 * terminate vid, establish pid 2972 */ 2973 *pid++ = 0; 2974 } else { 2975 /* 2976 * vid will stay "ATA ", the rule is same 2977 * as sata framework implementation. 2978 */ 2979 vid = NULL; 2980 /* 2981 * model is all pid 2982 */ 2983 pid = model; 2984 } 2985 2986 /* 2987 * override SCSA "inquiry-*" properties 2988 */ 2989 if (vid) 2990 (void) scsi_device_prop_update_inqstring(sd, 2991 INQUIRY_VENDOR_ID, vid, strlen(vid)); 2992 if (pid) 2993 (void) scsi_device_prop_update_inqstring(sd, 2994 INQUIRY_PRODUCT_ID, pid, strlen(pid)); 2995 (void) scsi_device_prop_update_inqstring(sd, 2996 INQUIRY_REVISION_ID, fw, strlen(fw)); 2997 2998 if (inq89 != NULL) { 2999 kmem_free(inq89, inq89_len); 3000 } 3001 } else { 3002 mutex_exit(&mpt->m_mutex); 3003 } 3004 3005 return (DDI_SUCCESS); 3006 } 3007 /* 3008 * tran_tgt_free(9E) - target device instance deallocation 3009 */ 3010 static void 3011 mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 3012 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 3013 { 3014 #ifndef __lock_lint 3015 _NOTE(ARGUNUSED(hba_dip, tgt_dip, hba_tran, sd)) 3016 #endif 3017 3018 mptsas_tgt_private_t *tgt_private = hba_tran->tran_tgt_private; 3019 3020 if (tgt_private != NULL) { 3021 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t)); 3022 hba_tran->tran_tgt_private = NULL; 3023 } 3024 } 3025 3026 /* 3027 * scsi_pkt handling 3028 * 3029 * Visible to the external world via the transport structure. 3030 */ 3031 3032 /* 3033 * Notes: 3034 * - transport the command to the addressed SCSI target/lun device 3035 * - normal operation is to schedule the command to be transported, 3036 * and return TRAN_ACCEPT if this is successful. 3037 * - if NO_INTR, tran_start must poll device for command completion 3038 */ 3039 static int 3040 mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt) 3041 { 3042 #ifndef __lock_lint 3043 _NOTE(ARGUNUSED(ap)) 3044 #endif 3045 mptsas_t *mpt = PKT2MPT(pkt); 3046 mptsas_cmd_t *cmd = PKT2CMD(pkt); 3047 int rval; 3048 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3049 3050 NDBG1(("mptsas_scsi_start: pkt=0x%p", (void *)pkt)); 3051 ASSERT(ptgt); 3052 if (ptgt == NULL) 3053 return (TRAN_FATAL_ERROR); 3054 3055 /* 3056 * prepare the pkt before taking mutex. 3057 */ 3058 rval = mptsas_prepare_pkt(cmd); 3059 if (rval != TRAN_ACCEPT) { 3060 return (rval); 3061 } 3062 3063 /* 3064 * Send the command to target/lun, however your HBA requires it. 3065 * If busy, return TRAN_BUSY; if there's some other formatting error 3066 * in the packet, return TRAN_BADPKT; otherwise, fall through to the 3067 * return of TRAN_ACCEPT. 3068 * 3069 * Remember that access to shared resources, including the mptsas_t 3070 * data structure and the HBA hardware registers, must be protected 3071 * with mutexes, here and everywhere. 3072 * 3073 * Also remember that at interrupt time, you'll get an argument 3074 * to the interrupt handler which is a pointer to your mptsas_t 3075 * structure; you'll have to remember which commands are outstanding 3076 * and which scsi_pkt is the currently-running command so the 3077 * interrupt handler can refer to the pkt to set completion 3078 * status, call the target driver back through pkt_comp, etc. 3079 * 3080 * If the instance lock is held by other thread, don't spin to wait 3081 * for it. Instead, queue the cmd and next time when the instance lock 3082 * is not held, accept all the queued cmd. A extra tx_waitq is 3083 * introduced to protect the queue. 3084 * 3085 * The polled cmd will not be queud and accepted as usual. 3086 * 3087 * Under the tx_waitq mutex, record whether a thread is draining 3088 * the tx_waitq. An IO requesting thread that finds the instance 3089 * mutex contended appends to the tx_waitq and while holding the 3090 * tx_wait mutex, if the draining flag is not set, sets it and then 3091 * proceeds to spin for the instance mutex. This scheme ensures that 3092 * the last cmd in a burst be processed. 3093 * 3094 * we enable this feature only when the helper threads are enabled, 3095 * at which we think the loads are heavy. 3096 * 3097 * per instance mutex m_tx_waitq_mutex is introduced to protect the 3098 * m_tx_waitqtail, m_tx_waitq, m_tx_draining. 3099 */ 3100 3101 if (mpt->m_doneq_thread_n) { 3102 if (mutex_tryenter(&mpt->m_mutex) != 0) { 3103 rval = mptsas_accept_txwq_and_pkt(mpt, cmd); 3104 mutex_exit(&mpt->m_mutex); 3105 } else if (cmd->cmd_pkt_flags & FLAG_NOINTR) { 3106 mutex_enter(&mpt->m_mutex); 3107 rval = mptsas_accept_txwq_and_pkt(mpt, cmd); 3108 mutex_exit(&mpt->m_mutex); 3109 } else { 3110 mutex_enter(&mpt->m_tx_waitq_mutex); 3111 /* 3112 * ptgt->m_dr_flag is protected by m_mutex or 3113 * m_tx_waitq_mutex. In this case, m_tx_waitq_mutex 3114 * is acquired. 3115 */ 3116 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3117 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3118 /* 3119 * The command should be allowed to 3120 * retry by returning TRAN_BUSY to 3121 * to stall the I/O's which come from 3122 * scsi_vhci since the device/path is 3123 * in unstable state now. 3124 */ 3125 mutex_exit(&mpt->m_tx_waitq_mutex); 3126 return (TRAN_BUSY); 3127 } else { 3128 /* 3129 * The device is offline, just fail the 3130 * command by returning 3131 * TRAN_FATAL_ERROR. 3132 */ 3133 mutex_exit(&mpt->m_tx_waitq_mutex); 3134 return (TRAN_FATAL_ERROR); 3135 } 3136 } 3137 if (mpt->m_tx_draining) { 3138 cmd->cmd_flags |= CFLAG_TXQ; 3139 *mpt->m_tx_waitqtail = cmd; 3140 mpt->m_tx_waitqtail = &cmd->cmd_linkp; 3141 mutex_exit(&mpt->m_tx_waitq_mutex); 3142 } else { /* drain the queue */ 3143 mpt->m_tx_draining = 1; 3144 mutex_exit(&mpt->m_tx_waitq_mutex); 3145 mutex_enter(&mpt->m_mutex); 3146 rval = mptsas_accept_txwq_and_pkt(mpt, cmd); 3147 mutex_exit(&mpt->m_mutex); 3148 } 3149 } 3150 } else { 3151 mutex_enter(&mpt->m_mutex); 3152 /* 3153 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex 3154 * in this case, m_mutex is acquired. 3155 */ 3156 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3157 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3158 /* 3159 * commands should be allowed to retry by 3160 * returning TRAN_BUSY to stall the I/O's 3161 * which come from scsi_vhci since the device/ 3162 * path is in unstable state now. 3163 */ 3164 mutex_exit(&mpt->m_mutex); 3165 return (TRAN_BUSY); 3166 } else { 3167 /* 3168 * The device is offline, just fail the 3169 * command by returning TRAN_FATAL_ERROR. 3170 */ 3171 mutex_exit(&mpt->m_mutex); 3172 return (TRAN_FATAL_ERROR); 3173 } 3174 } 3175 rval = mptsas_accept_pkt(mpt, cmd); 3176 mutex_exit(&mpt->m_mutex); 3177 } 3178 3179 return (rval); 3180 } 3181 3182 /* 3183 * Accept all the queued cmds(if any) before accept the current one. 3184 */ 3185 static int 3186 mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd) 3187 { 3188 int rval; 3189 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3190 3191 ASSERT(mutex_owned(&mpt->m_mutex)); 3192 /* 3193 * The call to mptsas_accept_tx_waitq() must always be performed 3194 * because that is where mpt->m_tx_draining is cleared. 3195 */ 3196 mutex_enter(&mpt->m_tx_waitq_mutex); 3197 mptsas_accept_tx_waitq(mpt); 3198 mutex_exit(&mpt->m_tx_waitq_mutex); 3199 /* 3200 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex 3201 * in this case, m_mutex is acquired. 3202 */ 3203 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3204 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3205 /* 3206 * The command should be allowed to retry by returning 3207 * TRAN_BUSY to stall the I/O's which come from 3208 * scsi_vhci since the device/path is in unstable state 3209 * now. 3210 */ 3211 return (TRAN_BUSY); 3212 } else { 3213 /* 3214 * The device is offline, just fail the command by 3215 * return TRAN_FATAL_ERROR. 3216 */ 3217 return (TRAN_FATAL_ERROR); 3218 } 3219 } 3220 rval = mptsas_accept_pkt(mpt, cmd); 3221 3222 return (rval); 3223 } 3224 3225 static int 3226 mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd) 3227 { 3228 int rval = TRAN_ACCEPT; 3229 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3230 3231 NDBG1(("mptsas_accept_pkt: cmd=0x%p", (void *)cmd)); 3232 3233 ASSERT(mutex_owned(&mpt->m_mutex)); 3234 3235 if ((cmd->cmd_flags & CFLAG_PREPARED) == 0) { 3236 rval = mptsas_prepare_pkt(cmd); 3237 if (rval != TRAN_ACCEPT) { 3238 cmd->cmd_flags &= ~CFLAG_TRANFLAG; 3239 return (rval); 3240 } 3241 } 3242 3243 /* 3244 * reset the throttle if we were draining 3245 */ 3246 if ((ptgt->m_t_ncmds == 0) && 3247 (ptgt->m_t_throttle == DRAIN_THROTTLE)) { 3248 NDBG23(("reset throttle")); 3249 ASSERT(ptgt->m_reset_delay == 0); 3250 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 3251 } 3252 3253 /* 3254 * If HBA is being reset, the DevHandles are being re-initialized, 3255 * which means that they could be invalid even if the target is still 3256 * attached. Check if being reset and if DevHandle is being 3257 * re-initialized. If this is the case, return BUSY so the I/O can be 3258 * retried later. 3259 */ 3260 if ((ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) && mpt->m_in_reset) { 3261 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 3262 if (cmd->cmd_flags & CFLAG_TXQ) { 3263 mptsas_doneq_add(mpt, cmd); 3264 mptsas_doneq_empty(mpt); 3265 return (rval); 3266 } else { 3267 return (TRAN_BUSY); 3268 } 3269 } 3270 3271 /* 3272 * If device handle has already been invalidated, just 3273 * fail the command. In theory, command from scsi_vhci 3274 * client is impossible send down command with invalid 3275 * devhdl since devhdl is set after path offline, target 3276 * driver is not suppose to select a offlined path. 3277 */ 3278 if (ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) { 3279 NDBG20(("rejecting command, it might because invalid devhdl " 3280 "request.")); 3281 mptsas_set_pkt_reason(mpt, cmd, CMD_DEV_GONE, STAT_TERMINATED); 3282 if (cmd->cmd_flags & CFLAG_TXQ) { 3283 mptsas_doneq_add(mpt, cmd); 3284 mptsas_doneq_empty(mpt); 3285 return (rval); 3286 } else { 3287 return (TRAN_FATAL_ERROR); 3288 } 3289 } 3290 /* 3291 * The first case is the normal case. mpt gets a command from the 3292 * target driver and starts it. 3293 * Since SMID 0 is reserved and the TM slot is reserved, the actual max 3294 * commands is m_max_requests - 2. 3295 */ 3296 if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) && 3297 (ptgt->m_t_throttle > HOLD_THROTTLE) && 3298 (ptgt->m_t_ncmds < ptgt->m_t_throttle) && 3299 (ptgt->m_reset_delay == 0) && 3300 (ptgt->m_t_nwait == 0) && 3301 ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0)) { 3302 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 3303 (void) mptsas_start_cmd(mpt, cmd); 3304 } else { 3305 mptsas_waitq_add(mpt, cmd); 3306 } 3307 } else { 3308 /* 3309 * Add this pkt to the work queue 3310 */ 3311 mptsas_waitq_add(mpt, cmd); 3312 3313 if (cmd->cmd_pkt_flags & FLAG_NOINTR) { 3314 (void) mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME); 3315 3316 /* 3317 * Only flush the doneq if this is not a TM 3318 * cmd. For TM cmds the flushing of the 3319 * doneq will be done in those routines. 3320 */ 3321 if ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) { 3322 mptsas_doneq_empty(mpt); 3323 } 3324 } 3325 } 3326 return (rval); 3327 } 3328 3329 int 3330 mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 3331 { 3332 mptsas_slots_t *slots = mpt->m_active; 3333 uint_t slot, start_rotor; 3334 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3335 3336 ASSERT(MUTEX_HELD(&mpt->m_mutex)); 3337 3338 /* 3339 * Account for reserved TM request slot and reserved SMID of 0. 3340 */ 3341 ASSERT(slots->m_n_normal == (mpt->m_max_requests - 2)); 3342 3343 /* 3344 * Find the next available slot, beginning at m_rotor. If no slot is 3345 * available, we'll return FALSE to indicate that. This mechanism 3346 * considers only the normal slots, not the reserved slot 0 nor the 3347 * task management slot m_n_normal + 1. The rotor is left to point to 3348 * the normal slot after the one we select, unless we select the last 3349 * normal slot in which case it returns to slot 1. 3350 */ 3351 start_rotor = slots->m_rotor; 3352 do { 3353 slot = slots->m_rotor++; 3354 if (slots->m_rotor > slots->m_n_normal) 3355 slots->m_rotor = 1; 3356 3357 if (slots->m_rotor == start_rotor) 3358 break; 3359 } while (slots->m_slot[slot] != NULL); 3360 3361 if (slots->m_slot[slot] != NULL) 3362 return (FALSE); 3363 3364 ASSERT(slot != 0 && slot <= slots->m_n_normal); 3365 3366 cmd->cmd_slot = slot; 3367 slots->m_slot[slot] = cmd; 3368 mpt->m_ncmds++; 3369 3370 /* 3371 * only increment per target ncmds if this is not a 3372 * command that has no target associated with it (i.e. a 3373 * event acknoledgment) 3374 */ 3375 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 3376 /* 3377 * Expiration time is set in mptsas_start_cmd 3378 */ 3379 ptgt->m_t_ncmds++; 3380 cmd->cmd_active_expiration = 0; 3381 } else { 3382 /* 3383 * Initialize expiration time for passthrough commands, 3384 */ 3385 cmd->cmd_active_expiration = gethrtime() + 3386 (hrtime_t)cmd->cmd_pkt->pkt_time * NANOSEC; 3387 } 3388 return (TRUE); 3389 } 3390 3391 /* 3392 * prepare the pkt: 3393 * the pkt may have been resubmitted or just reused so 3394 * initialize some fields and do some checks. 3395 */ 3396 static int 3397 mptsas_prepare_pkt(mptsas_cmd_t *cmd) 3398 { 3399 struct scsi_pkt *pkt = CMD2PKT(cmd); 3400 3401 NDBG1(("mptsas_prepare_pkt: cmd=0x%p", (void *)cmd)); 3402 3403 /* 3404 * Reinitialize some fields that need it; the packet may 3405 * have been resubmitted 3406 */ 3407 pkt->pkt_reason = CMD_CMPLT; 3408 pkt->pkt_state = 0; 3409 pkt->pkt_statistics = 0; 3410 pkt->pkt_resid = 0; 3411 cmd->cmd_age = 0; 3412 cmd->cmd_pkt_flags = pkt->pkt_flags; 3413 3414 /* 3415 * zero status byte. 3416 */ 3417 *(pkt->pkt_scbp) = 0; 3418 3419 if (cmd->cmd_flags & CFLAG_DMAVALID) { 3420 pkt->pkt_resid = cmd->cmd_dmacount; 3421 3422 /* 3423 * consistent packets need to be sync'ed first 3424 * (only for data going out) 3425 */ 3426 if ((cmd->cmd_flags & CFLAG_CMDIOPB) && 3427 (cmd->cmd_flags & CFLAG_DMASEND)) { 3428 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 3429 DDI_DMA_SYNC_FORDEV); 3430 } 3431 } 3432 3433 cmd->cmd_flags = 3434 (cmd->cmd_flags & ~(CFLAG_TRANFLAG)) | 3435 CFLAG_PREPARED | CFLAG_IN_TRANSPORT; 3436 3437 return (TRAN_ACCEPT); 3438 } 3439 3440 /* 3441 * tran_init_pkt(9E) - allocate scsi_pkt(9S) for command 3442 * 3443 * One of three possibilities: 3444 * - allocate scsi_pkt 3445 * - allocate scsi_pkt and DMA resources 3446 * - allocate DMA resources to an already-allocated pkt 3447 */ 3448 static struct scsi_pkt * 3449 mptsas_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt, 3450 struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags, 3451 int (*callback)(), caddr_t arg) 3452 { 3453 mptsas_cmd_t *cmd, *new_cmd; 3454 mptsas_t *mpt = ADDR2MPT(ap); 3455 int failure = 1; 3456 uint_t oldcookiec; 3457 mptsas_target_t *ptgt = NULL; 3458 int rval; 3459 mptsas_tgt_private_t *tgt_private; 3460 int kf; 3461 3462 kf = (callback == SLEEP_FUNC)? KM_SLEEP: KM_NOSLEEP; 3463 3464 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran-> 3465 tran_tgt_private; 3466 ASSERT(tgt_private != NULL); 3467 if (tgt_private == NULL) { 3468 return (NULL); 3469 } 3470 ptgt = tgt_private->t_private; 3471 ASSERT(ptgt != NULL); 3472 if (ptgt == NULL) 3473 return (NULL); 3474 ap->a_target = ptgt->m_devhdl; 3475 ap->a_lun = tgt_private->t_lun; 3476 3477 ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC); 3478 #ifdef MPTSAS_TEST_EXTRN_ALLOC 3479 statuslen *= 100; tgtlen *= 4; 3480 #endif 3481 NDBG3(("mptsas_scsi_init_pkt:\n" 3482 "\ttgt=%d in=0x%p bp=0x%p clen=%d slen=%d tlen=%d flags=%x", 3483 ap->a_target, (void *)pkt, (void *)bp, 3484 cmdlen, statuslen, tgtlen, flags)); 3485 3486 /* 3487 * Allocate the new packet. 3488 */ 3489 if (pkt == NULL) { 3490 ddi_dma_handle_t save_dma_handle; 3491 ddi_dma_handle_t save_arq_dma_handle; 3492 struct buf *save_arq_bp; 3493 ddi_dma_cookie_t save_arqcookie; 3494 3495 cmd = kmem_cache_alloc(mpt->m_kmem_cache, kf); 3496 3497 if (cmd) { 3498 save_dma_handle = cmd->cmd_dmahandle; 3499 save_arq_dma_handle = cmd->cmd_arqhandle; 3500 save_arq_bp = cmd->cmd_arq_buf; 3501 save_arqcookie = cmd->cmd_arqcookie; 3502 bzero(cmd, sizeof (*cmd) + scsi_pkt_size()); 3503 cmd->cmd_dmahandle = save_dma_handle; 3504 cmd->cmd_arqhandle = save_arq_dma_handle; 3505 cmd->cmd_arq_buf = save_arq_bp; 3506 cmd->cmd_arqcookie = save_arqcookie; 3507 3508 pkt = (void *)((uchar_t *)cmd + 3509 sizeof (struct mptsas_cmd)); 3510 pkt->pkt_ha_private = (opaque_t)cmd; 3511 pkt->pkt_address = *ap; 3512 pkt->pkt_private = (opaque_t)cmd->cmd_pkt_private; 3513 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; 3514 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb; 3515 cmd->cmd_pkt = (struct scsi_pkt *)pkt; 3516 cmd->cmd_cdblen = (uchar_t)cmdlen; 3517 cmd->cmd_scblen = statuslen; 3518 cmd->cmd_rqslen = SENSE_LENGTH; 3519 cmd->cmd_tgt_addr = ptgt; 3520 failure = 0; 3521 } 3522 3523 if (failure || (cmdlen > sizeof (cmd->cmd_cdb)) || 3524 (tgtlen > PKT_PRIV_LEN) || 3525 (statuslen > EXTCMDS_STATUS_SIZE)) { 3526 if (failure == 0) { 3527 /* 3528 * if extern alloc fails, all will be 3529 * deallocated, including cmd 3530 */ 3531 failure = mptsas_pkt_alloc_extern(mpt, cmd, 3532 cmdlen, tgtlen, statuslen, kf); 3533 } 3534 if (failure) { 3535 /* 3536 * if extern allocation fails, it will 3537 * deallocate the new pkt as well 3538 */ 3539 return (NULL); 3540 } 3541 } 3542 new_cmd = cmd; 3543 3544 } else { 3545 cmd = PKT2CMD(pkt); 3546 new_cmd = NULL; 3547 } 3548 3549 3550 /* grab cmd->cmd_cookiec here as oldcookiec */ 3551 3552 oldcookiec = cmd->cmd_cookiec; 3553 3554 /* 3555 * If the dma was broken up into PARTIAL transfers cmd_nwin will be 3556 * greater than 0 and we'll need to grab the next dma window 3557 */ 3558 /* 3559 * SLM-not doing extra command frame right now; may add later 3560 */ 3561 3562 if (cmd->cmd_nwin > 0) { 3563 3564 /* 3565 * Make sure we havn't gone past the the total number 3566 * of windows 3567 */ 3568 if (++cmd->cmd_winindex >= cmd->cmd_nwin) { 3569 return (NULL); 3570 } 3571 if (ddi_dma_getwin(cmd->cmd_dmahandle, cmd->cmd_winindex, 3572 &cmd->cmd_dma_offset, &cmd->cmd_dma_len, 3573 &cmd->cmd_cookie, &cmd->cmd_cookiec) == DDI_FAILURE) { 3574 return (NULL); 3575 } 3576 goto get_dma_cookies; 3577 } 3578 3579 3580 if (flags & PKT_XARQ) { 3581 cmd->cmd_flags |= CFLAG_XARQ; 3582 } 3583 3584 /* 3585 * DMA resource allocation. This version assumes your 3586 * HBA has some sort of bus-mastering or onboard DMA capability, with a 3587 * scatter-gather list of length MPTSAS_MAX_DMA_SEGS, as given in the 3588 * ddi_dma_attr_t structure and passed to scsi_impl_dmaget. 3589 */ 3590 if (bp && (bp->b_bcount != 0) && 3591 (cmd->cmd_flags & CFLAG_DMAVALID) == 0) { 3592 3593 int cnt, dma_flags; 3594 mptti_t *dmap; /* ptr to the S/G list */ 3595 3596 /* 3597 * Set up DMA memory and position to the next DMA segment. 3598 */ 3599 ASSERT(cmd->cmd_dmahandle != NULL); 3600 3601 if (bp->b_flags & B_READ) { 3602 dma_flags = DDI_DMA_READ; 3603 cmd->cmd_flags &= ~CFLAG_DMASEND; 3604 } else { 3605 dma_flags = DDI_DMA_WRITE; 3606 cmd->cmd_flags |= CFLAG_DMASEND; 3607 } 3608 if (flags & PKT_CONSISTENT) { 3609 cmd->cmd_flags |= CFLAG_CMDIOPB; 3610 dma_flags |= DDI_DMA_CONSISTENT; 3611 } 3612 3613 if (flags & PKT_DMA_PARTIAL) { 3614 dma_flags |= DDI_DMA_PARTIAL; 3615 } 3616 3617 /* 3618 * workaround for byte hole issue on psycho and 3619 * schizo pre 2.1 3620 */ 3621 if ((bp->b_flags & B_READ) && ((bp->b_flags & 3622 (B_PAGEIO|B_REMAPPED)) != B_PAGEIO) && 3623 ((uintptr_t)bp->b_un.b_addr & 0x7)) { 3624 dma_flags |= DDI_DMA_CONSISTENT; 3625 } 3626 3627 rval = ddi_dma_buf_bind_handle(cmd->cmd_dmahandle, bp, 3628 dma_flags, callback, arg, 3629 &cmd->cmd_cookie, &cmd->cmd_cookiec); 3630 if (rval == DDI_DMA_PARTIAL_MAP) { 3631 (void) ddi_dma_numwin(cmd->cmd_dmahandle, 3632 &cmd->cmd_nwin); 3633 cmd->cmd_winindex = 0; 3634 (void) ddi_dma_getwin(cmd->cmd_dmahandle, 3635 cmd->cmd_winindex, &cmd->cmd_dma_offset, 3636 &cmd->cmd_dma_len, &cmd->cmd_cookie, 3637 &cmd->cmd_cookiec); 3638 } else if (rval && (rval != DDI_DMA_MAPPED)) { 3639 switch (rval) { 3640 case DDI_DMA_NORESOURCES: 3641 bioerror(bp, 0); 3642 break; 3643 case DDI_DMA_BADATTR: 3644 case DDI_DMA_NOMAPPING: 3645 bioerror(bp, EFAULT); 3646 break; 3647 case DDI_DMA_TOOBIG: 3648 default: 3649 bioerror(bp, EINVAL); 3650 break; 3651 } 3652 cmd->cmd_flags &= ~CFLAG_DMAVALID; 3653 if (new_cmd) { 3654 mptsas_scsi_destroy_pkt(ap, pkt); 3655 } 3656 return ((struct scsi_pkt *)NULL); 3657 } 3658 3659 get_dma_cookies: 3660 cmd->cmd_flags |= CFLAG_DMAVALID; 3661 ASSERT(cmd->cmd_cookiec > 0); 3662 3663 if (cmd->cmd_cookiec > MPTSAS_MAX_CMD_SEGS) { 3664 mptsas_log(mpt, CE_NOTE, "large cookiec received %d\n", 3665 cmd->cmd_cookiec); 3666 bioerror(bp, EINVAL); 3667 if (new_cmd) { 3668 mptsas_scsi_destroy_pkt(ap, pkt); 3669 } 3670 return ((struct scsi_pkt *)NULL); 3671 } 3672 3673 /* 3674 * Allocate extra SGL buffer if needed. 3675 */ 3676 if ((cmd->cmd_cookiec > MPTSAS_MAX_FRAME_SGES64(mpt)) && 3677 (cmd->cmd_extra_frames == NULL)) { 3678 if (mptsas_alloc_extra_sgl_frame(mpt, cmd) == 3679 DDI_FAILURE) { 3680 mptsas_log(mpt, CE_WARN, "MPT SGL mem alloc " 3681 "failed"); 3682 bioerror(bp, ENOMEM); 3683 if (new_cmd) { 3684 mptsas_scsi_destroy_pkt(ap, pkt); 3685 } 3686 return ((struct scsi_pkt *)NULL); 3687 } 3688 } 3689 3690 /* 3691 * Always use scatter-gather transfer 3692 * Use the loop below to store physical addresses of 3693 * DMA segments, from the DMA cookies, into your HBA's 3694 * scatter-gather list. 3695 * We need to ensure we have enough kmem alloc'd 3696 * for the sg entries since we are no longer using an 3697 * array inside mptsas_cmd_t. 3698 * 3699 * We check cmd->cmd_cookiec against oldcookiec so 3700 * the scatter-gather list is correctly allocated 3701 */ 3702 3703 if (oldcookiec != cmd->cmd_cookiec) { 3704 if (cmd->cmd_sg != (mptti_t *)NULL) { 3705 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * 3706 oldcookiec); 3707 cmd->cmd_sg = NULL; 3708 } 3709 } 3710 3711 if (cmd->cmd_sg == (mptti_t *)NULL) { 3712 cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)* 3713 cmd->cmd_cookiec), kf); 3714 3715 if (cmd->cmd_sg == (mptti_t *)NULL) { 3716 mptsas_log(mpt, CE_WARN, 3717 "unable to kmem_alloc enough memory " 3718 "for scatter/gather list"); 3719 /* 3720 * if we have an ENOMEM condition we need to behave 3721 * the same way as the rest of this routine 3722 */ 3723 3724 bioerror(bp, ENOMEM); 3725 if (new_cmd) { 3726 mptsas_scsi_destroy_pkt(ap, pkt); 3727 } 3728 return ((struct scsi_pkt *)NULL); 3729 } 3730 } 3731 3732 dmap = cmd->cmd_sg; 3733 3734 ASSERT(cmd->cmd_cookie.dmac_size != 0); 3735 3736 /* 3737 * store the first segment into the S/G list 3738 */ 3739 dmap->count = cmd->cmd_cookie.dmac_size; 3740 dmap->addr.address64.Low = (uint32_t) 3741 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull); 3742 dmap->addr.address64.High = (uint32_t) 3743 (cmd->cmd_cookie.dmac_laddress >> 32); 3744 3745 /* 3746 * dmacount counts the size of the dma for this window 3747 * (if partial dma is being used). totaldmacount 3748 * keeps track of the total amount of dma we have 3749 * transferred for all the windows (needed to calculate 3750 * the resid value below). 3751 */ 3752 cmd->cmd_dmacount = cmd->cmd_cookie.dmac_size; 3753 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size; 3754 3755 /* 3756 * We already stored the first DMA scatter gather segment, 3757 * start at 1 if we need to store more. 3758 */ 3759 for (cnt = 1; cnt < cmd->cmd_cookiec; cnt++) { 3760 /* 3761 * Get next DMA cookie 3762 */ 3763 ddi_dma_nextcookie(cmd->cmd_dmahandle, 3764 &cmd->cmd_cookie); 3765 dmap++; 3766 3767 cmd->cmd_dmacount += cmd->cmd_cookie.dmac_size; 3768 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size; 3769 3770 /* 3771 * store the segment parms into the S/G list 3772 */ 3773 dmap->count = cmd->cmd_cookie.dmac_size; 3774 dmap->addr.address64.Low = (uint32_t) 3775 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull); 3776 dmap->addr.address64.High = (uint32_t) 3777 (cmd->cmd_cookie.dmac_laddress >> 32); 3778 } 3779 3780 /* 3781 * If this was partially allocated we set the resid 3782 * the amount of data NOT transferred in this window 3783 * If there is only one window, the resid will be 0 3784 */ 3785 pkt->pkt_resid = (bp->b_bcount - cmd->cmd_totaldmacount); 3786 NDBG16(("mptsas_dmaget: cmd_dmacount=%d.", cmd->cmd_dmacount)); 3787 } 3788 return (pkt); 3789 } 3790 3791 /* 3792 * tran_destroy_pkt(9E) - scsi_pkt(9s) deallocation 3793 * 3794 * Notes: 3795 * - also frees DMA resources if allocated 3796 * - implicit DMA synchonization 3797 */ 3798 static void 3799 mptsas_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 3800 { 3801 mptsas_cmd_t *cmd = PKT2CMD(pkt); 3802 mptsas_t *mpt = ADDR2MPT(ap); 3803 3804 NDBG3(("mptsas_scsi_destroy_pkt: target=%d pkt=0x%p", 3805 ap->a_target, (void *)pkt)); 3806 3807 if (cmd->cmd_flags & CFLAG_DMAVALID) { 3808 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle); 3809 cmd->cmd_flags &= ~CFLAG_DMAVALID; 3810 } 3811 3812 if (cmd->cmd_sg) { 3813 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * cmd->cmd_cookiec); 3814 cmd->cmd_sg = NULL; 3815 } 3816 3817 mptsas_free_extra_sgl_frame(mpt, cmd); 3818 3819 if ((cmd->cmd_flags & 3820 (CFLAG_FREE | CFLAG_CDBEXTERN | CFLAG_PRIVEXTERN | 3821 CFLAG_SCBEXTERN)) == 0) { 3822 cmd->cmd_flags = CFLAG_FREE; 3823 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd); 3824 } else { 3825 mptsas_pkt_destroy_extern(mpt, cmd); 3826 } 3827 } 3828 3829 /* 3830 * kmem cache constructor and destructor: 3831 * When constructing, we bzero the cmd and allocate the dma handle 3832 * When destructing, just free the dma handle 3833 */ 3834 static int 3835 mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags) 3836 { 3837 mptsas_cmd_t *cmd = buf; 3838 mptsas_t *mpt = cdrarg; 3839 struct scsi_address ap; 3840 uint_t cookiec; 3841 ddi_dma_attr_t arq_dma_attr; 3842 int (*callback)(caddr_t); 3843 3844 callback = (kmflags == KM_SLEEP)? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT; 3845 3846 NDBG4(("mptsas_kmem_cache_constructor")); 3847 3848 ap.a_hba_tran = mpt->m_tran; 3849 ap.a_target = 0; 3850 ap.a_lun = 0; 3851 3852 /* 3853 * allocate a dma handle 3854 */ 3855 if ((ddi_dma_alloc_handle(mpt->m_dip, &mpt->m_io_dma_attr, callback, 3856 NULL, &cmd->cmd_dmahandle)) != DDI_SUCCESS) { 3857 cmd->cmd_dmahandle = NULL; 3858 return (-1); 3859 } 3860 3861 cmd->cmd_arq_buf = scsi_alloc_consistent_buf(&ap, (struct buf *)NULL, 3862 SENSE_LENGTH, B_READ, callback, NULL); 3863 if (cmd->cmd_arq_buf == NULL) { 3864 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3865 cmd->cmd_dmahandle = NULL; 3866 return (-1); 3867 } 3868 3869 /* 3870 * allocate a arq handle 3871 */ 3872 arq_dma_attr = mpt->m_msg_dma_attr; 3873 arq_dma_attr.dma_attr_sgllen = 1; 3874 if ((ddi_dma_alloc_handle(mpt->m_dip, &arq_dma_attr, callback, 3875 NULL, &cmd->cmd_arqhandle)) != DDI_SUCCESS) { 3876 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3877 scsi_free_consistent_buf(cmd->cmd_arq_buf); 3878 cmd->cmd_dmahandle = NULL; 3879 cmd->cmd_arqhandle = NULL; 3880 return (-1); 3881 } 3882 3883 if (ddi_dma_buf_bind_handle(cmd->cmd_arqhandle, 3884 cmd->cmd_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT), 3885 callback, NULL, &cmd->cmd_arqcookie, &cookiec) != DDI_SUCCESS) { 3886 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3887 ddi_dma_free_handle(&cmd->cmd_arqhandle); 3888 scsi_free_consistent_buf(cmd->cmd_arq_buf); 3889 cmd->cmd_dmahandle = NULL; 3890 cmd->cmd_arqhandle = NULL; 3891 cmd->cmd_arq_buf = NULL; 3892 return (-1); 3893 } 3894 3895 return (0); 3896 } 3897 3898 static void 3899 mptsas_kmem_cache_destructor(void *buf, void *cdrarg) 3900 { 3901 #ifndef __lock_lint 3902 _NOTE(ARGUNUSED(cdrarg)) 3903 #endif 3904 mptsas_cmd_t *cmd = buf; 3905 3906 NDBG4(("mptsas_kmem_cache_destructor")); 3907 3908 if (cmd->cmd_arqhandle) { 3909 (void) ddi_dma_unbind_handle(cmd->cmd_arqhandle); 3910 ddi_dma_free_handle(&cmd->cmd_arqhandle); 3911 cmd->cmd_arqhandle = NULL; 3912 } 3913 if (cmd->cmd_arq_buf) { 3914 scsi_free_consistent_buf(cmd->cmd_arq_buf); 3915 cmd->cmd_arq_buf = NULL; 3916 } 3917 if (cmd->cmd_dmahandle) { 3918 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3919 cmd->cmd_dmahandle = NULL; 3920 } 3921 } 3922 3923 static int 3924 mptsas_cache_frames_constructor(void *buf, void *cdrarg, int kmflags) 3925 { 3926 mptsas_cache_frames_t *p = buf; 3927 mptsas_t *mpt = cdrarg; 3928 ddi_dma_attr_t frame_dma_attr; 3929 size_t mem_size, alloc_len; 3930 ddi_dma_cookie_t cookie; 3931 uint_t ncookie; 3932 int (*callback)(caddr_t) = (kmflags == KM_SLEEP) 3933 ? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT; 3934 3935 frame_dma_attr = mpt->m_msg_dma_attr; 3936 frame_dma_attr.dma_attr_align = 0x10; 3937 frame_dma_attr.dma_attr_sgllen = 1; 3938 3939 if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attr, callback, NULL, 3940 &p->m_dma_hdl) != DDI_SUCCESS) { 3941 mptsas_log(mpt, CE_WARN, "Unable to allocate dma handle for" 3942 " extra SGL."); 3943 return (DDI_FAILURE); 3944 } 3945 3946 mem_size = (mpt->m_max_request_frames - 1) * mpt->m_req_frame_size; 3947 3948 if (ddi_dma_mem_alloc(p->m_dma_hdl, mem_size, &mpt->m_dev_acc_attr, 3949 DDI_DMA_CONSISTENT, callback, NULL, (caddr_t *)&p->m_frames_addr, 3950 &alloc_len, &p->m_acc_hdl) != DDI_SUCCESS) { 3951 ddi_dma_free_handle(&p->m_dma_hdl); 3952 p->m_dma_hdl = NULL; 3953 mptsas_log(mpt, CE_WARN, "Unable to allocate dma memory for" 3954 " extra SGL."); 3955 return (DDI_FAILURE); 3956 } 3957 3958 if (ddi_dma_addr_bind_handle(p->m_dma_hdl, NULL, p->m_frames_addr, 3959 alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, callback, NULL, 3960 &cookie, &ncookie) != DDI_DMA_MAPPED) { 3961 (void) ddi_dma_mem_free(&p->m_acc_hdl); 3962 ddi_dma_free_handle(&p->m_dma_hdl); 3963 p->m_dma_hdl = NULL; 3964 mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources for" 3965 " extra SGL"); 3966 return (DDI_FAILURE); 3967 } 3968 3969 /* 3970 * Store the SGL memory address. This chip uses this 3971 * address to dma to and from the driver. The second 3972 * address is the address mpt uses to fill in the SGL. 3973 */ 3974 p->m_phys_addr = cookie.dmac_address; 3975 3976 return (DDI_SUCCESS); 3977 } 3978 3979 static void 3980 mptsas_cache_frames_destructor(void *buf, void *cdrarg) 3981 { 3982 #ifndef __lock_lint 3983 _NOTE(ARGUNUSED(cdrarg)) 3984 #endif 3985 mptsas_cache_frames_t *p = buf; 3986 if (p->m_dma_hdl != NULL) { 3987 (void) ddi_dma_unbind_handle(p->m_dma_hdl); 3988 (void) ddi_dma_mem_free(&p->m_acc_hdl); 3989 ddi_dma_free_handle(&p->m_dma_hdl); 3990 p->m_phys_addr = NULL; 3991 p->m_frames_addr = NULL; 3992 p->m_dma_hdl = NULL; 3993 p->m_acc_hdl = NULL; 3994 } 3995 3996 } 3997 3998 /* 3999 * allocate and deallocate external pkt space (ie. not part of mptsas_cmd) 4000 * for non-standard length cdb, pkt_private, status areas 4001 * if allocation fails, then deallocate all external space and the pkt 4002 */ 4003 /* ARGSUSED */ 4004 static int 4005 mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd, 4006 int cmdlen, int tgtlen, int statuslen, int kf) 4007 { 4008 caddr_t cdbp, scbp, tgt; 4009 int (*callback)(caddr_t) = (kf == KM_SLEEP) ? 4010 DDI_DMA_SLEEP : DDI_DMA_DONTWAIT; 4011 struct scsi_address ap; 4012 size_t senselength; 4013 ddi_dma_attr_t ext_arq_dma_attr; 4014 uint_t cookiec; 4015 4016 NDBG3(("mptsas_pkt_alloc_extern: " 4017 "cmd=0x%p cmdlen=%d tgtlen=%d statuslen=%d kf=%x", 4018 (void *)cmd, cmdlen, tgtlen, statuslen, kf)); 4019 4020 tgt = cdbp = scbp = NULL; 4021 cmd->cmd_scblen = statuslen; 4022 cmd->cmd_privlen = (uchar_t)tgtlen; 4023 4024 if (cmdlen > sizeof (cmd->cmd_cdb)) { 4025 if ((cdbp = kmem_zalloc((size_t)cmdlen, kf)) == NULL) { 4026 goto fail; 4027 } 4028 cmd->cmd_pkt->pkt_cdbp = (opaque_t)cdbp; 4029 cmd->cmd_flags |= CFLAG_CDBEXTERN; 4030 } 4031 if (tgtlen > PKT_PRIV_LEN) { 4032 if ((tgt = kmem_zalloc((size_t)tgtlen, kf)) == NULL) { 4033 goto fail; 4034 } 4035 cmd->cmd_flags |= CFLAG_PRIVEXTERN; 4036 cmd->cmd_pkt->pkt_private = tgt; 4037 } 4038 if (statuslen > EXTCMDS_STATUS_SIZE) { 4039 if ((scbp = kmem_zalloc((size_t)statuslen, kf)) == NULL) { 4040 goto fail; 4041 } 4042 cmd->cmd_flags |= CFLAG_SCBEXTERN; 4043 cmd->cmd_pkt->pkt_scbp = (opaque_t)scbp; 4044 4045 /* allocate sense data buf for DMA */ 4046 4047 senselength = statuslen - MPTSAS_GET_ITEM_OFF( 4048 struct scsi_arq_status, sts_sensedata); 4049 cmd->cmd_rqslen = (uchar_t)senselength; 4050 4051 ap.a_hba_tran = mpt->m_tran; 4052 ap.a_target = 0; 4053 ap.a_lun = 0; 4054 4055 cmd->cmd_ext_arq_buf = scsi_alloc_consistent_buf(&ap, 4056 (struct buf *)NULL, senselength, B_READ, 4057 callback, NULL); 4058 4059 if (cmd->cmd_ext_arq_buf == NULL) { 4060 goto fail; 4061 } 4062 /* 4063 * allocate a extern arq handle and bind the buf 4064 */ 4065 ext_arq_dma_attr = mpt->m_msg_dma_attr; 4066 ext_arq_dma_attr.dma_attr_sgllen = 1; 4067 if ((ddi_dma_alloc_handle(mpt->m_dip, 4068 &ext_arq_dma_attr, callback, 4069 NULL, &cmd->cmd_ext_arqhandle)) != DDI_SUCCESS) { 4070 goto fail; 4071 } 4072 4073 if (ddi_dma_buf_bind_handle(cmd->cmd_ext_arqhandle, 4074 cmd->cmd_ext_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT), 4075 callback, NULL, &cmd->cmd_ext_arqcookie, 4076 &cookiec) 4077 != DDI_SUCCESS) { 4078 goto fail; 4079 } 4080 cmd->cmd_flags |= CFLAG_EXTARQBUFVALID; 4081 } 4082 return (0); 4083 fail: 4084 mptsas_pkt_destroy_extern(mpt, cmd); 4085 return (1); 4086 } 4087 4088 /* 4089 * deallocate external pkt space and deallocate the pkt 4090 */ 4091 static void 4092 mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd) 4093 { 4094 NDBG3(("mptsas_pkt_destroy_extern: cmd=0x%p", (void *)cmd)); 4095 4096 if (cmd->cmd_flags & CFLAG_FREE) { 4097 mptsas_log(mpt, CE_PANIC, 4098 "mptsas_pkt_destroy_extern: freeing free packet"); 4099 _NOTE(NOT_REACHED) 4100 /* NOTREACHED */ 4101 } 4102 if (cmd->cmd_flags & CFLAG_CDBEXTERN) { 4103 kmem_free(cmd->cmd_pkt->pkt_cdbp, (size_t)cmd->cmd_cdblen); 4104 } 4105 if (cmd->cmd_flags & CFLAG_SCBEXTERN) { 4106 kmem_free(cmd->cmd_pkt->pkt_scbp, (size_t)cmd->cmd_scblen); 4107 if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) { 4108 (void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle); 4109 } 4110 if (cmd->cmd_ext_arqhandle) { 4111 ddi_dma_free_handle(&cmd->cmd_ext_arqhandle); 4112 cmd->cmd_ext_arqhandle = NULL; 4113 } 4114 if (cmd->cmd_ext_arq_buf) 4115 scsi_free_consistent_buf(cmd->cmd_ext_arq_buf); 4116 } 4117 if (cmd->cmd_flags & CFLAG_PRIVEXTERN) { 4118 kmem_free(cmd->cmd_pkt->pkt_private, (size_t)cmd->cmd_privlen); 4119 } 4120 cmd->cmd_flags = CFLAG_FREE; 4121 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd); 4122 } 4123 4124 /* 4125 * tran_sync_pkt(9E) - explicit DMA synchronization 4126 */ 4127 /*ARGSUSED*/ 4128 static void 4129 mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 4130 { 4131 mptsas_cmd_t *cmd = PKT2CMD(pkt); 4132 4133 NDBG3(("mptsas_scsi_sync_pkt: target=%d, pkt=0x%p", 4134 ap->a_target, (void *)pkt)); 4135 4136 if (cmd->cmd_dmahandle) { 4137 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 4138 (cmd->cmd_flags & CFLAG_DMASEND) ? 4139 DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU); 4140 } 4141 } 4142 4143 /* 4144 * tran_dmafree(9E) - deallocate DMA resources allocated for command 4145 */ 4146 /*ARGSUSED*/ 4147 static void 4148 mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt) 4149 { 4150 mptsas_cmd_t *cmd = PKT2CMD(pkt); 4151 mptsas_t *mpt = ADDR2MPT(ap); 4152 4153 NDBG3(("mptsas_scsi_dmafree: target=%d pkt=0x%p", 4154 ap->a_target, (void *)pkt)); 4155 4156 if (cmd->cmd_flags & CFLAG_DMAVALID) { 4157 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle); 4158 cmd->cmd_flags &= ~CFLAG_DMAVALID; 4159 } 4160 4161 if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) { 4162 (void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle); 4163 cmd->cmd_flags &= ~CFLAG_EXTARQBUFVALID; 4164 } 4165 4166 mptsas_free_extra_sgl_frame(mpt, cmd); 4167 } 4168 4169 static void 4170 mptsas_pkt_comp(struct scsi_pkt *pkt, mptsas_cmd_t *cmd) 4171 { 4172 if ((cmd->cmd_flags & CFLAG_CMDIOPB) && 4173 (!(cmd->cmd_flags & CFLAG_DMASEND))) { 4174 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 4175 DDI_DMA_SYNC_FORCPU); 4176 } 4177 (*pkt->pkt_comp)(pkt); 4178 } 4179 4180 static void 4181 mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, uint32_t *control, 4182 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl) 4183 { 4184 uint_t cookiec; 4185 mptti_t *dmap; 4186 uint32_t flags; 4187 pMpi2SGESimple64_t sge; 4188 pMpi2SGEChain64_t sgechain; 4189 ASSERT(cmd->cmd_flags & CFLAG_DMAVALID); 4190 4191 /* 4192 * Save the number of entries in the DMA 4193 * Scatter/Gather list 4194 */ 4195 cookiec = cmd->cmd_cookiec; 4196 4197 NDBG1(("mptsas_sge_setup: cookiec=%d", cookiec)); 4198 4199 /* 4200 * Set read/write bit in control. 4201 */ 4202 if (cmd->cmd_flags & CFLAG_DMASEND) { 4203 *control |= MPI2_SCSIIO_CONTROL_WRITE; 4204 } else { 4205 *control |= MPI2_SCSIIO_CONTROL_READ; 4206 } 4207 4208 ddi_put32(acc_hdl, &frame->DataLength, cmd->cmd_dmacount); 4209 4210 /* 4211 * We have 2 cases here. First where we can fit all the 4212 * SG elements into the main frame, and the case 4213 * where we can't. 4214 * If we have more cookies than we can attach to a frame 4215 * we will need to use a chain element to point 4216 * a location of memory where the rest of the S/G 4217 * elements reside. 4218 */ 4219 if (cookiec <= MPTSAS_MAX_FRAME_SGES64(mpt)) { 4220 dmap = cmd->cmd_sg; 4221 sge = (pMpi2SGESimple64_t)(&frame->SGL); 4222 while (cookiec--) { 4223 ddi_put32(acc_hdl, 4224 &sge->Address.Low, dmap->addr.address64.Low); 4225 ddi_put32(acc_hdl, 4226 &sge->Address.High, dmap->addr.address64.High); 4227 ddi_put32(acc_hdl, &sge->FlagsLength, 4228 dmap->count); 4229 flags = ddi_get32(acc_hdl, &sge->FlagsLength); 4230 flags |= ((uint32_t) 4231 (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4232 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4233 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4234 MPI2_SGE_FLAGS_SHIFT); 4235 4236 /* 4237 * If this is the last cookie, we set the flags 4238 * to indicate so 4239 */ 4240 if (cookiec == 0) { 4241 flags |= 4242 ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT 4243 | MPI2_SGE_FLAGS_END_OF_BUFFER 4244 | MPI2_SGE_FLAGS_END_OF_LIST) << 4245 MPI2_SGE_FLAGS_SHIFT); 4246 } 4247 if (cmd->cmd_flags & CFLAG_DMASEND) { 4248 flags |= (MPI2_SGE_FLAGS_HOST_TO_IOC << 4249 MPI2_SGE_FLAGS_SHIFT); 4250 } else { 4251 flags |= (MPI2_SGE_FLAGS_IOC_TO_HOST << 4252 MPI2_SGE_FLAGS_SHIFT); 4253 } 4254 ddi_put32(acc_hdl, &sge->FlagsLength, flags); 4255 dmap++; 4256 sge++; 4257 } 4258 } else { 4259 /* 4260 * Hereby we start to deal with multiple frames. 4261 * The process is as follows: 4262 * 1. Determine how many frames are needed for SGL element 4263 * storage; Note that all frames are stored in contiguous 4264 * memory space and in 64-bit DMA mode each element is 4265 * 3 double-words (12 bytes) long. 4266 * 2. Fill up the main frame. We need to do this separately 4267 * since it contains the SCSI IO request header and needs 4268 * dedicated processing. Note that the last 4 double-words 4269 * of the SCSI IO header is for SGL element storage 4270 * (MPI2_SGE_IO_UNION). 4271 * 3. Fill the chain element in the main frame, so the DMA 4272 * engine can use the following frames. 4273 * 4. Enter a loop to fill the remaining frames. Note that the 4274 * last frame contains no chain element. The remaining 4275 * frames go into the mpt SGL buffer allocated on the fly, 4276 * not immediately following the main message frame, as in 4277 * Gen1. 4278 * Some restrictions: 4279 * 1. For 64-bit DMA, the simple element and chain element 4280 * are both of 3 double-words (12 bytes) in size, even 4281 * though all frames are stored in the first 4G of mem 4282 * range and the higher 32-bits of the address are always 0. 4283 * 2. On some controllers (like the 1064/1068), a frame can 4284 * hold SGL elements with the last 1 or 2 double-words 4285 * (4 or 8 bytes) un-used. On these controllers, we should 4286 * recognize that there's not enough room for another SGL 4287 * element and move the sge pointer to the next frame. 4288 */ 4289 int i, j, k, l, frames, sgemax; 4290 int temp; 4291 uint8_t chainflags; 4292 uint16_t chainlength; 4293 mptsas_cache_frames_t *p; 4294 4295 /* 4296 * Sgemax is the number of SGE's that will fit 4297 * each extra frame and frames is total 4298 * number of frames we'll need. 1 sge entry per 4299 * frame is reseverd for the chain element thus the -1 below. 4300 */ 4301 sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_SGE_SIMPLE64)) 4302 - 1); 4303 temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax; 4304 4305 /* 4306 * A little check to see if we need to round up the number 4307 * of frames we need 4308 */ 4309 if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp * 4310 sgemax) > 1) { 4311 frames = (temp + 1); 4312 } else { 4313 frames = temp; 4314 } 4315 dmap = cmd->cmd_sg; 4316 sge = (pMpi2SGESimple64_t)(&frame->SGL); 4317 4318 /* 4319 * First fill in the main frame 4320 */ 4321 for (j = 1; j < MPTSAS_MAX_FRAME_SGES64(mpt); j++) { 4322 ddi_put32(acc_hdl, &sge->Address.Low, 4323 dmap->addr.address64.Low); 4324 ddi_put32(acc_hdl, &sge->Address.High, 4325 dmap->addr.address64.High); 4326 ddi_put32(acc_hdl, &sge->FlagsLength, dmap->count); 4327 flags = ddi_get32(acc_hdl, &sge->FlagsLength); 4328 flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4329 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4330 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4331 MPI2_SGE_FLAGS_SHIFT); 4332 4333 /* 4334 * If this is the last SGE of this frame 4335 * we set the end of list flag 4336 */ 4337 if (j == (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) { 4338 flags |= ((uint32_t) 4339 (MPI2_SGE_FLAGS_LAST_ELEMENT) << 4340 MPI2_SGE_FLAGS_SHIFT); 4341 } 4342 if (cmd->cmd_flags & CFLAG_DMASEND) { 4343 flags |= 4344 (MPI2_SGE_FLAGS_HOST_TO_IOC << 4345 MPI2_SGE_FLAGS_SHIFT); 4346 } else { 4347 flags |= 4348 (MPI2_SGE_FLAGS_IOC_TO_HOST << 4349 MPI2_SGE_FLAGS_SHIFT); 4350 } 4351 ddi_put32(acc_hdl, &sge->FlagsLength, flags); 4352 dmap++; 4353 sge++; 4354 } 4355 4356 /* 4357 * Fill in the chain element in the main frame. 4358 * About calculation on ChainOffset: 4359 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes) 4360 * in the end reserved for SGL element storage 4361 * (MPI2_SGE_IO_UNION); we should count it in our 4362 * calculation. See its definition in the header file. 4363 * 2. Constant j is the counter of the current SGL element 4364 * that will be processed, and (j - 1) is the number of 4365 * SGL elements that have been processed (stored in the 4366 * main frame). 4367 * 3. ChainOffset value should be in units of double-words (4 4368 * bytes) so the last value should be divided by 4. 4369 */ 4370 ddi_put8(acc_hdl, &frame->ChainOffset, 4371 (sizeof (MPI2_SCSI_IO_REQUEST) - 4372 sizeof (MPI2_SGE_IO_UNION) + 4373 (j - 1) * sizeof (MPI2_SGE_SIMPLE64)) >> 2); 4374 sgechain = (pMpi2SGEChain64_t)sge; 4375 chainflags = (MPI2_SGE_FLAGS_CHAIN_ELEMENT | 4376 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4377 MPI2_SGE_FLAGS_64_BIT_ADDRESSING); 4378 ddi_put8(acc_hdl, &sgechain->Flags, chainflags); 4379 4380 /* 4381 * The size of the next frame is the accurate size of space 4382 * (in bytes) used to store the SGL elements. j is the counter 4383 * of SGL elements. (j - 1) is the number of SGL elements that 4384 * have been processed (stored in frames). 4385 */ 4386 if (frames >= 2) { 4387 chainlength = mpt->m_req_frame_size / 4388 sizeof (MPI2_SGE_SIMPLE64) * 4389 sizeof (MPI2_SGE_SIMPLE64); 4390 } else { 4391 chainlength = ((cookiec - (j - 1)) * 4392 sizeof (MPI2_SGE_SIMPLE64)); 4393 } 4394 4395 p = cmd->cmd_extra_frames; 4396 4397 ddi_put16(acc_hdl, &sgechain->Length, chainlength); 4398 ddi_put32(acc_hdl, &sgechain->Address.Low, 4399 p->m_phys_addr); 4400 /* SGL is allocated in the first 4G mem range */ 4401 ddi_put32(acc_hdl, &sgechain->Address.High, 0); 4402 4403 /* 4404 * If there are more than 2 frames left we have to 4405 * fill in the next chain offset to the location of 4406 * the chain element in the next frame. 4407 * sgemax is the number of simple elements in an extra 4408 * frame. Note that the value NextChainOffset should be 4409 * in double-words (4 bytes). 4410 */ 4411 if (frames >= 2) { 4412 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 4413 (sgemax * sizeof (MPI2_SGE_SIMPLE64)) >> 2); 4414 } else { 4415 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 0); 4416 } 4417 4418 /* 4419 * Jump to next frame; 4420 * Starting here, chain buffers go into the per command SGL. 4421 * This buffer is allocated when chain buffers are needed. 4422 */ 4423 sge = (pMpi2SGESimple64_t)p->m_frames_addr; 4424 i = cookiec; 4425 4426 /* 4427 * Start filling in frames with SGE's. If we 4428 * reach the end of frame and still have SGE's 4429 * to fill we need to add a chain element and 4430 * use another frame. j will be our counter 4431 * for what cookie we are at and i will be 4432 * the total cookiec. k is the current frame 4433 */ 4434 for (k = 1; k <= frames; k++) { 4435 for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) { 4436 4437 /* 4438 * If we have reached the end of frame 4439 * and we have more SGE's to fill in 4440 * we have to fill the final entry 4441 * with a chain element and then 4442 * continue to the next frame 4443 */ 4444 if ((l == (sgemax + 1)) && (k != frames)) { 4445 sgechain = (pMpi2SGEChain64_t)sge; 4446 j--; 4447 chainflags = ( 4448 MPI2_SGE_FLAGS_CHAIN_ELEMENT | 4449 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4450 MPI2_SGE_FLAGS_64_BIT_ADDRESSING); 4451 ddi_put8(p->m_acc_hdl, 4452 &sgechain->Flags, chainflags); 4453 /* 4454 * k is the frame counter and (k + 1) 4455 * is the number of the next frame. 4456 * Note that frames are in contiguous 4457 * memory space. 4458 */ 4459 ddi_put32(p->m_acc_hdl, 4460 &sgechain->Address.Low, 4461 (p->m_phys_addr + 4462 (mpt->m_req_frame_size * k))); 4463 ddi_put32(p->m_acc_hdl, 4464 &sgechain->Address.High, 0); 4465 4466 /* 4467 * If there are more than 2 frames left 4468 * we have to next chain offset to 4469 * the location of the chain element 4470 * in the next frame and fill in the 4471 * length of the next chain 4472 */ 4473 if ((frames - k) >= 2) { 4474 ddi_put8(p->m_acc_hdl, 4475 &sgechain->NextChainOffset, 4476 (sgemax * 4477 sizeof (MPI2_SGE_SIMPLE64)) 4478 >> 2); 4479 ddi_put16(p->m_acc_hdl, 4480 &sgechain->Length, 4481 mpt->m_req_frame_size / 4482 sizeof (MPI2_SGE_SIMPLE64) * 4483 sizeof (MPI2_SGE_SIMPLE64)); 4484 } else { 4485 /* 4486 * This is the last frame. Set 4487 * the NextChainOffset to 0 and 4488 * Length is the total size of 4489 * all remaining simple elements 4490 */ 4491 ddi_put8(p->m_acc_hdl, 4492 &sgechain->NextChainOffset, 4493 0); 4494 ddi_put16(p->m_acc_hdl, 4495 &sgechain->Length, 4496 (cookiec - j) * 4497 sizeof (MPI2_SGE_SIMPLE64)); 4498 } 4499 4500 /* Jump to the next frame */ 4501 sge = (pMpi2SGESimple64_t) 4502 ((char *)p->m_frames_addr + 4503 (int)mpt->m_req_frame_size * k); 4504 4505 continue; 4506 } 4507 4508 ddi_put32(p->m_acc_hdl, 4509 &sge->Address.Low, 4510 dmap->addr.address64.Low); 4511 ddi_put32(p->m_acc_hdl, 4512 &sge->Address.High, 4513 dmap->addr.address64.High); 4514 ddi_put32(p->m_acc_hdl, 4515 &sge->FlagsLength, dmap->count); 4516 flags = ddi_get32(p->m_acc_hdl, 4517 &sge->FlagsLength); 4518 flags |= ((uint32_t)( 4519 MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4520 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4521 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4522 MPI2_SGE_FLAGS_SHIFT); 4523 4524 /* 4525 * If we are at the end of the frame and 4526 * there is another frame to fill in 4527 * we set the last simple element as last 4528 * element 4529 */ 4530 if ((l == sgemax) && (k != frames)) { 4531 flags |= ((uint32_t) 4532 (MPI2_SGE_FLAGS_LAST_ELEMENT) << 4533 MPI2_SGE_FLAGS_SHIFT); 4534 } 4535 4536 /* 4537 * If this is the final cookie we 4538 * indicate it by setting the flags 4539 */ 4540 if (j == i) { 4541 flags |= ((uint32_t) 4542 (MPI2_SGE_FLAGS_LAST_ELEMENT | 4543 MPI2_SGE_FLAGS_END_OF_BUFFER | 4544 MPI2_SGE_FLAGS_END_OF_LIST) << 4545 MPI2_SGE_FLAGS_SHIFT); 4546 } 4547 if (cmd->cmd_flags & CFLAG_DMASEND) { 4548 flags |= 4549 (MPI2_SGE_FLAGS_HOST_TO_IOC << 4550 MPI2_SGE_FLAGS_SHIFT); 4551 } else { 4552 flags |= 4553 (MPI2_SGE_FLAGS_IOC_TO_HOST << 4554 MPI2_SGE_FLAGS_SHIFT); 4555 } 4556 ddi_put32(p->m_acc_hdl, 4557 &sge->FlagsLength, flags); 4558 dmap++; 4559 sge++; 4560 } 4561 } 4562 4563 /* 4564 * Sync DMA with the chain buffers that were just created 4565 */ 4566 (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 4567 } 4568 } 4569 4570 /* 4571 * Interrupt handling 4572 * Utility routine. Poll for status of a command sent to HBA 4573 * without interrupts (a FLAG_NOINTR command). 4574 */ 4575 int 4576 mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime) 4577 { 4578 int rval = TRUE; 4579 4580 NDBG5(("mptsas_poll: cmd=0x%p", (void *)poll_cmd)); 4581 4582 if ((poll_cmd->cmd_flags & CFLAG_TM_CMD) == 0) { 4583 mptsas_restart_hba(mpt); 4584 } 4585 4586 /* 4587 * Wait, using drv_usecwait(), long enough for the command to 4588 * reasonably return from the target if the target isn't 4589 * "dead". A polled command may well be sent from scsi_poll, and 4590 * there are retries built in to scsi_poll if the transport 4591 * accepted the packet (TRAN_ACCEPT). scsi_poll waits 1 second 4592 * and retries the transport up to scsi_poll_busycnt times 4593 * (currently 60) if 4594 * 1. pkt_reason is CMD_INCOMPLETE and pkt_state is 0, or 4595 * 2. pkt_reason is CMD_CMPLT and *pkt_scbp has STATUS_BUSY 4596 * 4597 * limit the waiting to avoid a hang in the event that the 4598 * cmd never gets started but we are still receiving interrupts 4599 */ 4600 while (!(poll_cmd->cmd_flags & CFLAG_FINISHED)) { 4601 if (mptsas_wait_intr(mpt, polltime) == FALSE) { 4602 NDBG5(("mptsas_poll: command incomplete")); 4603 rval = FALSE; 4604 break; 4605 } 4606 } 4607 4608 if (rval == FALSE) { 4609 4610 /* 4611 * this isn't supposed to happen, the hba must be wedged 4612 * Mark this cmd as a timeout. 4613 */ 4614 mptsas_set_pkt_reason(mpt, poll_cmd, CMD_TIMEOUT, 4615 (STAT_TIMEOUT|STAT_ABORTED)); 4616 4617 if (poll_cmd->cmd_queued == FALSE) { 4618 4619 NDBG5(("mptsas_poll: not on waitq")); 4620 4621 poll_cmd->cmd_pkt->pkt_state |= 4622 (STATE_GOT_BUS|STATE_GOT_TARGET|STATE_SENT_CMD); 4623 } else { 4624 4625 /* find and remove it from the waitq */ 4626 NDBG5(("mptsas_poll: delete from waitq")); 4627 mptsas_waitq_delete(mpt, poll_cmd); 4628 } 4629 4630 } 4631 mptsas_fma_check(mpt, poll_cmd); 4632 NDBG5(("mptsas_poll: done")); 4633 return (rval); 4634 } 4635 4636 /* 4637 * Used for polling cmds and TM function 4638 */ 4639 static int 4640 mptsas_wait_intr(mptsas_t *mpt, int polltime) 4641 { 4642 int cnt; 4643 pMpi2ReplyDescriptorsUnion_t reply_desc_union; 4644 uint32_t int_mask; 4645 4646 NDBG5(("mptsas_wait_intr")); 4647 4648 mpt->m_polled_intr = 1; 4649 4650 /* 4651 * Get the current interrupt mask and disable interrupts. When 4652 * re-enabling ints, set mask to saved value. 4653 */ 4654 int_mask = ddi_get32(mpt->m_datap, &mpt->m_reg->HostInterruptMask); 4655 MPTSAS_DISABLE_INTR(mpt); 4656 4657 /* 4658 * Keep polling for at least (polltime * 1000) seconds 4659 */ 4660 for (cnt = 0; cnt < polltime; cnt++) { 4661 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 4662 DDI_DMA_SYNC_FORCPU); 4663 4664 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t) 4665 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index); 4666 4667 if (ddi_get32(mpt->m_acc_post_queue_hdl, 4668 &reply_desc_union->Words.Low) == 0xFFFFFFFF || 4669 ddi_get32(mpt->m_acc_post_queue_hdl, 4670 &reply_desc_union->Words.High) == 0xFFFFFFFF) { 4671 drv_usecwait(1000); 4672 continue; 4673 } 4674 4675 /* 4676 * The reply is valid, process it according to its 4677 * type. 4678 */ 4679 mptsas_process_intr(mpt, reply_desc_union); 4680 4681 if (++mpt->m_post_index == mpt->m_post_queue_depth) { 4682 mpt->m_post_index = 0; 4683 } 4684 4685 /* 4686 * Update the global reply index 4687 */ 4688 ddi_put32(mpt->m_datap, 4689 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); 4690 mpt->m_polled_intr = 0; 4691 4692 /* 4693 * Re-enable interrupts and quit. 4694 */ 4695 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, 4696 int_mask); 4697 return (TRUE); 4698 4699 } 4700 4701 /* 4702 * Clear polling flag, re-enable interrupts and quit. 4703 */ 4704 mpt->m_polled_intr = 0; 4705 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, int_mask); 4706 return (FALSE); 4707 } 4708 4709 static void 4710 mptsas_handle_scsi_io_success(mptsas_t *mpt, 4711 pMpi2ReplyDescriptorsUnion_t reply_desc) 4712 { 4713 pMpi2SCSIIOSuccessReplyDescriptor_t scsi_io_success; 4714 uint16_t SMID; 4715 mptsas_slots_t *slots = mpt->m_active; 4716 mptsas_cmd_t *cmd = NULL; 4717 struct scsi_pkt *pkt; 4718 4719 ASSERT(mutex_owned(&mpt->m_mutex)); 4720 4721 scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc; 4722 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &scsi_io_success->SMID); 4723 4724 /* 4725 * This is a success reply so just complete the IO. First, do a sanity 4726 * check on the SMID. The final slot is used for TM requests, which 4727 * would not come into this reply handler. 4728 */ 4729 if ((SMID == 0) || (SMID > slots->m_n_normal)) { 4730 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n", 4731 SMID); 4732 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 4733 return; 4734 } 4735 4736 cmd = slots->m_slot[SMID]; 4737 4738 /* 4739 * print warning and return if the slot is empty 4740 */ 4741 if (cmd == NULL) { 4742 mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO " 4743 "in slot %d", SMID); 4744 return; 4745 } 4746 4747 pkt = CMD2PKT(cmd); 4748 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD | 4749 STATE_GOT_STATUS); 4750 if (cmd->cmd_flags & CFLAG_DMAVALID) { 4751 pkt->pkt_state |= STATE_XFERRED_DATA; 4752 } 4753 pkt->pkt_resid = 0; 4754 4755 if (cmd->cmd_flags & CFLAG_PASSTHRU) { 4756 cmd->cmd_flags |= CFLAG_FINISHED; 4757 cv_broadcast(&mpt->m_passthru_cv); 4758 return; 4759 } else { 4760 mptsas_remove_cmd(mpt, cmd); 4761 } 4762 4763 if (cmd->cmd_flags & CFLAG_RETRY) { 4764 /* 4765 * The target returned QFULL or busy, do not add tihs 4766 * pkt to the doneq since the hba will retry 4767 * this cmd. 4768 * 4769 * The pkt has already been resubmitted in 4770 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error(). 4771 * Remove this cmd_flag here. 4772 */ 4773 cmd->cmd_flags &= ~CFLAG_RETRY; 4774 } else { 4775 mptsas_doneq_add(mpt, cmd); 4776 } 4777 } 4778 4779 static void 4780 mptsas_handle_address_reply(mptsas_t *mpt, 4781 pMpi2ReplyDescriptorsUnion_t reply_desc) 4782 { 4783 pMpi2AddressReplyDescriptor_t address_reply; 4784 pMPI2DefaultReply_t reply; 4785 mptsas_fw_diagnostic_buffer_t *pBuffer; 4786 uint32_t reply_addr; 4787 uint16_t SMID, iocstatus; 4788 mptsas_slots_t *slots = mpt->m_active; 4789 mptsas_cmd_t *cmd = NULL; 4790 uint8_t function, buffer_type; 4791 m_replyh_arg_t *args; 4792 int reply_frame_no; 4793 4794 ASSERT(mutex_owned(&mpt->m_mutex)); 4795 4796 address_reply = (pMpi2AddressReplyDescriptor_t)reply_desc; 4797 reply_addr = ddi_get32(mpt->m_acc_post_queue_hdl, 4798 &address_reply->ReplyFrameAddress); 4799 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &address_reply->SMID); 4800 4801 /* 4802 * If reply frame is not in the proper range we should ignore this 4803 * message and exit the interrupt handler. 4804 */ 4805 if ((reply_addr < mpt->m_reply_frame_dma_addr) || 4806 (reply_addr >= (mpt->m_reply_frame_dma_addr + 4807 (mpt->m_reply_frame_size * mpt->m_max_replies))) || 4808 ((reply_addr - mpt->m_reply_frame_dma_addr) % 4809 mpt->m_reply_frame_size != 0)) { 4810 mptsas_log(mpt, CE_WARN, "?Received invalid reply frame " 4811 "address 0x%x\n", reply_addr); 4812 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 4813 return; 4814 } 4815 4816 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 4817 DDI_DMA_SYNC_FORCPU); 4818 reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame + (reply_addr - 4819 mpt->m_reply_frame_dma_addr)); 4820 function = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Function); 4821 4822 /* 4823 * don't get slot information and command for events since these values 4824 * don't exist 4825 */ 4826 if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) && 4827 (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) { 4828 /* 4829 * This could be a TM reply, which use the last allocated SMID, 4830 * so allow for that. 4831 */ 4832 if ((SMID == 0) || (SMID > (slots->m_n_normal + 1))) { 4833 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of " 4834 "%d\n", SMID); 4835 ddi_fm_service_impact(mpt->m_dip, 4836 DDI_SERVICE_UNAFFECTED); 4837 return; 4838 } 4839 4840 cmd = slots->m_slot[SMID]; 4841 4842 /* 4843 * print warning and return if the slot is empty 4844 */ 4845 if (cmd == NULL) { 4846 mptsas_log(mpt, CE_WARN, "?NULL command for address " 4847 "reply in slot %d", SMID); 4848 return; 4849 } 4850 if ((cmd->cmd_flags & 4851 (CFLAG_PASSTHRU | CFLAG_CONFIG | CFLAG_FW_DIAG))) { 4852 cmd->cmd_rfm = reply_addr; 4853 cmd->cmd_flags |= CFLAG_FINISHED; 4854 cv_broadcast(&mpt->m_passthru_cv); 4855 cv_broadcast(&mpt->m_config_cv); 4856 cv_broadcast(&mpt->m_fw_diag_cv); 4857 return; 4858 } else if (!(cmd->cmd_flags & CFLAG_FW_CMD)) { 4859 mptsas_remove_cmd(mpt, cmd); 4860 } 4861 NDBG31(("\t\tmptsas_process_intr: slot=%d", SMID)); 4862 } 4863 /* 4864 * Depending on the function, we need to handle 4865 * the reply frame (and cmd) differently. 4866 */ 4867 switch (function) { 4868 case MPI2_FUNCTION_SCSI_IO_REQUEST: 4869 mptsas_check_scsi_io_error(mpt, (pMpi2SCSIIOReply_t)reply, cmd); 4870 break; 4871 case MPI2_FUNCTION_SCSI_TASK_MGMT: 4872 cmd->cmd_rfm = reply_addr; 4873 mptsas_check_task_mgt(mpt, (pMpi2SCSIManagementReply_t)reply, 4874 cmd); 4875 break; 4876 case MPI2_FUNCTION_FW_DOWNLOAD: 4877 cmd->cmd_flags |= CFLAG_FINISHED; 4878 cv_signal(&mpt->m_fw_cv); 4879 break; 4880 case MPI2_FUNCTION_EVENT_NOTIFICATION: 4881 reply_frame_no = (reply_addr - mpt->m_reply_frame_dma_addr) / 4882 mpt->m_reply_frame_size; 4883 args = &mpt->m_replyh_args[reply_frame_no]; 4884 args->mpt = (void *)mpt; 4885 args->rfm = reply_addr; 4886 4887 /* 4888 * Record the event if its type is enabled in 4889 * this mpt instance by ioctl. 4890 */ 4891 mptsas_record_event(args); 4892 4893 /* 4894 * Handle time critical events 4895 * NOT_RESPONDING/ADDED only now 4896 */ 4897 if (mptsas_handle_event_sync(args) == DDI_SUCCESS) { 4898 /* 4899 * Would not return main process, 4900 * just let taskq resolve ack action 4901 * and ack would be sent in taskq thread 4902 */ 4903 NDBG20(("send mptsas_handle_event_sync success")); 4904 } 4905 4906 if (mpt->m_in_reset) { 4907 NDBG20(("dropping event received during reset")); 4908 return; 4909 } 4910 4911 if ((ddi_taskq_dispatch(mpt->m_event_taskq, mptsas_handle_event, 4912 (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) { 4913 mptsas_log(mpt, CE_WARN, "No memory available" 4914 "for dispatch taskq"); 4915 /* 4916 * Return the reply frame to the free queue. 4917 */ 4918 ddi_put32(mpt->m_acc_free_queue_hdl, 4919 &((uint32_t *)(void *) 4920 mpt->m_free_queue)[mpt->m_free_index], reply_addr); 4921 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 4922 DDI_DMA_SYNC_FORDEV); 4923 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 4924 mpt->m_free_index = 0; 4925 } 4926 4927 ddi_put32(mpt->m_datap, 4928 &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index); 4929 } 4930 return; 4931 case MPI2_FUNCTION_DIAG_BUFFER_POST: 4932 /* 4933 * If SMID is 0, this implies that the reply is due to a 4934 * release function with a status that the buffer has been 4935 * released. Set the buffer flags accordingly. 4936 */ 4937 if (SMID == 0) { 4938 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 4939 &reply->IOCStatus); 4940 buffer_type = ddi_get8(mpt->m_acc_reply_frame_hdl, 4941 &(((pMpi2DiagBufferPostReply_t)reply)->BufferType)); 4942 if (iocstatus == MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED) { 4943 pBuffer = 4944 &mpt->m_fw_diag_buffer_list[buffer_type]; 4945 pBuffer->valid_data = TRUE; 4946 pBuffer->owned_by_firmware = FALSE; 4947 pBuffer->immediate = FALSE; 4948 } 4949 } else { 4950 /* 4951 * Normal handling of diag post reply with SMID. 4952 */ 4953 cmd = slots->m_slot[SMID]; 4954 4955 /* 4956 * print warning and return if the slot is empty 4957 */ 4958 if (cmd == NULL) { 4959 mptsas_log(mpt, CE_WARN, "?NULL command for " 4960 "address reply in slot %d", SMID); 4961 return; 4962 } 4963 cmd->cmd_rfm = reply_addr; 4964 cmd->cmd_flags |= CFLAG_FINISHED; 4965 cv_broadcast(&mpt->m_fw_diag_cv); 4966 } 4967 return; 4968 default: 4969 mptsas_log(mpt, CE_WARN, "Unknown function 0x%x ", function); 4970 break; 4971 } 4972 4973 /* 4974 * Return the reply frame to the free queue. 4975 */ 4976 ddi_put32(mpt->m_acc_free_queue_hdl, 4977 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 4978 reply_addr); 4979 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 4980 DDI_DMA_SYNC_FORDEV); 4981 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 4982 mpt->m_free_index = 0; 4983 } 4984 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 4985 mpt->m_free_index); 4986 4987 if (cmd->cmd_flags & CFLAG_FW_CMD) 4988 return; 4989 4990 if (cmd->cmd_flags & CFLAG_RETRY) { 4991 /* 4992 * The target returned QFULL or busy, do not add tihs 4993 * pkt to the doneq since the hba will retry 4994 * this cmd. 4995 * 4996 * The pkt has already been resubmitted in 4997 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error(). 4998 * Remove this cmd_flag here. 4999 */ 5000 cmd->cmd_flags &= ~CFLAG_RETRY; 5001 } else { 5002 mptsas_doneq_add(mpt, cmd); 5003 } 5004 } 5005 5006 static void 5007 mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, 5008 mptsas_cmd_t *cmd) 5009 { 5010 uint8_t scsi_status, scsi_state; 5011 uint16_t ioc_status; 5012 uint32_t xferred, sensecount, responsedata, loginfo = 0; 5013 struct scsi_pkt *pkt; 5014 struct scsi_arq_status *arqstat; 5015 struct buf *bp; 5016 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 5017 uint8_t *sensedata = NULL; 5018 uint64_t sas_wwn; 5019 uint8_t phy; 5020 char wwn_str[MPTSAS_WWN_STRLEN]; 5021 5022 if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) == 5023 (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) { 5024 bp = cmd->cmd_ext_arq_buf; 5025 } else { 5026 bp = cmd->cmd_arq_buf; 5027 } 5028 5029 scsi_status = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIStatus); 5030 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus); 5031 scsi_state = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIState); 5032 xferred = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->TransferCount); 5033 sensecount = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->SenseCount); 5034 responsedata = ddi_get32(mpt->m_acc_reply_frame_hdl, 5035 &reply->ResponseInfo); 5036 5037 if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 5038 sas_wwn = ptgt->m_addr.mta_wwn; 5039 phy = ptgt->m_phynum; 5040 if (sas_wwn == 0) { 5041 (void) sprintf(wwn_str, "p%x", phy); 5042 } else { 5043 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 5044 } 5045 loginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 5046 &reply->IOCLogInfo); 5047 mptsas_log(mpt, CE_NOTE, 5048 "?Log info 0x%x received for target %d %s.\n" 5049 "\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x", 5050 loginfo, Tgt(cmd), wwn_str, scsi_status, ioc_status, 5051 scsi_state); 5052 } 5053 5054 NDBG31(("\t\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x", 5055 scsi_status, ioc_status, scsi_state)); 5056 5057 pkt = CMD2PKT(cmd); 5058 *(pkt->pkt_scbp) = scsi_status; 5059 5060 if (loginfo == 0x31170000) { 5061 /* 5062 * if loginfo PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY 5063 * 0x31170000 comes, that means the device missing delay 5064 * is in progressing, the command need retry later. 5065 */ 5066 *(pkt->pkt_scbp) = STATUS_BUSY; 5067 return; 5068 } 5069 5070 if ((scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS) && 5071 ((ioc_status & MPI2_IOCSTATUS_MASK) == 5072 MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE)) { 5073 pkt->pkt_reason = CMD_INCOMPLETE; 5074 pkt->pkt_state |= STATE_GOT_BUS; 5075 if (ptgt->m_reset_delay == 0) { 5076 mptsas_set_throttle(mpt, ptgt, 5077 DRAIN_THROTTLE); 5078 } 5079 return; 5080 } 5081 5082 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) { 5083 responsedata &= 0x000000FF; 5084 if (responsedata & MPTSAS_SCSI_RESPONSE_CODE_TLR_OFF) { 5085 mptsas_log(mpt, CE_NOTE, "Do not support the TLR\n"); 5086 pkt->pkt_reason = CMD_TLR_OFF; 5087 return; 5088 } 5089 } 5090 5091 5092 switch (scsi_status) { 5093 case MPI2_SCSI_STATUS_CHECK_CONDITION: 5094 pkt->pkt_resid = (cmd->cmd_dmacount - xferred); 5095 arqstat = (void*)(pkt->pkt_scbp); 5096 arqstat->sts_rqpkt_status = *((struct scsi_status *) 5097 (pkt->pkt_scbp)); 5098 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 5099 STATE_SENT_CMD | STATE_GOT_STATUS | STATE_ARQ_DONE); 5100 if (cmd->cmd_flags & CFLAG_XARQ) { 5101 pkt->pkt_state |= STATE_XARQ_DONE; 5102 } 5103 if (pkt->pkt_resid != cmd->cmd_dmacount) { 5104 pkt->pkt_state |= STATE_XFERRED_DATA; 5105 } 5106 arqstat->sts_rqpkt_reason = pkt->pkt_reason; 5107 arqstat->sts_rqpkt_state = pkt->pkt_state; 5108 arqstat->sts_rqpkt_state |= STATE_XFERRED_DATA; 5109 arqstat->sts_rqpkt_statistics = pkt->pkt_statistics; 5110 sensedata = (uint8_t *)&arqstat->sts_sensedata; 5111 5112 bcopy((uchar_t *)bp->b_un.b_addr, sensedata, 5113 ((cmd->cmd_rqslen >= sensecount) ? sensecount : 5114 cmd->cmd_rqslen)); 5115 arqstat->sts_rqpkt_resid = (cmd->cmd_rqslen - sensecount); 5116 cmd->cmd_flags |= CFLAG_CMDARQ; 5117 /* 5118 * Set proper status for pkt if autosense was valid 5119 */ 5120 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) { 5121 struct scsi_status zero_status = { 0 }; 5122 arqstat->sts_rqpkt_status = zero_status; 5123 } 5124 5125 /* 5126 * ASC=0x47 is parity error 5127 * ASC=0x48 is initiator detected error received 5128 */ 5129 if ((scsi_sense_key(sensedata) == KEY_ABORTED_COMMAND) && 5130 ((scsi_sense_asc(sensedata) == 0x47) || 5131 (scsi_sense_asc(sensedata) == 0x48))) { 5132 mptsas_log(mpt, CE_NOTE, "Aborted_command!"); 5133 } 5134 5135 /* 5136 * ASC/ASCQ=0x3F/0x0E means report_luns data changed 5137 * ASC/ASCQ=0x25/0x00 means invalid lun 5138 */ 5139 if (((scsi_sense_key(sensedata) == KEY_UNIT_ATTENTION) && 5140 (scsi_sense_asc(sensedata) == 0x3F) && 5141 (scsi_sense_ascq(sensedata) == 0x0E)) || 5142 ((scsi_sense_key(sensedata) == KEY_ILLEGAL_REQUEST) && 5143 (scsi_sense_asc(sensedata) == 0x25) && 5144 (scsi_sense_ascq(sensedata) == 0x00))) { 5145 mptsas_topo_change_list_t *topo_node = NULL; 5146 5147 topo_node = kmem_zalloc( 5148 sizeof (mptsas_topo_change_list_t), 5149 KM_NOSLEEP); 5150 if (topo_node == NULL) { 5151 mptsas_log(mpt, CE_NOTE, "No memory" 5152 "resource for handle SAS dynamic" 5153 "reconfigure.\n"); 5154 break; 5155 } 5156 topo_node->mpt = mpt; 5157 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET; 5158 topo_node->un.phymask = ptgt->m_addr.mta_phymask; 5159 topo_node->devhdl = ptgt->m_devhdl; 5160 topo_node->object = (void *)ptgt; 5161 topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED; 5162 5163 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 5164 mptsas_handle_dr, 5165 (void *)topo_node, 5166 DDI_NOSLEEP)) != DDI_SUCCESS) { 5167 mptsas_log(mpt, CE_NOTE, "mptsas start taskq" 5168 "for handle SAS dynamic reconfigure" 5169 "failed. \n"); 5170 } 5171 } 5172 break; 5173 case MPI2_SCSI_STATUS_GOOD: 5174 switch (ioc_status & MPI2_IOCSTATUS_MASK) { 5175 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 5176 pkt->pkt_reason = CMD_DEV_GONE; 5177 pkt->pkt_state |= STATE_GOT_BUS; 5178 if (ptgt->m_reset_delay == 0) { 5179 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5180 } 5181 NDBG31(("lost disk for target%d, command:%x", 5182 Tgt(cmd), pkt->pkt_cdbp[0])); 5183 break; 5184 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN: 5185 NDBG31(("data overrun: xferred=%d", xferred)); 5186 NDBG31(("dmacount=%d", cmd->cmd_dmacount)); 5187 pkt->pkt_reason = CMD_DATA_OVR; 5188 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET 5189 | STATE_SENT_CMD | STATE_GOT_STATUS 5190 | STATE_XFERRED_DATA); 5191 pkt->pkt_resid = 0; 5192 break; 5193 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: 5194 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN: 5195 NDBG31(("data underrun: xferred=%d", xferred)); 5196 NDBG31(("dmacount=%d", cmd->cmd_dmacount)); 5197 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET 5198 | STATE_SENT_CMD | STATE_GOT_STATUS); 5199 pkt->pkt_resid = (cmd->cmd_dmacount - xferred); 5200 if (pkt->pkt_resid != cmd->cmd_dmacount) { 5201 pkt->pkt_state |= STATE_XFERRED_DATA; 5202 } 5203 break; 5204 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: 5205 if (cmd->cmd_active_expiration <= gethrtime()) { 5206 /* 5207 * When timeout requested, propagate 5208 * proper reason and statistics to 5209 * target drivers. 5210 */ 5211 mptsas_set_pkt_reason(mpt, cmd, CMD_TIMEOUT, 5212 STAT_BUS_RESET | STAT_TIMEOUT); 5213 } else { 5214 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, 5215 STAT_BUS_RESET); 5216 } 5217 break; 5218 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: 5219 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: 5220 mptsas_set_pkt_reason(mpt, 5221 cmd, CMD_RESET, STAT_DEV_RESET); 5222 break; 5223 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR: 5224 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR: 5225 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET); 5226 mptsas_set_pkt_reason(mpt, 5227 cmd, CMD_TERMINATED, STAT_TERMINATED); 5228 break; 5229 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: 5230 case MPI2_IOCSTATUS_BUSY: 5231 /* 5232 * set throttles to drain 5233 */ 5234 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 5235 ptgt = refhash_next(mpt->m_targets, ptgt)) { 5236 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5237 } 5238 5239 /* 5240 * retry command 5241 */ 5242 cmd->cmd_flags |= CFLAG_RETRY; 5243 cmd->cmd_pkt_flags |= FLAG_HEAD; 5244 5245 (void) mptsas_accept_pkt(mpt, cmd); 5246 break; 5247 default: 5248 mptsas_log(mpt, CE_WARN, 5249 "unknown ioc_status = %x\n", ioc_status); 5250 mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer " 5251 "count = %x, scsi_status = %x", scsi_state, 5252 xferred, scsi_status); 5253 break; 5254 } 5255 break; 5256 case MPI2_SCSI_STATUS_TASK_SET_FULL: 5257 mptsas_handle_qfull(mpt, cmd); 5258 break; 5259 case MPI2_SCSI_STATUS_BUSY: 5260 NDBG31(("scsi_status busy received")); 5261 break; 5262 case MPI2_SCSI_STATUS_RESERVATION_CONFLICT: 5263 NDBG31(("scsi_status reservation conflict received")); 5264 break; 5265 default: 5266 mptsas_log(mpt, CE_WARN, "scsi_status=%x, ioc_status=%x\n", 5267 scsi_status, ioc_status); 5268 mptsas_log(mpt, CE_WARN, 5269 "mptsas_process_intr: invalid scsi status\n"); 5270 break; 5271 } 5272 } 5273 5274 static void 5275 mptsas_check_task_mgt(mptsas_t *mpt, pMpi2SCSIManagementReply_t reply, 5276 mptsas_cmd_t *cmd) 5277 { 5278 uint8_t task_type; 5279 uint16_t ioc_status; 5280 uint32_t log_info; 5281 uint16_t dev_handle; 5282 struct scsi_pkt *pkt = CMD2PKT(cmd); 5283 5284 task_type = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->TaskType); 5285 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus); 5286 log_info = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo); 5287 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->DevHandle); 5288 5289 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 5290 mptsas_log(mpt, CE_WARN, "mptsas_check_task_mgt: Task 0x%x " 5291 "failed. IOCStatus=0x%x IOCLogInfo=0x%x target=%d\n", 5292 task_type, ioc_status, log_info, dev_handle); 5293 pkt->pkt_reason = CMD_INCOMPLETE; 5294 return; 5295 } 5296 5297 switch (task_type) { 5298 case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK: 5299 case MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET: 5300 case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK: 5301 case MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA: 5302 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET: 5303 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION: 5304 break; 5305 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 5306 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 5307 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 5308 /* 5309 * Check for invalid DevHandle of 0 in case application 5310 * sends bad command. DevHandle of 0 could cause problems. 5311 */ 5312 if (dev_handle == 0) { 5313 mptsas_log(mpt, CE_WARN, "!Can't flush target with" 5314 " DevHandle of 0."); 5315 } else { 5316 mptsas_flush_target(mpt, dev_handle, Lun(cmd), 5317 task_type); 5318 } 5319 break; 5320 default: 5321 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.", 5322 task_type); 5323 mptsas_log(mpt, CE_WARN, "ioc status = %x", ioc_status); 5324 break; 5325 } 5326 } 5327 5328 static void 5329 mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg) 5330 { 5331 mptsas_t *mpt = arg->mpt; 5332 uint64_t t = arg->t; 5333 mptsas_cmd_t *cmd; 5334 struct scsi_pkt *pkt; 5335 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 5336 5337 mutex_enter(&item->mutex); 5338 while (item->flag & MPTSAS_DONEQ_THREAD_ACTIVE) { 5339 if (!item->doneq) { 5340 cv_wait(&item->cv, &item->mutex); 5341 } 5342 pkt = NULL; 5343 if ((cmd = mptsas_doneq_thread_rm(mpt, t)) != NULL) { 5344 cmd->cmd_flags |= CFLAG_COMPLETED; 5345 pkt = CMD2PKT(cmd); 5346 } 5347 mutex_exit(&item->mutex); 5348 if (pkt) { 5349 mptsas_pkt_comp(pkt, cmd); 5350 } 5351 mutex_enter(&item->mutex); 5352 } 5353 mutex_exit(&item->mutex); 5354 mutex_enter(&mpt->m_doneq_mutex); 5355 mpt->m_doneq_thread_n--; 5356 cv_broadcast(&mpt->m_doneq_thread_cv); 5357 mutex_exit(&mpt->m_doneq_mutex); 5358 } 5359 5360 5361 /* 5362 * mpt interrupt handler. 5363 */ 5364 static uint_t 5365 mptsas_intr(caddr_t arg1, caddr_t arg2) 5366 { 5367 mptsas_t *mpt = (void *)arg1; 5368 pMpi2ReplyDescriptorsUnion_t reply_desc_union; 5369 uchar_t did_reply = FALSE; 5370 5371 NDBG1(("mptsas_intr: arg1 0x%p arg2 0x%p", (void *)arg1, (void *)arg2)); 5372 5373 mutex_enter(&mpt->m_mutex); 5374 5375 /* 5376 * If interrupts are shared by two channels then check whether this 5377 * interrupt is genuinely for this channel by making sure first the 5378 * chip is in high power state. 5379 */ 5380 if ((mpt->m_options & MPTSAS_OPT_PM) && 5381 (mpt->m_power_level != PM_LEVEL_D0)) { 5382 mutex_exit(&mpt->m_mutex); 5383 return (DDI_INTR_UNCLAIMED); 5384 } 5385 5386 /* 5387 * If polling, interrupt was triggered by some shared interrupt because 5388 * IOC interrupts are disabled during polling, so polling routine will 5389 * handle any replies. Considering this, if polling is happening, 5390 * return with interrupt unclaimed. 5391 */ 5392 if (mpt->m_polled_intr) { 5393 mutex_exit(&mpt->m_mutex); 5394 mptsas_log(mpt, CE_WARN, "mpt_sas: Unclaimed interrupt"); 5395 return (DDI_INTR_UNCLAIMED); 5396 } 5397 5398 /* 5399 * Read the istat register. 5400 */ 5401 if ((INTPENDING(mpt)) != 0) { 5402 /* 5403 * read fifo until empty. 5404 */ 5405 #ifndef __lock_lint 5406 _NOTE(CONSTCOND) 5407 #endif 5408 while (TRUE) { 5409 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 5410 DDI_DMA_SYNC_FORCPU); 5411 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t) 5412 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index); 5413 5414 if (ddi_get32(mpt->m_acc_post_queue_hdl, 5415 &reply_desc_union->Words.Low) == 0xFFFFFFFF || 5416 ddi_get32(mpt->m_acc_post_queue_hdl, 5417 &reply_desc_union->Words.High) == 0xFFFFFFFF) { 5418 break; 5419 } 5420 5421 /* 5422 * The reply is valid, process it according to its 5423 * type. Also, set a flag for updating the reply index 5424 * after they've all been processed. 5425 */ 5426 did_reply = TRUE; 5427 5428 mptsas_process_intr(mpt, reply_desc_union); 5429 5430 /* 5431 * Increment post index and roll over if needed. 5432 */ 5433 if (++mpt->m_post_index == mpt->m_post_queue_depth) { 5434 mpt->m_post_index = 0; 5435 } 5436 } 5437 5438 /* 5439 * Update the global reply index if at least one reply was 5440 * processed. 5441 */ 5442 if (did_reply) { 5443 ddi_put32(mpt->m_datap, 5444 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); 5445 } 5446 } else { 5447 mutex_exit(&mpt->m_mutex); 5448 return (DDI_INTR_UNCLAIMED); 5449 } 5450 NDBG1(("mptsas_intr complete")); 5451 5452 /* 5453 * If no helper threads are created, process the doneq in ISR. If 5454 * helpers are created, use the doneq length as a metric to measure the 5455 * load on the interrupt CPU. If it is long enough, which indicates the 5456 * load is heavy, then we deliver the IO completions to the helpers. 5457 * This measurement has some limitations, although it is simple and 5458 * straightforward and works well for most of the cases at present. 5459 */ 5460 if (!mpt->m_doneq_thread_n || 5461 (mpt->m_doneq_len <= mpt->m_doneq_length_threshold)) { 5462 mptsas_doneq_empty(mpt); 5463 } else { 5464 mptsas_deliver_doneq_thread(mpt); 5465 } 5466 5467 /* 5468 * If there are queued cmd, start them now. 5469 */ 5470 if (mpt->m_waitq != NULL) { 5471 mptsas_restart_waitq(mpt); 5472 } 5473 5474 mutex_exit(&mpt->m_mutex); 5475 return (DDI_INTR_CLAIMED); 5476 } 5477 5478 static void 5479 mptsas_process_intr(mptsas_t *mpt, 5480 pMpi2ReplyDescriptorsUnion_t reply_desc_union) 5481 { 5482 uint8_t reply_type; 5483 5484 ASSERT(mutex_owned(&mpt->m_mutex)); 5485 5486 /* 5487 * The reply is valid, process it according to its 5488 * type. Also, set a flag for updated the reply index 5489 * after they've all been processed. 5490 */ 5491 reply_type = ddi_get8(mpt->m_acc_post_queue_hdl, 5492 &reply_desc_union->Default.ReplyFlags); 5493 reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; 5494 if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) { 5495 mptsas_handle_scsi_io_success(mpt, reply_desc_union); 5496 } else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { 5497 mptsas_handle_address_reply(mpt, reply_desc_union); 5498 } else { 5499 mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type); 5500 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 5501 } 5502 5503 /* 5504 * Clear the reply descriptor for re-use and increment 5505 * index. 5506 */ 5507 ddi_put64(mpt->m_acc_post_queue_hdl, 5508 &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index], 5509 0xFFFFFFFFFFFFFFFF); 5510 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 5511 DDI_DMA_SYNC_FORDEV); 5512 } 5513 5514 /* 5515 * handle qfull condition 5516 */ 5517 static void 5518 mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd) 5519 { 5520 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 5521 5522 if ((++cmd->cmd_qfull_retries > ptgt->m_qfull_retries) || 5523 (ptgt->m_qfull_retries == 0)) { 5524 /* 5525 * We have exhausted the retries on QFULL, or, 5526 * the target driver has indicated that it 5527 * wants to handle QFULL itself by setting 5528 * qfull-retries capability to 0. In either case 5529 * we want the target driver's QFULL handling 5530 * to kick in. We do this by having pkt_reason 5531 * as CMD_CMPLT and pkt_scbp as STATUS_QFULL. 5532 */ 5533 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5534 } else { 5535 if (ptgt->m_reset_delay == 0) { 5536 ptgt->m_t_throttle = 5537 max((ptgt->m_t_ncmds - 2), 0); 5538 } 5539 5540 cmd->cmd_pkt_flags |= FLAG_HEAD; 5541 cmd->cmd_flags &= ~(CFLAG_TRANFLAG); 5542 cmd->cmd_flags |= CFLAG_RETRY; 5543 5544 (void) mptsas_accept_pkt(mpt, cmd); 5545 5546 /* 5547 * when target gives queue full status with no commands 5548 * outstanding (m_t_ncmds == 0), throttle is set to 0 5549 * (HOLD_THROTTLE), and the queue full handling start 5550 * (see psarc/1994/313); if there are commands outstanding, 5551 * throttle is set to (m_t_ncmds - 2) 5552 */ 5553 if (ptgt->m_t_throttle == HOLD_THROTTLE) { 5554 /* 5555 * By setting throttle to QFULL_THROTTLE, we 5556 * avoid submitting new commands and in 5557 * mptsas_restart_cmd find out slots which need 5558 * their throttles to be cleared. 5559 */ 5560 mptsas_set_throttle(mpt, ptgt, QFULL_THROTTLE); 5561 if (mpt->m_restart_cmd_timeid == 0) { 5562 mpt->m_restart_cmd_timeid = 5563 timeout(mptsas_restart_cmd, mpt, 5564 ptgt->m_qfull_retry_interval); 5565 } 5566 } 5567 } 5568 } 5569 5570 mptsas_phymask_t 5571 mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport) 5572 { 5573 mptsas_phymask_t phy_mask = 0; 5574 uint8_t i = 0; 5575 5576 NDBG20(("mptsas%d physport_to_phymask enter", mpt->m_instance)); 5577 5578 ASSERT(mutex_owned(&mpt->m_mutex)); 5579 5580 /* 5581 * If physport is 0xFF, this is a RAID volume. Use phymask of 0. 5582 */ 5583 if (physport == 0xFF) { 5584 return (0); 5585 } 5586 5587 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 5588 if (mpt->m_phy_info[i].attached_devhdl && 5589 (mpt->m_phy_info[i].phy_mask != 0) && 5590 (mpt->m_phy_info[i].port_num == physport)) { 5591 phy_mask = mpt->m_phy_info[i].phy_mask; 5592 break; 5593 } 5594 } 5595 NDBG20(("mptsas%d physport_to_phymask:physport :%x phymask :%x, ", 5596 mpt->m_instance, physport, phy_mask)); 5597 return (phy_mask); 5598 } 5599 5600 /* 5601 * mpt free device handle after device gone, by use of passthrough 5602 */ 5603 static int 5604 mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl) 5605 { 5606 Mpi2SasIoUnitControlRequest_t req; 5607 Mpi2SasIoUnitControlReply_t rep; 5608 int ret; 5609 5610 ASSERT(mutex_owned(&mpt->m_mutex)); 5611 5612 /* 5613 * Need to compose a SAS IO Unit Control request message 5614 * and call mptsas_do_passthru() function 5615 */ 5616 bzero(&req, sizeof (req)); 5617 bzero(&rep, sizeof (rep)); 5618 5619 req.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 5620 req.Operation = MPI2_SAS_OP_REMOVE_DEVICE; 5621 req.DevHandle = LE_16(devhdl); 5622 5623 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL, 5624 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL); 5625 if (ret != 0) { 5626 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit " 5627 "Control error %d", ret); 5628 return (DDI_FAILURE); 5629 } 5630 5631 /* do passthrough success, check the ioc status */ 5632 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 5633 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit " 5634 "Control IOCStatus %d", LE_16(rep.IOCStatus)); 5635 return (DDI_FAILURE); 5636 } 5637 5638 return (DDI_SUCCESS); 5639 } 5640 5641 static void 5642 mptsas_update_phymask(mptsas_t *mpt) 5643 { 5644 mptsas_phymask_t mask = 0, phy_mask; 5645 char *phy_mask_name; 5646 uint8_t current_port; 5647 int i, j; 5648 5649 NDBG20(("mptsas%d update phymask ", mpt->m_instance)); 5650 5651 ASSERT(mutex_owned(&mpt->m_mutex)); 5652 5653 (void) mptsas_get_sas_io_unit_page(mpt); 5654 5655 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 5656 5657 for (i = 0; i < mpt->m_num_phys; i++) { 5658 phy_mask = 0x00; 5659 5660 if (mpt->m_phy_info[i].attached_devhdl == 0) 5661 continue; 5662 5663 bzero(phy_mask_name, sizeof (phy_mask_name)); 5664 5665 current_port = mpt->m_phy_info[i].port_num; 5666 5667 if ((mask & (1 << i)) != 0) 5668 continue; 5669 5670 for (j = 0; j < mpt->m_num_phys; j++) { 5671 if (mpt->m_phy_info[j].attached_devhdl && 5672 (mpt->m_phy_info[j].port_num == current_port)) { 5673 phy_mask |= (1 << j); 5674 } 5675 } 5676 mask = mask | phy_mask; 5677 5678 for (j = 0; j < mpt->m_num_phys; j++) { 5679 if ((phy_mask >> j) & 0x01) { 5680 mpt->m_phy_info[j].phy_mask = phy_mask; 5681 } 5682 } 5683 5684 (void) sprintf(phy_mask_name, "%x", phy_mask); 5685 5686 mutex_exit(&mpt->m_mutex); 5687 /* 5688 * register a iport, if the port has already been existed 5689 * SCSA will do nothing and just return. 5690 */ 5691 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name); 5692 mutex_enter(&mpt->m_mutex); 5693 } 5694 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 5695 NDBG20(("mptsas%d update phymask return", mpt->m_instance)); 5696 } 5697 5698 /* 5699 * mptsas_handle_dr is a task handler for DR, the DR action includes: 5700 * 1. Directly attched Device Added/Removed. 5701 * 2. Expander Device Added/Removed. 5702 * 3. Indirectly Attached Device Added/Expander. 5703 * 4. LUNs of a existing device status change. 5704 * 5. RAID volume created/deleted. 5705 * 6. Member of RAID volume is released because of RAID deletion. 5706 * 7. Physical disks are removed because of RAID creation. 5707 */ 5708 static void 5709 mptsas_handle_dr(void *args) { 5710 mptsas_topo_change_list_t *topo_node = NULL; 5711 mptsas_topo_change_list_t *save_node = NULL; 5712 mptsas_t *mpt; 5713 dev_info_t *parent = NULL; 5714 mptsas_phymask_t phymask = 0; 5715 char *phy_mask_name; 5716 uint8_t flags = 0, physport = 0xff; 5717 uint8_t port_update = 0; 5718 uint_t event; 5719 5720 topo_node = (mptsas_topo_change_list_t *)args; 5721 5722 mpt = topo_node->mpt; 5723 event = topo_node->event; 5724 flags = topo_node->flags; 5725 5726 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 5727 5728 NDBG20(("mptsas%d handle_dr enter", mpt->m_instance)); 5729 5730 switch (event) { 5731 case MPTSAS_DR_EVENT_RECONFIG_TARGET: 5732 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 5733 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE) || 5734 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) { 5735 /* 5736 * Direct attached or expander attached device added 5737 * into system or a Phys Disk that is being unhidden. 5738 */ 5739 port_update = 1; 5740 } 5741 break; 5742 case MPTSAS_DR_EVENT_RECONFIG_SMP: 5743 /* 5744 * New expander added into system, it must be the head 5745 * of topo_change_list_t 5746 */ 5747 port_update = 1; 5748 break; 5749 default: 5750 port_update = 0; 5751 break; 5752 } 5753 /* 5754 * All cases port_update == 1 may cause initiator port form change 5755 */ 5756 mutex_enter(&mpt->m_mutex); 5757 if (mpt->m_port_chng && port_update) { 5758 /* 5759 * mpt->m_port_chng flag indicates some PHYs of initiator 5760 * port have changed to online. So when expander added or 5761 * directly attached device online event come, we force to 5762 * update port information by issueing SAS IO Unit Page and 5763 * update PHYMASKs. 5764 */ 5765 (void) mptsas_update_phymask(mpt); 5766 mpt->m_port_chng = 0; 5767 5768 } 5769 mutex_exit(&mpt->m_mutex); 5770 while (topo_node) { 5771 phymask = 0; 5772 if (parent == NULL) { 5773 physport = topo_node->un.physport; 5774 event = topo_node->event; 5775 flags = topo_node->flags; 5776 if (event & (MPTSAS_DR_EVENT_OFFLINE_TARGET | 5777 MPTSAS_DR_EVENT_OFFLINE_SMP)) { 5778 /* 5779 * For all offline events, phymask is known 5780 */ 5781 phymask = topo_node->un.phymask; 5782 goto find_parent; 5783 } 5784 if (event & MPTSAS_TOPO_FLAG_REMOVE_HANDLE) { 5785 goto handle_topo_change; 5786 } 5787 if (flags & MPTSAS_TOPO_FLAG_LUN_ASSOCIATED) { 5788 phymask = topo_node->un.phymask; 5789 goto find_parent; 5790 } 5791 5792 if ((flags == 5793 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) && 5794 (event == MPTSAS_DR_EVENT_RECONFIG_TARGET)) { 5795 /* 5796 * There is no any field in IR_CONFIG_CHANGE 5797 * event indicate physport/phynum, let's get 5798 * parent after SAS Device Page0 request. 5799 */ 5800 goto handle_topo_change; 5801 } 5802 5803 mutex_enter(&mpt->m_mutex); 5804 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 5805 /* 5806 * If the direct attached device added or a 5807 * phys disk is being unhidden, argument 5808 * physport actually is PHY#, so we have to get 5809 * phymask according PHY#. 5810 */ 5811 physport = mpt->m_phy_info[physport].port_num; 5812 } 5813 5814 /* 5815 * Translate physport to phymask so that we can search 5816 * parent dip. 5817 */ 5818 phymask = mptsas_physport_to_phymask(mpt, 5819 physport); 5820 mutex_exit(&mpt->m_mutex); 5821 5822 find_parent: 5823 bzero(phy_mask_name, MPTSAS_MAX_PHYS); 5824 /* 5825 * For RAID topology change node, write the iport name 5826 * as v0. 5827 */ 5828 if (flags & MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 5829 (void) sprintf(phy_mask_name, "v0"); 5830 } else { 5831 /* 5832 * phymask can bo 0 if the drive has been 5833 * pulled by the time an add event is 5834 * processed. If phymask is 0, just skip this 5835 * event and continue. 5836 */ 5837 if (phymask == 0) { 5838 mutex_enter(&mpt->m_mutex); 5839 save_node = topo_node; 5840 topo_node = topo_node->next; 5841 ASSERT(save_node); 5842 kmem_free(save_node, 5843 sizeof (mptsas_topo_change_list_t)); 5844 mutex_exit(&mpt->m_mutex); 5845 5846 parent = NULL; 5847 continue; 5848 } 5849 (void) sprintf(phy_mask_name, "%x", phymask); 5850 } 5851 parent = scsi_hba_iport_find(mpt->m_dip, 5852 phy_mask_name); 5853 if (parent == NULL) { 5854 mptsas_log(mpt, CE_WARN, "Failed to find an " 5855 "iport, should not happen!"); 5856 goto out; 5857 } 5858 5859 } 5860 ASSERT(parent); 5861 handle_topo_change: 5862 5863 mutex_enter(&mpt->m_mutex); 5864 /* 5865 * If HBA is being reset, don't perform operations depending 5866 * on the IOC. We must free the topo list, however. 5867 */ 5868 if (!mpt->m_in_reset) 5869 mptsas_handle_topo_change(topo_node, parent); 5870 else 5871 NDBG20(("skipping topo change received during reset")); 5872 save_node = topo_node; 5873 topo_node = topo_node->next; 5874 ASSERT(save_node); 5875 kmem_free(save_node, sizeof (mptsas_topo_change_list_t)); 5876 mutex_exit(&mpt->m_mutex); 5877 5878 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 5879 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) || 5880 (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) { 5881 /* 5882 * If direct attached device associated, make sure 5883 * reset the parent before start the next one. But 5884 * all devices associated with expander shares the 5885 * parent. Also, reset parent if this is for RAID. 5886 */ 5887 parent = NULL; 5888 } 5889 } 5890 out: 5891 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 5892 } 5893 5894 static void 5895 mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node, 5896 dev_info_t *parent) 5897 { 5898 mptsas_target_t *ptgt = NULL; 5899 mptsas_smp_t *psmp = NULL; 5900 mptsas_t *mpt = (void *)topo_node->mpt; 5901 uint16_t devhdl; 5902 uint16_t attached_devhdl; 5903 uint64_t sas_wwn = 0; 5904 int rval = 0; 5905 uint32_t page_address; 5906 uint8_t phy, flags; 5907 char *addr = NULL; 5908 dev_info_t *lundip; 5909 int circ = 0, circ1 = 0; 5910 char attached_wwnstr[MPTSAS_WWN_STRLEN]; 5911 5912 NDBG20(("mptsas%d handle_topo_change enter", mpt->m_instance)); 5913 5914 ASSERT(mutex_owned(&mpt->m_mutex)); 5915 5916 switch (topo_node->event) { 5917 case MPTSAS_DR_EVENT_RECONFIG_TARGET: 5918 { 5919 char *phy_mask_name; 5920 mptsas_phymask_t phymask = 0; 5921 5922 if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 5923 /* 5924 * Get latest RAID info. 5925 */ 5926 (void) mptsas_get_raid_info(mpt); 5927 ptgt = refhash_linear_search(mpt->m_targets, 5928 mptsas_target_eval_devhdl, &topo_node->devhdl); 5929 if (ptgt == NULL) 5930 break; 5931 } else { 5932 ptgt = (void *)topo_node->object; 5933 } 5934 5935 if (ptgt == NULL) { 5936 /* 5937 * If a Phys Disk was deleted, RAID info needs to be 5938 * updated to reflect the new topology. 5939 */ 5940 (void) mptsas_get_raid_info(mpt); 5941 5942 /* 5943 * Get sas device page 0 by DevHandle to make sure if 5944 * SSP/SATA end device exist. 5945 */ 5946 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 5947 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 5948 topo_node->devhdl; 5949 5950 rval = mptsas_get_target_device_info(mpt, page_address, 5951 &devhdl, &ptgt); 5952 if (rval == DEV_INFO_WRONG_DEVICE_TYPE) { 5953 mptsas_log(mpt, CE_NOTE, 5954 "mptsas_handle_topo_change: target %d is " 5955 "not a SAS/SATA device. \n", 5956 topo_node->devhdl); 5957 } else if (rval == DEV_INFO_FAIL_ALLOC) { 5958 mptsas_log(mpt, CE_NOTE, 5959 "mptsas_handle_topo_change: could not " 5960 "allocate memory. \n"); 5961 } 5962 /* 5963 * If rval is DEV_INFO_PHYS_DISK than there is nothing 5964 * else to do, just leave. 5965 */ 5966 if (rval != DEV_INFO_SUCCESS) { 5967 return; 5968 } 5969 } 5970 5971 ASSERT(ptgt->m_devhdl == topo_node->devhdl); 5972 5973 mutex_exit(&mpt->m_mutex); 5974 flags = topo_node->flags; 5975 5976 if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) { 5977 phymask = ptgt->m_addr.mta_phymask; 5978 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 5979 (void) sprintf(phy_mask_name, "%x", phymask); 5980 parent = scsi_hba_iport_find(mpt->m_dip, 5981 phy_mask_name); 5982 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 5983 if (parent == NULL) { 5984 mptsas_log(mpt, CE_WARN, "Failed to find a " 5985 "iport for PD, should not happen!"); 5986 mutex_enter(&mpt->m_mutex); 5987 break; 5988 } 5989 } 5990 5991 if (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 5992 ndi_devi_enter(parent, &circ1); 5993 (void) mptsas_config_raid(parent, topo_node->devhdl, 5994 &lundip); 5995 ndi_devi_exit(parent, circ1); 5996 } else { 5997 /* 5998 * hold nexus for bus configure 5999 */ 6000 ndi_devi_enter(scsi_vhci_dip, &circ); 6001 ndi_devi_enter(parent, &circ1); 6002 rval = mptsas_config_target(parent, ptgt); 6003 /* 6004 * release nexus for bus configure 6005 */ 6006 ndi_devi_exit(parent, circ1); 6007 ndi_devi_exit(scsi_vhci_dip, circ); 6008 6009 /* 6010 * Add parent's props for SMHBA support 6011 */ 6012 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 6013 bzero(attached_wwnstr, 6014 sizeof (attached_wwnstr)); 6015 (void) sprintf(attached_wwnstr, "w%016"PRIx64, 6016 ptgt->m_addr.mta_wwn); 6017 if (ddi_prop_update_string(DDI_DEV_T_NONE, 6018 parent, 6019 SCSI_ADDR_PROP_ATTACHED_PORT, 6020 attached_wwnstr) 6021 != DDI_PROP_SUCCESS) { 6022 (void) ddi_prop_remove(DDI_DEV_T_NONE, 6023 parent, 6024 SCSI_ADDR_PROP_ATTACHED_PORT); 6025 mptsas_log(mpt, CE_WARN, "Failed to" 6026 "attached-port props"); 6027 return; 6028 } 6029 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6030 MPTSAS_NUM_PHYS, 1) != 6031 DDI_PROP_SUCCESS) { 6032 (void) ddi_prop_remove(DDI_DEV_T_NONE, 6033 parent, MPTSAS_NUM_PHYS); 6034 mptsas_log(mpt, CE_WARN, "Failed to" 6035 " create num-phys props"); 6036 return; 6037 } 6038 6039 /* 6040 * Update PHY info for smhba 6041 */ 6042 mutex_enter(&mpt->m_mutex); 6043 if (mptsas_smhba_phy_init(mpt)) { 6044 mutex_exit(&mpt->m_mutex); 6045 mptsas_log(mpt, CE_WARN, "mptsas phy" 6046 " update failed"); 6047 return; 6048 } 6049 mutex_exit(&mpt->m_mutex); 6050 6051 /* 6052 * topo_node->un.physport is really the PHY# 6053 * for direct attached devices 6054 */ 6055 mptsas_smhba_set_one_phy_props(mpt, parent, 6056 topo_node->un.physport, &attached_devhdl); 6057 6058 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6059 MPTSAS_VIRTUAL_PORT, 0) != 6060 DDI_PROP_SUCCESS) { 6061 (void) ddi_prop_remove(DDI_DEV_T_NONE, 6062 parent, MPTSAS_VIRTUAL_PORT); 6063 mptsas_log(mpt, CE_WARN, 6064 "mptsas virtual-port" 6065 "port prop update failed"); 6066 return; 6067 } 6068 } 6069 } 6070 mutex_enter(&mpt->m_mutex); 6071 6072 NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, " 6073 "phymask:%x.", mpt->m_instance, ptgt->m_devhdl, 6074 ptgt->m_addr.mta_phymask)); 6075 break; 6076 } 6077 case MPTSAS_DR_EVENT_OFFLINE_TARGET: 6078 { 6079 devhdl = topo_node->devhdl; 6080 ptgt = refhash_linear_search(mpt->m_targets, 6081 mptsas_target_eval_devhdl, &devhdl); 6082 if (ptgt == NULL) 6083 break; 6084 6085 sas_wwn = ptgt->m_addr.mta_wwn; 6086 phy = ptgt->m_phynum; 6087 6088 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 6089 6090 if (sas_wwn) { 6091 (void) sprintf(addr, "w%016"PRIx64, sas_wwn); 6092 } else { 6093 (void) sprintf(addr, "p%x", phy); 6094 } 6095 ASSERT(ptgt->m_devhdl == devhdl); 6096 6097 if ((topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) || 6098 (topo_node->flags == 6099 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) { 6100 /* 6101 * Get latest RAID info if RAID volume status changes 6102 * or Phys Disk status changes 6103 */ 6104 (void) mptsas_get_raid_info(mpt); 6105 } 6106 /* 6107 * Abort all outstanding command on the device 6108 */ 6109 rval = mptsas_do_scsi_reset(mpt, devhdl); 6110 if (rval) { 6111 NDBG20(("mptsas%d handle_topo_change to reset target " 6112 "before offline devhdl:%x, phymask:%x, rval:%x", 6113 mpt->m_instance, ptgt->m_devhdl, 6114 ptgt->m_addr.mta_phymask, rval)); 6115 } 6116 6117 mutex_exit(&mpt->m_mutex); 6118 6119 ndi_devi_enter(scsi_vhci_dip, &circ); 6120 ndi_devi_enter(parent, &circ1); 6121 rval = mptsas_offline_target(parent, addr); 6122 ndi_devi_exit(parent, circ1); 6123 ndi_devi_exit(scsi_vhci_dip, circ); 6124 NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, " 6125 "phymask:%x, rval:%x", mpt->m_instance, 6126 ptgt->m_devhdl, ptgt->m_addr.mta_phymask, rval)); 6127 6128 kmem_free(addr, SCSI_MAXNAMELEN); 6129 6130 /* 6131 * Clear parent's props for SMHBA support 6132 */ 6133 flags = topo_node->flags; 6134 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 6135 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6136 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent, 6137 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 6138 DDI_PROP_SUCCESS) { 6139 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6140 SCSI_ADDR_PROP_ATTACHED_PORT); 6141 mptsas_log(mpt, CE_WARN, "mptsas attached port " 6142 "prop update failed"); 6143 break; 6144 } 6145 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6146 MPTSAS_NUM_PHYS, 0) != 6147 DDI_PROP_SUCCESS) { 6148 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6149 MPTSAS_NUM_PHYS); 6150 mptsas_log(mpt, CE_WARN, "mptsas num phys " 6151 "prop update failed"); 6152 break; 6153 } 6154 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6155 MPTSAS_VIRTUAL_PORT, 1) != 6156 DDI_PROP_SUCCESS) { 6157 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6158 MPTSAS_VIRTUAL_PORT); 6159 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 6160 "prop update failed"); 6161 break; 6162 } 6163 } 6164 6165 mutex_enter(&mpt->m_mutex); 6166 ptgt->m_led_status = 0; 6167 (void) mptsas_flush_led_status(mpt, ptgt); 6168 if (rval == DDI_SUCCESS) { 6169 refhash_remove(mpt->m_targets, ptgt); 6170 ptgt = NULL; 6171 } else { 6172 /* 6173 * clean DR_INTRANSITION flag to allow I/O down to 6174 * PHCI driver since failover finished. 6175 * Invalidate the devhdl 6176 */ 6177 ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL; 6178 ptgt->m_tgt_unconfigured = 0; 6179 mutex_enter(&mpt->m_tx_waitq_mutex); 6180 ptgt->m_dr_flag = MPTSAS_DR_INACTIVE; 6181 mutex_exit(&mpt->m_tx_waitq_mutex); 6182 } 6183 6184 /* 6185 * Send SAS IO Unit Control to free the dev handle 6186 */ 6187 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 6188 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE)) { 6189 rval = mptsas_free_devhdl(mpt, devhdl); 6190 6191 NDBG20(("mptsas%d handle_topo_change to remove " 6192 "devhdl:%x, rval:%x", mpt->m_instance, devhdl, 6193 rval)); 6194 } 6195 6196 break; 6197 } 6198 case MPTSAS_TOPO_FLAG_REMOVE_HANDLE: 6199 { 6200 devhdl = topo_node->devhdl; 6201 /* 6202 * If this is the remove handle event, do a reset first. 6203 */ 6204 if (topo_node->event == MPTSAS_TOPO_FLAG_REMOVE_HANDLE) { 6205 rval = mptsas_do_scsi_reset(mpt, devhdl); 6206 if (rval) { 6207 NDBG20(("mpt%d reset target before remove " 6208 "devhdl:%x, rval:%x", mpt->m_instance, 6209 devhdl, rval)); 6210 } 6211 } 6212 6213 /* 6214 * Send SAS IO Unit Control to free the dev handle 6215 */ 6216 rval = mptsas_free_devhdl(mpt, devhdl); 6217 NDBG20(("mptsas%d handle_topo_change to remove " 6218 "devhdl:%x, rval:%x", mpt->m_instance, devhdl, 6219 rval)); 6220 break; 6221 } 6222 case MPTSAS_DR_EVENT_RECONFIG_SMP: 6223 { 6224 mptsas_smp_t smp; 6225 dev_info_t *smpdip; 6226 6227 devhdl = topo_node->devhdl; 6228 6229 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL & 6230 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl; 6231 rval = mptsas_get_sas_expander_page0(mpt, page_address, &smp); 6232 if (rval != DDI_SUCCESS) { 6233 mptsas_log(mpt, CE_WARN, "failed to online smp, " 6234 "handle %x", devhdl); 6235 return; 6236 } 6237 6238 psmp = mptsas_smp_alloc(mpt, &smp); 6239 if (psmp == NULL) { 6240 return; 6241 } 6242 6243 mutex_exit(&mpt->m_mutex); 6244 ndi_devi_enter(parent, &circ1); 6245 (void) mptsas_online_smp(parent, psmp, &smpdip); 6246 ndi_devi_exit(parent, circ1); 6247 6248 mutex_enter(&mpt->m_mutex); 6249 break; 6250 } 6251 case MPTSAS_DR_EVENT_OFFLINE_SMP: 6252 { 6253 devhdl = topo_node->devhdl; 6254 uint32_t dev_info; 6255 6256 psmp = refhash_linear_search(mpt->m_smp_targets, 6257 mptsas_smp_eval_devhdl, &devhdl); 6258 if (psmp == NULL) 6259 break; 6260 /* 6261 * The mptsas_smp_t data is released only if the dip is offlined 6262 * successfully. 6263 */ 6264 mutex_exit(&mpt->m_mutex); 6265 6266 ndi_devi_enter(parent, &circ1); 6267 rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE); 6268 ndi_devi_exit(parent, circ1); 6269 6270 dev_info = psmp->m_deviceinfo; 6271 if ((dev_info & DEVINFO_DIRECT_ATTACHED) == 6272 DEVINFO_DIRECT_ATTACHED) { 6273 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6274 MPTSAS_VIRTUAL_PORT, 1) != 6275 DDI_PROP_SUCCESS) { 6276 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6277 MPTSAS_VIRTUAL_PORT); 6278 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 6279 "prop update failed"); 6280 return; 6281 } 6282 /* 6283 * Check whether the smp connected to the iport, 6284 */ 6285 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6286 MPTSAS_NUM_PHYS, 0) != 6287 DDI_PROP_SUCCESS) { 6288 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6289 MPTSAS_NUM_PHYS); 6290 mptsas_log(mpt, CE_WARN, "mptsas num phys" 6291 "prop update failed"); 6292 return; 6293 } 6294 /* 6295 * Clear parent's attached-port props 6296 */ 6297 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6298 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent, 6299 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 6300 DDI_PROP_SUCCESS) { 6301 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6302 SCSI_ADDR_PROP_ATTACHED_PORT); 6303 mptsas_log(mpt, CE_WARN, "mptsas attached port " 6304 "prop update failed"); 6305 return; 6306 } 6307 } 6308 6309 mutex_enter(&mpt->m_mutex); 6310 NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, " 6311 "rval:%x", mpt->m_instance, psmp->m_devhdl, rval)); 6312 if (rval == DDI_SUCCESS) { 6313 refhash_remove(mpt->m_smp_targets, psmp); 6314 } else { 6315 psmp->m_devhdl = MPTSAS_INVALID_DEVHDL; 6316 } 6317 6318 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6319 6320 break; 6321 } 6322 default: 6323 return; 6324 } 6325 } 6326 6327 /* 6328 * Record the event if its type is enabled in mpt instance by ioctl. 6329 */ 6330 static void 6331 mptsas_record_event(void *args) 6332 { 6333 m_replyh_arg_t *replyh_arg; 6334 pMpi2EventNotificationReply_t eventreply; 6335 uint32_t event, rfm; 6336 mptsas_t *mpt; 6337 int i, j; 6338 uint16_t event_data_len; 6339 boolean_t sendAEN = FALSE; 6340 6341 replyh_arg = (m_replyh_arg_t *)args; 6342 rfm = replyh_arg->rfm; 6343 mpt = replyh_arg->mpt; 6344 6345 eventreply = (pMpi2EventNotificationReply_t) 6346 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr)); 6347 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 6348 6349 6350 /* 6351 * Generate a system event to let anyone who cares know that a 6352 * LOG_ENTRY_ADDED event has occurred. This is sent no matter what the 6353 * event mask is set to. 6354 */ 6355 if (event == MPI2_EVENT_LOG_ENTRY_ADDED) { 6356 sendAEN = TRUE; 6357 } 6358 6359 /* 6360 * Record the event only if it is not masked. Determine which dword 6361 * and bit of event mask to test. 6362 */ 6363 i = (uint8_t)(event / 32); 6364 j = (uint8_t)(event % 32); 6365 if ((i < 4) && ((1 << j) & mpt->m_event_mask[i])) { 6366 i = mpt->m_event_index; 6367 mpt->m_events[i].Type = event; 6368 mpt->m_events[i].Number = ++mpt->m_event_number; 6369 bzero(mpt->m_events[i].Data, MPTSAS_MAX_EVENT_DATA_LENGTH * 4); 6370 event_data_len = ddi_get16(mpt->m_acc_reply_frame_hdl, 6371 &eventreply->EventDataLength); 6372 6373 if (event_data_len > 0) { 6374 /* 6375 * Limit data to size in m_event entry 6376 */ 6377 if (event_data_len > MPTSAS_MAX_EVENT_DATA_LENGTH) { 6378 event_data_len = MPTSAS_MAX_EVENT_DATA_LENGTH; 6379 } 6380 for (j = 0; j < event_data_len; j++) { 6381 mpt->m_events[i].Data[j] = 6382 ddi_get32(mpt->m_acc_reply_frame_hdl, 6383 &(eventreply->EventData[j])); 6384 } 6385 6386 /* 6387 * check for index wrap-around 6388 */ 6389 if (++i == MPTSAS_EVENT_QUEUE_SIZE) { 6390 i = 0; 6391 } 6392 mpt->m_event_index = (uint8_t)i; 6393 6394 /* 6395 * Set flag to send the event. 6396 */ 6397 sendAEN = TRUE; 6398 } 6399 } 6400 6401 /* 6402 * Generate a system event if flag is set to let anyone who cares know 6403 * that an event has occurred. 6404 */ 6405 if (sendAEN) { 6406 (void) ddi_log_sysevent(mpt->m_dip, DDI_VENDOR_LSI, "MPT_SAS", 6407 "SAS", NULL, NULL, DDI_NOSLEEP); 6408 } 6409 } 6410 6411 #define SMP_RESET_IN_PROGRESS MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS 6412 /* 6413 * handle sync events from ioc in interrupt 6414 * return value: 6415 * DDI_SUCCESS: The event is handled by this func 6416 * DDI_FAILURE: Event is not handled 6417 */ 6418 static int 6419 mptsas_handle_event_sync(void *args) 6420 { 6421 m_replyh_arg_t *replyh_arg; 6422 pMpi2EventNotificationReply_t eventreply; 6423 uint32_t event, rfm; 6424 mptsas_t *mpt; 6425 uint_t iocstatus; 6426 6427 replyh_arg = (m_replyh_arg_t *)args; 6428 rfm = replyh_arg->rfm; 6429 mpt = replyh_arg->mpt; 6430 6431 ASSERT(mutex_owned(&mpt->m_mutex)); 6432 6433 eventreply = (pMpi2EventNotificationReply_t) 6434 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr)); 6435 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 6436 6437 if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 6438 &eventreply->IOCStatus)) { 6439 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 6440 mptsas_log(mpt, CE_WARN, 6441 "!mptsas_handle_event_sync: IOCStatus=0x%x, " 6442 "IOCLogInfo=0x%x", iocstatus, 6443 ddi_get32(mpt->m_acc_reply_frame_hdl, 6444 &eventreply->IOCLogInfo)); 6445 } else { 6446 mptsas_log(mpt, CE_WARN, 6447 "mptsas_handle_event_sync: IOCStatus=0x%x, " 6448 "IOCLogInfo=0x%x", iocstatus, 6449 ddi_get32(mpt->m_acc_reply_frame_hdl, 6450 &eventreply->IOCLogInfo)); 6451 } 6452 } 6453 6454 /* 6455 * figure out what kind of event we got and handle accordingly 6456 */ 6457 switch (event) { 6458 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 6459 { 6460 pMpi2EventDataSasTopologyChangeList_t sas_topo_change_list; 6461 uint8_t num_entries, expstatus, phy; 6462 uint8_t phystatus, physport, state, i; 6463 uint8_t start_phy_num, link_rate; 6464 uint16_t dev_handle, reason_code; 6465 uint16_t enc_handle, expd_handle; 6466 char string[80], curr[80], prev[80]; 6467 mptsas_topo_change_list_t *topo_head = NULL; 6468 mptsas_topo_change_list_t *topo_tail = NULL; 6469 mptsas_topo_change_list_t *topo_node = NULL; 6470 mptsas_target_t *ptgt; 6471 mptsas_smp_t *psmp; 6472 uint8_t flags = 0, exp_flag; 6473 smhba_info_t *pSmhba = NULL; 6474 6475 NDBG20(("mptsas_handle_event_sync: SAS topology change")); 6476 6477 sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t) 6478 eventreply->EventData; 6479 6480 enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6481 &sas_topo_change_list->EnclosureHandle); 6482 expd_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6483 &sas_topo_change_list->ExpanderDevHandle); 6484 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl, 6485 &sas_topo_change_list->NumEntries); 6486 start_phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl, 6487 &sas_topo_change_list->StartPhyNum); 6488 expstatus = ddi_get8(mpt->m_acc_reply_frame_hdl, 6489 &sas_topo_change_list->ExpStatus); 6490 physport = ddi_get8(mpt->m_acc_reply_frame_hdl, 6491 &sas_topo_change_list->PhysicalPort); 6492 6493 string[0] = 0; 6494 if (expd_handle) { 6495 flags = MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED; 6496 switch (expstatus) { 6497 case MPI2_EVENT_SAS_TOPO_ES_ADDED: 6498 (void) sprintf(string, " added"); 6499 /* 6500 * New expander device added 6501 */ 6502 mpt->m_port_chng = 1; 6503 topo_node = kmem_zalloc( 6504 sizeof (mptsas_topo_change_list_t), 6505 KM_SLEEP); 6506 topo_node->mpt = mpt; 6507 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_SMP; 6508 topo_node->un.physport = physport; 6509 topo_node->devhdl = expd_handle; 6510 topo_node->flags = flags; 6511 topo_node->object = NULL; 6512 if (topo_head == NULL) { 6513 topo_head = topo_tail = topo_node; 6514 } else { 6515 topo_tail->next = topo_node; 6516 topo_tail = topo_node; 6517 } 6518 break; 6519 case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING: 6520 (void) sprintf(string, " not responding, " 6521 "removed"); 6522 psmp = refhash_linear_search(mpt->m_smp_targets, 6523 mptsas_smp_eval_devhdl, &expd_handle); 6524 if (psmp == NULL) 6525 break; 6526 6527 topo_node = kmem_zalloc( 6528 sizeof (mptsas_topo_change_list_t), 6529 KM_SLEEP); 6530 topo_node->mpt = mpt; 6531 topo_node->un.phymask = 6532 psmp->m_addr.mta_phymask; 6533 topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP; 6534 topo_node->devhdl = expd_handle; 6535 topo_node->flags = flags; 6536 topo_node->object = NULL; 6537 if (topo_head == NULL) { 6538 topo_head = topo_tail = topo_node; 6539 } else { 6540 topo_tail->next = topo_node; 6541 topo_tail = topo_node; 6542 } 6543 break; 6544 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING: 6545 break; 6546 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING: 6547 (void) sprintf(string, " not responding, " 6548 "delaying removal"); 6549 break; 6550 default: 6551 break; 6552 } 6553 } else { 6554 flags = MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE; 6555 } 6556 6557 NDBG20(("SAS TOPOLOGY CHANGE for enclosure %x expander %x%s\n", 6558 enc_handle, expd_handle, string)); 6559 for (i = 0; i < num_entries; i++) { 6560 phy = i + start_phy_num; 6561 phystatus = ddi_get8(mpt->m_acc_reply_frame_hdl, 6562 &sas_topo_change_list->PHY[i].PhyStatus); 6563 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6564 &sas_topo_change_list->PHY[i].AttachedDevHandle); 6565 reason_code = phystatus & MPI2_EVENT_SAS_TOPO_RC_MASK; 6566 /* 6567 * Filter out processing of Phy Vacant Status unless 6568 * the reason code is "Not Responding". Process all 6569 * other combinations of Phy Status and Reason Codes. 6570 */ 6571 if ((phystatus & 6572 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) && 6573 (reason_code != 6574 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) { 6575 continue; 6576 } 6577 curr[0] = 0; 6578 prev[0] = 0; 6579 string[0] = 0; 6580 switch (reason_code) { 6581 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 6582 { 6583 NDBG20(("mptsas%d phy %d physical_port %d " 6584 "dev_handle %d added", mpt->m_instance, phy, 6585 physport, dev_handle)); 6586 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl, 6587 &sas_topo_change_list->PHY[i].LinkRate); 6588 state = (link_rate & 6589 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >> 6590 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT; 6591 switch (state) { 6592 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 6593 (void) sprintf(curr, "is disabled"); 6594 break; 6595 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 6596 (void) sprintf(curr, "is offline, " 6597 "failed speed negotiation"); 6598 break; 6599 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 6600 (void) sprintf(curr, "SATA OOB " 6601 "complete"); 6602 break; 6603 case SMP_RESET_IN_PROGRESS: 6604 (void) sprintf(curr, "SMP reset in " 6605 "progress"); 6606 break; 6607 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 6608 (void) sprintf(curr, "is online at " 6609 "1.5 Gbps"); 6610 break; 6611 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 6612 (void) sprintf(curr, "is online at 3.0 " 6613 "Gbps"); 6614 break; 6615 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 6616 (void) sprintf(curr, "is online at 6.0 " 6617 "Gbps"); 6618 break; 6619 default: 6620 (void) sprintf(curr, "state is " 6621 "unknown"); 6622 break; 6623 } 6624 /* 6625 * New target device added into the system. 6626 * Set association flag according to if an 6627 * expander is used or not. 6628 */ 6629 exp_flag = 6630 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE; 6631 if (flags == 6632 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) { 6633 flags = exp_flag; 6634 } 6635 topo_node = kmem_zalloc( 6636 sizeof (mptsas_topo_change_list_t), 6637 KM_SLEEP); 6638 topo_node->mpt = mpt; 6639 topo_node->event = 6640 MPTSAS_DR_EVENT_RECONFIG_TARGET; 6641 if (expd_handle == 0) { 6642 /* 6643 * Per MPI 2, if expander dev handle 6644 * is 0, it's a directly attached 6645 * device. So driver use PHY to decide 6646 * which iport is associated 6647 */ 6648 physport = phy; 6649 mpt->m_port_chng = 1; 6650 } 6651 topo_node->un.physport = physport; 6652 topo_node->devhdl = dev_handle; 6653 topo_node->flags = flags; 6654 topo_node->object = NULL; 6655 if (topo_head == NULL) { 6656 topo_head = topo_tail = topo_node; 6657 } else { 6658 topo_tail->next = topo_node; 6659 topo_tail = topo_node; 6660 } 6661 break; 6662 } 6663 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 6664 { 6665 NDBG20(("mptsas%d phy %d physical_port %d " 6666 "dev_handle %d removed", mpt->m_instance, 6667 phy, physport, dev_handle)); 6668 /* 6669 * Set association flag according to if an 6670 * expander is used or not. 6671 */ 6672 exp_flag = 6673 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE; 6674 if (flags == 6675 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) { 6676 flags = exp_flag; 6677 } 6678 /* 6679 * Target device is removed from the system 6680 * Before the device is really offline from 6681 * from system. 6682 */ 6683 ptgt = refhash_linear_search(mpt->m_targets, 6684 mptsas_target_eval_devhdl, &dev_handle); 6685 /* 6686 * If ptgt is NULL here, it means that the 6687 * DevHandle is not in the hash table. This is 6688 * reasonable sometimes. For example, if a 6689 * disk was pulled, then added, then pulled 6690 * again, the disk will not have been put into 6691 * the hash table because the add event will 6692 * have an invalid phymask. BUT, this does not 6693 * mean that the DevHandle is invalid. The 6694 * controller will still have a valid DevHandle 6695 * that must be removed. To do this, use the 6696 * MPTSAS_TOPO_FLAG_REMOVE_HANDLE event. 6697 */ 6698 if (ptgt == NULL) { 6699 topo_node = kmem_zalloc( 6700 sizeof (mptsas_topo_change_list_t), 6701 KM_SLEEP); 6702 topo_node->mpt = mpt; 6703 topo_node->un.phymask = 0; 6704 topo_node->event = 6705 MPTSAS_TOPO_FLAG_REMOVE_HANDLE; 6706 topo_node->devhdl = dev_handle; 6707 topo_node->flags = flags; 6708 topo_node->object = NULL; 6709 if (topo_head == NULL) { 6710 topo_head = topo_tail = 6711 topo_node; 6712 } else { 6713 topo_tail->next = topo_node; 6714 topo_tail = topo_node; 6715 } 6716 break; 6717 } 6718 6719 /* 6720 * Update DR flag immediately avoid I/O failure 6721 * before failover finish. Pay attention to the 6722 * mutex protect, we need grab m_tx_waitq_mutex 6723 * during set m_dr_flag because we won't add 6724 * the following command into waitq, instead, 6725 * we need return TRAN_BUSY in the tran_start 6726 * context. 6727 */ 6728 mutex_enter(&mpt->m_tx_waitq_mutex); 6729 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 6730 mutex_exit(&mpt->m_tx_waitq_mutex); 6731 6732 topo_node = kmem_zalloc( 6733 sizeof (mptsas_topo_change_list_t), 6734 KM_SLEEP); 6735 topo_node->mpt = mpt; 6736 topo_node->un.phymask = 6737 ptgt->m_addr.mta_phymask; 6738 topo_node->event = 6739 MPTSAS_DR_EVENT_OFFLINE_TARGET; 6740 topo_node->devhdl = dev_handle; 6741 topo_node->flags = flags; 6742 topo_node->object = NULL; 6743 if (topo_head == NULL) { 6744 topo_head = topo_tail = topo_node; 6745 } else { 6746 topo_tail->next = topo_node; 6747 topo_tail = topo_node; 6748 } 6749 break; 6750 } 6751 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 6752 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl, 6753 &sas_topo_change_list->PHY[i].LinkRate); 6754 state = (link_rate & 6755 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >> 6756 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT; 6757 pSmhba = &mpt->m_phy_info[i].smhba_info; 6758 pSmhba->negotiated_link_rate = state; 6759 switch (state) { 6760 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 6761 (void) sprintf(curr, "is disabled"); 6762 mptsas_smhba_log_sysevent(mpt, 6763 ESC_SAS_PHY_EVENT, 6764 SAS_PHY_REMOVE, 6765 &mpt->m_phy_info[i].smhba_info); 6766 mpt->m_phy_info[i].smhba_info. 6767 negotiated_link_rate 6768 = 0x1; 6769 break; 6770 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 6771 (void) sprintf(curr, "is offline, " 6772 "failed speed negotiation"); 6773 mptsas_smhba_log_sysevent(mpt, 6774 ESC_SAS_PHY_EVENT, 6775 SAS_PHY_OFFLINE, 6776 &mpt->m_phy_info[i].smhba_info); 6777 break; 6778 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 6779 (void) sprintf(curr, "SATA OOB " 6780 "complete"); 6781 break; 6782 case SMP_RESET_IN_PROGRESS: 6783 (void) sprintf(curr, "SMP reset in " 6784 "progress"); 6785 break; 6786 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 6787 (void) sprintf(curr, "is online at " 6788 "1.5 Gbps"); 6789 if ((expd_handle == 0) && 6790 (enc_handle == 1)) { 6791 mpt->m_port_chng = 1; 6792 } 6793 mptsas_smhba_log_sysevent(mpt, 6794 ESC_SAS_PHY_EVENT, 6795 SAS_PHY_ONLINE, 6796 &mpt->m_phy_info[i].smhba_info); 6797 break; 6798 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 6799 (void) sprintf(curr, "is online at 3.0 " 6800 "Gbps"); 6801 if ((expd_handle == 0) && 6802 (enc_handle == 1)) { 6803 mpt->m_port_chng = 1; 6804 } 6805 mptsas_smhba_log_sysevent(mpt, 6806 ESC_SAS_PHY_EVENT, 6807 SAS_PHY_ONLINE, 6808 &mpt->m_phy_info[i].smhba_info); 6809 break; 6810 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 6811 (void) sprintf(curr, "is online at " 6812 "6.0 Gbps"); 6813 if ((expd_handle == 0) && 6814 (enc_handle == 1)) { 6815 mpt->m_port_chng = 1; 6816 } 6817 mptsas_smhba_log_sysevent(mpt, 6818 ESC_SAS_PHY_EVENT, 6819 SAS_PHY_ONLINE, 6820 &mpt->m_phy_info[i].smhba_info); 6821 break; 6822 default: 6823 (void) sprintf(curr, "state is " 6824 "unknown"); 6825 break; 6826 } 6827 6828 state = (link_rate & 6829 MPI2_EVENT_SAS_TOPO_LR_PREV_MASK) >> 6830 MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT; 6831 switch (state) { 6832 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 6833 (void) sprintf(prev, ", was disabled"); 6834 break; 6835 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 6836 (void) sprintf(prev, ", was offline, " 6837 "failed speed negotiation"); 6838 break; 6839 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 6840 (void) sprintf(prev, ", was SATA OOB " 6841 "complete"); 6842 break; 6843 case SMP_RESET_IN_PROGRESS: 6844 (void) sprintf(prev, ", was SMP reset " 6845 "in progress"); 6846 break; 6847 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 6848 (void) sprintf(prev, ", was online at " 6849 "1.5 Gbps"); 6850 break; 6851 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 6852 (void) sprintf(prev, ", was online at " 6853 "3.0 Gbps"); 6854 break; 6855 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 6856 (void) sprintf(prev, ", was online at " 6857 "6.0 Gbps"); 6858 break; 6859 default: 6860 break; 6861 } 6862 (void) sprintf(&string[strlen(string)], "link " 6863 "changed, "); 6864 break; 6865 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE: 6866 continue; 6867 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING: 6868 (void) sprintf(&string[strlen(string)], 6869 "target not responding, delaying " 6870 "removal"); 6871 break; 6872 } 6873 NDBG20(("mptsas%d phy %d DevHandle %x, %s%s%s\n", 6874 mpt->m_instance, phy, dev_handle, string, curr, 6875 prev)); 6876 } 6877 if (topo_head != NULL) { 6878 /* 6879 * Launch DR taskq to handle topology change 6880 */ 6881 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 6882 mptsas_handle_dr, (void *)topo_head, 6883 DDI_NOSLEEP)) != DDI_SUCCESS) { 6884 mptsas_log(mpt, CE_NOTE, "mptsas start taskq " 6885 "for handle SAS DR event failed. \n"); 6886 } 6887 } 6888 break; 6889 } 6890 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 6891 { 6892 Mpi2EventDataIrConfigChangeList_t *irChangeList; 6893 mptsas_topo_change_list_t *topo_head = NULL; 6894 mptsas_topo_change_list_t *topo_tail = NULL; 6895 mptsas_topo_change_list_t *topo_node = NULL; 6896 mptsas_target_t *ptgt; 6897 uint8_t num_entries, i, reason; 6898 uint16_t volhandle, diskhandle; 6899 6900 irChangeList = (pMpi2EventDataIrConfigChangeList_t) 6901 eventreply->EventData; 6902 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl, 6903 &irChangeList->NumElements); 6904 6905 NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received", 6906 mpt->m_instance)); 6907 6908 for (i = 0; i < num_entries; i++) { 6909 reason = ddi_get8(mpt->m_acc_reply_frame_hdl, 6910 &irChangeList->ConfigElement[i].ReasonCode); 6911 volhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6912 &irChangeList->ConfigElement[i].VolDevHandle); 6913 diskhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6914 &irChangeList->ConfigElement[i].PhysDiskDevHandle); 6915 6916 switch (reason) { 6917 case MPI2_EVENT_IR_CHANGE_RC_ADDED: 6918 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: 6919 { 6920 NDBG20(("mptsas %d volume added\n", 6921 mpt->m_instance)); 6922 6923 topo_node = kmem_zalloc( 6924 sizeof (mptsas_topo_change_list_t), 6925 KM_SLEEP); 6926 6927 topo_node->mpt = mpt; 6928 topo_node->event = 6929 MPTSAS_DR_EVENT_RECONFIG_TARGET; 6930 topo_node->un.physport = 0xff; 6931 topo_node->devhdl = volhandle; 6932 topo_node->flags = 6933 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED; 6934 topo_node->object = NULL; 6935 if (topo_head == NULL) { 6936 topo_head = topo_tail = topo_node; 6937 } else { 6938 topo_tail->next = topo_node; 6939 topo_tail = topo_node; 6940 } 6941 break; 6942 } 6943 case MPI2_EVENT_IR_CHANGE_RC_REMOVED: 6944 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: 6945 { 6946 NDBG20(("mptsas %d volume deleted\n", 6947 mpt->m_instance)); 6948 ptgt = refhash_linear_search(mpt->m_targets, 6949 mptsas_target_eval_devhdl, &volhandle); 6950 if (ptgt == NULL) 6951 break; 6952 6953 /* 6954 * Clear any flags related to volume 6955 */ 6956 (void) mptsas_delete_volume(mpt, volhandle); 6957 6958 /* 6959 * Update DR flag immediately avoid I/O failure 6960 */ 6961 mutex_enter(&mpt->m_tx_waitq_mutex); 6962 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 6963 mutex_exit(&mpt->m_tx_waitq_mutex); 6964 6965 topo_node = kmem_zalloc( 6966 sizeof (mptsas_topo_change_list_t), 6967 KM_SLEEP); 6968 topo_node->mpt = mpt; 6969 topo_node->un.phymask = 6970 ptgt->m_addr.mta_phymask; 6971 topo_node->event = 6972 MPTSAS_DR_EVENT_OFFLINE_TARGET; 6973 topo_node->devhdl = volhandle; 6974 topo_node->flags = 6975 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED; 6976 topo_node->object = (void *)ptgt; 6977 if (topo_head == NULL) { 6978 topo_head = topo_tail = topo_node; 6979 } else { 6980 topo_tail->next = topo_node; 6981 topo_tail = topo_node; 6982 } 6983 break; 6984 } 6985 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: 6986 case MPI2_EVENT_IR_CHANGE_RC_HIDE: 6987 { 6988 ptgt = refhash_linear_search(mpt->m_targets, 6989 mptsas_target_eval_devhdl, &diskhandle); 6990 if (ptgt == NULL) 6991 break; 6992 6993 /* 6994 * Update DR flag immediately avoid I/O failure 6995 */ 6996 mutex_enter(&mpt->m_tx_waitq_mutex); 6997 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 6998 mutex_exit(&mpt->m_tx_waitq_mutex); 6999 7000 topo_node = kmem_zalloc( 7001 sizeof (mptsas_topo_change_list_t), 7002 KM_SLEEP); 7003 topo_node->mpt = mpt; 7004 topo_node->un.phymask = 7005 ptgt->m_addr.mta_phymask; 7006 topo_node->event = 7007 MPTSAS_DR_EVENT_OFFLINE_TARGET; 7008 topo_node->devhdl = diskhandle; 7009 topo_node->flags = 7010 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED; 7011 topo_node->object = (void *)ptgt; 7012 if (topo_head == NULL) { 7013 topo_head = topo_tail = topo_node; 7014 } else { 7015 topo_tail->next = topo_node; 7016 topo_tail = topo_node; 7017 } 7018 break; 7019 } 7020 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: 7021 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: 7022 { 7023 /* 7024 * The physical drive is released by a IR 7025 * volume. But we cannot get the the physport 7026 * or phynum from the event data, so we only 7027 * can get the physport/phynum after SAS 7028 * Device Page0 request for the devhdl. 7029 */ 7030 topo_node = kmem_zalloc( 7031 sizeof (mptsas_topo_change_list_t), 7032 KM_SLEEP); 7033 topo_node->mpt = mpt; 7034 topo_node->un.phymask = 0; 7035 topo_node->event = 7036 MPTSAS_DR_EVENT_RECONFIG_TARGET; 7037 topo_node->devhdl = diskhandle; 7038 topo_node->flags = 7039 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED; 7040 topo_node->object = NULL; 7041 mpt->m_port_chng = 1; 7042 if (topo_head == NULL) { 7043 topo_head = topo_tail = topo_node; 7044 } else { 7045 topo_tail->next = topo_node; 7046 topo_tail = topo_node; 7047 } 7048 break; 7049 } 7050 default: 7051 break; 7052 } 7053 } 7054 7055 if (topo_head != NULL) { 7056 /* 7057 * Launch DR taskq to handle topology change 7058 */ 7059 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 7060 mptsas_handle_dr, (void *)topo_head, 7061 DDI_NOSLEEP)) != DDI_SUCCESS) { 7062 mptsas_log(mpt, CE_NOTE, "mptsas start taskq " 7063 "for handle SAS DR event failed. \n"); 7064 } 7065 } 7066 break; 7067 } 7068 default: 7069 return (DDI_FAILURE); 7070 } 7071 7072 return (DDI_SUCCESS); 7073 } 7074 7075 /* 7076 * handle events from ioc 7077 */ 7078 static void 7079 mptsas_handle_event(void *args) 7080 { 7081 m_replyh_arg_t *replyh_arg; 7082 pMpi2EventNotificationReply_t eventreply; 7083 uint32_t event, iocloginfo, rfm; 7084 uint32_t status; 7085 uint8_t port; 7086 mptsas_t *mpt; 7087 uint_t iocstatus; 7088 7089 replyh_arg = (m_replyh_arg_t *)args; 7090 rfm = replyh_arg->rfm; 7091 mpt = replyh_arg->mpt; 7092 7093 mutex_enter(&mpt->m_mutex); 7094 /* 7095 * If HBA is being reset, drop incoming event. 7096 */ 7097 if (mpt->m_in_reset) { 7098 NDBG20(("dropping event received prior to reset")); 7099 mutex_exit(&mpt->m_mutex); 7100 return; 7101 } 7102 7103 eventreply = (pMpi2EventNotificationReply_t) 7104 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr)); 7105 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 7106 7107 if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 7108 &eventreply->IOCStatus)) { 7109 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 7110 mptsas_log(mpt, CE_WARN, 7111 "!mptsas_handle_event: IOCStatus=0x%x, " 7112 "IOCLogInfo=0x%x", iocstatus, 7113 ddi_get32(mpt->m_acc_reply_frame_hdl, 7114 &eventreply->IOCLogInfo)); 7115 } else { 7116 mptsas_log(mpt, CE_WARN, 7117 "mptsas_handle_event: IOCStatus=0x%x, " 7118 "IOCLogInfo=0x%x", iocstatus, 7119 ddi_get32(mpt->m_acc_reply_frame_hdl, 7120 &eventreply->IOCLogInfo)); 7121 } 7122 } 7123 7124 /* 7125 * figure out what kind of event we got and handle accordingly 7126 */ 7127 switch (event) { 7128 case MPI2_EVENT_LOG_ENTRY_ADDED: 7129 break; 7130 case MPI2_EVENT_LOG_DATA: 7131 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 7132 &eventreply->IOCLogInfo); 7133 NDBG20(("mptsas %d log info %x received.\n", mpt->m_instance, 7134 iocloginfo)); 7135 break; 7136 case MPI2_EVENT_STATE_CHANGE: 7137 NDBG20(("mptsas%d state change.", mpt->m_instance)); 7138 break; 7139 case MPI2_EVENT_HARD_RESET_RECEIVED: 7140 NDBG20(("mptsas%d event change.", mpt->m_instance)); 7141 break; 7142 case MPI2_EVENT_SAS_DISCOVERY: 7143 { 7144 MPI2_EVENT_DATA_SAS_DISCOVERY *sasdiscovery; 7145 char string[80]; 7146 uint8_t rc; 7147 7148 sasdiscovery = 7149 (pMpi2EventDataSasDiscovery_t)eventreply->EventData; 7150 7151 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7152 &sasdiscovery->ReasonCode); 7153 port = ddi_get8(mpt->m_acc_reply_frame_hdl, 7154 &sasdiscovery->PhysicalPort); 7155 status = ddi_get32(mpt->m_acc_reply_frame_hdl, 7156 &sasdiscovery->DiscoveryStatus); 7157 7158 string[0] = 0; 7159 switch (rc) { 7160 case MPI2_EVENT_SAS_DISC_RC_STARTED: 7161 (void) sprintf(string, "STARTING"); 7162 break; 7163 case MPI2_EVENT_SAS_DISC_RC_COMPLETED: 7164 (void) sprintf(string, "COMPLETED"); 7165 break; 7166 default: 7167 (void) sprintf(string, "UNKNOWN"); 7168 break; 7169 } 7170 7171 NDBG20(("SAS DISCOVERY is %s for port %d, status %x", string, 7172 port, status)); 7173 7174 break; 7175 } 7176 case MPI2_EVENT_EVENT_CHANGE: 7177 NDBG20(("mptsas%d event change.", mpt->m_instance)); 7178 break; 7179 case MPI2_EVENT_TASK_SET_FULL: 7180 { 7181 pMpi2EventDataTaskSetFull_t taskfull; 7182 7183 taskfull = (pMpi2EventDataTaskSetFull_t)eventreply->EventData; 7184 7185 NDBG20(("TASK_SET_FULL received for mptsas%d, depth %d\n", 7186 mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl, 7187 &taskfull->CurrentDepth))); 7188 break; 7189 } 7190 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 7191 { 7192 /* 7193 * SAS TOPOLOGY CHANGE LIST Event has already been handled 7194 * in mptsas_handle_event_sync() of interrupt context 7195 */ 7196 break; 7197 } 7198 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: 7199 { 7200 pMpi2EventDataSasEnclDevStatusChange_t encstatus; 7201 uint8_t rc; 7202 char string[80]; 7203 7204 encstatus = (pMpi2EventDataSasEnclDevStatusChange_t) 7205 eventreply->EventData; 7206 7207 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7208 &encstatus->ReasonCode); 7209 switch (rc) { 7210 case MPI2_EVENT_SAS_ENCL_RC_ADDED: 7211 (void) sprintf(string, "added"); 7212 break; 7213 case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING: 7214 (void) sprintf(string, ", not responding"); 7215 break; 7216 default: 7217 break; 7218 } 7219 NDBG20(("mptsas%d ENCLOSURE STATUS CHANGE for enclosure %x%s\n", 7220 mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl, 7221 &encstatus->EnclosureHandle), string)); 7222 break; 7223 } 7224 7225 /* 7226 * MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE is handled by 7227 * mptsas_handle_event_sync,in here just send ack message. 7228 */ 7229 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: 7230 { 7231 pMpi2EventDataSasDeviceStatusChange_t statuschange; 7232 uint8_t rc; 7233 uint16_t devhdl; 7234 uint64_t wwn = 0; 7235 uint32_t wwn_lo, wwn_hi; 7236 7237 statuschange = (pMpi2EventDataSasDeviceStatusChange_t) 7238 eventreply->EventData; 7239 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7240 &statuschange->ReasonCode); 7241 wwn_lo = ddi_get32(mpt->m_acc_reply_frame_hdl, 7242 (uint32_t *)(void *)&statuschange->SASAddress); 7243 wwn_hi = ddi_get32(mpt->m_acc_reply_frame_hdl, 7244 (uint32_t *)(void *)&statuschange->SASAddress + 1); 7245 wwn = ((uint64_t)wwn_hi << 32) | wwn_lo; 7246 devhdl = ddi_get16(mpt->m_acc_reply_frame_hdl, 7247 &statuschange->DevHandle); 7248 7249 NDBG13(("MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE wwn is %"PRIx64, 7250 wwn)); 7251 7252 switch (rc) { 7253 case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA: 7254 NDBG20(("SMART data received, ASC/ASCQ = %02x/%02x", 7255 ddi_get8(mpt->m_acc_reply_frame_hdl, 7256 &statuschange->ASC), 7257 ddi_get8(mpt->m_acc_reply_frame_hdl, 7258 &statuschange->ASCQ))); 7259 break; 7260 7261 case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED: 7262 NDBG20(("Device not supported")); 7263 break; 7264 7265 case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: 7266 NDBG20(("IOC internally generated the Target Reset " 7267 "for devhdl:%x", devhdl)); 7268 break; 7269 7270 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET: 7271 NDBG20(("IOC's internally generated Target Reset " 7272 "completed for devhdl:%x", devhdl)); 7273 break; 7274 7275 case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: 7276 NDBG20(("IOC internally generated Abort Task")); 7277 break; 7278 7279 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL: 7280 NDBG20(("IOC's internally generated Abort Task " 7281 "completed")); 7282 break; 7283 7284 case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: 7285 NDBG20(("IOC internally generated Abort Task Set")); 7286 break; 7287 7288 case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: 7289 NDBG20(("IOC internally generated Clear Task Set")); 7290 break; 7291 7292 case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: 7293 NDBG20(("IOC internally generated Query Task")); 7294 break; 7295 7296 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION: 7297 NDBG20(("Device sent an Asynchronous Notification")); 7298 break; 7299 7300 default: 7301 break; 7302 } 7303 break; 7304 } 7305 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 7306 { 7307 /* 7308 * IR TOPOLOGY CHANGE LIST Event has already been handled 7309 * in mpt_handle_event_sync() of interrupt context 7310 */ 7311 break; 7312 } 7313 case MPI2_EVENT_IR_OPERATION_STATUS: 7314 { 7315 Mpi2EventDataIrOperationStatus_t *irOpStatus; 7316 char reason_str[80]; 7317 uint8_t rc, percent; 7318 uint16_t handle; 7319 7320 irOpStatus = (pMpi2EventDataIrOperationStatus_t) 7321 eventreply->EventData; 7322 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7323 &irOpStatus->RAIDOperation); 7324 percent = ddi_get8(mpt->m_acc_reply_frame_hdl, 7325 &irOpStatus->PercentComplete); 7326 handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7327 &irOpStatus->VolDevHandle); 7328 7329 switch (rc) { 7330 case MPI2_EVENT_IR_RAIDOP_RESYNC: 7331 (void) sprintf(reason_str, "resync"); 7332 break; 7333 case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION: 7334 (void) sprintf(reason_str, "online capacity " 7335 "expansion"); 7336 break; 7337 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK: 7338 (void) sprintf(reason_str, "consistency check"); 7339 break; 7340 default: 7341 (void) sprintf(reason_str, "unknown reason %x", 7342 rc); 7343 } 7344 7345 NDBG20(("mptsas%d raid operational status: (%s)" 7346 "\thandle(0x%04x), percent complete(%d)\n", 7347 mpt->m_instance, reason_str, handle, percent)); 7348 break; 7349 } 7350 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: 7351 { 7352 pMpi2EventDataSasBroadcastPrimitive_t sas_broadcast; 7353 uint8_t phy_num; 7354 uint8_t primitive; 7355 7356 sas_broadcast = (pMpi2EventDataSasBroadcastPrimitive_t) 7357 eventreply->EventData; 7358 7359 phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl, 7360 &sas_broadcast->PhyNum); 7361 primitive = ddi_get8(mpt->m_acc_reply_frame_hdl, 7362 &sas_broadcast->Primitive); 7363 7364 switch (primitive) { 7365 case MPI2_EVENT_PRIMITIVE_CHANGE: 7366 mptsas_smhba_log_sysevent(mpt, 7367 ESC_SAS_HBA_PORT_BROADCAST, 7368 SAS_PORT_BROADCAST_CHANGE, 7369 &mpt->m_phy_info[phy_num].smhba_info); 7370 break; 7371 case MPI2_EVENT_PRIMITIVE_SES: 7372 mptsas_smhba_log_sysevent(mpt, 7373 ESC_SAS_HBA_PORT_BROADCAST, 7374 SAS_PORT_BROADCAST_SES, 7375 &mpt->m_phy_info[phy_num].smhba_info); 7376 break; 7377 case MPI2_EVENT_PRIMITIVE_EXPANDER: 7378 mptsas_smhba_log_sysevent(mpt, 7379 ESC_SAS_HBA_PORT_BROADCAST, 7380 SAS_PORT_BROADCAST_D01_4, 7381 &mpt->m_phy_info[phy_num].smhba_info); 7382 break; 7383 case MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT: 7384 mptsas_smhba_log_sysevent(mpt, 7385 ESC_SAS_HBA_PORT_BROADCAST, 7386 SAS_PORT_BROADCAST_D04_7, 7387 &mpt->m_phy_info[phy_num].smhba_info); 7388 break; 7389 case MPI2_EVENT_PRIMITIVE_RESERVED3: 7390 mptsas_smhba_log_sysevent(mpt, 7391 ESC_SAS_HBA_PORT_BROADCAST, 7392 SAS_PORT_BROADCAST_D16_7, 7393 &mpt->m_phy_info[phy_num].smhba_info); 7394 break; 7395 case MPI2_EVENT_PRIMITIVE_RESERVED4: 7396 mptsas_smhba_log_sysevent(mpt, 7397 ESC_SAS_HBA_PORT_BROADCAST, 7398 SAS_PORT_BROADCAST_D29_7, 7399 &mpt->m_phy_info[phy_num].smhba_info); 7400 break; 7401 case MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED: 7402 mptsas_smhba_log_sysevent(mpt, 7403 ESC_SAS_HBA_PORT_BROADCAST, 7404 SAS_PORT_BROADCAST_D24_0, 7405 &mpt->m_phy_info[phy_num].smhba_info); 7406 break; 7407 case MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED: 7408 mptsas_smhba_log_sysevent(mpt, 7409 ESC_SAS_HBA_PORT_BROADCAST, 7410 SAS_PORT_BROADCAST_D27_4, 7411 &mpt->m_phy_info[phy_num].smhba_info); 7412 break; 7413 default: 7414 NDBG20(("mptsas%d: unknown BROADCAST PRIMITIVE" 7415 " %x received", 7416 mpt->m_instance, primitive)); 7417 break; 7418 } 7419 NDBG20(("mptsas%d sas broadcast primitive: " 7420 "\tprimitive(0x%04x), phy(%d) complete\n", 7421 mpt->m_instance, primitive, phy_num)); 7422 break; 7423 } 7424 case MPI2_EVENT_IR_VOLUME: 7425 { 7426 Mpi2EventDataIrVolume_t *irVolume; 7427 uint16_t devhandle; 7428 uint32_t state; 7429 int config, vol; 7430 uint8_t found = FALSE; 7431 7432 irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData; 7433 state = ddi_get32(mpt->m_acc_reply_frame_hdl, 7434 &irVolume->NewValue); 7435 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7436 &irVolume->VolDevHandle); 7437 7438 NDBG20(("EVENT_IR_VOLUME event is received")); 7439 7440 /* 7441 * Get latest RAID info and then find the DevHandle for this 7442 * event in the configuration. If the DevHandle is not found 7443 * just exit the event. 7444 */ 7445 (void) mptsas_get_raid_info(mpt); 7446 for (config = 0; (config < mpt->m_num_raid_configs) && 7447 (!found); config++) { 7448 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) { 7449 if (mpt->m_raidconfig[config].m_raidvol[vol]. 7450 m_raidhandle == devhandle) { 7451 found = TRUE; 7452 break; 7453 } 7454 } 7455 } 7456 if (!found) { 7457 break; 7458 } 7459 7460 switch (irVolume->ReasonCode) { 7461 case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED: 7462 { 7463 uint32_t i; 7464 mpt->m_raidconfig[config].m_raidvol[vol].m_settings = 7465 state; 7466 7467 i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING; 7468 mptsas_log(mpt, CE_NOTE, " Volume %d settings changed" 7469 ", auto-config of hot-swap drives is %s" 7470 ", write caching is %s" 7471 ", hot-spare pool mask is %02x\n", 7472 vol, state & 7473 MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE 7474 ? "disabled" : "enabled", 7475 i == MPI2_RAIDVOL0_SETTING_UNCHANGED 7476 ? "controlled by member disks" : 7477 i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING 7478 ? "disabled" : 7479 i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING 7480 ? "enabled" : 7481 "incorrectly set", 7482 (state >> 16) & 0xff); 7483 break; 7484 } 7485 case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED: 7486 { 7487 mpt->m_raidconfig[config].m_raidvol[vol].m_state = 7488 (uint8_t)state; 7489 7490 mptsas_log(mpt, CE_NOTE, 7491 "Volume %d is now %s\n", vol, 7492 state == MPI2_RAID_VOL_STATE_OPTIMAL 7493 ? "optimal" : 7494 state == MPI2_RAID_VOL_STATE_DEGRADED 7495 ? "degraded" : 7496 state == MPI2_RAID_VOL_STATE_ONLINE 7497 ? "online" : 7498 state == MPI2_RAID_VOL_STATE_INITIALIZING 7499 ? "initializing" : 7500 state == MPI2_RAID_VOL_STATE_FAILED 7501 ? "failed" : 7502 state == MPI2_RAID_VOL_STATE_MISSING 7503 ? "missing" : 7504 "state unknown"); 7505 break; 7506 } 7507 case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED: 7508 { 7509 mpt->m_raidconfig[config].m_raidvol[vol]. 7510 m_statusflags = state; 7511 7512 mptsas_log(mpt, CE_NOTE, 7513 " Volume %d is now %s%s%s%s%s%s%s%s%s\n", 7514 vol, 7515 state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED 7516 ? ", enabled" : ", disabled", 7517 state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED 7518 ? ", quiesced" : "", 7519 state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE 7520 ? ", inactive" : ", active", 7521 state & 7522 MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL 7523 ? ", bad block table is full" : "", 7524 state & 7525 MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS 7526 ? ", resync in progress" : "", 7527 state & MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT 7528 ? ", background initialization in progress" : "", 7529 state & 7530 MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION 7531 ? ", capacity expansion in progress" : "", 7532 state & 7533 MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK 7534 ? ", consistency check in progress" : "", 7535 state & MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB 7536 ? ", data scrub in progress" : ""); 7537 break; 7538 } 7539 default: 7540 break; 7541 } 7542 break; 7543 } 7544 case MPI2_EVENT_IR_PHYSICAL_DISK: 7545 { 7546 Mpi2EventDataIrPhysicalDisk_t *irPhysDisk; 7547 uint16_t devhandle, enchandle, slot; 7548 uint32_t status, state; 7549 uint8_t physdisknum, reason; 7550 7551 irPhysDisk = (Mpi2EventDataIrPhysicalDisk_t *) 7552 eventreply->EventData; 7553 physdisknum = ddi_get8(mpt->m_acc_reply_frame_hdl, 7554 &irPhysDisk->PhysDiskNum); 7555 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7556 &irPhysDisk->PhysDiskDevHandle); 7557 enchandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7558 &irPhysDisk->EnclosureHandle); 7559 slot = ddi_get16(mpt->m_acc_reply_frame_hdl, 7560 &irPhysDisk->Slot); 7561 state = ddi_get32(mpt->m_acc_reply_frame_hdl, 7562 &irPhysDisk->NewValue); 7563 reason = ddi_get8(mpt->m_acc_reply_frame_hdl, 7564 &irPhysDisk->ReasonCode); 7565 7566 NDBG20(("EVENT_IR_PHYSICAL_DISK event is received")); 7567 7568 switch (reason) { 7569 case MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED: 7570 mptsas_log(mpt, CE_NOTE, 7571 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 7572 "for enclosure with handle 0x%x is now in hot " 7573 "spare pool %d", 7574 physdisknum, devhandle, slot, enchandle, 7575 (state >> 16) & 0xff); 7576 break; 7577 7578 case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED: 7579 status = state; 7580 mptsas_log(mpt, CE_NOTE, 7581 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 7582 "for enclosure with handle 0x%x is now " 7583 "%s%s%s%s%s\n", physdisknum, devhandle, slot, 7584 enchandle, 7585 status & MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME 7586 ? ", inactive" : ", active", 7587 status & MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC 7588 ? ", out of sync" : "", 7589 status & MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED 7590 ? ", quiesced" : "", 7591 status & 7592 MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED 7593 ? ", write cache enabled" : "", 7594 status & MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET 7595 ? ", capacity expansion target" : ""); 7596 break; 7597 7598 case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED: 7599 mptsas_log(mpt, CE_NOTE, 7600 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 7601 "for enclosure with handle 0x%x is now %s\n", 7602 physdisknum, devhandle, slot, enchandle, 7603 state == MPI2_RAID_PD_STATE_OPTIMAL 7604 ? "optimal" : 7605 state == MPI2_RAID_PD_STATE_REBUILDING 7606 ? "rebuilding" : 7607 state == MPI2_RAID_PD_STATE_DEGRADED 7608 ? "degraded" : 7609 state == MPI2_RAID_PD_STATE_HOT_SPARE 7610 ? "a hot spare" : 7611 state == MPI2_RAID_PD_STATE_ONLINE 7612 ? "online" : 7613 state == MPI2_RAID_PD_STATE_OFFLINE 7614 ? "offline" : 7615 state == MPI2_RAID_PD_STATE_NOT_COMPATIBLE 7616 ? "not compatible" : 7617 state == MPI2_RAID_PD_STATE_NOT_CONFIGURED 7618 ? "not configured" : 7619 "state unknown"); 7620 break; 7621 } 7622 break; 7623 } 7624 default: 7625 NDBG20(("mptsas%d: unknown event %x received", 7626 mpt->m_instance, event)); 7627 break; 7628 } 7629 7630 /* 7631 * Return the reply frame to the free queue. 7632 */ 7633 ddi_put32(mpt->m_acc_free_queue_hdl, 7634 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], rfm); 7635 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 7636 DDI_DMA_SYNC_FORDEV); 7637 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 7638 mpt->m_free_index = 0; 7639 } 7640 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 7641 mpt->m_free_index); 7642 mutex_exit(&mpt->m_mutex); 7643 } 7644 7645 /* 7646 * invoked from timeout() to restart qfull cmds with throttle == 0 7647 */ 7648 static void 7649 mptsas_restart_cmd(void *arg) 7650 { 7651 mptsas_t *mpt = arg; 7652 mptsas_target_t *ptgt = NULL; 7653 7654 mutex_enter(&mpt->m_mutex); 7655 7656 mpt->m_restart_cmd_timeid = 0; 7657 7658 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 7659 ptgt = refhash_next(mpt->m_targets, ptgt)) { 7660 if (ptgt->m_reset_delay == 0) { 7661 if (ptgt->m_t_throttle == QFULL_THROTTLE) { 7662 mptsas_set_throttle(mpt, ptgt, 7663 MAX_THROTTLE); 7664 } 7665 } 7666 } 7667 mptsas_restart_hba(mpt); 7668 mutex_exit(&mpt->m_mutex); 7669 } 7670 7671 void 7672 mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 7673 { 7674 int slot; 7675 mptsas_slots_t *slots = mpt->m_active; 7676 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 7677 7678 ASSERT(cmd != NULL); 7679 ASSERT(cmd->cmd_queued == FALSE); 7680 7681 /* 7682 * Task Management cmds are removed in their own routines. Also, 7683 * we don't want to modify timeout based on TM cmds. 7684 */ 7685 if (cmd->cmd_flags & CFLAG_TM_CMD) { 7686 return; 7687 } 7688 7689 slot = cmd->cmd_slot; 7690 7691 /* 7692 * remove the cmd. 7693 */ 7694 if (cmd == slots->m_slot[slot]) { 7695 NDBG31(("mptsas_remove_cmd: removing cmd=0x%p", (void *)cmd)); 7696 slots->m_slot[slot] = NULL; 7697 mpt->m_ncmds--; 7698 7699 /* 7700 * only decrement per target ncmds if command 7701 * has a target associated with it. 7702 */ 7703 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 7704 ptgt->m_t_ncmds--; 7705 /* 7706 * reset throttle if we just ran an untagged command 7707 * to a tagged target 7708 */ 7709 if ((ptgt->m_t_ncmds == 0) && 7710 ((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0)) { 7711 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 7712 } 7713 7714 /* 7715 * Remove this command from the active queue. 7716 */ 7717 if (cmd->cmd_active_expiration != 0) { 7718 TAILQ_REMOVE(&ptgt->m_active_cmdq, cmd, 7719 cmd_active_link); 7720 cmd->cmd_active_expiration = 0; 7721 } 7722 } 7723 } 7724 7725 /* 7726 * This is all we need to do for ioc commands. 7727 */ 7728 if (cmd->cmd_flags & CFLAG_CMDIOC) { 7729 mptsas_return_to_pool(mpt, cmd); 7730 return; 7731 } 7732 7733 ASSERT(cmd != slots->m_slot[cmd->cmd_slot]); 7734 } 7735 7736 /* 7737 * accept all cmds on the tx_waitq if any and then 7738 * start a fresh request from the top of the device queue. 7739 * 7740 * since there are always cmds queued on the tx_waitq, and rare cmds on 7741 * the instance waitq, so this function should not be invoked in the ISR, 7742 * the mptsas_restart_waitq() is invoked in the ISR instead. otherwise, the 7743 * burden belongs to the IO dispatch CPUs is moved the interrupt CPU. 7744 */ 7745 static void 7746 mptsas_restart_hba(mptsas_t *mpt) 7747 { 7748 ASSERT(mutex_owned(&mpt->m_mutex)); 7749 7750 mutex_enter(&mpt->m_tx_waitq_mutex); 7751 if (mpt->m_tx_waitq) { 7752 mptsas_accept_tx_waitq(mpt); 7753 } 7754 mutex_exit(&mpt->m_tx_waitq_mutex); 7755 mptsas_restart_waitq(mpt); 7756 } 7757 7758 /* 7759 * start a fresh request from the top of the device queue 7760 */ 7761 static void 7762 mptsas_restart_waitq(mptsas_t *mpt) 7763 { 7764 mptsas_cmd_t *cmd, *next_cmd; 7765 mptsas_target_t *ptgt = NULL; 7766 7767 NDBG1(("mptsas_restart_waitq: mpt=0x%p", (void *)mpt)); 7768 7769 ASSERT(mutex_owned(&mpt->m_mutex)); 7770 7771 /* 7772 * If there is a reset delay, don't start any cmds. Otherwise, start 7773 * as many cmds as possible. 7774 * Since SMID 0 is reserved and the TM slot is reserved, the actual max 7775 * commands is m_max_requests - 2. 7776 */ 7777 cmd = mpt->m_waitq; 7778 7779 while (cmd != NULL) { 7780 next_cmd = cmd->cmd_linkp; 7781 if (cmd->cmd_flags & CFLAG_PASSTHRU) { 7782 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 7783 /* 7784 * passthru command get slot need 7785 * set CFLAG_PREPARED. 7786 */ 7787 cmd->cmd_flags |= CFLAG_PREPARED; 7788 mptsas_waitq_delete(mpt, cmd); 7789 mptsas_start_passthru(mpt, cmd); 7790 } 7791 cmd = next_cmd; 7792 continue; 7793 } 7794 if (cmd->cmd_flags & CFLAG_CONFIG) { 7795 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 7796 /* 7797 * Send the config page request and delete it 7798 * from the waitq. 7799 */ 7800 cmd->cmd_flags |= CFLAG_PREPARED; 7801 mptsas_waitq_delete(mpt, cmd); 7802 mptsas_start_config_page_access(mpt, cmd); 7803 } 7804 cmd = next_cmd; 7805 continue; 7806 } 7807 if (cmd->cmd_flags & CFLAG_FW_DIAG) { 7808 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 7809 /* 7810 * Send the FW Diag request and delete if from 7811 * the waitq. 7812 */ 7813 cmd->cmd_flags |= CFLAG_PREPARED; 7814 mptsas_waitq_delete(mpt, cmd); 7815 mptsas_start_diag(mpt, cmd); 7816 } 7817 cmd = next_cmd; 7818 continue; 7819 } 7820 7821 ptgt = cmd->cmd_tgt_addr; 7822 if (ptgt && (ptgt->m_t_throttle == DRAIN_THROTTLE) && 7823 (ptgt->m_t_ncmds == 0)) { 7824 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 7825 } 7826 if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) && 7827 (ptgt && (ptgt->m_reset_delay == 0)) && 7828 (ptgt && (ptgt->m_t_ncmds < 7829 ptgt->m_t_throttle))) { 7830 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 7831 mptsas_waitq_delete(mpt, cmd); 7832 (void) mptsas_start_cmd(mpt, cmd); 7833 } 7834 } 7835 cmd = next_cmd; 7836 } 7837 } 7838 /* 7839 * Cmds are queued if tran_start() doesn't get the m_mutexlock(no wait). 7840 * Accept all those queued cmds before new cmd is accept so that the 7841 * cmds are sent in order. 7842 */ 7843 static void 7844 mptsas_accept_tx_waitq(mptsas_t *mpt) 7845 { 7846 mptsas_cmd_t *cmd; 7847 7848 ASSERT(mutex_owned(&mpt->m_mutex)); 7849 ASSERT(mutex_owned(&mpt->m_tx_waitq_mutex)); 7850 7851 /* 7852 * A Bus Reset could occur at any time and flush the tx_waitq, 7853 * so we cannot count on the tx_waitq to contain even one cmd. 7854 * And when the m_tx_waitq_mutex is released and run 7855 * mptsas_accept_pkt(), the tx_waitq may be flushed. 7856 */ 7857 cmd = mpt->m_tx_waitq; 7858 for (;;) { 7859 if ((cmd = mpt->m_tx_waitq) == NULL) { 7860 mpt->m_tx_draining = 0; 7861 break; 7862 } 7863 if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) { 7864 mpt->m_tx_waitqtail = &mpt->m_tx_waitq; 7865 } 7866 cmd->cmd_linkp = NULL; 7867 mutex_exit(&mpt->m_tx_waitq_mutex); 7868 if (mptsas_accept_pkt(mpt, cmd) != TRAN_ACCEPT) 7869 cmn_err(CE_WARN, "mpt: mptsas_accept_tx_waitq: failed " 7870 "to accept cmd on queue\n"); 7871 mutex_enter(&mpt->m_tx_waitq_mutex); 7872 } 7873 } 7874 7875 7876 /* 7877 * mpt tag type lookup 7878 */ 7879 static char mptsas_tag_lookup[] = 7880 {0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG}; 7881 7882 static int 7883 mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 7884 { 7885 struct scsi_pkt *pkt = CMD2PKT(cmd); 7886 uint32_t control = 0; 7887 caddr_t mem; 7888 pMpi2SCSIIORequest_t io_request; 7889 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; 7890 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl; 7891 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 7892 uint16_t SMID, io_flags = 0; 7893 uint32_t request_desc_low, request_desc_high; 7894 mptsas_cmd_t *c; 7895 7896 NDBG1(("mptsas_start_cmd: cmd=0x%p", (void *)cmd)); 7897 7898 /* 7899 * Set SMID and increment index. Rollover to 1 instead of 0 if index 7900 * is at the max. 0 is an invalid SMID, so we call the first index 1. 7901 */ 7902 SMID = cmd->cmd_slot; 7903 7904 /* 7905 * It is possible for back to back device reset to 7906 * happen before the reset delay has expired. That's 7907 * ok, just let the device reset go out on the bus. 7908 */ 7909 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 7910 ASSERT(ptgt->m_reset_delay == 0); 7911 } 7912 7913 /* 7914 * if a non-tagged cmd is submitted to an active tagged target 7915 * then drain before submitting this cmd; SCSI-2 allows RQSENSE 7916 * to be untagged 7917 */ 7918 if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) && 7919 (ptgt->m_t_ncmds > 1) && 7920 ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) && 7921 (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) { 7922 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 7923 NDBG23(("target=%d, untagged cmd, start draining\n", 7924 ptgt->m_devhdl)); 7925 7926 if (ptgt->m_reset_delay == 0) { 7927 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 7928 } 7929 7930 mptsas_remove_cmd(mpt, cmd); 7931 cmd->cmd_pkt_flags |= FLAG_HEAD; 7932 mptsas_waitq_add(mpt, cmd); 7933 } 7934 return (DDI_FAILURE); 7935 } 7936 7937 /* 7938 * Set correct tag bits. 7939 */ 7940 if (cmd->cmd_pkt_flags & FLAG_TAGMASK) { 7941 switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags & 7942 FLAG_TAGMASK) >> 12)]) { 7943 case MSG_SIMPLE_QTAG: 7944 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 7945 break; 7946 case MSG_HEAD_QTAG: 7947 control |= MPI2_SCSIIO_CONTROL_HEADOFQ; 7948 break; 7949 case MSG_ORDERED_QTAG: 7950 control |= MPI2_SCSIIO_CONTROL_ORDEREDQ; 7951 break; 7952 default: 7953 mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n"); 7954 break; 7955 } 7956 } else { 7957 if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) { 7958 ptgt->m_t_throttle = 1; 7959 } 7960 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 7961 } 7962 7963 if (cmd->cmd_pkt_flags & FLAG_TLR) { 7964 control |= MPI2_SCSIIO_CONTROL_TLR_ON; 7965 } 7966 7967 mem = mpt->m_req_frame + (mpt->m_req_frame_size * SMID); 7968 io_request = (pMpi2SCSIIORequest_t)mem; 7969 7970 bzero(io_request, sizeof (Mpi2SCSIIORequest_t)); 7971 ddi_put8(acc_hdl, &io_request->SGLOffset0, offsetof 7972 (MPI2_SCSI_IO_REQUEST, SGL) / 4); 7973 mptsas_init_std_hdr(acc_hdl, io_request, ptgt->m_devhdl, Lun(cmd), 0, 7974 MPI2_FUNCTION_SCSI_IO_REQUEST); 7975 7976 (void) ddi_rep_put8(acc_hdl, (uint8_t *)pkt->pkt_cdbp, 7977 io_request->CDB.CDB32, cmd->cmd_cdblen, DDI_DEV_AUTOINCR); 7978 7979 io_flags = cmd->cmd_cdblen; 7980 ddi_put16(acc_hdl, &io_request->IoFlags, io_flags); 7981 /* 7982 * setup the Scatter/Gather DMA list for this request 7983 */ 7984 if (cmd->cmd_cookiec > 0) { 7985 mptsas_sge_setup(mpt, cmd, &control, io_request, acc_hdl); 7986 } else { 7987 ddi_put32(acc_hdl, &io_request->SGL.MpiSimple.FlagsLength, 7988 ((uint32_t)MPI2_SGE_FLAGS_LAST_ELEMENT | 7989 MPI2_SGE_FLAGS_END_OF_BUFFER | 7990 MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 7991 MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); 7992 } 7993 7994 /* 7995 * save ARQ information 7996 */ 7997 ddi_put8(acc_hdl, &io_request->SenseBufferLength, cmd->cmd_rqslen); 7998 if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) == 7999 (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) { 8000 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, 8001 cmd->cmd_ext_arqcookie.dmac_address); 8002 } else { 8003 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, 8004 cmd->cmd_arqcookie.dmac_address); 8005 } 8006 8007 ddi_put32(acc_hdl, &io_request->Control, control); 8008 8009 NDBG31(("starting message=0x%p, with cmd=0x%p", 8010 (void *)(uintptr_t)mpt->m_req_frame_dma_addr, (void *)cmd)); 8011 8012 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 8013 8014 /* 8015 * Build request descriptor and write it to the request desc post reg. 8016 */ 8017 request_desc_low = (SMID << 16) + MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 8018 request_desc_high = ptgt->m_devhdl << 16; 8019 MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high); 8020 8021 /* 8022 * Start timeout. 8023 */ 8024 cmd->cmd_active_expiration = 8025 gethrtime() + (hrtime_t)pkt->pkt_time * NANOSEC; 8026 #ifdef MPTSAS_TEST 8027 /* 8028 * Force timeouts to happen immediately. 8029 */ 8030 if (mptsas_test_timeouts) 8031 cmd->cmd_active_expiration = gethrtime(); 8032 #endif 8033 c = TAILQ_FIRST(&ptgt->m_active_cmdq); 8034 if (c == NULL || 8035 c->cmd_active_expiration < cmd->cmd_active_expiration) { 8036 /* 8037 * Common case is that this is the last pending expiration 8038 * (or queue is empty). Insert at head of the queue. 8039 */ 8040 TAILQ_INSERT_HEAD(&ptgt->m_active_cmdq, cmd, cmd_active_link); 8041 } else { 8042 /* 8043 * Queue is not empty and first element expires later than 8044 * this command. Search for element expiring sooner. 8045 */ 8046 while ((c = TAILQ_NEXT(c, cmd_active_link)) != NULL) { 8047 if (c->cmd_active_expiration < 8048 cmd->cmd_active_expiration) { 8049 TAILQ_INSERT_BEFORE(c, cmd, cmd_active_link); 8050 break; 8051 } 8052 } 8053 if (c == NULL) { 8054 /* 8055 * No element found expiring sooner, append to 8056 * non-empty queue. 8057 */ 8058 TAILQ_INSERT_TAIL(&ptgt->m_active_cmdq, cmd, 8059 cmd_active_link); 8060 } 8061 } 8062 8063 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || 8064 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { 8065 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8066 return (DDI_FAILURE); 8067 } 8068 return (DDI_SUCCESS); 8069 } 8070 8071 /* 8072 * Select a helper thread to handle current doneq 8073 */ 8074 static void 8075 mptsas_deliver_doneq_thread(mptsas_t *mpt) 8076 { 8077 uint64_t t, i; 8078 uint32_t min = 0xffffffff; 8079 mptsas_doneq_thread_list_t *item; 8080 8081 for (i = 0; i < mpt->m_doneq_thread_n; i++) { 8082 item = &mpt->m_doneq_thread_id[i]; 8083 /* 8084 * If the completed command on help thread[i] less than 8085 * doneq_thread_threshold, then pick the thread[i]. Otherwise 8086 * pick a thread which has least completed command. 8087 */ 8088 8089 mutex_enter(&item->mutex); 8090 if (item->len < mpt->m_doneq_thread_threshold) { 8091 t = i; 8092 mutex_exit(&item->mutex); 8093 break; 8094 } 8095 if (item->len < min) { 8096 min = item->len; 8097 t = i; 8098 } 8099 mutex_exit(&item->mutex); 8100 } 8101 mutex_enter(&mpt->m_doneq_thread_id[t].mutex); 8102 mptsas_doneq_mv(mpt, t); 8103 cv_signal(&mpt->m_doneq_thread_id[t].cv); 8104 mutex_exit(&mpt->m_doneq_thread_id[t].mutex); 8105 } 8106 8107 /* 8108 * move the current global doneq to the doneq of thead[t] 8109 */ 8110 static void 8111 mptsas_doneq_mv(mptsas_t *mpt, uint64_t t) 8112 { 8113 mptsas_cmd_t *cmd; 8114 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 8115 8116 ASSERT(mutex_owned(&item->mutex)); 8117 while ((cmd = mpt->m_doneq) != NULL) { 8118 if ((mpt->m_doneq = cmd->cmd_linkp) == NULL) { 8119 mpt->m_donetail = &mpt->m_doneq; 8120 } 8121 cmd->cmd_linkp = NULL; 8122 *item->donetail = cmd; 8123 item->donetail = &cmd->cmd_linkp; 8124 mpt->m_doneq_len--; 8125 item->len++; 8126 } 8127 } 8128 8129 void 8130 mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd) 8131 { 8132 struct scsi_pkt *pkt = CMD2PKT(cmd); 8133 8134 /* Check all acc and dma handles */ 8135 if ((mptsas_check_acc_handle(mpt->m_datap) != 8136 DDI_SUCCESS) || 8137 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 8138 DDI_SUCCESS) || 8139 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) != 8140 DDI_SUCCESS) || 8141 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) != 8142 DDI_SUCCESS) || 8143 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) != 8144 DDI_SUCCESS) || 8145 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) != 8146 DDI_SUCCESS) || 8147 (mptsas_check_acc_handle(mpt->m_config_handle) != 8148 DDI_SUCCESS)) { 8149 ddi_fm_service_impact(mpt->m_dip, 8150 DDI_SERVICE_UNAFFECTED); 8151 ddi_fm_acc_err_clear(mpt->m_config_handle, 8152 DDI_FME_VER0); 8153 pkt->pkt_reason = CMD_TRAN_ERR; 8154 pkt->pkt_statistics = 0; 8155 } 8156 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 8157 DDI_SUCCESS) || 8158 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) != 8159 DDI_SUCCESS) || 8160 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) != 8161 DDI_SUCCESS) || 8162 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) != 8163 DDI_SUCCESS) || 8164 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) != 8165 DDI_SUCCESS)) { 8166 ddi_fm_service_impact(mpt->m_dip, 8167 DDI_SERVICE_UNAFFECTED); 8168 pkt->pkt_reason = CMD_TRAN_ERR; 8169 pkt->pkt_statistics = 0; 8170 } 8171 if (cmd->cmd_dmahandle && 8172 (mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS)) { 8173 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8174 pkt->pkt_reason = CMD_TRAN_ERR; 8175 pkt->pkt_statistics = 0; 8176 } 8177 if ((cmd->cmd_extra_frames && 8178 ((mptsas_check_dma_handle(cmd->cmd_extra_frames->m_dma_hdl) != 8179 DDI_SUCCESS) || 8180 (mptsas_check_acc_handle(cmd->cmd_extra_frames->m_acc_hdl) != 8181 DDI_SUCCESS)))) { 8182 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8183 pkt->pkt_reason = CMD_TRAN_ERR; 8184 pkt->pkt_statistics = 0; 8185 } 8186 if (cmd->cmd_arqhandle && 8187 (mptsas_check_dma_handle(cmd->cmd_arqhandle) != DDI_SUCCESS)) { 8188 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8189 pkt->pkt_reason = CMD_TRAN_ERR; 8190 pkt->pkt_statistics = 0; 8191 } 8192 if (cmd->cmd_ext_arqhandle && 8193 (mptsas_check_dma_handle(cmd->cmd_ext_arqhandle) != DDI_SUCCESS)) { 8194 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8195 pkt->pkt_reason = CMD_TRAN_ERR; 8196 pkt->pkt_statistics = 0; 8197 } 8198 } 8199 8200 /* 8201 * These routines manipulate the queue of commands that 8202 * are waiting for their completion routines to be called. 8203 * The queue is usually in FIFO order but on an MP system 8204 * it's possible for the completion routines to get out 8205 * of order. If that's a problem you need to add a global 8206 * mutex around the code that calls the completion routine 8207 * in the interrupt handler. 8208 */ 8209 static void 8210 mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd) 8211 { 8212 struct scsi_pkt *pkt = CMD2PKT(cmd); 8213 8214 NDBG31(("mptsas_doneq_add: cmd=0x%p", (void *)cmd)); 8215 8216 ASSERT((cmd->cmd_flags & CFLAG_COMPLETED) == 0); 8217 cmd->cmd_linkp = NULL; 8218 cmd->cmd_flags |= CFLAG_FINISHED; 8219 cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT; 8220 8221 mptsas_fma_check(mpt, cmd); 8222 8223 /* 8224 * only add scsi pkts that have completion routines to 8225 * the doneq. no intr cmds do not have callbacks. 8226 */ 8227 if (pkt && (pkt->pkt_comp)) { 8228 *mpt->m_donetail = cmd; 8229 mpt->m_donetail = &cmd->cmd_linkp; 8230 mpt->m_doneq_len++; 8231 } 8232 } 8233 8234 static mptsas_cmd_t * 8235 mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t) 8236 { 8237 mptsas_cmd_t *cmd; 8238 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 8239 8240 /* pop one off the done queue */ 8241 if ((cmd = item->doneq) != NULL) { 8242 /* if the queue is now empty fix the tail pointer */ 8243 NDBG31(("mptsas_doneq_thread_rm: cmd=0x%p", (void *)cmd)); 8244 if ((item->doneq = cmd->cmd_linkp) == NULL) { 8245 item->donetail = &item->doneq; 8246 } 8247 cmd->cmd_linkp = NULL; 8248 item->len--; 8249 } 8250 return (cmd); 8251 } 8252 8253 static void 8254 mptsas_doneq_empty(mptsas_t *mpt) 8255 { 8256 if (mpt->m_doneq && !mpt->m_in_callback) { 8257 mptsas_cmd_t *cmd, *next; 8258 struct scsi_pkt *pkt; 8259 8260 mpt->m_in_callback = 1; 8261 cmd = mpt->m_doneq; 8262 mpt->m_doneq = NULL; 8263 mpt->m_donetail = &mpt->m_doneq; 8264 mpt->m_doneq_len = 0; 8265 8266 mutex_exit(&mpt->m_mutex); 8267 /* 8268 * run the completion routines of all the 8269 * completed commands 8270 */ 8271 while (cmd != NULL) { 8272 next = cmd->cmd_linkp; 8273 cmd->cmd_linkp = NULL; 8274 /* run this command's completion routine */ 8275 cmd->cmd_flags |= CFLAG_COMPLETED; 8276 pkt = CMD2PKT(cmd); 8277 mptsas_pkt_comp(pkt, cmd); 8278 cmd = next; 8279 } 8280 mutex_enter(&mpt->m_mutex); 8281 mpt->m_in_callback = 0; 8282 } 8283 } 8284 8285 /* 8286 * These routines manipulate the target's queue of pending requests 8287 */ 8288 void 8289 mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd) 8290 { 8291 NDBG7(("mptsas_waitq_add: cmd=0x%p", (void *)cmd)); 8292 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8293 cmd->cmd_queued = TRUE; 8294 if (ptgt) 8295 ptgt->m_t_nwait++; 8296 if (cmd->cmd_pkt_flags & FLAG_HEAD) { 8297 if ((cmd->cmd_linkp = mpt->m_waitq) == NULL) { 8298 mpt->m_waitqtail = &cmd->cmd_linkp; 8299 } 8300 mpt->m_waitq = cmd; 8301 } else { 8302 cmd->cmd_linkp = NULL; 8303 *(mpt->m_waitqtail) = cmd; 8304 mpt->m_waitqtail = &cmd->cmd_linkp; 8305 } 8306 } 8307 8308 static mptsas_cmd_t * 8309 mptsas_waitq_rm(mptsas_t *mpt) 8310 { 8311 mptsas_cmd_t *cmd; 8312 mptsas_target_t *ptgt; 8313 NDBG7(("mptsas_waitq_rm")); 8314 8315 MPTSAS_WAITQ_RM(mpt, cmd); 8316 8317 NDBG7(("mptsas_waitq_rm: cmd=0x%p", (void *)cmd)); 8318 if (cmd) { 8319 ptgt = cmd->cmd_tgt_addr; 8320 if (ptgt) { 8321 ptgt->m_t_nwait--; 8322 ASSERT(ptgt->m_t_nwait >= 0); 8323 } 8324 } 8325 return (cmd); 8326 } 8327 8328 /* 8329 * remove specified cmd from the middle of the wait queue. 8330 */ 8331 static void 8332 mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd) 8333 { 8334 mptsas_cmd_t *prevp = mpt->m_waitq; 8335 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8336 8337 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8338 (void *)mpt, (void *)cmd)); 8339 if (ptgt) { 8340 ptgt->m_t_nwait--; 8341 ASSERT(ptgt->m_t_nwait >= 0); 8342 } 8343 8344 if (prevp == cmd) { 8345 if ((mpt->m_waitq = cmd->cmd_linkp) == NULL) 8346 mpt->m_waitqtail = &mpt->m_waitq; 8347 8348 cmd->cmd_linkp = NULL; 8349 cmd->cmd_queued = FALSE; 8350 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8351 (void *)mpt, (void *)cmd)); 8352 return; 8353 } 8354 8355 while (prevp != NULL) { 8356 if (prevp->cmd_linkp == cmd) { 8357 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL) 8358 mpt->m_waitqtail = &prevp->cmd_linkp; 8359 8360 cmd->cmd_linkp = NULL; 8361 cmd->cmd_queued = FALSE; 8362 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8363 (void *)mpt, (void *)cmd)); 8364 return; 8365 } 8366 prevp = prevp->cmd_linkp; 8367 } 8368 cmn_err(CE_PANIC, "mpt: mptsas_waitq_delete: queue botch"); 8369 } 8370 8371 static mptsas_cmd_t * 8372 mptsas_tx_waitq_rm(mptsas_t *mpt) 8373 { 8374 mptsas_cmd_t *cmd; 8375 NDBG7(("mptsas_tx_waitq_rm")); 8376 8377 MPTSAS_TX_WAITQ_RM(mpt, cmd); 8378 8379 NDBG7(("mptsas_tx_waitq_rm: cmd=0x%p", (void *)cmd)); 8380 8381 return (cmd); 8382 } 8383 8384 /* 8385 * remove specified cmd from the middle of the tx_waitq. 8386 */ 8387 static void 8388 mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd) 8389 { 8390 mptsas_cmd_t *prevp = mpt->m_tx_waitq; 8391 8392 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p", 8393 (void *)mpt, (void *)cmd)); 8394 8395 if (prevp == cmd) { 8396 if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) 8397 mpt->m_tx_waitqtail = &mpt->m_tx_waitq; 8398 8399 cmd->cmd_linkp = NULL; 8400 cmd->cmd_queued = FALSE; 8401 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p", 8402 (void *)mpt, (void *)cmd)); 8403 return; 8404 } 8405 8406 while (prevp != NULL) { 8407 if (prevp->cmd_linkp == cmd) { 8408 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL) 8409 mpt->m_tx_waitqtail = &prevp->cmd_linkp; 8410 8411 cmd->cmd_linkp = NULL; 8412 cmd->cmd_queued = FALSE; 8413 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p", 8414 (void *)mpt, (void *)cmd)); 8415 return; 8416 } 8417 prevp = prevp->cmd_linkp; 8418 } 8419 cmn_err(CE_PANIC, "mpt: mptsas_tx_waitq_delete: queue botch"); 8420 } 8421 8422 /* 8423 * device and bus reset handling 8424 * 8425 * Notes: 8426 * - RESET_ALL: reset the controller 8427 * - RESET_TARGET: reset the target specified in scsi_address 8428 */ 8429 static int 8430 mptsas_scsi_reset(struct scsi_address *ap, int level) 8431 { 8432 mptsas_t *mpt = ADDR2MPT(ap); 8433 int rval; 8434 mptsas_tgt_private_t *tgt_private; 8435 mptsas_target_t *ptgt = NULL; 8436 8437 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->tran_tgt_private; 8438 ptgt = tgt_private->t_private; 8439 if (ptgt == NULL) { 8440 return (FALSE); 8441 } 8442 NDBG22(("mptsas_scsi_reset: target=%d level=%d", ptgt->m_devhdl, 8443 level)); 8444 8445 mutex_enter(&mpt->m_mutex); 8446 /* 8447 * if we are not in panic set up a reset delay for this target 8448 */ 8449 if (!ddi_in_panic()) { 8450 mptsas_setup_bus_reset_delay(mpt); 8451 } else { 8452 drv_usecwait(mpt->m_scsi_reset_delay * 1000); 8453 } 8454 rval = mptsas_do_scsi_reset(mpt, ptgt->m_devhdl); 8455 mutex_exit(&mpt->m_mutex); 8456 8457 /* 8458 * The transport layer expect to only see TRUE and 8459 * FALSE. Therefore, we will adjust the return value 8460 * if mptsas_do_scsi_reset returns FAILED. 8461 */ 8462 if (rval == FAILED) 8463 rval = FALSE; 8464 return (rval); 8465 } 8466 8467 static int 8468 mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl) 8469 { 8470 int rval = FALSE; 8471 uint8_t config, disk; 8472 8473 ASSERT(mutex_owned(&mpt->m_mutex)); 8474 8475 if (mptsas_debug_resets) { 8476 mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d", 8477 devhdl); 8478 } 8479 8480 /* 8481 * Issue a Target Reset message to the target specified but not to a 8482 * disk making up a raid volume. Just look through the RAID config 8483 * Phys Disk list of DevHandles. If the target's DevHandle is in this 8484 * list, then don't reset this target. 8485 */ 8486 for (config = 0; config < mpt->m_num_raid_configs; config++) { 8487 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) { 8488 if (devhdl == mpt->m_raidconfig[config]. 8489 m_physdisk_devhdl[disk]) { 8490 return (TRUE); 8491 } 8492 } 8493 } 8494 8495 rval = mptsas_ioc_task_management(mpt, 8496 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, devhdl, 0, NULL, 0, 0); 8497 8498 mptsas_doneq_empty(mpt); 8499 return (rval); 8500 } 8501 8502 static int 8503 mptsas_scsi_reset_notify(struct scsi_address *ap, int flag, 8504 void (*callback)(caddr_t), caddr_t arg) 8505 { 8506 mptsas_t *mpt = ADDR2MPT(ap); 8507 8508 NDBG22(("mptsas_scsi_reset_notify: tgt=%d", ap->a_target)); 8509 8510 return (scsi_hba_reset_notify_setup(ap, flag, callback, arg, 8511 &mpt->m_mutex, &mpt->m_reset_notify_listf)); 8512 } 8513 8514 static int 8515 mptsas_get_name(struct scsi_device *sd, char *name, int len) 8516 { 8517 dev_info_t *lun_dip = NULL; 8518 8519 ASSERT(sd != NULL); 8520 ASSERT(name != NULL); 8521 lun_dip = sd->sd_dev; 8522 ASSERT(lun_dip != NULL); 8523 8524 if (mptsas_name_child(lun_dip, name, len) == DDI_SUCCESS) { 8525 return (1); 8526 } else { 8527 return (0); 8528 } 8529 } 8530 8531 static int 8532 mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len) 8533 { 8534 return (mptsas_get_name(sd, name, len)); 8535 } 8536 8537 void 8538 mptsas_set_throttle(mptsas_t *mpt, mptsas_target_t *ptgt, int what) 8539 { 8540 8541 NDBG25(("mptsas_set_throttle: throttle=%x", what)); 8542 8543 /* 8544 * if the bus is draining/quiesced, no changes to the throttles 8545 * are allowed. Not allowing change of throttles during draining 8546 * limits error recovery but will reduce draining time 8547 * 8548 * all throttles should have been set to HOLD_THROTTLE 8549 */ 8550 if (mpt->m_softstate & (MPTSAS_SS_QUIESCED | MPTSAS_SS_DRAINING)) { 8551 return; 8552 } 8553 8554 if (what == HOLD_THROTTLE) { 8555 ptgt->m_t_throttle = HOLD_THROTTLE; 8556 } else if (ptgt->m_reset_delay == 0) { 8557 ptgt->m_t_throttle = what; 8558 } 8559 } 8560 8561 /* 8562 * Clean up from a device reset. 8563 * For the case of target reset, this function clears the waitq of all 8564 * commands for a particular target. For the case of abort task set, this 8565 * function clears the waitq of all commonds for a particular target/lun. 8566 */ 8567 static void 8568 mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype) 8569 { 8570 mptsas_slots_t *slots = mpt->m_active; 8571 mptsas_cmd_t *cmd, *next_cmd; 8572 int slot; 8573 uchar_t reason; 8574 uint_t stat; 8575 hrtime_t timestamp; 8576 8577 NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun)); 8578 8579 timestamp = gethrtime(); 8580 8581 /* 8582 * Make sure the I/O Controller has flushed all cmds 8583 * that are associated with this target for a target reset 8584 * and target/lun for abort task set. 8585 * Account for TM requests, which use the last SMID. 8586 */ 8587 for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) { 8588 if ((cmd = slots->m_slot[slot]) == NULL) 8589 continue; 8590 reason = CMD_RESET; 8591 stat = STAT_DEV_RESET; 8592 switch (tasktype) { 8593 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 8594 if (Tgt(cmd) == target) { 8595 if (cmd->cmd_active_expiration <= timestamp) { 8596 /* 8597 * When timeout requested, propagate 8598 * proper reason and statistics to 8599 * target drivers. 8600 */ 8601 reason = CMD_TIMEOUT; 8602 stat |= STAT_TIMEOUT; 8603 } 8604 NDBG25(("mptsas_flush_target discovered non-" 8605 "NULL cmd in slot %d, tasktype 0x%x", slot, 8606 tasktype)); 8607 mptsas_dump_cmd(mpt, cmd); 8608 mptsas_remove_cmd(mpt, cmd); 8609 mptsas_set_pkt_reason(mpt, cmd, reason, stat); 8610 mptsas_doneq_add(mpt, cmd); 8611 } 8612 break; 8613 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 8614 reason = CMD_ABORTED; 8615 stat = STAT_ABORTED; 8616 /*FALLTHROUGH*/ 8617 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 8618 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 8619 8620 NDBG25(("mptsas_flush_target discovered non-" 8621 "NULL cmd in slot %d, tasktype 0x%x", slot, 8622 tasktype)); 8623 mptsas_dump_cmd(mpt, cmd); 8624 mptsas_remove_cmd(mpt, cmd); 8625 mptsas_set_pkt_reason(mpt, cmd, reason, 8626 stat); 8627 mptsas_doneq_add(mpt, cmd); 8628 } 8629 break; 8630 default: 8631 break; 8632 } 8633 } 8634 8635 /* 8636 * Flush the waitq and tx_waitq of this target's cmds 8637 */ 8638 cmd = mpt->m_waitq; 8639 8640 reason = CMD_RESET; 8641 stat = STAT_DEV_RESET; 8642 8643 switch (tasktype) { 8644 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 8645 while (cmd != NULL) { 8646 next_cmd = cmd->cmd_linkp; 8647 if (Tgt(cmd) == target) { 8648 mptsas_waitq_delete(mpt, cmd); 8649 mptsas_set_pkt_reason(mpt, cmd, 8650 reason, stat); 8651 mptsas_doneq_add(mpt, cmd); 8652 } 8653 cmd = next_cmd; 8654 } 8655 mutex_enter(&mpt->m_tx_waitq_mutex); 8656 cmd = mpt->m_tx_waitq; 8657 while (cmd != NULL) { 8658 next_cmd = cmd->cmd_linkp; 8659 if (Tgt(cmd) == target) { 8660 mptsas_tx_waitq_delete(mpt, cmd); 8661 mutex_exit(&mpt->m_tx_waitq_mutex); 8662 mptsas_set_pkt_reason(mpt, cmd, 8663 reason, stat); 8664 mptsas_doneq_add(mpt, cmd); 8665 mutex_enter(&mpt->m_tx_waitq_mutex); 8666 } 8667 cmd = next_cmd; 8668 } 8669 mutex_exit(&mpt->m_tx_waitq_mutex); 8670 break; 8671 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 8672 reason = CMD_ABORTED; 8673 stat = STAT_ABORTED; 8674 /*FALLTHROUGH*/ 8675 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 8676 while (cmd != NULL) { 8677 next_cmd = cmd->cmd_linkp; 8678 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 8679 mptsas_waitq_delete(mpt, cmd); 8680 mptsas_set_pkt_reason(mpt, cmd, 8681 reason, stat); 8682 mptsas_doneq_add(mpt, cmd); 8683 } 8684 cmd = next_cmd; 8685 } 8686 mutex_enter(&mpt->m_tx_waitq_mutex); 8687 cmd = mpt->m_tx_waitq; 8688 while (cmd != NULL) { 8689 next_cmd = cmd->cmd_linkp; 8690 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 8691 mptsas_tx_waitq_delete(mpt, cmd); 8692 mutex_exit(&mpt->m_tx_waitq_mutex); 8693 mptsas_set_pkt_reason(mpt, cmd, 8694 reason, stat); 8695 mptsas_doneq_add(mpt, cmd); 8696 mutex_enter(&mpt->m_tx_waitq_mutex); 8697 } 8698 cmd = next_cmd; 8699 } 8700 mutex_exit(&mpt->m_tx_waitq_mutex); 8701 break; 8702 default: 8703 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.", 8704 tasktype); 8705 break; 8706 } 8707 } 8708 8709 /* 8710 * Clean up hba state, abort all outstanding command and commands in waitq 8711 * reset timeout of all targets. 8712 */ 8713 static void 8714 mptsas_flush_hba(mptsas_t *mpt) 8715 { 8716 mptsas_slots_t *slots = mpt->m_active; 8717 mptsas_cmd_t *cmd; 8718 int slot; 8719 8720 NDBG25(("mptsas_flush_hba")); 8721 8722 /* 8723 * The I/O Controller should have already sent back 8724 * all commands via the scsi I/O reply frame. Make 8725 * sure all commands have been flushed. 8726 * Account for TM request, which use the last SMID. 8727 */ 8728 for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) { 8729 if ((cmd = slots->m_slot[slot]) == NULL) 8730 continue; 8731 8732 if (cmd->cmd_flags & CFLAG_CMDIOC) { 8733 /* 8734 * Need to make sure to tell everyone that might be 8735 * waiting on this command that it's going to fail. If 8736 * we get here, this command will never timeout because 8737 * the active command table is going to be re-allocated, 8738 * so there will be nothing to check against a time out. 8739 * Instead, mark the command as failed due to reset. 8740 */ 8741 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, 8742 STAT_BUS_RESET); 8743 if ((cmd->cmd_flags & 8744 (CFLAG_PASSTHRU | CFLAG_CONFIG | CFLAG_FW_DIAG))) { 8745 cmd->cmd_flags |= CFLAG_FINISHED; 8746 cv_broadcast(&mpt->m_passthru_cv); 8747 cv_broadcast(&mpt->m_config_cv); 8748 cv_broadcast(&mpt->m_fw_diag_cv); 8749 } 8750 continue; 8751 } 8752 8753 NDBG25(("mptsas_flush_hba discovered non-NULL cmd in slot %d", 8754 slot)); 8755 mptsas_dump_cmd(mpt, cmd); 8756 8757 mptsas_remove_cmd(mpt, cmd); 8758 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 8759 mptsas_doneq_add(mpt, cmd); 8760 } 8761 8762 /* 8763 * Flush the waitq. 8764 */ 8765 while ((cmd = mptsas_waitq_rm(mpt)) != NULL) { 8766 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 8767 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 8768 (cmd->cmd_flags & CFLAG_CONFIG) || 8769 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 8770 cmd->cmd_flags |= CFLAG_FINISHED; 8771 cv_broadcast(&mpt->m_passthru_cv); 8772 cv_broadcast(&mpt->m_config_cv); 8773 cv_broadcast(&mpt->m_fw_diag_cv); 8774 } else { 8775 mptsas_doneq_add(mpt, cmd); 8776 } 8777 } 8778 8779 /* 8780 * Flush the tx_waitq 8781 */ 8782 mutex_enter(&mpt->m_tx_waitq_mutex); 8783 while ((cmd = mptsas_tx_waitq_rm(mpt)) != NULL) { 8784 mutex_exit(&mpt->m_tx_waitq_mutex); 8785 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 8786 mptsas_doneq_add(mpt, cmd); 8787 mutex_enter(&mpt->m_tx_waitq_mutex); 8788 } 8789 mutex_exit(&mpt->m_tx_waitq_mutex); 8790 8791 /* 8792 * Drain the taskqs prior to reallocating resources. 8793 */ 8794 mutex_exit(&mpt->m_mutex); 8795 ddi_taskq_wait(mpt->m_event_taskq); 8796 ddi_taskq_wait(mpt->m_dr_taskq); 8797 mutex_enter(&mpt->m_mutex); 8798 } 8799 8800 /* 8801 * set pkt_reason and OR in pkt_statistics flag 8802 */ 8803 static void 8804 mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, uchar_t reason, 8805 uint_t stat) 8806 { 8807 #ifndef __lock_lint 8808 _NOTE(ARGUNUSED(mpt)) 8809 #endif 8810 8811 NDBG25(("mptsas_set_pkt_reason: cmd=0x%p reason=%x stat=%x", 8812 (void *)cmd, reason, stat)); 8813 8814 if (cmd) { 8815 if (cmd->cmd_pkt->pkt_reason == CMD_CMPLT) { 8816 cmd->cmd_pkt->pkt_reason = reason; 8817 } 8818 cmd->cmd_pkt->pkt_statistics |= stat; 8819 } 8820 } 8821 8822 static void 8823 mptsas_start_watch_reset_delay() 8824 { 8825 NDBG22(("mptsas_start_watch_reset_delay")); 8826 8827 mutex_enter(&mptsas_global_mutex); 8828 if (mptsas_reset_watch == NULL && mptsas_timeouts_enabled) { 8829 mptsas_reset_watch = timeout(mptsas_watch_reset_delay, NULL, 8830 drv_usectohz((clock_t) 8831 MPTSAS_WATCH_RESET_DELAY_TICK * 1000)); 8832 ASSERT(mptsas_reset_watch != NULL); 8833 } 8834 mutex_exit(&mptsas_global_mutex); 8835 } 8836 8837 static void 8838 mptsas_setup_bus_reset_delay(mptsas_t *mpt) 8839 { 8840 mptsas_target_t *ptgt = NULL; 8841 8842 ASSERT(MUTEX_HELD(&mpt->m_mutex)); 8843 8844 NDBG22(("mptsas_setup_bus_reset_delay")); 8845 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 8846 ptgt = refhash_next(mpt->m_targets, ptgt)) { 8847 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 8848 ptgt->m_reset_delay = mpt->m_scsi_reset_delay; 8849 } 8850 8851 mptsas_start_watch_reset_delay(); 8852 } 8853 8854 /* 8855 * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every 8856 * mpt instance for active reset delays 8857 */ 8858 static void 8859 mptsas_watch_reset_delay(void *arg) 8860 { 8861 #ifndef __lock_lint 8862 _NOTE(ARGUNUSED(arg)) 8863 #endif 8864 8865 mptsas_t *mpt; 8866 int not_done = 0; 8867 8868 NDBG22(("mptsas_watch_reset_delay")); 8869 8870 mutex_enter(&mptsas_global_mutex); 8871 mptsas_reset_watch = 0; 8872 mutex_exit(&mptsas_global_mutex); 8873 rw_enter(&mptsas_global_rwlock, RW_READER); 8874 for (mpt = mptsas_head; mpt != NULL; mpt = mpt->m_next) { 8875 if (mpt->m_tran == 0) { 8876 continue; 8877 } 8878 mutex_enter(&mpt->m_mutex); 8879 not_done += mptsas_watch_reset_delay_subr(mpt); 8880 mutex_exit(&mpt->m_mutex); 8881 } 8882 rw_exit(&mptsas_global_rwlock); 8883 8884 if (not_done) { 8885 mptsas_start_watch_reset_delay(); 8886 } 8887 } 8888 8889 static int 8890 mptsas_watch_reset_delay_subr(mptsas_t *mpt) 8891 { 8892 int done = 0; 8893 int restart = 0; 8894 mptsas_target_t *ptgt = NULL; 8895 8896 NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt)); 8897 8898 ASSERT(mutex_owned(&mpt->m_mutex)); 8899 8900 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 8901 ptgt = refhash_next(mpt->m_targets, ptgt)) { 8902 if (ptgt->m_reset_delay != 0) { 8903 ptgt->m_reset_delay -= 8904 MPTSAS_WATCH_RESET_DELAY_TICK; 8905 if (ptgt->m_reset_delay <= 0) { 8906 ptgt->m_reset_delay = 0; 8907 mptsas_set_throttle(mpt, ptgt, 8908 MAX_THROTTLE); 8909 restart++; 8910 } else { 8911 done = -1; 8912 } 8913 } 8914 } 8915 8916 if (restart > 0) { 8917 mptsas_restart_hba(mpt); 8918 } 8919 return (done); 8920 } 8921 8922 #ifdef MPTSAS_TEST 8923 static void 8924 mptsas_test_reset(mptsas_t *mpt, int target) 8925 { 8926 mptsas_target_t *ptgt = NULL; 8927 8928 if (mptsas_rtest == target) { 8929 if (mptsas_do_scsi_reset(mpt, target) == TRUE) { 8930 mptsas_rtest = -1; 8931 } 8932 if (mptsas_rtest == -1) { 8933 NDBG22(("mptsas_test_reset success")); 8934 } 8935 } 8936 } 8937 #endif 8938 8939 /* 8940 * abort handling: 8941 * 8942 * Notes: 8943 * - if pkt is not NULL, abort just that command 8944 * - if pkt is NULL, abort all outstanding commands for target 8945 */ 8946 static int 8947 mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt) 8948 { 8949 mptsas_t *mpt = ADDR2MPT(ap); 8950 int rval; 8951 mptsas_tgt_private_t *tgt_private; 8952 int target, lun; 8953 8954 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran-> 8955 tran_tgt_private; 8956 ASSERT(tgt_private != NULL); 8957 target = tgt_private->t_private->m_devhdl; 8958 lun = tgt_private->t_lun; 8959 8960 NDBG23(("mptsas_scsi_abort: target=%d.%d", target, lun)); 8961 8962 mutex_enter(&mpt->m_mutex); 8963 rval = mptsas_do_scsi_abort(mpt, target, lun, pkt); 8964 mutex_exit(&mpt->m_mutex); 8965 return (rval); 8966 } 8967 8968 static int 8969 mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, struct scsi_pkt *pkt) 8970 { 8971 mptsas_cmd_t *sp = NULL; 8972 mptsas_slots_t *slots = mpt->m_active; 8973 int rval = FALSE; 8974 8975 ASSERT(mutex_owned(&mpt->m_mutex)); 8976 8977 /* 8978 * Abort the command pkt on the target/lun in ap. If pkt is 8979 * NULL, abort all outstanding commands on that target/lun. 8980 * If you can abort them, return 1, else return 0. 8981 * Each packet that's aborted should be sent back to the target 8982 * driver through the callback routine, with pkt_reason set to 8983 * CMD_ABORTED. 8984 * 8985 * abort cmd pkt on HBA hardware; clean out of outstanding 8986 * command lists, etc. 8987 */ 8988 if (pkt != NULL) { 8989 /* abort the specified packet */ 8990 sp = PKT2CMD(pkt); 8991 8992 if (sp->cmd_queued) { 8993 NDBG23(("mptsas_do_scsi_abort: queued sp=0x%p aborted", 8994 (void *)sp)); 8995 mptsas_waitq_delete(mpt, sp); 8996 mptsas_set_pkt_reason(mpt, sp, CMD_ABORTED, 8997 STAT_ABORTED); 8998 mptsas_doneq_add(mpt, sp); 8999 rval = TRUE; 9000 goto done; 9001 } 9002 9003 /* 9004 * Have mpt firmware abort this command 9005 */ 9006 9007 if (slots->m_slot[sp->cmd_slot] != NULL) { 9008 rval = mptsas_ioc_task_management(mpt, 9009 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, target, 9010 lun, NULL, 0, 0); 9011 9012 /* 9013 * The transport layer expects only TRUE and FALSE. 9014 * Therefore, if mptsas_ioc_task_management returns 9015 * FAILED we will return FALSE. 9016 */ 9017 if (rval == FAILED) 9018 rval = FALSE; 9019 goto done; 9020 } 9021 } 9022 9023 /* 9024 * If pkt is NULL then abort task set 9025 */ 9026 rval = mptsas_ioc_task_management(mpt, 9027 MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, target, lun, NULL, 0, 0); 9028 9029 /* 9030 * The transport layer expects only TRUE and FALSE. 9031 * Therefore, if mptsas_ioc_task_management returns 9032 * FAILED we will return FALSE. 9033 */ 9034 if (rval == FAILED) 9035 rval = FALSE; 9036 9037 #ifdef MPTSAS_TEST 9038 if (rval && mptsas_test_stop) { 9039 debug_enter("mptsas_do_scsi_abort"); 9040 } 9041 #endif 9042 9043 done: 9044 mptsas_doneq_empty(mpt); 9045 return (rval); 9046 } 9047 9048 /* 9049 * capability handling: 9050 * (*tran_getcap). Get the capability named, and return its value. 9051 */ 9052 static int 9053 mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly) 9054 { 9055 mptsas_t *mpt = ADDR2MPT(ap); 9056 int ckey; 9057 int rval = FALSE; 9058 9059 NDBG24(("mptsas_scsi_getcap: target=%d, cap=%s tgtonly=%x", 9060 ap->a_target, cap, tgtonly)); 9061 9062 mutex_enter(&mpt->m_mutex); 9063 9064 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) { 9065 mutex_exit(&mpt->m_mutex); 9066 return (UNDEFINED); 9067 } 9068 9069 switch (ckey) { 9070 case SCSI_CAP_DMA_MAX: 9071 rval = (int)mpt->m_msg_dma_attr.dma_attr_maxxfer; 9072 break; 9073 case SCSI_CAP_ARQ: 9074 rval = TRUE; 9075 break; 9076 case SCSI_CAP_MSG_OUT: 9077 case SCSI_CAP_PARITY: 9078 case SCSI_CAP_UNTAGGED_QING: 9079 rval = TRUE; 9080 break; 9081 case SCSI_CAP_TAGGED_QING: 9082 rval = TRUE; 9083 break; 9084 case SCSI_CAP_RESET_NOTIFICATION: 9085 rval = TRUE; 9086 break; 9087 case SCSI_CAP_LINKED_CMDS: 9088 rval = FALSE; 9089 break; 9090 case SCSI_CAP_QFULL_RETRIES: 9091 rval = ((mptsas_tgt_private_t *)(ap->a_hba_tran-> 9092 tran_tgt_private))->t_private->m_qfull_retries; 9093 break; 9094 case SCSI_CAP_QFULL_RETRY_INTERVAL: 9095 rval = drv_hztousec(((mptsas_tgt_private_t *) 9096 (ap->a_hba_tran->tran_tgt_private))-> 9097 t_private->m_qfull_retry_interval) / 1000; 9098 break; 9099 case SCSI_CAP_CDB_LEN: 9100 rval = CDB_GROUP4; 9101 break; 9102 case SCSI_CAP_INTERCONNECT_TYPE: 9103 rval = INTERCONNECT_SAS; 9104 break; 9105 case SCSI_CAP_TRAN_LAYER_RETRIES: 9106 if (mpt->m_ioc_capabilities & 9107 MPI2_IOCFACTS_CAPABILITY_TLR) 9108 rval = TRUE; 9109 else 9110 rval = FALSE; 9111 break; 9112 default: 9113 rval = UNDEFINED; 9114 break; 9115 } 9116 9117 NDBG24(("mptsas_scsi_getcap: %s, rval=%x", cap, rval)); 9118 9119 mutex_exit(&mpt->m_mutex); 9120 return (rval); 9121 } 9122 9123 /* 9124 * (*tran_setcap). Set the capability named to the value given. 9125 */ 9126 static int 9127 mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, int tgtonly) 9128 { 9129 mptsas_t *mpt = ADDR2MPT(ap); 9130 int ckey; 9131 int rval = FALSE; 9132 9133 NDBG24(("mptsas_scsi_setcap: target=%d, cap=%s value=%x tgtonly=%x", 9134 ap->a_target, cap, value, tgtonly)); 9135 9136 if (!tgtonly) { 9137 return (rval); 9138 } 9139 9140 mutex_enter(&mpt->m_mutex); 9141 9142 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) { 9143 mutex_exit(&mpt->m_mutex); 9144 return (UNDEFINED); 9145 } 9146 9147 switch (ckey) { 9148 case SCSI_CAP_DMA_MAX: 9149 case SCSI_CAP_MSG_OUT: 9150 case SCSI_CAP_PARITY: 9151 case SCSI_CAP_INITIATOR_ID: 9152 case SCSI_CAP_LINKED_CMDS: 9153 case SCSI_CAP_UNTAGGED_QING: 9154 case SCSI_CAP_RESET_NOTIFICATION: 9155 /* 9156 * None of these are settable via 9157 * the capability interface. 9158 */ 9159 break; 9160 case SCSI_CAP_ARQ: 9161 /* 9162 * We cannot turn off arq so return false if asked to 9163 */ 9164 if (value) { 9165 rval = TRUE; 9166 } else { 9167 rval = FALSE; 9168 } 9169 break; 9170 case SCSI_CAP_TAGGED_QING: 9171 mptsas_set_throttle(mpt, ((mptsas_tgt_private_t *) 9172 (ap->a_hba_tran->tran_tgt_private))->t_private, 9173 MAX_THROTTLE); 9174 rval = TRUE; 9175 break; 9176 case SCSI_CAP_QFULL_RETRIES: 9177 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))-> 9178 t_private->m_qfull_retries = (uchar_t)value; 9179 rval = TRUE; 9180 break; 9181 case SCSI_CAP_QFULL_RETRY_INTERVAL: 9182 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))-> 9183 t_private->m_qfull_retry_interval = 9184 drv_usectohz(value * 1000); 9185 rval = TRUE; 9186 break; 9187 default: 9188 rval = UNDEFINED; 9189 break; 9190 } 9191 mutex_exit(&mpt->m_mutex); 9192 return (rval); 9193 } 9194 9195 /* 9196 * Utility routine for mptsas_ifsetcap/ifgetcap 9197 */ 9198 /*ARGSUSED*/ 9199 static int 9200 mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp) 9201 { 9202 NDBG24(("mptsas_scsi_capchk: cap=%s", cap)); 9203 9204 if (!cap) 9205 return (FALSE); 9206 9207 *cidxp = scsi_hba_lookup_capstr(cap); 9208 return (TRUE); 9209 } 9210 9211 static int 9212 mptsas_alloc_active_slots(mptsas_t *mpt, int flag) 9213 { 9214 mptsas_slots_t *old_active = mpt->m_active; 9215 mptsas_slots_t *new_active; 9216 size_t size; 9217 9218 /* 9219 * if there are active commands, then we cannot 9220 * change size of active slots array. 9221 */ 9222 ASSERT(mpt->m_ncmds == 0); 9223 9224 size = MPTSAS_SLOTS_SIZE(mpt); 9225 new_active = kmem_zalloc(size, flag); 9226 if (new_active == NULL) { 9227 NDBG1(("new active alloc failed")); 9228 return (-1); 9229 } 9230 /* 9231 * Since SMID 0 is reserved and the TM slot is reserved, the 9232 * number of slots that can be used at any one time is 9233 * m_max_requests - 2. 9234 */ 9235 new_active->m_n_normal = (mpt->m_max_requests - 2); 9236 new_active->m_size = size; 9237 new_active->m_rotor = 1; 9238 if (old_active) 9239 mptsas_free_active_slots(mpt); 9240 mpt->m_active = new_active; 9241 9242 return (0); 9243 } 9244 9245 static void 9246 mptsas_free_active_slots(mptsas_t *mpt) 9247 { 9248 mptsas_slots_t *active = mpt->m_active; 9249 size_t size; 9250 9251 if (active == NULL) 9252 return; 9253 size = active->m_size; 9254 kmem_free(active, size); 9255 mpt->m_active = NULL; 9256 } 9257 9258 /* 9259 * Error logging, printing, and debug print routines. 9260 */ 9261 static char *mptsas_label = "mpt_sas"; 9262 9263 /*PRINTFLIKE3*/ 9264 void 9265 mptsas_log(mptsas_t *mpt, int level, char *fmt, ...) 9266 { 9267 dev_info_t *dev; 9268 va_list ap; 9269 9270 if (mpt) { 9271 dev = mpt->m_dip; 9272 } else { 9273 dev = 0; 9274 } 9275 9276 mutex_enter(&mptsas_log_mutex); 9277 9278 va_start(ap, fmt); 9279 (void) vsprintf(mptsas_log_buf, fmt, ap); 9280 va_end(ap); 9281 9282 if (level == CE_CONT) { 9283 scsi_log(dev, mptsas_label, level, "%s\n", mptsas_log_buf); 9284 } else { 9285 scsi_log(dev, mptsas_label, level, "%s", mptsas_log_buf); 9286 } 9287 9288 mutex_exit(&mptsas_log_mutex); 9289 } 9290 9291 #ifdef MPTSAS_DEBUG 9292 /*PRINTFLIKE1*/ 9293 void 9294 mptsas_printf(char *fmt, ...) 9295 { 9296 dev_info_t *dev = 0; 9297 va_list ap; 9298 9299 mutex_enter(&mptsas_log_mutex); 9300 9301 va_start(ap, fmt); 9302 (void) vsprintf(mptsas_log_buf, fmt, ap); 9303 va_end(ap); 9304 9305 #ifdef PROM_PRINTF 9306 prom_printf("%s:\t%s\n", mptsas_label, mptsas_log_buf); 9307 #else 9308 scsi_log(dev, mptsas_label, SCSI_DEBUG, "%s\n", mptsas_log_buf); 9309 #endif 9310 mutex_exit(&mptsas_log_mutex); 9311 } 9312 #endif 9313 9314 /* 9315 * timeout handling 9316 */ 9317 static void 9318 mptsas_watch(void *arg) 9319 { 9320 #ifndef __lock_lint 9321 _NOTE(ARGUNUSED(arg)) 9322 #endif 9323 9324 mptsas_t *mpt; 9325 uint32_t doorbell; 9326 9327 NDBG30(("mptsas_watch")); 9328 9329 rw_enter(&mptsas_global_rwlock, RW_READER); 9330 for (mpt = mptsas_head; mpt != (mptsas_t *)NULL; mpt = mpt->m_next) { 9331 9332 mutex_enter(&mpt->m_mutex); 9333 9334 /* Skip device if not powered on */ 9335 if (mpt->m_options & MPTSAS_OPT_PM) { 9336 if (mpt->m_power_level == PM_LEVEL_D0) { 9337 (void) pm_busy_component(mpt->m_dip, 0); 9338 mpt->m_busy = 1; 9339 } else { 9340 mutex_exit(&mpt->m_mutex); 9341 continue; 9342 } 9343 } 9344 9345 /* 9346 * Check if controller is in a FAULT state. If so, reset it. 9347 */ 9348 doorbell = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell); 9349 if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { 9350 doorbell &= MPI2_DOORBELL_DATA_MASK; 9351 mptsas_log(mpt, CE_WARN, "MPT Firmware Fault, " 9352 "code: %04x", doorbell); 9353 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 9354 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 9355 mptsas_log(mpt, CE_WARN, "Reset failed" 9356 "after fault was detected"); 9357 } 9358 } 9359 9360 /* 9361 * For now, always call mptsas_watchsubr. 9362 */ 9363 mptsas_watchsubr(mpt); 9364 9365 if (mpt->m_options & MPTSAS_OPT_PM) { 9366 mpt->m_busy = 0; 9367 (void) pm_idle_component(mpt->m_dip, 0); 9368 } 9369 9370 mutex_exit(&mpt->m_mutex); 9371 } 9372 rw_exit(&mptsas_global_rwlock); 9373 9374 mutex_enter(&mptsas_global_mutex); 9375 if (mptsas_timeouts_enabled) 9376 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick); 9377 mutex_exit(&mptsas_global_mutex); 9378 } 9379 9380 static void 9381 mptsas_watchsubr(mptsas_t *mpt) 9382 { 9383 int i; 9384 mptsas_cmd_t *cmd; 9385 mptsas_target_t *ptgt = NULL; 9386 hrtime_t timestamp = gethrtime(); 9387 9388 ASSERT(MUTEX_HELD(&mpt->m_mutex)); 9389 9390 NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt)); 9391 9392 #ifdef MPTSAS_TEST 9393 if (mptsas_enable_untagged) { 9394 mptsas_test_untagged++; 9395 } 9396 #endif 9397 9398 /* 9399 * Check for commands stuck in active slot 9400 * Account for TM requests, which use the last SMID. 9401 */ 9402 for (i = 0; i <= mpt->m_active->m_n_normal; i++) { 9403 if ((cmd = mpt->m_active->m_slot[i]) != NULL) { 9404 if (cmd->cmd_active_expiration <= timestamp) { 9405 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 9406 /* 9407 * There seems to be a command stuck 9408 * in the active slot. Drain throttle. 9409 */ 9410 mptsas_set_throttle(mpt, 9411 cmd->cmd_tgt_addr, 9412 DRAIN_THROTTLE); 9413 } else if (cmd->cmd_flags & 9414 (CFLAG_PASSTHRU | CFLAG_CONFIG | 9415 CFLAG_FW_DIAG)) { 9416 /* 9417 * passthrough command timeout 9418 */ 9419 cmd->cmd_flags |= (CFLAG_FINISHED | 9420 CFLAG_TIMEOUT); 9421 cv_broadcast(&mpt->m_passthru_cv); 9422 cv_broadcast(&mpt->m_config_cv); 9423 cv_broadcast(&mpt->m_fw_diag_cv); 9424 } 9425 } 9426 } 9427 } 9428 9429 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 9430 ptgt = refhash_next(mpt->m_targets, ptgt)) { 9431 /* 9432 * If we were draining due to a qfull condition, 9433 * go back to full throttle. 9434 */ 9435 if ((ptgt->m_t_throttle < MAX_THROTTLE) && 9436 (ptgt->m_t_throttle > HOLD_THROTTLE) && 9437 (ptgt->m_t_ncmds < ptgt->m_t_throttle)) { 9438 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 9439 mptsas_restart_hba(mpt); 9440 } 9441 9442 cmd = TAILQ_LAST(&ptgt->m_active_cmdq, mptsas_active_cmdq); 9443 if (cmd == NULL) 9444 continue; 9445 9446 if (cmd->cmd_active_expiration <= timestamp) { 9447 /* 9448 * Earliest command timeout expired. Drain throttle. 9449 */ 9450 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 9451 9452 /* 9453 * Check for remaining commands. 9454 */ 9455 cmd = TAILQ_FIRST(&ptgt->m_active_cmdq); 9456 if (cmd->cmd_active_expiration > timestamp) { 9457 /* 9458 * Wait for remaining commands to complete or 9459 * time out. 9460 */ 9461 NDBG23(("command timed out, pending drain")); 9462 continue; 9463 } 9464 9465 /* 9466 * All command timeouts expired. 9467 */ 9468 mptsas_log(mpt, CE_NOTE, "Timeout of %d seconds " 9469 "expired with %d commands on target %d lun %d.", 9470 cmd->cmd_pkt->pkt_time, ptgt->m_t_ncmds, 9471 ptgt->m_devhdl, Lun(cmd)); 9472 9473 mptsas_cmd_timeout(mpt, ptgt); 9474 } else if (cmd->cmd_active_expiration <= 9475 timestamp + (hrtime_t)mptsas_scsi_watchdog_tick * NANOSEC) { 9476 NDBG23(("pending timeout")); 9477 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 9478 } 9479 } 9480 } 9481 9482 /* 9483 * timeout recovery 9484 */ 9485 static void 9486 mptsas_cmd_timeout(mptsas_t *mpt, mptsas_target_t *ptgt) 9487 { 9488 uint16_t devhdl; 9489 uint64_t sas_wwn; 9490 uint8_t phy; 9491 char wwn_str[MPTSAS_WWN_STRLEN]; 9492 9493 devhdl = ptgt->m_devhdl; 9494 sas_wwn = ptgt->m_addr.mta_wwn; 9495 phy = ptgt->m_phynum; 9496 if (sas_wwn == 0) { 9497 (void) sprintf(wwn_str, "p%x", phy); 9498 } else { 9499 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 9500 } 9501 9502 NDBG29(("mptsas_cmd_timeout: target=%d", devhdl)); 9503 mptsas_log(mpt, CE_WARN, "Disconnected command timeout for " 9504 "target %d %s.", devhdl, wwn_str); 9505 9506 /* 9507 * Abort all outstanding commands on the device. 9508 */ 9509 NDBG29(("mptsas_cmd_timeout: device reset")); 9510 if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) { 9511 mptsas_log(mpt, CE_WARN, "Target %d reset for command timeout " 9512 "recovery failed!", devhdl); 9513 } 9514 } 9515 9516 /* 9517 * Device / Hotplug control 9518 */ 9519 static int 9520 mptsas_scsi_quiesce(dev_info_t *dip) 9521 { 9522 mptsas_t *mpt; 9523 scsi_hba_tran_t *tran; 9524 9525 tran = ddi_get_driver_private(dip); 9526 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL) 9527 return (-1); 9528 9529 return (mptsas_quiesce_bus(mpt)); 9530 } 9531 9532 static int 9533 mptsas_scsi_unquiesce(dev_info_t *dip) 9534 { 9535 mptsas_t *mpt; 9536 scsi_hba_tran_t *tran; 9537 9538 tran = ddi_get_driver_private(dip); 9539 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL) 9540 return (-1); 9541 9542 return (mptsas_unquiesce_bus(mpt)); 9543 } 9544 9545 static int 9546 mptsas_quiesce_bus(mptsas_t *mpt) 9547 { 9548 mptsas_target_t *ptgt = NULL; 9549 9550 NDBG28(("mptsas_quiesce_bus")); 9551 mutex_enter(&mpt->m_mutex); 9552 9553 /* Set all the throttles to zero */ 9554 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 9555 ptgt = refhash_next(mpt->m_targets, ptgt)) { 9556 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 9557 } 9558 9559 /* If there are any outstanding commands in the queue */ 9560 if (mpt->m_ncmds) { 9561 mpt->m_softstate |= MPTSAS_SS_DRAINING; 9562 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain, 9563 mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000))); 9564 if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) { 9565 /* 9566 * Quiesce has been interrupted 9567 */ 9568 mpt->m_softstate &= ~MPTSAS_SS_DRAINING; 9569 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 9570 ptgt = refhash_next(mpt->m_targets, ptgt)) { 9571 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 9572 } 9573 mptsas_restart_hba(mpt); 9574 if (mpt->m_quiesce_timeid != 0) { 9575 timeout_id_t tid = mpt->m_quiesce_timeid; 9576 mpt->m_quiesce_timeid = 0; 9577 mutex_exit(&mpt->m_mutex); 9578 (void) untimeout(tid); 9579 return (-1); 9580 } 9581 mutex_exit(&mpt->m_mutex); 9582 return (-1); 9583 } else { 9584 /* Bus has been quiesced */ 9585 ASSERT(mpt->m_quiesce_timeid == 0); 9586 mpt->m_softstate &= ~MPTSAS_SS_DRAINING; 9587 mpt->m_softstate |= MPTSAS_SS_QUIESCED; 9588 mutex_exit(&mpt->m_mutex); 9589 return (0); 9590 } 9591 } 9592 /* Bus was not busy - QUIESCED */ 9593 mutex_exit(&mpt->m_mutex); 9594 9595 return (0); 9596 } 9597 9598 static int 9599 mptsas_unquiesce_bus(mptsas_t *mpt) 9600 { 9601 mptsas_target_t *ptgt = NULL; 9602 9603 NDBG28(("mptsas_unquiesce_bus")); 9604 mutex_enter(&mpt->m_mutex); 9605 mpt->m_softstate &= ~MPTSAS_SS_QUIESCED; 9606 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 9607 ptgt = refhash_next(mpt->m_targets, ptgt)) { 9608 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 9609 } 9610 mptsas_restart_hba(mpt); 9611 mutex_exit(&mpt->m_mutex); 9612 return (0); 9613 } 9614 9615 static void 9616 mptsas_ncmds_checkdrain(void *arg) 9617 { 9618 mptsas_t *mpt = arg; 9619 mptsas_target_t *ptgt = NULL; 9620 9621 mutex_enter(&mpt->m_mutex); 9622 if (mpt->m_softstate & MPTSAS_SS_DRAINING) { 9623 mpt->m_quiesce_timeid = 0; 9624 if (mpt->m_ncmds == 0) { 9625 /* Command queue has been drained */ 9626 cv_signal(&mpt->m_cv); 9627 } else { 9628 /* 9629 * The throttle may have been reset because 9630 * of a SCSI bus reset 9631 */ 9632 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 9633 ptgt = refhash_next(mpt->m_targets, ptgt)) { 9634 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 9635 } 9636 9637 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain, 9638 mpt, (MPTSAS_QUIESCE_TIMEOUT * 9639 drv_usectohz(1000000))); 9640 } 9641 } 9642 mutex_exit(&mpt->m_mutex); 9643 } 9644 9645 /*ARGSUSED*/ 9646 static void 9647 mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 9648 { 9649 int i; 9650 uint8_t *cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp; 9651 char buf[128]; 9652 9653 buf[0] = '\0'; 9654 NDBG25(("?Cmd (0x%p) dump for Target %d Lun %d:\n", (void *)cmd, 9655 Tgt(cmd), Lun(cmd))); 9656 (void) sprintf(&buf[0], "\tcdb=["); 9657 for (i = 0; i < (int)cmd->cmd_cdblen; i++) { 9658 (void) sprintf(&buf[strlen(buf)], " 0x%x", *cp++); 9659 } 9660 (void) sprintf(&buf[strlen(buf)], " ]"); 9661 NDBG25(("?%s\n", buf)); 9662 NDBG25(("?pkt_flags=0x%x pkt_statistics=0x%x pkt_state=0x%x\n", 9663 cmd->cmd_pkt->pkt_flags, cmd->cmd_pkt->pkt_statistics, 9664 cmd->cmd_pkt->pkt_state)); 9665 NDBG25(("?pkt_scbp=0x%x cmd_flags=0x%x\n", cmd->cmd_pkt->pkt_scbp ? 9666 *(cmd->cmd_pkt->pkt_scbp) : 0, cmd->cmd_flags)); 9667 } 9668 9669 static void 9670 mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd) 9671 { 9672 caddr_t memp; 9673 pMPI2RequestHeader_t request_hdrp; 9674 struct scsi_pkt *pkt = cmd->cmd_pkt; 9675 mptsas_pt_request_t *pt = pkt->pkt_ha_private; 9676 uint32_t request_size, data_size, dataout_size; 9677 uint32_t direction; 9678 ddi_dma_cookie_t data_cookie; 9679 ddi_dma_cookie_t dataout_cookie; 9680 uint32_t request_desc_low, request_desc_high = 0; 9681 uint32_t i, sense_bufp; 9682 uint8_t desc_type; 9683 uint8_t *request, function; 9684 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; 9685 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl; 9686 9687 desc_type = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 9688 9689 request = pt->request; 9690 direction = pt->direction; 9691 request_size = pt->request_size; 9692 data_size = pt->data_size; 9693 dataout_size = pt->dataout_size; 9694 data_cookie = pt->data_cookie; 9695 dataout_cookie = pt->dataout_cookie; 9696 9697 /* 9698 * Store the passthrough message in memory location 9699 * corresponding to our slot number 9700 */ 9701 memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot); 9702 request_hdrp = (pMPI2RequestHeader_t)memp; 9703 bzero(memp, mpt->m_req_frame_size); 9704 9705 for (i = 0; i < request_size; i++) { 9706 bcopy(request + i, memp + i, 1); 9707 } 9708 9709 if (data_size || dataout_size) { 9710 pMpi2SGESimple64_t sgep; 9711 uint32_t sge_flags; 9712 9713 sgep = (pMpi2SGESimple64_t)((uint8_t *)request_hdrp + 9714 request_size); 9715 if (dataout_size) { 9716 9717 sge_flags = dataout_size | 9718 ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 9719 MPI2_SGE_FLAGS_END_OF_BUFFER | 9720 MPI2_SGE_FLAGS_HOST_TO_IOC | 9721 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 9722 MPI2_SGE_FLAGS_SHIFT); 9723 ddi_put32(acc_hdl, &sgep->FlagsLength, sge_flags); 9724 ddi_put32(acc_hdl, &sgep->Address.Low, 9725 (uint32_t)(dataout_cookie.dmac_laddress & 9726 0xffffffffull)); 9727 ddi_put32(acc_hdl, &sgep->Address.High, 9728 (uint32_t)(dataout_cookie.dmac_laddress 9729 >> 32)); 9730 sgep++; 9731 } 9732 sge_flags = data_size; 9733 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 9734 MPI2_SGE_FLAGS_LAST_ELEMENT | 9735 MPI2_SGE_FLAGS_END_OF_BUFFER | 9736 MPI2_SGE_FLAGS_END_OF_LIST | 9737 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 9738 MPI2_SGE_FLAGS_SHIFT); 9739 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) { 9740 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_HOST_TO_IOC) << 9741 MPI2_SGE_FLAGS_SHIFT); 9742 } else { 9743 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_IOC_TO_HOST) << 9744 MPI2_SGE_FLAGS_SHIFT); 9745 } 9746 ddi_put32(acc_hdl, &sgep->FlagsLength, 9747 sge_flags); 9748 ddi_put32(acc_hdl, &sgep->Address.Low, 9749 (uint32_t)(data_cookie.dmac_laddress & 9750 0xffffffffull)); 9751 ddi_put32(acc_hdl, &sgep->Address.High, 9752 (uint32_t)(data_cookie.dmac_laddress >> 32)); 9753 } 9754 9755 function = request_hdrp->Function; 9756 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) || 9757 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 9758 pMpi2SCSIIORequest_t scsi_io_req; 9759 9760 scsi_io_req = (pMpi2SCSIIORequest_t)request_hdrp; 9761 /* 9762 * Put SGE for data and data_out buffer at the end of 9763 * scsi_io_request message header.(64 bytes in total) 9764 * Following above SGEs, the residual space will be 9765 * used by sense data. 9766 */ 9767 ddi_put8(acc_hdl, 9768 &scsi_io_req->SenseBufferLength, 9769 (uint8_t)(request_size - 64)); 9770 9771 sense_bufp = mpt->m_req_frame_dma_addr + 9772 (mpt->m_req_frame_size * cmd->cmd_slot); 9773 sense_bufp += 64; 9774 ddi_put32(acc_hdl, 9775 &scsi_io_req->SenseBufferLowAddress, sense_bufp); 9776 9777 /* 9778 * Set SGLOffset0 value 9779 */ 9780 ddi_put8(acc_hdl, &scsi_io_req->SGLOffset0, 9781 offsetof(MPI2_SCSI_IO_REQUEST, SGL) / 4); 9782 9783 /* 9784 * Setup descriptor info. RAID passthrough must use the 9785 * default request descriptor which is already set, so if this 9786 * is a SCSI IO request, change the descriptor to SCSI IO. 9787 */ 9788 if (function == MPI2_FUNCTION_SCSI_IO_REQUEST) { 9789 desc_type = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 9790 request_desc_high = (ddi_get16(acc_hdl, 9791 &scsi_io_req->DevHandle) << 16); 9792 } 9793 } 9794 9795 /* 9796 * We must wait till the message has been completed before 9797 * beginning the next message so we wait for this one to 9798 * finish. 9799 */ 9800 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 9801 request_desc_low = (cmd->cmd_slot << 16) + desc_type; 9802 cmd->cmd_rfm = NULL; 9803 MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high); 9804 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || 9805 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { 9806 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 9807 } 9808 } 9809 9810 9811 9812 static int 9813 mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply, 9814 uint8_t *data, uint32_t request_size, uint32_t reply_size, 9815 uint32_t data_size, uint32_t direction, uint8_t *dataout, 9816 uint32_t dataout_size, short timeout, int mode) 9817 { 9818 mptsas_pt_request_t pt; 9819 mptsas_dma_alloc_state_t data_dma_state; 9820 mptsas_dma_alloc_state_t dataout_dma_state; 9821 caddr_t memp; 9822 mptsas_cmd_t *cmd = NULL; 9823 struct scsi_pkt *pkt; 9824 uint32_t reply_len = 0, sense_len = 0; 9825 pMPI2RequestHeader_t request_hdrp; 9826 pMPI2RequestHeader_t request_msg; 9827 pMPI2DefaultReply_t reply_msg; 9828 Mpi2SCSIIOReply_t rep_msg; 9829 int i, status = 0, pt_flags = 0, rv = 0; 9830 int rvalue; 9831 uint8_t function; 9832 9833 ASSERT(mutex_owned(&mpt->m_mutex)); 9834 9835 reply_msg = (pMPI2DefaultReply_t)(&rep_msg); 9836 bzero(reply_msg, sizeof (MPI2_DEFAULT_REPLY)); 9837 request_msg = kmem_zalloc(request_size, KM_SLEEP); 9838 9839 mutex_exit(&mpt->m_mutex); 9840 /* 9841 * copy in the request buffer since it could be used by 9842 * another thread when the pt request into waitq 9843 */ 9844 if (ddi_copyin(request, request_msg, request_size, mode)) { 9845 mutex_enter(&mpt->m_mutex); 9846 status = EFAULT; 9847 mptsas_log(mpt, CE_WARN, "failed to copy request data"); 9848 goto out; 9849 } 9850 mutex_enter(&mpt->m_mutex); 9851 9852 function = request_msg->Function; 9853 if (function == MPI2_FUNCTION_SCSI_TASK_MGMT) { 9854 pMpi2SCSITaskManagementRequest_t task; 9855 task = (pMpi2SCSITaskManagementRequest_t)request_msg; 9856 mptsas_setup_bus_reset_delay(mpt); 9857 rv = mptsas_ioc_task_management(mpt, task->TaskType, 9858 task->DevHandle, (int)task->LUN[1], reply, reply_size, 9859 mode); 9860 9861 if (rv != TRUE) { 9862 status = EIO; 9863 mptsas_log(mpt, CE_WARN, "task management failed"); 9864 } 9865 goto out; 9866 } 9867 9868 if (data_size != 0) { 9869 data_dma_state.size = data_size; 9870 if (mptsas_dma_alloc(mpt, &data_dma_state) != DDI_SUCCESS) { 9871 status = ENOMEM; 9872 mptsas_log(mpt, CE_WARN, "failed to alloc DMA " 9873 "resource"); 9874 goto out; 9875 } 9876 pt_flags |= MPTSAS_DATA_ALLOCATED; 9877 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) { 9878 mutex_exit(&mpt->m_mutex); 9879 for (i = 0; i < data_size; i++) { 9880 if (ddi_copyin(data + i, (uint8_t *) 9881 data_dma_state.memp + i, 1, mode)) { 9882 mutex_enter(&mpt->m_mutex); 9883 status = EFAULT; 9884 mptsas_log(mpt, CE_WARN, "failed to " 9885 "copy read data"); 9886 goto out; 9887 } 9888 } 9889 mutex_enter(&mpt->m_mutex); 9890 } 9891 } 9892 9893 if (dataout_size != 0) { 9894 dataout_dma_state.size = dataout_size; 9895 if (mptsas_dma_alloc(mpt, &dataout_dma_state) != DDI_SUCCESS) { 9896 status = ENOMEM; 9897 mptsas_log(mpt, CE_WARN, "failed to alloc DMA " 9898 "resource"); 9899 goto out; 9900 } 9901 pt_flags |= MPTSAS_DATAOUT_ALLOCATED; 9902 mutex_exit(&mpt->m_mutex); 9903 for (i = 0; i < dataout_size; i++) { 9904 if (ddi_copyin(dataout + i, (uint8_t *) 9905 dataout_dma_state.memp + i, 1, mode)) { 9906 mutex_enter(&mpt->m_mutex); 9907 mptsas_log(mpt, CE_WARN, "failed to copy out" 9908 " data"); 9909 status = EFAULT; 9910 goto out; 9911 } 9912 } 9913 mutex_enter(&mpt->m_mutex); 9914 } 9915 9916 if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 9917 status = EAGAIN; 9918 mptsas_log(mpt, CE_NOTE, "event ack command pool is full"); 9919 goto out; 9920 } 9921 pt_flags |= MPTSAS_REQUEST_POOL_CMD; 9922 9923 bzero((caddr_t)cmd, sizeof (*cmd)); 9924 bzero((caddr_t)pkt, scsi_pkt_size()); 9925 bzero((caddr_t)&pt, sizeof (pt)); 9926 9927 cmd->ioc_cmd_slot = (uint32_t)(rvalue); 9928 9929 pt.request = (uint8_t *)request_msg; 9930 pt.direction = direction; 9931 pt.request_size = request_size; 9932 pt.data_size = data_size; 9933 pt.dataout_size = dataout_size; 9934 pt.data_cookie = data_dma_state.cookie; 9935 pt.dataout_cookie = dataout_dma_state.cookie; 9936 9937 /* 9938 * Form a blank cmd/pkt to store the acknowledgement message 9939 */ 9940 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb[0]; 9941 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; 9942 pkt->pkt_ha_private = (opaque_t)&pt; 9943 pkt->pkt_flags = FLAG_HEAD; 9944 pkt->pkt_time = timeout; 9945 cmd->cmd_pkt = pkt; 9946 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_PASSTHRU; 9947 9948 /* 9949 * Save the command in a slot 9950 */ 9951 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 9952 /* 9953 * Once passthru command get slot, set cmd_flags 9954 * CFLAG_PREPARED. 9955 */ 9956 cmd->cmd_flags |= CFLAG_PREPARED; 9957 mptsas_start_passthru(mpt, cmd); 9958 } else { 9959 mptsas_waitq_add(mpt, cmd); 9960 } 9961 9962 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 9963 cv_wait(&mpt->m_passthru_cv, &mpt->m_mutex); 9964 } 9965 9966 if (cmd->cmd_flags & CFLAG_PREPARED) { 9967 memp = mpt->m_req_frame + (mpt->m_req_frame_size * 9968 cmd->cmd_slot); 9969 request_hdrp = (pMPI2RequestHeader_t)memp; 9970 } 9971 9972 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 9973 status = ETIMEDOUT; 9974 mptsas_log(mpt, CE_WARN, "passthrough command timeout"); 9975 pt_flags |= MPTSAS_CMD_TIMEOUT; 9976 goto out; 9977 } 9978 9979 if (cmd->cmd_rfm) { 9980 /* 9981 * cmd_rfm is zero means the command reply is a CONTEXT 9982 * reply and no PCI Write to post the free reply SMFA 9983 * because no reply message frame is used. 9984 * cmd_rfm is non-zero means the reply is a ADDRESS 9985 * reply and reply message frame is used. 9986 */ 9987 pt_flags |= MPTSAS_ADDRESS_REPLY; 9988 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 9989 DDI_DMA_SYNC_FORCPU); 9990 reply_msg = (pMPI2DefaultReply_t) 9991 (mpt->m_reply_frame + (cmd->cmd_rfm - 9992 mpt->m_reply_frame_dma_addr)); 9993 } 9994 9995 mptsas_fma_check(mpt, cmd); 9996 if (pkt->pkt_reason == CMD_TRAN_ERR) { 9997 status = EAGAIN; 9998 mptsas_log(mpt, CE_WARN, "passthru fma error"); 9999 goto out; 10000 } 10001 if (pkt->pkt_reason == CMD_RESET) { 10002 status = EAGAIN; 10003 mptsas_log(mpt, CE_WARN, "ioc reset abort passthru"); 10004 goto out; 10005 } 10006 10007 if (pkt->pkt_reason == CMD_INCOMPLETE) { 10008 status = EIO; 10009 mptsas_log(mpt, CE_WARN, "passthrough command incomplete"); 10010 goto out; 10011 } 10012 10013 mutex_exit(&mpt->m_mutex); 10014 if (cmd->cmd_flags & CFLAG_PREPARED) { 10015 function = request_hdrp->Function; 10016 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) || 10017 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 10018 reply_len = sizeof (MPI2_SCSI_IO_REPLY); 10019 sense_len = reply_size - reply_len; 10020 } else { 10021 reply_len = reply_size; 10022 sense_len = 0; 10023 } 10024 10025 for (i = 0; i < reply_len; i++) { 10026 if (ddi_copyout((uint8_t *)reply_msg + i, reply + i, 1, 10027 mode)) { 10028 mutex_enter(&mpt->m_mutex); 10029 status = EFAULT; 10030 mptsas_log(mpt, CE_WARN, "failed to copy out " 10031 "reply data"); 10032 goto out; 10033 } 10034 } 10035 for (i = 0; i < sense_len; i++) { 10036 if (ddi_copyout((uint8_t *)request_hdrp + 64 + i, 10037 reply + reply_len + i, 1, mode)) { 10038 mutex_enter(&mpt->m_mutex); 10039 status = EFAULT; 10040 mptsas_log(mpt, CE_WARN, "failed to copy out " 10041 "sense data"); 10042 goto out; 10043 } 10044 } 10045 } 10046 10047 if (data_size) { 10048 if (direction != MPTSAS_PASS_THRU_DIRECTION_WRITE) { 10049 (void) ddi_dma_sync(data_dma_state.handle, 0, 0, 10050 DDI_DMA_SYNC_FORCPU); 10051 for (i = 0; i < data_size; i++) { 10052 if (ddi_copyout((uint8_t *)( 10053 data_dma_state.memp + i), data + i, 1, 10054 mode)) { 10055 mutex_enter(&mpt->m_mutex); 10056 status = EFAULT; 10057 mptsas_log(mpt, CE_WARN, "failed to " 10058 "copy out the reply data"); 10059 goto out; 10060 } 10061 } 10062 } 10063 } 10064 mutex_enter(&mpt->m_mutex); 10065 out: 10066 /* 10067 * Put the reply frame back on the free queue, increment the free 10068 * index, and write the new index to the free index register. But only 10069 * if this reply is an ADDRESS reply. 10070 */ 10071 if (pt_flags & MPTSAS_ADDRESS_REPLY) { 10072 ddi_put32(mpt->m_acc_free_queue_hdl, 10073 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 10074 cmd->cmd_rfm); 10075 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 10076 DDI_DMA_SYNC_FORDEV); 10077 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 10078 mpt->m_free_index = 0; 10079 } 10080 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 10081 mpt->m_free_index); 10082 } 10083 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 10084 mptsas_remove_cmd(mpt, cmd); 10085 pt_flags &= (~MPTSAS_REQUEST_POOL_CMD); 10086 } 10087 if (pt_flags & MPTSAS_REQUEST_POOL_CMD) 10088 mptsas_return_to_pool(mpt, cmd); 10089 if (pt_flags & MPTSAS_DATA_ALLOCATED) { 10090 if (mptsas_check_dma_handle(data_dma_state.handle) != 10091 DDI_SUCCESS) { 10092 ddi_fm_service_impact(mpt->m_dip, 10093 DDI_SERVICE_UNAFFECTED); 10094 status = EFAULT; 10095 } 10096 mptsas_dma_free(&data_dma_state); 10097 } 10098 if (pt_flags & MPTSAS_DATAOUT_ALLOCATED) { 10099 if (mptsas_check_dma_handle(dataout_dma_state.handle) != 10100 DDI_SUCCESS) { 10101 ddi_fm_service_impact(mpt->m_dip, 10102 DDI_SERVICE_UNAFFECTED); 10103 status = EFAULT; 10104 } 10105 mptsas_dma_free(&dataout_dma_state); 10106 } 10107 if (pt_flags & MPTSAS_CMD_TIMEOUT) { 10108 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 10109 mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed"); 10110 } 10111 } 10112 if (request_msg) 10113 kmem_free(request_msg, request_size); 10114 10115 return (status); 10116 } 10117 10118 static int 10119 mptsas_pass_thru(mptsas_t *mpt, mptsas_pass_thru_t *data, int mode) 10120 { 10121 /* 10122 * If timeout is 0, set timeout to default of 60 seconds. 10123 */ 10124 if (data->Timeout == 0) { 10125 data->Timeout = MPTSAS_PASS_THRU_TIME_DEFAULT; 10126 } 10127 10128 if (((data->DataSize == 0) && 10129 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_NONE)) || 10130 ((data->DataSize != 0) && 10131 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_READ) || 10132 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_WRITE) || 10133 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) && 10134 (data->DataOutSize != 0))))) { 10135 if (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) { 10136 data->DataDirection = MPTSAS_PASS_THRU_DIRECTION_READ; 10137 } else { 10138 data->DataOutSize = 0; 10139 } 10140 /* 10141 * Send passthru request messages 10142 */ 10143 return (mptsas_do_passthru(mpt, 10144 (uint8_t *)((uintptr_t)data->PtrRequest), 10145 (uint8_t *)((uintptr_t)data->PtrReply), 10146 (uint8_t *)((uintptr_t)data->PtrData), 10147 data->RequestSize, data->ReplySize, 10148 data->DataSize, data->DataDirection, 10149 (uint8_t *)((uintptr_t)data->PtrDataOut), 10150 data->DataOutSize, data->Timeout, mode)); 10151 } else { 10152 return (EINVAL); 10153 } 10154 } 10155 10156 static uint8_t 10157 mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, uint32_t unique_id) 10158 { 10159 uint8_t index; 10160 10161 for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) { 10162 if (mpt->m_fw_diag_buffer_list[index].unique_id == unique_id) { 10163 return (index); 10164 } 10165 } 10166 10167 return (MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND); 10168 } 10169 10170 static void 10171 mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd) 10172 { 10173 pMpi2DiagBufferPostRequest_t pDiag_post_msg; 10174 pMpi2DiagReleaseRequest_t pDiag_release_msg; 10175 struct scsi_pkt *pkt = cmd->cmd_pkt; 10176 mptsas_diag_request_t *diag = pkt->pkt_ha_private; 10177 uint32_t request_desc_low, i; 10178 10179 ASSERT(mutex_owned(&mpt->m_mutex)); 10180 10181 /* 10182 * Form the diag message depending on the post or release function. 10183 */ 10184 if (diag->function == MPI2_FUNCTION_DIAG_BUFFER_POST) { 10185 pDiag_post_msg = (pMpi2DiagBufferPostRequest_t) 10186 (mpt->m_req_frame + (mpt->m_req_frame_size * 10187 cmd->cmd_slot)); 10188 bzero(pDiag_post_msg, mpt->m_req_frame_size); 10189 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->Function, 10190 diag->function); 10191 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->BufferType, 10192 diag->pBuffer->buffer_type); 10193 ddi_put8(mpt->m_acc_req_frame_hdl, 10194 &pDiag_post_msg->ExtendedType, 10195 diag->pBuffer->extended_type); 10196 ddi_put32(mpt->m_acc_req_frame_hdl, 10197 &pDiag_post_msg->BufferLength, 10198 diag->pBuffer->buffer_data.size); 10199 for (i = 0; i < (sizeof (pDiag_post_msg->ProductSpecific) / 4); 10200 i++) { 10201 ddi_put32(mpt->m_acc_req_frame_hdl, 10202 &pDiag_post_msg->ProductSpecific[i], 10203 diag->pBuffer->product_specific[i]); 10204 } 10205 ddi_put32(mpt->m_acc_req_frame_hdl, 10206 &pDiag_post_msg->BufferAddress.Low, 10207 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress 10208 & 0xffffffffull)); 10209 ddi_put32(mpt->m_acc_req_frame_hdl, 10210 &pDiag_post_msg->BufferAddress.High, 10211 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress 10212 >> 32)); 10213 } else { 10214 pDiag_release_msg = (pMpi2DiagReleaseRequest_t) 10215 (mpt->m_req_frame + (mpt->m_req_frame_size * 10216 cmd->cmd_slot)); 10217 bzero(pDiag_release_msg, mpt->m_req_frame_size); 10218 ddi_put8(mpt->m_acc_req_frame_hdl, 10219 &pDiag_release_msg->Function, diag->function); 10220 ddi_put8(mpt->m_acc_req_frame_hdl, 10221 &pDiag_release_msg->BufferType, 10222 diag->pBuffer->buffer_type); 10223 } 10224 10225 /* 10226 * Send the message 10227 */ 10228 (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0, 10229 DDI_DMA_SYNC_FORDEV); 10230 request_desc_low = (cmd->cmd_slot << 16) + 10231 MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 10232 cmd->cmd_rfm = NULL; 10233 MPTSAS_START_CMD(mpt, request_desc_low, 0); 10234 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 10235 DDI_SUCCESS) || 10236 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 10237 DDI_SUCCESS)) { 10238 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 10239 } 10240 } 10241 10242 static int 10243 mptsas_post_fw_diag_buffer(mptsas_t *mpt, 10244 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code) 10245 { 10246 mptsas_diag_request_t diag; 10247 int status, slot_num, post_flags = 0; 10248 mptsas_cmd_t *cmd = NULL; 10249 struct scsi_pkt *pkt; 10250 pMpi2DiagBufferPostReply_t reply; 10251 uint16_t iocstatus; 10252 uint32_t iocloginfo, transfer_length; 10253 10254 /* 10255 * If buffer is not enabled, just leave. 10256 */ 10257 *return_code = MPTSAS_FW_DIAG_ERROR_POST_FAILED; 10258 if (!pBuffer->enabled) { 10259 status = DDI_FAILURE; 10260 goto out; 10261 } 10262 10263 /* 10264 * Clear some flags initially. 10265 */ 10266 pBuffer->force_release = FALSE; 10267 pBuffer->valid_data = FALSE; 10268 pBuffer->owned_by_firmware = FALSE; 10269 10270 /* 10271 * Get a cmd buffer from the cmd buffer pool 10272 */ 10273 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 10274 status = DDI_FAILURE; 10275 mptsas_log(mpt, CE_NOTE, "command pool is full: Post FW Diag"); 10276 goto out; 10277 } 10278 post_flags |= MPTSAS_REQUEST_POOL_CMD; 10279 10280 bzero((caddr_t)cmd, sizeof (*cmd)); 10281 bzero((caddr_t)pkt, scsi_pkt_size()); 10282 10283 cmd->ioc_cmd_slot = (uint32_t)(slot_num); 10284 10285 diag.pBuffer = pBuffer; 10286 diag.function = MPI2_FUNCTION_DIAG_BUFFER_POST; 10287 10288 /* 10289 * Form a blank cmd/pkt to store the acknowledgement message 10290 */ 10291 pkt->pkt_ha_private = (opaque_t)&diag; 10292 pkt->pkt_flags = FLAG_HEAD; 10293 pkt->pkt_time = 60; 10294 cmd->cmd_pkt = pkt; 10295 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG; 10296 10297 /* 10298 * Save the command in a slot 10299 */ 10300 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 10301 /* 10302 * Once passthru command get slot, set cmd_flags 10303 * CFLAG_PREPARED. 10304 */ 10305 cmd->cmd_flags |= CFLAG_PREPARED; 10306 mptsas_start_diag(mpt, cmd); 10307 } else { 10308 mptsas_waitq_add(mpt, cmd); 10309 } 10310 10311 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 10312 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex); 10313 } 10314 10315 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 10316 status = DDI_FAILURE; 10317 mptsas_log(mpt, CE_WARN, "Post FW Diag command timeout"); 10318 goto out; 10319 } 10320 10321 /* 10322 * cmd_rfm points to the reply message if a reply was given. Check the 10323 * IOCStatus to make sure everything went OK with the FW diag request 10324 * and set buffer flags. 10325 */ 10326 if (cmd->cmd_rfm) { 10327 post_flags |= MPTSAS_ADDRESS_REPLY; 10328 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 10329 DDI_DMA_SYNC_FORCPU); 10330 reply = (pMpi2DiagBufferPostReply_t)(mpt->m_reply_frame + 10331 (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr)); 10332 10333 /* 10334 * Get the reply message data 10335 */ 10336 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 10337 &reply->IOCStatus); 10338 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 10339 &reply->IOCLogInfo); 10340 transfer_length = ddi_get32(mpt->m_acc_reply_frame_hdl, 10341 &reply->TransferLength); 10342 10343 /* 10344 * If post failed quit. 10345 */ 10346 if (iocstatus != MPI2_IOCSTATUS_SUCCESS) { 10347 status = DDI_FAILURE; 10348 NDBG13(("post FW Diag Buffer failed: IOCStatus=0x%x, " 10349 "IOCLogInfo=0x%x, TransferLength=0x%x", iocstatus, 10350 iocloginfo, transfer_length)); 10351 goto out; 10352 } 10353 10354 /* 10355 * Post was successful. 10356 */ 10357 pBuffer->valid_data = TRUE; 10358 pBuffer->owned_by_firmware = TRUE; 10359 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 10360 status = DDI_SUCCESS; 10361 } 10362 10363 out: 10364 /* 10365 * Put the reply frame back on the free queue, increment the free 10366 * index, and write the new index to the free index register. But only 10367 * if this reply is an ADDRESS reply. 10368 */ 10369 if (post_flags & MPTSAS_ADDRESS_REPLY) { 10370 ddi_put32(mpt->m_acc_free_queue_hdl, 10371 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 10372 cmd->cmd_rfm); 10373 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 10374 DDI_DMA_SYNC_FORDEV); 10375 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 10376 mpt->m_free_index = 0; 10377 } 10378 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 10379 mpt->m_free_index); 10380 } 10381 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 10382 mptsas_remove_cmd(mpt, cmd); 10383 post_flags &= (~MPTSAS_REQUEST_POOL_CMD); 10384 } 10385 if (post_flags & MPTSAS_REQUEST_POOL_CMD) { 10386 mptsas_return_to_pool(mpt, cmd); 10387 } 10388 10389 return (status); 10390 } 10391 10392 static int 10393 mptsas_release_fw_diag_buffer(mptsas_t *mpt, 10394 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code, 10395 uint32_t diag_type) 10396 { 10397 mptsas_diag_request_t diag; 10398 int status, slot_num, rel_flags = 0; 10399 mptsas_cmd_t *cmd = NULL; 10400 struct scsi_pkt *pkt; 10401 pMpi2DiagReleaseReply_t reply; 10402 uint16_t iocstatus; 10403 uint32_t iocloginfo; 10404 10405 /* 10406 * If buffer is not enabled, just leave. 10407 */ 10408 *return_code = MPTSAS_FW_DIAG_ERROR_RELEASE_FAILED; 10409 if (!pBuffer->enabled) { 10410 mptsas_log(mpt, CE_NOTE, "This buffer type is not supported " 10411 "by the IOC"); 10412 status = DDI_FAILURE; 10413 goto out; 10414 } 10415 10416 /* 10417 * Clear some flags initially. 10418 */ 10419 pBuffer->force_release = FALSE; 10420 pBuffer->valid_data = FALSE; 10421 pBuffer->owned_by_firmware = FALSE; 10422 10423 /* 10424 * Get a cmd buffer from the cmd buffer pool 10425 */ 10426 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 10427 status = DDI_FAILURE; 10428 mptsas_log(mpt, CE_NOTE, "command pool is full: Release FW " 10429 "Diag"); 10430 goto out; 10431 } 10432 rel_flags |= MPTSAS_REQUEST_POOL_CMD; 10433 10434 bzero((caddr_t)cmd, sizeof (*cmd)); 10435 bzero((caddr_t)pkt, scsi_pkt_size()); 10436 10437 cmd->ioc_cmd_slot = (uint32_t)(slot_num); 10438 10439 diag.pBuffer = pBuffer; 10440 diag.function = MPI2_FUNCTION_DIAG_RELEASE; 10441 10442 /* 10443 * Form a blank cmd/pkt to store the acknowledgement message 10444 */ 10445 pkt->pkt_ha_private = (opaque_t)&diag; 10446 pkt->pkt_flags = FLAG_HEAD; 10447 pkt->pkt_time = 60; 10448 cmd->cmd_pkt = pkt; 10449 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG; 10450 10451 /* 10452 * Save the command in a slot 10453 */ 10454 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 10455 /* 10456 * Once passthru command get slot, set cmd_flags 10457 * CFLAG_PREPARED. 10458 */ 10459 cmd->cmd_flags |= CFLAG_PREPARED; 10460 mptsas_start_diag(mpt, cmd); 10461 } else { 10462 mptsas_waitq_add(mpt, cmd); 10463 } 10464 10465 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 10466 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex); 10467 } 10468 10469 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 10470 status = DDI_FAILURE; 10471 mptsas_log(mpt, CE_WARN, "Release FW Diag command timeout"); 10472 goto out; 10473 } 10474 10475 /* 10476 * cmd_rfm points to the reply message if a reply was given. Check the 10477 * IOCStatus to make sure everything went OK with the FW diag request 10478 * and set buffer flags. 10479 */ 10480 if (cmd->cmd_rfm) { 10481 rel_flags |= MPTSAS_ADDRESS_REPLY; 10482 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 10483 DDI_DMA_SYNC_FORCPU); 10484 reply = (pMpi2DiagReleaseReply_t)(mpt->m_reply_frame + 10485 (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr)); 10486 10487 /* 10488 * Get the reply message data 10489 */ 10490 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 10491 &reply->IOCStatus); 10492 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 10493 &reply->IOCLogInfo); 10494 10495 /* 10496 * If release failed quit. 10497 */ 10498 if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) || 10499 pBuffer->owned_by_firmware) { 10500 status = DDI_FAILURE; 10501 NDBG13(("release FW Diag Buffer failed: " 10502 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus, 10503 iocloginfo)); 10504 goto out; 10505 } 10506 10507 /* 10508 * Release was successful. 10509 */ 10510 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 10511 status = DDI_SUCCESS; 10512 10513 /* 10514 * If this was for an UNREGISTER diag type command, clear the 10515 * unique ID. 10516 */ 10517 if (diag_type == MPTSAS_FW_DIAG_TYPE_UNREGISTER) { 10518 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID; 10519 } 10520 } 10521 10522 out: 10523 /* 10524 * Put the reply frame back on the free queue, increment the free 10525 * index, and write the new index to the free index register. But only 10526 * if this reply is an ADDRESS reply. 10527 */ 10528 if (rel_flags & MPTSAS_ADDRESS_REPLY) { 10529 ddi_put32(mpt->m_acc_free_queue_hdl, 10530 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 10531 cmd->cmd_rfm); 10532 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 10533 DDI_DMA_SYNC_FORDEV); 10534 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 10535 mpt->m_free_index = 0; 10536 } 10537 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 10538 mpt->m_free_index); 10539 } 10540 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 10541 mptsas_remove_cmd(mpt, cmd); 10542 rel_flags &= (~MPTSAS_REQUEST_POOL_CMD); 10543 } 10544 if (rel_flags & MPTSAS_REQUEST_POOL_CMD) { 10545 mptsas_return_to_pool(mpt, cmd); 10546 } 10547 10548 return (status); 10549 } 10550 10551 static int 10552 mptsas_diag_register(mptsas_t *mpt, mptsas_fw_diag_register_t *diag_register, 10553 uint32_t *return_code) 10554 { 10555 mptsas_fw_diagnostic_buffer_t *pBuffer; 10556 uint8_t extended_type, buffer_type, i; 10557 uint32_t buffer_size; 10558 uint32_t unique_id; 10559 int status; 10560 10561 ASSERT(mutex_owned(&mpt->m_mutex)); 10562 10563 extended_type = diag_register->ExtendedType; 10564 buffer_type = diag_register->BufferType; 10565 buffer_size = diag_register->RequestedBufferSize; 10566 unique_id = diag_register->UniqueId; 10567 10568 /* 10569 * Check for valid buffer type 10570 */ 10571 if (buffer_type >= MPI2_DIAG_BUF_TYPE_COUNT) { 10572 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10573 return (DDI_FAILURE); 10574 } 10575 10576 /* 10577 * Get the current buffer and look up the unique ID. The unique ID 10578 * should not be found. If it is, the ID is already in use. 10579 */ 10580 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 10581 pBuffer = &mpt->m_fw_diag_buffer_list[buffer_type]; 10582 if (i != MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 10583 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10584 return (DDI_FAILURE); 10585 } 10586 10587 /* 10588 * The buffer's unique ID should not be registered yet, and the given 10589 * unique ID cannot be 0. 10590 */ 10591 if ((pBuffer->unique_id != MPTSAS_FW_DIAG_INVALID_UID) || 10592 (unique_id == MPTSAS_FW_DIAG_INVALID_UID)) { 10593 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10594 return (DDI_FAILURE); 10595 } 10596 10597 /* 10598 * If this buffer is already posted as immediate, just change owner. 10599 */ 10600 if (pBuffer->immediate && pBuffer->owned_by_firmware && 10601 (pBuffer->unique_id == MPTSAS_FW_DIAG_INVALID_UID)) { 10602 pBuffer->immediate = FALSE; 10603 pBuffer->unique_id = unique_id; 10604 return (DDI_SUCCESS); 10605 } 10606 10607 /* 10608 * Post a new buffer after checking if it's enabled. The DMA buffer 10609 * that is allocated will be contiguous (sgl_len = 1). 10610 */ 10611 if (!pBuffer->enabled) { 10612 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER; 10613 return (DDI_FAILURE); 10614 } 10615 bzero(&pBuffer->buffer_data, sizeof (mptsas_dma_alloc_state_t)); 10616 pBuffer->buffer_data.size = buffer_size; 10617 if (mptsas_dma_alloc(mpt, &pBuffer->buffer_data) != DDI_SUCCESS) { 10618 mptsas_log(mpt, CE_WARN, "failed to alloc DMA resource for " 10619 "diag buffer: size = %d bytes", buffer_size); 10620 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER; 10621 return (DDI_FAILURE); 10622 } 10623 10624 /* 10625 * Copy the given info to the diag buffer and post the buffer. 10626 */ 10627 pBuffer->buffer_type = buffer_type; 10628 pBuffer->immediate = FALSE; 10629 if (buffer_type == MPI2_DIAG_BUF_TYPE_TRACE) { 10630 for (i = 0; i < (sizeof (pBuffer->product_specific) / 4); 10631 i++) { 10632 pBuffer->product_specific[i] = 10633 diag_register->ProductSpecific[i]; 10634 } 10635 } 10636 pBuffer->extended_type = extended_type; 10637 pBuffer->unique_id = unique_id; 10638 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, return_code); 10639 10640 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) != 10641 DDI_SUCCESS) { 10642 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed in " 10643 "mptsas_diag_register."); 10644 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 10645 status = DDI_FAILURE; 10646 } 10647 10648 /* 10649 * In case there was a failure, free the DMA buffer. 10650 */ 10651 if (status == DDI_FAILURE) { 10652 mptsas_dma_free(&pBuffer->buffer_data); 10653 } 10654 10655 return (status); 10656 } 10657 10658 static int 10659 mptsas_diag_unregister(mptsas_t *mpt, 10660 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code) 10661 { 10662 mptsas_fw_diagnostic_buffer_t *pBuffer; 10663 uint8_t i; 10664 uint32_t unique_id; 10665 int status; 10666 10667 ASSERT(mutex_owned(&mpt->m_mutex)); 10668 10669 unique_id = diag_unregister->UniqueId; 10670 10671 /* 10672 * Get the current buffer and look up the unique ID. The unique ID 10673 * should be there. 10674 */ 10675 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 10676 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 10677 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10678 return (DDI_FAILURE); 10679 } 10680 10681 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 10682 10683 /* 10684 * Try to release the buffer from FW before freeing it. If release 10685 * fails, don't free the DMA buffer in case FW tries to access it 10686 * later. If buffer is not owned by firmware, can't release it. 10687 */ 10688 if (!pBuffer->owned_by_firmware) { 10689 status = DDI_SUCCESS; 10690 } else { 10691 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, 10692 return_code, MPTSAS_FW_DIAG_TYPE_UNREGISTER); 10693 } 10694 10695 /* 10696 * At this point, return the current status no matter what happens with 10697 * the DMA buffer. 10698 */ 10699 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID; 10700 if (status == DDI_SUCCESS) { 10701 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) != 10702 DDI_SUCCESS) { 10703 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed " 10704 "in mptsas_diag_unregister."); 10705 ddi_fm_service_impact(mpt->m_dip, 10706 DDI_SERVICE_UNAFFECTED); 10707 } 10708 mptsas_dma_free(&pBuffer->buffer_data); 10709 } 10710 10711 return (status); 10712 } 10713 10714 static int 10715 mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query, 10716 uint32_t *return_code) 10717 { 10718 mptsas_fw_diagnostic_buffer_t *pBuffer; 10719 uint8_t i; 10720 uint32_t unique_id; 10721 10722 ASSERT(mutex_owned(&mpt->m_mutex)); 10723 10724 unique_id = diag_query->UniqueId; 10725 10726 /* 10727 * If ID is valid, query on ID. 10728 * If ID is invalid, query on buffer type. 10729 */ 10730 if (unique_id == MPTSAS_FW_DIAG_INVALID_UID) { 10731 i = diag_query->BufferType; 10732 if (i >= MPI2_DIAG_BUF_TYPE_COUNT) { 10733 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10734 return (DDI_FAILURE); 10735 } 10736 } else { 10737 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 10738 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 10739 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10740 return (DDI_FAILURE); 10741 } 10742 } 10743 10744 /* 10745 * Fill query structure with the diag buffer info. 10746 */ 10747 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 10748 diag_query->BufferType = pBuffer->buffer_type; 10749 diag_query->ExtendedType = pBuffer->extended_type; 10750 if (diag_query->BufferType == MPI2_DIAG_BUF_TYPE_TRACE) { 10751 for (i = 0; i < (sizeof (diag_query->ProductSpecific) / 4); 10752 i++) { 10753 diag_query->ProductSpecific[i] = 10754 pBuffer->product_specific[i]; 10755 } 10756 } 10757 diag_query->TotalBufferSize = pBuffer->buffer_data.size; 10758 diag_query->DriverAddedBufferSize = 0; 10759 diag_query->UniqueId = pBuffer->unique_id; 10760 diag_query->ApplicationFlags = 0; 10761 diag_query->DiagnosticFlags = 0; 10762 10763 /* 10764 * Set/Clear application flags 10765 */ 10766 if (pBuffer->immediate) { 10767 diag_query->ApplicationFlags &= ~MPTSAS_FW_DIAG_FLAG_APP_OWNED; 10768 } else { 10769 diag_query->ApplicationFlags |= MPTSAS_FW_DIAG_FLAG_APP_OWNED; 10770 } 10771 if (pBuffer->valid_data || pBuffer->owned_by_firmware) { 10772 diag_query->ApplicationFlags |= 10773 MPTSAS_FW_DIAG_FLAG_BUFFER_VALID; 10774 } else { 10775 diag_query->ApplicationFlags &= 10776 ~MPTSAS_FW_DIAG_FLAG_BUFFER_VALID; 10777 } 10778 if (pBuffer->owned_by_firmware) { 10779 diag_query->ApplicationFlags |= 10780 MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS; 10781 } else { 10782 diag_query->ApplicationFlags &= 10783 ~MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS; 10784 } 10785 10786 return (DDI_SUCCESS); 10787 } 10788 10789 static int 10790 mptsas_diag_read_buffer(mptsas_t *mpt, 10791 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf, 10792 uint32_t *return_code, int ioctl_mode) 10793 { 10794 mptsas_fw_diagnostic_buffer_t *pBuffer; 10795 uint8_t i, *pData; 10796 uint32_t unique_id, byte; 10797 int status; 10798 10799 ASSERT(mutex_owned(&mpt->m_mutex)); 10800 10801 unique_id = diag_read_buffer->UniqueId; 10802 10803 /* 10804 * Get the current buffer and look up the unique ID. The unique ID 10805 * should be there. 10806 */ 10807 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 10808 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 10809 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10810 return (DDI_FAILURE); 10811 } 10812 10813 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 10814 10815 /* 10816 * Make sure requested read is within limits 10817 */ 10818 if (diag_read_buffer->StartingOffset + diag_read_buffer->BytesToRead > 10819 pBuffer->buffer_data.size) { 10820 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10821 return (DDI_FAILURE); 10822 } 10823 10824 /* 10825 * Copy the requested data from DMA to the diag_read_buffer. The DMA 10826 * buffer that was allocated is one contiguous buffer. 10827 */ 10828 pData = (uint8_t *)(pBuffer->buffer_data.memp + 10829 diag_read_buffer->StartingOffset); 10830 (void) ddi_dma_sync(pBuffer->buffer_data.handle, 0, 0, 10831 DDI_DMA_SYNC_FORCPU); 10832 for (byte = 0; byte < diag_read_buffer->BytesToRead; byte++) { 10833 if (ddi_copyout(pData + byte, ioctl_buf + byte, 1, ioctl_mode) 10834 != 0) { 10835 return (DDI_FAILURE); 10836 } 10837 } 10838 diag_read_buffer->Status = 0; 10839 10840 /* 10841 * Set or clear the Force Release flag. 10842 */ 10843 if (pBuffer->force_release) { 10844 diag_read_buffer->Flags |= MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE; 10845 } else { 10846 diag_read_buffer->Flags &= ~MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE; 10847 } 10848 10849 /* 10850 * If buffer is to be reregistered, make sure it's not already owned by 10851 * firmware first. 10852 */ 10853 status = DDI_SUCCESS; 10854 if (!pBuffer->owned_by_firmware) { 10855 if (diag_read_buffer->Flags & MPTSAS_FW_DIAG_FLAG_REREGISTER) { 10856 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, 10857 return_code); 10858 } 10859 } 10860 10861 return (status); 10862 } 10863 10864 static int 10865 mptsas_diag_release(mptsas_t *mpt, mptsas_fw_diag_release_t *diag_release, 10866 uint32_t *return_code) 10867 { 10868 mptsas_fw_diagnostic_buffer_t *pBuffer; 10869 uint8_t i; 10870 uint32_t unique_id; 10871 int status; 10872 10873 ASSERT(mutex_owned(&mpt->m_mutex)); 10874 10875 unique_id = diag_release->UniqueId; 10876 10877 /* 10878 * Get the current buffer and look up the unique ID. The unique ID 10879 * should be there. 10880 */ 10881 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 10882 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 10883 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10884 return (DDI_FAILURE); 10885 } 10886 10887 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 10888 10889 /* 10890 * If buffer is not owned by firmware, it's already been released. 10891 */ 10892 if (!pBuffer->owned_by_firmware) { 10893 *return_code = MPTSAS_FW_DIAG_ERROR_ALREADY_RELEASED; 10894 return (DDI_FAILURE); 10895 } 10896 10897 /* 10898 * Release the buffer. 10899 */ 10900 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, return_code, 10901 MPTSAS_FW_DIAG_TYPE_RELEASE); 10902 return (status); 10903 } 10904 10905 static int 10906 mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, uint8_t *diag_action, 10907 uint32_t length, uint32_t *return_code, int ioctl_mode) 10908 { 10909 mptsas_fw_diag_register_t diag_register; 10910 mptsas_fw_diag_unregister_t diag_unregister; 10911 mptsas_fw_diag_query_t diag_query; 10912 mptsas_diag_read_buffer_t diag_read_buffer; 10913 mptsas_fw_diag_release_t diag_release; 10914 int status = DDI_SUCCESS; 10915 uint32_t original_return_code, read_buf_len; 10916 10917 ASSERT(mutex_owned(&mpt->m_mutex)); 10918 10919 original_return_code = *return_code; 10920 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 10921 10922 switch (action) { 10923 case MPTSAS_FW_DIAG_TYPE_REGISTER: 10924 if (!length) { 10925 *return_code = 10926 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10927 status = DDI_FAILURE; 10928 break; 10929 } 10930 if (ddi_copyin(diag_action, &diag_register, 10931 sizeof (diag_register), ioctl_mode) != 0) { 10932 return (DDI_FAILURE); 10933 } 10934 status = mptsas_diag_register(mpt, &diag_register, 10935 return_code); 10936 break; 10937 10938 case MPTSAS_FW_DIAG_TYPE_UNREGISTER: 10939 if (length < sizeof (diag_unregister)) { 10940 *return_code = 10941 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10942 status = DDI_FAILURE; 10943 break; 10944 } 10945 if (ddi_copyin(diag_action, &diag_unregister, 10946 sizeof (diag_unregister), ioctl_mode) != 0) { 10947 return (DDI_FAILURE); 10948 } 10949 status = mptsas_diag_unregister(mpt, &diag_unregister, 10950 return_code); 10951 break; 10952 10953 case MPTSAS_FW_DIAG_TYPE_QUERY: 10954 if (length < sizeof (diag_query)) { 10955 *return_code = 10956 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10957 status = DDI_FAILURE; 10958 break; 10959 } 10960 if (ddi_copyin(diag_action, &diag_query, 10961 sizeof (diag_query), ioctl_mode) != 0) { 10962 return (DDI_FAILURE); 10963 } 10964 status = mptsas_diag_query(mpt, &diag_query, 10965 return_code); 10966 if (status == DDI_SUCCESS) { 10967 if (ddi_copyout(&diag_query, diag_action, 10968 sizeof (diag_query), ioctl_mode) != 0) { 10969 return (DDI_FAILURE); 10970 } 10971 } 10972 break; 10973 10974 case MPTSAS_FW_DIAG_TYPE_READ_BUFFER: 10975 if (ddi_copyin(diag_action, &diag_read_buffer, 10976 sizeof (diag_read_buffer) - 4, ioctl_mode) != 0) { 10977 return (DDI_FAILURE); 10978 } 10979 read_buf_len = sizeof (diag_read_buffer) - 10980 sizeof (diag_read_buffer.DataBuffer) + 10981 diag_read_buffer.BytesToRead; 10982 if (length < read_buf_len) { 10983 *return_code = 10984 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10985 status = DDI_FAILURE; 10986 break; 10987 } 10988 status = mptsas_diag_read_buffer(mpt, 10989 &diag_read_buffer, diag_action + 10990 sizeof (diag_read_buffer) - 4, return_code, 10991 ioctl_mode); 10992 if (status == DDI_SUCCESS) { 10993 if (ddi_copyout(&diag_read_buffer, diag_action, 10994 sizeof (diag_read_buffer) - 4, ioctl_mode) 10995 != 0) { 10996 return (DDI_FAILURE); 10997 } 10998 } 10999 break; 11000 11001 case MPTSAS_FW_DIAG_TYPE_RELEASE: 11002 if (length < sizeof (diag_release)) { 11003 *return_code = 11004 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11005 status = DDI_FAILURE; 11006 break; 11007 } 11008 if (ddi_copyin(diag_action, &diag_release, 11009 sizeof (diag_release), ioctl_mode) != 0) { 11010 return (DDI_FAILURE); 11011 } 11012 status = mptsas_diag_release(mpt, &diag_release, 11013 return_code); 11014 break; 11015 11016 default: 11017 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11018 status = DDI_FAILURE; 11019 break; 11020 } 11021 11022 if ((status == DDI_FAILURE) && 11023 (original_return_code == MPTSAS_FW_DIAG_NEW) && 11024 (*return_code != MPTSAS_FW_DIAG_ERROR_SUCCESS)) { 11025 status = DDI_SUCCESS; 11026 } 11027 11028 return (status); 11029 } 11030 11031 static int 11032 mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *user_data, int mode) 11033 { 11034 int status; 11035 mptsas_diag_action_t driver_data; 11036 11037 ASSERT(mutex_owned(&mpt->m_mutex)); 11038 11039 /* 11040 * Copy the user data to a driver data buffer. 11041 */ 11042 if (ddi_copyin(user_data, &driver_data, sizeof (mptsas_diag_action_t), 11043 mode) == 0) { 11044 /* 11045 * Send diag action request if Action is valid 11046 */ 11047 if (driver_data.Action == MPTSAS_FW_DIAG_TYPE_REGISTER || 11048 driver_data.Action == MPTSAS_FW_DIAG_TYPE_UNREGISTER || 11049 driver_data.Action == MPTSAS_FW_DIAG_TYPE_QUERY || 11050 driver_data.Action == MPTSAS_FW_DIAG_TYPE_READ_BUFFER || 11051 driver_data.Action == MPTSAS_FW_DIAG_TYPE_RELEASE) { 11052 status = mptsas_do_diag_action(mpt, driver_data.Action, 11053 (void *)(uintptr_t)driver_data.PtrDiagAction, 11054 driver_data.Length, &driver_data.ReturnCode, 11055 mode); 11056 if (status == DDI_SUCCESS) { 11057 if (ddi_copyout(&driver_data.ReturnCode, 11058 &user_data->ReturnCode, 11059 sizeof (user_data->ReturnCode), mode) 11060 != 0) { 11061 status = EFAULT; 11062 } else { 11063 status = 0; 11064 } 11065 } else { 11066 status = EIO; 11067 } 11068 } else { 11069 status = EINVAL; 11070 } 11071 } else { 11072 status = EFAULT; 11073 } 11074 11075 return (status); 11076 } 11077 11078 /* 11079 * This routine handles the "event query" ioctl. 11080 */ 11081 static int 11082 mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, int mode, 11083 int *rval) 11084 { 11085 int status; 11086 mptsas_event_query_t driverdata; 11087 uint8_t i; 11088 11089 driverdata.Entries = MPTSAS_EVENT_QUEUE_SIZE; 11090 11091 mutex_enter(&mpt->m_mutex); 11092 for (i = 0; i < 4; i++) { 11093 driverdata.Types[i] = mpt->m_event_mask[i]; 11094 } 11095 mutex_exit(&mpt->m_mutex); 11096 11097 if (ddi_copyout(&driverdata, data, sizeof (driverdata), mode) != 0) { 11098 status = EFAULT; 11099 } else { 11100 *rval = MPTIOCTL_STATUS_GOOD; 11101 status = 0; 11102 } 11103 11104 return (status); 11105 } 11106 11107 /* 11108 * This routine handles the "event enable" ioctl. 11109 */ 11110 static int 11111 mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, int mode, 11112 int *rval) 11113 { 11114 int status; 11115 mptsas_event_enable_t driverdata; 11116 uint8_t i; 11117 11118 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) { 11119 mutex_enter(&mpt->m_mutex); 11120 for (i = 0; i < 4; i++) { 11121 mpt->m_event_mask[i] = driverdata.Types[i]; 11122 } 11123 mutex_exit(&mpt->m_mutex); 11124 11125 *rval = MPTIOCTL_STATUS_GOOD; 11126 status = 0; 11127 } else { 11128 status = EFAULT; 11129 } 11130 return (status); 11131 } 11132 11133 /* 11134 * This routine handles the "event report" ioctl. 11135 */ 11136 static int 11137 mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, int mode, 11138 int *rval) 11139 { 11140 int status; 11141 mptsas_event_report_t driverdata; 11142 11143 mutex_enter(&mpt->m_mutex); 11144 11145 if (ddi_copyin(&data->Size, &driverdata.Size, sizeof (driverdata.Size), 11146 mode) == 0) { 11147 if (driverdata.Size >= sizeof (mpt->m_events)) { 11148 if (ddi_copyout(mpt->m_events, data->Events, 11149 sizeof (mpt->m_events), mode) != 0) { 11150 status = EFAULT; 11151 } else { 11152 if (driverdata.Size > sizeof (mpt->m_events)) { 11153 driverdata.Size = 11154 sizeof (mpt->m_events); 11155 if (ddi_copyout(&driverdata.Size, 11156 &data->Size, 11157 sizeof (driverdata.Size), 11158 mode) != 0) { 11159 status = EFAULT; 11160 } else { 11161 *rval = MPTIOCTL_STATUS_GOOD; 11162 status = 0; 11163 } 11164 } else { 11165 *rval = MPTIOCTL_STATUS_GOOD; 11166 status = 0; 11167 } 11168 } 11169 } else { 11170 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT; 11171 status = 0; 11172 } 11173 } else { 11174 status = EFAULT; 11175 } 11176 11177 mutex_exit(&mpt->m_mutex); 11178 return (status); 11179 } 11180 11181 static void 11182 mptsas_lookup_pci_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data) 11183 { 11184 int *reg_data; 11185 uint_t reglen; 11186 11187 /* 11188 * Lookup the 'reg' property and extract the other data 11189 */ 11190 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip, 11191 DDI_PROP_DONTPASS, "reg", ®_data, ®len) == 11192 DDI_PROP_SUCCESS) { 11193 /* 11194 * Extract the PCI data from the 'reg' property first DWORD. 11195 * The entry looks like the following: 11196 * First DWORD: 11197 * Bits 0 - 7 8-bit Register number 11198 * Bits 8 - 10 3-bit Function number 11199 * Bits 11 - 15 5-bit Device number 11200 * Bits 16 - 23 8-bit Bus number 11201 * Bits 24 - 25 2-bit Address Space type identifier 11202 * 11203 */ 11204 adapter_data->PciInformation.u.bits.BusNumber = 11205 (reg_data[0] & 0x00FF0000) >> 16; 11206 adapter_data->PciInformation.u.bits.DeviceNumber = 11207 (reg_data[0] & 0x0000F800) >> 11; 11208 adapter_data->PciInformation.u.bits.FunctionNumber = 11209 (reg_data[0] & 0x00000700) >> 8; 11210 ddi_prop_free((void *)reg_data); 11211 } else { 11212 /* 11213 * If we can't determine the PCI data then we fill in FF's for 11214 * the data to indicate this. 11215 */ 11216 adapter_data->PCIDeviceHwId = 0xFFFFFFFF; 11217 adapter_data->MpiPortNumber = 0xFFFFFFFF; 11218 adapter_data->PciInformation.u.AsDWORD = 0xFFFFFFFF; 11219 } 11220 11221 /* 11222 * Saved in the mpt->m_fwversion 11223 */ 11224 adapter_data->MpiFirmwareVersion = mpt->m_fwversion; 11225 } 11226 11227 static void 11228 mptsas_read_adapter_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data) 11229 { 11230 char *driver_verstr = MPTSAS_MOD_STRING; 11231 11232 mptsas_lookup_pci_data(mpt, adapter_data); 11233 adapter_data->AdapterType = MPTIOCTL_ADAPTER_TYPE_SAS2; 11234 adapter_data->PCIDeviceHwId = (uint32_t)mpt->m_devid; 11235 adapter_data->PCIDeviceHwRev = (uint32_t)mpt->m_revid; 11236 adapter_data->SubSystemId = (uint32_t)mpt->m_ssid; 11237 adapter_data->SubsystemVendorId = (uint32_t)mpt->m_svid; 11238 (void) strcpy((char *)&adapter_data->DriverVersion[0], driver_verstr); 11239 adapter_data->BiosVersion = 0; 11240 (void) mptsas_get_bios_page3(mpt, &adapter_data->BiosVersion); 11241 } 11242 11243 static void 11244 mptsas_read_pci_info(mptsas_t *mpt, mptsas_pci_info_t *pci_info) 11245 { 11246 int *reg_data, i; 11247 uint_t reglen; 11248 11249 /* 11250 * Lookup the 'reg' property and extract the other data 11251 */ 11252 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip, 11253 DDI_PROP_DONTPASS, "reg", ®_data, ®len) == 11254 DDI_PROP_SUCCESS) { 11255 /* 11256 * Extract the PCI data from the 'reg' property first DWORD. 11257 * The entry looks like the following: 11258 * First DWORD: 11259 * Bits 8 - 10 3-bit Function number 11260 * Bits 11 - 15 5-bit Device number 11261 * Bits 16 - 23 8-bit Bus number 11262 */ 11263 pci_info->BusNumber = (reg_data[0] & 0x00FF0000) >> 16; 11264 pci_info->DeviceNumber = (reg_data[0] & 0x0000F800) >> 11; 11265 pci_info->FunctionNumber = (reg_data[0] & 0x00000700) >> 8; 11266 ddi_prop_free((void *)reg_data); 11267 } else { 11268 /* 11269 * If we can't determine the PCI info then we fill in FF's for 11270 * the data to indicate this. 11271 */ 11272 pci_info->BusNumber = 0xFFFFFFFF; 11273 pci_info->DeviceNumber = 0xFF; 11274 pci_info->FunctionNumber = 0xFF; 11275 } 11276 11277 /* 11278 * Now get the interrupt vector and the pci header. The vector can 11279 * only be 0 right now. The header is the first 256 bytes of config 11280 * space. 11281 */ 11282 pci_info->InterruptVector = 0; 11283 for (i = 0; i < sizeof (pci_info->PciHeader); i++) { 11284 pci_info->PciHeader[i] = pci_config_get8(mpt->m_config_handle, 11285 i); 11286 } 11287 } 11288 11289 static int 11290 mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, int mode) 11291 { 11292 int status = 0; 11293 mptsas_reg_access_t driverdata; 11294 11295 mutex_enter(&mpt->m_mutex); 11296 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) { 11297 switch (driverdata.Command) { 11298 /* 11299 * IO access is not supported. 11300 */ 11301 case REG_IO_READ: 11302 case REG_IO_WRITE: 11303 mptsas_log(mpt, CE_WARN, "IO access is not " 11304 "supported. Use memory access."); 11305 status = EINVAL; 11306 break; 11307 11308 case REG_MEM_READ: 11309 driverdata.RegData = ddi_get32(mpt->m_datap, 11310 (uint32_t *)(void *)mpt->m_reg + 11311 driverdata.RegOffset); 11312 if (ddi_copyout(&driverdata.RegData, 11313 &data->RegData, 11314 sizeof (driverdata.RegData), mode) != 0) { 11315 mptsas_log(mpt, CE_WARN, "Register " 11316 "Read Failed"); 11317 status = EFAULT; 11318 } 11319 break; 11320 11321 case REG_MEM_WRITE: 11322 ddi_put32(mpt->m_datap, 11323 (uint32_t *)(void *)mpt->m_reg + 11324 driverdata.RegOffset, 11325 driverdata.RegData); 11326 break; 11327 11328 default: 11329 status = EINVAL; 11330 break; 11331 } 11332 } else { 11333 status = EFAULT; 11334 } 11335 11336 mutex_exit(&mpt->m_mutex); 11337 return (status); 11338 } 11339 11340 static int 11341 led_control(mptsas_t *mpt, intptr_t data, int mode) 11342 { 11343 int ret = 0; 11344 mptsas_led_control_t lc; 11345 mptsas_target_t *ptgt; 11346 11347 if (ddi_copyin((void *)data, &lc, sizeof (lc), mode) != 0) { 11348 return (EFAULT); 11349 } 11350 11351 if ((lc.Command != MPTSAS_LEDCTL_FLAG_SET && 11352 lc.Command != MPTSAS_LEDCTL_FLAG_GET) || 11353 lc.Led < MPTSAS_LEDCTL_LED_MIN || 11354 lc.Led > MPTSAS_LEDCTL_LED_MAX || 11355 (lc.Command == MPTSAS_LEDCTL_FLAG_SET && lc.LedStatus != 0 && 11356 lc.LedStatus != 1)) { 11357 return (EINVAL); 11358 } 11359 11360 if ((lc.Command == MPTSAS_LEDCTL_FLAG_SET && (mode & FWRITE) == 0) || 11361 (lc.Command == MPTSAS_LEDCTL_FLAG_GET && (mode & FREAD) == 0)) 11362 return (EACCES); 11363 11364 /* Locate the target we're interrogating... */ 11365 mutex_enter(&mpt->m_mutex); 11366 ptgt = refhash_linear_search(mpt->m_targets, 11367 mptsas_target_eval_slot, &lc); 11368 if (ptgt == NULL) { 11369 /* We could not find a target for that enclosure/slot. */ 11370 mutex_exit(&mpt->m_mutex); 11371 return (ENOENT); 11372 } 11373 11374 if (lc.Command == MPTSAS_LEDCTL_FLAG_SET) { 11375 /* Update our internal LED state. */ 11376 ptgt->m_led_status &= ~(1 << (lc.Led - 1)); 11377 ptgt->m_led_status |= lc.LedStatus << (lc.Led - 1); 11378 11379 /* Flush it to the controller. */ 11380 ret = mptsas_flush_led_status(mpt, ptgt); 11381 mutex_exit(&mpt->m_mutex); 11382 return (ret); 11383 } 11384 11385 /* Return our internal LED state. */ 11386 lc.LedStatus = (ptgt->m_led_status >> (lc.Led - 1)) & 1; 11387 mutex_exit(&mpt->m_mutex); 11388 11389 if (ddi_copyout(&lc, (void *)data, sizeof (lc), mode) != 0) { 11390 return (EFAULT); 11391 } 11392 11393 return (0); 11394 } 11395 11396 static int 11397 get_disk_info(mptsas_t *mpt, intptr_t data, int mode) 11398 { 11399 uint16_t i = 0; 11400 uint16_t count = 0; 11401 int ret = 0; 11402 mptsas_target_t *ptgt; 11403 mptsas_disk_info_t *di; 11404 STRUCT_DECL(mptsas_get_disk_info, gdi); 11405 11406 if ((mode & FREAD) == 0) 11407 return (EACCES); 11408 11409 STRUCT_INIT(gdi, get_udatamodel()); 11410 11411 if (ddi_copyin((void *)data, STRUCT_BUF(gdi), STRUCT_SIZE(gdi), 11412 mode) != 0) { 11413 return (EFAULT); 11414 } 11415 11416 /* Find out how many targets there are. */ 11417 mutex_enter(&mpt->m_mutex); 11418 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 11419 ptgt = refhash_next(mpt->m_targets, ptgt)) { 11420 count++; 11421 } 11422 mutex_exit(&mpt->m_mutex); 11423 11424 /* 11425 * If we haven't been asked to copy out information on each target, 11426 * then just return the count. 11427 */ 11428 STRUCT_FSET(gdi, DiskCount, count); 11429 if (STRUCT_FGETP(gdi, PtrDiskInfoArray) == NULL) 11430 goto copy_out; 11431 11432 /* 11433 * If we haven't been given a large enough buffer to copy out into, 11434 * let the caller know. 11435 */ 11436 if (STRUCT_FGET(gdi, DiskInfoArraySize) < 11437 count * sizeof (mptsas_disk_info_t)) { 11438 ret = ENOSPC; 11439 goto copy_out; 11440 } 11441 11442 di = kmem_zalloc(count * sizeof (mptsas_disk_info_t), KM_SLEEP); 11443 11444 mutex_enter(&mpt->m_mutex); 11445 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 11446 ptgt = refhash_next(mpt->m_targets, ptgt)) { 11447 if (i >= count) { 11448 /* 11449 * The number of targets changed while we weren't 11450 * looking, so give up. 11451 */ 11452 refhash_rele(mpt->m_targets, ptgt); 11453 mutex_exit(&mpt->m_mutex); 11454 kmem_free(di, count * sizeof (mptsas_disk_info_t)); 11455 return (EAGAIN); 11456 } 11457 di[i].Instance = mpt->m_instance; 11458 di[i].Enclosure = ptgt->m_enclosure; 11459 di[i].Slot = ptgt->m_slot_num; 11460 di[i].SasAddress = ptgt->m_addr.mta_wwn; 11461 i++; 11462 } 11463 mutex_exit(&mpt->m_mutex); 11464 STRUCT_FSET(gdi, DiskCount, i); 11465 11466 /* Copy out the disk information to the caller. */ 11467 if (ddi_copyout((void *)di, STRUCT_FGETP(gdi, PtrDiskInfoArray), 11468 i * sizeof (mptsas_disk_info_t), mode) != 0) { 11469 ret = EFAULT; 11470 } 11471 11472 kmem_free(di, count * sizeof (mptsas_disk_info_t)); 11473 11474 copy_out: 11475 if (ddi_copyout(STRUCT_BUF(gdi), (void *)data, STRUCT_SIZE(gdi), 11476 mode) != 0) { 11477 ret = EFAULT; 11478 } 11479 11480 return (ret); 11481 } 11482 11483 static int 11484 mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp, 11485 int *rval) 11486 { 11487 int status = 0; 11488 mptsas_t *mpt; 11489 mptsas_update_flash_t flashdata; 11490 mptsas_pass_thru_t passthru_data; 11491 mptsas_adapter_data_t adapter_data; 11492 mptsas_pci_info_t pci_info; 11493 int copylen; 11494 11495 int iport_flag = 0; 11496 dev_info_t *dip = NULL; 11497 mptsas_phymask_t phymask = 0; 11498 struct devctl_iocdata *dcp = NULL; 11499 char *addr = NULL; 11500 mptsas_target_t *ptgt = NULL; 11501 11502 *rval = MPTIOCTL_STATUS_GOOD; 11503 if (secpolicy_sys_config(credp, B_FALSE) != 0) { 11504 return (EPERM); 11505 } 11506 11507 mpt = ddi_get_soft_state(mptsas_state, MINOR2INST(getminor(dev))); 11508 if (mpt == NULL) { 11509 /* 11510 * Called from iport node, get the states 11511 */ 11512 iport_flag = 1; 11513 dip = mptsas_get_dip_from_dev(dev, &phymask); 11514 if (dip == NULL) { 11515 return (ENXIO); 11516 } 11517 mpt = DIP2MPT(dip); 11518 } 11519 /* Make sure power level is D0 before accessing registers */ 11520 mutex_enter(&mpt->m_mutex); 11521 if (mpt->m_options & MPTSAS_OPT_PM) { 11522 (void) pm_busy_component(mpt->m_dip, 0); 11523 if (mpt->m_power_level != PM_LEVEL_D0) { 11524 mutex_exit(&mpt->m_mutex); 11525 if (pm_raise_power(mpt->m_dip, 0, PM_LEVEL_D0) != 11526 DDI_SUCCESS) { 11527 mptsas_log(mpt, CE_WARN, 11528 "mptsas%d: mptsas_ioctl: Raise power " 11529 "request failed.", mpt->m_instance); 11530 (void) pm_idle_component(mpt->m_dip, 0); 11531 return (ENXIO); 11532 } 11533 } else { 11534 mutex_exit(&mpt->m_mutex); 11535 } 11536 } else { 11537 mutex_exit(&mpt->m_mutex); 11538 } 11539 11540 if (iport_flag) { 11541 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, rval); 11542 if (status != 0) { 11543 goto out; 11544 } 11545 /* 11546 * The following code control the OK2RM LED, it doesn't affect 11547 * the ioctl return status. 11548 */ 11549 if ((cmd == DEVCTL_DEVICE_ONLINE) || 11550 (cmd == DEVCTL_DEVICE_OFFLINE)) { 11551 if (ndi_dc_allochdl((void *)data, &dcp) != 11552 NDI_SUCCESS) { 11553 goto out; 11554 } 11555 addr = ndi_dc_getaddr(dcp); 11556 ptgt = mptsas_addr_to_ptgt(mpt, addr, phymask); 11557 if (ptgt == NULL) { 11558 NDBG14(("mptsas_ioctl led control: tgt %s not " 11559 "found", addr)); 11560 ndi_dc_freehdl(dcp); 11561 goto out; 11562 } 11563 mutex_enter(&mpt->m_mutex); 11564 if (cmd == DEVCTL_DEVICE_ONLINE) { 11565 ptgt->m_tgt_unconfigured = 0; 11566 } else if (cmd == DEVCTL_DEVICE_OFFLINE) { 11567 ptgt->m_tgt_unconfigured = 1; 11568 } 11569 if (cmd == DEVCTL_DEVICE_OFFLINE) { 11570 ptgt->m_led_status |= 11571 (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1)); 11572 } else { 11573 ptgt->m_led_status &= 11574 ~(1 << (MPTSAS_LEDCTL_LED_OK2RM - 1)); 11575 } 11576 (void) mptsas_flush_led_status(mpt, ptgt); 11577 mutex_exit(&mpt->m_mutex); 11578 ndi_dc_freehdl(dcp); 11579 } 11580 goto out; 11581 } 11582 switch (cmd) { 11583 case MPTIOCTL_GET_DISK_INFO: 11584 status = get_disk_info(mpt, data, mode); 11585 break; 11586 case MPTIOCTL_LED_CONTROL: 11587 status = led_control(mpt, data, mode); 11588 break; 11589 case MPTIOCTL_UPDATE_FLASH: 11590 if (ddi_copyin((void *)data, &flashdata, 11591 sizeof (struct mptsas_update_flash), mode)) { 11592 status = EFAULT; 11593 break; 11594 } 11595 11596 mutex_enter(&mpt->m_mutex); 11597 if (mptsas_update_flash(mpt, 11598 (caddr_t)(long)flashdata.PtrBuffer, 11599 flashdata.ImageSize, flashdata.ImageType, mode)) { 11600 status = EFAULT; 11601 } 11602 11603 /* 11604 * Reset the chip to start using the new 11605 * firmware. Reset if failed also. 11606 */ 11607 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 11608 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) { 11609 status = EFAULT; 11610 } 11611 mutex_exit(&mpt->m_mutex); 11612 break; 11613 case MPTIOCTL_PASS_THRU: 11614 /* 11615 * The user has requested to pass through a command to 11616 * be executed by the MPT firmware. Call our routine 11617 * which does this. Only allow one passthru IOCTL at 11618 * one time. Other threads will block on 11619 * m_passthru_mutex, which is of adaptive variant. 11620 */ 11621 if (ddi_copyin((void *)data, &passthru_data, 11622 sizeof (mptsas_pass_thru_t), mode)) { 11623 status = EFAULT; 11624 break; 11625 } 11626 mutex_enter(&mpt->m_passthru_mutex); 11627 mutex_enter(&mpt->m_mutex); 11628 status = mptsas_pass_thru(mpt, &passthru_data, mode); 11629 mutex_exit(&mpt->m_mutex); 11630 mutex_exit(&mpt->m_passthru_mutex); 11631 11632 break; 11633 case MPTIOCTL_GET_ADAPTER_DATA: 11634 /* 11635 * The user has requested to read adapter data. Call 11636 * our routine which does this. 11637 */ 11638 bzero(&adapter_data, sizeof (mptsas_adapter_data_t)); 11639 if (ddi_copyin((void *)data, (void *)&adapter_data, 11640 sizeof (mptsas_adapter_data_t), mode)) { 11641 status = EFAULT; 11642 break; 11643 } 11644 if (adapter_data.StructureLength >= 11645 sizeof (mptsas_adapter_data_t)) { 11646 adapter_data.StructureLength = (uint32_t) 11647 sizeof (mptsas_adapter_data_t); 11648 copylen = sizeof (mptsas_adapter_data_t); 11649 mutex_enter(&mpt->m_mutex); 11650 mptsas_read_adapter_data(mpt, &adapter_data); 11651 mutex_exit(&mpt->m_mutex); 11652 } else { 11653 adapter_data.StructureLength = (uint32_t) 11654 sizeof (mptsas_adapter_data_t); 11655 copylen = sizeof (adapter_data.StructureLength); 11656 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT; 11657 } 11658 if (ddi_copyout((void *)(&adapter_data), (void *)data, 11659 copylen, mode) != 0) { 11660 status = EFAULT; 11661 } 11662 break; 11663 case MPTIOCTL_GET_PCI_INFO: 11664 /* 11665 * The user has requested to read pci info. Call 11666 * our routine which does this. 11667 */ 11668 bzero(&pci_info, sizeof (mptsas_pci_info_t)); 11669 mutex_enter(&mpt->m_mutex); 11670 mptsas_read_pci_info(mpt, &pci_info); 11671 mutex_exit(&mpt->m_mutex); 11672 if (ddi_copyout((void *)(&pci_info), (void *)data, 11673 sizeof (mptsas_pci_info_t), mode) != 0) { 11674 status = EFAULT; 11675 } 11676 break; 11677 case MPTIOCTL_RESET_ADAPTER: 11678 mutex_enter(&mpt->m_mutex); 11679 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 11680 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 11681 mptsas_log(mpt, CE_WARN, "reset adapter IOCTL " 11682 "failed"); 11683 status = EFAULT; 11684 } 11685 mutex_exit(&mpt->m_mutex); 11686 break; 11687 case MPTIOCTL_DIAG_ACTION: 11688 /* 11689 * The user has done a diag buffer action. Call our 11690 * routine which does this. Only allow one diag action 11691 * at one time. 11692 */ 11693 mutex_enter(&mpt->m_mutex); 11694 if (mpt->m_diag_action_in_progress) { 11695 mutex_exit(&mpt->m_mutex); 11696 return (EBUSY); 11697 } 11698 mpt->m_diag_action_in_progress = 1; 11699 status = mptsas_diag_action(mpt, 11700 (mptsas_diag_action_t *)data, mode); 11701 mpt->m_diag_action_in_progress = 0; 11702 mutex_exit(&mpt->m_mutex); 11703 break; 11704 case MPTIOCTL_EVENT_QUERY: 11705 /* 11706 * The user has done an event query. Call our routine 11707 * which does this. 11708 */ 11709 status = mptsas_event_query(mpt, 11710 (mptsas_event_query_t *)data, mode, rval); 11711 break; 11712 case MPTIOCTL_EVENT_ENABLE: 11713 /* 11714 * The user has done an event enable. Call our routine 11715 * which does this. 11716 */ 11717 status = mptsas_event_enable(mpt, 11718 (mptsas_event_enable_t *)data, mode, rval); 11719 break; 11720 case MPTIOCTL_EVENT_REPORT: 11721 /* 11722 * The user has done an event report. Call our routine 11723 * which does this. 11724 */ 11725 status = mptsas_event_report(mpt, 11726 (mptsas_event_report_t *)data, mode, rval); 11727 break; 11728 case MPTIOCTL_REG_ACCESS: 11729 /* 11730 * The user has requested register access. Call our 11731 * routine which does this. 11732 */ 11733 status = mptsas_reg_access(mpt, 11734 (mptsas_reg_access_t *)data, mode); 11735 break; 11736 default: 11737 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, 11738 rval); 11739 break; 11740 } 11741 11742 out: 11743 return (status); 11744 } 11745 11746 int 11747 mptsas_restart_ioc(mptsas_t *mpt) 11748 { 11749 int rval = DDI_SUCCESS; 11750 mptsas_target_t *ptgt = NULL; 11751 11752 ASSERT(mutex_owned(&mpt->m_mutex)); 11753 11754 /* 11755 * Set a flag telling I/O path that we're processing a reset. This is 11756 * needed because after the reset is complete, the hash table still 11757 * needs to be rebuilt. If I/Os are started before the hash table is 11758 * rebuilt, I/O errors will occur. This flag allows I/Os to be marked 11759 * so that they can be retried. 11760 */ 11761 mpt->m_in_reset = TRUE; 11762 11763 /* 11764 * Set all throttles to HOLD 11765 */ 11766 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 11767 ptgt = refhash_next(mpt->m_targets, ptgt)) { 11768 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 11769 } 11770 11771 /* 11772 * Disable interrupts 11773 */ 11774 MPTSAS_DISABLE_INTR(mpt); 11775 11776 /* 11777 * Abort all commands: outstanding commands, commands in waitq and 11778 * tx_waitq. 11779 */ 11780 mptsas_flush_hba(mpt); 11781 11782 /* 11783 * Reinitialize the chip. 11784 */ 11785 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) { 11786 rval = DDI_FAILURE; 11787 } 11788 11789 /* 11790 * Enable interrupts again 11791 */ 11792 MPTSAS_ENABLE_INTR(mpt); 11793 11794 /* 11795 * If mptsas_init_chip was successful, update the driver data. 11796 */ 11797 if (rval == DDI_SUCCESS) { 11798 mptsas_update_driver_data(mpt); 11799 } 11800 11801 /* 11802 * Reset the throttles 11803 */ 11804 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 11805 ptgt = refhash_next(mpt->m_targets, ptgt)) { 11806 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 11807 } 11808 11809 mptsas_doneq_empty(mpt); 11810 mptsas_restart_hba(mpt); 11811 11812 if (rval != DDI_SUCCESS) { 11813 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 11814 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 11815 } 11816 11817 /* 11818 * Clear the reset flag so that I/Os can continue. 11819 */ 11820 mpt->m_in_reset = FALSE; 11821 11822 return (rval); 11823 } 11824 11825 static int 11826 mptsas_init_chip(mptsas_t *mpt, int first_time) 11827 { 11828 ddi_dma_cookie_t cookie; 11829 uint32_t i; 11830 int rval; 11831 11832 /* 11833 * Check to see if the firmware image is valid 11834 */ 11835 if (ddi_get32(mpt->m_datap, &mpt->m_reg->HostDiagnostic) & 11836 MPI2_DIAG_FLASH_BAD_SIG) { 11837 mptsas_log(mpt, CE_WARN, "mptsas bad flash signature!"); 11838 goto fail; 11839 } 11840 11841 /* 11842 * Reset the chip 11843 */ 11844 rval = mptsas_ioc_reset(mpt, first_time); 11845 if (rval == MPTSAS_RESET_FAIL) { 11846 mptsas_log(mpt, CE_WARN, "hard reset failed!"); 11847 goto fail; 11848 } 11849 11850 if ((rval == MPTSAS_SUCCESS_MUR) && (!first_time)) { 11851 goto mur; 11852 } 11853 /* 11854 * Setup configuration space 11855 */ 11856 if (mptsas_config_space_init(mpt) == FALSE) { 11857 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init " 11858 "failed!"); 11859 goto fail; 11860 } 11861 11862 /* 11863 * IOC facts can change after a diag reset so all buffers that are 11864 * based on these numbers must be de-allocated and re-allocated. Get 11865 * new IOC facts each time chip is initialized. 11866 */ 11867 if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) { 11868 mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed"); 11869 goto fail; 11870 } 11871 11872 mpt->m_targets = refhash_create(MPTSAS_TARGET_BUCKET_COUNT, 11873 mptsas_target_addr_hash, mptsas_target_addr_cmp, 11874 mptsas_target_free, sizeof (mptsas_target_t), 11875 offsetof(mptsas_target_t, m_link), 11876 offsetof(mptsas_target_t, m_addr), KM_SLEEP); 11877 11878 if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) { 11879 goto fail; 11880 } 11881 /* 11882 * Allocate request message frames, reply free queue, reply descriptor 11883 * post queue, and reply message frames using latest IOC facts. 11884 */ 11885 if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) { 11886 mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed"); 11887 goto fail; 11888 } 11889 if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) { 11890 mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue failed!"); 11891 goto fail; 11892 } 11893 if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) { 11894 mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue failed!"); 11895 goto fail; 11896 } 11897 if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) { 11898 mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames failed!"); 11899 goto fail; 11900 } 11901 11902 mur: 11903 /* 11904 * Re-Initialize ioc to operational state 11905 */ 11906 if (mptsas_ioc_init(mpt) == DDI_FAILURE) { 11907 mptsas_log(mpt, CE_WARN, "mptsas_ioc_init failed"); 11908 goto fail; 11909 } 11910 11911 mptsas_alloc_reply_args(mpt); 11912 11913 /* 11914 * Initialize reply post index. Reply free index is initialized after 11915 * the next loop. 11916 */ 11917 mpt->m_post_index = 0; 11918 11919 /* 11920 * Initialize the Reply Free Queue with the physical addresses of our 11921 * reply frames. 11922 */ 11923 cookie.dmac_address = mpt->m_reply_frame_dma_addr; 11924 for (i = 0; i < mpt->m_max_replies; i++) { 11925 ddi_put32(mpt->m_acc_free_queue_hdl, 11926 &((uint32_t *)(void *)mpt->m_free_queue)[i], 11927 cookie.dmac_address); 11928 cookie.dmac_address += mpt->m_reply_frame_size; 11929 } 11930 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 11931 DDI_DMA_SYNC_FORDEV); 11932 11933 /* 11934 * Initialize the reply free index to one past the last frame on the 11935 * queue. This will signify that the queue is empty to start with. 11936 */ 11937 mpt->m_free_index = i; 11938 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, i); 11939 11940 /* 11941 * Initialize the reply post queue to 0xFFFFFFFF,0xFFFFFFFF's. 11942 */ 11943 for (i = 0; i < mpt->m_post_queue_depth; i++) { 11944 ddi_put64(mpt->m_acc_post_queue_hdl, 11945 &((uint64_t *)(void *)mpt->m_post_queue)[i], 11946 0xFFFFFFFFFFFFFFFF); 11947 } 11948 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 11949 DDI_DMA_SYNC_FORDEV); 11950 11951 /* 11952 * Enable ports 11953 */ 11954 if (mptsas_ioc_enable_port(mpt) == DDI_FAILURE) { 11955 mptsas_log(mpt, CE_WARN, "mptsas_ioc_enable_port failed"); 11956 goto fail; 11957 } 11958 11959 /* 11960 * enable events 11961 */ 11962 if (mptsas_ioc_enable_event_notification(mpt)) { 11963 goto fail; 11964 } 11965 11966 /* 11967 * We need checks in attach and these. 11968 * chip_init is called in mult. places 11969 */ 11970 11971 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 11972 DDI_SUCCESS) || 11973 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) != 11974 DDI_SUCCESS) || 11975 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) != 11976 DDI_SUCCESS) || 11977 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) != 11978 DDI_SUCCESS) || 11979 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) != 11980 DDI_SUCCESS)) { 11981 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 11982 goto fail; 11983 } 11984 11985 /* Check all acc handles */ 11986 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) || 11987 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 11988 DDI_SUCCESS) || 11989 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) != 11990 DDI_SUCCESS) || 11991 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) != 11992 DDI_SUCCESS) || 11993 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) != 11994 DDI_SUCCESS) || 11995 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) != 11996 DDI_SUCCESS) || 11997 (mptsas_check_acc_handle(mpt->m_config_handle) != 11998 DDI_SUCCESS)) { 11999 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 12000 goto fail; 12001 } 12002 12003 return (DDI_SUCCESS); 12004 12005 fail: 12006 return (DDI_FAILURE); 12007 } 12008 12009 static int 12010 mptsas_get_pci_cap(mptsas_t *mpt) 12011 { 12012 ushort_t caps_ptr, cap, cap_count; 12013 12014 if (mpt->m_config_handle == NULL) 12015 return (FALSE); 12016 /* 12017 * Check if capabilities list is supported and if so, 12018 * get initial capabilities pointer and clear bits 0,1. 12019 */ 12020 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) 12021 & PCI_STAT_CAP) { 12022 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle, 12023 PCI_CONF_CAP_PTR), 4); 12024 } else { 12025 caps_ptr = PCI_CAP_NEXT_PTR_NULL; 12026 } 12027 12028 /* 12029 * Walk capabilities if supported. 12030 */ 12031 for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) { 12032 12033 /* 12034 * Check that we haven't exceeded the maximum number of 12035 * capabilities and that the pointer is in a valid range. 12036 */ 12037 if (++cap_count > 48) { 12038 mptsas_log(mpt, CE_WARN, 12039 "too many device capabilities.\n"); 12040 break; 12041 } 12042 if (caps_ptr < 64) { 12043 mptsas_log(mpt, CE_WARN, 12044 "capabilities pointer 0x%x out of range.\n", 12045 caps_ptr); 12046 break; 12047 } 12048 12049 /* 12050 * Get next capability and check that it is valid. 12051 * For now, we only support power management. 12052 */ 12053 cap = pci_config_get8(mpt->m_config_handle, caps_ptr); 12054 switch (cap) { 12055 case PCI_CAP_ID_PM: 12056 mptsas_log(mpt, CE_NOTE, 12057 "?mptsas%d supports power management.\n", 12058 mpt->m_instance); 12059 mpt->m_options |= MPTSAS_OPT_PM; 12060 12061 /* Save PMCSR offset */ 12062 mpt->m_pmcsr_offset = caps_ptr + PCI_PMCSR; 12063 break; 12064 /* 12065 * The following capabilities are valid. Any others 12066 * will cause a message to be logged. 12067 */ 12068 case PCI_CAP_ID_VPD: 12069 case PCI_CAP_ID_MSI: 12070 case PCI_CAP_ID_PCIX: 12071 case PCI_CAP_ID_PCI_E: 12072 case PCI_CAP_ID_MSI_X: 12073 break; 12074 default: 12075 mptsas_log(mpt, CE_NOTE, 12076 "?mptsas%d unrecognized capability " 12077 "0x%x.\n", mpt->m_instance, cap); 12078 break; 12079 } 12080 12081 /* 12082 * Get next capabilities pointer and clear bits 0,1. 12083 */ 12084 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle, 12085 (caps_ptr + PCI_CAP_NEXT_PTR)), 4); 12086 } 12087 return (TRUE); 12088 } 12089 12090 static int 12091 mptsas_init_pm(mptsas_t *mpt) 12092 { 12093 char pmc_name[16]; 12094 char *pmc[] = { 12095 NULL, 12096 "0=Off (PCI D3 State)", 12097 "3=On (PCI D0 State)", 12098 NULL 12099 }; 12100 uint16_t pmcsr_stat; 12101 12102 if (mptsas_get_pci_cap(mpt) == FALSE) { 12103 return (DDI_FAILURE); 12104 } 12105 /* 12106 * If PCI's capability does not support PM, then don't need 12107 * to registe the pm-components 12108 */ 12109 if (!(mpt->m_options & MPTSAS_OPT_PM)) 12110 return (DDI_SUCCESS); 12111 /* 12112 * If power management is supported by this chip, create 12113 * pm-components property for the power management framework 12114 */ 12115 (void) sprintf(pmc_name, "NAME=mptsas%d", mpt->m_instance); 12116 pmc[0] = pmc_name; 12117 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, mpt->m_dip, 12118 "pm-components", pmc, 3) != DDI_PROP_SUCCESS) { 12119 mpt->m_options &= ~MPTSAS_OPT_PM; 12120 mptsas_log(mpt, CE_WARN, 12121 "mptsas%d: pm-component property creation failed.", 12122 mpt->m_instance); 12123 return (DDI_FAILURE); 12124 } 12125 12126 /* 12127 * Power on device. 12128 */ 12129 (void) pm_busy_component(mpt->m_dip, 0); 12130 pmcsr_stat = pci_config_get16(mpt->m_config_handle, 12131 mpt->m_pmcsr_offset); 12132 if ((pmcsr_stat & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_D0) { 12133 mptsas_log(mpt, CE_WARN, "mptsas%d: Power up the device", 12134 mpt->m_instance); 12135 pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset, 12136 PCI_PMCSR_D0); 12137 } 12138 if (pm_power_has_changed(mpt->m_dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) { 12139 mptsas_log(mpt, CE_WARN, "pm_power_has_changed failed"); 12140 return (DDI_FAILURE); 12141 } 12142 mpt->m_power_level = PM_LEVEL_D0; 12143 /* 12144 * Set pm idle delay. 12145 */ 12146 mpt->m_pm_idle_delay = ddi_prop_get_int(DDI_DEV_T_ANY, 12147 mpt->m_dip, 0, "mptsas-pm-idle-delay", MPTSAS_PM_IDLE_TIMEOUT); 12148 12149 return (DDI_SUCCESS); 12150 } 12151 12152 static int 12153 mptsas_register_intrs(mptsas_t *mpt) 12154 { 12155 dev_info_t *dip; 12156 int intr_types; 12157 12158 dip = mpt->m_dip; 12159 12160 /* Get supported interrupt types */ 12161 if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) { 12162 mptsas_log(mpt, CE_WARN, "ddi_intr_get_supported_types " 12163 "failed\n"); 12164 return (FALSE); 12165 } 12166 12167 NDBG6(("ddi_intr_get_supported_types() returned: 0x%x", intr_types)); 12168 12169 /* 12170 * Try MSI, but fall back to FIXED 12171 */ 12172 if (mptsas_enable_msi && (intr_types & DDI_INTR_TYPE_MSI)) { 12173 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_MSI) == DDI_SUCCESS) { 12174 NDBG0(("Using MSI interrupt type")); 12175 mpt->m_intr_type = DDI_INTR_TYPE_MSI; 12176 return (TRUE); 12177 } 12178 } 12179 if (intr_types & DDI_INTR_TYPE_FIXED) { 12180 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_FIXED) == DDI_SUCCESS) { 12181 NDBG0(("Using FIXED interrupt type")); 12182 mpt->m_intr_type = DDI_INTR_TYPE_FIXED; 12183 return (TRUE); 12184 } else { 12185 NDBG0(("FIXED interrupt registration failed")); 12186 return (FALSE); 12187 } 12188 } 12189 12190 return (FALSE); 12191 } 12192 12193 static void 12194 mptsas_unregister_intrs(mptsas_t *mpt) 12195 { 12196 mptsas_rem_intrs(mpt); 12197 } 12198 12199 /* 12200 * mptsas_add_intrs: 12201 * 12202 * Register FIXED or MSI interrupts. 12203 */ 12204 static int 12205 mptsas_add_intrs(mptsas_t *mpt, int intr_type) 12206 { 12207 dev_info_t *dip = mpt->m_dip; 12208 int avail, actual, count = 0; 12209 int i, flag, ret; 12210 12211 NDBG6(("mptsas_add_intrs:interrupt type 0x%x", intr_type)); 12212 12213 /* Get number of interrupts */ 12214 ret = ddi_intr_get_nintrs(dip, intr_type, &count); 12215 if ((ret != DDI_SUCCESS) || (count <= 0)) { 12216 mptsas_log(mpt, CE_WARN, "ddi_intr_get_nintrs() failed, " 12217 "ret %d count %d\n", ret, count); 12218 12219 return (DDI_FAILURE); 12220 } 12221 12222 /* Get number of available interrupts */ 12223 ret = ddi_intr_get_navail(dip, intr_type, &avail); 12224 if ((ret != DDI_SUCCESS) || (avail == 0)) { 12225 mptsas_log(mpt, CE_WARN, "ddi_intr_get_navail() failed, " 12226 "ret %d avail %d\n", ret, avail); 12227 12228 return (DDI_FAILURE); 12229 } 12230 12231 if (avail < count) { 12232 mptsas_log(mpt, CE_NOTE, "ddi_intr_get_nvail returned %d, " 12233 "navail() returned %d", count, avail); 12234 } 12235 12236 /* Mpt only have one interrupt routine */ 12237 if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) { 12238 count = 1; 12239 } 12240 12241 /* Allocate an array of interrupt handles */ 12242 mpt->m_intr_size = count * sizeof (ddi_intr_handle_t); 12243 mpt->m_htable = kmem_alloc(mpt->m_intr_size, KM_SLEEP); 12244 12245 flag = DDI_INTR_ALLOC_NORMAL; 12246 12247 /* call ddi_intr_alloc() */ 12248 ret = ddi_intr_alloc(dip, mpt->m_htable, intr_type, 0, 12249 count, &actual, flag); 12250 12251 if ((ret != DDI_SUCCESS) || (actual == 0)) { 12252 mptsas_log(mpt, CE_WARN, "ddi_intr_alloc() failed, ret %d\n", 12253 ret); 12254 kmem_free(mpt->m_htable, mpt->m_intr_size); 12255 return (DDI_FAILURE); 12256 } 12257 12258 /* use interrupt count returned or abort? */ 12259 if (actual < count) { 12260 mptsas_log(mpt, CE_NOTE, "Requested: %d, Received: %d\n", 12261 count, actual); 12262 } 12263 12264 mpt->m_intr_cnt = actual; 12265 12266 /* 12267 * Get priority for first msi, assume remaining are all the same 12268 */ 12269 if ((ret = ddi_intr_get_pri(mpt->m_htable[0], 12270 &mpt->m_intr_pri)) != DDI_SUCCESS) { 12271 mptsas_log(mpt, CE_WARN, "ddi_intr_get_pri() failed %d\n", ret); 12272 12273 /* Free already allocated intr */ 12274 for (i = 0; i < actual; i++) { 12275 (void) ddi_intr_free(mpt->m_htable[i]); 12276 } 12277 12278 kmem_free(mpt->m_htable, mpt->m_intr_size); 12279 return (DDI_FAILURE); 12280 } 12281 12282 /* Test for high level mutex */ 12283 if (mpt->m_intr_pri >= ddi_intr_get_hilevel_pri()) { 12284 mptsas_log(mpt, CE_WARN, "mptsas_add_intrs: " 12285 "Hi level interrupt not supported\n"); 12286 12287 /* Free already allocated intr */ 12288 for (i = 0; i < actual; i++) { 12289 (void) ddi_intr_free(mpt->m_htable[i]); 12290 } 12291 12292 kmem_free(mpt->m_htable, mpt->m_intr_size); 12293 return (DDI_FAILURE); 12294 } 12295 12296 /* Call ddi_intr_add_handler() */ 12297 for (i = 0; i < actual; i++) { 12298 if ((ret = ddi_intr_add_handler(mpt->m_htable[i], mptsas_intr, 12299 (caddr_t)mpt, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) { 12300 mptsas_log(mpt, CE_WARN, "ddi_intr_add_handler() " 12301 "failed %d\n", ret); 12302 12303 /* Free already allocated intr */ 12304 for (i = 0; i < actual; i++) { 12305 (void) ddi_intr_free(mpt->m_htable[i]); 12306 } 12307 12308 kmem_free(mpt->m_htable, mpt->m_intr_size); 12309 return (DDI_FAILURE); 12310 } 12311 } 12312 12313 if ((ret = ddi_intr_get_cap(mpt->m_htable[0], &mpt->m_intr_cap)) 12314 != DDI_SUCCESS) { 12315 mptsas_log(mpt, CE_WARN, "ddi_intr_get_cap() failed %d\n", ret); 12316 12317 /* Free already allocated intr */ 12318 for (i = 0; i < actual; i++) { 12319 (void) ddi_intr_free(mpt->m_htable[i]); 12320 } 12321 12322 kmem_free(mpt->m_htable, mpt->m_intr_size); 12323 return (DDI_FAILURE); 12324 } 12325 12326 /* 12327 * Enable interrupts 12328 */ 12329 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) { 12330 /* Call ddi_intr_block_enable() for MSI interrupts */ 12331 (void) ddi_intr_block_enable(mpt->m_htable, mpt->m_intr_cnt); 12332 } else { 12333 /* Call ddi_intr_enable for MSI or FIXED interrupts */ 12334 for (i = 0; i < mpt->m_intr_cnt; i++) { 12335 (void) ddi_intr_enable(mpt->m_htable[i]); 12336 } 12337 } 12338 return (DDI_SUCCESS); 12339 } 12340 12341 /* 12342 * mptsas_rem_intrs: 12343 * 12344 * Unregister FIXED or MSI interrupts 12345 */ 12346 static void 12347 mptsas_rem_intrs(mptsas_t *mpt) 12348 { 12349 int i; 12350 12351 NDBG6(("mptsas_rem_intrs")); 12352 12353 /* Disable all interrupts */ 12354 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) { 12355 /* Call ddi_intr_block_disable() */ 12356 (void) ddi_intr_block_disable(mpt->m_htable, mpt->m_intr_cnt); 12357 } else { 12358 for (i = 0; i < mpt->m_intr_cnt; i++) { 12359 (void) ddi_intr_disable(mpt->m_htable[i]); 12360 } 12361 } 12362 12363 /* Call ddi_intr_remove_handler() */ 12364 for (i = 0; i < mpt->m_intr_cnt; i++) { 12365 (void) ddi_intr_remove_handler(mpt->m_htable[i]); 12366 (void) ddi_intr_free(mpt->m_htable[i]); 12367 } 12368 12369 kmem_free(mpt->m_htable, mpt->m_intr_size); 12370 } 12371 12372 /* 12373 * The IO fault service error handling callback function 12374 */ 12375 /*ARGSUSED*/ 12376 static int 12377 mptsas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data) 12378 { 12379 /* 12380 * as the driver can always deal with an error in any dma or 12381 * access handle, we can just return the fme_status value. 12382 */ 12383 pci_ereport_post(dip, err, NULL); 12384 return (err->fme_status); 12385 } 12386 12387 /* 12388 * mptsas_fm_init - initialize fma capabilities and register with IO 12389 * fault services. 12390 */ 12391 static void 12392 mptsas_fm_init(mptsas_t *mpt) 12393 { 12394 /* 12395 * Need to change iblock to priority for new MSI intr 12396 */ 12397 ddi_iblock_cookie_t fm_ibc; 12398 12399 /* Only register with IO Fault Services if we have some capability */ 12400 if (mpt->m_fm_capabilities) { 12401 /* Adjust access and dma attributes for FMA */ 12402 mpt->m_reg_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC; 12403 mpt->m_msg_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 12404 mpt->m_io_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 12405 12406 /* 12407 * Register capabilities with IO Fault Services. 12408 * mpt->m_fm_capabilities will be updated to indicate 12409 * capabilities actually supported (not requested.) 12410 */ 12411 ddi_fm_init(mpt->m_dip, &mpt->m_fm_capabilities, &fm_ibc); 12412 12413 /* 12414 * Initialize pci ereport capabilities if ereport 12415 * capable (should always be.) 12416 */ 12417 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) || 12418 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 12419 pci_ereport_setup(mpt->m_dip); 12420 } 12421 12422 /* 12423 * Register error callback if error callback capable. 12424 */ 12425 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 12426 ddi_fm_handler_register(mpt->m_dip, 12427 mptsas_fm_error_cb, (void *) mpt); 12428 } 12429 } 12430 } 12431 12432 /* 12433 * mptsas_fm_fini - Releases fma capabilities and un-registers with IO 12434 * fault services. 12435 * 12436 */ 12437 static void 12438 mptsas_fm_fini(mptsas_t *mpt) 12439 { 12440 /* Only unregister FMA capabilities if registered */ 12441 if (mpt->m_fm_capabilities) { 12442 12443 /* 12444 * Un-register error callback if error callback capable. 12445 */ 12446 12447 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 12448 ddi_fm_handler_unregister(mpt->m_dip); 12449 } 12450 12451 /* 12452 * Release any resources allocated by pci_ereport_setup() 12453 */ 12454 12455 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) || 12456 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 12457 pci_ereport_teardown(mpt->m_dip); 12458 } 12459 12460 /* Unregister from IO Fault Services */ 12461 ddi_fm_fini(mpt->m_dip); 12462 12463 /* Adjust access and dma attributes for FMA */ 12464 mpt->m_reg_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC; 12465 mpt->m_msg_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 12466 mpt->m_io_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 12467 12468 } 12469 } 12470 12471 int 12472 mptsas_check_acc_handle(ddi_acc_handle_t handle) 12473 { 12474 ddi_fm_error_t de; 12475 12476 if (handle == NULL) 12477 return (DDI_FAILURE); 12478 ddi_fm_acc_err_get(handle, &de, DDI_FME_VER0); 12479 return (de.fme_status); 12480 } 12481 12482 int 12483 mptsas_check_dma_handle(ddi_dma_handle_t handle) 12484 { 12485 ddi_fm_error_t de; 12486 12487 if (handle == NULL) 12488 return (DDI_FAILURE); 12489 ddi_fm_dma_err_get(handle, &de, DDI_FME_VER0); 12490 return (de.fme_status); 12491 } 12492 12493 void 12494 mptsas_fm_ereport(mptsas_t *mpt, char *detail) 12495 { 12496 uint64_t ena; 12497 char buf[FM_MAX_CLASS]; 12498 12499 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail); 12500 ena = fm_ena_generate(0, FM_ENA_FMT1); 12501 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities)) { 12502 ddi_fm_ereport_post(mpt->m_dip, buf, ena, DDI_NOSLEEP, 12503 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL); 12504 } 12505 } 12506 12507 static int 12508 mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address, 12509 uint16_t *dev_handle, mptsas_target_t **pptgt) 12510 { 12511 int rval; 12512 uint32_t dev_info; 12513 uint64_t sas_wwn; 12514 mptsas_phymask_t phymask; 12515 uint8_t physport, phynum, config, disk; 12516 uint64_t devicename; 12517 uint16_t pdev_hdl; 12518 mptsas_target_t *tmp_tgt = NULL; 12519 uint16_t bay_num, enclosure; 12520 12521 ASSERT(*pptgt == NULL); 12522 12523 rval = mptsas_get_sas_device_page0(mpt, page_address, dev_handle, 12524 &sas_wwn, &dev_info, &physport, &phynum, &pdev_hdl, 12525 &bay_num, &enclosure); 12526 if (rval != DDI_SUCCESS) { 12527 rval = DEV_INFO_FAIL_PAGE0; 12528 return (rval); 12529 } 12530 12531 if ((dev_info & (MPI2_SAS_DEVICE_INFO_SSP_TARGET | 12532 MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 12533 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) == NULL) { 12534 rval = DEV_INFO_WRONG_DEVICE_TYPE; 12535 return (rval); 12536 } 12537 12538 /* 12539 * Check if the dev handle is for a Phys Disk. If so, set return value 12540 * and exit. Don't add Phys Disks to hash. 12541 */ 12542 for (config = 0; config < mpt->m_num_raid_configs; config++) { 12543 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) { 12544 if (*dev_handle == mpt->m_raidconfig[config]. 12545 m_physdisk_devhdl[disk]) { 12546 rval = DEV_INFO_PHYS_DISK; 12547 return (rval); 12548 } 12549 } 12550 } 12551 12552 /* 12553 * Get SATA Device Name from SAS device page0 for 12554 * sata device, if device name doesn't exist, set mta_wwn to 12555 * 0 for direct attached SATA. For the device behind the expander 12556 * we still can use STP address assigned by expander. 12557 */ 12558 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 12559 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 12560 mutex_exit(&mpt->m_mutex); 12561 /* alloc a tmp_tgt to send the cmd */ 12562 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), 12563 KM_SLEEP); 12564 tmp_tgt->m_devhdl = *dev_handle; 12565 tmp_tgt->m_deviceinfo = dev_info; 12566 tmp_tgt->m_qfull_retries = QFULL_RETRIES; 12567 tmp_tgt->m_qfull_retry_interval = 12568 drv_usectohz(QFULL_RETRY_INTERVAL * 1000); 12569 tmp_tgt->m_t_throttle = MAX_THROTTLE; 12570 devicename = mptsas_get_sata_guid(mpt, tmp_tgt, 0); 12571 kmem_free(tmp_tgt, sizeof (struct mptsas_target)); 12572 mutex_enter(&mpt->m_mutex); 12573 if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) { 12574 sas_wwn = devicename; 12575 } else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) { 12576 sas_wwn = 0; 12577 } 12578 } 12579 12580 phymask = mptsas_physport_to_phymask(mpt, physport); 12581 *pptgt = mptsas_tgt_alloc(mpt, *dev_handle, sas_wwn, 12582 dev_info, phymask, phynum); 12583 if (*pptgt == NULL) { 12584 mptsas_log(mpt, CE_WARN, "Failed to allocated target" 12585 "structure!"); 12586 rval = DEV_INFO_FAIL_ALLOC; 12587 return (rval); 12588 } 12589 (*pptgt)->m_enclosure = enclosure; 12590 (*pptgt)->m_slot_num = bay_num; 12591 return (DEV_INFO_SUCCESS); 12592 } 12593 12594 uint64_t 12595 mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun) 12596 { 12597 uint64_t sata_guid = 0, *pwwn = NULL; 12598 int target = ptgt->m_devhdl; 12599 uchar_t *inq83 = NULL; 12600 int inq83_len = 0xFF; 12601 uchar_t *dblk = NULL; 12602 int inq83_retry = 3; 12603 int rval = DDI_FAILURE; 12604 12605 inq83 = kmem_zalloc(inq83_len, KM_SLEEP); 12606 12607 inq83_retry: 12608 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83, 12609 inq83_len, NULL, 1); 12610 if (rval != DDI_SUCCESS) { 12611 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 12612 "0x83 for target:%x, lun:%x failed!", target, lun); 12613 goto out; 12614 } 12615 /* According to SAT2, the first descriptor is logic unit name */ 12616 dblk = &inq83[4]; 12617 if ((dblk[1] & 0x30) != 0) { 12618 mptsas_log(mpt, CE_WARN, "!Descriptor is not lun associated."); 12619 goto out; 12620 } 12621 pwwn = (uint64_t *)(void *)(&dblk[4]); 12622 if ((dblk[4] & 0xf0) == 0x50) { 12623 sata_guid = BE_64(*pwwn); 12624 goto out; 12625 } else if (dblk[4] == 'A') { 12626 NDBG20(("SATA drive has no NAA format GUID.")); 12627 goto out; 12628 } else { 12629 /* The data is not ready, wait and retry */ 12630 inq83_retry--; 12631 if (inq83_retry <= 0) { 12632 goto out; 12633 } 12634 NDBG20(("The GUID is not ready, retry...")); 12635 delay(1 * drv_usectohz(1000000)); 12636 goto inq83_retry; 12637 } 12638 out: 12639 kmem_free(inq83, inq83_len); 12640 return (sata_guid); 12641 } 12642 12643 static int 12644 mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, uchar_t page, 12645 unsigned char *buf, int len, int *reallen, uchar_t evpd) 12646 { 12647 uchar_t cdb[CDB_GROUP0]; 12648 struct scsi_address ap; 12649 struct buf *data_bp = NULL; 12650 int resid = 0; 12651 int ret = DDI_FAILURE; 12652 12653 ASSERT(len <= 0xffff); 12654 12655 ap.a_target = MPTSAS_INVALID_DEVHDL; 12656 ap.a_lun = (uchar_t)(lun); 12657 ap.a_hba_tran = mpt->m_tran; 12658 12659 data_bp = scsi_alloc_consistent_buf(&ap, 12660 (struct buf *)NULL, len, B_READ, NULL_FUNC, NULL); 12661 if (data_bp == NULL) { 12662 return (ret); 12663 } 12664 bzero(cdb, CDB_GROUP0); 12665 cdb[0] = SCMD_INQUIRY; 12666 cdb[1] = evpd; 12667 cdb[2] = page; 12668 cdb[3] = (len & 0xff00) >> 8; 12669 cdb[4] = (len & 0x00ff); 12670 cdb[5] = 0; 12671 12672 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP0, data_bp, 12673 &resid); 12674 if (ret == DDI_SUCCESS) { 12675 if (reallen) { 12676 *reallen = len - resid; 12677 } 12678 bcopy((caddr_t)data_bp->b_un.b_addr, buf, len); 12679 } 12680 if (data_bp) { 12681 scsi_free_consistent_buf(data_bp); 12682 } 12683 return (ret); 12684 } 12685 12686 static int 12687 mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap, 12688 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp, 12689 int *resid) 12690 { 12691 struct scsi_pkt *pktp = NULL; 12692 scsi_hba_tran_t *tran_clone = NULL; 12693 mptsas_tgt_private_t *tgt_private = NULL; 12694 int ret = DDI_FAILURE; 12695 12696 /* 12697 * scsi_hba_tran_t->tran_tgt_private is used to pass the address 12698 * information to scsi_init_pkt, allocate a scsi_hba_tran structure 12699 * to simulate the cmds from sd 12700 */ 12701 tran_clone = kmem_alloc( 12702 sizeof (scsi_hba_tran_t), KM_SLEEP); 12703 if (tran_clone == NULL) { 12704 goto out; 12705 } 12706 bcopy((caddr_t)mpt->m_tran, 12707 (caddr_t)tran_clone, sizeof (scsi_hba_tran_t)); 12708 tgt_private = kmem_alloc( 12709 sizeof (mptsas_tgt_private_t), KM_SLEEP); 12710 if (tgt_private == NULL) { 12711 goto out; 12712 } 12713 tgt_private->t_lun = ap->a_lun; 12714 tgt_private->t_private = ptgt; 12715 tran_clone->tran_tgt_private = tgt_private; 12716 ap->a_hba_tran = tran_clone; 12717 12718 pktp = scsi_init_pkt(ap, (struct scsi_pkt *)NULL, 12719 data_bp, cdblen, sizeof (struct scsi_arq_status), 12720 0, PKT_CONSISTENT, NULL, NULL); 12721 if (pktp == NULL) { 12722 goto out; 12723 } 12724 bcopy(cdb, pktp->pkt_cdbp, cdblen); 12725 pktp->pkt_flags = FLAG_NOPARITY; 12726 if (scsi_poll(pktp) < 0) { 12727 goto out; 12728 } 12729 if (((struct scsi_status *)pktp->pkt_scbp)->sts_chk) { 12730 goto out; 12731 } 12732 if (resid != NULL) { 12733 *resid = pktp->pkt_resid; 12734 } 12735 12736 ret = DDI_SUCCESS; 12737 out: 12738 if (pktp) { 12739 scsi_destroy_pkt(pktp); 12740 } 12741 if (tran_clone) { 12742 kmem_free(tran_clone, sizeof (scsi_hba_tran_t)); 12743 } 12744 if (tgt_private) { 12745 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t)); 12746 } 12747 return (ret); 12748 } 12749 static int 12750 mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, int *lun) 12751 { 12752 char *cp = NULL; 12753 char *ptr = NULL; 12754 size_t s = 0; 12755 char *wwid_str = NULL; 12756 char *lun_str = NULL; 12757 long lunnum; 12758 long phyid = -1; 12759 int rc = DDI_FAILURE; 12760 12761 ptr = name; 12762 ASSERT(ptr[0] == 'w' || ptr[0] == 'p'); 12763 ptr++; 12764 if ((cp = strchr(ptr, ',')) == NULL) { 12765 return (DDI_FAILURE); 12766 } 12767 12768 wwid_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 12769 s = (uintptr_t)cp - (uintptr_t)ptr; 12770 12771 bcopy(ptr, wwid_str, s); 12772 wwid_str[s] = '\0'; 12773 12774 ptr = ++cp; 12775 12776 if ((cp = strchr(ptr, '\0')) == NULL) { 12777 goto out; 12778 } 12779 lun_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 12780 s = (uintptr_t)cp - (uintptr_t)ptr; 12781 12782 bcopy(ptr, lun_str, s); 12783 lun_str[s] = '\0'; 12784 12785 if (name[0] == 'p') { 12786 rc = ddi_strtol(wwid_str, NULL, 0x10, &phyid); 12787 } else { 12788 rc = scsi_wwnstr_to_wwn(wwid_str, wwid); 12789 } 12790 if (rc != DDI_SUCCESS) 12791 goto out; 12792 12793 if (phyid != -1) { 12794 ASSERT(phyid < MPTSAS_MAX_PHYS); 12795 *phy = (uint8_t)phyid; 12796 } 12797 rc = ddi_strtol(lun_str, NULL, 0x10, &lunnum); 12798 if (rc != 0) 12799 goto out; 12800 12801 *lun = (int)lunnum; 12802 rc = DDI_SUCCESS; 12803 out: 12804 if (wwid_str) 12805 kmem_free(wwid_str, SCSI_MAXNAMELEN); 12806 if (lun_str) 12807 kmem_free(lun_str, SCSI_MAXNAMELEN); 12808 12809 return (rc); 12810 } 12811 12812 /* 12813 * mptsas_parse_smp_name() is to parse sas wwn string 12814 * which format is "wWWN" 12815 */ 12816 static int 12817 mptsas_parse_smp_name(char *name, uint64_t *wwn) 12818 { 12819 char *ptr = name; 12820 12821 if (*ptr != 'w') { 12822 return (DDI_FAILURE); 12823 } 12824 12825 ptr++; 12826 if (scsi_wwnstr_to_wwn(ptr, wwn)) { 12827 return (DDI_FAILURE); 12828 } 12829 return (DDI_SUCCESS); 12830 } 12831 12832 static int 12833 mptsas_bus_config(dev_info_t *pdip, uint_t flag, 12834 ddi_bus_config_op_t op, void *arg, dev_info_t **childp) 12835 { 12836 int ret = NDI_FAILURE; 12837 int circ = 0; 12838 int circ1 = 0; 12839 mptsas_t *mpt; 12840 char *ptr = NULL; 12841 char *devnm = NULL; 12842 uint64_t wwid = 0; 12843 uint8_t phy = 0xFF; 12844 int lun = 0; 12845 uint_t mflags = flag; 12846 int bconfig = TRUE; 12847 12848 if (scsi_hba_iport_unit_address(pdip) == 0) { 12849 return (DDI_FAILURE); 12850 } 12851 12852 mpt = DIP2MPT(pdip); 12853 if (!mpt) { 12854 return (DDI_FAILURE); 12855 } 12856 /* 12857 * Hold the nexus across the bus_config 12858 */ 12859 ndi_devi_enter(scsi_vhci_dip, &circ); 12860 ndi_devi_enter(pdip, &circ1); 12861 switch (op) { 12862 case BUS_CONFIG_ONE: 12863 /* parse wwid/target name out of name given */ 12864 if ((ptr = strchr((char *)arg, '@')) == NULL) { 12865 ret = NDI_FAILURE; 12866 break; 12867 } 12868 ptr++; 12869 if (strncmp((char *)arg, "smp", 3) == 0) { 12870 /* 12871 * This is a SMP target device 12872 */ 12873 ret = mptsas_parse_smp_name(ptr, &wwid); 12874 if (ret != DDI_SUCCESS) { 12875 ret = NDI_FAILURE; 12876 break; 12877 } 12878 ret = mptsas_config_smp(pdip, wwid, childp); 12879 } else if ((ptr[0] == 'w') || (ptr[0] == 'p')) { 12880 /* 12881 * OBP could pass down a non-canonical form 12882 * bootpath without LUN part when LUN is 0. 12883 * So driver need adjust the string. 12884 */ 12885 if (strchr(ptr, ',') == NULL) { 12886 devnm = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 12887 (void) sprintf(devnm, "%s,0", (char *)arg); 12888 ptr = strchr(devnm, '@'); 12889 ptr++; 12890 } 12891 12892 /* 12893 * The device path is wWWID format and the device 12894 * is not SMP target device. 12895 */ 12896 ret = mptsas_parse_address(ptr, &wwid, &phy, &lun); 12897 if (ret != DDI_SUCCESS) { 12898 ret = NDI_FAILURE; 12899 break; 12900 } 12901 *childp = NULL; 12902 if (ptr[0] == 'w') { 12903 ret = mptsas_config_one_addr(pdip, wwid, 12904 lun, childp); 12905 } else if (ptr[0] == 'p') { 12906 ret = mptsas_config_one_phy(pdip, phy, lun, 12907 childp); 12908 } 12909 12910 /* 12911 * If this is CD/DVD device in OBP path, the 12912 * ndi_busop_bus_config can be skipped as config one 12913 * operation is done above. 12914 */ 12915 if ((ret == NDI_SUCCESS) && (*childp != NULL) && 12916 (strcmp(ddi_node_name(*childp), "cdrom") == 0) && 12917 (strncmp((char *)arg, "disk", 4) == 0)) { 12918 bconfig = FALSE; 12919 ndi_hold_devi(*childp); 12920 } 12921 } else { 12922 ret = NDI_FAILURE; 12923 break; 12924 } 12925 12926 /* 12927 * DDI group instructed us to use this flag. 12928 */ 12929 mflags |= NDI_MDI_FALLBACK; 12930 break; 12931 case BUS_CONFIG_DRIVER: 12932 case BUS_CONFIG_ALL: 12933 mptsas_config_all(pdip); 12934 ret = NDI_SUCCESS; 12935 break; 12936 } 12937 12938 if ((ret == NDI_SUCCESS) && bconfig) { 12939 ret = ndi_busop_bus_config(pdip, mflags, op, 12940 (devnm == NULL) ? arg : devnm, childp, 0); 12941 } 12942 12943 ndi_devi_exit(pdip, circ1); 12944 ndi_devi_exit(scsi_vhci_dip, circ); 12945 if (devnm != NULL) 12946 kmem_free(devnm, SCSI_MAXNAMELEN); 12947 return (ret); 12948 } 12949 12950 static int 12951 mptsas_probe_lun(dev_info_t *pdip, int lun, dev_info_t **dip, 12952 mptsas_target_t *ptgt) 12953 { 12954 int rval = DDI_FAILURE; 12955 struct scsi_inquiry *sd_inq = NULL; 12956 mptsas_t *mpt = DIP2MPT(pdip); 12957 12958 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP); 12959 12960 rval = mptsas_inquiry(mpt, ptgt, lun, 0, (uchar_t *)sd_inq, 12961 SUN_INQSIZE, 0, (uchar_t)0); 12962 12963 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) { 12964 rval = mptsas_create_lun(pdip, sd_inq, dip, ptgt, lun); 12965 } else { 12966 rval = DDI_FAILURE; 12967 } 12968 12969 kmem_free(sd_inq, SUN_INQSIZE); 12970 return (rval); 12971 } 12972 12973 static int 12974 mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun, 12975 dev_info_t **lundip) 12976 { 12977 int rval; 12978 mptsas_t *mpt = DIP2MPT(pdip); 12979 int phymask; 12980 mptsas_target_t *ptgt = NULL; 12981 12982 /* 12983 * Get the physical port associated to the iport 12984 */ 12985 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 12986 "phymask", 0); 12987 12988 ptgt = mptsas_wwid_to_ptgt(mpt, phymask, sasaddr); 12989 if (ptgt == NULL) { 12990 /* 12991 * didn't match any device by searching 12992 */ 12993 return (DDI_FAILURE); 12994 } 12995 /* 12996 * If the LUN already exists and the status is online, 12997 * we just return the pointer to dev_info_t directly. 12998 * For the mdi_pathinfo node, we'll handle it in 12999 * mptsas_create_virt_lun() 13000 * TODO should be also in mptsas_handle_dr 13001 */ 13002 13003 *lundip = mptsas_find_child_addr(pdip, sasaddr, lun); 13004 if (*lundip != NULL) { 13005 /* 13006 * TODO Another senario is, we hotplug the same disk 13007 * on the same slot, the devhdl changed, is this 13008 * possible? 13009 * tgt_private->t_private != ptgt 13010 */ 13011 if (sasaddr != ptgt->m_addr.mta_wwn) { 13012 /* 13013 * The device has changed although the devhdl is the 13014 * same (Enclosure mapping mode, change drive on the 13015 * same slot) 13016 */ 13017 return (DDI_FAILURE); 13018 } 13019 return (DDI_SUCCESS); 13020 } 13021 13022 if (phymask == 0) { 13023 /* 13024 * Configure IR volume 13025 */ 13026 rval = mptsas_config_raid(pdip, ptgt->m_devhdl, lundip); 13027 return (rval); 13028 } 13029 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt); 13030 13031 return (rval); 13032 } 13033 13034 static int 13035 mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun, 13036 dev_info_t **lundip) 13037 { 13038 int rval; 13039 mptsas_t *mpt = DIP2MPT(pdip); 13040 mptsas_phymask_t phymask; 13041 mptsas_target_t *ptgt = NULL; 13042 13043 /* 13044 * Get the physical port associated to the iport 13045 */ 13046 phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 13047 "phymask", 0); 13048 13049 ptgt = mptsas_phy_to_tgt(mpt, phymask, phy); 13050 if (ptgt == NULL) { 13051 /* 13052 * didn't match any device by searching 13053 */ 13054 return (DDI_FAILURE); 13055 } 13056 13057 /* 13058 * If the LUN already exists and the status is online, 13059 * we just return the pointer to dev_info_t directly. 13060 * For the mdi_pathinfo node, we'll handle it in 13061 * mptsas_create_virt_lun(). 13062 */ 13063 13064 *lundip = mptsas_find_child_phy(pdip, phy); 13065 if (*lundip != NULL) { 13066 return (DDI_SUCCESS); 13067 } 13068 13069 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt); 13070 13071 return (rval); 13072 } 13073 13074 static int 13075 mptsas_retrieve_lundata(int lun_cnt, uint8_t *buf, uint16_t *lun_num, 13076 uint8_t *lun_addr_type) 13077 { 13078 uint32_t lun_idx = 0; 13079 13080 ASSERT(lun_num != NULL); 13081 ASSERT(lun_addr_type != NULL); 13082 13083 lun_idx = (lun_cnt + 1) * MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE; 13084 /* determine report luns addressing type */ 13085 switch (buf[lun_idx] & MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) { 13086 /* 13087 * Vendors in the field have been found to be concatenating 13088 * bus/target/lun to equal the complete lun value instead 13089 * of switching to flat space addressing 13090 */ 13091 /* 00b - peripheral device addressing method */ 13092 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_PERIPHERAL: 13093 /* FALLTHRU */ 13094 /* 10b - logical unit addressing method */ 13095 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT: 13096 /* FALLTHRU */ 13097 /* 01b - flat space addressing method */ 13098 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE: 13099 /* byte0 bit0-5=msb lun byte1 bit0-7=lsb lun */ 13100 *lun_addr_type = (buf[lun_idx] & 13101 MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) >> 6; 13102 *lun_num = (buf[lun_idx] & 0x3F) << 8; 13103 *lun_num |= buf[lun_idx + 1]; 13104 return (DDI_SUCCESS); 13105 default: 13106 return (DDI_FAILURE); 13107 } 13108 } 13109 13110 static int 13111 mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt) 13112 { 13113 struct buf *repluns_bp = NULL; 13114 struct scsi_address ap; 13115 uchar_t cdb[CDB_GROUP5]; 13116 int ret = DDI_FAILURE; 13117 int retry = 0; 13118 int lun_list_len = 0; 13119 uint16_t lun_num = 0; 13120 uint8_t lun_addr_type = 0; 13121 uint32_t lun_cnt = 0; 13122 uint32_t lun_total = 0; 13123 dev_info_t *cdip = NULL; 13124 uint16_t *saved_repluns = NULL; 13125 char *buffer = NULL; 13126 int buf_len = 128; 13127 mptsas_t *mpt = DIP2MPT(pdip); 13128 uint64_t sas_wwn = 0; 13129 uint8_t phy = 0xFF; 13130 uint32_t dev_info = 0; 13131 13132 mutex_enter(&mpt->m_mutex); 13133 sas_wwn = ptgt->m_addr.mta_wwn; 13134 phy = ptgt->m_phynum; 13135 dev_info = ptgt->m_deviceinfo; 13136 mutex_exit(&mpt->m_mutex); 13137 13138 if (sas_wwn == 0) { 13139 /* 13140 * It's a SATA without Device Name 13141 * So don't try multi-LUNs 13142 */ 13143 if (mptsas_find_child_phy(pdip, phy)) { 13144 return (DDI_SUCCESS); 13145 } else { 13146 /* 13147 * need configure and create node 13148 */ 13149 return (DDI_FAILURE); 13150 } 13151 } 13152 13153 /* 13154 * WWN (SAS address or Device Name exist) 13155 */ 13156 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 13157 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 13158 /* 13159 * SATA device with Device Name 13160 * So don't try multi-LUNs 13161 */ 13162 if (mptsas_find_child_addr(pdip, sas_wwn, 0)) { 13163 return (DDI_SUCCESS); 13164 } else { 13165 return (DDI_FAILURE); 13166 } 13167 } 13168 13169 do { 13170 ap.a_target = MPTSAS_INVALID_DEVHDL; 13171 ap.a_lun = 0; 13172 ap.a_hba_tran = mpt->m_tran; 13173 repluns_bp = scsi_alloc_consistent_buf(&ap, 13174 (struct buf *)NULL, buf_len, B_READ, NULL_FUNC, NULL); 13175 if (repluns_bp == NULL) { 13176 retry++; 13177 continue; 13178 } 13179 bzero(cdb, CDB_GROUP5); 13180 cdb[0] = SCMD_REPORT_LUNS; 13181 cdb[6] = (buf_len & 0xff000000) >> 24; 13182 cdb[7] = (buf_len & 0x00ff0000) >> 16; 13183 cdb[8] = (buf_len & 0x0000ff00) >> 8; 13184 cdb[9] = (buf_len & 0x000000ff); 13185 13186 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP5, 13187 repluns_bp, NULL); 13188 if (ret != DDI_SUCCESS) { 13189 scsi_free_consistent_buf(repluns_bp); 13190 retry++; 13191 continue; 13192 } 13193 lun_list_len = BE_32(*(int *)((void *)( 13194 repluns_bp->b_un.b_addr))); 13195 if (buf_len >= lun_list_len + 8) { 13196 ret = DDI_SUCCESS; 13197 break; 13198 } 13199 scsi_free_consistent_buf(repluns_bp); 13200 buf_len = lun_list_len + 8; 13201 13202 } while (retry < 3); 13203 13204 if (ret != DDI_SUCCESS) 13205 return (ret); 13206 buffer = (char *)repluns_bp->b_un.b_addr; 13207 /* 13208 * find out the number of luns returned by the SCSI ReportLun call 13209 * and allocate buffer space 13210 */ 13211 lun_total = lun_list_len / MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE; 13212 saved_repluns = kmem_zalloc(sizeof (uint16_t) * lun_total, KM_SLEEP); 13213 if (saved_repluns == NULL) { 13214 scsi_free_consistent_buf(repluns_bp); 13215 return (DDI_FAILURE); 13216 } 13217 for (lun_cnt = 0; lun_cnt < lun_total; lun_cnt++) { 13218 if (mptsas_retrieve_lundata(lun_cnt, (uint8_t *)(buffer), 13219 &lun_num, &lun_addr_type) != DDI_SUCCESS) { 13220 continue; 13221 } 13222 saved_repluns[lun_cnt] = lun_num; 13223 if (cdip = mptsas_find_child_addr(pdip, sas_wwn, lun_num)) 13224 ret = DDI_SUCCESS; 13225 else 13226 ret = mptsas_probe_lun(pdip, lun_num, &cdip, 13227 ptgt); 13228 if ((ret == DDI_SUCCESS) && (cdip != NULL)) { 13229 (void) ndi_prop_remove(DDI_DEV_T_NONE, cdip, 13230 MPTSAS_DEV_GONE); 13231 } 13232 } 13233 mptsas_offline_missed_luns(pdip, saved_repluns, lun_total, ptgt); 13234 kmem_free(saved_repluns, sizeof (uint16_t) * lun_total); 13235 scsi_free_consistent_buf(repluns_bp); 13236 return (DDI_SUCCESS); 13237 } 13238 13239 static int 13240 mptsas_config_raid(dev_info_t *pdip, uint16_t target, dev_info_t **dip) 13241 { 13242 int rval = DDI_FAILURE; 13243 struct scsi_inquiry *sd_inq = NULL; 13244 mptsas_t *mpt = DIP2MPT(pdip); 13245 mptsas_target_t *ptgt = NULL; 13246 13247 mutex_enter(&mpt->m_mutex); 13248 ptgt = refhash_linear_search(mpt->m_targets, 13249 mptsas_target_eval_devhdl, &target); 13250 mutex_exit(&mpt->m_mutex); 13251 if (ptgt == NULL) { 13252 mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x " 13253 "not found.", target); 13254 return (rval); 13255 } 13256 13257 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP); 13258 rval = mptsas_inquiry(mpt, ptgt, 0, 0, (uchar_t *)sd_inq, 13259 SUN_INQSIZE, 0, (uchar_t)0); 13260 13261 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) { 13262 rval = mptsas_create_phys_lun(pdip, sd_inq, NULL, dip, ptgt, 13263 0); 13264 } else { 13265 rval = DDI_FAILURE; 13266 } 13267 13268 kmem_free(sd_inq, SUN_INQSIZE); 13269 return (rval); 13270 } 13271 13272 /* 13273 * configure all RAID volumes for virtual iport 13274 */ 13275 static void 13276 mptsas_config_all_viport(dev_info_t *pdip) 13277 { 13278 mptsas_t *mpt = DIP2MPT(pdip); 13279 int config, vol; 13280 int target; 13281 dev_info_t *lundip = NULL; 13282 13283 /* 13284 * Get latest RAID info and search for any Volume DevHandles. If any 13285 * are found, configure the volume. 13286 */ 13287 mutex_enter(&mpt->m_mutex); 13288 for (config = 0; config < mpt->m_num_raid_configs; config++) { 13289 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) { 13290 if (mpt->m_raidconfig[config].m_raidvol[vol].m_israid 13291 == 1) { 13292 target = mpt->m_raidconfig[config]. 13293 m_raidvol[vol].m_raidhandle; 13294 mutex_exit(&mpt->m_mutex); 13295 (void) mptsas_config_raid(pdip, target, 13296 &lundip); 13297 mutex_enter(&mpt->m_mutex); 13298 } 13299 } 13300 } 13301 mutex_exit(&mpt->m_mutex); 13302 } 13303 13304 static void 13305 mptsas_offline_missed_luns(dev_info_t *pdip, uint16_t *repluns, 13306 int lun_cnt, mptsas_target_t *ptgt) 13307 { 13308 dev_info_t *child = NULL, *savechild = NULL; 13309 mdi_pathinfo_t *pip = NULL, *savepip = NULL; 13310 uint64_t sas_wwn, wwid; 13311 uint8_t phy; 13312 int lun; 13313 int i; 13314 int find; 13315 char *addr; 13316 char *nodename; 13317 mptsas_t *mpt = DIP2MPT(pdip); 13318 13319 mutex_enter(&mpt->m_mutex); 13320 wwid = ptgt->m_addr.mta_wwn; 13321 mutex_exit(&mpt->m_mutex); 13322 13323 child = ddi_get_child(pdip); 13324 while (child) { 13325 find = 0; 13326 savechild = child; 13327 child = ddi_get_next_sibling(child); 13328 13329 nodename = ddi_node_name(savechild); 13330 if (strcmp(nodename, "smp") == 0) { 13331 continue; 13332 } 13333 13334 addr = ddi_get_name_addr(savechild); 13335 if (addr == NULL) { 13336 continue; 13337 } 13338 13339 if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) != 13340 DDI_SUCCESS) { 13341 continue; 13342 } 13343 13344 if (wwid == sas_wwn) { 13345 for (i = 0; i < lun_cnt; i++) { 13346 if (repluns[i] == lun) { 13347 find = 1; 13348 break; 13349 } 13350 } 13351 } else { 13352 continue; 13353 } 13354 if (find == 0) { 13355 /* 13356 * The lun has not been there already 13357 */ 13358 (void) mptsas_offline_lun(pdip, savechild, NULL, 13359 NDI_DEVI_REMOVE); 13360 } 13361 } 13362 13363 pip = mdi_get_next_client_path(pdip, NULL); 13364 while (pip) { 13365 find = 0; 13366 savepip = pip; 13367 addr = MDI_PI(pip)->pi_addr; 13368 13369 pip = mdi_get_next_client_path(pdip, pip); 13370 13371 if (addr == NULL) { 13372 continue; 13373 } 13374 13375 if (mptsas_parse_address(addr, &sas_wwn, &phy, 13376 &lun) != DDI_SUCCESS) { 13377 continue; 13378 } 13379 13380 if (sas_wwn == wwid) { 13381 for (i = 0; i < lun_cnt; i++) { 13382 if (repluns[i] == lun) { 13383 find = 1; 13384 break; 13385 } 13386 } 13387 } else { 13388 continue; 13389 } 13390 13391 if (find == 0) { 13392 /* 13393 * The lun has not been there already 13394 */ 13395 (void) mptsas_offline_lun(pdip, NULL, savepip, 13396 NDI_DEVI_REMOVE); 13397 } 13398 } 13399 } 13400 13401 void 13402 mptsas_update_hashtab(struct mptsas *mpt) 13403 { 13404 uint32_t page_address; 13405 int rval = 0; 13406 uint16_t dev_handle; 13407 mptsas_target_t *ptgt = NULL; 13408 mptsas_smp_t smp_node; 13409 13410 /* 13411 * Get latest RAID info. 13412 */ 13413 (void) mptsas_get_raid_info(mpt); 13414 13415 dev_handle = mpt->m_smp_devhdl; 13416 for (; mpt->m_done_traverse_smp == 0; ) { 13417 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL & 13418 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)dev_handle; 13419 if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node) 13420 != DDI_SUCCESS) { 13421 break; 13422 } 13423 mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl; 13424 (void) mptsas_smp_alloc(mpt, &smp_node); 13425 } 13426 13427 /* 13428 * Config target devices 13429 */ 13430 dev_handle = mpt->m_dev_handle; 13431 13432 /* 13433 * Do loop to get sas device page 0 by GetNextHandle till the 13434 * the last handle. If the sas device is a SATA/SSP target, 13435 * we try to config it. 13436 */ 13437 for (; mpt->m_done_traverse_dev == 0; ) { 13438 ptgt = NULL; 13439 page_address = 13440 (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 13441 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 13442 (uint32_t)dev_handle; 13443 rval = mptsas_get_target_device_info(mpt, page_address, 13444 &dev_handle, &ptgt); 13445 if ((rval == DEV_INFO_FAIL_PAGE0) || 13446 (rval == DEV_INFO_FAIL_ALLOC)) { 13447 break; 13448 } 13449 13450 mpt->m_dev_handle = dev_handle; 13451 } 13452 13453 } 13454 13455 void 13456 mptsas_update_driver_data(struct mptsas *mpt) 13457 { 13458 mptsas_target_t *tp; 13459 mptsas_smp_t *sp; 13460 13461 ASSERT(MUTEX_HELD(&mpt->m_mutex)); 13462 13463 /* 13464 * TODO after hard reset, update the driver data structures 13465 * 1. update port/phymask mapping table mpt->m_phy_info 13466 * 2. invalid all the entries in hash table 13467 * m_devhdl = 0xffff and m_deviceinfo = 0 13468 * 3. call sas_device_page/expander_page to update hash table 13469 */ 13470 mptsas_update_phymask(mpt); 13471 /* 13472 * Invalid the existing entries 13473 * 13474 * XXX - It seems like we should just delete everything here. We are 13475 * holding the lock and are about to refresh all the targets in both 13476 * hashes anyway. Given the path we're in, what outstanding async 13477 * event could possibly be trying to reference one of these things 13478 * without taking the lock, and how would that be useful anyway? 13479 */ 13480 for (tp = refhash_first(mpt->m_targets); tp != NULL; 13481 tp = refhash_next(mpt->m_targets, tp)) { 13482 tp->m_devhdl = MPTSAS_INVALID_DEVHDL; 13483 tp->m_deviceinfo = 0; 13484 tp->m_dr_flag = MPTSAS_DR_INACTIVE; 13485 } 13486 for (sp = refhash_first(mpt->m_smp_targets); sp != NULL; 13487 sp = refhash_next(mpt->m_smp_targets, sp)) { 13488 sp->m_devhdl = MPTSAS_INVALID_DEVHDL; 13489 sp->m_deviceinfo = 0; 13490 } 13491 mpt->m_done_traverse_dev = 0; 13492 mpt->m_done_traverse_smp = 0; 13493 mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL; 13494 mptsas_update_hashtab(mpt); 13495 } 13496 13497 static void 13498 mptsas_config_all(dev_info_t *pdip) 13499 { 13500 dev_info_t *smpdip = NULL; 13501 mptsas_t *mpt = DIP2MPT(pdip); 13502 int phymask = 0; 13503 mptsas_phymask_t phy_mask; 13504 mptsas_target_t *ptgt = NULL; 13505 mptsas_smp_t *psmp; 13506 13507 /* 13508 * Get the phymask associated to the iport 13509 */ 13510 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 13511 "phymask", 0); 13512 13513 /* 13514 * Enumerate RAID volumes here (phymask == 0). 13515 */ 13516 if (phymask == 0) { 13517 mptsas_config_all_viport(pdip); 13518 return; 13519 } 13520 13521 mutex_enter(&mpt->m_mutex); 13522 13523 if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp) { 13524 mptsas_update_hashtab(mpt); 13525 } 13526 13527 for (psmp = refhash_first(mpt->m_smp_targets); psmp != NULL; 13528 psmp = refhash_next(mpt->m_smp_targets, psmp)) { 13529 phy_mask = psmp->m_addr.mta_phymask; 13530 if (phy_mask == phymask) { 13531 smpdip = NULL; 13532 mutex_exit(&mpt->m_mutex); 13533 (void) mptsas_online_smp(pdip, psmp, &smpdip); 13534 mutex_enter(&mpt->m_mutex); 13535 } 13536 } 13537 13538 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 13539 ptgt = refhash_next(mpt->m_targets, ptgt)) { 13540 phy_mask = ptgt->m_addr.mta_phymask; 13541 if (phy_mask == phymask) { 13542 mutex_exit(&mpt->m_mutex); 13543 (void) mptsas_config_target(pdip, ptgt); 13544 mutex_enter(&mpt->m_mutex); 13545 } 13546 } 13547 mutex_exit(&mpt->m_mutex); 13548 } 13549 13550 static int 13551 mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt) 13552 { 13553 int rval = DDI_FAILURE; 13554 dev_info_t *tdip; 13555 13556 rval = mptsas_config_luns(pdip, ptgt); 13557 if (rval != DDI_SUCCESS) { 13558 /* 13559 * The return value means the SCMD_REPORT_LUNS 13560 * did not execute successfully. The target maybe 13561 * doesn't support such command. 13562 */ 13563 rval = mptsas_probe_lun(pdip, 0, &tdip, ptgt); 13564 } 13565 return (rval); 13566 } 13567 13568 /* 13569 * Return fail if not all the childs/paths are freed. 13570 * if there is any path under the HBA, the return value will be always fail 13571 * because we didn't call mdi_pi_free for path 13572 */ 13573 static int 13574 mptsas_offline_target(dev_info_t *pdip, char *name) 13575 { 13576 dev_info_t *child = NULL, *prechild = NULL; 13577 mdi_pathinfo_t *pip = NULL, *savepip = NULL; 13578 int tmp_rval, rval = DDI_SUCCESS; 13579 char *addr, *cp; 13580 size_t s; 13581 mptsas_t *mpt = DIP2MPT(pdip); 13582 13583 child = ddi_get_child(pdip); 13584 while (child) { 13585 addr = ddi_get_name_addr(child); 13586 prechild = child; 13587 child = ddi_get_next_sibling(child); 13588 13589 if (addr == NULL) { 13590 continue; 13591 } 13592 if ((cp = strchr(addr, ',')) == NULL) { 13593 continue; 13594 } 13595 13596 s = (uintptr_t)cp - (uintptr_t)addr; 13597 13598 if (strncmp(addr, name, s) != 0) { 13599 continue; 13600 } 13601 13602 tmp_rval = mptsas_offline_lun(pdip, prechild, NULL, 13603 NDI_DEVI_REMOVE); 13604 if (tmp_rval != DDI_SUCCESS) { 13605 rval = DDI_FAILURE; 13606 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 13607 prechild, MPTSAS_DEV_GONE) != 13608 DDI_PROP_SUCCESS) { 13609 mptsas_log(mpt, CE_WARN, "mptsas driver " 13610 "unable to create property for " 13611 "SAS %s (MPTSAS_DEV_GONE)", addr); 13612 } 13613 } 13614 } 13615 13616 pip = mdi_get_next_client_path(pdip, NULL); 13617 while (pip) { 13618 addr = MDI_PI(pip)->pi_addr; 13619 savepip = pip; 13620 pip = mdi_get_next_client_path(pdip, pip); 13621 if (addr == NULL) { 13622 continue; 13623 } 13624 13625 if ((cp = strchr(addr, ',')) == NULL) { 13626 continue; 13627 } 13628 13629 s = (uintptr_t)cp - (uintptr_t)addr; 13630 13631 if (strncmp(addr, name, s) != 0) { 13632 continue; 13633 } 13634 13635 (void) mptsas_offline_lun(pdip, NULL, savepip, 13636 NDI_DEVI_REMOVE); 13637 /* 13638 * driver will not invoke mdi_pi_free, so path will not 13639 * be freed forever, return DDI_FAILURE. 13640 */ 13641 rval = DDI_FAILURE; 13642 } 13643 return (rval); 13644 } 13645 13646 static int 13647 mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip, 13648 mdi_pathinfo_t *rpip, uint_t flags) 13649 { 13650 int rval = DDI_FAILURE; 13651 char *devname; 13652 dev_info_t *cdip, *parent; 13653 13654 if (rpip != NULL) { 13655 parent = scsi_vhci_dip; 13656 cdip = mdi_pi_get_client(rpip); 13657 } else if (rdip != NULL) { 13658 parent = pdip; 13659 cdip = rdip; 13660 } else { 13661 return (DDI_FAILURE); 13662 } 13663 13664 /* 13665 * Make sure node is attached otherwise 13666 * it won't have related cache nodes to 13667 * clean up. i_ddi_devi_attached is 13668 * similiar to i_ddi_node_state(cdip) >= 13669 * DS_ATTACHED. 13670 */ 13671 if (i_ddi_devi_attached(cdip)) { 13672 13673 /* Get full devname */ 13674 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 13675 (void) ddi_deviname(cdip, devname); 13676 /* Clean cache */ 13677 (void) devfs_clean(parent, devname + 1, 13678 DV_CLEAN_FORCE); 13679 kmem_free(devname, MAXNAMELEN + 1); 13680 } 13681 if (rpip != NULL) { 13682 if (MDI_PI_IS_OFFLINE(rpip)) { 13683 rval = DDI_SUCCESS; 13684 } else { 13685 rval = mdi_pi_offline(rpip, 0); 13686 } 13687 } else { 13688 rval = ndi_devi_offline(cdip, flags); 13689 } 13690 13691 return (rval); 13692 } 13693 13694 static dev_info_t * 13695 mptsas_find_smp_child(dev_info_t *parent, char *str_wwn) 13696 { 13697 dev_info_t *child = NULL; 13698 char *smp_wwn = NULL; 13699 13700 child = ddi_get_child(parent); 13701 while (child) { 13702 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child, 13703 DDI_PROP_DONTPASS, SMP_WWN, &smp_wwn) 13704 != DDI_SUCCESS) { 13705 child = ddi_get_next_sibling(child); 13706 continue; 13707 } 13708 13709 if (strcmp(smp_wwn, str_wwn) == 0) { 13710 ddi_prop_free(smp_wwn); 13711 break; 13712 } 13713 child = ddi_get_next_sibling(child); 13714 ddi_prop_free(smp_wwn); 13715 } 13716 return (child); 13717 } 13718 13719 static int 13720 mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags) 13721 { 13722 int rval = DDI_FAILURE; 13723 char *devname; 13724 char wwn_str[MPTSAS_WWN_STRLEN]; 13725 dev_info_t *cdip; 13726 13727 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn); 13728 13729 cdip = mptsas_find_smp_child(pdip, wwn_str); 13730 13731 if (cdip == NULL) 13732 return (DDI_SUCCESS); 13733 13734 /* 13735 * Make sure node is attached otherwise 13736 * it won't have related cache nodes to 13737 * clean up. i_ddi_devi_attached is 13738 * similiar to i_ddi_node_state(cdip) >= 13739 * DS_ATTACHED. 13740 */ 13741 if (i_ddi_devi_attached(cdip)) { 13742 13743 /* Get full devname */ 13744 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 13745 (void) ddi_deviname(cdip, devname); 13746 /* Clean cache */ 13747 (void) devfs_clean(pdip, devname + 1, 13748 DV_CLEAN_FORCE); 13749 kmem_free(devname, MAXNAMELEN + 1); 13750 } 13751 13752 rval = ndi_devi_offline(cdip, flags); 13753 13754 return (rval); 13755 } 13756 13757 static dev_info_t * 13758 mptsas_find_child(dev_info_t *pdip, char *name) 13759 { 13760 dev_info_t *child = NULL; 13761 char *rname = NULL; 13762 int rval = DDI_FAILURE; 13763 13764 rname = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13765 13766 child = ddi_get_child(pdip); 13767 while (child) { 13768 rval = mptsas_name_child(child, rname, SCSI_MAXNAMELEN); 13769 if (rval != DDI_SUCCESS) { 13770 child = ddi_get_next_sibling(child); 13771 bzero(rname, SCSI_MAXNAMELEN); 13772 continue; 13773 } 13774 13775 if (strcmp(rname, name) == 0) { 13776 break; 13777 } 13778 child = ddi_get_next_sibling(child); 13779 bzero(rname, SCSI_MAXNAMELEN); 13780 } 13781 13782 kmem_free(rname, SCSI_MAXNAMELEN); 13783 13784 return (child); 13785 } 13786 13787 13788 static dev_info_t * 13789 mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, int lun) 13790 { 13791 dev_info_t *child = NULL; 13792 char *name = NULL; 13793 char *addr = NULL; 13794 13795 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13796 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13797 (void) sprintf(name, "%016"PRIx64, sasaddr); 13798 (void) sprintf(addr, "w%s,%x", name, lun); 13799 child = mptsas_find_child(pdip, addr); 13800 kmem_free(name, SCSI_MAXNAMELEN); 13801 kmem_free(addr, SCSI_MAXNAMELEN); 13802 return (child); 13803 } 13804 13805 static dev_info_t * 13806 mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy) 13807 { 13808 dev_info_t *child; 13809 char *addr; 13810 13811 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13812 (void) sprintf(addr, "p%x,0", phy); 13813 child = mptsas_find_child(pdip, addr); 13814 kmem_free(addr, SCSI_MAXNAMELEN); 13815 return (child); 13816 } 13817 13818 static mdi_pathinfo_t * 13819 mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy) 13820 { 13821 mdi_pathinfo_t *path; 13822 char *addr = NULL; 13823 13824 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13825 (void) sprintf(addr, "p%x,0", phy); 13826 path = mdi_pi_find(pdip, NULL, addr); 13827 kmem_free(addr, SCSI_MAXNAMELEN); 13828 return (path); 13829 } 13830 13831 static mdi_pathinfo_t * 13832 mptsas_find_path_addr(dev_info_t *parent, uint64_t sasaddr, int lun) 13833 { 13834 mdi_pathinfo_t *path; 13835 char *name = NULL; 13836 char *addr = NULL; 13837 13838 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13839 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13840 (void) sprintf(name, "%016"PRIx64, sasaddr); 13841 (void) sprintf(addr, "w%s,%x", name, lun); 13842 path = mdi_pi_find(parent, NULL, addr); 13843 kmem_free(name, SCSI_MAXNAMELEN); 13844 kmem_free(addr, SCSI_MAXNAMELEN); 13845 13846 return (path); 13847 } 13848 13849 static int 13850 mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq, 13851 dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun) 13852 { 13853 int i = 0; 13854 uchar_t *inq83 = NULL; 13855 int inq83_len1 = 0xFF; 13856 int inq83_len = 0; 13857 int rval = DDI_FAILURE; 13858 ddi_devid_t devid; 13859 char *guid = NULL; 13860 int target = ptgt->m_devhdl; 13861 mdi_pathinfo_t *pip = NULL; 13862 mptsas_t *mpt = DIP2MPT(pdip); 13863 13864 /* 13865 * For DVD/CD ROM and tape devices and optical 13866 * devices, we won't try to enumerate them under 13867 * scsi_vhci, so no need to try page83 13868 */ 13869 if (sd_inq && (sd_inq->inq_dtype == DTYPE_RODIRECT || 13870 sd_inq->inq_dtype == DTYPE_OPTICAL || 13871 sd_inq->inq_dtype == DTYPE_ESI)) 13872 goto create_lun; 13873 13874 /* 13875 * The LCA returns good SCSI status, but corrupt page 83 data the first 13876 * time it is queried. The solution is to keep trying to request page83 13877 * and verify the GUID is not (DDI_NOT_WELL_FORMED) in 13878 * mptsas_inq83_retry_timeout seconds. If the timeout expires, driver 13879 * give up to get VPD page at this stage and fail the enumeration. 13880 */ 13881 13882 inq83 = kmem_zalloc(inq83_len1, KM_SLEEP); 13883 13884 for (i = 0; i < mptsas_inq83_retry_timeout; i++) { 13885 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83, 13886 inq83_len1, &inq83_len, 1); 13887 if (rval != 0) { 13888 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 13889 "0x83 for target:%x, lun:%x failed!", target, lun); 13890 if (mptsas_physical_bind_failed_page_83 != B_FALSE) 13891 goto create_lun; 13892 goto out; 13893 } 13894 /* 13895 * create DEVID from inquiry data 13896 */ 13897 if ((rval = ddi_devid_scsi_encode( 13898 DEVID_SCSI_ENCODE_VERSION_LATEST, NULL, (uchar_t *)sd_inq, 13899 sizeof (struct scsi_inquiry), NULL, 0, inq83, 13900 (size_t)inq83_len, &devid)) == DDI_SUCCESS) { 13901 /* 13902 * extract GUID from DEVID 13903 */ 13904 guid = ddi_devid_to_guid(devid); 13905 13906 /* 13907 * Do not enable MPXIO if the strlen(guid) is greater 13908 * than MPTSAS_MAX_GUID_LEN, this constrain would be 13909 * handled by framework later. 13910 */ 13911 if (guid && (strlen(guid) > MPTSAS_MAX_GUID_LEN)) { 13912 ddi_devid_free_guid(guid); 13913 guid = NULL; 13914 if (mpt->m_mpxio_enable == TRUE) { 13915 mptsas_log(mpt, CE_NOTE, "!Target:%x, " 13916 "lun:%x doesn't have a valid GUID, " 13917 "multipathing for this drive is " 13918 "not enabled", target, lun); 13919 } 13920 } 13921 13922 /* 13923 * devid no longer needed 13924 */ 13925 ddi_devid_free(devid); 13926 break; 13927 } else if (rval == DDI_NOT_WELL_FORMED) { 13928 /* 13929 * return value of ddi_devid_scsi_encode equal to 13930 * DDI_NOT_WELL_FORMED means DEVID_RETRY, it worth 13931 * to retry inquiry page 0x83 and get GUID. 13932 */ 13933 NDBG20(("Not well formed devid, retry...")); 13934 delay(1 * drv_usectohz(1000000)); 13935 continue; 13936 } else { 13937 mptsas_log(mpt, CE_WARN, "!Encode devid failed for " 13938 "path target:%x, lun:%x", target, lun); 13939 rval = DDI_FAILURE; 13940 goto create_lun; 13941 } 13942 } 13943 13944 if (i == mptsas_inq83_retry_timeout) { 13945 mptsas_log(mpt, CE_WARN, "!Repeated page83 requests timeout " 13946 "for path target:%x, lun:%x", target, lun); 13947 } 13948 13949 rval = DDI_FAILURE; 13950 13951 create_lun: 13952 if ((guid != NULL) && (mpt->m_mpxio_enable == TRUE)) { 13953 rval = mptsas_create_virt_lun(pdip, sd_inq, guid, lun_dip, &pip, 13954 ptgt, lun); 13955 } 13956 if (rval != DDI_SUCCESS) { 13957 rval = mptsas_create_phys_lun(pdip, sd_inq, guid, lun_dip, 13958 ptgt, lun); 13959 13960 } 13961 out: 13962 if (guid != NULL) { 13963 /* 13964 * guid no longer needed 13965 */ 13966 ddi_devid_free_guid(guid); 13967 } 13968 if (inq83 != NULL) 13969 kmem_free(inq83, inq83_len1); 13970 return (rval); 13971 } 13972 13973 static int 13974 mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *inq, char *guid, 13975 dev_info_t **lun_dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, int lun) 13976 { 13977 int target; 13978 char *nodename = NULL; 13979 char **compatible = NULL; 13980 int ncompatible = 0; 13981 int mdi_rtn = MDI_FAILURE; 13982 int rval = DDI_FAILURE; 13983 char *old_guid = NULL; 13984 mptsas_t *mpt = DIP2MPT(pdip); 13985 char *lun_addr = NULL; 13986 char *wwn_str = NULL; 13987 char *attached_wwn_str = NULL; 13988 char *component = NULL; 13989 uint8_t phy = 0xFF; 13990 uint64_t sas_wwn; 13991 int64_t lun64 = 0; 13992 uint32_t devinfo; 13993 uint16_t dev_hdl; 13994 uint16_t pdev_hdl; 13995 uint64_t dev_sas_wwn; 13996 uint64_t pdev_sas_wwn; 13997 uint32_t pdev_info; 13998 uint8_t physport; 13999 uint8_t phy_id; 14000 uint32_t page_address; 14001 uint16_t bay_num, enclosure; 14002 char pdev_wwn_str[MPTSAS_WWN_STRLEN]; 14003 uint32_t dev_info; 14004 14005 mutex_enter(&mpt->m_mutex); 14006 target = ptgt->m_devhdl; 14007 sas_wwn = ptgt->m_addr.mta_wwn; 14008 devinfo = ptgt->m_deviceinfo; 14009 phy = ptgt->m_phynum; 14010 mutex_exit(&mpt->m_mutex); 14011 14012 if (sas_wwn) { 14013 *pip = mptsas_find_path_addr(pdip, sas_wwn, lun); 14014 } else { 14015 *pip = mptsas_find_path_phy(pdip, phy); 14016 } 14017 14018 if (*pip != NULL) { 14019 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip; 14020 ASSERT(*lun_dip != NULL); 14021 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip, 14022 (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM), 14023 MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) { 14024 if (strncmp(guid, old_guid, strlen(guid)) == 0) { 14025 /* 14026 * Same path back online again. 14027 */ 14028 (void) ddi_prop_free(old_guid); 14029 if ((!MDI_PI_IS_ONLINE(*pip)) && 14030 (!MDI_PI_IS_STANDBY(*pip)) && 14031 (ptgt->m_tgt_unconfigured == 0)) { 14032 rval = mdi_pi_online(*pip, 0); 14033 mutex_enter(&mpt->m_mutex); 14034 ptgt->m_led_status = 0; 14035 (void) mptsas_flush_led_status(mpt, 14036 ptgt); 14037 mutex_exit(&mpt->m_mutex); 14038 } else { 14039 rval = DDI_SUCCESS; 14040 } 14041 if (rval != DDI_SUCCESS) { 14042 mptsas_log(mpt, CE_WARN, "path:target: " 14043 "%x, lun:%x online failed!", target, 14044 lun); 14045 *pip = NULL; 14046 *lun_dip = NULL; 14047 } 14048 return (rval); 14049 } else { 14050 /* 14051 * The GUID of the LUN has changed which maybe 14052 * because customer mapped another volume to the 14053 * same LUN. 14054 */ 14055 mptsas_log(mpt, CE_WARN, "The GUID of the " 14056 "target:%x, lun:%x was changed, maybe " 14057 "because someone mapped another volume " 14058 "to the same LUN", target, lun); 14059 (void) ddi_prop_free(old_guid); 14060 if (!MDI_PI_IS_OFFLINE(*pip)) { 14061 rval = mdi_pi_offline(*pip, 0); 14062 if (rval != MDI_SUCCESS) { 14063 mptsas_log(mpt, CE_WARN, "path:" 14064 "target:%x, lun:%x offline " 14065 "failed!", target, lun); 14066 *pip = NULL; 14067 *lun_dip = NULL; 14068 return (DDI_FAILURE); 14069 } 14070 } 14071 if (mdi_pi_free(*pip, 0) != MDI_SUCCESS) { 14072 mptsas_log(mpt, CE_WARN, "path:target:" 14073 "%x, lun:%x free failed!", target, 14074 lun); 14075 *pip = NULL; 14076 *lun_dip = NULL; 14077 return (DDI_FAILURE); 14078 } 14079 } 14080 } else { 14081 mptsas_log(mpt, CE_WARN, "Can't get client-guid " 14082 "property for path:target:%x, lun:%x", target, lun); 14083 *pip = NULL; 14084 *lun_dip = NULL; 14085 return (DDI_FAILURE); 14086 } 14087 } 14088 scsi_hba_nodename_compatible_get(inq, NULL, 14089 inq->inq_dtype, NULL, &nodename, &compatible, &ncompatible); 14090 14091 /* 14092 * if nodename can't be determined then print a message and skip it 14093 */ 14094 if (nodename == NULL) { 14095 mptsas_log(mpt, CE_WARN, "mptsas driver found no compatible " 14096 "driver for target%d lun %d dtype:0x%02x", target, lun, 14097 inq->inq_dtype); 14098 return (DDI_FAILURE); 14099 } 14100 14101 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP); 14102 /* The property is needed by MPAPI */ 14103 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn); 14104 14105 lun_addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14106 if (guid) { 14107 (void) sprintf(lun_addr, "w%s,%x", wwn_str, lun); 14108 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 14109 } else { 14110 (void) sprintf(lun_addr, "p%x,%x", phy, lun); 14111 (void) sprintf(wwn_str, "p%x", phy); 14112 } 14113 14114 mdi_rtn = mdi_pi_alloc_compatible(pdip, nodename, 14115 guid, lun_addr, compatible, ncompatible, 14116 0, pip); 14117 if (mdi_rtn == MDI_SUCCESS) { 14118 14119 if (mdi_prop_update_string(*pip, MDI_GUID, 14120 guid) != DDI_SUCCESS) { 14121 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14122 "create prop for target %d lun %d (MDI_GUID)", 14123 target, lun); 14124 mdi_rtn = MDI_FAILURE; 14125 goto virt_create_done; 14126 } 14127 14128 if (mdi_prop_update_int(*pip, LUN_PROP, 14129 lun) != DDI_SUCCESS) { 14130 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14131 "create prop for target %d lun %d (LUN_PROP)", 14132 target, lun); 14133 mdi_rtn = MDI_FAILURE; 14134 goto virt_create_done; 14135 } 14136 lun64 = (int64_t)lun; 14137 if (mdi_prop_update_int64(*pip, LUN64_PROP, 14138 lun64) != DDI_SUCCESS) { 14139 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14140 "create prop for target %d (LUN64_PROP)", 14141 target); 14142 mdi_rtn = MDI_FAILURE; 14143 goto virt_create_done; 14144 } 14145 if (mdi_prop_update_string_array(*pip, "compatible", 14146 compatible, ncompatible) != 14147 DDI_PROP_SUCCESS) { 14148 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14149 "create prop for target %d lun %d (COMPATIBLE)", 14150 target, lun); 14151 mdi_rtn = MDI_FAILURE; 14152 goto virt_create_done; 14153 } 14154 if (sas_wwn && (mdi_prop_update_string(*pip, 14155 SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != DDI_PROP_SUCCESS)) { 14156 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14157 "create prop for target %d lun %d " 14158 "(target-port)", target, lun); 14159 mdi_rtn = MDI_FAILURE; 14160 goto virt_create_done; 14161 } else if ((sas_wwn == 0) && (mdi_prop_update_int(*pip, 14162 "sata-phy", phy) != DDI_PROP_SUCCESS)) { 14163 /* 14164 * Direct attached SATA device without DeviceName 14165 */ 14166 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14167 "create prop for SAS target %d lun %d " 14168 "(sata-phy)", target, lun); 14169 mdi_rtn = MDI_FAILURE; 14170 goto virt_create_done; 14171 } 14172 mutex_enter(&mpt->m_mutex); 14173 14174 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14175 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14176 (uint32_t)ptgt->m_devhdl; 14177 rval = mptsas_get_sas_device_page0(mpt, page_address, 14178 &dev_hdl, &dev_sas_wwn, &dev_info, &physport, 14179 &phy_id, &pdev_hdl, &bay_num, &enclosure); 14180 if (rval != DDI_SUCCESS) { 14181 mutex_exit(&mpt->m_mutex); 14182 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 14183 "parent device for handle %d", page_address); 14184 mdi_rtn = MDI_FAILURE; 14185 goto virt_create_done; 14186 } 14187 14188 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14189 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl; 14190 rval = mptsas_get_sas_device_page0(mpt, page_address, 14191 &dev_hdl, &pdev_sas_wwn, &pdev_info, &physport, 14192 &phy_id, &pdev_hdl, &bay_num, &enclosure); 14193 if (rval != DDI_SUCCESS) { 14194 mutex_exit(&mpt->m_mutex); 14195 mptsas_log(mpt, CE_WARN, "mptsas unable to get" 14196 "device info for handle %d", page_address); 14197 mdi_rtn = MDI_FAILURE; 14198 goto virt_create_done; 14199 } 14200 14201 mutex_exit(&mpt->m_mutex); 14202 14203 /* 14204 * If this device direct attached to the controller 14205 * set the attached-port to the base wwid 14206 */ 14207 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 14208 != DEVINFO_DIRECT_ATTACHED) { 14209 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 14210 pdev_sas_wwn); 14211 } else { 14212 /* 14213 * Update the iport's attached-port to guid 14214 */ 14215 if (sas_wwn == 0) { 14216 (void) sprintf(wwn_str, "p%x", phy); 14217 } else { 14218 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 14219 } 14220 if (ddi_prop_update_string(DDI_DEV_T_NONE, 14221 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 14222 DDI_PROP_SUCCESS) { 14223 mptsas_log(mpt, CE_WARN, 14224 "mptsas unable to create " 14225 "property for iport target-port" 14226 " %s (sas_wwn)", 14227 wwn_str); 14228 mdi_rtn = MDI_FAILURE; 14229 goto virt_create_done; 14230 } 14231 14232 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 14233 mpt->un.m_base_wwid); 14234 } 14235 14236 if (mdi_prop_update_string(*pip, 14237 SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) != 14238 DDI_PROP_SUCCESS) { 14239 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14240 "property for iport attached-port %s (sas_wwn)", 14241 attached_wwn_str); 14242 mdi_rtn = MDI_FAILURE; 14243 goto virt_create_done; 14244 } 14245 14246 14247 if (inq->inq_dtype == 0) { 14248 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 14249 /* 14250 * set obp path for pathinfo 14251 */ 14252 (void) snprintf(component, MAXPATHLEN, 14253 "disk@%s", lun_addr); 14254 14255 if (mdi_pi_pathname_obp_set(*pip, component) != 14256 DDI_SUCCESS) { 14257 mptsas_log(mpt, CE_WARN, "mpt_sas driver " 14258 "unable to set obp-path for object %s", 14259 component); 14260 mdi_rtn = MDI_FAILURE; 14261 goto virt_create_done; 14262 } 14263 } 14264 14265 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip; 14266 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 14267 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 14268 if ((ndi_prop_update_int(DDI_DEV_T_NONE, *lun_dip, 14269 "pm-capable", 1)) != 14270 DDI_PROP_SUCCESS) { 14271 mptsas_log(mpt, CE_WARN, "mptsas driver" 14272 "failed to create pm-capable " 14273 "property, target %d", target); 14274 mdi_rtn = MDI_FAILURE; 14275 goto virt_create_done; 14276 } 14277 } 14278 /* 14279 * Create the phy-num property 14280 */ 14281 if (mdi_prop_update_int(*pip, "phy-num", 14282 ptgt->m_phynum) != DDI_SUCCESS) { 14283 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14284 "create phy-num property for target %d lun %d", 14285 target, lun); 14286 mdi_rtn = MDI_FAILURE; 14287 goto virt_create_done; 14288 } 14289 NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr)); 14290 mdi_rtn = mdi_pi_online(*pip, 0); 14291 if (mdi_rtn == MDI_SUCCESS) { 14292 mutex_enter(&mpt->m_mutex); 14293 ptgt->m_led_status = 0; 14294 (void) mptsas_flush_led_status(mpt, ptgt); 14295 mutex_exit(&mpt->m_mutex); 14296 } 14297 if (mdi_rtn == MDI_NOT_SUPPORTED) { 14298 mdi_rtn = MDI_FAILURE; 14299 } 14300 virt_create_done: 14301 if (*pip && mdi_rtn != MDI_SUCCESS) { 14302 (void) mdi_pi_free(*pip, 0); 14303 *pip = NULL; 14304 *lun_dip = NULL; 14305 } 14306 } 14307 14308 scsi_hba_nodename_compatible_free(nodename, compatible); 14309 if (lun_addr != NULL) { 14310 kmem_free(lun_addr, SCSI_MAXNAMELEN); 14311 } 14312 if (wwn_str != NULL) { 14313 kmem_free(wwn_str, MPTSAS_WWN_STRLEN); 14314 } 14315 if (component != NULL) { 14316 kmem_free(component, MAXPATHLEN); 14317 } 14318 14319 return ((mdi_rtn == MDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 14320 } 14321 14322 static int 14323 mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *inq, 14324 char *guid, dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun) 14325 { 14326 int target; 14327 int rval; 14328 int ndi_rtn = NDI_FAILURE; 14329 uint64_t be_sas_wwn; 14330 char *nodename = NULL; 14331 char **compatible = NULL; 14332 int ncompatible = 0; 14333 int instance = 0; 14334 mptsas_t *mpt = DIP2MPT(pdip); 14335 char *wwn_str = NULL; 14336 char *component = NULL; 14337 char *attached_wwn_str = NULL; 14338 uint8_t phy = 0xFF; 14339 uint64_t sas_wwn; 14340 uint32_t devinfo; 14341 uint16_t dev_hdl; 14342 uint16_t pdev_hdl; 14343 uint64_t pdev_sas_wwn; 14344 uint64_t dev_sas_wwn; 14345 uint32_t pdev_info; 14346 uint8_t physport; 14347 uint8_t phy_id; 14348 uint32_t page_address; 14349 uint16_t bay_num, enclosure; 14350 char pdev_wwn_str[MPTSAS_WWN_STRLEN]; 14351 uint32_t dev_info; 14352 int64_t lun64 = 0; 14353 14354 mutex_enter(&mpt->m_mutex); 14355 target = ptgt->m_devhdl; 14356 sas_wwn = ptgt->m_addr.mta_wwn; 14357 devinfo = ptgt->m_deviceinfo; 14358 phy = ptgt->m_phynum; 14359 mutex_exit(&mpt->m_mutex); 14360 14361 /* 14362 * generate compatible property with binding-set "mpt" 14363 */ 14364 scsi_hba_nodename_compatible_get(inq, NULL, inq->inq_dtype, NULL, 14365 &nodename, &compatible, &ncompatible); 14366 14367 /* 14368 * if nodename can't be determined then print a message and skip it 14369 */ 14370 if (nodename == NULL) { 14371 mptsas_log(mpt, CE_WARN, "mptsas found no compatible driver " 14372 "for target %d lun %d", target, lun); 14373 return (DDI_FAILURE); 14374 } 14375 14376 ndi_rtn = ndi_devi_alloc(pdip, nodename, 14377 DEVI_SID_NODEID, lun_dip); 14378 14379 /* 14380 * if lun alloc success, set props 14381 */ 14382 if (ndi_rtn == NDI_SUCCESS) { 14383 14384 if (ndi_prop_update_int(DDI_DEV_T_NONE, 14385 *lun_dip, LUN_PROP, lun) != 14386 DDI_PROP_SUCCESS) { 14387 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14388 "property for target %d lun %d (LUN_PROP)", 14389 target, lun); 14390 ndi_rtn = NDI_FAILURE; 14391 goto phys_create_done; 14392 } 14393 14394 lun64 = (int64_t)lun; 14395 if (ndi_prop_update_int64(DDI_DEV_T_NONE, 14396 *lun_dip, LUN64_PROP, lun64) != 14397 DDI_PROP_SUCCESS) { 14398 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14399 "property for target %d lun64 %d (LUN64_PROP)", 14400 target, lun); 14401 ndi_rtn = NDI_FAILURE; 14402 goto phys_create_done; 14403 } 14404 if (ndi_prop_update_string_array(DDI_DEV_T_NONE, 14405 *lun_dip, "compatible", compatible, ncompatible) 14406 != DDI_PROP_SUCCESS) { 14407 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14408 "property for target %d lun %d (COMPATIBLE)", 14409 target, lun); 14410 ndi_rtn = NDI_FAILURE; 14411 goto phys_create_done; 14412 } 14413 14414 /* 14415 * We need the SAS WWN for non-multipath devices, so 14416 * we'll use the same property as that multipathing 14417 * devices need to present for MPAPI. If we don't have 14418 * a WWN (e.g. parallel SCSI), don't create the prop. 14419 */ 14420 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP); 14421 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 14422 if (sas_wwn && ndi_prop_update_string(DDI_DEV_T_NONE, 14423 *lun_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) 14424 != DDI_PROP_SUCCESS) { 14425 mptsas_log(mpt, CE_WARN, "mptsas unable to " 14426 "create property for SAS target %d lun %d " 14427 "(target-port)", target, lun); 14428 ndi_rtn = NDI_FAILURE; 14429 goto phys_create_done; 14430 } 14431 14432 be_sas_wwn = BE_64(sas_wwn); 14433 if (sas_wwn && ndi_prop_update_byte_array( 14434 DDI_DEV_T_NONE, *lun_dip, "port-wwn", 14435 (uchar_t *)&be_sas_wwn, 8) != DDI_PROP_SUCCESS) { 14436 mptsas_log(mpt, CE_WARN, "mptsas unable to " 14437 "create property for SAS target %d lun %d " 14438 "(port-wwn)", target, lun); 14439 ndi_rtn = NDI_FAILURE; 14440 goto phys_create_done; 14441 } else if ((sas_wwn == 0) && (ndi_prop_update_int( 14442 DDI_DEV_T_NONE, *lun_dip, "sata-phy", phy) != 14443 DDI_PROP_SUCCESS)) { 14444 /* 14445 * Direct attached SATA device without DeviceName 14446 */ 14447 mptsas_log(mpt, CE_WARN, "mptsas unable to " 14448 "create property for SAS target %d lun %d " 14449 "(sata-phy)", target, lun); 14450 ndi_rtn = NDI_FAILURE; 14451 goto phys_create_done; 14452 } 14453 14454 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 14455 *lun_dip, SAS_PROP) != DDI_PROP_SUCCESS) { 14456 mptsas_log(mpt, CE_WARN, "mptsas unable to" 14457 "create property for SAS target %d lun %d" 14458 " (SAS_PROP)", target, lun); 14459 ndi_rtn = NDI_FAILURE; 14460 goto phys_create_done; 14461 } 14462 if (guid && (ndi_prop_update_string(DDI_DEV_T_NONE, 14463 *lun_dip, NDI_GUID, guid) != DDI_SUCCESS)) { 14464 mptsas_log(mpt, CE_WARN, "mptsas unable " 14465 "to create guid property for target %d " 14466 "lun %d", target, lun); 14467 ndi_rtn = NDI_FAILURE; 14468 goto phys_create_done; 14469 } 14470 14471 /* 14472 * The following code is to set properties for SM-HBA support, 14473 * it doesn't apply to RAID volumes 14474 */ 14475 if (ptgt->m_addr.mta_phymask == 0) 14476 goto phys_raid_lun; 14477 14478 mutex_enter(&mpt->m_mutex); 14479 14480 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14481 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14482 (uint32_t)ptgt->m_devhdl; 14483 rval = mptsas_get_sas_device_page0(mpt, page_address, 14484 &dev_hdl, &dev_sas_wwn, &dev_info, 14485 &physport, &phy_id, &pdev_hdl, 14486 &bay_num, &enclosure); 14487 if (rval != DDI_SUCCESS) { 14488 mutex_exit(&mpt->m_mutex); 14489 mptsas_log(mpt, CE_WARN, "mptsas unable to get" 14490 "parent device for handle %d.", page_address); 14491 ndi_rtn = NDI_FAILURE; 14492 goto phys_create_done; 14493 } 14494 14495 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14496 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl; 14497 rval = mptsas_get_sas_device_page0(mpt, page_address, 14498 &dev_hdl, &pdev_sas_wwn, &pdev_info, 14499 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure); 14500 if (rval != DDI_SUCCESS) { 14501 mutex_exit(&mpt->m_mutex); 14502 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14503 "device for handle %d.", page_address); 14504 ndi_rtn = NDI_FAILURE; 14505 goto phys_create_done; 14506 } 14507 14508 mutex_exit(&mpt->m_mutex); 14509 14510 /* 14511 * If this device direct attached to the controller 14512 * set the attached-port to the base wwid 14513 */ 14514 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 14515 != DEVINFO_DIRECT_ATTACHED) { 14516 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 14517 pdev_sas_wwn); 14518 } else { 14519 /* 14520 * Update the iport's attached-port to guid 14521 */ 14522 if (sas_wwn == 0) { 14523 (void) sprintf(wwn_str, "p%x", phy); 14524 } else { 14525 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 14526 } 14527 if (ddi_prop_update_string(DDI_DEV_T_NONE, 14528 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 14529 DDI_PROP_SUCCESS) { 14530 mptsas_log(mpt, CE_WARN, 14531 "mptsas unable to create " 14532 "property for iport target-port" 14533 " %s (sas_wwn)", 14534 wwn_str); 14535 ndi_rtn = NDI_FAILURE; 14536 goto phys_create_done; 14537 } 14538 14539 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 14540 mpt->un.m_base_wwid); 14541 } 14542 14543 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14544 *lun_dip, SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) != 14545 DDI_PROP_SUCCESS) { 14546 mptsas_log(mpt, CE_WARN, 14547 "mptsas unable to create " 14548 "property for iport attached-port %s (sas_wwn)", 14549 attached_wwn_str); 14550 ndi_rtn = NDI_FAILURE; 14551 goto phys_create_done; 14552 } 14553 14554 if (IS_SATA_DEVICE(dev_info)) { 14555 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14556 *lun_dip, MPTSAS_VARIANT, "sata") != 14557 DDI_PROP_SUCCESS) { 14558 mptsas_log(mpt, CE_WARN, 14559 "mptsas unable to create " 14560 "property for device variant "); 14561 ndi_rtn = NDI_FAILURE; 14562 goto phys_create_done; 14563 } 14564 } 14565 14566 if (IS_ATAPI_DEVICE(dev_info)) { 14567 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14568 *lun_dip, MPTSAS_VARIANT, "atapi") != 14569 DDI_PROP_SUCCESS) { 14570 mptsas_log(mpt, CE_WARN, 14571 "mptsas unable to create " 14572 "property for device variant "); 14573 ndi_rtn = NDI_FAILURE; 14574 goto phys_create_done; 14575 } 14576 } 14577 14578 phys_raid_lun: 14579 /* 14580 * if this is a SAS controller, and the target is a SATA 14581 * drive, set the 'pm-capable' property for sd and if on 14582 * an OPL platform, also check if this is an ATAPI 14583 * device. 14584 */ 14585 instance = ddi_get_instance(mpt->m_dip); 14586 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 14587 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 14588 NDBG2(("mptsas%d: creating pm-capable property, " 14589 "target %d", instance, target)); 14590 14591 if ((ndi_prop_update_int(DDI_DEV_T_NONE, 14592 *lun_dip, "pm-capable", 1)) != 14593 DDI_PROP_SUCCESS) { 14594 mptsas_log(mpt, CE_WARN, "mptsas " 14595 "failed to create pm-capable " 14596 "property, target %d", target); 14597 ndi_rtn = NDI_FAILURE; 14598 goto phys_create_done; 14599 } 14600 14601 } 14602 14603 if ((inq->inq_dtype == 0) || (inq->inq_dtype == 5)) { 14604 /* 14605 * add 'obp-path' properties for devinfo 14606 */ 14607 bzero(wwn_str, sizeof (wwn_str)); 14608 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn); 14609 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 14610 if (guid) { 14611 (void) snprintf(component, MAXPATHLEN, 14612 "disk@w%s,%x", wwn_str, lun); 14613 } else { 14614 (void) snprintf(component, MAXPATHLEN, 14615 "disk@p%x,%x", phy, lun); 14616 } 14617 if (ddi_pathname_obp_set(*lun_dip, component) 14618 != DDI_SUCCESS) { 14619 mptsas_log(mpt, CE_WARN, "mpt_sas driver " 14620 "unable to set obp-path for SAS " 14621 "object %s", component); 14622 ndi_rtn = NDI_FAILURE; 14623 goto phys_create_done; 14624 } 14625 } 14626 /* 14627 * Create the phy-num property for non-raid disk 14628 */ 14629 if (ptgt->m_addr.mta_phymask != 0) { 14630 if (ndi_prop_update_int(DDI_DEV_T_NONE, 14631 *lun_dip, "phy-num", ptgt->m_phynum) != 14632 DDI_PROP_SUCCESS) { 14633 mptsas_log(mpt, CE_WARN, "mptsas driver " 14634 "failed to create phy-num property for " 14635 "target %d", target); 14636 ndi_rtn = NDI_FAILURE; 14637 goto phys_create_done; 14638 } 14639 } 14640 phys_create_done: 14641 /* 14642 * If props were setup ok, online the lun 14643 */ 14644 if (ndi_rtn == NDI_SUCCESS) { 14645 /* 14646 * Try to online the new node 14647 */ 14648 ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH); 14649 } 14650 if (ndi_rtn == NDI_SUCCESS) { 14651 mutex_enter(&mpt->m_mutex); 14652 ptgt->m_led_status = 0; 14653 (void) mptsas_flush_led_status(mpt, ptgt); 14654 mutex_exit(&mpt->m_mutex); 14655 } 14656 14657 /* 14658 * If success set rtn flag, else unwire alloc'd lun 14659 */ 14660 if (ndi_rtn != NDI_SUCCESS) { 14661 NDBG12(("mptsas driver unable to online " 14662 "target %d lun %d", target, lun)); 14663 ndi_prop_remove_all(*lun_dip); 14664 (void) ndi_devi_free(*lun_dip); 14665 *lun_dip = NULL; 14666 } 14667 } 14668 14669 scsi_hba_nodename_compatible_free(nodename, compatible); 14670 14671 if (wwn_str != NULL) { 14672 kmem_free(wwn_str, MPTSAS_WWN_STRLEN); 14673 } 14674 if (component != NULL) { 14675 kmem_free(component, MAXPATHLEN); 14676 } 14677 14678 14679 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 14680 } 14681 14682 static int 14683 mptsas_probe_smp(dev_info_t *pdip, uint64_t wwn) 14684 { 14685 mptsas_t *mpt = DIP2MPT(pdip); 14686 struct smp_device smp_sd; 14687 14688 /* XXX An HBA driver should not be allocating an smp_device. */ 14689 bzero(&smp_sd, sizeof (struct smp_device)); 14690 smp_sd.smp_sd_address.smp_a_hba_tran = mpt->m_smptran; 14691 bcopy(&wwn, smp_sd.smp_sd_address.smp_a_wwn, SAS_WWN_BYTE_SIZE); 14692 14693 if (smp_probe(&smp_sd) != DDI_PROBE_SUCCESS) 14694 return (NDI_FAILURE); 14695 return (NDI_SUCCESS); 14696 } 14697 14698 static int 14699 mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, dev_info_t **smp_dip) 14700 { 14701 mptsas_t *mpt = DIP2MPT(pdip); 14702 mptsas_smp_t *psmp = NULL; 14703 int rval; 14704 int phymask; 14705 14706 /* 14707 * Get the physical port associated to the iport 14708 * PHYMASK TODO 14709 */ 14710 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 14711 "phymask", 0); 14712 /* 14713 * Find the smp node in hash table with specified sas address and 14714 * physical port 14715 */ 14716 psmp = mptsas_wwid_to_psmp(mpt, phymask, sas_wwn); 14717 if (psmp == NULL) { 14718 return (DDI_FAILURE); 14719 } 14720 14721 rval = mptsas_online_smp(pdip, psmp, smp_dip); 14722 14723 return (rval); 14724 } 14725 14726 static int 14727 mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 14728 dev_info_t **smp_dip) 14729 { 14730 char wwn_str[MPTSAS_WWN_STRLEN]; 14731 char attached_wwn_str[MPTSAS_WWN_STRLEN]; 14732 int ndi_rtn = NDI_FAILURE; 14733 int rval = 0; 14734 mptsas_smp_t dev_info; 14735 uint32_t page_address; 14736 mptsas_t *mpt = DIP2MPT(pdip); 14737 uint16_t dev_hdl; 14738 uint64_t sas_wwn; 14739 uint64_t smp_sas_wwn; 14740 uint8_t physport; 14741 uint8_t phy_id; 14742 uint16_t pdev_hdl; 14743 uint8_t numphys = 0; 14744 uint16_t i = 0; 14745 char phymask[MPTSAS_MAX_PHYS]; 14746 char *iport = NULL; 14747 mptsas_phymask_t phy_mask = 0; 14748 uint16_t attached_devhdl; 14749 uint16_t bay_num, enclosure; 14750 14751 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn); 14752 14753 /* 14754 * Probe smp device, prevent the node of removed device from being 14755 * configured succesfully 14756 */ 14757 if (mptsas_probe_smp(pdip, smp_node->m_addr.mta_wwn) != NDI_SUCCESS) { 14758 return (DDI_FAILURE); 14759 } 14760 14761 if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) { 14762 return (DDI_SUCCESS); 14763 } 14764 14765 ndi_rtn = ndi_devi_alloc(pdip, "smp", DEVI_SID_NODEID, smp_dip); 14766 14767 /* 14768 * if lun alloc success, set props 14769 */ 14770 if (ndi_rtn == NDI_SUCCESS) { 14771 /* 14772 * Set the flavor of the child to be SMP flavored 14773 */ 14774 ndi_flavor_set(*smp_dip, SCSA_FLAVOR_SMP); 14775 14776 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14777 *smp_dip, SMP_WWN, wwn_str) != 14778 DDI_PROP_SUCCESS) { 14779 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14780 "property for smp device %s (sas_wwn)", 14781 wwn_str); 14782 ndi_rtn = NDI_FAILURE; 14783 goto smp_create_done; 14784 } 14785 (void) sprintf(wwn_str, "w%"PRIx64, smp_node->m_addr.mta_wwn); 14786 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14787 *smp_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != 14788 DDI_PROP_SUCCESS) { 14789 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14790 "property for iport target-port %s (sas_wwn)", 14791 wwn_str); 14792 ndi_rtn = NDI_FAILURE; 14793 goto smp_create_done; 14794 } 14795 14796 mutex_enter(&mpt->m_mutex); 14797 14798 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL & 14799 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | smp_node->m_devhdl; 14800 rval = mptsas_get_sas_expander_page0(mpt, page_address, 14801 &dev_info); 14802 if (rval != DDI_SUCCESS) { 14803 mutex_exit(&mpt->m_mutex); 14804 mptsas_log(mpt, CE_WARN, 14805 "mptsas unable to get expander " 14806 "parent device info for %x", page_address); 14807 ndi_rtn = NDI_FAILURE; 14808 goto smp_create_done; 14809 } 14810 14811 smp_node->m_pdevhdl = dev_info.m_pdevhdl; 14812 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14813 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14814 (uint32_t)dev_info.m_pdevhdl; 14815 rval = mptsas_get_sas_device_page0(mpt, page_address, 14816 &dev_hdl, &sas_wwn, &smp_node->m_pdevinfo, 14817 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure); 14818 if (rval != DDI_SUCCESS) { 14819 mutex_exit(&mpt->m_mutex); 14820 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 14821 "device info for %x", page_address); 14822 ndi_rtn = NDI_FAILURE; 14823 goto smp_create_done; 14824 } 14825 14826 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14827 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14828 (uint32_t)dev_info.m_devhdl; 14829 rval = mptsas_get_sas_device_page0(mpt, page_address, 14830 &dev_hdl, &smp_sas_wwn, &smp_node->m_deviceinfo, 14831 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure); 14832 if (rval != DDI_SUCCESS) { 14833 mutex_exit(&mpt->m_mutex); 14834 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 14835 "device info for %x", page_address); 14836 ndi_rtn = NDI_FAILURE; 14837 goto smp_create_done; 14838 } 14839 mutex_exit(&mpt->m_mutex); 14840 14841 /* 14842 * If this smp direct attached to the controller 14843 * set the attached-port to the base wwid 14844 */ 14845 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 14846 != DEVINFO_DIRECT_ATTACHED) { 14847 (void) sprintf(attached_wwn_str, "w%016"PRIx64, 14848 sas_wwn); 14849 } else { 14850 (void) sprintf(attached_wwn_str, "w%016"PRIx64, 14851 mpt->un.m_base_wwid); 14852 } 14853 14854 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14855 *smp_dip, SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwn_str) != 14856 DDI_PROP_SUCCESS) { 14857 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14858 "property for smp attached-port %s (sas_wwn)", 14859 attached_wwn_str); 14860 ndi_rtn = NDI_FAILURE; 14861 goto smp_create_done; 14862 } 14863 14864 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 14865 *smp_dip, SMP_PROP) != DDI_PROP_SUCCESS) { 14866 mptsas_log(mpt, CE_WARN, "mptsas unable to " 14867 "create property for SMP %s (SMP_PROP) ", 14868 wwn_str); 14869 ndi_rtn = NDI_FAILURE; 14870 goto smp_create_done; 14871 } 14872 14873 /* 14874 * check the smp to see whether it direct 14875 * attached to the controller 14876 */ 14877 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 14878 != DEVINFO_DIRECT_ATTACHED) { 14879 goto smp_create_done; 14880 } 14881 numphys = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 14882 DDI_PROP_DONTPASS, MPTSAS_NUM_PHYS, -1); 14883 if (numphys > 0) { 14884 goto smp_create_done; 14885 } 14886 /* 14887 * this iport is an old iport, we need to 14888 * reconfig the props for it. 14889 */ 14890 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip, 14891 MPTSAS_VIRTUAL_PORT, 0) != 14892 DDI_PROP_SUCCESS) { 14893 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 14894 MPTSAS_VIRTUAL_PORT); 14895 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 14896 "prop update failed"); 14897 goto smp_create_done; 14898 } 14899 14900 mutex_enter(&mpt->m_mutex); 14901 numphys = 0; 14902 iport = ddi_get_name_addr(pdip); 14903 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 14904 bzero(phymask, sizeof (phymask)); 14905 (void) sprintf(phymask, 14906 "%x", mpt->m_phy_info[i].phy_mask); 14907 if (strcmp(phymask, iport) == 0) { 14908 phy_mask = mpt->m_phy_info[i].phy_mask; 14909 break; 14910 } 14911 } 14912 14913 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 14914 if ((phy_mask >> i) & 0x01) { 14915 numphys++; 14916 } 14917 } 14918 /* 14919 * Update PHY info for smhba 14920 */ 14921 if (mptsas_smhba_phy_init(mpt)) { 14922 mutex_exit(&mpt->m_mutex); 14923 mptsas_log(mpt, CE_WARN, "mptsas phy update " 14924 "failed"); 14925 goto smp_create_done; 14926 } 14927 mutex_exit(&mpt->m_mutex); 14928 14929 mptsas_smhba_set_all_phy_props(mpt, pdip, numphys, phy_mask, 14930 &attached_devhdl); 14931 14932 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip, 14933 MPTSAS_NUM_PHYS, numphys) != 14934 DDI_PROP_SUCCESS) { 14935 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 14936 MPTSAS_NUM_PHYS); 14937 mptsas_log(mpt, CE_WARN, "mptsas update " 14938 "num phys props failed"); 14939 goto smp_create_done; 14940 } 14941 /* 14942 * Add parent's props for SMHBA support 14943 */ 14944 if (ddi_prop_update_string(DDI_DEV_T_NONE, pdip, 14945 SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 14946 DDI_PROP_SUCCESS) { 14947 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 14948 SCSI_ADDR_PROP_ATTACHED_PORT); 14949 mptsas_log(mpt, CE_WARN, "mptsas update iport" 14950 "attached-port failed"); 14951 goto smp_create_done; 14952 } 14953 14954 smp_create_done: 14955 /* 14956 * If props were setup ok, online the lun 14957 */ 14958 if (ndi_rtn == NDI_SUCCESS) { 14959 /* 14960 * Try to online the new node 14961 */ 14962 ndi_rtn = ndi_devi_online(*smp_dip, NDI_ONLINE_ATTACH); 14963 } 14964 14965 /* 14966 * If success set rtn flag, else unwire alloc'd lun 14967 */ 14968 if (ndi_rtn != NDI_SUCCESS) { 14969 NDBG12(("mptsas unable to online " 14970 "SMP target %s", wwn_str)); 14971 ndi_prop_remove_all(*smp_dip); 14972 (void) ndi_devi_free(*smp_dip); 14973 } 14974 } 14975 14976 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 14977 } 14978 14979 /* smp transport routine */ 14980 static int mptsas_smp_start(struct smp_pkt *smp_pkt) 14981 { 14982 uint64_t wwn; 14983 Mpi2SmpPassthroughRequest_t req; 14984 Mpi2SmpPassthroughReply_t rep; 14985 uint32_t direction = 0; 14986 mptsas_t *mpt; 14987 int ret; 14988 uint64_t tmp64; 14989 14990 mpt = (mptsas_t *)smp_pkt->smp_pkt_address-> 14991 smp_a_hba_tran->smp_tran_hba_private; 14992 14993 bcopy(smp_pkt->smp_pkt_address->smp_a_wwn, &wwn, SAS_WWN_BYTE_SIZE); 14994 /* 14995 * Need to compose a SMP request message 14996 * and call mptsas_do_passthru() function 14997 */ 14998 bzero(&req, sizeof (req)); 14999 bzero(&rep, sizeof (rep)); 15000 req.PassthroughFlags = 0; 15001 req.PhysicalPort = 0xff; 15002 req.ChainOffset = 0; 15003 req.Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 15004 15005 if ((smp_pkt->smp_pkt_reqsize & 0xffff0000ul) != 0) { 15006 smp_pkt->smp_pkt_reason = ERANGE; 15007 return (DDI_FAILURE); 15008 } 15009 req.RequestDataLength = LE_16((uint16_t)(smp_pkt->smp_pkt_reqsize - 4)); 15010 15011 req.MsgFlags = 0; 15012 tmp64 = LE_64(wwn); 15013 bcopy(&tmp64, &req.SASAddress, SAS_WWN_BYTE_SIZE); 15014 if (smp_pkt->smp_pkt_rspsize > 0) { 15015 direction |= MPTSAS_PASS_THRU_DIRECTION_READ; 15016 } 15017 if (smp_pkt->smp_pkt_reqsize > 0) { 15018 direction |= MPTSAS_PASS_THRU_DIRECTION_WRITE; 15019 } 15020 15021 mutex_enter(&mpt->m_mutex); 15022 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, 15023 (uint8_t *)smp_pkt->smp_pkt_rsp, 15024 offsetof(Mpi2SmpPassthroughRequest_t, SGL), sizeof (rep), 15025 smp_pkt->smp_pkt_rspsize - 4, direction, 15026 (uint8_t *)smp_pkt->smp_pkt_req, smp_pkt->smp_pkt_reqsize - 4, 15027 smp_pkt->smp_pkt_timeout, FKIOCTL); 15028 mutex_exit(&mpt->m_mutex); 15029 if (ret != 0) { 15030 cmn_err(CE_WARN, "smp_start do passthru error %d", ret); 15031 smp_pkt->smp_pkt_reason = (uchar_t)(ret); 15032 return (DDI_FAILURE); 15033 } 15034 /* do passthrough success, check the smp status */ 15035 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 15036 switch (LE_16(rep.IOCStatus)) { 15037 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 15038 smp_pkt->smp_pkt_reason = ENODEV; 15039 break; 15040 case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN: 15041 smp_pkt->smp_pkt_reason = EOVERFLOW; 15042 break; 15043 case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED: 15044 smp_pkt->smp_pkt_reason = EIO; 15045 break; 15046 default: 15047 mptsas_log(mpt, CE_NOTE, "smp_start: get unknown ioc" 15048 "status:%x", LE_16(rep.IOCStatus)); 15049 smp_pkt->smp_pkt_reason = EIO; 15050 break; 15051 } 15052 return (DDI_FAILURE); 15053 } 15054 if (rep.SASStatus != MPI2_SASSTATUS_SUCCESS) { 15055 mptsas_log(mpt, CE_NOTE, "smp_start: get error SAS status:%x", 15056 rep.SASStatus); 15057 smp_pkt->smp_pkt_reason = EIO; 15058 return (DDI_FAILURE); 15059 } 15060 15061 return (DDI_SUCCESS); 15062 } 15063 15064 /* 15065 * If we didn't get a match, we need to get sas page0 for each device, and 15066 * untill we get a match. If failed, return NULL 15067 */ 15068 static mptsas_target_t * 15069 mptsas_phy_to_tgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint8_t phy) 15070 { 15071 int i, j = 0; 15072 int rval = 0; 15073 uint16_t cur_handle; 15074 uint32_t page_address; 15075 mptsas_target_t *ptgt = NULL; 15076 15077 /* 15078 * PHY named device must be direct attached and attaches to 15079 * narrow port, if the iport is not parent of the device which 15080 * we are looking for. 15081 */ 15082 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 15083 if ((1 << i) & phymask) 15084 j++; 15085 } 15086 15087 if (j > 1) 15088 return (NULL); 15089 15090 /* 15091 * Must be a narrow port and single device attached to the narrow port 15092 * So the physical port num of device which is equal to the iport's 15093 * port num is the device what we are looking for. 15094 */ 15095 15096 if (mpt->m_phy_info[phy].phy_mask != phymask) 15097 return (NULL); 15098 15099 mutex_enter(&mpt->m_mutex); 15100 15101 ptgt = refhash_linear_search(mpt->m_targets, mptsas_target_eval_nowwn, 15102 &phy); 15103 if (ptgt != NULL) { 15104 mutex_exit(&mpt->m_mutex); 15105 return (ptgt); 15106 } 15107 15108 if (mpt->m_done_traverse_dev) { 15109 mutex_exit(&mpt->m_mutex); 15110 return (NULL); 15111 } 15112 15113 /* If didn't get a match, come here */ 15114 cur_handle = mpt->m_dev_handle; 15115 for (; ; ) { 15116 ptgt = NULL; 15117 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 15118 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)cur_handle; 15119 rval = mptsas_get_target_device_info(mpt, page_address, 15120 &cur_handle, &ptgt); 15121 if ((rval == DEV_INFO_FAIL_PAGE0) || 15122 (rval == DEV_INFO_FAIL_ALLOC)) { 15123 break; 15124 } 15125 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) || 15126 (rval == DEV_INFO_PHYS_DISK)) { 15127 continue; 15128 } 15129 mpt->m_dev_handle = cur_handle; 15130 15131 if ((ptgt->m_addr.mta_wwn == 0) && (ptgt->m_phynum == phy)) { 15132 break; 15133 } 15134 } 15135 15136 mutex_exit(&mpt->m_mutex); 15137 return (ptgt); 15138 } 15139 15140 /* 15141 * The ptgt->m_addr.mta_wwn contains the wwid for each disk. 15142 * For Raid volumes, we need to check m_raidvol[x].m_raidwwid 15143 * If we didn't get a match, we need to get sas page0 for each device, and 15144 * untill we get a match 15145 * If failed, return NULL 15146 */ 15147 static mptsas_target_t * 15148 mptsas_wwid_to_ptgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid) 15149 { 15150 int rval = 0; 15151 uint16_t cur_handle; 15152 uint32_t page_address; 15153 mptsas_target_t *tmp_tgt = NULL; 15154 mptsas_target_addr_t addr; 15155 15156 addr.mta_wwn = wwid; 15157 addr.mta_phymask = phymask; 15158 mutex_enter(&mpt->m_mutex); 15159 tmp_tgt = refhash_lookup(mpt->m_targets, &addr); 15160 if (tmp_tgt != NULL) { 15161 mutex_exit(&mpt->m_mutex); 15162 return (tmp_tgt); 15163 } 15164 15165 if (phymask == 0) { 15166 /* 15167 * It's IR volume 15168 */ 15169 rval = mptsas_get_raid_info(mpt); 15170 if (rval) { 15171 tmp_tgt = refhash_lookup(mpt->m_targets, &addr); 15172 } 15173 mutex_exit(&mpt->m_mutex); 15174 return (tmp_tgt); 15175 } 15176 15177 if (mpt->m_done_traverse_dev) { 15178 mutex_exit(&mpt->m_mutex); 15179 return (NULL); 15180 } 15181 15182 /* If didn't get a match, come here */ 15183 cur_handle = mpt->m_dev_handle; 15184 for (;;) { 15185 tmp_tgt = NULL; 15186 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 15187 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle; 15188 rval = mptsas_get_target_device_info(mpt, page_address, 15189 &cur_handle, &tmp_tgt); 15190 if ((rval == DEV_INFO_FAIL_PAGE0) || 15191 (rval == DEV_INFO_FAIL_ALLOC)) { 15192 tmp_tgt = NULL; 15193 break; 15194 } 15195 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) || 15196 (rval == DEV_INFO_PHYS_DISK)) { 15197 continue; 15198 } 15199 mpt->m_dev_handle = cur_handle; 15200 if ((tmp_tgt->m_addr.mta_wwn) && 15201 (tmp_tgt->m_addr.mta_wwn == wwid) && 15202 (tmp_tgt->m_addr.mta_phymask == phymask)) { 15203 break; 15204 } 15205 } 15206 15207 mutex_exit(&mpt->m_mutex); 15208 return (tmp_tgt); 15209 } 15210 15211 static mptsas_smp_t * 15212 mptsas_wwid_to_psmp(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid) 15213 { 15214 int rval = 0; 15215 uint16_t cur_handle; 15216 uint32_t page_address; 15217 mptsas_smp_t smp_node, *psmp = NULL; 15218 mptsas_target_addr_t addr; 15219 15220 addr.mta_wwn = wwid; 15221 addr.mta_phymask = phymask; 15222 mutex_enter(&mpt->m_mutex); 15223 psmp = refhash_lookup(mpt->m_smp_targets, &addr); 15224 if (psmp != NULL) { 15225 mutex_exit(&mpt->m_mutex); 15226 return (psmp); 15227 } 15228 15229 if (mpt->m_done_traverse_smp) { 15230 mutex_exit(&mpt->m_mutex); 15231 return (NULL); 15232 } 15233 15234 /* If didn't get a match, come here */ 15235 cur_handle = mpt->m_smp_devhdl; 15236 for (;;) { 15237 psmp = NULL; 15238 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL & 15239 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle; 15240 rval = mptsas_get_sas_expander_page0(mpt, page_address, 15241 &smp_node); 15242 if (rval != DDI_SUCCESS) { 15243 break; 15244 } 15245 mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl; 15246 psmp = mptsas_smp_alloc(mpt, &smp_node); 15247 ASSERT(psmp); 15248 if ((psmp->m_addr.mta_wwn) && (psmp->m_addr.mta_wwn == wwid) && 15249 (psmp->m_addr.mta_phymask == phymask)) { 15250 break; 15251 } 15252 } 15253 15254 mutex_exit(&mpt->m_mutex); 15255 return (psmp); 15256 } 15257 15258 mptsas_target_t * 15259 mptsas_tgt_alloc(mptsas_t *mpt, uint16_t devhdl, uint64_t wwid, 15260 uint32_t devinfo, mptsas_phymask_t phymask, uint8_t phynum) 15261 { 15262 mptsas_target_t *tmp_tgt = NULL; 15263 mptsas_target_addr_t addr; 15264 15265 addr.mta_wwn = wwid; 15266 addr.mta_phymask = phymask; 15267 tmp_tgt = refhash_lookup(mpt->m_targets, &addr); 15268 if (tmp_tgt != NULL) { 15269 NDBG20(("Hash item already exist")); 15270 tmp_tgt->m_deviceinfo = devinfo; 15271 tmp_tgt->m_devhdl = devhdl; /* XXX - duplicate? */ 15272 return (tmp_tgt); 15273 } 15274 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP); 15275 if (tmp_tgt == NULL) { 15276 cmn_err(CE_WARN, "Fatal, allocated tgt failed"); 15277 return (NULL); 15278 } 15279 tmp_tgt->m_devhdl = devhdl; 15280 tmp_tgt->m_addr.mta_wwn = wwid; 15281 tmp_tgt->m_deviceinfo = devinfo; 15282 tmp_tgt->m_addr.mta_phymask = phymask; 15283 tmp_tgt->m_phynum = phynum; 15284 /* Initialized the tgt structure */ 15285 tmp_tgt->m_qfull_retries = QFULL_RETRIES; 15286 tmp_tgt->m_qfull_retry_interval = 15287 drv_usectohz(QFULL_RETRY_INTERVAL * 1000); 15288 tmp_tgt->m_t_throttle = MAX_THROTTLE; 15289 TAILQ_INIT(&tmp_tgt->m_active_cmdq); 15290 15291 refhash_insert(mpt->m_targets, tmp_tgt); 15292 15293 return (tmp_tgt); 15294 } 15295 15296 static void 15297 mptsas_smp_target_copy(mptsas_smp_t *src, mptsas_smp_t *dst) 15298 { 15299 dst->m_devhdl = src->m_devhdl; 15300 dst->m_deviceinfo = src->m_deviceinfo; 15301 dst->m_pdevhdl = src->m_pdevhdl; 15302 dst->m_pdevinfo = src->m_pdevinfo; 15303 } 15304 15305 static mptsas_smp_t * 15306 mptsas_smp_alloc(mptsas_t *mpt, mptsas_smp_t *data) 15307 { 15308 mptsas_target_addr_t addr; 15309 mptsas_smp_t *ret_data; 15310 15311 addr.mta_wwn = data->m_addr.mta_wwn; 15312 addr.mta_phymask = data->m_addr.mta_phymask; 15313 ret_data = refhash_lookup(mpt->m_smp_targets, &addr); 15314 /* 15315 * If there's already a matching SMP target, update its fields 15316 * in place. Since the address is not changing, it's safe to do 15317 * this. We cannot just bcopy() here because the structure we've 15318 * been given has invalid hash links. 15319 */ 15320 if (ret_data != NULL) { 15321 mptsas_smp_target_copy(data, ret_data); 15322 return (ret_data); 15323 } 15324 15325 ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP); 15326 bcopy(data, ret_data, sizeof (mptsas_smp_t)); 15327 refhash_insert(mpt->m_smp_targets, ret_data); 15328 return (ret_data); 15329 } 15330 15331 /* 15332 * Functions for SGPIO LED support 15333 */ 15334 static dev_info_t * 15335 mptsas_get_dip_from_dev(dev_t dev, mptsas_phymask_t *phymask) 15336 { 15337 dev_info_t *dip; 15338 int prop; 15339 dip = e_ddi_hold_devi_by_dev(dev, 0); 15340 if (dip == NULL) 15341 return (dip); 15342 prop = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 15343 "phymask", 0); 15344 *phymask = (mptsas_phymask_t)prop; 15345 ddi_release_devi(dip); 15346 return (dip); 15347 } 15348 static mptsas_target_t * 15349 mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask) 15350 { 15351 uint8_t phynum; 15352 uint64_t wwn; 15353 int lun; 15354 mptsas_target_t *ptgt = NULL; 15355 15356 if (mptsas_parse_address(addr, &wwn, &phynum, &lun) != DDI_SUCCESS) { 15357 return (NULL); 15358 } 15359 if (addr[0] == 'w') { 15360 ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn); 15361 } else { 15362 ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum); 15363 } 15364 return (ptgt); 15365 } 15366 15367 static int 15368 mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt) 15369 { 15370 uint32_t slotstatus = 0; 15371 15372 /* Build an MPI2 Slot Status based on our view of the world */ 15373 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_IDENT - 1))) 15374 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST; 15375 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_FAIL - 1))) 15376 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT; 15377 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1))) 15378 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE; 15379 15380 /* Write it to the controller */ 15381 NDBG14(("mptsas_ioctl: set LED status %x for slot %x", 15382 slotstatus, ptgt->m_slot_num)); 15383 return (mptsas_send_sep(mpt, ptgt, &slotstatus, 15384 MPI2_SEP_REQ_ACTION_WRITE_STATUS)); 15385 } 15386 15387 /* 15388 * send sep request, use enclosure/slot addressing 15389 */ 15390 static int 15391 mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt, 15392 uint32_t *status, uint8_t act) 15393 { 15394 Mpi2SepRequest_t req; 15395 Mpi2SepReply_t rep; 15396 int ret; 15397 15398 ASSERT(mutex_owned(&mpt->m_mutex)); 15399 15400 /* 15401 * We only support SEP control of directly-attached targets, in which 15402 * case the "SEP" we're talking to is a virtual one contained within 15403 * the HBA itself. This is necessary because DA targets typically have 15404 * no other mechanism for LED control. Targets for which a separate 15405 * enclosure service processor exists should be controlled via ses(7d) 15406 * or sgen(7d). Furthermore, since such requests can time out, they 15407 * should be made in user context rather than in response to 15408 * asynchronous fabric changes. 15409 * 15410 * In addition, we do not support this operation for RAID volumes, 15411 * since there is no slot associated with them. 15412 */ 15413 if (!(ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) || 15414 ptgt->m_addr.mta_phymask == 0) { 15415 return (ENOTTY); 15416 } 15417 15418 bzero(&req, sizeof (req)); 15419 bzero(&rep, sizeof (rep)); 15420 15421 req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; 15422 req.Action = act; 15423 req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS; 15424 req.EnclosureHandle = LE_16(ptgt->m_enclosure); 15425 req.Slot = LE_16(ptgt->m_slot_num); 15426 if (act == MPI2_SEP_REQ_ACTION_WRITE_STATUS) { 15427 req.SlotStatus = LE_32(*status); 15428 } 15429 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL, 15430 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL); 15431 if (ret != 0) { 15432 mptsas_log(mpt, CE_NOTE, "mptsas_send_sep: passthru SEP " 15433 "Processor Request message error %d", ret); 15434 return (ret); 15435 } 15436 /* do passthrough success, check the ioc status */ 15437 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 15438 mptsas_log(mpt, CE_NOTE, "send_sep act %x: ioc " 15439 "status:%x loginfo %x", act, LE_16(rep.IOCStatus), 15440 LE_32(rep.IOCLogInfo)); 15441 switch (LE_16(rep.IOCStatus) & MPI2_IOCSTATUS_MASK) { 15442 case MPI2_IOCSTATUS_INVALID_FUNCTION: 15443 case MPI2_IOCSTATUS_INVALID_VPID: 15444 case MPI2_IOCSTATUS_INVALID_FIELD: 15445 case MPI2_IOCSTATUS_INVALID_STATE: 15446 case MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED: 15447 case MPI2_IOCSTATUS_CONFIG_INVALID_ACTION: 15448 case MPI2_IOCSTATUS_CONFIG_INVALID_TYPE: 15449 case MPI2_IOCSTATUS_CONFIG_INVALID_PAGE: 15450 case MPI2_IOCSTATUS_CONFIG_INVALID_DATA: 15451 case MPI2_IOCSTATUS_CONFIG_NO_DEFAULTS: 15452 return (EINVAL); 15453 case MPI2_IOCSTATUS_BUSY: 15454 return (EBUSY); 15455 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: 15456 return (EAGAIN); 15457 case MPI2_IOCSTATUS_INVALID_SGL: 15458 case MPI2_IOCSTATUS_INTERNAL_ERROR: 15459 case MPI2_IOCSTATUS_CONFIG_CANT_COMMIT: 15460 default: 15461 return (EIO); 15462 } 15463 } 15464 if (act != MPI2_SEP_REQ_ACTION_WRITE_STATUS) { 15465 *status = LE_32(rep.SlotStatus); 15466 } 15467 15468 return (0); 15469 } 15470 15471 int 15472 mptsas_dma_addr_create(mptsas_t *mpt, ddi_dma_attr_t dma_attr, 15473 ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp, caddr_t *dma_memp, 15474 uint32_t alloc_size, ddi_dma_cookie_t *cookiep) 15475 { 15476 ddi_dma_cookie_t new_cookie; 15477 size_t alloc_len; 15478 uint_t ncookie; 15479 15480 if (cookiep == NULL) 15481 cookiep = &new_cookie; 15482 15483 if (ddi_dma_alloc_handle(mpt->m_dip, &dma_attr, DDI_DMA_SLEEP, 15484 NULL, dma_hdp) != DDI_SUCCESS) { 15485 return (FALSE); 15486 } 15487 15488 if (ddi_dma_mem_alloc(*dma_hdp, alloc_size, &mpt->m_dev_acc_attr, 15489 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, dma_memp, &alloc_len, 15490 acc_hdp) != DDI_SUCCESS) { 15491 ddi_dma_free_handle(dma_hdp); 15492 return (FALSE); 15493 } 15494 15495 if (ddi_dma_addr_bind_handle(*dma_hdp, NULL, *dma_memp, alloc_len, 15496 (DDI_DMA_RDWR | DDI_DMA_CONSISTENT), DDI_DMA_SLEEP, NULL, 15497 cookiep, &ncookie) != DDI_DMA_MAPPED) { 15498 (void) ddi_dma_mem_free(acc_hdp); 15499 ddi_dma_free_handle(dma_hdp); 15500 return (FALSE); 15501 } 15502 15503 return (TRUE); 15504 } 15505 15506 void 15507 mptsas_dma_addr_destroy(ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp) 15508 { 15509 if (*dma_hdp == NULL) 15510 return; 15511 15512 (void) ddi_dma_unbind_handle(*dma_hdp); 15513 (void) ddi_dma_mem_free(acc_hdp); 15514 ddi_dma_free_handle(dma_hdp); 15515 } 15516