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 2012 Nexenta Systems, Inc. All rights reserved. 25 * Copyright (c) 2013, Joyent, Inc. All rights reserved. 26 */ 27 28 /* 29 * Copyright (c) 2000 to 2010, LSI Corporation. 30 * All rights reserved. 31 * 32 * Redistribution and use in source and binary forms of all code within 33 * this file that is exclusively owned by LSI, with or without 34 * modification, is permitted provided that, in addition to the CDDL 1.0 35 * License requirements, the following conditions are met: 36 * 37 * Neither the name of the author nor the names of its contributors may be 38 * used to endorse or promote products derived from this software without 39 * specific prior written permission. 40 * 41 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 42 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 43 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 44 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 45 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 46 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 47 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 48 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 49 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 50 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 51 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 52 * DAMAGE. 53 */ 54 55 /* 56 * mptsas - This is a driver based on LSI Logic's MPT2.0 interface. 57 * 58 */ 59 60 #if defined(lint) || defined(DEBUG) 61 #define MPTSAS_DEBUG 62 #endif 63 64 /* 65 * standard header files. 66 */ 67 #include <sys/note.h> 68 #include <sys/scsi/scsi.h> 69 #include <sys/pci.h> 70 #include <sys/file.h> 71 #include <sys/policy.h> 72 #include <sys/model.h> 73 #include <sys/sysevent.h> 74 #include <sys/sysevent/eventdefs.h> 75 #include <sys/sysevent/dr.h> 76 #include <sys/sata/sata_defs.h> 77 #include <sys/scsi/generic/sas.h> 78 #include <sys/scsi/impl/scsi_sas.h> 79 80 #pragma pack(1) 81 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h> 82 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h> 83 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h> 84 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h> 85 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h> 86 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h> 87 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h> 88 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h> 89 #pragma pack() 90 91 /* 92 * private header files. 93 * 94 */ 95 #include <sys/scsi/impl/scsi_reset_notify.h> 96 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h> 97 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h> 98 #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h> 99 #include <sys/raidioctl.h> 100 101 #include <sys/fs/dv_node.h> /* devfs_clean */ 102 103 /* 104 * FMA header files 105 */ 106 #include <sys/ddifm.h> 107 #include <sys/fm/protocol.h> 108 #include <sys/fm/util.h> 109 #include <sys/fm/io/ddi.h> 110 111 /* 112 * autoconfiguration data and routines. 113 */ 114 static int mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 115 static int mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd); 116 static int mptsas_power(dev_info_t *dip, int component, int level); 117 118 /* 119 * cb_ops function 120 */ 121 static int mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, 122 cred_t *credp, int *rval); 123 #ifdef __sparc 124 static int mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd); 125 #else /* __sparc */ 126 static int mptsas_quiesce(dev_info_t *devi); 127 #endif /* __sparc */ 128 129 /* 130 * Resource initilaization for hardware 131 */ 132 static void mptsas_setup_cmd_reg(mptsas_t *mpt); 133 static void mptsas_disable_bus_master(mptsas_t *mpt); 134 static void mptsas_hba_fini(mptsas_t *mpt); 135 static void mptsas_cfg_fini(mptsas_t *mptsas_blkp); 136 static int mptsas_hba_setup(mptsas_t *mpt); 137 static void mptsas_hba_teardown(mptsas_t *mpt); 138 static int mptsas_config_space_init(mptsas_t *mpt); 139 static void mptsas_config_space_fini(mptsas_t *mpt); 140 static void mptsas_iport_register(mptsas_t *mpt); 141 static int mptsas_smp_setup(mptsas_t *mpt); 142 static void mptsas_smp_teardown(mptsas_t *mpt); 143 static int mptsas_cache_create(mptsas_t *mpt); 144 static void mptsas_cache_destroy(mptsas_t *mpt); 145 static int mptsas_alloc_request_frames(mptsas_t *mpt); 146 static int mptsas_alloc_reply_frames(mptsas_t *mpt); 147 static int mptsas_alloc_free_queue(mptsas_t *mpt); 148 static int mptsas_alloc_post_queue(mptsas_t *mpt); 149 static void mptsas_alloc_reply_args(mptsas_t *mpt); 150 static int mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd); 151 static void mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd); 152 static int mptsas_init_chip(mptsas_t *mpt, int first_time); 153 154 /* 155 * SCSA function prototypes 156 */ 157 static int mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt); 158 static int mptsas_scsi_reset(struct scsi_address *ap, int level); 159 static int mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt); 160 static int mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly); 161 static int mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, 162 int tgtonly); 163 static void mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt); 164 static struct scsi_pkt *mptsas_scsi_init_pkt(struct scsi_address *ap, 165 struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen, 166 int tgtlen, int flags, int (*callback)(), caddr_t arg); 167 static void mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt); 168 static void mptsas_scsi_destroy_pkt(struct scsi_address *ap, 169 struct scsi_pkt *pkt); 170 static int mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 171 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 172 static void mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 173 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 174 static int mptsas_scsi_reset_notify(struct scsi_address *ap, int flag, 175 void (*callback)(caddr_t), caddr_t arg); 176 static int mptsas_get_name(struct scsi_device *sd, char *name, int len); 177 static int mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len); 178 static int mptsas_scsi_quiesce(dev_info_t *dip); 179 static int mptsas_scsi_unquiesce(dev_info_t *dip); 180 static int mptsas_bus_config(dev_info_t *pdip, uint_t flags, 181 ddi_bus_config_op_t op, void *arg, dev_info_t **childp); 182 183 /* 184 * SMP functions 185 */ 186 static int mptsas_smp_start(struct smp_pkt *smp_pkt); 187 188 /* 189 * internal function prototypes. 190 */ 191 static void mptsas_list_add(mptsas_t *mpt); 192 static void mptsas_list_del(mptsas_t *mpt); 193 194 static int mptsas_quiesce_bus(mptsas_t *mpt); 195 static int mptsas_unquiesce_bus(mptsas_t *mpt); 196 197 static int mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size); 198 static void mptsas_free_handshake_msg(mptsas_t *mpt); 199 200 static void mptsas_ncmds_checkdrain(void *arg); 201 202 static int mptsas_prepare_pkt(mptsas_cmd_t *cmd); 203 static int mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *sp); 204 static int mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *sp); 205 static void mptsas_accept_tx_waitq(mptsas_t *mpt); 206 207 static int mptsas_do_detach(dev_info_t *dev); 208 static int mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl); 209 static int mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, 210 struct scsi_pkt *pkt); 211 static int mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp); 212 213 static void mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd); 214 static void mptsas_handle_event(void *args); 215 static int mptsas_handle_event_sync(void *args); 216 static void mptsas_handle_dr(void *args); 217 static void mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node, 218 dev_info_t *pdip); 219 220 static void mptsas_restart_cmd(void *); 221 222 static void mptsas_flush_hba(mptsas_t *mpt); 223 static void mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, 224 uint8_t tasktype); 225 static void mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, 226 uchar_t reason, uint_t stat); 227 228 static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2); 229 static void mptsas_process_intr(mptsas_t *mpt, 230 pMpi2ReplyDescriptorsUnion_t reply_desc_union); 231 static void mptsas_handle_scsi_io_success(mptsas_t *mpt, 232 pMpi2ReplyDescriptorsUnion_t reply_desc); 233 static void mptsas_handle_address_reply(mptsas_t *mpt, 234 pMpi2ReplyDescriptorsUnion_t reply_desc); 235 static int mptsas_wait_intr(mptsas_t *mpt, int polltime); 236 static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, 237 uint32_t *control, pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl); 238 239 static void mptsas_watch(void *arg); 240 static void mptsas_watchsubr(mptsas_t *mpt); 241 static void mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl); 242 243 static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd); 244 static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply, 245 uint8_t *data, uint32_t request_size, uint32_t reply_size, 246 uint32_t data_size, uint32_t direction, uint8_t *dataout, 247 uint32_t dataout_size, short timeout, int mode); 248 static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl); 249 250 static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, 251 uint32_t unique_id); 252 static void mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd); 253 static int mptsas_post_fw_diag_buffer(mptsas_t *mpt, 254 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code); 255 static int mptsas_release_fw_diag_buffer(mptsas_t *mpt, 256 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code, 257 uint32_t diag_type); 258 static int mptsas_diag_register(mptsas_t *mpt, 259 mptsas_fw_diag_register_t *diag_register, uint32_t *return_code); 260 static int mptsas_diag_unregister(mptsas_t *mpt, 261 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code); 262 static int mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query, 263 uint32_t *return_code); 264 static int mptsas_diag_read_buffer(mptsas_t *mpt, 265 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf, 266 uint32_t *return_code, int ioctl_mode); 267 static int mptsas_diag_release(mptsas_t *mpt, 268 mptsas_fw_diag_release_t *diag_release, uint32_t *return_code); 269 static int mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, 270 uint8_t *diag_action, uint32_t length, uint32_t *return_code, 271 int ioctl_mode); 272 static int mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *data, 273 int mode); 274 275 static int mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd, 276 int cmdlen, int tgtlen, int statuslen, int kf); 277 static void mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd); 278 279 static int mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags); 280 static void mptsas_kmem_cache_destructor(void *buf, void *cdrarg); 281 282 static int mptsas_cache_frames_constructor(void *buf, void *cdrarg, 283 int kmflags); 284 static void mptsas_cache_frames_destructor(void *buf, void *cdrarg); 285 286 static void mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, 287 mptsas_cmd_t *cmd); 288 static void mptsas_check_task_mgt(mptsas_t *mpt, 289 pMpi2SCSIManagementReply_t reply, mptsas_cmd_t *cmd); 290 static int mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap, 291 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp, 292 int *resid); 293 294 static int mptsas_alloc_active_slots(mptsas_t *mpt, int flag); 295 static void mptsas_free_active_slots(mptsas_t *mpt); 296 static int mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd); 297 298 static void mptsas_restart_hba(mptsas_t *mpt); 299 static void mptsas_restart_waitq(mptsas_t *mpt); 300 301 static void mptsas_deliver_doneq_thread(mptsas_t *mpt); 302 static void mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd); 303 static void mptsas_doneq_mv(mptsas_t *mpt, uint64_t t); 304 305 static mptsas_cmd_t *mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t); 306 static void mptsas_doneq_empty(mptsas_t *mpt); 307 static void mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg); 308 309 static mptsas_cmd_t *mptsas_waitq_rm(mptsas_t *mpt); 310 static void mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd); 311 static mptsas_cmd_t *mptsas_tx_waitq_rm(mptsas_t *mpt); 312 static void mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd); 313 314 315 static void mptsas_start_watch_reset_delay(); 316 static void mptsas_setup_bus_reset_delay(mptsas_t *mpt); 317 static void mptsas_watch_reset_delay(void *arg); 318 static int mptsas_watch_reset_delay_subr(mptsas_t *mpt); 319 320 /* 321 * helper functions 322 */ 323 static void mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd); 324 325 static dev_info_t *mptsas_find_child(dev_info_t *pdip, char *name); 326 static dev_info_t *mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy); 327 static dev_info_t *mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, 328 int lun); 329 static mdi_pathinfo_t *mptsas_find_path_addr(dev_info_t *pdip, uint64_t sasaddr, 330 int lun); 331 static mdi_pathinfo_t *mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy); 332 static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn); 333 334 static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, 335 int *lun); 336 static int mptsas_parse_smp_name(char *name, uint64_t *wwn); 337 338 static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt, int phymask, 339 uint8_t phy); 340 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask, 341 uint64_t wwid); 342 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask, 343 uint64_t wwid); 344 345 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, 346 uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd); 347 348 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address, 349 uint16_t *handle, mptsas_target_t **pptgt); 350 static void mptsas_update_phymask(mptsas_t *mpt); 351 352 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt, 353 uint32_t *status, uint8_t cmd); 354 static dev_info_t *mptsas_get_dip_from_dev(dev_t dev, 355 mptsas_phymask_t *phymask); 356 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, 357 mptsas_phymask_t phymask); 358 static int mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt); 359 360 361 /* 362 * Enumeration / DR functions 363 */ 364 static void mptsas_config_all(dev_info_t *pdip); 365 static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun, 366 dev_info_t **lundip); 367 static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun, 368 dev_info_t **lundip); 369 370 static int mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt); 371 static int mptsas_offline_target(dev_info_t *pdip, char *name); 372 373 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target, 374 dev_info_t **dip); 375 376 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt); 377 static int mptsas_probe_lun(dev_info_t *pdip, int lun, 378 dev_info_t **dip, mptsas_target_t *ptgt); 379 380 static int mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq, 381 dev_info_t **dip, mptsas_target_t *ptgt, int lun); 382 383 static int mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *sd, 384 char *guid, dev_info_t **dip, mptsas_target_t *ptgt, int lun); 385 static int mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *sd, 386 char *guid, dev_info_t **dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, 387 int lun); 388 389 static void mptsas_offline_missed_luns(dev_info_t *pdip, 390 uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt); 391 static int mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip, 392 mdi_pathinfo_t *rpip, uint_t flags); 393 394 static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, 395 dev_info_t **smp_dip); 396 static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 397 uint_t flags); 398 399 static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, 400 int mode, int *rval); 401 static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, 402 int mode, int *rval); 403 static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, 404 int mode, int *rval); 405 static void mptsas_record_event(void *args); 406 static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, 407 int mode); 408 409 static void mptsas_hash_init(mptsas_hash_table_t *hashtab); 410 static void mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen); 411 static void mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data); 412 static void * mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1, 413 mptsas_phymask_t key2); 414 static void * mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1, 415 mptsas_phymask_t key2); 416 static void * mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos); 417 418 mptsas_target_t *mptsas_tgt_alloc(mptsas_hash_table_t *, uint16_t, uint64_t, 419 uint32_t, mptsas_phymask_t, uint8_t); 420 static mptsas_smp_t *mptsas_smp_alloc(mptsas_hash_table_t *hashtab, 421 mptsas_smp_t *data); 422 static void mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid, 423 mptsas_phymask_t phymask); 424 static void mptsas_tgt_free(mptsas_hash_table_t *, uint64_t, mptsas_phymask_t); 425 static void * mptsas_search_by_devhdl(mptsas_hash_table_t *, uint16_t); 426 static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 427 dev_info_t **smp_dip); 428 429 /* 430 * Power management functions 431 */ 432 static int mptsas_get_pci_cap(mptsas_t *mpt); 433 static int mptsas_init_pm(mptsas_t *mpt); 434 435 /* 436 * MPT MSI tunable: 437 * 438 * By default MSI is enabled on all supported platforms. 439 */ 440 boolean_t mptsas_enable_msi = B_TRUE; 441 boolean_t mptsas_physical_bind_failed_page_83 = B_FALSE; 442 443 static int mptsas_register_intrs(mptsas_t *); 444 static void mptsas_unregister_intrs(mptsas_t *); 445 static int mptsas_add_intrs(mptsas_t *, int); 446 static void mptsas_rem_intrs(mptsas_t *); 447 448 /* 449 * FMA Prototypes 450 */ 451 static void mptsas_fm_init(mptsas_t *mpt); 452 static void mptsas_fm_fini(mptsas_t *mpt); 453 static int mptsas_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *); 454 455 extern pri_t minclsyspri, maxclsyspri; 456 457 /* 458 * This device is created by the SCSI pseudo nexus driver (SCSI vHCI). It is 459 * under this device that the paths to a physical device are created when 460 * MPxIO is used. 461 */ 462 extern dev_info_t *scsi_vhci_dip; 463 464 /* 465 * Tunable timeout value for Inquiry VPD page 0x83 466 * By default the value is 30 seconds. 467 */ 468 int mptsas_inq83_retry_timeout = 30; 469 470 /* 471 * This is used to allocate memory for message frame storage, not for 472 * data I/O DMA. All message frames must be stored in the first 4G of 473 * physical memory. 474 */ 475 ddi_dma_attr_t mptsas_dma_attrs = { 476 DMA_ATTR_V0, /* attribute layout version */ 477 0x0ull, /* address low - should be 0 (longlong) */ 478 0xffffffffull, /* address high - 32-bit max range */ 479 0x00ffffffull, /* count max - max DMA object size */ 480 4, /* allocation alignment requirements */ 481 0x78, /* burstsizes - binary encoded values */ 482 1, /* minxfer - gran. of DMA engine */ 483 0x00ffffffull, /* maxxfer - gran. of DMA engine */ 484 0xffffffffull, /* max segment size (DMA boundary) */ 485 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */ 486 512, /* granularity - device transfer size */ 487 0 /* flags, set to 0 */ 488 }; 489 490 /* 491 * This is used for data I/O DMA memory allocation. (full 64-bit DMA 492 * physical addresses are supported.) 493 */ 494 ddi_dma_attr_t mptsas_dma_attrs64 = { 495 DMA_ATTR_V0, /* attribute layout version */ 496 0x0ull, /* address low - should be 0 (longlong) */ 497 0xffffffffffffffffull, /* address high - 64-bit max */ 498 0x00ffffffull, /* count max - max DMA object size */ 499 4, /* allocation alignment requirements */ 500 0x78, /* burstsizes - binary encoded values */ 501 1, /* minxfer - gran. of DMA engine */ 502 0x00ffffffull, /* maxxfer - gran. of DMA engine */ 503 0xffffffffull, /* max segment size (DMA boundary) */ 504 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */ 505 512, /* granularity - device transfer size */ 506 DDI_DMA_RELAXED_ORDERING /* flags, enable relaxed ordering */ 507 }; 508 509 ddi_device_acc_attr_t mptsas_dev_attr = { 510 DDI_DEVICE_ATTR_V1, 511 DDI_STRUCTURE_LE_ACC, 512 DDI_STRICTORDER_ACC, 513 DDI_DEFAULT_ACC 514 }; 515 516 static struct cb_ops mptsas_cb_ops = { 517 scsi_hba_open, /* open */ 518 scsi_hba_close, /* close */ 519 nodev, /* strategy */ 520 nodev, /* print */ 521 nodev, /* dump */ 522 nodev, /* read */ 523 nodev, /* write */ 524 mptsas_ioctl, /* ioctl */ 525 nodev, /* devmap */ 526 nodev, /* mmap */ 527 nodev, /* segmap */ 528 nochpoll, /* chpoll */ 529 ddi_prop_op, /* cb_prop_op */ 530 NULL, /* streamtab */ 531 D_MP, /* cb_flag */ 532 CB_REV, /* rev */ 533 nodev, /* aread */ 534 nodev /* awrite */ 535 }; 536 537 static struct dev_ops mptsas_ops = { 538 DEVO_REV, /* devo_rev, */ 539 0, /* refcnt */ 540 ddi_no_info, /* info */ 541 nulldev, /* identify */ 542 nulldev, /* probe */ 543 mptsas_attach, /* attach */ 544 mptsas_detach, /* detach */ 545 #ifdef __sparc 546 mptsas_reset, 547 #else 548 nodev, /* reset */ 549 #endif /* __sparc */ 550 &mptsas_cb_ops, /* driver operations */ 551 NULL, /* bus operations */ 552 mptsas_power, /* power management */ 553 #ifdef __sparc 554 ddi_quiesce_not_needed 555 #else 556 mptsas_quiesce /* quiesce */ 557 #endif /* __sparc */ 558 }; 559 560 561 #define MPTSAS_MOD_STRING "MPTSAS HBA Driver 00.00.00.24" 562 563 static struct modldrv modldrv = { 564 &mod_driverops, /* Type of module. This one is a driver */ 565 MPTSAS_MOD_STRING, /* Name of the module. */ 566 &mptsas_ops, /* driver ops */ 567 }; 568 569 static struct modlinkage modlinkage = { 570 MODREV_1, &modldrv, NULL 571 }; 572 #define TARGET_PROP "target" 573 #define LUN_PROP "lun" 574 #define LUN64_PROP "lun64" 575 #define SAS_PROP "sas-mpt" 576 #define MDI_GUID "wwn" 577 #define NDI_GUID "guid" 578 #define MPTSAS_DEV_GONE "mptsas_dev_gone" 579 580 /* 581 * Local static data 582 */ 583 #if defined(MPTSAS_DEBUG) 584 uint32_t mptsas_debug_flags = 0; 585 #endif /* defined(MPTSAS_DEBUG) */ 586 uint32_t mptsas_debug_resets = 0; 587 588 static kmutex_t mptsas_global_mutex; 589 static void *mptsas_state; /* soft state ptr */ 590 static krwlock_t mptsas_global_rwlock; 591 592 static kmutex_t mptsas_log_mutex; 593 static char mptsas_log_buf[256]; 594 _NOTE(MUTEX_PROTECTS_DATA(mptsas_log_mutex, mptsas_log_buf)) 595 596 static mptsas_t *mptsas_head, *mptsas_tail; 597 static clock_t mptsas_scsi_watchdog_tick; 598 static clock_t mptsas_tick; 599 static timeout_id_t mptsas_reset_watch; 600 static timeout_id_t mptsas_timeout_id; 601 static int mptsas_timeouts_enabled = 0; 602 /* 603 * warlock directives 604 */ 605 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt \ 606 mptsas_cmd NcrTableIndirect buf scsi_cdb scsi_status)) 607 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", smp_pkt)) 608 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address)) 609 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", mptsas_tgt_private)) 610 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_hba_tran::tran_tgt_private)) 611 612 /* 613 * SM - HBA statics 614 */ 615 char *mptsas_driver_rev = MPTSAS_MOD_STRING; 616 617 #ifdef MPTSAS_DEBUG 618 void debug_enter(char *); 619 #endif 620 621 /* 622 * Notes: 623 * - scsi_hba_init(9F) initializes SCSI HBA modules 624 * - must call scsi_hba_fini(9F) if modload() fails 625 */ 626 int 627 _init(void) 628 { 629 int status; 630 /* CONSTCOND */ 631 ASSERT(NO_COMPETING_THREADS); 632 633 NDBG0(("_init")); 634 635 status = ddi_soft_state_init(&mptsas_state, MPTSAS_SIZE, 636 MPTSAS_INITIAL_SOFT_SPACE); 637 if (status != 0) { 638 return (status); 639 } 640 641 if ((status = scsi_hba_init(&modlinkage)) != 0) { 642 ddi_soft_state_fini(&mptsas_state); 643 return (status); 644 } 645 646 mutex_init(&mptsas_global_mutex, NULL, MUTEX_DRIVER, NULL); 647 rw_init(&mptsas_global_rwlock, NULL, RW_DRIVER, NULL); 648 mutex_init(&mptsas_log_mutex, NULL, MUTEX_DRIVER, NULL); 649 650 if ((status = mod_install(&modlinkage)) != 0) { 651 mutex_destroy(&mptsas_log_mutex); 652 rw_destroy(&mptsas_global_rwlock); 653 mutex_destroy(&mptsas_global_mutex); 654 ddi_soft_state_fini(&mptsas_state); 655 scsi_hba_fini(&modlinkage); 656 } 657 658 return (status); 659 } 660 661 /* 662 * Notes: 663 * - scsi_hba_fini(9F) uninitializes SCSI HBA modules 664 */ 665 int 666 _fini(void) 667 { 668 int status; 669 /* CONSTCOND */ 670 ASSERT(NO_COMPETING_THREADS); 671 672 NDBG0(("_fini")); 673 674 if ((status = mod_remove(&modlinkage)) == 0) { 675 ddi_soft_state_fini(&mptsas_state); 676 scsi_hba_fini(&modlinkage); 677 mutex_destroy(&mptsas_global_mutex); 678 rw_destroy(&mptsas_global_rwlock); 679 mutex_destroy(&mptsas_log_mutex); 680 } 681 return (status); 682 } 683 684 /* 685 * The loadable-module _info(9E) entry point 686 */ 687 int 688 _info(struct modinfo *modinfop) 689 { 690 /* CONSTCOND */ 691 ASSERT(NO_COMPETING_THREADS); 692 NDBG0(("mptsas _info")); 693 694 return (mod_info(&modlinkage, modinfop)); 695 } 696 697 698 static int 699 mptsas_iport_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 700 { 701 dev_info_t *pdip; 702 mptsas_t *mpt; 703 scsi_hba_tran_t *hba_tran; 704 char *iport = NULL; 705 char phymask[MPTSAS_MAX_PHYS]; 706 mptsas_phymask_t phy_mask = 0; 707 int dynamic_port = 0; 708 uint32_t page_address; 709 char initiator_wwnstr[MPTSAS_WWN_STRLEN]; 710 int rval = DDI_FAILURE; 711 int i = 0; 712 uint8_t numphys = 0; 713 uint8_t phy_id; 714 uint8_t phy_port = 0; 715 uint16_t attached_devhdl = 0; 716 uint32_t dev_info; 717 uint64_t attached_sas_wwn; 718 uint16_t dev_hdl; 719 uint16_t pdev_hdl; 720 uint16_t bay_num, enclosure; 721 char attached_wwnstr[MPTSAS_WWN_STRLEN]; 722 723 /* CONSTCOND */ 724 ASSERT(NO_COMPETING_THREADS); 725 726 switch (cmd) { 727 case DDI_ATTACH: 728 break; 729 730 case DDI_RESUME: 731 /* 732 * If this a scsi-iport node, nothing to do here. 733 */ 734 return (DDI_SUCCESS); 735 736 default: 737 return (DDI_FAILURE); 738 } 739 740 pdip = ddi_get_parent(dip); 741 742 if ((hba_tran = ndi_flavorv_get(pdip, SCSA_FLAVOR_SCSI_DEVICE)) == 743 NULL) { 744 cmn_err(CE_WARN, "Failed attach iport because fail to " 745 "get tran vector for the HBA node"); 746 return (DDI_FAILURE); 747 } 748 749 mpt = TRAN2MPT(hba_tran); 750 ASSERT(mpt != NULL); 751 if (mpt == NULL) 752 return (DDI_FAILURE); 753 754 if ((hba_tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == 755 NULL) { 756 mptsas_log(mpt, CE_WARN, "Failed attach iport because fail to " 757 "get tran vector for the iport node"); 758 return (DDI_FAILURE); 759 } 760 761 /* 762 * Overwrite parent's tran_hba_private to iport's tran vector 763 */ 764 hba_tran->tran_hba_private = mpt; 765 766 ddi_report_dev(dip); 767 768 /* 769 * Get SAS address for initiator port according dev_handle 770 */ 771 iport = ddi_get_name_addr(dip); 772 if (iport && strncmp(iport, "v0", 2) == 0) { 773 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 774 MPTSAS_VIRTUAL_PORT, 1) != 775 DDI_PROP_SUCCESS) { 776 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, 777 MPTSAS_VIRTUAL_PORT); 778 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 779 "prop update failed"); 780 return (DDI_FAILURE); 781 } 782 return (DDI_SUCCESS); 783 } 784 785 mutex_enter(&mpt->m_mutex); 786 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 787 bzero(phymask, sizeof (phymask)); 788 (void) sprintf(phymask, 789 "%x", mpt->m_phy_info[i].phy_mask); 790 if (strcmp(phymask, iport) == 0) { 791 break; 792 } 793 } 794 795 if (i == MPTSAS_MAX_PHYS) { 796 mptsas_log(mpt, CE_WARN, "Failed attach port %s because port" 797 "seems not exist", iport); 798 mutex_exit(&mpt->m_mutex); 799 return (DDI_FAILURE); 800 } 801 802 phy_mask = mpt->m_phy_info[i].phy_mask; 803 804 if (mpt->m_phy_info[i].port_flags & AUTO_PORT_CONFIGURATION) 805 dynamic_port = 1; 806 else 807 dynamic_port = 0; 808 809 /* 810 * Update PHY info for smhba 811 */ 812 if (mptsas_smhba_phy_init(mpt)) { 813 mutex_exit(&mpt->m_mutex); 814 mptsas_log(mpt, CE_WARN, "mptsas phy update " 815 "failed"); 816 return (DDI_FAILURE); 817 } 818 819 mutex_exit(&mpt->m_mutex); 820 821 numphys = 0; 822 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 823 if ((phy_mask >> i) & 0x01) { 824 numphys++; 825 } 826 } 827 828 bzero(initiator_wwnstr, sizeof (initiator_wwnstr)); 829 (void) sprintf(initiator_wwnstr, "w%016"PRIx64, 830 mpt->un.m_base_wwid); 831 832 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, 833 SCSI_ADDR_PROP_INITIATOR_PORT, initiator_wwnstr) != 834 DDI_PROP_SUCCESS) { 835 (void) ddi_prop_remove(DDI_DEV_T_NONE, 836 dip, SCSI_ADDR_PROP_INITIATOR_PORT); 837 mptsas_log(mpt, CE_WARN, "mptsas Initiator port " 838 "prop update failed"); 839 return (DDI_FAILURE); 840 } 841 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 842 MPTSAS_NUM_PHYS, numphys) != 843 DDI_PROP_SUCCESS) { 844 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, MPTSAS_NUM_PHYS); 845 return (DDI_FAILURE); 846 } 847 848 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 849 "phymask", phy_mask) != 850 DDI_PROP_SUCCESS) { 851 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "phymask"); 852 mptsas_log(mpt, CE_WARN, "mptsas phy mask " 853 "prop update failed"); 854 return (DDI_FAILURE); 855 } 856 857 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 858 "dynamic-port", dynamic_port) != 859 DDI_PROP_SUCCESS) { 860 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "dynamic-port"); 861 mptsas_log(mpt, CE_WARN, "mptsas dynamic port " 862 "prop update failed"); 863 return (DDI_FAILURE); 864 } 865 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 866 MPTSAS_VIRTUAL_PORT, 0) != 867 DDI_PROP_SUCCESS) { 868 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, 869 MPTSAS_VIRTUAL_PORT); 870 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 871 "prop update failed"); 872 return (DDI_FAILURE); 873 } 874 mptsas_smhba_set_all_phy_props(mpt, dip, numphys, phy_mask, 875 &attached_devhdl); 876 877 mutex_enter(&mpt->m_mutex); 878 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 879 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)attached_devhdl; 880 rval = mptsas_get_sas_device_page0(mpt, page_address, &dev_hdl, 881 &attached_sas_wwn, &dev_info, &phy_port, &phy_id, 882 &pdev_hdl, &bay_num, &enclosure); 883 if (rval != DDI_SUCCESS) { 884 mptsas_log(mpt, CE_WARN, 885 "Failed to get device page0 for handle:%d", 886 attached_devhdl); 887 mutex_exit(&mpt->m_mutex); 888 return (DDI_FAILURE); 889 } 890 891 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 892 bzero(phymask, sizeof (phymask)); 893 (void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask); 894 if (strcmp(phymask, iport) == 0) { 895 (void) sprintf(&mpt->m_phy_info[i].smhba_info.path[0], 896 "%x", 897 mpt->m_phy_info[i].phy_mask); 898 } 899 } 900 mutex_exit(&mpt->m_mutex); 901 902 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 903 (void) sprintf(attached_wwnstr, "w%016"PRIx64, 904 attached_sas_wwn); 905 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, 906 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 907 DDI_PROP_SUCCESS) { 908 (void) ddi_prop_remove(DDI_DEV_T_NONE, 909 dip, SCSI_ADDR_PROP_ATTACHED_PORT); 910 return (DDI_FAILURE); 911 } 912 913 /* Create kstats for each phy on this iport */ 914 915 mptsas_create_phy_stats(mpt, iport, dip); 916 917 /* 918 * register sas hba iport with mdi (MPxIO/vhci) 919 */ 920 if (mdi_phci_register(MDI_HCI_CLASS_SCSI, 921 dip, 0) == MDI_SUCCESS) { 922 mpt->m_mpxio_enable = TRUE; 923 } 924 return (DDI_SUCCESS); 925 } 926 927 /* 928 * Notes: 929 * Set up all device state and allocate data structures, 930 * mutexes, condition variables, etc. for device operation. 931 * Add interrupts needed. 932 * Return DDI_SUCCESS if device is ready, else return DDI_FAILURE. 933 */ 934 static int 935 mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 936 { 937 mptsas_t *mpt = NULL; 938 int instance, i, j; 939 int doneq_thread_num; 940 char intr_added = 0; 941 char map_setup = 0; 942 char config_setup = 0; 943 char hba_attach_setup = 0; 944 char smp_attach_setup = 0; 945 char mutex_init_done = 0; 946 char event_taskq_create = 0; 947 char dr_taskq_create = 0; 948 char doneq_thread_create = 0; 949 scsi_hba_tran_t *hba_tran; 950 uint_t mem_bar = MEM_SPACE; 951 int rval = DDI_FAILURE; 952 953 /* CONSTCOND */ 954 ASSERT(NO_COMPETING_THREADS); 955 956 if (scsi_hba_iport_unit_address(dip)) { 957 return (mptsas_iport_attach(dip, cmd)); 958 } 959 960 switch (cmd) { 961 case DDI_ATTACH: 962 break; 963 964 case DDI_RESUME: 965 if ((hba_tran = ddi_get_driver_private(dip)) == NULL) 966 return (DDI_FAILURE); 967 968 mpt = TRAN2MPT(hba_tran); 969 970 if (!mpt) { 971 return (DDI_FAILURE); 972 } 973 974 /* 975 * Reset hardware and softc to "no outstanding commands" 976 * Note that a check condition can result on first command 977 * to a target. 978 */ 979 mutex_enter(&mpt->m_mutex); 980 981 /* 982 * raise power. 983 */ 984 if (mpt->m_options & MPTSAS_OPT_PM) { 985 mutex_exit(&mpt->m_mutex); 986 (void) pm_busy_component(dip, 0); 987 rval = pm_power_has_changed(dip, 0, PM_LEVEL_D0); 988 if (rval == DDI_SUCCESS) { 989 mutex_enter(&mpt->m_mutex); 990 } else { 991 /* 992 * The pm_raise_power() call above failed, 993 * and that can only occur if we were unable 994 * to reset the hardware. This is probably 995 * due to unhealty hardware, and because 996 * important filesystems(such as the root 997 * filesystem) could be on the attached disks, 998 * it would not be a good idea to continue, 999 * as we won't be entirely certain we are 1000 * writing correct data. So we panic() here 1001 * to not only prevent possible data corruption, 1002 * but to give developers or end users a hope 1003 * of identifying and correcting any problems. 1004 */ 1005 fm_panic("mptsas could not reset hardware " 1006 "during resume"); 1007 } 1008 } 1009 1010 mpt->m_suspended = 0; 1011 1012 /* 1013 * Reinitialize ioc 1014 */ 1015 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1016 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) { 1017 mutex_exit(&mpt->m_mutex); 1018 if (mpt->m_options & MPTSAS_OPT_PM) { 1019 (void) pm_idle_component(dip, 0); 1020 } 1021 fm_panic("mptsas init chip fail during resume"); 1022 } 1023 /* 1024 * mptsas_update_driver_data needs interrupts so enable them 1025 * first. 1026 */ 1027 MPTSAS_ENABLE_INTR(mpt); 1028 mptsas_update_driver_data(mpt); 1029 1030 /* start requests, if possible */ 1031 mptsas_restart_hba(mpt); 1032 1033 mutex_exit(&mpt->m_mutex); 1034 1035 /* 1036 * Restart watch thread 1037 */ 1038 mutex_enter(&mptsas_global_mutex); 1039 if (mptsas_timeout_id == 0) { 1040 mptsas_timeout_id = timeout(mptsas_watch, NULL, 1041 mptsas_tick); 1042 mptsas_timeouts_enabled = 1; 1043 } 1044 mutex_exit(&mptsas_global_mutex); 1045 1046 /* report idle status to pm framework */ 1047 if (mpt->m_options & MPTSAS_OPT_PM) { 1048 (void) pm_idle_component(dip, 0); 1049 } 1050 1051 return (DDI_SUCCESS); 1052 1053 default: 1054 return (DDI_FAILURE); 1055 1056 } 1057 1058 instance = ddi_get_instance(dip); 1059 1060 /* 1061 * Allocate softc information. 1062 */ 1063 if (ddi_soft_state_zalloc(mptsas_state, instance) != DDI_SUCCESS) { 1064 mptsas_log(NULL, CE_WARN, 1065 "mptsas%d: cannot allocate soft state", instance); 1066 goto fail; 1067 } 1068 1069 mpt = ddi_get_soft_state(mptsas_state, instance); 1070 1071 if (mpt == NULL) { 1072 mptsas_log(NULL, CE_WARN, 1073 "mptsas%d: cannot get soft state", instance); 1074 goto fail; 1075 } 1076 1077 /* Indicate that we are 'sizeof (scsi_*(9S))' clean. */ 1078 scsi_size_clean(dip); 1079 1080 mpt->m_dip = dip; 1081 mpt->m_instance = instance; 1082 1083 /* Make a per-instance copy of the structures */ 1084 mpt->m_io_dma_attr = mptsas_dma_attrs64; 1085 mpt->m_msg_dma_attr = mptsas_dma_attrs; 1086 mpt->m_reg_acc_attr = mptsas_dev_attr; 1087 mpt->m_dev_acc_attr = mptsas_dev_attr; 1088 1089 /* 1090 * Initialize FMA 1091 */ 1092 mpt->m_fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, mpt->m_dip, 1093 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable", 1094 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE | 1095 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE); 1096 1097 mptsas_fm_init(mpt); 1098 1099 if (mptsas_alloc_handshake_msg(mpt, 1100 sizeof (Mpi2SCSITaskManagementRequest_t)) == DDI_FAILURE) { 1101 mptsas_log(mpt, CE_WARN, "cannot initialize handshake msg."); 1102 goto fail; 1103 } 1104 1105 /* 1106 * Setup configuration space 1107 */ 1108 if (mptsas_config_space_init(mpt) == FALSE) { 1109 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init failed"); 1110 goto fail; 1111 } 1112 config_setup++; 1113 1114 if (ddi_regs_map_setup(dip, mem_bar, (caddr_t *)&mpt->m_reg, 1115 0, 0, &mpt->m_reg_acc_attr, &mpt->m_datap) != DDI_SUCCESS) { 1116 mptsas_log(mpt, CE_WARN, "map setup failed"); 1117 goto fail; 1118 } 1119 map_setup++; 1120 1121 /* 1122 * A taskq is created for dealing with the event handler 1123 */ 1124 if ((mpt->m_event_taskq = ddi_taskq_create(dip, "mptsas_event_taskq", 1125 1, TASKQ_DEFAULTPRI, 0)) == NULL) { 1126 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create failed"); 1127 goto fail; 1128 } 1129 event_taskq_create++; 1130 1131 /* 1132 * A taskq is created for dealing with dr events 1133 */ 1134 if ((mpt->m_dr_taskq = ddi_taskq_create(dip, 1135 "mptsas_dr_taskq", 1136 1, TASKQ_DEFAULTPRI, 0)) == NULL) { 1137 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create for discovery " 1138 "failed"); 1139 goto fail; 1140 } 1141 dr_taskq_create++; 1142 1143 mpt->m_doneq_thread_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1144 0, "mptsas_doneq_thread_threshold_prop", 10); 1145 mpt->m_doneq_length_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1146 0, "mptsas_doneq_length_threshold_prop", 8); 1147 mpt->m_doneq_thread_n = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1148 0, "mptsas_doneq_thread_n_prop", 8); 1149 1150 if (mpt->m_doneq_thread_n) { 1151 cv_init(&mpt->m_doneq_thread_cv, NULL, CV_DRIVER, NULL); 1152 mutex_init(&mpt->m_doneq_mutex, NULL, MUTEX_DRIVER, NULL); 1153 1154 mutex_enter(&mpt->m_doneq_mutex); 1155 mpt->m_doneq_thread_id = 1156 kmem_zalloc(sizeof (mptsas_doneq_thread_list_t) 1157 * mpt->m_doneq_thread_n, KM_SLEEP); 1158 1159 for (j = 0; j < mpt->m_doneq_thread_n; j++) { 1160 cv_init(&mpt->m_doneq_thread_id[j].cv, NULL, 1161 CV_DRIVER, NULL); 1162 mutex_init(&mpt->m_doneq_thread_id[j].mutex, NULL, 1163 MUTEX_DRIVER, NULL); 1164 mutex_enter(&mpt->m_doneq_thread_id[j].mutex); 1165 mpt->m_doneq_thread_id[j].flag |= 1166 MPTSAS_DONEQ_THREAD_ACTIVE; 1167 mpt->m_doneq_thread_id[j].arg.mpt = mpt; 1168 mpt->m_doneq_thread_id[j].arg.t = j; 1169 mpt->m_doneq_thread_id[j].threadp = 1170 thread_create(NULL, 0, mptsas_doneq_thread, 1171 &mpt->m_doneq_thread_id[j].arg, 1172 0, &p0, TS_RUN, minclsyspri); 1173 mpt->m_doneq_thread_id[j].donetail = 1174 &mpt->m_doneq_thread_id[j].doneq; 1175 mutex_exit(&mpt->m_doneq_thread_id[j].mutex); 1176 } 1177 mutex_exit(&mpt->m_doneq_mutex); 1178 doneq_thread_create++; 1179 } 1180 1181 /* Initialize mutex used in interrupt handler */ 1182 mutex_init(&mpt->m_mutex, NULL, MUTEX_DRIVER, 1183 DDI_INTR_PRI(mpt->m_intr_pri)); 1184 mutex_init(&mpt->m_passthru_mutex, NULL, MUTEX_DRIVER, NULL); 1185 mutex_init(&mpt->m_tx_waitq_mutex, NULL, MUTEX_DRIVER, 1186 DDI_INTR_PRI(mpt->m_intr_pri)); 1187 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1188 mutex_init(&mpt->m_phy_info[i].smhba_info.phy_mutex, 1189 NULL, MUTEX_DRIVER, 1190 DDI_INTR_PRI(mpt->m_intr_pri)); 1191 } 1192 1193 cv_init(&mpt->m_cv, NULL, CV_DRIVER, NULL); 1194 cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL); 1195 cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL); 1196 cv_init(&mpt->m_config_cv, NULL, CV_DRIVER, NULL); 1197 cv_init(&mpt->m_fw_diag_cv, NULL, CV_DRIVER, NULL); 1198 mutex_init_done++; 1199 1200 /* 1201 * Disable hardware interrupt since we're not ready to 1202 * handle it yet. 1203 */ 1204 MPTSAS_DISABLE_INTR(mpt); 1205 if (mptsas_register_intrs(mpt) == FALSE) 1206 goto fail; 1207 intr_added++; 1208 1209 mutex_enter(&mpt->m_mutex); 1210 /* 1211 * Initialize power management component 1212 */ 1213 if (mpt->m_options & MPTSAS_OPT_PM) { 1214 if (mptsas_init_pm(mpt)) { 1215 mutex_exit(&mpt->m_mutex); 1216 mptsas_log(mpt, CE_WARN, "mptsas pm initialization " 1217 "failed"); 1218 goto fail; 1219 } 1220 } 1221 1222 /* 1223 * Initialize chip using Message Unit Reset, if allowed 1224 */ 1225 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1226 if (mptsas_init_chip(mpt, TRUE) == DDI_FAILURE) { 1227 mutex_exit(&mpt->m_mutex); 1228 mptsas_log(mpt, CE_WARN, "mptsas chip initialization failed"); 1229 goto fail; 1230 } 1231 1232 /* 1233 * Fill in the phy_info structure and get the base WWID 1234 */ 1235 if (mptsas_get_manufacture_page5(mpt) == DDI_FAILURE) { 1236 mptsas_log(mpt, CE_WARN, 1237 "mptsas_get_manufacture_page5 failed!"); 1238 goto fail; 1239 } 1240 1241 if (mptsas_get_sas_io_unit_page_hndshk(mpt)) { 1242 mptsas_log(mpt, CE_WARN, 1243 "mptsas_get_sas_io_unit_page_hndshk failed!"); 1244 goto fail; 1245 } 1246 1247 if (mptsas_get_manufacture_page0(mpt) == DDI_FAILURE) { 1248 mptsas_log(mpt, CE_WARN, 1249 "mptsas_get_manufacture_page0 failed!"); 1250 goto fail; 1251 } 1252 1253 mutex_exit(&mpt->m_mutex); 1254 1255 /* 1256 * Register the iport for multiple port HBA 1257 */ 1258 mptsas_iport_register(mpt); 1259 1260 /* 1261 * initialize SCSI HBA transport structure 1262 */ 1263 if (mptsas_hba_setup(mpt) == FALSE) 1264 goto fail; 1265 hba_attach_setup++; 1266 1267 if (mptsas_smp_setup(mpt) == FALSE) 1268 goto fail; 1269 smp_attach_setup++; 1270 1271 if (mptsas_cache_create(mpt) == FALSE) 1272 goto fail; 1273 1274 mpt->m_scsi_reset_delay = ddi_prop_get_int(DDI_DEV_T_ANY, 1275 dip, 0, "scsi-reset-delay", SCSI_DEFAULT_RESET_DELAY); 1276 if (mpt->m_scsi_reset_delay == 0) { 1277 mptsas_log(mpt, CE_NOTE, 1278 "scsi_reset_delay of 0 is not recommended," 1279 " resetting to SCSI_DEFAULT_RESET_DELAY\n"); 1280 mpt->m_scsi_reset_delay = SCSI_DEFAULT_RESET_DELAY; 1281 } 1282 1283 /* 1284 * Initialize the wait and done FIFO queue 1285 */ 1286 mpt->m_donetail = &mpt->m_doneq; 1287 mpt->m_waitqtail = &mpt->m_waitq; 1288 mpt->m_tx_waitqtail = &mpt->m_tx_waitq; 1289 mpt->m_tx_draining = 0; 1290 1291 /* 1292 * ioc cmd queue initialize 1293 */ 1294 mpt->m_ioc_event_cmdtail = &mpt->m_ioc_event_cmdq; 1295 mpt->m_dev_handle = 0xFFFF; 1296 1297 MPTSAS_ENABLE_INTR(mpt); 1298 1299 /* 1300 * enable event notification 1301 */ 1302 mutex_enter(&mpt->m_mutex); 1303 if (mptsas_ioc_enable_event_notification(mpt)) { 1304 mutex_exit(&mpt->m_mutex); 1305 goto fail; 1306 } 1307 mutex_exit(&mpt->m_mutex); 1308 1309 /* 1310 * Initialize PHY info for smhba 1311 */ 1312 if (mptsas_smhba_setup(mpt)) { 1313 mptsas_log(mpt, CE_WARN, "mptsas phy initialization " 1314 "failed"); 1315 goto fail; 1316 } 1317 1318 /* Check all dma handles allocated in attach */ 1319 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) 1320 != DDI_SUCCESS) || 1321 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) 1322 != DDI_SUCCESS) || 1323 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) 1324 != DDI_SUCCESS) || 1325 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) 1326 != DDI_SUCCESS) || 1327 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) 1328 != DDI_SUCCESS)) { 1329 goto fail; 1330 } 1331 1332 /* Check all acc handles allocated in attach */ 1333 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) || 1334 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) 1335 != DDI_SUCCESS) || 1336 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) 1337 != DDI_SUCCESS) || 1338 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) 1339 != DDI_SUCCESS) || 1340 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) 1341 != DDI_SUCCESS) || 1342 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) 1343 != DDI_SUCCESS) || 1344 (mptsas_check_acc_handle(mpt->m_config_handle) 1345 != DDI_SUCCESS)) { 1346 goto fail; 1347 } 1348 1349 /* 1350 * After this point, we are not going to fail the attach. 1351 */ 1352 /* 1353 * used for mptsas_watch 1354 */ 1355 mptsas_list_add(mpt); 1356 1357 mutex_enter(&mptsas_global_mutex); 1358 if (mptsas_timeouts_enabled == 0) { 1359 mptsas_scsi_watchdog_tick = ddi_prop_get_int(DDI_DEV_T_ANY, 1360 dip, 0, "scsi-watchdog-tick", DEFAULT_WD_TICK); 1361 1362 mptsas_tick = mptsas_scsi_watchdog_tick * 1363 drv_usectohz((clock_t)1000000); 1364 1365 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick); 1366 mptsas_timeouts_enabled = 1; 1367 } 1368 mutex_exit(&mptsas_global_mutex); 1369 1370 /* Print message of HBA present */ 1371 ddi_report_dev(dip); 1372 1373 /* report idle status to pm framework */ 1374 if (mpt->m_options & MPTSAS_OPT_PM) { 1375 (void) pm_idle_component(dip, 0); 1376 } 1377 1378 return (DDI_SUCCESS); 1379 1380 fail: 1381 mptsas_log(mpt, CE_WARN, "attach failed"); 1382 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 1383 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 1384 if (mpt) { 1385 mutex_enter(&mptsas_global_mutex); 1386 1387 if (mptsas_timeout_id && (mptsas_head == NULL)) { 1388 timeout_id_t tid = mptsas_timeout_id; 1389 mptsas_timeouts_enabled = 0; 1390 mptsas_timeout_id = 0; 1391 mutex_exit(&mptsas_global_mutex); 1392 (void) untimeout(tid); 1393 mutex_enter(&mptsas_global_mutex); 1394 } 1395 mutex_exit(&mptsas_global_mutex); 1396 /* deallocate in reverse order */ 1397 mptsas_cache_destroy(mpt); 1398 1399 if (smp_attach_setup) { 1400 mptsas_smp_teardown(mpt); 1401 } 1402 if (hba_attach_setup) { 1403 mptsas_hba_teardown(mpt); 1404 } 1405 1406 if (mpt->m_active) { 1407 mptsas_hash_uninit(&mpt->m_active->m_smptbl, 1408 sizeof (mptsas_smp_t)); 1409 mptsas_hash_uninit(&mpt->m_active->m_tgttbl, 1410 sizeof (mptsas_target_t)); 1411 mptsas_free_active_slots(mpt); 1412 } 1413 if (intr_added) { 1414 mptsas_unregister_intrs(mpt); 1415 } 1416 1417 if (doneq_thread_create) { 1418 mutex_enter(&mpt->m_doneq_mutex); 1419 doneq_thread_num = mpt->m_doneq_thread_n; 1420 for (j = 0; j < mpt->m_doneq_thread_n; j++) { 1421 mutex_enter(&mpt->m_doneq_thread_id[j].mutex); 1422 mpt->m_doneq_thread_id[j].flag &= 1423 (~MPTSAS_DONEQ_THREAD_ACTIVE); 1424 cv_signal(&mpt->m_doneq_thread_id[j].cv); 1425 mutex_exit(&mpt->m_doneq_thread_id[j].mutex); 1426 } 1427 while (mpt->m_doneq_thread_n) { 1428 cv_wait(&mpt->m_doneq_thread_cv, 1429 &mpt->m_doneq_mutex); 1430 } 1431 for (j = 0; j < doneq_thread_num; j++) { 1432 cv_destroy(&mpt->m_doneq_thread_id[j].cv); 1433 mutex_destroy(&mpt->m_doneq_thread_id[j].mutex); 1434 } 1435 kmem_free(mpt->m_doneq_thread_id, 1436 sizeof (mptsas_doneq_thread_list_t) 1437 * doneq_thread_num); 1438 mutex_exit(&mpt->m_doneq_mutex); 1439 cv_destroy(&mpt->m_doneq_thread_cv); 1440 mutex_destroy(&mpt->m_doneq_mutex); 1441 } 1442 if (event_taskq_create) { 1443 ddi_taskq_destroy(mpt->m_event_taskq); 1444 } 1445 if (dr_taskq_create) { 1446 ddi_taskq_destroy(mpt->m_dr_taskq); 1447 } 1448 if (mutex_init_done) { 1449 mutex_destroy(&mpt->m_tx_waitq_mutex); 1450 mutex_destroy(&mpt->m_passthru_mutex); 1451 mutex_destroy(&mpt->m_mutex); 1452 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1453 mutex_destroy( 1454 &mpt->m_phy_info[i].smhba_info.phy_mutex); 1455 } 1456 cv_destroy(&mpt->m_cv); 1457 cv_destroy(&mpt->m_passthru_cv); 1458 cv_destroy(&mpt->m_fw_cv); 1459 cv_destroy(&mpt->m_config_cv); 1460 cv_destroy(&mpt->m_fw_diag_cv); 1461 } 1462 1463 if (map_setup) { 1464 mptsas_cfg_fini(mpt); 1465 } 1466 if (config_setup) { 1467 mptsas_config_space_fini(mpt); 1468 } 1469 mptsas_free_handshake_msg(mpt); 1470 mptsas_hba_fini(mpt); 1471 1472 mptsas_fm_fini(mpt); 1473 ddi_soft_state_free(mptsas_state, instance); 1474 ddi_prop_remove_all(dip); 1475 } 1476 return (DDI_FAILURE); 1477 } 1478 1479 static int 1480 mptsas_suspend(dev_info_t *devi) 1481 { 1482 mptsas_t *mpt, *g; 1483 scsi_hba_tran_t *tran; 1484 1485 if (scsi_hba_iport_unit_address(devi)) { 1486 return (DDI_SUCCESS); 1487 } 1488 1489 if ((tran = ddi_get_driver_private(devi)) == NULL) 1490 return (DDI_SUCCESS); 1491 1492 mpt = TRAN2MPT(tran); 1493 if (!mpt) { 1494 return (DDI_SUCCESS); 1495 } 1496 1497 mutex_enter(&mpt->m_mutex); 1498 1499 if (mpt->m_suspended++) { 1500 mutex_exit(&mpt->m_mutex); 1501 return (DDI_SUCCESS); 1502 } 1503 1504 /* 1505 * Cancel timeout threads for this mpt 1506 */ 1507 if (mpt->m_quiesce_timeid) { 1508 timeout_id_t tid = mpt->m_quiesce_timeid; 1509 mpt->m_quiesce_timeid = 0; 1510 mutex_exit(&mpt->m_mutex); 1511 (void) untimeout(tid); 1512 mutex_enter(&mpt->m_mutex); 1513 } 1514 1515 if (mpt->m_restart_cmd_timeid) { 1516 timeout_id_t tid = mpt->m_restart_cmd_timeid; 1517 mpt->m_restart_cmd_timeid = 0; 1518 mutex_exit(&mpt->m_mutex); 1519 (void) untimeout(tid); 1520 mutex_enter(&mpt->m_mutex); 1521 } 1522 1523 mutex_exit(&mpt->m_mutex); 1524 1525 (void) pm_idle_component(mpt->m_dip, 0); 1526 1527 /* 1528 * Cancel watch threads if all mpts suspended 1529 */ 1530 rw_enter(&mptsas_global_rwlock, RW_WRITER); 1531 for (g = mptsas_head; g != NULL; g = g->m_next) { 1532 if (!g->m_suspended) 1533 break; 1534 } 1535 rw_exit(&mptsas_global_rwlock); 1536 1537 mutex_enter(&mptsas_global_mutex); 1538 if (g == NULL) { 1539 timeout_id_t tid; 1540 1541 mptsas_timeouts_enabled = 0; 1542 if (mptsas_timeout_id) { 1543 tid = mptsas_timeout_id; 1544 mptsas_timeout_id = 0; 1545 mutex_exit(&mptsas_global_mutex); 1546 (void) untimeout(tid); 1547 mutex_enter(&mptsas_global_mutex); 1548 } 1549 if (mptsas_reset_watch) { 1550 tid = mptsas_reset_watch; 1551 mptsas_reset_watch = 0; 1552 mutex_exit(&mptsas_global_mutex); 1553 (void) untimeout(tid); 1554 mutex_enter(&mptsas_global_mutex); 1555 } 1556 } 1557 mutex_exit(&mptsas_global_mutex); 1558 1559 mutex_enter(&mpt->m_mutex); 1560 1561 /* 1562 * If this mpt is not in full power(PM_LEVEL_D0), just return. 1563 */ 1564 if ((mpt->m_options & MPTSAS_OPT_PM) && 1565 (mpt->m_power_level != PM_LEVEL_D0)) { 1566 mutex_exit(&mpt->m_mutex); 1567 return (DDI_SUCCESS); 1568 } 1569 1570 /* Disable HBA interrupts in hardware */ 1571 MPTSAS_DISABLE_INTR(mpt); 1572 /* 1573 * Send RAID action system shutdown to sync IR 1574 */ 1575 mptsas_raid_action_system_shutdown(mpt); 1576 1577 mutex_exit(&mpt->m_mutex); 1578 1579 /* drain the taskq */ 1580 ddi_taskq_wait(mpt->m_event_taskq); 1581 ddi_taskq_wait(mpt->m_dr_taskq); 1582 1583 return (DDI_SUCCESS); 1584 } 1585 1586 #ifdef __sparc 1587 /*ARGSUSED*/ 1588 static int 1589 mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd) 1590 { 1591 mptsas_t *mpt; 1592 scsi_hba_tran_t *tran; 1593 1594 /* 1595 * If this call is for iport, just return. 1596 */ 1597 if (scsi_hba_iport_unit_address(devi)) 1598 return (DDI_SUCCESS); 1599 1600 if ((tran = ddi_get_driver_private(devi)) == NULL) 1601 return (DDI_SUCCESS); 1602 1603 if ((mpt = TRAN2MPT(tran)) == NULL) 1604 return (DDI_SUCCESS); 1605 1606 /* 1607 * Send RAID action system shutdown to sync IR. Disable HBA 1608 * interrupts in hardware first. 1609 */ 1610 MPTSAS_DISABLE_INTR(mpt); 1611 mptsas_raid_action_system_shutdown(mpt); 1612 1613 return (DDI_SUCCESS); 1614 } 1615 #else /* __sparc */ 1616 /* 1617 * quiesce(9E) entry point. 1618 * 1619 * This function is called when the system is single-threaded at high 1620 * PIL with preemption disabled. Therefore, this function must not be 1621 * blocked. 1622 * 1623 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 1624 * DDI_FAILURE indicates an error condition and should almost never happen. 1625 */ 1626 static int 1627 mptsas_quiesce(dev_info_t *devi) 1628 { 1629 mptsas_t *mpt; 1630 scsi_hba_tran_t *tran; 1631 1632 /* 1633 * If this call is for iport, just return. 1634 */ 1635 if (scsi_hba_iport_unit_address(devi)) 1636 return (DDI_SUCCESS); 1637 1638 if ((tran = ddi_get_driver_private(devi)) == NULL) 1639 return (DDI_SUCCESS); 1640 1641 if ((mpt = TRAN2MPT(tran)) == NULL) 1642 return (DDI_SUCCESS); 1643 1644 /* Disable HBA interrupts in hardware */ 1645 MPTSAS_DISABLE_INTR(mpt); 1646 /* Send RAID action system shutdonw to sync IR */ 1647 mptsas_raid_action_system_shutdown(mpt); 1648 1649 return (DDI_SUCCESS); 1650 } 1651 #endif /* __sparc */ 1652 1653 /* 1654 * detach(9E). Remove all device allocations and system resources; 1655 * disable device interrupts. 1656 * Return DDI_SUCCESS if done; DDI_FAILURE if there's a problem. 1657 */ 1658 static int 1659 mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 1660 { 1661 /* CONSTCOND */ 1662 ASSERT(NO_COMPETING_THREADS); 1663 NDBG0(("mptsas_detach: dip=0x%p cmd=0x%p", (void *)devi, (void *)cmd)); 1664 1665 switch (cmd) { 1666 case DDI_DETACH: 1667 return (mptsas_do_detach(devi)); 1668 1669 case DDI_SUSPEND: 1670 return (mptsas_suspend(devi)); 1671 1672 default: 1673 return (DDI_FAILURE); 1674 } 1675 /* NOTREACHED */ 1676 } 1677 1678 static int 1679 mptsas_do_detach(dev_info_t *dip) 1680 { 1681 mptsas_t *mpt; 1682 scsi_hba_tran_t *tran; 1683 int circ = 0; 1684 int circ1 = 0; 1685 mdi_pathinfo_t *pip = NULL; 1686 int i; 1687 int doneq_thread_num = 0; 1688 1689 NDBG0(("mptsas_do_detach: dip=0x%p", (void *)dip)); 1690 1691 if ((tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == NULL) 1692 return (DDI_FAILURE); 1693 1694 mpt = TRAN2MPT(tran); 1695 if (!mpt) { 1696 return (DDI_FAILURE); 1697 } 1698 /* 1699 * Still have pathinfo child, should not detach mpt driver 1700 */ 1701 if (scsi_hba_iport_unit_address(dip)) { 1702 if (mpt->m_mpxio_enable) { 1703 /* 1704 * MPxIO enabled for the iport 1705 */ 1706 ndi_devi_enter(scsi_vhci_dip, &circ1); 1707 ndi_devi_enter(dip, &circ); 1708 while (pip = mdi_get_next_client_path(dip, NULL)) { 1709 if (mdi_pi_free(pip, 0) == MDI_SUCCESS) { 1710 continue; 1711 } 1712 ndi_devi_exit(dip, circ); 1713 ndi_devi_exit(scsi_vhci_dip, circ1); 1714 NDBG12(("detach failed because of " 1715 "outstanding path info")); 1716 return (DDI_FAILURE); 1717 } 1718 ndi_devi_exit(dip, circ); 1719 ndi_devi_exit(scsi_vhci_dip, circ1); 1720 (void) mdi_phci_unregister(dip, 0); 1721 } 1722 1723 ddi_prop_remove_all(dip); 1724 1725 return (DDI_SUCCESS); 1726 } 1727 1728 /* Make sure power level is D0 before accessing registers */ 1729 if (mpt->m_options & MPTSAS_OPT_PM) { 1730 (void) pm_busy_component(dip, 0); 1731 if (mpt->m_power_level != PM_LEVEL_D0) { 1732 if (pm_raise_power(dip, 0, PM_LEVEL_D0) != 1733 DDI_SUCCESS) { 1734 mptsas_log(mpt, CE_WARN, 1735 "mptsas%d: Raise power request failed.", 1736 mpt->m_instance); 1737 (void) pm_idle_component(dip, 0); 1738 return (DDI_FAILURE); 1739 } 1740 } 1741 } 1742 1743 /* 1744 * Send RAID action system shutdown to sync IR. After action, send a 1745 * Message Unit Reset. Since after that DMA resource will be freed, 1746 * set ioc to READY state will avoid HBA initiated DMA operation. 1747 */ 1748 mutex_enter(&mpt->m_mutex); 1749 MPTSAS_DISABLE_INTR(mpt); 1750 mptsas_raid_action_system_shutdown(mpt); 1751 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1752 (void) mptsas_ioc_reset(mpt, FALSE); 1753 mutex_exit(&mpt->m_mutex); 1754 mptsas_rem_intrs(mpt); 1755 ddi_taskq_destroy(mpt->m_event_taskq); 1756 ddi_taskq_destroy(mpt->m_dr_taskq); 1757 1758 if (mpt->m_doneq_thread_n) { 1759 mutex_enter(&mpt->m_doneq_mutex); 1760 doneq_thread_num = mpt->m_doneq_thread_n; 1761 for (i = 0; i < mpt->m_doneq_thread_n; i++) { 1762 mutex_enter(&mpt->m_doneq_thread_id[i].mutex); 1763 mpt->m_doneq_thread_id[i].flag &= 1764 (~MPTSAS_DONEQ_THREAD_ACTIVE); 1765 cv_signal(&mpt->m_doneq_thread_id[i].cv); 1766 mutex_exit(&mpt->m_doneq_thread_id[i].mutex); 1767 } 1768 while (mpt->m_doneq_thread_n) { 1769 cv_wait(&mpt->m_doneq_thread_cv, 1770 &mpt->m_doneq_mutex); 1771 } 1772 for (i = 0; i < doneq_thread_num; i++) { 1773 cv_destroy(&mpt->m_doneq_thread_id[i].cv); 1774 mutex_destroy(&mpt->m_doneq_thread_id[i].mutex); 1775 } 1776 kmem_free(mpt->m_doneq_thread_id, 1777 sizeof (mptsas_doneq_thread_list_t) 1778 * doneq_thread_num); 1779 mutex_exit(&mpt->m_doneq_mutex); 1780 cv_destroy(&mpt->m_doneq_thread_cv); 1781 mutex_destroy(&mpt->m_doneq_mutex); 1782 } 1783 1784 scsi_hba_reset_notify_tear_down(mpt->m_reset_notify_listf); 1785 1786 mptsas_list_del(mpt); 1787 1788 /* 1789 * Cancel timeout threads for this mpt 1790 */ 1791 mutex_enter(&mpt->m_mutex); 1792 if (mpt->m_quiesce_timeid) { 1793 timeout_id_t tid = mpt->m_quiesce_timeid; 1794 mpt->m_quiesce_timeid = 0; 1795 mutex_exit(&mpt->m_mutex); 1796 (void) untimeout(tid); 1797 mutex_enter(&mpt->m_mutex); 1798 } 1799 1800 if (mpt->m_restart_cmd_timeid) { 1801 timeout_id_t tid = mpt->m_restart_cmd_timeid; 1802 mpt->m_restart_cmd_timeid = 0; 1803 mutex_exit(&mpt->m_mutex); 1804 (void) untimeout(tid); 1805 mutex_enter(&mpt->m_mutex); 1806 } 1807 1808 mutex_exit(&mpt->m_mutex); 1809 1810 /* 1811 * last mpt? ... if active, CANCEL watch threads. 1812 */ 1813 mutex_enter(&mptsas_global_mutex); 1814 if (mptsas_head == NULL) { 1815 timeout_id_t tid; 1816 /* 1817 * Clear mptsas_timeouts_enable so that the watch thread 1818 * gets restarted on DDI_ATTACH 1819 */ 1820 mptsas_timeouts_enabled = 0; 1821 if (mptsas_timeout_id) { 1822 tid = mptsas_timeout_id; 1823 mptsas_timeout_id = 0; 1824 mutex_exit(&mptsas_global_mutex); 1825 (void) untimeout(tid); 1826 mutex_enter(&mptsas_global_mutex); 1827 } 1828 if (mptsas_reset_watch) { 1829 tid = mptsas_reset_watch; 1830 mptsas_reset_watch = 0; 1831 mutex_exit(&mptsas_global_mutex); 1832 (void) untimeout(tid); 1833 mutex_enter(&mptsas_global_mutex); 1834 } 1835 } 1836 mutex_exit(&mptsas_global_mutex); 1837 1838 /* 1839 * Delete Phy stats 1840 */ 1841 mptsas_destroy_phy_stats(mpt); 1842 1843 /* 1844 * Delete nt_active. 1845 */ 1846 mutex_enter(&mpt->m_mutex); 1847 mptsas_hash_uninit(&mpt->m_active->m_tgttbl, sizeof (mptsas_target_t)); 1848 mptsas_hash_uninit(&mpt->m_active->m_smptbl, sizeof (mptsas_smp_t)); 1849 mptsas_free_active_slots(mpt); 1850 mutex_exit(&mpt->m_mutex); 1851 1852 /* deallocate everything that was allocated in mptsas_attach */ 1853 mptsas_cache_destroy(mpt); 1854 1855 mptsas_hba_fini(mpt); 1856 mptsas_cfg_fini(mpt); 1857 1858 /* Lower the power informing PM Framework */ 1859 if (mpt->m_options & MPTSAS_OPT_PM) { 1860 if (pm_lower_power(dip, 0, PM_LEVEL_D3) != DDI_SUCCESS) 1861 mptsas_log(mpt, CE_WARN, 1862 "!mptsas%d: Lower power request failed " 1863 "during detach, ignoring.", 1864 mpt->m_instance); 1865 } 1866 1867 mutex_destroy(&mpt->m_tx_waitq_mutex); 1868 mutex_destroy(&mpt->m_passthru_mutex); 1869 mutex_destroy(&mpt->m_mutex); 1870 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1871 mutex_destroy(&mpt->m_phy_info[i].smhba_info.phy_mutex); 1872 } 1873 cv_destroy(&mpt->m_cv); 1874 cv_destroy(&mpt->m_passthru_cv); 1875 cv_destroy(&mpt->m_fw_cv); 1876 cv_destroy(&mpt->m_config_cv); 1877 cv_destroy(&mpt->m_fw_diag_cv); 1878 1879 1880 mptsas_smp_teardown(mpt); 1881 mptsas_hba_teardown(mpt); 1882 1883 mptsas_config_space_fini(mpt); 1884 1885 mptsas_free_handshake_msg(mpt); 1886 1887 mptsas_fm_fini(mpt); 1888 ddi_soft_state_free(mptsas_state, ddi_get_instance(dip)); 1889 ddi_prop_remove_all(dip); 1890 1891 return (DDI_SUCCESS); 1892 } 1893 1894 static void 1895 mptsas_list_add(mptsas_t *mpt) 1896 { 1897 rw_enter(&mptsas_global_rwlock, RW_WRITER); 1898 1899 if (mptsas_head == NULL) { 1900 mptsas_head = mpt; 1901 } else { 1902 mptsas_tail->m_next = mpt; 1903 } 1904 mptsas_tail = mpt; 1905 rw_exit(&mptsas_global_rwlock); 1906 } 1907 1908 static void 1909 mptsas_list_del(mptsas_t *mpt) 1910 { 1911 mptsas_t *m; 1912 /* 1913 * Remove device instance from the global linked list 1914 */ 1915 rw_enter(&mptsas_global_rwlock, RW_WRITER); 1916 if (mptsas_head == mpt) { 1917 m = mptsas_head = mpt->m_next; 1918 } else { 1919 for (m = mptsas_head; m != NULL; m = m->m_next) { 1920 if (m->m_next == mpt) { 1921 m->m_next = mpt->m_next; 1922 break; 1923 } 1924 } 1925 if (m == NULL) { 1926 mptsas_log(mpt, CE_PANIC, "Not in softc list!"); 1927 } 1928 } 1929 1930 if (mptsas_tail == mpt) { 1931 mptsas_tail = m; 1932 } 1933 rw_exit(&mptsas_global_rwlock); 1934 } 1935 1936 static int 1937 mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size) 1938 { 1939 ddi_dma_attr_t task_dma_attrs; 1940 1941 task_dma_attrs = mpt->m_msg_dma_attr; 1942 task_dma_attrs.dma_attr_sgllen = 1; 1943 task_dma_attrs.dma_attr_granular = (uint32_t)(alloc_size); 1944 1945 /* allocate Task Management ddi_dma resources */ 1946 if (mptsas_dma_addr_create(mpt, task_dma_attrs, 1947 &mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl, &mpt->m_hshk_memp, 1948 alloc_size, NULL) == FALSE) { 1949 return (DDI_FAILURE); 1950 } 1951 mpt->m_hshk_dma_size = alloc_size; 1952 1953 return (DDI_SUCCESS); 1954 } 1955 1956 static void 1957 mptsas_free_handshake_msg(mptsas_t *mpt) 1958 { 1959 mptsas_dma_addr_destroy(&mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl); 1960 mpt->m_hshk_dma_size = 0; 1961 } 1962 1963 static int 1964 mptsas_hba_setup(mptsas_t *mpt) 1965 { 1966 scsi_hba_tran_t *hba_tran; 1967 int tran_flags; 1968 1969 /* Allocate a transport structure */ 1970 hba_tran = mpt->m_tran = scsi_hba_tran_alloc(mpt->m_dip, 1971 SCSI_HBA_CANSLEEP); 1972 ASSERT(mpt->m_tran != NULL); 1973 1974 hba_tran->tran_hba_private = mpt; 1975 hba_tran->tran_tgt_private = NULL; 1976 1977 hba_tran->tran_tgt_init = mptsas_scsi_tgt_init; 1978 hba_tran->tran_tgt_free = mptsas_scsi_tgt_free; 1979 1980 hba_tran->tran_start = mptsas_scsi_start; 1981 hba_tran->tran_reset = mptsas_scsi_reset; 1982 hba_tran->tran_abort = mptsas_scsi_abort; 1983 hba_tran->tran_getcap = mptsas_scsi_getcap; 1984 hba_tran->tran_setcap = mptsas_scsi_setcap; 1985 hba_tran->tran_init_pkt = mptsas_scsi_init_pkt; 1986 hba_tran->tran_destroy_pkt = mptsas_scsi_destroy_pkt; 1987 1988 hba_tran->tran_dmafree = mptsas_scsi_dmafree; 1989 hba_tran->tran_sync_pkt = mptsas_scsi_sync_pkt; 1990 hba_tran->tran_reset_notify = mptsas_scsi_reset_notify; 1991 1992 hba_tran->tran_get_bus_addr = mptsas_get_bus_addr; 1993 hba_tran->tran_get_name = mptsas_get_name; 1994 1995 hba_tran->tran_quiesce = mptsas_scsi_quiesce; 1996 hba_tran->tran_unquiesce = mptsas_scsi_unquiesce; 1997 hba_tran->tran_bus_reset = NULL; 1998 1999 hba_tran->tran_add_eventcall = NULL; 2000 hba_tran->tran_get_eventcookie = NULL; 2001 hba_tran->tran_post_event = NULL; 2002 hba_tran->tran_remove_eventcall = NULL; 2003 2004 hba_tran->tran_bus_config = mptsas_bus_config; 2005 2006 hba_tran->tran_interconnect_type = INTERCONNECT_SAS; 2007 2008 /* 2009 * All children of the HBA are iports. We need tran was cloned. 2010 * So we pass the flags to SCSA. SCSI_HBA_TRAN_CLONE will be 2011 * inherited to iport's tran vector. 2012 */ 2013 tran_flags = (SCSI_HBA_HBA | SCSI_HBA_TRAN_CLONE); 2014 2015 if (scsi_hba_attach_setup(mpt->m_dip, &mpt->m_msg_dma_attr, 2016 hba_tran, tran_flags) != DDI_SUCCESS) { 2017 mptsas_log(mpt, CE_WARN, "hba attach setup failed"); 2018 scsi_hba_tran_free(hba_tran); 2019 mpt->m_tran = NULL; 2020 return (FALSE); 2021 } 2022 return (TRUE); 2023 } 2024 2025 static void 2026 mptsas_hba_teardown(mptsas_t *mpt) 2027 { 2028 (void) scsi_hba_detach(mpt->m_dip); 2029 if (mpt->m_tran != NULL) { 2030 scsi_hba_tran_free(mpt->m_tran); 2031 mpt->m_tran = NULL; 2032 } 2033 } 2034 2035 static void 2036 mptsas_iport_register(mptsas_t *mpt) 2037 { 2038 int i, j; 2039 mptsas_phymask_t mask = 0x0; 2040 /* 2041 * initial value of mask is 0 2042 */ 2043 mutex_enter(&mpt->m_mutex); 2044 for (i = 0; i < mpt->m_num_phys; i++) { 2045 mptsas_phymask_t phy_mask = 0x0; 2046 char phy_mask_name[MPTSAS_MAX_PHYS]; 2047 uint8_t current_port; 2048 2049 if (mpt->m_phy_info[i].attached_devhdl == 0) 2050 continue; 2051 2052 bzero(phy_mask_name, sizeof (phy_mask_name)); 2053 2054 current_port = mpt->m_phy_info[i].port_num; 2055 2056 if ((mask & (1 << i)) != 0) 2057 continue; 2058 2059 for (j = 0; j < mpt->m_num_phys; j++) { 2060 if (mpt->m_phy_info[j].attached_devhdl && 2061 (mpt->m_phy_info[j].port_num == current_port)) { 2062 phy_mask |= (1 << j); 2063 } 2064 } 2065 mask = mask | phy_mask; 2066 2067 for (j = 0; j < mpt->m_num_phys; j++) { 2068 if ((phy_mask >> j) & 0x01) { 2069 mpt->m_phy_info[j].phy_mask = phy_mask; 2070 } 2071 } 2072 2073 (void) sprintf(phy_mask_name, "%x", phy_mask); 2074 2075 mutex_exit(&mpt->m_mutex); 2076 /* 2077 * register a iport 2078 */ 2079 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name); 2080 mutex_enter(&mpt->m_mutex); 2081 } 2082 mutex_exit(&mpt->m_mutex); 2083 /* 2084 * register a virtual port for RAID volume always 2085 */ 2086 (void) scsi_hba_iport_register(mpt->m_dip, "v0"); 2087 2088 } 2089 2090 static int 2091 mptsas_smp_setup(mptsas_t *mpt) 2092 { 2093 mpt->m_smptran = smp_hba_tran_alloc(mpt->m_dip); 2094 ASSERT(mpt->m_smptran != NULL); 2095 mpt->m_smptran->smp_tran_hba_private = mpt; 2096 mpt->m_smptran->smp_tran_start = mptsas_smp_start; 2097 if (smp_hba_attach_setup(mpt->m_dip, mpt->m_smptran) != DDI_SUCCESS) { 2098 mptsas_log(mpt, CE_WARN, "smp attach setup failed"); 2099 smp_hba_tran_free(mpt->m_smptran); 2100 mpt->m_smptran = NULL; 2101 return (FALSE); 2102 } 2103 /* 2104 * Initialize smp hash table 2105 */ 2106 mptsas_hash_init(&mpt->m_active->m_smptbl); 2107 mpt->m_smp_devhdl = 0xFFFF; 2108 2109 return (TRUE); 2110 } 2111 2112 static void 2113 mptsas_smp_teardown(mptsas_t *mpt) 2114 { 2115 (void) smp_hba_detach(mpt->m_dip); 2116 if (mpt->m_smptran != NULL) { 2117 smp_hba_tran_free(mpt->m_smptran); 2118 mpt->m_smptran = NULL; 2119 } 2120 mpt->m_smp_devhdl = 0; 2121 } 2122 2123 static int 2124 mptsas_cache_create(mptsas_t *mpt) 2125 { 2126 int instance = mpt->m_instance; 2127 char buf[64]; 2128 2129 /* 2130 * create kmem cache for packets 2131 */ 2132 (void) sprintf(buf, "mptsas%d_cache", instance); 2133 mpt->m_kmem_cache = kmem_cache_create(buf, 2134 sizeof (struct mptsas_cmd) + scsi_pkt_size(), 8, 2135 mptsas_kmem_cache_constructor, mptsas_kmem_cache_destructor, 2136 NULL, (void *)mpt, NULL, 0); 2137 2138 if (mpt->m_kmem_cache == NULL) { 2139 mptsas_log(mpt, CE_WARN, "creating kmem cache failed"); 2140 return (FALSE); 2141 } 2142 2143 /* 2144 * create kmem cache for extra SGL frames if SGL cannot 2145 * be accomodated into main request frame. 2146 */ 2147 (void) sprintf(buf, "mptsas%d_cache_frames", instance); 2148 mpt->m_cache_frames = kmem_cache_create(buf, 2149 sizeof (mptsas_cache_frames_t), 8, 2150 mptsas_cache_frames_constructor, mptsas_cache_frames_destructor, 2151 NULL, (void *)mpt, NULL, 0); 2152 2153 if (mpt->m_cache_frames == NULL) { 2154 mptsas_log(mpt, CE_WARN, "creating cache for frames failed"); 2155 return (FALSE); 2156 } 2157 2158 return (TRUE); 2159 } 2160 2161 static void 2162 mptsas_cache_destroy(mptsas_t *mpt) 2163 { 2164 /* deallocate in reverse order */ 2165 if (mpt->m_cache_frames) { 2166 kmem_cache_destroy(mpt->m_cache_frames); 2167 mpt->m_cache_frames = NULL; 2168 } 2169 if (mpt->m_kmem_cache) { 2170 kmem_cache_destroy(mpt->m_kmem_cache); 2171 mpt->m_kmem_cache = NULL; 2172 } 2173 } 2174 2175 static int 2176 mptsas_power(dev_info_t *dip, int component, int level) 2177 { 2178 #ifndef __lock_lint 2179 _NOTE(ARGUNUSED(component)) 2180 #endif 2181 mptsas_t *mpt; 2182 int rval = DDI_SUCCESS; 2183 int polls = 0; 2184 uint32_t ioc_status; 2185 2186 if (scsi_hba_iport_unit_address(dip) != 0) 2187 return (DDI_SUCCESS); 2188 2189 mpt = ddi_get_soft_state(mptsas_state, ddi_get_instance(dip)); 2190 if (mpt == NULL) { 2191 return (DDI_FAILURE); 2192 } 2193 2194 mutex_enter(&mpt->m_mutex); 2195 2196 /* 2197 * If the device is busy, don't lower its power level 2198 */ 2199 if (mpt->m_busy && (mpt->m_power_level > level)) { 2200 mutex_exit(&mpt->m_mutex); 2201 return (DDI_FAILURE); 2202 } 2203 switch (level) { 2204 case PM_LEVEL_D0: 2205 NDBG11(("mptsas%d: turning power ON.", mpt->m_instance)); 2206 MPTSAS_POWER_ON(mpt); 2207 /* 2208 * Wait up to 30 seconds for IOC to come out of reset. 2209 */ 2210 while (((ioc_status = ddi_get32(mpt->m_datap, 2211 &mpt->m_reg->Doorbell)) & 2212 MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_RESET) { 2213 if (polls++ > 3000) { 2214 break; 2215 } 2216 delay(drv_usectohz(10000)); 2217 } 2218 /* 2219 * If IOC is not in operational state, try to hard reset it. 2220 */ 2221 if ((ioc_status & MPI2_IOC_STATE_MASK) != 2222 MPI2_IOC_STATE_OPERATIONAL) { 2223 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 2224 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) { 2225 mptsas_log(mpt, CE_WARN, 2226 "mptsas_power: hard reset failed"); 2227 mutex_exit(&mpt->m_mutex); 2228 return (DDI_FAILURE); 2229 } 2230 } 2231 mpt->m_power_level = PM_LEVEL_D0; 2232 break; 2233 case PM_LEVEL_D3: 2234 NDBG11(("mptsas%d: turning power OFF.", mpt->m_instance)); 2235 MPTSAS_POWER_OFF(mpt); 2236 break; 2237 default: 2238 mptsas_log(mpt, CE_WARN, "mptsas%d: unknown power level <%x>.", 2239 mpt->m_instance, level); 2240 rval = DDI_FAILURE; 2241 break; 2242 } 2243 mutex_exit(&mpt->m_mutex); 2244 return (rval); 2245 } 2246 2247 /* 2248 * Initialize configuration space and figure out which 2249 * chip and revison of the chip the mpt driver is using. 2250 */ 2251 static int 2252 mptsas_config_space_init(mptsas_t *mpt) 2253 { 2254 NDBG0(("mptsas_config_space_init")); 2255 2256 if (mpt->m_config_handle != NULL) 2257 return (TRUE); 2258 2259 if (pci_config_setup(mpt->m_dip, 2260 &mpt->m_config_handle) != DDI_SUCCESS) { 2261 mptsas_log(mpt, CE_WARN, "cannot map configuration space."); 2262 return (FALSE); 2263 } 2264 2265 /* 2266 * This is a workaround for a XMITS ASIC bug which does not 2267 * drive the CBE upper bits. 2268 */ 2269 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) & 2270 PCI_STAT_PERROR) { 2271 pci_config_put16(mpt->m_config_handle, PCI_CONF_STAT, 2272 PCI_STAT_PERROR); 2273 } 2274 2275 mptsas_setup_cmd_reg(mpt); 2276 2277 /* 2278 * Get the chip device id: 2279 */ 2280 mpt->m_devid = pci_config_get16(mpt->m_config_handle, PCI_CONF_DEVID); 2281 2282 /* 2283 * Save the revision. 2284 */ 2285 mpt->m_revid = pci_config_get8(mpt->m_config_handle, PCI_CONF_REVID); 2286 2287 /* 2288 * Save the SubSystem Vendor and Device IDs 2289 */ 2290 mpt->m_svid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBVENID); 2291 mpt->m_ssid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBSYSID); 2292 2293 /* 2294 * Set the latency timer to 0x40 as specified by the upa -> pci 2295 * bridge chip design team. This may be done by the sparc pci 2296 * bus nexus driver, but the driver should make sure the latency 2297 * timer is correct for performance reasons. 2298 */ 2299 pci_config_put8(mpt->m_config_handle, PCI_CONF_LATENCY_TIMER, 2300 MPTSAS_LATENCY_TIMER); 2301 2302 (void) mptsas_get_pci_cap(mpt); 2303 return (TRUE); 2304 } 2305 2306 static void 2307 mptsas_config_space_fini(mptsas_t *mpt) 2308 { 2309 if (mpt->m_config_handle != NULL) { 2310 mptsas_disable_bus_master(mpt); 2311 pci_config_teardown(&mpt->m_config_handle); 2312 mpt->m_config_handle = NULL; 2313 } 2314 } 2315 2316 static void 2317 mptsas_setup_cmd_reg(mptsas_t *mpt) 2318 { 2319 ushort_t cmdreg; 2320 2321 /* 2322 * Set the command register to the needed values. 2323 */ 2324 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM); 2325 cmdreg |= (PCI_COMM_ME | PCI_COMM_SERR_ENABLE | 2326 PCI_COMM_PARITY_DETECT | PCI_COMM_MAE); 2327 cmdreg &= ~PCI_COMM_IO; 2328 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg); 2329 } 2330 2331 static void 2332 mptsas_disable_bus_master(mptsas_t *mpt) 2333 { 2334 ushort_t cmdreg; 2335 2336 /* 2337 * Clear the master enable bit in the PCI command register. 2338 * This prevents any bus mastering activity like DMA. 2339 */ 2340 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM); 2341 cmdreg &= ~PCI_COMM_ME; 2342 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg); 2343 } 2344 2345 int 2346 mptsas_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep) 2347 { 2348 ddi_dma_attr_t attrs; 2349 2350 attrs = mpt->m_io_dma_attr; 2351 attrs.dma_attr_sgllen = 1; 2352 2353 ASSERT(dma_statep != NULL); 2354 2355 if (mptsas_dma_addr_create(mpt, attrs, &dma_statep->handle, 2356 &dma_statep->accessp, &dma_statep->memp, dma_statep->size, 2357 &dma_statep->cookie) == FALSE) { 2358 return (DDI_FAILURE); 2359 } 2360 2361 return (DDI_SUCCESS); 2362 } 2363 2364 void 2365 mptsas_dma_free(mptsas_dma_alloc_state_t *dma_statep) 2366 { 2367 ASSERT(dma_statep != NULL); 2368 mptsas_dma_addr_destroy(&dma_statep->handle, &dma_statep->accessp); 2369 dma_statep->size = 0; 2370 } 2371 2372 int 2373 mptsas_do_dma(mptsas_t *mpt, uint32_t size, int var, int (*callback)()) 2374 { 2375 ddi_dma_attr_t attrs; 2376 ddi_dma_handle_t dma_handle; 2377 caddr_t memp; 2378 ddi_acc_handle_t accessp; 2379 int rval; 2380 2381 ASSERT(mutex_owned(&mpt->m_mutex)); 2382 2383 attrs = mpt->m_msg_dma_attr; 2384 attrs.dma_attr_sgllen = 1; 2385 attrs.dma_attr_granular = size; 2386 2387 if (mptsas_dma_addr_create(mpt, attrs, &dma_handle, 2388 &accessp, &memp, size, NULL) == FALSE) { 2389 return (DDI_FAILURE); 2390 } 2391 2392 rval = (*callback) (mpt, memp, var, accessp); 2393 2394 if ((mptsas_check_dma_handle(dma_handle) != DDI_SUCCESS) || 2395 (mptsas_check_acc_handle(accessp) != DDI_SUCCESS)) { 2396 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 2397 rval = DDI_FAILURE; 2398 } 2399 2400 mptsas_dma_addr_destroy(&dma_handle, &accessp); 2401 return (rval); 2402 2403 } 2404 2405 static int 2406 mptsas_alloc_request_frames(mptsas_t *mpt) 2407 { 2408 ddi_dma_attr_t frame_dma_attrs; 2409 caddr_t memp; 2410 ddi_dma_cookie_t cookie; 2411 size_t mem_size; 2412 2413 /* 2414 * re-alloc when it has already alloced 2415 */ 2416 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl, 2417 &mpt->m_acc_req_frame_hdl); 2418 2419 /* 2420 * The size of the request frame pool is: 2421 * Number of Request Frames * Request Frame Size 2422 */ 2423 mem_size = mpt->m_max_requests * mpt->m_req_frame_size; 2424 2425 /* 2426 * set the DMA attributes. System Request Message Frames must be 2427 * aligned on a 16-byte boundry. 2428 */ 2429 frame_dma_attrs = mpt->m_msg_dma_attr; 2430 frame_dma_attrs.dma_attr_align = 16; 2431 frame_dma_attrs.dma_attr_sgllen = 1; 2432 2433 /* 2434 * allocate the request frame pool. 2435 */ 2436 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2437 &mpt->m_dma_req_frame_hdl, &mpt->m_acc_req_frame_hdl, &memp, 2438 mem_size, &cookie) == FALSE) { 2439 return (DDI_FAILURE); 2440 } 2441 2442 /* 2443 * Store the request frame memory address. This chip uses this 2444 * address to dma to and from the driver's frame. The second 2445 * address is the address mpt uses to fill in the frame. 2446 */ 2447 mpt->m_req_frame_dma_addr = cookie.dmac_laddress; 2448 mpt->m_req_frame = memp; 2449 2450 /* 2451 * Clear the request frame pool. 2452 */ 2453 bzero(mpt->m_req_frame, mem_size); 2454 2455 return (DDI_SUCCESS); 2456 } 2457 2458 static int 2459 mptsas_alloc_reply_frames(mptsas_t *mpt) 2460 { 2461 ddi_dma_attr_t frame_dma_attrs; 2462 caddr_t memp; 2463 ddi_dma_cookie_t cookie; 2464 size_t mem_size; 2465 2466 /* 2467 * re-alloc when it has already alloced 2468 */ 2469 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl, 2470 &mpt->m_acc_reply_frame_hdl); 2471 2472 /* 2473 * The size of the reply frame pool is: 2474 * Number of Reply Frames * Reply Frame Size 2475 */ 2476 mem_size = mpt->m_max_replies * mpt->m_reply_frame_size; 2477 2478 /* 2479 * set the DMA attributes. System Reply Message Frames must be 2480 * aligned on a 4-byte boundry. This is the default. 2481 */ 2482 frame_dma_attrs = mpt->m_msg_dma_attr; 2483 frame_dma_attrs.dma_attr_sgllen = 1; 2484 2485 /* 2486 * allocate the reply frame pool 2487 */ 2488 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2489 &mpt->m_dma_reply_frame_hdl, &mpt->m_acc_reply_frame_hdl, &memp, 2490 mem_size, &cookie) == FALSE) { 2491 return (DDI_FAILURE); 2492 } 2493 2494 /* 2495 * Store the reply frame memory address. This chip uses this 2496 * address to dma to and from the driver's frame. The second 2497 * address is the address mpt uses to process the frame. 2498 */ 2499 mpt->m_reply_frame_dma_addr = cookie.dmac_laddress; 2500 mpt->m_reply_frame = memp; 2501 2502 /* 2503 * Clear the reply frame pool. 2504 */ 2505 bzero(mpt->m_reply_frame, mem_size); 2506 2507 return (DDI_SUCCESS); 2508 } 2509 2510 static int 2511 mptsas_alloc_free_queue(mptsas_t *mpt) 2512 { 2513 ddi_dma_attr_t frame_dma_attrs; 2514 caddr_t memp; 2515 ddi_dma_cookie_t cookie; 2516 size_t mem_size; 2517 2518 /* 2519 * re-alloc when it has already alloced 2520 */ 2521 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl, 2522 &mpt->m_acc_free_queue_hdl); 2523 2524 /* 2525 * The reply free queue size is: 2526 * Reply Free Queue Depth * 4 2527 * The "4" is the size of one 32 bit address (low part of 64-bit 2528 * address) 2529 */ 2530 mem_size = mpt->m_free_queue_depth * 4; 2531 2532 /* 2533 * set the DMA attributes The Reply Free Queue must be aligned on a 2534 * 16-byte boundry. 2535 */ 2536 frame_dma_attrs = mpt->m_msg_dma_attr; 2537 frame_dma_attrs.dma_attr_align = 16; 2538 frame_dma_attrs.dma_attr_sgllen = 1; 2539 2540 /* 2541 * allocate the reply free queue 2542 */ 2543 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2544 &mpt->m_dma_free_queue_hdl, &mpt->m_acc_free_queue_hdl, &memp, 2545 mem_size, &cookie) == FALSE) { 2546 return (DDI_FAILURE); 2547 } 2548 2549 /* 2550 * Store the reply free queue memory address. This chip uses this 2551 * address to read from the reply free queue. The second address 2552 * is the address mpt uses to manage the queue. 2553 */ 2554 mpt->m_free_queue_dma_addr = cookie.dmac_laddress; 2555 mpt->m_free_queue = memp; 2556 2557 /* 2558 * Clear the reply free queue memory. 2559 */ 2560 bzero(mpt->m_free_queue, mem_size); 2561 2562 return (DDI_SUCCESS); 2563 } 2564 2565 static int 2566 mptsas_alloc_post_queue(mptsas_t *mpt) 2567 { 2568 ddi_dma_attr_t frame_dma_attrs; 2569 caddr_t memp; 2570 ddi_dma_cookie_t cookie; 2571 size_t mem_size; 2572 2573 /* 2574 * re-alloc when it has already alloced 2575 */ 2576 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl, 2577 &mpt->m_acc_post_queue_hdl); 2578 2579 /* 2580 * The reply descriptor post queue size is: 2581 * Reply Descriptor Post Queue Depth * 8 2582 * The "8" is the size of each descriptor (8 bytes or 64 bits). 2583 */ 2584 mem_size = mpt->m_post_queue_depth * 8; 2585 2586 /* 2587 * set the DMA attributes. The Reply Descriptor Post Queue must be 2588 * aligned on a 16-byte boundry. 2589 */ 2590 frame_dma_attrs = mpt->m_msg_dma_attr; 2591 frame_dma_attrs.dma_attr_align = 16; 2592 frame_dma_attrs.dma_attr_sgllen = 1; 2593 2594 /* 2595 * allocate the reply post queue 2596 */ 2597 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2598 &mpt->m_dma_post_queue_hdl, &mpt->m_acc_post_queue_hdl, &memp, 2599 mem_size, &cookie) == FALSE) { 2600 return (DDI_FAILURE); 2601 } 2602 2603 /* 2604 * Store the reply descriptor post queue memory address. This chip 2605 * uses this address to write to the reply descriptor post queue. The 2606 * second address is the address mpt uses to manage the queue. 2607 */ 2608 mpt->m_post_queue_dma_addr = cookie.dmac_laddress; 2609 mpt->m_post_queue = memp; 2610 2611 /* 2612 * Clear the reply post queue memory. 2613 */ 2614 bzero(mpt->m_post_queue, mem_size); 2615 2616 return (DDI_SUCCESS); 2617 } 2618 2619 static void 2620 mptsas_alloc_reply_args(mptsas_t *mpt) 2621 { 2622 if (mpt->m_replyh_args == NULL) { 2623 mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) * 2624 mpt->m_max_replies, KM_SLEEP); 2625 } 2626 } 2627 2628 static int 2629 mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd) 2630 { 2631 mptsas_cache_frames_t *frames = NULL; 2632 if (cmd->cmd_extra_frames == NULL) { 2633 frames = kmem_cache_alloc(mpt->m_cache_frames, KM_NOSLEEP); 2634 if (frames == NULL) { 2635 return (DDI_FAILURE); 2636 } 2637 cmd->cmd_extra_frames = frames; 2638 } 2639 return (DDI_SUCCESS); 2640 } 2641 2642 static void 2643 mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd) 2644 { 2645 if (cmd->cmd_extra_frames) { 2646 kmem_cache_free(mpt->m_cache_frames, 2647 (void *)cmd->cmd_extra_frames); 2648 cmd->cmd_extra_frames = NULL; 2649 } 2650 } 2651 2652 static void 2653 mptsas_cfg_fini(mptsas_t *mpt) 2654 { 2655 NDBG0(("mptsas_cfg_fini")); 2656 ddi_regs_map_free(&mpt->m_datap); 2657 } 2658 2659 static void 2660 mptsas_hba_fini(mptsas_t *mpt) 2661 { 2662 NDBG0(("mptsas_hba_fini")); 2663 2664 /* 2665 * Free up any allocated memory 2666 */ 2667 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl, 2668 &mpt->m_acc_req_frame_hdl); 2669 2670 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl, 2671 &mpt->m_acc_reply_frame_hdl); 2672 2673 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl, 2674 &mpt->m_acc_free_queue_hdl); 2675 2676 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl, 2677 &mpt->m_acc_post_queue_hdl); 2678 2679 if (mpt->m_replyh_args != NULL) { 2680 kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t) 2681 * mpt->m_max_replies); 2682 } 2683 } 2684 2685 static int 2686 mptsas_name_child(dev_info_t *lun_dip, char *name, int len) 2687 { 2688 int lun = 0; 2689 char *sas_wwn = NULL; 2690 int phynum = -1; 2691 int reallen = 0; 2692 2693 /* Get the target num */ 2694 lun = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, DDI_PROP_DONTPASS, 2695 LUN_PROP, 0); 2696 2697 if ((phynum = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, 2698 DDI_PROP_DONTPASS, "sata-phy", -1)) != -1) { 2699 /* 2700 * Stick in the address of form "pPHY,LUN" 2701 */ 2702 reallen = snprintf(name, len, "p%x,%x", phynum, lun); 2703 } else if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lun_dip, 2704 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &sas_wwn) 2705 == DDI_PROP_SUCCESS) { 2706 /* 2707 * Stick in the address of the form "wWWN,LUN" 2708 */ 2709 reallen = snprintf(name, len, "%s,%x", sas_wwn, lun); 2710 ddi_prop_free(sas_wwn); 2711 } else { 2712 return (DDI_FAILURE); 2713 } 2714 2715 ASSERT(reallen < len); 2716 if (reallen >= len) { 2717 mptsas_log(0, CE_WARN, "!mptsas_get_name: name parameter " 2718 "length too small, it needs to be %d bytes", reallen + 1); 2719 } 2720 return (DDI_SUCCESS); 2721 } 2722 2723 /* 2724 * tran_tgt_init(9E) - target device instance initialization 2725 */ 2726 static int 2727 mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 2728 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 2729 { 2730 #ifndef __lock_lint 2731 _NOTE(ARGUNUSED(hba_tran)) 2732 #endif 2733 2734 /* 2735 * At this point, the scsi_device structure already exists 2736 * and has been initialized. 2737 * 2738 * Use this function to allocate target-private data structures, 2739 * if needed by this HBA. Add revised flow-control and queue 2740 * properties for child here, if desired and if you can tell they 2741 * support tagged queueing by now. 2742 */ 2743 mptsas_t *mpt; 2744 int lun = sd->sd_address.a_lun; 2745 mdi_pathinfo_t *pip = NULL; 2746 mptsas_tgt_private_t *tgt_private = NULL; 2747 mptsas_target_t *ptgt = NULL; 2748 char *psas_wwn = NULL; 2749 int phymask = 0; 2750 uint64_t sas_wwn = 0; 2751 mpt = SDEV2MPT(sd); 2752 2753 ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0); 2754 2755 NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d", 2756 (void *)hba_dip, (void *)tgt_dip, lun)); 2757 2758 if (ndi_dev_is_persistent_node(tgt_dip) == 0) { 2759 (void) ndi_merge_node(tgt_dip, mptsas_name_child); 2760 ddi_set_name_addr(tgt_dip, NULL); 2761 return (DDI_FAILURE); 2762 } 2763 /* 2764 * phymask is 0 means the virtual port for RAID 2765 */ 2766 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0, 2767 "phymask", 0); 2768 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) { 2769 if ((pip = (void *)(sd->sd_private)) == NULL) { 2770 /* 2771 * Very bad news if this occurs. Somehow scsi_vhci has 2772 * lost the pathinfo node for this target. 2773 */ 2774 return (DDI_NOT_WELL_FORMED); 2775 } 2776 2777 if (mdi_prop_lookup_int(pip, LUN_PROP, &lun) != 2778 DDI_PROP_SUCCESS) { 2779 mptsas_log(mpt, CE_WARN, "Get lun property failed\n"); 2780 return (DDI_FAILURE); 2781 } 2782 2783 if (mdi_prop_lookup_string(pip, SCSI_ADDR_PROP_TARGET_PORT, 2784 &psas_wwn) == MDI_SUCCESS) { 2785 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) { 2786 sas_wwn = 0; 2787 } 2788 (void) mdi_prop_free(psas_wwn); 2789 } 2790 } else { 2791 lun = ddi_prop_get_int(DDI_DEV_T_ANY, tgt_dip, 2792 DDI_PROP_DONTPASS, LUN_PROP, 0); 2793 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, tgt_dip, 2794 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &psas_wwn) == 2795 DDI_PROP_SUCCESS) { 2796 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) { 2797 sas_wwn = 0; 2798 } 2799 ddi_prop_free(psas_wwn); 2800 } else { 2801 sas_wwn = 0; 2802 } 2803 } 2804 ASSERT((sas_wwn != 0) || (phymask != 0)); 2805 mutex_enter(&mpt->m_mutex); 2806 ptgt = mptsas_hash_search(&mpt->m_active->m_tgttbl, sas_wwn, phymask); 2807 mutex_exit(&mpt->m_mutex); 2808 if (ptgt == NULL) { 2809 mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or " 2810 "gone already! phymask:%x, saswwn %"PRIx64, phymask, 2811 sas_wwn); 2812 return (DDI_FAILURE); 2813 } 2814 if (hba_tran->tran_tgt_private == NULL) { 2815 tgt_private = kmem_zalloc(sizeof (mptsas_tgt_private_t), 2816 KM_SLEEP); 2817 tgt_private->t_lun = lun; 2818 tgt_private->t_private = ptgt; 2819 hba_tran->tran_tgt_private = tgt_private; 2820 } 2821 2822 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) { 2823 return (DDI_SUCCESS); 2824 } 2825 mutex_enter(&mpt->m_mutex); 2826 2827 if (ptgt->m_deviceinfo & 2828 (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 2829 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 2830 uchar_t *inq89 = NULL; 2831 int inq89_len = 0x238; 2832 int reallen = 0; 2833 int rval = 0; 2834 struct sata_id *sid = NULL; 2835 char model[SATA_ID_MODEL_LEN + 1]; 2836 char fw[SATA_ID_FW_LEN + 1]; 2837 char *vid, *pid; 2838 int i; 2839 2840 mutex_exit(&mpt->m_mutex); 2841 /* 2842 * According SCSI/ATA Translation -2 (SAT-2) revision 01a 2843 * chapter 12.4.2 VPD page 89h includes 512 bytes ATA IDENTIFY 2844 * DEVICE data or ATA IDENTIFY PACKET DEVICE data. 2845 */ 2846 inq89 = kmem_zalloc(inq89_len, KM_SLEEP); 2847 rval = mptsas_inquiry(mpt, ptgt, 0, 0x89, 2848 inq89, inq89_len, &reallen, 1); 2849 2850 if (rval != 0) { 2851 if (inq89 != NULL) { 2852 kmem_free(inq89, inq89_len); 2853 } 2854 2855 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 2856 "0x89 for SATA target:%x failed!", ptgt->m_devhdl); 2857 return (DDI_SUCCESS); 2858 } 2859 sid = (void *)(&inq89[60]); 2860 2861 swab(sid->ai_model, model, SATA_ID_MODEL_LEN); 2862 swab(sid->ai_fw, fw, SATA_ID_FW_LEN); 2863 2864 model[SATA_ID_MODEL_LEN] = 0; 2865 fw[SATA_ID_FW_LEN] = 0; 2866 2867 /* 2868 * split model into into vid/pid 2869 */ 2870 for (i = 0, pid = model; i < SATA_ID_MODEL_LEN; i++, pid++) 2871 if ((*pid == ' ') || (*pid == '\t')) 2872 break; 2873 if (i < SATA_ID_MODEL_LEN) { 2874 vid = model; 2875 /* 2876 * terminate vid, establish pid 2877 */ 2878 *pid++ = 0; 2879 } else { 2880 /* 2881 * vid will stay "ATA ", the rule is same 2882 * as sata framework implementation. 2883 */ 2884 vid = NULL; 2885 /* 2886 * model is all pid 2887 */ 2888 pid = model; 2889 } 2890 2891 /* 2892 * override SCSA "inquiry-*" properties 2893 */ 2894 if (vid) 2895 (void) scsi_device_prop_update_inqstring(sd, 2896 INQUIRY_VENDOR_ID, vid, strlen(vid)); 2897 if (pid) 2898 (void) scsi_device_prop_update_inqstring(sd, 2899 INQUIRY_PRODUCT_ID, pid, strlen(pid)); 2900 (void) scsi_device_prop_update_inqstring(sd, 2901 INQUIRY_REVISION_ID, fw, strlen(fw)); 2902 2903 if (inq89 != NULL) { 2904 kmem_free(inq89, inq89_len); 2905 } 2906 } else { 2907 mutex_exit(&mpt->m_mutex); 2908 } 2909 2910 return (DDI_SUCCESS); 2911 } 2912 /* 2913 * tran_tgt_free(9E) - target device instance deallocation 2914 */ 2915 static void 2916 mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 2917 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 2918 { 2919 #ifndef __lock_lint 2920 _NOTE(ARGUNUSED(hba_dip, tgt_dip, hba_tran, sd)) 2921 #endif 2922 2923 mptsas_tgt_private_t *tgt_private = hba_tran->tran_tgt_private; 2924 2925 if (tgt_private != NULL) { 2926 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t)); 2927 hba_tran->tran_tgt_private = NULL; 2928 } 2929 } 2930 2931 /* 2932 * scsi_pkt handling 2933 * 2934 * Visible to the external world via the transport structure. 2935 */ 2936 2937 /* 2938 * Notes: 2939 * - transport the command to the addressed SCSI target/lun device 2940 * - normal operation is to schedule the command to be transported, 2941 * and return TRAN_ACCEPT if this is successful. 2942 * - if NO_INTR, tran_start must poll device for command completion 2943 */ 2944 static int 2945 mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt) 2946 { 2947 #ifndef __lock_lint 2948 _NOTE(ARGUNUSED(ap)) 2949 #endif 2950 mptsas_t *mpt = PKT2MPT(pkt); 2951 mptsas_cmd_t *cmd = PKT2CMD(pkt); 2952 int rval; 2953 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 2954 2955 NDBG1(("mptsas_scsi_start: pkt=0x%p", (void *)pkt)); 2956 ASSERT(ptgt); 2957 if (ptgt == NULL) 2958 return (TRAN_FATAL_ERROR); 2959 2960 /* 2961 * prepare the pkt before taking mutex. 2962 */ 2963 rval = mptsas_prepare_pkt(cmd); 2964 if (rval != TRAN_ACCEPT) { 2965 return (rval); 2966 } 2967 2968 /* 2969 * Send the command to target/lun, however your HBA requires it. 2970 * If busy, return TRAN_BUSY; if there's some other formatting error 2971 * in the packet, return TRAN_BADPKT; otherwise, fall through to the 2972 * return of TRAN_ACCEPT. 2973 * 2974 * Remember that access to shared resources, including the mptsas_t 2975 * data structure and the HBA hardware registers, must be protected 2976 * with mutexes, here and everywhere. 2977 * 2978 * Also remember that at interrupt time, you'll get an argument 2979 * to the interrupt handler which is a pointer to your mptsas_t 2980 * structure; you'll have to remember which commands are outstanding 2981 * and which scsi_pkt is the currently-running command so the 2982 * interrupt handler can refer to the pkt to set completion 2983 * status, call the target driver back through pkt_comp, etc. 2984 * 2985 * If the instance lock is held by other thread, don't spin to wait 2986 * for it. Instead, queue the cmd and next time when the instance lock 2987 * is not held, accept all the queued cmd. A extra tx_waitq is 2988 * introduced to protect the queue. 2989 * 2990 * The polled cmd will not be queud and accepted as usual. 2991 * 2992 * Under the tx_waitq mutex, record whether a thread is draining 2993 * the tx_waitq. An IO requesting thread that finds the instance 2994 * mutex contended appends to the tx_waitq and while holding the 2995 * tx_wait mutex, if the draining flag is not set, sets it and then 2996 * proceeds to spin for the instance mutex. This scheme ensures that 2997 * the last cmd in a burst be processed. 2998 * 2999 * we enable this feature only when the helper threads are enabled, 3000 * at which we think the loads are heavy. 3001 * 3002 * per instance mutex m_tx_waitq_mutex is introduced to protect the 3003 * m_tx_waitqtail, m_tx_waitq, m_tx_draining. 3004 */ 3005 3006 if (mpt->m_doneq_thread_n) { 3007 if (mutex_tryenter(&mpt->m_mutex) != 0) { 3008 rval = mptsas_accept_txwq_and_pkt(mpt, cmd); 3009 mutex_exit(&mpt->m_mutex); 3010 } else if (cmd->cmd_pkt_flags & FLAG_NOINTR) { 3011 mutex_enter(&mpt->m_mutex); 3012 rval = mptsas_accept_txwq_and_pkt(mpt, cmd); 3013 mutex_exit(&mpt->m_mutex); 3014 } else { 3015 mutex_enter(&mpt->m_tx_waitq_mutex); 3016 /* 3017 * ptgt->m_dr_flag is protected by m_mutex or 3018 * m_tx_waitq_mutex. In this case, m_tx_waitq_mutex 3019 * is acquired. 3020 */ 3021 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3022 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3023 /* 3024 * The command should be allowed to 3025 * retry by returning TRAN_BUSY to 3026 * to stall the I/O's which come from 3027 * scsi_vhci since the device/path is 3028 * in unstable state now. 3029 */ 3030 mutex_exit(&mpt->m_tx_waitq_mutex); 3031 return (TRAN_BUSY); 3032 } else { 3033 /* 3034 * The device is offline, just fail the 3035 * command by returning 3036 * TRAN_FATAL_ERROR. 3037 */ 3038 mutex_exit(&mpt->m_tx_waitq_mutex); 3039 return (TRAN_FATAL_ERROR); 3040 } 3041 } 3042 if (mpt->m_tx_draining) { 3043 cmd->cmd_flags |= CFLAG_TXQ; 3044 *mpt->m_tx_waitqtail = cmd; 3045 mpt->m_tx_waitqtail = &cmd->cmd_linkp; 3046 mutex_exit(&mpt->m_tx_waitq_mutex); 3047 } else { /* drain the queue */ 3048 mpt->m_tx_draining = 1; 3049 mutex_exit(&mpt->m_tx_waitq_mutex); 3050 mutex_enter(&mpt->m_mutex); 3051 rval = mptsas_accept_txwq_and_pkt(mpt, cmd); 3052 mutex_exit(&mpt->m_mutex); 3053 } 3054 } 3055 } else { 3056 mutex_enter(&mpt->m_mutex); 3057 /* 3058 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex 3059 * in this case, m_mutex is acquired. 3060 */ 3061 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3062 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3063 /* 3064 * commands should be allowed to retry by 3065 * returning TRAN_BUSY to stall the I/O's 3066 * which come from scsi_vhci since the device/ 3067 * path is in unstable state now. 3068 */ 3069 mutex_exit(&mpt->m_mutex); 3070 return (TRAN_BUSY); 3071 } else { 3072 /* 3073 * The device is offline, just fail the 3074 * command by returning TRAN_FATAL_ERROR. 3075 */ 3076 mutex_exit(&mpt->m_mutex); 3077 return (TRAN_FATAL_ERROR); 3078 } 3079 } 3080 rval = mptsas_accept_pkt(mpt, cmd); 3081 mutex_exit(&mpt->m_mutex); 3082 } 3083 3084 return (rval); 3085 } 3086 3087 /* 3088 * Accept all the queued cmds(if any) before accept the current one. 3089 */ 3090 static int 3091 mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd) 3092 { 3093 int rval; 3094 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3095 3096 ASSERT(mutex_owned(&mpt->m_mutex)); 3097 /* 3098 * The call to mptsas_accept_tx_waitq() must always be performed 3099 * because that is where mpt->m_tx_draining is cleared. 3100 */ 3101 mutex_enter(&mpt->m_tx_waitq_mutex); 3102 mptsas_accept_tx_waitq(mpt); 3103 mutex_exit(&mpt->m_tx_waitq_mutex); 3104 /* 3105 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex 3106 * in this case, m_mutex is acquired. 3107 */ 3108 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3109 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3110 /* 3111 * The command should be allowed to retry by returning 3112 * TRAN_BUSY to stall the I/O's which come from 3113 * scsi_vhci since the device/path is in unstable state 3114 * now. 3115 */ 3116 return (TRAN_BUSY); 3117 } else { 3118 /* 3119 * The device is offline, just fail the command by 3120 * return TRAN_FATAL_ERROR. 3121 */ 3122 return (TRAN_FATAL_ERROR); 3123 } 3124 } 3125 rval = mptsas_accept_pkt(mpt, cmd); 3126 3127 return (rval); 3128 } 3129 3130 static int 3131 mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd) 3132 { 3133 int rval = TRAN_ACCEPT; 3134 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3135 3136 NDBG1(("mptsas_accept_pkt: cmd=0x%p", (void *)cmd)); 3137 3138 ASSERT(mutex_owned(&mpt->m_mutex)); 3139 3140 if ((cmd->cmd_flags & CFLAG_PREPARED) == 0) { 3141 rval = mptsas_prepare_pkt(cmd); 3142 if (rval != TRAN_ACCEPT) { 3143 cmd->cmd_flags &= ~CFLAG_TRANFLAG; 3144 return (rval); 3145 } 3146 } 3147 3148 /* 3149 * reset the throttle if we were draining 3150 */ 3151 if ((ptgt->m_t_ncmds == 0) && 3152 (ptgt->m_t_throttle == DRAIN_THROTTLE)) { 3153 NDBG23(("reset throttle")); 3154 ASSERT(ptgt->m_reset_delay == 0); 3155 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 3156 } 3157 3158 /* 3159 * If HBA is being reset, the DevHandles are being re-initialized, 3160 * which means that they could be invalid even if the target is still 3161 * attached. Check if being reset and if DevHandle is being 3162 * re-initialized. If this is the case, return BUSY so the I/O can be 3163 * retried later. 3164 */ 3165 if ((ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) && mpt->m_in_reset) { 3166 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 3167 if (cmd->cmd_flags & CFLAG_TXQ) { 3168 mptsas_doneq_add(mpt, cmd); 3169 mptsas_doneq_empty(mpt); 3170 return (rval); 3171 } else { 3172 return (TRAN_BUSY); 3173 } 3174 } 3175 3176 /* 3177 * If device handle has already been invalidated, just 3178 * fail the command. In theory, command from scsi_vhci 3179 * client is impossible send down command with invalid 3180 * devhdl since devhdl is set after path offline, target 3181 * driver is not suppose to select a offlined path. 3182 */ 3183 if (ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) { 3184 NDBG20(("rejecting command, it might because invalid devhdl " 3185 "request.")); 3186 mptsas_set_pkt_reason(mpt, cmd, CMD_DEV_GONE, STAT_TERMINATED); 3187 if (cmd->cmd_flags & CFLAG_TXQ) { 3188 mptsas_doneq_add(mpt, cmd); 3189 mptsas_doneq_empty(mpt); 3190 return (rval); 3191 } else { 3192 return (TRAN_FATAL_ERROR); 3193 } 3194 } 3195 /* 3196 * The first case is the normal case. mpt gets a command from the 3197 * target driver and starts it. 3198 * Since SMID 0 is reserved and the TM slot is reserved, the actual max 3199 * commands is m_max_requests - 2. 3200 */ 3201 if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) && 3202 (ptgt->m_t_throttle > HOLD_THROTTLE) && 3203 (ptgt->m_t_ncmds < ptgt->m_t_throttle) && 3204 (ptgt->m_reset_delay == 0) && 3205 (ptgt->m_t_nwait == 0) && 3206 ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0)) { 3207 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 3208 (void) mptsas_start_cmd(mpt, cmd); 3209 } else { 3210 mptsas_waitq_add(mpt, cmd); 3211 } 3212 } else { 3213 /* 3214 * Add this pkt to the work queue 3215 */ 3216 mptsas_waitq_add(mpt, cmd); 3217 3218 if (cmd->cmd_pkt_flags & FLAG_NOINTR) { 3219 (void) mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME); 3220 3221 /* 3222 * Only flush the doneq if this is not a TM 3223 * cmd. For TM cmds the flushing of the 3224 * doneq will be done in those routines. 3225 */ 3226 if ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) { 3227 mptsas_doneq_empty(mpt); 3228 } 3229 } 3230 } 3231 return (rval); 3232 } 3233 3234 int 3235 mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 3236 { 3237 mptsas_slots_t *slots; 3238 int slot; 3239 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3240 3241 ASSERT(mutex_owned(&mpt->m_mutex)); 3242 slots = mpt->m_active; 3243 3244 /* 3245 * Account for reserved TM request slot and reserved SMID of 0. 3246 */ 3247 ASSERT(slots->m_n_slots == (mpt->m_max_requests - 2)); 3248 3249 /* 3250 * m_tags is equivalent to the SMID when sending requests. Since the 3251 * SMID cannot be 0, start out at one if rolling over past the size 3252 * of the request queue depth. Also, don't use the last SMID, which is 3253 * reserved for TM requests. 3254 */ 3255 slot = (slots->m_tags)++; 3256 if (slots->m_tags > slots->m_n_slots) { 3257 slots->m_tags = 1; 3258 } 3259 3260 alloc_tag: 3261 /* Validate tag, should never fail. */ 3262 if (slots->m_slot[slot] == NULL) { 3263 /* 3264 * Make sure SMID is not using reserved value of 0 3265 * and the TM request slot. 3266 */ 3267 ASSERT((slot > 0) && (slot <= slots->m_n_slots)); 3268 cmd->cmd_slot = slot; 3269 slots->m_slot[slot] = cmd; 3270 mpt->m_ncmds++; 3271 3272 /* 3273 * only increment per target ncmds if this is not a 3274 * command that has no target associated with it (i.e. a 3275 * event acknoledgment) 3276 */ 3277 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 3278 ptgt->m_t_ncmds++; 3279 } 3280 cmd->cmd_active_timeout = cmd->cmd_pkt->pkt_time; 3281 3282 /* 3283 * If initial timout is less than or equal to one tick, bump 3284 * the timeout by a tick so that command doesn't timeout before 3285 * its allotted time. 3286 */ 3287 if (cmd->cmd_active_timeout <= mptsas_scsi_watchdog_tick) { 3288 cmd->cmd_active_timeout += mptsas_scsi_watchdog_tick; 3289 } 3290 return (TRUE); 3291 } else { 3292 int i; 3293 3294 /* 3295 * If slot in use, scan until a free one is found. Don't use 0 3296 * or final slot, which is reserved for TM requests. 3297 */ 3298 for (i = 0; i < slots->m_n_slots; i++) { 3299 slot = slots->m_tags; 3300 if (++(slots->m_tags) > slots->m_n_slots) { 3301 slots->m_tags = 1; 3302 } 3303 if (slots->m_slot[slot] == NULL) { 3304 NDBG22(("found free slot %d", slot)); 3305 goto alloc_tag; 3306 } 3307 } 3308 } 3309 return (FALSE); 3310 } 3311 3312 /* 3313 * prepare the pkt: 3314 * the pkt may have been resubmitted or just reused so 3315 * initialize some fields and do some checks. 3316 */ 3317 static int 3318 mptsas_prepare_pkt(mptsas_cmd_t *cmd) 3319 { 3320 struct scsi_pkt *pkt = CMD2PKT(cmd); 3321 3322 NDBG1(("mptsas_prepare_pkt: cmd=0x%p", (void *)cmd)); 3323 3324 /* 3325 * Reinitialize some fields that need it; the packet may 3326 * have been resubmitted 3327 */ 3328 pkt->pkt_reason = CMD_CMPLT; 3329 pkt->pkt_state = 0; 3330 pkt->pkt_statistics = 0; 3331 pkt->pkt_resid = 0; 3332 cmd->cmd_age = 0; 3333 cmd->cmd_pkt_flags = pkt->pkt_flags; 3334 3335 /* 3336 * zero status byte. 3337 */ 3338 *(pkt->pkt_scbp) = 0; 3339 3340 if (cmd->cmd_flags & CFLAG_DMAVALID) { 3341 pkt->pkt_resid = cmd->cmd_dmacount; 3342 3343 /* 3344 * consistent packets need to be sync'ed first 3345 * (only for data going out) 3346 */ 3347 if ((cmd->cmd_flags & CFLAG_CMDIOPB) && 3348 (cmd->cmd_flags & CFLAG_DMASEND)) { 3349 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 3350 DDI_DMA_SYNC_FORDEV); 3351 } 3352 } 3353 3354 cmd->cmd_flags = 3355 (cmd->cmd_flags & ~(CFLAG_TRANFLAG)) | 3356 CFLAG_PREPARED | CFLAG_IN_TRANSPORT; 3357 3358 return (TRAN_ACCEPT); 3359 } 3360 3361 /* 3362 * tran_init_pkt(9E) - allocate scsi_pkt(9S) for command 3363 * 3364 * One of three possibilities: 3365 * - allocate scsi_pkt 3366 * - allocate scsi_pkt and DMA resources 3367 * - allocate DMA resources to an already-allocated pkt 3368 */ 3369 static struct scsi_pkt * 3370 mptsas_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt, 3371 struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags, 3372 int (*callback)(), caddr_t arg) 3373 { 3374 mptsas_cmd_t *cmd, *new_cmd; 3375 mptsas_t *mpt = ADDR2MPT(ap); 3376 int failure = 1; 3377 uint_t oldcookiec; 3378 mptsas_target_t *ptgt = NULL; 3379 int rval; 3380 mptsas_tgt_private_t *tgt_private; 3381 int kf; 3382 3383 kf = (callback == SLEEP_FUNC)? KM_SLEEP: KM_NOSLEEP; 3384 3385 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran-> 3386 tran_tgt_private; 3387 ASSERT(tgt_private != NULL); 3388 if (tgt_private == NULL) { 3389 return (NULL); 3390 } 3391 ptgt = tgt_private->t_private; 3392 ASSERT(ptgt != NULL); 3393 if (ptgt == NULL) 3394 return (NULL); 3395 ap->a_target = ptgt->m_devhdl; 3396 ap->a_lun = tgt_private->t_lun; 3397 3398 ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC); 3399 #ifdef MPTSAS_TEST_EXTRN_ALLOC 3400 statuslen *= 100; tgtlen *= 4; 3401 #endif 3402 NDBG3(("mptsas_scsi_init_pkt:\n" 3403 "\ttgt=%d in=0x%p bp=0x%p clen=%d slen=%d tlen=%d flags=%x", 3404 ap->a_target, (void *)pkt, (void *)bp, 3405 cmdlen, statuslen, tgtlen, flags)); 3406 3407 /* 3408 * Allocate the new packet. 3409 */ 3410 if (pkt == NULL) { 3411 ddi_dma_handle_t save_dma_handle; 3412 ddi_dma_handle_t save_arq_dma_handle; 3413 struct buf *save_arq_bp; 3414 ddi_dma_cookie_t save_arqcookie; 3415 3416 cmd = kmem_cache_alloc(mpt->m_kmem_cache, kf); 3417 3418 if (cmd) { 3419 save_dma_handle = cmd->cmd_dmahandle; 3420 save_arq_dma_handle = cmd->cmd_arqhandle; 3421 save_arq_bp = cmd->cmd_arq_buf; 3422 save_arqcookie = cmd->cmd_arqcookie; 3423 bzero(cmd, sizeof (*cmd) + scsi_pkt_size()); 3424 cmd->cmd_dmahandle = save_dma_handle; 3425 cmd->cmd_arqhandle = save_arq_dma_handle; 3426 cmd->cmd_arq_buf = save_arq_bp; 3427 cmd->cmd_arqcookie = save_arqcookie; 3428 3429 pkt = (void *)((uchar_t *)cmd + 3430 sizeof (struct mptsas_cmd)); 3431 pkt->pkt_ha_private = (opaque_t)cmd; 3432 pkt->pkt_address = *ap; 3433 pkt->pkt_private = (opaque_t)cmd->cmd_pkt_private; 3434 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; 3435 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb; 3436 cmd->cmd_pkt = (struct scsi_pkt *)pkt; 3437 cmd->cmd_cdblen = (uchar_t)cmdlen; 3438 cmd->cmd_scblen = statuslen; 3439 cmd->cmd_rqslen = SENSE_LENGTH; 3440 cmd->cmd_tgt_addr = ptgt; 3441 failure = 0; 3442 } 3443 3444 if (failure || (cmdlen > sizeof (cmd->cmd_cdb)) || 3445 (tgtlen > PKT_PRIV_LEN) || 3446 (statuslen > EXTCMDS_STATUS_SIZE)) { 3447 if (failure == 0) { 3448 /* 3449 * if extern alloc fails, all will be 3450 * deallocated, including cmd 3451 */ 3452 failure = mptsas_pkt_alloc_extern(mpt, cmd, 3453 cmdlen, tgtlen, statuslen, kf); 3454 } 3455 if (failure) { 3456 /* 3457 * if extern allocation fails, it will 3458 * deallocate the new pkt as well 3459 */ 3460 return (NULL); 3461 } 3462 } 3463 new_cmd = cmd; 3464 3465 } else { 3466 cmd = PKT2CMD(pkt); 3467 new_cmd = NULL; 3468 } 3469 3470 3471 /* grab cmd->cmd_cookiec here as oldcookiec */ 3472 3473 oldcookiec = cmd->cmd_cookiec; 3474 3475 /* 3476 * If the dma was broken up into PARTIAL transfers cmd_nwin will be 3477 * greater than 0 and we'll need to grab the next dma window 3478 */ 3479 /* 3480 * SLM-not doing extra command frame right now; may add later 3481 */ 3482 3483 if (cmd->cmd_nwin > 0) { 3484 3485 /* 3486 * Make sure we havn't gone past the the total number 3487 * of windows 3488 */ 3489 if (++cmd->cmd_winindex >= cmd->cmd_nwin) { 3490 return (NULL); 3491 } 3492 if (ddi_dma_getwin(cmd->cmd_dmahandle, cmd->cmd_winindex, 3493 &cmd->cmd_dma_offset, &cmd->cmd_dma_len, 3494 &cmd->cmd_cookie, &cmd->cmd_cookiec) == DDI_FAILURE) { 3495 return (NULL); 3496 } 3497 goto get_dma_cookies; 3498 } 3499 3500 3501 if (flags & PKT_XARQ) { 3502 cmd->cmd_flags |= CFLAG_XARQ; 3503 } 3504 3505 /* 3506 * DMA resource allocation. This version assumes your 3507 * HBA has some sort of bus-mastering or onboard DMA capability, with a 3508 * scatter-gather list of length MPTSAS_MAX_DMA_SEGS, as given in the 3509 * ddi_dma_attr_t structure and passed to scsi_impl_dmaget. 3510 */ 3511 if (bp && (bp->b_bcount != 0) && 3512 (cmd->cmd_flags & CFLAG_DMAVALID) == 0) { 3513 3514 int cnt, dma_flags; 3515 mptti_t *dmap; /* ptr to the S/G list */ 3516 3517 /* 3518 * Set up DMA memory and position to the next DMA segment. 3519 */ 3520 ASSERT(cmd->cmd_dmahandle != NULL); 3521 3522 if (bp->b_flags & B_READ) { 3523 dma_flags = DDI_DMA_READ; 3524 cmd->cmd_flags &= ~CFLAG_DMASEND; 3525 } else { 3526 dma_flags = DDI_DMA_WRITE; 3527 cmd->cmd_flags |= CFLAG_DMASEND; 3528 } 3529 if (flags & PKT_CONSISTENT) { 3530 cmd->cmd_flags |= CFLAG_CMDIOPB; 3531 dma_flags |= DDI_DMA_CONSISTENT; 3532 } 3533 3534 if (flags & PKT_DMA_PARTIAL) { 3535 dma_flags |= DDI_DMA_PARTIAL; 3536 } 3537 3538 /* 3539 * workaround for byte hole issue on psycho and 3540 * schizo pre 2.1 3541 */ 3542 if ((bp->b_flags & B_READ) && ((bp->b_flags & 3543 (B_PAGEIO|B_REMAPPED)) != B_PAGEIO) && 3544 ((uintptr_t)bp->b_un.b_addr & 0x7)) { 3545 dma_flags |= DDI_DMA_CONSISTENT; 3546 } 3547 3548 rval = ddi_dma_buf_bind_handle(cmd->cmd_dmahandle, bp, 3549 dma_flags, callback, arg, 3550 &cmd->cmd_cookie, &cmd->cmd_cookiec); 3551 if (rval == DDI_DMA_PARTIAL_MAP) { 3552 (void) ddi_dma_numwin(cmd->cmd_dmahandle, 3553 &cmd->cmd_nwin); 3554 cmd->cmd_winindex = 0; 3555 (void) ddi_dma_getwin(cmd->cmd_dmahandle, 3556 cmd->cmd_winindex, &cmd->cmd_dma_offset, 3557 &cmd->cmd_dma_len, &cmd->cmd_cookie, 3558 &cmd->cmd_cookiec); 3559 } else if (rval && (rval != DDI_DMA_MAPPED)) { 3560 switch (rval) { 3561 case DDI_DMA_NORESOURCES: 3562 bioerror(bp, 0); 3563 break; 3564 case DDI_DMA_BADATTR: 3565 case DDI_DMA_NOMAPPING: 3566 bioerror(bp, EFAULT); 3567 break; 3568 case DDI_DMA_TOOBIG: 3569 default: 3570 bioerror(bp, EINVAL); 3571 break; 3572 } 3573 cmd->cmd_flags &= ~CFLAG_DMAVALID; 3574 if (new_cmd) { 3575 mptsas_scsi_destroy_pkt(ap, pkt); 3576 } 3577 return ((struct scsi_pkt *)NULL); 3578 } 3579 3580 get_dma_cookies: 3581 cmd->cmd_flags |= CFLAG_DMAVALID; 3582 ASSERT(cmd->cmd_cookiec > 0); 3583 3584 if (cmd->cmd_cookiec > MPTSAS_MAX_CMD_SEGS) { 3585 mptsas_log(mpt, CE_NOTE, "large cookiec received %d\n", 3586 cmd->cmd_cookiec); 3587 bioerror(bp, EINVAL); 3588 if (new_cmd) { 3589 mptsas_scsi_destroy_pkt(ap, pkt); 3590 } 3591 return ((struct scsi_pkt *)NULL); 3592 } 3593 3594 /* 3595 * Allocate extra SGL buffer if needed. 3596 */ 3597 if ((cmd->cmd_cookiec > MPTSAS_MAX_FRAME_SGES64(mpt)) && 3598 (cmd->cmd_extra_frames == NULL)) { 3599 if (mptsas_alloc_extra_sgl_frame(mpt, cmd) == 3600 DDI_FAILURE) { 3601 mptsas_log(mpt, CE_WARN, "MPT SGL mem alloc " 3602 "failed"); 3603 bioerror(bp, ENOMEM); 3604 if (new_cmd) { 3605 mptsas_scsi_destroy_pkt(ap, pkt); 3606 } 3607 return ((struct scsi_pkt *)NULL); 3608 } 3609 } 3610 3611 /* 3612 * Always use scatter-gather transfer 3613 * Use the loop below to store physical addresses of 3614 * DMA segments, from the DMA cookies, into your HBA's 3615 * scatter-gather list. 3616 * We need to ensure we have enough kmem alloc'd 3617 * for the sg entries since we are no longer using an 3618 * array inside mptsas_cmd_t. 3619 * 3620 * We check cmd->cmd_cookiec against oldcookiec so 3621 * the scatter-gather list is correctly allocated 3622 */ 3623 3624 if (oldcookiec != cmd->cmd_cookiec) { 3625 if (cmd->cmd_sg != (mptti_t *)NULL) { 3626 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * 3627 oldcookiec); 3628 cmd->cmd_sg = NULL; 3629 } 3630 } 3631 3632 if (cmd->cmd_sg == (mptti_t *)NULL) { 3633 cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)* 3634 cmd->cmd_cookiec), kf); 3635 3636 if (cmd->cmd_sg == (mptti_t *)NULL) { 3637 mptsas_log(mpt, CE_WARN, 3638 "unable to kmem_alloc enough memory " 3639 "for scatter/gather list"); 3640 /* 3641 * if we have an ENOMEM condition we need to behave 3642 * the same way as the rest of this routine 3643 */ 3644 3645 bioerror(bp, ENOMEM); 3646 if (new_cmd) { 3647 mptsas_scsi_destroy_pkt(ap, pkt); 3648 } 3649 return ((struct scsi_pkt *)NULL); 3650 } 3651 } 3652 3653 dmap = cmd->cmd_sg; 3654 3655 ASSERT(cmd->cmd_cookie.dmac_size != 0); 3656 3657 /* 3658 * store the first segment into the S/G list 3659 */ 3660 dmap->count = cmd->cmd_cookie.dmac_size; 3661 dmap->addr.address64.Low = (uint32_t) 3662 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull); 3663 dmap->addr.address64.High = (uint32_t) 3664 (cmd->cmd_cookie.dmac_laddress >> 32); 3665 3666 /* 3667 * dmacount counts the size of the dma for this window 3668 * (if partial dma is being used). totaldmacount 3669 * keeps track of the total amount of dma we have 3670 * transferred for all the windows (needed to calculate 3671 * the resid value below). 3672 */ 3673 cmd->cmd_dmacount = cmd->cmd_cookie.dmac_size; 3674 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size; 3675 3676 /* 3677 * We already stored the first DMA scatter gather segment, 3678 * start at 1 if we need to store more. 3679 */ 3680 for (cnt = 1; cnt < cmd->cmd_cookiec; cnt++) { 3681 /* 3682 * Get next DMA cookie 3683 */ 3684 ddi_dma_nextcookie(cmd->cmd_dmahandle, 3685 &cmd->cmd_cookie); 3686 dmap++; 3687 3688 cmd->cmd_dmacount += cmd->cmd_cookie.dmac_size; 3689 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size; 3690 3691 /* 3692 * store the segment parms into the S/G list 3693 */ 3694 dmap->count = cmd->cmd_cookie.dmac_size; 3695 dmap->addr.address64.Low = (uint32_t) 3696 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull); 3697 dmap->addr.address64.High = (uint32_t) 3698 (cmd->cmd_cookie.dmac_laddress >> 32); 3699 } 3700 3701 /* 3702 * If this was partially allocated we set the resid 3703 * the amount of data NOT transferred in this window 3704 * If there is only one window, the resid will be 0 3705 */ 3706 pkt->pkt_resid = (bp->b_bcount - cmd->cmd_totaldmacount); 3707 NDBG16(("mptsas_dmaget: cmd_dmacount=%d.", cmd->cmd_dmacount)); 3708 } 3709 return (pkt); 3710 } 3711 3712 /* 3713 * tran_destroy_pkt(9E) - scsi_pkt(9s) deallocation 3714 * 3715 * Notes: 3716 * - also frees DMA resources if allocated 3717 * - implicit DMA synchonization 3718 */ 3719 static void 3720 mptsas_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 3721 { 3722 mptsas_cmd_t *cmd = PKT2CMD(pkt); 3723 mptsas_t *mpt = ADDR2MPT(ap); 3724 3725 NDBG3(("mptsas_scsi_destroy_pkt: target=%d pkt=0x%p", 3726 ap->a_target, (void *)pkt)); 3727 3728 if (cmd->cmd_flags & CFLAG_DMAVALID) { 3729 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle); 3730 cmd->cmd_flags &= ~CFLAG_DMAVALID; 3731 } 3732 3733 if (cmd->cmd_sg) { 3734 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * cmd->cmd_cookiec); 3735 cmd->cmd_sg = NULL; 3736 } 3737 3738 mptsas_free_extra_sgl_frame(mpt, cmd); 3739 3740 if ((cmd->cmd_flags & 3741 (CFLAG_FREE | CFLAG_CDBEXTERN | CFLAG_PRIVEXTERN | 3742 CFLAG_SCBEXTERN)) == 0) { 3743 cmd->cmd_flags = CFLAG_FREE; 3744 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd); 3745 } else { 3746 mptsas_pkt_destroy_extern(mpt, cmd); 3747 } 3748 } 3749 3750 /* 3751 * kmem cache constructor and destructor: 3752 * When constructing, we bzero the cmd and allocate the dma handle 3753 * When destructing, just free the dma handle 3754 */ 3755 static int 3756 mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags) 3757 { 3758 mptsas_cmd_t *cmd = buf; 3759 mptsas_t *mpt = cdrarg; 3760 struct scsi_address ap; 3761 uint_t cookiec; 3762 ddi_dma_attr_t arq_dma_attr; 3763 int (*callback)(caddr_t); 3764 3765 callback = (kmflags == KM_SLEEP)? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT; 3766 3767 NDBG4(("mptsas_kmem_cache_constructor")); 3768 3769 ap.a_hba_tran = mpt->m_tran; 3770 ap.a_target = 0; 3771 ap.a_lun = 0; 3772 3773 /* 3774 * allocate a dma handle 3775 */ 3776 if ((ddi_dma_alloc_handle(mpt->m_dip, &mpt->m_io_dma_attr, callback, 3777 NULL, &cmd->cmd_dmahandle)) != DDI_SUCCESS) { 3778 cmd->cmd_dmahandle = NULL; 3779 return (-1); 3780 } 3781 3782 cmd->cmd_arq_buf = scsi_alloc_consistent_buf(&ap, (struct buf *)NULL, 3783 SENSE_LENGTH, B_READ, callback, NULL); 3784 if (cmd->cmd_arq_buf == NULL) { 3785 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3786 cmd->cmd_dmahandle = NULL; 3787 return (-1); 3788 } 3789 3790 /* 3791 * allocate a arq handle 3792 */ 3793 arq_dma_attr = mpt->m_msg_dma_attr; 3794 arq_dma_attr.dma_attr_sgllen = 1; 3795 if ((ddi_dma_alloc_handle(mpt->m_dip, &arq_dma_attr, callback, 3796 NULL, &cmd->cmd_arqhandle)) != DDI_SUCCESS) { 3797 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3798 scsi_free_consistent_buf(cmd->cmd_arq_buf); 3799 cmd->cmd_dmahandle = NULL; 3800 cmd->cmd_arqhandle = NULL; 3801 return (-1); 3802 } 3803 3804 if (ddi_dma_buf_bind_handle(cmd->cmd_arqhandle, 3805 cmd->cmd_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT), 3806 callback, NULL, &cmd->cmd_arqcookie, &cookiec) != DDI_SUCCESS) { 3807 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3808 ddi_dma_free_handle(&cmd->cmd_arqhandle); 3809 scsi_free_consistent_buf(cmd->cmd_arq_buf); 3810 cmd->cmd_dmahandle = NULL; 3811 cmd->cmd_arqhandle = NULL; 3812 cmd->cmd_arq_buf = NULL; 3813 return (-1); 3814 } 3815 3816 return (0); 3817 } 3818 3819 static void 3820 mptsas_kmem_cache_destructor(void *buf, void *cdrarg) 3821 { 3822 #ifndef __lock_lint 3823 _NOTE(ARGUNUSED(cdrarg)) 3824 #endif 3825 mptsas_cmd_t *cmd = buf; 3826 3827 NDBG4(("mptsas_kmem_cache_destructor")); 3828 3829 if (cmd->cmd_arqhandle) { 3830 (void) ddi_dma_unbind_handle(cmd->cmd_arqhandle); 3831 ddi_dma_free_handle(&cmd->cmd_arqhandle); 3832 cmd->cmd_arqhandle = NULL; 3833 } 3834 if (cmd->cmd_arq_buf) { 3835 scsi_free_consistent_buf(cmd->cmd_arq_buf); 3836 cmd->cmd_arq_buf = NULL; 3837 } 3838 if (cmd->cmd_dmahandle) { 3839 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3840 cmd->cmd_dmahandle = NULL; 3841 } 3842 } 3843 3844 static int 3845 mptsas_cache_frames_constructor(void *buf, void *cdrarg, int kmflags) 3846 { 3847 mptsas_cache_frames_t *p = buf; 3848 mptsas_t *mpt = cdrarg; 3849 ddi_dma_attr_t frame_dma_attr; 3850 size_t mem_size, alloc_len; 3851 ddi_dma_cookie_t cookie; 3852 uint_t ncookie; 3853 int (*callback)(caddr_t) = (kmflags == KM_SLEEP) 3854 ? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT; 3855 3856 frame_dma_attr = mpt->m_msg_dma_attr; 3857 frame_dma_attr.dma_attr_align = 0x10; 3858 frame_dma_attr.dma_attr_sgllen = 1; 3859 3860 if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attr, callback, NULL, 3861 &p->m_dma_hdl) != DDI_SUCCESS) { 3862 mptsas_log(mpt, CE_WARN, "Unable to allocate dma handle for" 3863 " extra SGL."); 3864 return (DDI_FAILURE); 3865 } 3866 3867 mem_size = (mpt->m_max_request_frames - 1) * mpt->m_req_frame_size; 3868 3869 if (ddi_dma_mem_alloc(p->m_dma_hdl, mem_size, &mpt->m_dev_acc_attr, 3870 DDI_DMA_CONSISTENT, callback, NULL, (caddr_t *)&p->m_frames_addr, 3871 &alloc_len, &p->m_acc_hdl) != DDI_SUCCESS) { 3872 ddi_dma_free_handle(&p->m_dma_hdl); 3873 p->m_dma_hdl = NULL; 3874 mptsas_log(mpt, CE_WARN, "Unable to allocate dma memory for" 3875 " extra SGL."); 3876 return (DDI_FAILURE); 3877 } 3878 3879 if (ddi_dma_addr_bind_handle(p->m_dma_hdl, NULL, p->m_frames_addr, 3880 alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, callback, NULL, 3881 &cookie, &ncookie) != DDI_DMA_MAPPED) { 3882 (void) ddi_dma_mem_free(&p->m_acc_hdl); 3883 ddi_dma_free_handle(&p->m_dma_hdl); 3884 p->m_dma_hdl = NULL; 3885 mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources for" 3886 " extra SGL"); 3887 return (DDI_FAILURE); 3888 } 3889 3890 /* 3891 * Store the SGL memory address. This chip uses this 3892 * address to dma to and from the driver. The second 3893 * address is the address mpt uses to fill in the SGL. 3894 */ 3895 p->m_phys_addr = cookie.dmac_address; 3896 3897 return (DDI_SUCCESS); 3898 } 3899 3900 static void 3901 mptsas_cache_frames_destructor(void *buf, void *cdrarg) 3902 { 3903 #ifndef __lock_lint 3904 _NOTE(ARGUNUSED(cdrarg)) 3905 #endif 3906 mptsas_cache_frames_t *p = buf; 3907 if (p->m_dma_hdl != NULL) { 3908 (void) ddi_dma_unbind_handle(p->m_dma_hdl); 3909 (void) ddi_dma_mem_free(&p->m_acc_hdl); 3910 ddi_dma_free_handle(&p->m_dma_hdl); 3911 p->m_phys_addr = NULL; 3912 p->m_frames_addr = NULL; 3913 p->m_dma_hdl = NULL; 3914 p->m_acc_hdl = NULL; 3915 } 3916 3917 } 3918 3919 /* 3920 * allocate and deallocate external pkt space (ie. not part of mptsas_cmd) 3921 * for non-standard length cdb, pkt_private, status areas 3922 * if allocation fails, then deallocate all external space and the pkt 3923 */ 3924 /* ARGSUSED */ 3925 static int 3926 mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd, 3927 int cmdlen, int tgtlen, int statuslen, int kf) 3928 { 3929 caddr_t cdbp, scbp, tgt; 3930 int (*callback)(caddr_t) = (kf == KM_SLEEP) ? 3931 DDI_DMA_SLEEP : DDI_DMA_DONTWAIT; 3932 struct scsi_address ap; 3933 size_t senselength; 3934 ddi_dma_attr_t ext_arq_dma_attr; 3935 uint_t cookiec; 3936 3937 NDBG3(("mptsas_pkt_alloc_extern: " 3938 "cmd=0x%p cmdlen=%d tgtlen=%d statuslen=%d kf=%x", 3939 (void *)cmd, cmdlen, tgtlen, statuslen, kf)); 3940 3941 tgt = cdbp = scbp = NULL; 3942 cmd->cmd_scblen = statuslen; 3943 cmd->cmd_privlen = (uchar_t)tgtlen; 3944 3945 if (cmdlen > sizeof (cmd->cmd_cdb)) { 3946 if ((cdbp = kmem_zalloc((size_t)cmdlen, kf)) == NULL) { 3947 goto fail; 3948 } 3949 cmd->cmd_pkt->pkt_cdbp = (opaque_t)cdbp; 3950 cmd->cmd_flags |= CFLAG_CDBEXTERN; 3951 } 3952 if (tgtlen > PKT_PRIV_LEN) { 3953 if ((tgt = kmem_zalloc((size_t)tgtlen, kf)) == NULL) { 3954 goto fail; 3955 } 3956 cmd->cmd_flags |= CFLAG_PRIVEXTERN; 3957 cmd->cmd_pkt->pkt_private = tgt; 3958 } 3959 if (statuslen > EXTCMDS_STATUS_SIZE) { 3960 if ((scbp = kmem_zalloc((size_t)statuslen, kf)) == NULL) { 3961 goto fail; 3962 } 3963 cmd->cmd_flags |= CFLAG_SCBEXTERN; 3964 cmd->cmd_pkt->pkt_scbp = (opaque_t)scbp; 3965 3966 /* allocate sense data buf for DMA */ 3967 3968 senselength = statuslen - MPTSAS_GET_ITEM_OFF( 3969 struct scsi_arq_status, sts_sensedata); 3970 cmd->cmd_rqslen = (uchar_t)senselength; 3971 3972 ap.a_hba_tran = mpt->m_tran; 3973 ap.a_target = 0; 3974 ap.a_lun = 0; 3975 3976 cmd->cmd_ext_arq_buf = scsi_alloc_consistent_buf(&ap, 3977 (struct buf *)NULL, senselength, B_READ, 3978 callback, NULL); 3979 3980 if (cmd->cmd_ext_arq_buf == NULL) { 3981 goto fail; 3982 } 3983 /* 3984 * allocate a extern arq handle and bind the buf 3985 */ 3986 ext_arq_dma_attr = mpt->m_msg_dma_attr; 3987 ext_arq_dma_attr.dma_attr_sgllen = 1; 3988 if ((ddi_dma_alloc_handle(mpt->m_dip, 3989 &ext_arq_dma_attr, callback, 3990 NULL, &cmd->cmd_ext_arqhandle)) != DDI_SUCCESS) { 3991 goto fail; 3992 } 3993 3994 if (ddi_dma_buf_bind_handle(cmd->cmd_ext_arqhandle, 3995 cmd->cmd_ext_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT), 3996 callback, NULL, &cmd->cmd_ext_arqcookie, 3997 &cookiec) 3998 != DDI_SUCCESS) { 3999 goto fail; 4000 } 4001 cmd->cmd_flags |= CFLAG_EXTARQBUFVALID; 4002 } 4003 return (0); 4004 fail: 4005 mptsas_pkt_destroy_extern(mpt, cmd); 4006 return (1); 4007 } 4008 4009 /* 4010 * deallocate external pkt space and deallocate the pkt 4011 */ 4012 static void 4013 mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd) 4014 { 4015 NDBG3(("mptsas_pkt_destroy_extern: cmd=0x%p", (void *)cmd)); 4016 4017 if (cmd->cmd_flags & CFLAG_FREE) { 4018 mptsas_log(mpt, CE_PANIC, 4019 "mptsas_pkt_destroy_extern: freeing free packet"); 4020 _NOTE(NOT_REACHED) 4021 /* NOTREACHED */ 4022 } 4023 if (cmd->cmd_flags & CFLAG_CDBEXTERN) { 4024 kmem_free(cmd->cmd_pkt->pkt_cdbp, (size_t)cmd->cmd_cdblen); 4025 } 4026 if (cmd->cmd_flags & CFLAG_SCBEXTERN) { 4027 kmem_free(cmd->cmd_pkt->pkt_scbp, (size_t)cmd->cmd_scblen); 4028 if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) { 4029 (void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle); 4030 } 4031 if (cmd->cmd_ext_arqhandle) { 4032 ddi_dma_free_handle(&cmd->cmd_ext_arqhandle); 4033 cmd->cmd_ext_arqhandle = NULL; 4034 } 4035 if (cmd->cmd_ext_arq_buf) 4036 scsi_free_consistent_buf(cmd->cmd_ext_arq_buf); 4037 } 4038 if (cmd->cmd_flags & CFLAG_PRIVEXTERN) { 4039 kmem_free(cmd->cmd_pkt->pkt_private, (size_t)cmd->cmd_privlen); 4040 } 4041 cmd->cmd_flags = CFLAG_FREE; 4042 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd); 4043 } 4044 4045 /* 4046 * tran_sync_pkt(9E) - explicit DMA synchronization 4047 */ 4048 /*ARGSUSED*/ 4049 static void 4050 mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 4051 { 4052 mptsas_cmd_t *cmd = PKT2CMD(pkt); 4053 4054 NDBG3(("mptsas_scsi_sync_pkt: target=%d, pkt=0x%p", 4055 ap->a_target, (void *)pkt)); 4056 4057 if (cmd->cmd_dmahandle) { 4058 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 4059 (cmd->cmd_flags & CFLAG_DMASEND) ? 4060 DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU); 4061 } 4062 } 4063 4064 /* 4065 * tran_dmafree(9E) - deallocate DMA resources allocated for command 4066 */ 4067 /*ARGSUSED*/ 4068 static void 4069 mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt) 4070 { 4071 mptsas_cmd_t *cmd = PKT2CMD(pkt); 4072 mptsas_t *mpt = ADDR2MPT(ap); 4073 4074 NDBG3(("mptsas_scsi_dmafree: target=%d pkt=0x%p", 4075 ap->a_target, (void *)pkt)); 4076 4077 if (cmd->cmd_flags & CFLAG_DMAVALID) { 4078 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle); 4079 cmd->cmd_flags &= ~CFLAG_DMAVALID; 4080 } 4081 4082 if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) { 4083 (void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle); 4084 cmd->cmd_flags &= ~CFLAG_EXTARQBUFVALID; 4085 } 4086 4087 mptsas_free_extra_sgl_frame(mpt, cmd); 4088 } 4089 4090 static void 4091 mptsas_pkt_comp(struct scsi_pkt *pkt, mptsas_cmd_t *cmd) 4092 { 4093 if ((cmd->cmd_flags & CFLAG_CMDIOPB) && 4094 (!(cmd->cmd_flags & CFLAG_DMASEND))) { 4095 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 4096 DDI_DMA_SYNC_FORCPU); 4097 } 4098 (*pkt->pkt_comp)(pkt); 4099 } 4100 4101 static void 4102 mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, uint32_t *control, 4103 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl) 4104 { 4105 uint_t cookiec; 4106 mptti_t *dmap; 4107 uint32_t flags; 4108 pMpi2SGESimple64_t sge; 4109 pMpi2SGEChain64_t sgechain; 4110 ASSERT(cmd->cmd_flags & CFLAG_DMAVALID); 4111 4112 /* 4113 * Save the number of entries in the DMA 4114 * Scatter/Gather list 4115 */ 4116 cookiec = cmd->cmd_cookiec; 4117 4118 NDBG1(("mptsas_sge_setup: cookiec=%d", cookiec)); 4119 4120 /* 4121 * Set read/write bit in control. 4122 */ 4123 if (cmd->cmd_flags & CFLAG_DMASEND) { 4124 *control |= MPI2_SCSIIO_CONTROL_WRITE; 4125 } else { 4126 *control |= MPI2_SCSIIO_CONTROL_READ; 4127 } 4128 4129 ddi_put32(acc_hdl, &frame->DataLength, cmd->cmd_dmacount); 4130 4131 /* 4132 * We have 2 cases here. First where we can fit all the 4133 * SG elements into the main frame, and the case 4134 * where we can't. 4135 * If we have more cookies than we can attach to a frame 4136 * we will need to use a chain element to point 4137 * a location of memory where the rest of the S/G 4138 * elements reside. 4139 */ 4140 if (cookiec <= MPTSAS_MAX_FRAME_SGES64(mpt)) { 4141 dmap = cmd->cmd_sg; 4142 sge = (pMpi2SGESimple64_t)(&frame->SGL); 4143 while (cookiec--) { 4144 ddi_put32(acc_hdl, 4145 &sge->Address.Low, dmap->addr.address64.Low); 4146 ddi_put32(acc_hdl, 4147 &sge->Address.High, dmap->addr.address64.High); 4148 ddi_put32(acc_hdl, &sge->FlagsLength, 4149 dmap->count); 4150 flags = ddi_get32(acc_hdl, &sge->FlagsLength); 4151 flags |= ((uint32_t) 4152 (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4153 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4154 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4155 MPI2_SGE_FLAGS_SHIFT); 4156 4157 /* 4158 * If this is the last cookie, we set the flags 4159 * to indicate so 4160 */ 4161 if (cookiec == 0) { 4162 flags |= 4163 ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT 4164 | MPI2_SGE_FLAGS_END_OF_BUFFER 4165 | MPI2_SGE_FLAGS_END_OF_LIST) << 4166 MPI2_SGE_FLAGS_SHIFT); 4167 } 4168 if (cmd->cmd_flags & CFLAG_DMASEND) { 4169 flags |= (MPI2_SGE_FLAGS_HOST_TO_IOC << 4170 MPI2_SGE_FLAGS_SHIFT); 4171 } else { 4172 flags |= (MPI2_SGE_FLAGS_IOC_TO_HOST << 4173 MPI2_SGE_FLAGS_SHIFT); 4174 } 4175 ddi_put32(acc_hdl, &sge->FlagsLength, flags); 4176 dmap++; 4177 sge++; 4178 } 4179 } else { 4180 /* 4181 * Hereby we start to deal with multiple frames. 4182 * The process is as follows: 4183 * 1. Determine how many frames are needed for SGL element 4184 * storage; Note that all frames are stored in contiguous 4185 * memory space and in 64-bit DMA mode each element is 4186 * 3 double-words (12 bytes) long. 4187 * 2. Fill up the main frame. We need to do this separately 4188 * since it contains the SCSI IO request header and needs 4189 * dedicated processing. Note that the last 4 double-words 4190 * of the SCSI IO header is for SGL element storage 4191 * (MPI2_SGE_IO_UNION). 4192 * 3. Fill the chain element in the main frame, so the DMA 4193 * engine can use the following frames. 4194 * 4. Enter a loop to fill the remaining frames. Note that the 4195 * last frame contains no chain element. The remaining 4196 * frames go into the mpt SGL buffer allocated on the fly, 4197 * not immediately following the main message frame, as in 4198 * Gen1. 4199 * Some restrictions: 4200 * 1. For 64-bit DMA, the simple element and chain element 4201 * are both of 3 double-words (12 bytes) in size, even 4202 * though all frames are stored in the first 4G of mem 4203 * range and the higher 32-bits of the address are always 0. 4204 * 2. On some controllers (like the 1064/1068), a frame can 4205 * hold SGL elements with the last 1 or 2 double-words 4206 * (4 or 8 bytes) un-used. On these controllers, we should 4207 * recognize that there's not enough room for another SGL 4208 * element and move the sge pointer to the next frame. 4209 */ 4210 int i, j, k, l, frames, sgemax; 4211 int temp; 4212 uint8_t chainflags; 4213 uint16_t chainlength; 4214 mptsas_cache_frames_t *p; 4215 4216 /* 4217 * Sgemax is the number of SGE's that will fit 4218 * each extra frame and frames is total 4219 * number of frames we'll need. 1 sge entry per 4220 * frame is reseverd for the chain element thus the -1 below. 4221 */ 4222 sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_SGE_SIMPLE64)) 4223 - 1); 4224 temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax; 4225 4226 /* 4227 * A little check to see if we need to round up the number 4228 * of frames we need 4229 */ 4230 if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp * 4231 sgemax) > 1) { 4232 frames = (temp + 1); 4233 } else { 4234 frames = temp; 4235 } 4236 dmap = cmd->cmd_sg; 4237 sge = (pMpi2SGESimple64_t)(&frame->SGL); 4238 4239 /* 4240 * First fill in the main frame 4241 */ 4242 for (j = 1; j < MPTSAS_MAX_FRAME_SGES64(mpt); j++) { 4243 ddi_put32(acc_hdl, &sge->Address.Low, 4244 dmap->addr.address64.Low); 4245 ddi_put32(acc_hdl, &sge->Address.High, 4246 dmap->addr.address64.High); 4247 ddi_put32(acc_hdl, &sge->FlagsLength, dmap->count); 4248 flags = ddi_get32(acc_hdl, &sge->FlagsLength); 4249 flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4250 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4251 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4252 MPI2_SGE_FLAGS_SHIFT); 4253 4254 /* 4255 * If this is the last SGE of this frame 4256 * we set the end of list flag 4257 */ 4258 if (j == (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) { 4259 flags |= ((uint32_t) 4260 (MPI2_SGE_FLAGS_LAST_ELEMENT) << 4261 MPI2_SGE_FLAGS_SHIFT); 4262 } 4263 if (cmd->cmd_flags & CFLAG_DMASEND) { 4264 flags |= 4265 (MPI2_SGE_FLAGS_HOST_TO_IOC << 4266 MPI2_SGE_FLAGS_SHIFT); 4267 } else { 4268 flags |= 4269 (MPI2_SGE_FLAGS_IOC_TO_HOST << 4270 MPI2_SGE_FLAGS_SHIFT); 4271 } 4272 ddi_put32(acc_hdl, &sge->FlagsLength, flags); 4273 dmap++; 4274 sge++; 4275 } 4276 4277 /* 4278 * Fill in the chain element in the main frame. 4279 * About calculation on ChainOffset: 4280 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes) 4281 * in the end reserved for SGL element storage 4282 * (MPI2_SGE_IO_UNION); we should count it in our 4283 * calculation. See its definition in the header file. 4284 * 2. Constant j is the counter of the current SGL element 4285 * that will be processed, and (j - 1) is the number of 4286 * SGL elements that have been processed (stored in the 4287 * main frame). 4288 * 3. ChainOffset value should be in units of double-words (4 4289 * bytes) so the last value should be divided by 4. 4290 */ 4291 ddi_put8(acc_hdl, &frame->ChainOffset, 4292 (sizeof (MPI2_SCSI_IO_REQUEST) - 4293 sizeof (MPI2_SGE_IO_UNION) + 4294 (j - 1) * sizeof (MPI2_SGE_SIMPLE64)) >> 2); 4295 sgechain = (pMpi2SGEChain64_t)sge; 4296 chainflags = (MPI2_SGE_FLAGS_CHAIN_ELEMENT | 4297 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4298 MPI2_SGE_FLAGS_64_BIT_ADDRESSING); 4299 ddi_put8(acc_hdl, &sgechain->Flags, chainflags); 4300 4301 /* 4302 * The size of the next frame is the accurate size of space 4303 * (in bytes) used to store the SGL elements. j is the counter 4304 * of SGL elements. (j - 1) is the number of SGL elements that 4305 * have been processed (stored in frames). 4306 */ 4307 if (frames >= 2) { 4308 chainlength = mpt->m_req_frame_size / 4309 sizeof (MPI2_SGE_SIMPLE64) * 4310 sizeof (MPI2_SGE_SIMPLE64); 4311 } else { 4312 chainlength = ((cookiec - (j - 1)) * 4313 sizeof (MPI2_SGE_SIMPLE64)); 4314 } 4315 4316 p = cmd->cmd_extra_frames; 4317 4318 ddi_put16(acc_hdl, &sgechain->Length, chainlength); 4319 ddi_put32(acc_hdl, &sgechain->Address.Low, 4320 p->m_phys_addr); 4321 /* SGL is allocated in the first 4G mem range */ 4322 ddi_put32(acc_hdl, &sgechain->Address.High, 0); 4323 4324 /* 4325 * If there are more than 2 frames left we have to 4326 * fill in the next chain offset to the location of 4327 * the chain element in the next frame. 4328 * sgemax is the number of simple elements in an extra 4329 * frame. Note that the value NextChainOffset should be 4330 * in double-words (4 bytes). 4331 */ 4332 if (frames >= 2) { 4333 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 4334 (sgemax * sizeof (MPI2_SGE_SIMPLE64)) >> 2); 4335 } else { 4336 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 0); 4337 } 4338 4339 /* 4340 * Jump to next frame; 4341 * Starting here, chain buffers go into the per command SGL. 4342 * This buffer is allocated when chain buffers are needed. 4343 */ 4344 sge = (pMpi2SGESimple64_t)p->m_frames_addr; 4345 i = cookiec; 4346 4347 /* 4348 * Start filling in frames with SGE's. If we 4349 * reach the end of frame and still have SGE's 4350 * to fill we need to add a chain element and 4351 * use another frame. j will be our counter 4352 * for what cookie we are at and i will be 4353 * the total cookiec. k is the current frame 4354 */ 4355 for (k = 1; k <= frames; k++) { 4356 for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) { 4357 4358 /* 4359 * If we have reached the end of frame 4360 * and we have more SGE's to fill in 4361 * we have to fill the final entry 4362 * with a chain element and then 4363 * continue to the next frame 4364 */ 4365 if ((l == (sgemax + 1)) && (k != frames)) { 4366 sgechain = (pMpi2SGEChain64_t)sge; 4367 j--; 4368 chainflags = ( 4369 MPI2_SGE_FLAGS_CHAIN_ELEMENT | 4370 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4371 MPI2_SGE_FLAGS_64_BIT_ADDRESSING); 4372 ddi_put8(p->m_acc_hdl, 4373 &sgechain->Flags, chainflags); 4374 /* 4375 * k is the frame counter and (k + 1) 4376 * is the number of the next frame. 4377 * Note that frames are in contiguous 4378 * memory space. 4379 */ 4380 ddi_put32(p->m_acc_hdl, 4381 &sgechain->Address.Low, 4382 (p->m_phys_addr + 4383 (mpt->m_req_frame_size * k))); 4384 ddi_put32(p->m_acc_hdl, 4385 &sgechain->Address.High, 0); 4386 4387 /* 4388 * If there are more than 2 frames left 4389 * we have to next chain offset to 4390 * the location of the chain element 4391 * in the next frame and fill in the 4392 * length of the next chain 4393 */ 4394 if ((frames - k) >= 2) { 4395 ddi_put8(p->m_acc_hdl, 4396 &sgechain->NextChainOffset, 4397 (sgemax * 4398 sizeof (MPI2_SGE_SIMPLE64)) 4399 >> 2); 4400 ddi_put16(p->m_acc_hdl, 4401 &sgechain->Length, 4402 mpt->m_req_frame_size / 4403 sizeof (MPI2_SGE_SIMPLE64) * 4404 sizeof (MPI2_SGE_SIMPLE64)); 4405 } else { 4406 /* 4407 * This is the last frame. Set 4408 * the NextChainOffset to 0 and 4409 * Length is the total size of 4410 * all remaining simple elements 4411 */ 4412 ddi_put8(p->m_acc_hdl, 4413 &sgechain->NextChainOffset, 4414 0); 4415 ddi_put16(p->m_acc_hdl, 4416 &sgechain->Length, 4417 (cookiec - j) * 4418 sizeof (MPI2_SGE_SIMPLE64)); 4419 } 4420 4421 /* Jump to the next frame */ 4422 sge = (pMpi2SGESimple64_t) 4423 ((char *)p->m_frames_addr + 4424 (int)mpt->m_req_frame_size * k); 4425 4426 continue; 4427 } 4428 4429 ddi_put32(p->m_acc_hdl, 4430 &sge->Address.Low, 4431 dmap->addr.address64.Low); 4432 ddi_put32(p->m_acc_hdl, 4433 &sge->Address.High, 4434 dmap->addr.address64.High); 4435 ddi_put32(p->m_acc_hdl, 4436 &sge->FlagsLength, dmap->count); 4437 flags = ddi_get32(p->m_acc_hdl, 4438 &sge->FlagsLength); 4439 flags |= ((uint32_t)( 4440 MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4441 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4442 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4443 MPI2_SGE_FLAGS_SHIFT); 4444 4445 /* 4446 * If we are at the end of the frame and 4447 * there is another frame to fill in 4448 * we set the last simple element as last 4449 * element 4450 */ 4451 if ((l == sgemax) && (k != frames)) { 4452 flags |= ((uint32_t) 4453 (MPI2_SGE_FLAGS_LAST_ELEMENT) << 4454 MPI2_SGE_FLAGS_SHIFT); 4455 } 4456 4457 /* 4458 * If this is the final cookie we 4459 * indicate it by setting the flags 4460 */ 4461 if (j == i) { 4462 flags |= ((uint32_t) 4463 (MPI2_SGE_FLAGS_LAST_ELEMENT | 4464 MPI2_SGE_FLAGS_END_OF_BUFFER | 4465 MPI2_SGE_FLAGS_END_OF_LIST) << 4466 MPI2_SGE_FLAGS_SHIFT); 4467 } 4468 if (cmd->cmd_flags & CFLAG_DMASEND) { 4469 flags |= 4470 (MPI2_SGE_FLAGS_HOST_TO_IOC << 4471 MPI2_SGE_FLAGS_SHIFT); 4472 } else { 4473 flags |= 4474 (MPI2_SGE_FLAGS_IOC_TO_HOST << 4475 MPI2_SGE_FLAGS_SHIFT); 4476 } 4477 ddi_put32(p->m_acc_hdl, 4478 &sge->FlagsLength, flags); 4479 dmap++; 4480 sge++; 4481 } 4482 } 4483 4484 /* 4485 * Sync DMA with the chain buffers that were just created 4486 */ 4487 (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 4488 } 4489 } 4490 4491 /* 4492 * Interrupt handling 4493 * Utility routine. Poll for status of a command sent to HBA 4494 * without interrupts (a FLAG_NOINTR command). 4495 */ 4496 int 4497 mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime) 4498 { 4499 int rval = TRUE; 4500 4501 NDBG5(("mptsas_poll: cmd=0x%p", (void *)poll_cmd)); 4502 4503 if ((poll_cmd->cmd_flags & CFLAG_TM_CMD) == 0) { 4504 mptsas_restart_hba(mpt); 4505 } 4506 4507 /* 4508 * Wait, using drv_usecwait(), long enough for the command to 4509 * reasonably return from the target if the target isn't 4510 * "dead". A polled command may well be sent from scsi_poll, and 4511 * there are retries built in to scsi_poll if the transport 4512 * accepted the packet (TRAN_ACCEPT). scsi_poll waits 1 second 4513 * and retries the transport up to scsi_poll_busycnt times 4514 * (currently 60) if 4515 * 1. pkt_reason is CMD_INCOMPLETE and pkt_state is 0, or 4516 * 2. pkt_reason is CMD_CMPLT and *pkt_scbp has STATUS_BUSY 4517 * 4518 * limit the waiting to avoid a hang in the event that the 4519 * cmd never gets started but we are still receiving interrupts 4520 */ 4521 while (!(poll_cmd->cmd_flags & CFLAG_FINISHED)) { 4522 if (mptsas_wait_intr(mpt, polltime) == FALSE) { 4523 NDBG5(("mptsas_poll: command incomplete")); 4524 rval = FALSE; 4525 break; 4526 } 4527 } 4528 4529 if (rval == FALSE) { 4530 4531 /* 4532 * this isn't supposed to happen, the hba must be wedged 4533 * Mark this cmd as a timeout. 4534 */ 4535 mptsas_set_pkt_reason(mpt, poll_cmd, CMD_TIMEOUT, 4536 (STAT_TIMEOUT|STAT_ABORTED)); 4537 4538 if (poll_cmd->cmd_queued == FALSE) { 4539 4540 NDBG5(("mptsas_poll: not on waitq")); 4541 4542 poll_cmd->cmd_pkt->pkt_state |= 4543 (STATE_GOT_BUS|STATE_GOT_TARGET|STATE_SENT_CMD); 4544 } else { 4545 4546 /* find and remove it from the waitq */ 4547 NDBG5(("mptsas_poll: delete from waitq")); 4548 mptsas_waitq_delete(mpt, poll_cmd); 4549 } 4550 4551 } 4552 mptsas_fma_check(mpt, poll_cmd); 4553 NDBG5(("mptsas_poll: done")); 4554 return (rval); 4555 } 4556 4557 /* 4558 * Used for polling cmds and TM function 4559 */ 4560 static int 4561 mptsas_wait_intr(mptsas_t *mpt, int polltime) 4562 { 4563 int cnt; 4564 pMpi2ReplyDescriptorsUnion_t reply_desc_union; 4565 uint32_t int_mask; 4566 4567 NDBG5(("mptsas_wait_intr")); 4568 4569 mpt->m_polled_intr = 1; 4570 4571 /* 4572 * Get the current interrupt mask and disable interrupts. When 4573 * re-enabling ints, set mask to saved value. 4574 */ 4575 int_mask = ddi_get32(mpt->m_datap, &mpt->m_reg->HostInterruptMask); 4576 MPTSAS_DISABLE_INTR(mpt); 4577 4578 /* 4579 * Keep polling for at least (polltime * 1000) seconds 4580 */ 4581 for (cnt = 0; cnt < polltime; cnt++) { 4582 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 4583 DDI_DMA_SYNC_FORCPU); 4584 4585 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t) 4586 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index); 4587 4588 if (ddi_get32(mpt->m_acc_post_queue_hdl, 4589 &reply_desc_union->Words.Low) == 0xFFFFFFFF || 4590 ddi_get32(mpt->m_acc_post_queue_hdl, 4591 &reply_desc_union->Words.High) == 0xFFFFFFFF) { 4592 drv_usecwait(1000); 4593 continue; 4594 } 4595 4596 /* 4597 * The reply is valid, process it according to its 4598 * type. 4599 */ 4600 mptsas_process_intr(mpt, reply_desc_union); 4601 4602 if (++mpt->m_post_index == mpt->m_post_queue_depth) { 4603 mpt->m_post_index = 0; 4604 } 4605 4606 /* 4607 * Update the global reply index 4608 */ 4609 ddi_put32(mpt->m_datap, 4610 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); 4611 mpt->m_polled_intr = 0; 4612 4613 /* 4614 * Re-enable interrupts and quit. 4615 */ 4616 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, 4617 int_mask); 4618 return (TRUE); 4619 4620 } 4621 4622 /* 4623 * Clear polling flag, re-enable interrupts and quit. 4624 */ 4625 mpt->m_polled_intr = 0; 4626 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, int_mask); 4627 return (FALSE); 4628 } 4629 4630 static void 4631 mptsas_handle_scsi_io_success(mptsas_t *mpt, 4632 pMpi2ReplyDescriptorsUnion_t reply_desc) 4633 { 4634 pMpi2SCSIIOSuccessReplyDescriptor_t scsi_io_success; 4635 uint16_t SMID; 4636 mptsas_slots_t *slots = mpt->m_active; 4637 mptsas_cmd_t *cmd = NULL; 4638 struct scsi_pkt *pkt; 4639 4640 ASSERT(mutex_owned(&mpt->m_mutex)); 4641 4642 scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc; 4643 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &scsi_io_success->SMID); 4644 4645 /* 4646 * This is a success reply so just complete the IO. First, do a sanity 4647 * check on the SMID. The final slot is used for TM requests, which 4648 * would not come into this reply handler. 4649 */ 4650 if ((SMID == 0) || (SMID > slots->m_n_slots)) { 4651 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n", 4652 SMID); 4653 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 4654 return; 4655 } 4656 4657 cmd = slots->m_slot[SMID]; 4658 4659 /* 4660 * print warning and return if the slot is empty 4661 */ 4662 if (cmd == NULL) { 4663 mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO " 4664 "in slot %d", SMID); 4665 return; 4666 } 4667 4668 pkt = CMD2PKT(cmd); 4669 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD | 4670 STATE_GOT_STATUS); 4671 if (cmd->cmd_flags & CFLAG_DMAVALID) { 4672 pkt->pkt_state |= STATE_XFERRED_DATA; 4673 } 4674 pkt->pkt_resid = 0; 4675 4676 if (cmd->cmd_flags & CFLAG_PASSTHRU) { 4677 cmd->cmd_flags |= CFLAG_FINISHED; 4678 cv_broadcast(&mpt->m_passthru_cv); 4679 return; 4680 } else { 4681 mptsas_remove_cmd(mpt, cmd); 4682 } 4683 4684 if (cmd->cmd_flags & CFLAG_RETRY) { 4685 /* 4686 * The target returned QFULL or busy, do not add tihs 4687 * pkt to the doneq since the hba will retry 4688 * this cmd. 4689 * 4690 * The pkt has already been resubmitted in 4691 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error(). 4692 * Remove this cmd_flag here. 4693 */ 4694 cmd->cmd_flags &= ~CFLAG_RETRY; 4695 } else { 4696 mptsas_doneq_add(mpt, cmd); 4697 } 4698 } 4699 4700 static void 4701 mptsas_handle_address_reply(mptsas_t *mpt, 4702 pMpi2ReplyDescriptorsUnion_t reply_desc) 4703 { 4704 pMpi2AddressReplyDescriptor_t address_reply; 4705 pMPI2DefaultReply_t reply; 4706 mptsas_fw_diagnostic_buffer_t *pBuffer; 4707 uint32_t reply_addr; 4708 uint16_t SMID, iocstatus; 4709 mptsas_slots_t *slots = mpt->m_active; 4710 mptsas_cmd_t *cmd = NULL; 4711 uint8_t function, buffer_type; 4712 m_replyh_arg_t *args; 4713 int reply_frame_no; 4714 4715 ASSERT(mutex_owned(&mpt->m_mutex)); 4716 4717 address_reply = (pMpi2AddressReplyDescriptor_t)reply_desc; 4718 reply_addr = ddi_get32(mpt->m_acc_post_queue_hdl, 4719 &address_reply->ReplyFrameAddress); 4720 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &address_reply->SMID); 4721 4722 /* 4723 * If reply frame is not in the proper range we should ignore this 4724 * message and exit the interrupt handler. 4725 */ 4726 if ((reply_addr < mpt->m_reply_frame_dma_addr) || 4727 (reply_addr >= (mpt->m_reply_frame_dma_addr + 4728 (mpt->m_reply_frame_size * mpt->m_max_replies))) || 4729 ((reply_addr - mpt->m_reply_frame_dma_addr) % 4730 mpt->m_reply_frame_size != 0)) { 4731 mptsas_log(mpt, CE_WARN, "?Received invalid reply frame " 4732 "address 0x%x\n", reply_addr); 4733 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 4734 return; 4735 } 4736 4737 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 4738 DDI_DMA_SYNC_FORCPU); 4739 reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame + (reply_addr - 4740 mpt->m_reply_frame_dma_addr)); 4741 function = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Function); 4742 4743 /* 4744 * don't get slot information and command for events since these values 4745 * don't exist 4746 */ 4747 if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) && 4748 (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) { 4749 /* 4750 * This could be a TM reply, which use the last allocated SMID, 4751 * so allow for that. 4752 */ 4753 if ((SMID == 0) || (SMID > (slots->m_n_slots + 1))) { 4754 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of " 4755 "%d\n", SMID); 4756 ddi_fm_service_impact(mpt->m_dip, 4757 DDI_SERVICE_UNAFFECTED); 4758 return; 4759 } 4760 4761 cmd = slots->m_slot[SMID]; 4762 4763 /* 4764 * print warning and return if the slot is empty 4765 */ 4766 if (cmd == NULL) { 4767 mptsas_log(mpt, CE_WARN, "?NULL command for address " 4768 "reply in slot %d", SMID); 4769 return; 4770 } 4771 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 4772 (cmd->cmd_flags & CFLAG_CONFIG) || 4773 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 4774 cmd->cmd_rfm = reply_addr; 4775 cmd->cmd_flags |= CFLAG_FINISHED; 4776 cv_broadcast(&mpt->m_passthru_cv); 4777 cv_broadcast(&mpt->m_config_cv); 4778 cv_broadcast(&mpt->m_fw_diag_cv); 4779 return; 4780 } else if (!(cmd->cmd_flags & CFLAG_FW_CMD)) { 4781 mptsas_remove_cmd(mpt, cmd); 4782 } 4783 NDBG31(("\t\tmptsas_process_intr: slot=%d", SMID)); 4784 } 4785 /* 4786 * Depending on the function, we need to handle 4787 * the reply frame (and cmd) differently. 4788 */ 4789 switch (function) { 4790 case MPI2_FUNCTION_SCSI_IO_REQUEST: 4791 mptsas_check_scsi_io_error(mpt, (pMpi2SCSIIOReply_t)reply, cmd); 4792 break; 4793 case MPI2_FUNCTION_SCSI_TASK_MGMT: 4794 cmd->cmd_rfm = reply_addr; 4795 mptsas_check_task_mgt(mpt, (pMpi2SCSIManagementReply_t)reply, 4796 cmd); 4797 break; 4798 case MPI2_FUNCTION_FW_DOWNLOAD: 4799 cmd->cmd_flags |= CFLAG_FINISHED; 4800 cv_signal(&mpt->m_fw_cv); 4801 break; 4802 case MPI2_FUNCTION_EVENT_NOTIFICATION: 4803 reply_frame_no = (reply_addr - mpt->m_reply_frame_dma_addr) / 4804 mpt->m_reply_frame_size; 4805 args = &mpt->m_replyh_args[reply_frame_no]; 4806 args->mpt = (void *)mpt; 4807 args->rfm = reply_addr; 4808 4809 /* 4810 * Record the event if its type is enabled in 4811 * this mpt instance by ioctl. 4812 */ 4813 mptsas_record_event(args); 4814 4815 /* 4816 * Handle time critical events 4817 * NOT_RESPONDING/ADDED only now 4818 */ 4819 if (mptsas_handle_event_sync(args) == DDI_SUCCESS) { 4820 /* 4821 * Would not return main process, 4822 * just let taskq resolve ack action 4823 * and ack would be sent in taskq thread 4824 */ 4825 NDBG20(("send mptsas_handle_event_sync success")); 4826 } 4827 4828 if (mpt->m_in_reset) { 4829 NDBG20(("dropping event received during reset")); 4830 return; 4831 } 4832 4833 if ((ddi_taskq_dispatch(mpt->m_event_taskq, mptsas_handle_event, 4834 (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) { 4835 mptsas_log(mpt, CE_WARN, "No memory available" 4836 "for dispatch taskq"); 4837 /* 4838 * Return the reply frame to the free queue. 4839 */ 4840 ddi_put32(mpt->m_acc_free_queue_hdl, 4841 &((uint32_t *)(void *) 4842 mpt->m_free_queue)[mpt->m_free_index], reply_addr); 4843 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 4844 DDI_DMA_SYNC_FORDEV); 4845 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 4846 mpt->m_free_index = 0; 4847 } 4848 4849 ddi_put32(mpt->m_datap, 4850 &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index); 4851 } 4852 return; 4853 case MPI2_FUNCTION_DIAG_BUFFER_POST: 4854 /* 4855 * If SMID is 0, this implies that the reply is due to a 4856 * release function with a status that the buffer has been 4857 * released. Set the buffer flags accordingly. 4858 */ 4859 if (SMID == 0) { 4860 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 4861 &reply->IOCStatus); 4862 buffer_type = ddi_get8(mpt->m_acc_reply_frame_hdl, 4863 &(((pMpi2DiagBufferPostReply_t)reply)->BufferType)); 4864 if (iocstatus == MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED) { 4865 pBuffer = 4866 &mpt->m_fw_diag_buffer_list[buffer_type]; 4867 pBuffer->valid_data = TRUE; 4868 pBuffer->owned_by_firmware = FALSE; 4869 pBuffer->immediate = FALSE; 4870 } 4871 } else { 4872 /* 4873 * Normal handling of diag post reply with SMID. 4874 */ 4875 cmd = slots->m_slot[SMID]; 4876 4877 /* 4878 * print warning and return if the slot is empty 4879 */ 4880 if (cmd == NULL) { 4881 mptsas_log(mpt, CE_WARN, "?NULL command for " 4882 "address reply in slot %d", SMID); 4883 return; 4884 } 4885 cmd->cmd_rfm = reply_addr; 4886 cmd->cmd_flags |= CFLAG_FINISHED; 4887 cv_broadcast(&mpt->m_fw_diag_cv); 4888 } 4889 return; 4890 default: 4891 mptsas_log(mpt, CE_WARN, "Unknown function 0x%x ", function); 4892 break; 4893 } 4894 4895 /* 4896 * Return the reply frame to the free queue. 4897 */ 4898 ddi_put32(mpt->m_acc_free_queue_hdl, 4899 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 4900 reply_addr); 4901 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 4902 DDI_DMA_SYNC_FORDEV); 4903 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 4904 mpt->m_free_index = 0; 4905 } 4906 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 4907 mpt->m_free_index); 4908 4909 if (cmd->cmd_flags & CFLAG_FW_CMD) 4910 return; 4911 4912 if (cmd->cmd_flags & CFLAG_RETRY) { 4913 /* 4914 * The target returned QFULL or busy, do not add tihs 4915 * pkt to the doneq since the hba will retry 4916 * this cmd. 4917 * 4918 * The pkt has already been resubmitted in 4919 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error(). 4920 * Remove this cmd_flag here. 4921 */ 4922 cmd->cmd_flags &= ~CFLAG_RETRY; 4923 } else { 4924 mptsas_doneq_add(mpt, cmd); 4925 } 4926 } 4927 4928 static void 4929 mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, 4930 mptsas_cmd_t *cmd) 4931 { 4932 uint8_t scsi_status, scsi_state; 4933 uint16_t ioc_status; 4934 uint32_t xferred, sensecount, responsedata, loginfo = 0; 4935 struct scsi_pkt *pkt; 4936 struct scsi_arq_status *arqstat; 4937 struct buf *bp; 4938 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 4939 uint8_t *sensedata = NULL; 4940 4941 if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) == 4942 (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) { 4943 bp = cmd->cmd_ext_arq_buf; 4944 } else { 4945 bp = cmd->cmd_arq_buf; 4946 } 4947 4948 scsi_status = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIStatus); 4949 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus); 4950 scsi_state = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIState); 4951 xferred = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->TransferCount); 4952 sensecount = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->SenseCount); 4953 responsedata = ddi_get32(mpt->m_acc_reply_frame_hdl, 4954 &reply->ResponseInfo); 4955 4956 if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 4957 loginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 4958 &reply->IOCLogInfo); 4959 mptsas_log(mpt, CE_NOTE, 4960 "?Log info 0x%x received for target %d.\n" 4961 "\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x", 4962 loginfo, Tgt(cmd), scsi_status, ioc_status, 4963 scsi_state); 4964 } 4965 4966 NDBG31(("\t\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x", 4967 scsi_status, ioc_status, scsi_state)); 4968 4969 pkt = CMD2PKT(cmd); 4970 *(pkt->pkt_scbp) = scsi_status; 4971 4972 if (loginfo == 0x31170000) { 4973 /* 4974 * if loginfo PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY 4975 * 0x31170000 comes, that means the device missing delay 4976 * is in progressing, the command need retry later. 4977 */ 4978 *(pkt->pkt_scbp) = STATUS_BUSY; 4979 return; 4980 } 4981 4982 if ((scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS) && 4983 ((ioc_status & MPI2_IOCSTATUS_MASK) == 4984 MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE)) { 4985 pkt->pkt_reason = CMD_INCOMPLETE; 4986 pkt->pkt_state |= STATE_GOT_BUS; 4987 if (ptgt->m_reset_delay == 0) { 4988 mptsas_set_throttle(mpt, ptgt, 4989 DRAIN_THROTTLE); 4990 } 4991 return; 4992 } 4993 4994 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) { 4995 responsedata &= 0x000000FF; 4996 if (responsedata & MPTSAS_SCSI_RESPONSE_CODE_TLR_OFF) { 4997 mptsas_log(mpt, CE_NOTE, "Do not support the TLR\n"); 4998 pkt->pkt_reason = CMD_TLR_OFF; 4999 return; 5000 } 5001 } 5002 5003 5004 switch (scsi_status) { 5005 case MPI2_SCSI_STATUS_CHECK_CONDITION: 5006 pkt->pkt_resid = (cmd->cmd_dmacount - xferred); 5007 arqstat = (void*)(pkt->pkt_scbp); 5008 arqstat->sts_rqpkt_status = *((struct scsi_status *) 5009 (pkt->pkt_scbp)); 5010 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 5011 STATE_SENT_CMD | STATE_GOT_STATUS | STATE_ARQ_DONE); 5012 if (cmd->cmd_flags & CFLAG_XARQ) { 5013 pkt->pkt_state |= STATE_XARQ_DONE; 5014 } 5015 if (pkt->pkt_resid != cmd->cmd_dmacount) { 5016 pkt->pkt_state |= STATE_XFERRED_DATA; 5017 } 5018 arqstat->sts_rqpkt_reason = pkt->pkt_reason; 5019 arqstat->sts_rqpkt_state = pkt->pkt_state; 5020 arqstat->sts_rqpkt_state |= STATE_XFERRED_DATA; 5021 arqstat->sts_rqpkt_statistics = pkt->pkt_statistics; 5022 sensedata = (uint8_t *)&arqstat->sts_sensedata; 5023 5024 bcopy((uchar_t *)bp->b_un.b_addr, sensedata, 5025 ((cmd->cmd_rqslen >= sensecount) ? sensecount : 5026 cmd->cmd_rqslen)); 5027 arqstat->sts_rqpkt_resid = (cmd->cmd_rqslen - sensecount); 5028 cmd->cmd_flags |= CFLAG_CMDARQ; 5029 /* 5030 * Set proper status for pkt if autosense was valid 5031 */ 5032 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) { 5033 struct scsi_status zero_status = { 0 }; 5034 arqstat->sts_rqpkt_status = zero_status; 5035 } 5036 5037 /* 5038 * ASC=0x47 is parity error 5039 * ASC=0x48 is initiator detected error received 5040 */ 5041 if ((scsi_sense_key(sensedata) == KEY_ABORTED_COMMAND) && 5042 ((scsi_sense_asc(sensedata) == 0x47) || 5043 (scsi_sense_asc(sensedata) == 0x48))) { 5044 mptsas_log(mpt, CE_NOTE, "Aborted_command!"); 5045 } 5046 5047 /* 5048 * ASC/ASCQ=0x3F/0x0E means report_luns data changed 5049 * ASC/ASCQ=0x25/0x00 means invalid lun 5050 */ 5051 if (((scsi_sense_key(sensedata) == KEY_UNIT_ATTENTION) && 5052 (scsi_sense_asc(sensedata) == 0x3F) && 5053 (scsi_sense_ascq(sensedata) == 0x0E)) || 5054 ((scsi_sense_key(sensedata) == KEY_ILLEGAL_REQUEST) && 5055 (scsi_sense_asc(sensedata) == 0x25) && 5056 (scsi_sense_ascq(sensedata) == 0x00))) { 5057 mptsas_topo_change_list_t *topo_node = NULL; 5058 5059 topo_node = kmem_zalloc( 5060 sizeof (mptsas_topo_change_list_t), 5061 KM_NOSLEEP); 5062 if (topo_node == NULL) { 5063 mptsas_log(mpt, CE_NOTE, "No memory" 5064 "resource for handle SAS dynamic" 5065 "reconfigure.\n"); 5066 break; 5067 } 5068 topo_node->mpt = mpt; 5069 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET; 5070 topo_node->un.phymask = ptgt->m_phymask; 5071 topo_node->devhdl = ptgt->m_devhdl; 5072 topo_node->object = (void *)ptgt; 5073 topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED; 5074 5075 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 5076 mptsas_handle_dr, 5077 (void *)topo_node, 5078 DDI_NOSLEEP)) != DDI_SUCCESS) { 5079 mptsas_log(mpt, CE_NOTE, "mptsas start taskq" 5080 "for handle SAS dynamic reconfigure" 5081 "failed. \n"); 5082 } 5083 } 5084 break; 5085 case MPI2_SCSI_STATUS_GOOD: 5086 switch (ioc_status & MPI2_IOCSTATUS_MASK) { 5087 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 5088 pkt->pkt_reason = CMD_DEV_GONE; 5089 pkt->pkt_state |= STATE_GOT_BUS; 5090 if (ptgt->m_reset_delay == 0) { 5091 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5092 } 5093 NDBG31(("lost disk for target%d, command:%x", 5094 Tgt(cmd), pkt->pkt_cdbp[0])); 5095 break; 5096 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN: 5097 NDBG31(("data overrun: xferred=%d", xferred)); 5098 NDBG31(("dmacount=%d", cmd->cmd_dmacount)); 5099 pkt->pkt_reason = CMD_DATA_OVR; 5100 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET 5101 | STATE_SENT_CMD | STATE_GOT_STATUS 5102 | STATE_XFERRED_DATA); 5103 pkt->pkt_resid = 0; 5104 break; 5105 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: 5106 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN: 5107 NDBG31(("data underrun: xferred=%d", xferred)); 5108 NDBG31(("dmacount=%d", cmd->cmd_dmacount)); 5109 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET 5110 | STATE_SENT_CMD | STATE_GOT_STATUS); 5111 pkt->pkt_resid = (cmd->cmd_dmacount - xferred); 5112 if (pkt->pkt_resid != cmd->cmd_dmacount) { 5113 pkt->pkt_state |= STATE_XFERRED_DATA; 5114 } 5115 break; 5116 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: 5117 mptsas_set_pkt_reason(mpt, 5118 cmd, CMD_RESET, STAT_BUS_RESET); 5119 break; 5120 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: 5121 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: 5122 mptsas_set_pkt_reason(mpt, 5123 cmd, CMD_RESET, STAT_DEV_RESET); 5124 break; 5125 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR: 5126 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR: 5127 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET); 5128 mptsas_set_pkt_reason(mpt, 5129 cmd, CMD_TERMINATED, STAT_TERMINATED); 5130 break; 5131 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: 5132 case MPI2_IOCSTATUS_BUSY: 5133 /* 5134 * set throttles to drain 5135 */ 5136 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 5137 &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST); 5138 while (ptgt != NULL) { 5139 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5140 5141 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 5142 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 5143 } 5144 5145 /* 5146 * retry command 5147 */ 5148 cmd->cmd_flags |= CFLAG_RETRY; 5149 cmd->cmd_pkt_flags |= FLAG_HEAD; 5150 5151 (void) mptsas_accept_pkt(mpt, cmd); 5152 break; 5153 default: 5154 mptsas_log(mpt, CE_WARN, 5155 "unknown ioc_status = %x\n", ioc_status); 5156 mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer " 5157 "count = %x, scsi_status = %x", scsi_state, 5158 xferred, scsi_status); 5159 break; 5160 } 5161 break; 5162 case MPI2_SCSI_STATUS_TASK_SET_FULL: 5163 mptsas_handle_qfull(mpt, cmd); 5164 break; 5165 case MPI2_SCSI_STATUS_BUSY: 5166 NDBG31(("scsi_status busy received")); 5167 break; 5168 case MPI2_SCSI_STATUS_RESERVATION_CONFLICT: 5169 NDBG31(("scsi_status reservation conflict received")); 5170 break; 5171 default: 5172 mptsas_log(mpt, CE_WARN, "scsi_status=%x, ioc_status=%x\n", 5173 scsi_status, ioc_status); 5174 mptsas_log(mpt, CE_WARN, 5175 "mptsas_process_intr: invalid scsi status\n"); 5176 break; 5177 } 5178 } 5179 5180 static void 5181 mptsas_check_task_mgt(mptsas_t *mpt, pMpi2SCSIManagementReply_t reply, 5182 mptsas_cmd_t *cmd) 5183 { 5184 uint8_t task_type; 5185 uint16_t ioc_status; 5186 uint32_t log_info; 5187 uint16_t dev_handle; 5188 struct scsi_pkt *pkt = CMD2PKT(cmd); 5189 5190 task_type = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->TaskType); 5191 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus); 5192 log_info = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo); 5193 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->DevHandle); 5194 5195 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 5196 mptsas_log(mpt, CE_WARN, "mptsas_check_task_mgt: Task 0x%x " 5197 "failed. IOCStatus=0x%x IOCLogInfo=0x%x target=%d\n", 5198 task_type, ioc_status, log_info, dev_handle); 5199 pkt->pkt_reason = CMD_INCOMPLETE; 5200 return; 5201 } 5202 5203 switch (task_type) { 5204 case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK: 5205 case MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET: 5206 case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK: 5207 case MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA: 5208 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET: 5209 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION: 5210 break; 5211 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 5212 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 5213 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 5214 /* 5215 * Check for invalid DevHandle of 0 in case application 5216 * sends bad command. DevHandle of 0 could cause problems. 5217 */ 5218 if (dev_handle == 0) { 5219 mptsas_log(mpt, CE_WARN, "!Can't flush target with" 5220 " DevHandle of 0."); 5221 } else { 5222 mptsas_flush_target(mpt, dev_handle, Lun(cmd), 5223 task_type); 5224 } 5225 break; 5226 default: 5227 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.", 5228 task_type); 5229 mptsas_log(mpt, CE_WARN, "ioc status = %x", ioc_status); 5230 break; 5231 } 5232 } 5233 5234 static void 5235 mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg) 5236 { 5237 mptsas_t *mpt = arg->mpt; 5238 uint64_t t = arg->t; 5239 mptsas_cmd_t *cmd; 5240 struct scsi_pkt *pkt; 5241 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 5242 5243 mutex_enter(&item->mutex); 5244 while (item->flag & MPTSAS_DONEQ_THREAD_ACTIVE) { 5245 if (!item->doneq) { 5246 cv_wait(&item->cv, &item->mutex); 5247 } 5248 pkt = NULL; 5249 if ((cmd = mptsas_doneq_thread_rm(mpt, t)) != NULL) { 5250 cmd->cmd_flags |= CFLAG_COMPLETED; 5251 pkt = CMD2PKT(cmd); 5252 } 5253 mutex_exit(&item->mutex); 5254 if (pkt) { 5255 mptsas_pkt_comp(pkt, cmd); 5256 } 5257 mutex_enter(&item->mutex); 5258 } 5259 mutex_exit(&item->mutex); 5260 mutex_enter(&mpt->m_doneq_mutex); 5261 mpt->m_doneq_thread_n--; 5262 cv_broadcast(&mpt->m_doneq_thread_cv); 5263 mutex_exit(&mpt->m_doneq_mutex); 5264 } 5265 5266 5267 /* 5268 * mpt interrupt handler. 5269 */ 5270 static uint_t 5271 mptsas_intr(caddr_t arg1, caddr_t arg2) 5272 { 5273 mptsas_t *mpt = (void *)arg1; 5274 pMpi2ReplyDescriptorsUnion_t reply_desc_union; 5275 uchar_t did_reply = FALSE; 5276 5277 NDBG1(("mptsas_intr: arg1 0x%p arg2 0x%p", (void *)arg1, (void *)arg2)); 5278 5279 mutex_enter(&mpt->m_mutex); 5280 5281 /* 5282 * If interrupts are shared by two channels then check whether this 5283 * interrupt is genuinely for this channel by making sure first the 5284 * chip is in high power state. 5285 */ 5286 if ((mpt->m_options & MPTSAS_OPT_PM) && 5287 (mpt->m_power_level != PM_LEVEL_D0)) { 5288 mutex_exit(&mpt->m_mutex); 5289 return (DDI_INTR_UNCLAIMED); 5290 } 5291 5292 /* 5293 * If polling, interrupt was triggered by some shared interrupt because 5294 * IOC interrupts are disabled during polling, so polling routine will 5295 * handle any replies. Considering this, if polling is happening, 5296 * return with interrupt unclaimed. 5297 */ 5298 if (mpt->m_polled_intr) { 5299 mutex_exit(&mpt->m_mutex); 5300 mptsas_log(mpt, CE_WARN, "mpt_sas: Unclaimed interrupt"); 5301 return (DDI_INTR_UNCLAIMED); 5302 } 5303 5304 /* 5305 * Read the istat register. 5306 */ 5307 if ((INTPENDING(mpt)) != 0) { 5308 /* 5309 * read fifo until empty. 5310 */ 5311 #ifndef __lock_lint 5312 _NOTE(CONSTCOND) 5313 #endif 5314 while (TRUE) { 5315 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 5316 DDI_DMA_SYNC_FORCPU); 5317 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t) 5318 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index); 5319 5320 if (ddi_get32(mpt->m_acc_post_queue_hdl, 5321 &reply_desc_union->Words.Low) == 0xFFFFFFFF || 5322 ddi_get32(mpt->m_acc_post_queue_hdl, 5323 &reply_desc_union->Words.High) == 0xFFFFFFFF) { 5324 break; 5325 } 5326 5327 /* 5328 * The reply is valid, process it according to its 5329 * type. Also, set a flag for updating the reply index 5330 * after they've all been processed. 5331 */ 5332 did_reply = TRUE; 5333 5334 mptsas_process_intr(mpt, reply_desc_union); 5335 5336 /* 5337 * Increment post index and roll over if needed. 5338 */ 5339 if (++mpt->m_post_index == mpt->m_post_queue_depth) { 5340 mpt->m_post_index = 0; 5341 } 5342 } 5343 5344 /* 5345 * Update the global reply index if at least one reply was 5346 * processed. 5347 */ 5348 if (did_reply) { 5349 ddi_put32(mpt->m_datap, 5350 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); 5351 } 5352 } else { 5353 mutex_exit(&mpt->m_mutex); 5354 return (DDI_INTR_UNCLAIMED); 5355 } 5356 NDBG1(("mptsas_intr complete")); 5357 5358 /* 5359 * If no helper threads are created, process the doneq in ISR. If 5360 * helpers are created, use the doneq length as a metric to measure the 5361 * load on the interrupt CPU. If it is long enough, which indicates the 5362 * load is heavy, then we deliver the IO completions to the helpers. 5363 * This measurement has some limitations, although it is simple and 5364 * straightforward and works well for most of the cases at present. 5365 */ 5366 if (!mpt->m_doneq_thread_n || 5367 (mpt->m_doneq_len <= mpt->m_doneq_length_threshold)) { 5368 mptsas_doneq_empty(mpt); 5369 } else { 5370 mptsas_deliver_doneq_thread(mpt); 5371 } 5372 5373 /* 5374 * If there are queued cmd, start them now. 5375 */ 5376 if (mpt->m_waitq != NULL) { 5377 mptsas_restart_waitq(mpt); 5378 } 5379 5380 mutex_exit(&mpt->m_mutex); 5381 return (DDI_INTR_CLAIMED); 5382 } 5383 5384 static void 5385 mptsas_process_intr(mptsas_t *mpt, 5386 pMpi2ReplyDescriptorsUnion_t reply_desc_union) 5387 { 5388 uint8_t reply_type; 5389 5390 ASSERT(mutex_owned(&mpt->m_mutex)); 5391 5392 /* 5393 * The reply is valid, process it according to its 5394 * type. Also, set a flag for updated the reply index 5395 * after they've all been processed. 5396 */ 5397 reply_type = ddi_get8(mpt->m_acc_post_queue_hdl, 5398 &reply_desc_union->Default.ReplyFlags); 5399 reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; 5400 if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) { 5401 mptsas_handle_scsi_io_success(mpt, reply_desc_union); 5402 } else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { 5403 mptsas_handle_address_reply(mpt, reply_desc_union); 5404 } else { 5405 mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type); 5406 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 5407 } 5408 5409 /* 5410 * Clear the reply descriptor for re-use and increment 5411 * index. 5412 */ 5413 ddi_put64(mpt->m_acc_post_queue_hdl, 5414 &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index], 5415 0xFFFFFFFFFFFFFFFF); 5416 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 5417 DDI_DMA_SYNC_FORDEV); 5418 } 5419 5420 /* 5421 * handle qfull condition 5422 */ 5423 static void 5424 mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd) 5425 { 5426 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 5427 5428 if ((++cmd->cmd_qfull_retries > ptgt->m_qfull_retries) || 5429 (ptgt->m_qfull_retries == 0)) { 5430 /* 5431 * We have exhausted the retries on QFULL, or, 5432 * the target driver has indicated that it 5433 * wants to handle QFULL itself by setting 5434 * qfull-retries capability to 0. In either case 5435 * we want the target driver's QFULL handling 5436 * to kick in. We do this by having pkt_reason 5437 * as CMD_CMPLT and pkt_scbp as STATUS_QFULL. 5438 */ 5439 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5440 } else { 5441 if (ptgt->m_reset_delay == 0) { 5442 ptgt->m_t_throttle = 5443 max((ptgt->m_t_ncmds - 2), 0); 5444 } 5445 5446 cmd->cmd_pkt_flags |= FLAG_HEAD; 5447 cmd->cmd_flags &= ~(CFLAG_TRANFLAG); 5448 cmd->cmd_flags |= CFLAG_RETRY; 5449 5450 (void) mptsas_accept_pkt(mpt, cmd); 5451 5452 /* 5453 * when target gives queue full status with no commands 5454 * outstanding (m_t_ncmds == 0), throttle is set to 0 5455 * (HOLD_THROTTLE), and the queue full handling start 5456 * (see psarc/1994/313); if there are commands outstanding, 5457 * throttle is set to (m_t_ncmds - 2) 5458 */ 5459 if (ptgt->m_t_throttle == HOLD_THROTTLE) { 5460 /* 5461 * By setting throttle to QFULL_THROTTLE, we 5462 * avoid submitting new commands and in 5463 * mptsas_restart_cmd find out slots which need 5464 * their throttles to be cleared. 5465 */ 5466 mptsas_set_throttle(mpt, ptgt, QFULL_THROTTLE); 5467 if (mpt->m_restart_cmd_timeid == 0) { 5468 mpt->m_restart_cmd_timeid = 5469 timeout(mptsas_restart_cmd, mpt, 5470 ptgt->m_qfull_retry_interval); 5471 } 5472 } 5473 } 5474 } 5475 5476 mptsas_phymask_t 5477 mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport) 5478 { 5479 mptsas_phymask_t phy_mask = 0; 5480 uint8_t i = 0; 5481 5482 NDBG20(("mptsas%d physport_to_phymask enter", mpt->m_instance)); 5483 5484 ASSERT(mutex_owned(&mpt->m_mutex)); 5485 5486 /* 5487 * If physport is 0xFF, this is a RAID volume. Use phymask of 0. 5488 */ 5489 if (physport == 0xFF) { 5490 return (0); 5491 } 5492 5493 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 5494 if (mpt->m_phy_info[i].attached_devhdl && 5495 (mpt->m_phy_info[i].phy_mask != 0) && 5496 (mpt->m_phy_info[i].port_num == physport)) { 5497 phy_mask = mpt->m_phy_info[i].phy_mask; 5498 break; 5499 } 5500 } 5501 NDBG20(("mptsas%d physport_to_phymask:physport :%x phymask :%x, ", 5502 mpt->m_instance, physport, phy_mask)); 5503 return (phy_mask); 5504 } 5505 5506 /* 5507 * mpt free device handle after device gone, by use of passthrough 5508 */ 5509 static int 5510 mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl) 5511 { 5512 Mpi2SasIoUnitControlRequest_t req; 5513 Mpi2SasIoUnitControlReply_t rep; 5514 int ret; 5515 5516 ASSERT(mutex_owned(&mpt->m_mutex)); 5517 5518 /* 5519 * Need to compose a SAS IO Unit Control request message 5520 * and call mptsas_do_passthru() function 5521 */ 5522 bzero(&req, sizeof (req)); 5523 bzero(&rep, sizeof (rep)); 5524 5525 req.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 5526 req.Operation = MPI2_SAS_OP_REMOVE_DEVICE; 5527 req.DevHandle = LE_16(devhdl); 5528 5529 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL, 5530 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL); 5531 if (ret != 0) { 5532 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit " 5533 "Control error %d", ret); 5534 return (DDI_FAILURE); 5535 } 5536 5537 /* do passthrough success, check the ioc status */ 5538 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 5539 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit " 5540 "Control IOCStatus %d", LE_16(rep.IOCStatus)); 5541 return (DDI_FAILURE); 5542 } 5543 5544 return (DDI_SUCCESS); 5545 } 5546 5547 static void 5548 mptsas_update_phymask(mptsas_t *mpt) 5549 { 5550 mptsas_phymask_t mask = 0, phy_mask; 5551 char *phy_mask_name; 5552 uint8_t current_port; 5553 int i, j; 5554 5555 NDBG20(("mptsas%d update phymask ", mpt->m_instance)); 5556 5557 ASSERT(mutex_owned(&mpt->m_mutex)); 5558 5559 (void) mptsas_get_sas_io_unit_page(mpt); 5560 5561 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 5562 5563 for (i = 0; i < mpt->m_num_phys; i++) { 5564 phy_mask = 0x00; 5565 5566 if (mpt->m_phy_info[i].attached_devhdl == 0) 5567 continue; 5568 5569 bzero(phy_mask_name, sizeof (phy_mask_name)); 5570 5571 current_port = mpt->m_phy_info[i].port_num; 5572 5573 if ((mask & (1 << i)) != 0) 5574 continue; 5575 5576 for (j = 0; j < mpt->m_num_phys; j++) { 5577 if (mpt->m_phy_info[j].attached_devhdl && 5578 (mpt->m_phy_info[j].port_num == current_port)) { 5579 phy_mask |= (1 << j); 5580 } 5581 } 5582 mask = mask | phy_mask; 5583 5584 for (j = 0; j < mpt->m_num_phys; j++) { 5585 if ((phy_mask >> j) & 0x01) { 5586 mpt->m_phy_info[j].phy_mask = phy_mask; 5587 } 5588 } 5589 5590 (void) sprintf(phy_mask_name, "%x", phy_mask); 5591 5592 mutex_exit(&mpt->m_mutex); 5593 /* 5594 * register a iport, if the port has already been existed 5595 * SCSA will do nothing and just return. 5596 */ 5597 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name); 5598 mutex_enter(&mpt->m_mutex); 5599 } 5600 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 5601 NDBG20(("mptsas%d update phymask return", mpt->m_instance)); 5602 } 5603 5604 /* 5605 * mptsas_handle_dr is a task handler for DR, the DR action includes: 5606 * 1. Directly attched Device Added/Removed. 5607 * 2. Expander Device Added/Removed. 5608 * 3. Indirectly Attached Device Added/Expander. 5609 * 4. LUNs of a existing device status change. 5610 * 5. RAID volume created/deleted. 5611 * 6. Member of RAID volume is released because of RAID deletion. 5612 * 7. Physical disks are removed because of RAID creation. 5613 */ 5614 static void 5615 mptsas_handle_dr(void *args) { 5616 mptsas_topo_change_list_t *topo_node = NULL; 5617 mptsas_topo_change_list_t *save_node = NULL; 5618 mptsas_t *mpt; 5619 dev_info_t *parent = NULL; 5620 mptsas_phymask_t phymask = 0; 5621 char *phy_mask_name; 5622 uint8_t flags = 0, physport = 0xff; 5623 uint8_t port_update = 0; 5624 uint_t event; 5625 5626 topo_node = (mptsas_topo_change_list_t *)args; 5627 5628 mpt = topo_node->mpt; 5629 event = topo_node->event; 5630 flags = topo_node->flags; 5631 5632 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 5633 5634 NDBG20(("mptsas%d handle_dr enter", mpt->m_instance)); 5635 5636 switch (event) { 5637 case MPTSAS_DR_EVENT_RECONFIG_TARGET: 5638 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 5639 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE) || 5640 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) { 5641 /* 5642 * Direct attached or expander attached device added 5643 * into system or a Phys Disk that is being unhidden. 5644 */ 5645 port_update = 1; 5646 } 5647 break; 5648 case MPTSAS_DR_EVENT_RECONFIG_SMP: 5649 /* 5650 * New expander added into system, it must be the head 5651 * of topo_change_list_t 5652 */ 5653 port_update = 1; 5654 break; 5655 default: 5656 port_update = 0; 5657 break; 5658 } 5659 /* 5660 * All cases port_update == 1 may cause initiator port form change 5661 */ 5662 mutex_enter(&mpt->m_mutex); 5663 if (mpt->m_port_chng && port_update) { 5664 /* 5665 * mpt->m_port_chng flag indicates some PHYs of initiator 5666 * port have changed to online. So when expander added or 5667 * directly attached device online event come, we force to 5668 * update port information by issueing SAS IO Unit Page and 5669 * update PHYMASKs. 5670 */ 5671 (void) mptsas_update_phymask(mpt); 5672 mpt->m_port_chng = 0; 5673 5674 } 5675 mutex_exit(&mpt->m_mutex); 5676 while (topo_node) { 5677 phymask = 0; 5678 if (parent == NULL) { 5679 physport = topo_node->un.physport; 5680 event = topo_node->event; 5681 flags = topo_node->flags; 5682 if (event & (MPTSAS_DR_EVENT_OFFLINE_TARGET | 5683 MPTSAS_DR_EVENT_OFFLINE_SMP)) { 5684 /* 5685 * For all offline events, phymask is known 5686 */ 5687 phymask = topo_node->un.phymask; 5688 goto find_parent; 5689 } 5690 if (event & MPTSAS_TOPO_FLAG_REMOVE_HANDLE) { 5691 goto handle_topo_change; 5692 } 5693 if (flags & MPTSAS_TOPO_FLAG_LUN_ASSOCIATED) { 5694 phymask = topo_node->un.phymask; 5695 goto find_parent; 5696 } 5697 5698 if ((flags == 5699 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) && 5700 (event == MPTSAS_DR_EVENT_RECONFIG_TARGET)) { 5701 /* 5702 * There is no any field in IR_CONFIG_CHANGE 5703 * event indicate physport/phynum, let's get 5704 * parent after SAS Device Page0 request. 5705 */ 5706 goto handle_topo_change; 5707 } 5708 5709 mutex_enter(&mpt->m_mutex); 5710 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 5711 /* 5712 * If the direct attached device added or a 5713 * phys disk is being unhidden, argument 5714 * physport actually is PHY#, so we have to get 5715 * phymask according PHY#. 5716 */ 5717 physport = mpt->m_phy_info[physport].port_num; 5718 } 5719 5720 /* 5721 * Translate physport to phymask so that we can search 5722 * parent dip. 5723 */ 5724 phymask = mptsas_physport_to_phymask(mpt, 5725 physport); 5726 mutex_exit(&mpt->m_mutex); 5727 5728 find_parent: 5729 bzero(phy_mask_name, MPTSAS_MAX_PHYS); 5730 /* 5731 * For RAID topology change node, write the iport name 5732 * as v0. 5733 */ 5734 if (flags & MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 5735 (void) sprintf(phy_mask_name, "v0"); 5736 } else { 5737 /* 5738 * phymask can bo 0 if the drive has been 5739 * pulled by the time an add event is 5740 * processed. If phymask is 0, just skip this 5741 * event and continue. 5742 */ 5743 if (phymask == 0) { 5744 mutex_enter(&mpt->m_mutex); 5745 save_node = topo_node; 5746 topo_node = topo_node->next; 5747 ASSERT(save_node); 5748 kmem_free(save_node, 5749 sizeof (mptsas_topo_change_list_t)); 5750 mutex_exit(&mpt->m_mutex); 5751 5752 parent = NULL; 5753 continue; 5754 } 5755 (void) sprintf(phy_mask_name, "%x", phymask); 5756 } 5757 parent = scsi_hba_iport_find(mpt->m_dip, 5758 phy_mask_name); 5759 if (parent == NULL) { 5760 mptsas_log(mpt, CE_WARN, "Failed to find an " 5761 "iport, should not happen!"); 5762 goto out; 5763 } 5764 5765 } 5766 ASSERT(parent); 5767 handle_topo_change: 5768 5769 mutex_enter(&mpt->m_mutex); 5770 /* 5771 * If HBA is being reset, don't perform operations depending 5772 * on the IOC. We must free the topo list, however. 5773 */ 5774 if (!mpt->m_in_reset) 5775 mptsas_handle_topo_change(topo_node, parent); 5776 else 5777 NDBG20(("skipping topo change received during reset")); 5778 save_node = topo_node; 5779 topo_node = topo_node->next; 5780 ASSERT(save_node); 5781 kmem_free(save_node, sizeof (mptsas_topo_change_list_t)); 5782 mutex_exit(&mpt->m_mutex); 5783 5784 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 5785 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) || 5786 (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) { 5787 /* 5788 * If direct attached device associated, make sure 5789 * reset the parent before start the next one. But 5790 * all devices associated with expander shares the 5791 * parent. Also, reset parent if this is for RAID. 5792 */ 5793 parent = NULL; 5794 } 5795 } 5796 out: 5797 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 5798 } 5799 5800 static void 5801 mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node, 5802 dev_info_t *parent) 5803 { 5804 mptsas_target_t *ptgt = NULL; 5805 mptsas_smp_t *psmp = NULL; 5806 mptsas_t *mpt = (void *)topo_node->mpt; 5807 uint16_t devhdl; 5808 uint16_t attached_devhdl; 5809 uint64_t sas_wwn = 0; 5810 int rval = 0; 5811 uint32_t page_address; 5812 uint8_t phy, flags; 5813 char *addr = NULL; 5814 dev_info_t *lundip; 5815 int circ = 0, circ1 = 0; 5816 char attached_wwnstr[MPTSAS_WWN_STRLEN]; 5817 5818 NDBG20(("mptsas%d handle_topo_change enter", mpt->m_instance)); 5819 5820 ASSERT(mutex_owned(&mpt->m_mutex)); 5821 5822 switch (topo_node->event) { 5823 case MPTSAS_DR_EVENT_RECONFIG_TARGET: 5824 { 5825 char *phy_mask_name; 5826 mptsas_phymask_t phymask = 0; 5827 5828 if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 5829 /* 5830 * Get latest RAID info. 5831 */ 5832 (void) mptsas_get_raid_info(mpt); 5833 ptgt = mptsas_search_by_devhdl( 5834 &mpt->m_active->m_tgttbl, topo_node->devhdl); 5835 if (ptgt == NULL) 5836 break; 5837 } else { 5838 ptgt = (void *)topo_node->object; 5839 } 5840 5841 if (ptgt == NULL) { 5842 /* 5843 * If a Phys Disk was deleted, RAID info needs to be 5844 * updated to reflect the new topology. 5845 */ 5846 (void) mptsas_get_raid_info(mpt); 5847 5848 /* 5849 * Get sas device page 0 by DevHandle to make sure if 5850 * SSP/SATA end device exist. 5851 */ 5852 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 5853 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 5854 topo_node->devhdl; 5855 5856 rval = mptsas_get_target_device_info(mpt, page_address, 5857 &devhdl, &ptgt); 5858 if (rval == DEV_INFO_WRONG_DEVICE_TYPE) { 5859 mptsas_log(mpt, CE_NOTE, 5860 "mptsas_handle_topo_change: target %d is " 5861 "not a SAS/SATA device. \n", 5862 topo_node->devhdl); 5863 } else if (rval == DEV_INFO_FAIL_ALLOC) { 5864 mptsas_log(mpt, CE_NOTE, 5865 "mptsas_handle_topo_change: could not " 5866 "allocate memory. \n"); 5867 } 5868 /* 5869 * If rval is DEV_INFO_PHYS_DISK than there is nothing 5870 * else to do, just leave. 5871 */ 5872 if (rval != DEV_INFO_SUCCESS) { 5873 return; 5874 } 5875 } 5876 5877 ASSERT(ptgt->m_devhdl == topo_node->devhdl); 5878 5879 mutex_exit(&mpt->m_mutex); 5880 flags = topo_node->flags; 5881 5882 if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) { 5883 phymask = ptgt->m_phymask; 5884 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 5885 (void) sprintf(phy_mask_name, "%x", phymask); 5886 parent = scsi_hba_iport_find(mpt->m_dip, 5887 phy_mask_name); 5888 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 5889 if (parent == NULL) { 5890 mptsas_log(mpt, CE_WARN, "Failed to find a " 5891 "iport for PD, should not happen!"); 5892 mutex_enter(&mpt->m_mutex); 5893 break; 5894 } 5895 } 5896 5897 if (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 5898 ndi_devi_enter(parent, &circ1); 5899 (void) mptsas_config_raid(parent, topo_node->devhdl, 5900 &lundip); 5901 ndi_devi_exit(parent, circ1); 5902 } else { 5903 /* 5904 * hold nexus for bus configure 5905 */ 5906 ndi_devi_enter(scsi_vhci_dip, &circ); 5907 ndi_devi_enter(parent, &circ1); 5908 rval = mptsas_config_target(parent, ptgt); 5909 /* 5910 * release nexus for bus configure 5911 */ 5912 ndi_devi_exit(parent, circ1); 5913 ndi_devi_exit(scsi_vhci_dip, circ); 5914 5915 /* 5916 * Add parent's props for SMHBA support 5917 */ 5918 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 5919 bzero(attached_wwnstr, 5920 sizeof (attached_wwnstr)); 5921 (void) sprintf(attached_wwnstr, "w%016"PRIx64, 5922 ptgt->m_sas_wwn); 5923 if (ddi_prop_update_string(DDI_DEV_T_NONE, 5924 parent, 5925 SCSI_ADDR_PROP_ATTACHED_PORT, 5926 attached_wwnstr) 5927 != DDI_PROP_SUCCESS) { 5928 (void) ddi_prop_remove(DDI_DEV_T_NONE, 5929 parent, 5930 SCSI_ADDR_PROP_ATTACHED_PORT); 5931 mptsas_log(mpt, CE_WARN, "Failed to" 5932 "attached-port props"); 5933 return; 5934 } 5935 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 5936 MPTSAS_NUM_PHYS, 1) != 5937 DDI_PROP_SUCCESS) { 5938 (void) ddi_prop_remove(DDI_DEV_T_NONE, 5939 parent, MPTSAS_NUM_PHYS); 5940 mptsas_log(mpt, CE_WARN, "Failed to" 5941 " create num-phys props"); 5942 return; 5943 } 5944 5945 /* 5946 * Update PHY info for smhba 5947 */ 5948 mutex_enter(&mpt->m_mutex); 5949 if (mptsas_smhba_phy_init(mpt)) { 5950 mutex_exit(&mpt->m_mutex); 5951 mptsas_log(mpt, CE_WARN, "mptsas phy" 5952 " update failed"); 5953 return; 5954 } 5955 mutex_exit(&mpt->m_mutex); 5956 5957 /* 5958 * topo_node->un.physport is really the PHY# 5959 * for direct attached devices 5960 */ 5961 mptsas_smhba_set_one_phy_props(mpt, parent, 5962 topo_node->un.physport, &attached_devhdl); 5963 5964 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 5965 MPTSAS_VIRTUAL_PORT, 0) != 5966 DDI_PROP_SUCCESS) { 5967 (void) ddi_prop_remove(DDI_DEV_T_NONE, 5968 parent, MPTSAS_VIRTUAL_PORT); 5969 mptsas_log(mpt, CE_WARN, 5970 "mptsas virtual-port" 5971 "port prop update failed"); 5972 return; 5973 } 5974 } 5975 } 5976 mutex_enter(&mpt->m_mutex); 5977 5978 NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, " 5979 "phymask:%x.", mpt->m_instance, ptgt->m_devhdl, 5980 ptgt->m_phymask)); 5981 break; 5982 } 5983 case MPTSAS_DR_EVENT_OFFLINE_TARGET: 5984 { 5985 mptsas_hash_table_t *tgttbl = &mpt->m_active->m_tgttbl; 5986 devhdl = topo_node->devhdl; 5987 ptgt = mptsas_search_by_devhdl(tgttbl, devhdl); 5988 if (ptgt == NULL) 5989 break; 5990 5991 sas_wwn = ptgt->m_sas_wwn; 5992 phy = ptgt->m_phynum; 5993 5994 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 5995 5996 if (sas_wwn) { 5997 (void) sprintf(addr, "w%016"PRIx64, sas_wwn); 5998 } else { 5999 (void) sprintf(addr, "p%x", phy); 6000 } 6001 ASSERT(ptgt->m_devhdl == devhdl); 6002 6003 if ((topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) || 6004 (topo_node->flags == 6005 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) { 6006 /* 6007 * Get latest RAID info if RAID volume status changes 6008 * or Phys Disk status changes 6009 */ 6010 (void) mptsas_get_raid_info(mpt); 6011 } 6012 /* 6013 * Abort all outstanding command on the device 6014 */ 6015 rval = mptsas_do_scsi_reset(mpt, devhdl); 6016 if (rval) { 6017 NDBG20(("mptsas%d handle_topo_change to reset target " 6018 "before offline devhdl:%x, phymask:%x, rval:%x", 6019 mpt->m_instance, ptgt->m_devhdl, ptgt->m_phymask, 6020 rval)); 6021 } 6022 6023 mutex_exit(&mpt->m_mutex); 6024 6025 ndi_devi_enter(scsi_vhci_dip, &circ); 6026 ndi_devi_enter(parent, &circ1); 6027 rval = mptsas_offline_target(parent, addr); 6028 ndi_devi_exit(parent, circ1); 6029 ndi_devi_exit(scsi_vhci_dip, circ); 6030 NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, " 6031 "phymask:%x, rval:%x", mpt->m_instance, 6032 ptgt->m_devhdl, ptgt->m_phymask, rval)); 6033 6034 kmem_free(addr, SCSI_MAXNAMELEN); 6035 6036 /* 6037 * Clear parent's props for SMHBA support 6038 */ 6039 flags = topo_node->flags; 6040 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 6041 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6042 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent, 6043 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 6044 DDI_PROP_SUCCESS) { 6045 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6046 SCSI_ADDR_PROP_ATTACHED_PORT); 6047 mptsas_log(mpt, CE_WARN, "mptsas attached port " 6048 "prop update failed"); 6049 break; 6050 } 6051 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6052 MPTSAS_NUM_PHYS, 0) != 6053 DDI_PROP_SUCCESS) { 6054 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6055 MPTSAS_NUM_PHYS); 6056 mptsas_log(mpt, CE_WARN, "mptsas num phys " 6057 "prop update failed"); 6058 break; 6059 } 6060 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6061 MPTSAS_VIRTUAL_PORT, 1) != 6062 DDI_PROP_SUCCESS) { 6063 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6064 MPTSAS_VIRTUAL_PORT); 6065 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 6066 "prop update failed"); 6067 break; 6068 } 6069 } 6070 6071 mutex_enter(&mpt->m_mutex); 6072 ptgt->m_led_status = 0; 6073 (void) mptsas_flush_led_status(mpt, ptgt); 6074 if (rval == DDI_SUCCESS) { 6075 mptsas_tgt_free(&mpt->m_active->m_tgttbl, 6076 ptgt->m_sas_wwn, ptgt->m_phymask); 6077 ptgt = NULL; 6078 } else { 6079 /* 6080 * clean DR_INTRANSITION flag to allow I/O down to 6081 * PHCI driver since failover finished. 6082 * Invalidate the devhdl 6083 */ 6084 ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL; 6085 ptgt->m_tgt_unconfigured = 0; 6086 mutex_enter(&mpt->m_tx_waitq_mutex); 6087 ptgt->m_dr_flag = MPTSAS_DR_INACTIVE; 6088 mutex_exit(&mpt->m_tx_waitq_mutex); 6089 } 6090 6091 /* 6092 * Send SAS IO Unit Control to free the dev handle 6093 */ 6094 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 6095 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE)) { 6096 rval = mptsas_free_devhdl(mpt, devhdl); 6097 6098 NDBG20(("mptsas%d handle_topo_change to remove " 6099 "devhdl:%x, rval:%x", mpt->m_instance, devhdl, 6100 rval)); 6101 } 6102 6103 break; 6104 } 6105 case MPTSAS_TOPO_FLAG_REMOVE_HANDLE: 6106 { 6107 devhdl = topo_node->devhdl; 6108 /* 6109 * If this is the remove handle event, do a reset first. 6110 */ 6111 if (topo_node->event == MPTSAS_TOPO_FLAG_REMOVE_HANDLE) { 6112 rval = mptsas_do_scsi_reset(mpt, devhdl); 6113 if (rval) { 6114 NDBG20(("mpt%d reset target before remove " 6115 "devhdl:%x, rval:%x", mpt->m_instance, 6116 devhdl, rval)); 6117 } 6118 } 6119 6120 /* 6121 * Send SAS IO Unit Control to free the dev handle 6122 */ 6123 rval = mptsas_free_devhdl(mpt, devhdl); 6124 NDBG20(("mptsas%d handle_topo_change to remove " 6125 "devhdl:%x, rval:%x", mpt->m_instance, devhdl, 6126 rval)); 6127 break; 6128 } 6129 case MPTSAS_DR_EVENT_RECONFIG_SMP: 6130 { 6131 mptsas_smp_t smp; 6132 dev_info_t *smpdip; 6133 mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl; 6134 6135 devhdl = topo_node->devhdl; 6136 6137 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL & 6138 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl; 6139 rval = mptsas_get_sas_expander_page0(mpt, page_address, &smp); 6140 if (rval != DDI_SUCCESS) { 6141 mptsas_log(mpt, CE_WARN, "failed to online smp, " 6142 "handle %x", devhdl); 6143 return; 6144 } 6145 6146 psmp = mptsas_smp_alloc(smptbl, &smp); 6147 if (psmp == NULL) { 6148 return; 6149 } 6150 6151 mutex_exit(&mpt->m_mutex); 6152 ndi_devi_enter(parent, &circ1); 6153 (void) mptsas_online_smp(parent, psmp, &smpdip); 6154 ndi_devi_exit(parent, circ1); 6155 6156 mutex_enter(&mpt->m_mutex); 6157 break; 6158 } 6159 case MPTSAS_DR_EVENT_OFFLINE_SMP: 6160 { 6161 mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl; 6162 devhdl = topo_node->devhdl; 6163 uint32_t dev_info; 6164 6165 psmp = mptsas_search_by_devhdl(smptbl, devhdl); 6166 if (psmp == NULL) 6167 break; 6168 /* 6169 * The mptsas_smp_t data is released only if the dip is offlined 6170 * successfully. 6171 */ 6172 mutex_exit(&mpt->m_mutex); 6173 6174 ndi_devi_enter(parent, &circ1); 6175 rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE); 6176 ndi_devi_exit(parent, circ1); 6177 6178 dev_info = psmp->m_deviceinfo; 6179 if ((dev_info & DEVINFO_DIRECT_ATTACHED) == 6180 DEVINFO_DIRECT_ATTACHED) { 6181 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6182 MPTSAS_VIRTUAL_PORT, 1) != 6183 DDI_PROP_SUCCESS) { 6184 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6185 MPTSAS_VIRTUAL_PORT); 6186 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 6187 "prop update failed"); 6188 return; 6189 } 6190 /* 6191 * Check whether the smp connected to the iport, 6192 */ 6193 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6194 MPTSAS_NUM_PHYS, 0) != 6195 DDI_PROP_SUCCESS) { 6196 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6197 MPTSAS_NUM_PHYS); 6198 mptsas_log(mpt, CE_WARN, "mptsas num phys" 6199 "prop update failed"); 6200 return; 6201 } 6202 /* 6203 * Clear parent's attached-port props 6204 */ 6205 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6206 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent, 6207 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 6208 DDI_PROP_SUCCESS) { 6209 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6210 SCSI_ADDR_PROP_ATTACHED_PORT); 6211 mptsas_log(mpt, CE_WARN, "mptsas attached port " 6212 "prop update failed"); 6213 return; 6214 } 6215 } 6216 6217 mutex_enter(&mpt->m_mutex); 6218 NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, " 6219 "rval:%x", mpt->m_instance, psmp->m_devhdl, rval)); 6220 if (rval == DDI_SUCCESS) { 6221 mptsas_smp_free(smptbl, psmp->m_sasaddr, 6222 psmp->m_phymask); 6223 } else { 6224 psmp->m_devhdl = MPTSAS_INVALID_DEVHDL; 6225 } 6226 6227 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6228 6229 break; 6230 } 6231 default: 6232 return; 6233 } 6234 } 6235 6236 /* 6237 * Record the event if its type is enabled in mpt instance by ioctl. 6238 */ 6239 static void 6240 mptsas_record_event(void *args) 6241 { 6242 m_replyh_arg_t *replyh_arg; 6243 pMpi2EventNotificationReply_t eventreply; 6244 uint32_t event, rfm; 6245 mptsas_t *mpt; 6246 int i, j; 6247 uint16_t event_data_len; 6248 boolean_t sendAEN = FALSE; 6249 6250 replyh_arg = (m_replyh_arg_t *)args; 6251 rfm = replyh_arg->rfm; 6252 mpt = replyh_arg->mpt; 6253 6254 eventreply = (pMpi2EventNotificationReply_t) 6255 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr)); 6256 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 6257 6258 6259 /* 6260 * Generate a system event to let anyone who cares know that a 6261 * LOG_ENTRY_ADDED event has occurred. This is sent no matter what the 6262 * event mask is set to. 6263 */ 6264 if (event == MPI2_EVENT_LOG_ENTRY_ADDED) { 6265 sendAEN = TRUE; 6266 } 6267 6268 /* 6269 * Record the event only if it is not masked. Determine which dword 6270 * and bit of event mask to test. 6271 */ 6272 i = (uint8_t)(event / 32); 6273 j = (uint8_t)(event % 32); 6274 if ((i < 4) && ((1 << j) & mpt->m_event_mask[i])) { 6275 i = mpt->m_event_index; 6276 mpt->m_events[i].Type = event; 6277 mpt->m_events[i].Number = ++mpt->m_event_number; 6278 bzero(mpt->m_events[i].Data, MPTSAS_MAX_EVENT_DATA_LENGTH * 4); 6279 event_data_len = ddi_get16(mpt->m_acc_reply_frame_hdl, 6280 &eventreply->EventDataLength); 6281 6282 if (event_data_len > 0) { 6283 /* 6284 * Limit data to size in m_event entry 6285 */ 6286 if (event_data_len > MPTSAS_MAX_EVENT_DATA_LENGTH) { 6287 event_data_len = MPTSAS_MAX_EVENT_DATA_LENGTH; 6288 } 6289 for (j = 0; j < event_data_len; j++) { 6290 mpt->m_events[i].Data[j] = 6291 ddi_get32(mpt->m_acc_reply_frame_hdl, 6292 &(eventreply->EventData[j])); 6293 } 6294 6295 /* 6296 * check for index wrap-around 6297 */ 6298 if (++i == MPTSAS_EVENT_QUEUE_SIZE) { 6299 i = 0; 6300 } 6301 mpt->m_event_index = (uint8_t)i; 6302 6303 /* 6304 * Set flag to send the event. 6305 */ 6306 sendAEN = TRUE; 6307 } 6308 } 6309 6310 /* 6311 * Generate a system event if flag is set to let anyone who cares know 6312 * that an event has occurred. 6313 */ 6314 if (sendAEN) { 6315 (void) ddi_log_sysevent(mpt->m_dip, DDI_VENDOR_LSI, "MPT_SAS", 6316 "SAS", NULL, NULL, DDI_NOSLEEP); 6317 } 6318 } 6319 6320 #define SMP_RESET_IN_PROGRESS MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS 6321 /* 6322 * handle sync events from ioc in interrupt 6323 * return value: 6324 * DDI_SUCCESS: The event is handled by this func 6325 * DDI_FAILURE: Event is not handled 6326 */ 6327 static int 6328 mptsas_handle_event_sync(void *args) 6329 { 6330 m_replyh_arg_t *replyh_arg; 6331 pMpi2EventNotificationReply_t eventreply; 6332 uint32_t event, rfm; 6333 mptsas_t *mpt; 6334 uint_t iocstatus; 6335 6336 replyh_arg = (m_replyh_arg_t *)args; 6337 rfm = replyh_arg->rfm; 6338 mpt = replyh_arg->mpt; 6339 6340 ASSERT(mutex_owned(&mpt->m_mutex)); 6341 6342 eventreply = (pMpi2EventNotificationReply_t) 6343 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr)); 6344 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 6345 6346 if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 6347 &eventreply->IOCStatus)) { 6348 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 6349 mptsas_log(mpt, CE_WARN, 6350 "!mptsas_handle_event_sync: IOCStatus=0x%x, " 6351 "IOCLogInfo=0x%x", iocstatus, 6352 ddi_get32(mpt->m_acc_reply_frame_hdl, 6353 &eventreply->IOCLogInfo)); 6354 } else { 6355 mptsas_log(mpt, CE_WARN, 6356 "mptsas_handle_event_sync: IOCStatus=0x%x, " 6357 "IOCLogInfo=0x%x", iocstatus, 6358 ddi_get32(mpt->m_acc_reply_frame_hdl, 6359 &eventreply->IOCLogInfo)); 6360 } 6361 } 6362 6363 /* 6364 * figure out what kind of event we got and handle accordingly 6365 */ 6366 switch (event) { 6367 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 6368 { 6369 pMpi2EventDataSasTopologyChangeList_t sas_topo_change_list; 6370 uint8_t num_entries, expstatus, phy; 6371 uint8_t phystatus, physport, state, i; 6372 uint8_t start_phy_num, link_rate; 6373 uint16_t dev_handle, reason_code; 6374 uint16_t enc_handle, expd_handle; 6375 char string[80], curr[80], prev[80]; 6376 mptsas_topo_change_list_t *topo_head = NULL; 6377 mptsas_topo_change_list_t *topo_tail = NULL; 6378 mptsas_topo_change_list_t *topo_node = NULL; 6379 mptsas_target_t *ptgt; 6380 mptsas_smp_t *psmp; 6381 mptsas_hash_table_t *tgttbl, *smptbl; 6382 uint8_t flags = 0, exp_flag; 6383 smhba_info_t *pSmhba = NULL; 6384 6385 NDBG20(("mptsas_handle_event_sync: SAS topology change")); 6386 6387 tgttbl = &mpt->m_active->m_tgttbl; 6388 smptbl = &mpt->m_active->m_smptbl; 6389 6390 sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t) 6391 eventreply->EventData; 6392 6393 enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6394 &sas_topo_change_list->EnclosureHandle); 6395 expd_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6396 &sas_topo_change_list->ExpanderDevHandle); 6397 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl, 6398 &sas_topo_change_list->NumEntries); 6399 start_phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl, 6400 &sas_topo_change_list->StartPhyNum); 6401 expstatus = ddi_get8(mpt->m_acc_reply_frame_hdl, 6402 &sas_topo_change_list->ExpStatus); 6403 physport = ddi_get8(mpt->m_acc_reply_frame_hdl, 6404 &sas_topo_change_list->PhysicalPort); 6405 6406 string[0] = 0; 6407 if (expd_handle) { 6408 flags = MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED; 6409 switch (expstatus) { 6410 case MPI2_EVENT_SAS_TOPO_ES_ADDED: 6411 (void) sprintf(string, " added"); 6412 /* 6413 * New expander device added 6414 */ 6415 mpt->m_port_chng = 1; 6416 topo_node = kmem_zalloc( 6417 sizeof (mptsas_topo_change_list_t), 6418 KM_SLEEP); 6419 topo_node->mpt = mpt; 6420 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_SMP; 6421 topo_node->un.physport = physport; 6422 topo_node->devhdl = expd_handle; 6423 topo_node->flags = flags; 6424 topo_node->object = NULL; 6425 if (topo_head == NULL) { 6426 topo_head = topo_tail = topo_node; 6427 } else { 6428 topo_tail->next = topo_node; 6429 topo_tail = topo_node; 6430 } 6431 break; 6432 case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING: 6433 (void) sprintf(string, " not responding, " 6434 "removed"); 6435 psmp = mptsas_search_by_devhdl(smptbl, 6436 expd_handle); 6437 if (psmp == NULL) 6438 break; 6439 6440 topo_node = kmem_zalloc( 6441 sizeof (mptsas_topo_change_list_t), 6442 KM_SLEEP); 6443 topo_node->mpt = mpt; 6444 topo_node->un.phymask = psmp->m_phymask; 6445 topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP; 6446 topo_node->devhdl = expd_handle; 6447 topo_node->flags = flags; 6448 topo_node->object = NULL; 6449 if (topo_head == NULL) { 6450 topo_head = topo_tail = topo_node; 6451 } else { 6452 topo_tail->next = topo_node; 6453 topo_tail = topo_node; 6454 } 6455 break; 6456 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING: 6457 break; 6458 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING: 6459 (void) sprintf(string, " not responding, " 6460 "delaying removal"); 6461 break; 6462 default: 6463 break; 6464 } 6465 } else { 6466 flags = MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE; 6467 } 6468 6469 NDBG20(("SAS TOPOLOGY CHANGE for enclosure %x expander %x%s\n", 6470 enc_handle, expd_handle, string)); 6471 for (i = 0; i < num_entries; i++) { 6472 phy = i + start_phy_num; 6473 phystatus = ddi_get8(mpt->m_acc_reply_frame_hdl, 6474 &sas_topo_change_list->PHY[i].PhyStatus); 6475 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6476 &sas_topo_change_list->PHY[i].AttachedDevHandle); 6477 reason_code = phystatus & MPI2_EVENT_SAS_TOPO_RC_MASK; 6478 /* 6479 * Filter out processing of Phy Vacant Status unless 6480 * the reason code is "Not Responding". Process all 6481 * other combinations of Phy Status and Reason Codes. 6482 */ 6483 if ((phystatus & 6484 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) && 6485 (reason_code != 6486 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) { 6487 continue; 6488 } 6489 curr[0] = 0; 6490 prev[0] = 0; 6491 string[0] = 0; 6492 switch (reason_code) { 6493 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 6494 { 6495 NDBG20(("mptsas%d phy %d physical_port %d " 6496 "dev_handle %d added", mpt->m_instance, phy, 6497 physport, dev_handle)); 6498 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl, 6499 &sas_topo_change_list->PHY[i].LinkRate); 6500 state = (link_rate & 6501 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >> 6502 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT; 6503 switch (state) { 6504 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 6505 (void) sprintf(curr, "is disabled"); 6506 break; 6507 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 6508 (void) sprintf(curr, "is offline, " 6509 "failed speed negotiation"); 6510 break; 6511 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 6512 (void) sprintf(curr, "SATA OOB " 6513 "complete"); 6514 break; 6515 case SMP_RESET_IN_PROGRESS: 6516 (void) sprintf(curr, "SMP reset in " 6517 "progress"); 6518 break; 6519 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 6520 (void) sprintf(curr, "is online at " 6521 "1.5 Gbps"); 6522 break; 6523 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 6524 (void) sprintf(curr, "is online at 3.0 " 6525 "Gbps"); 6526 break; 6527 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 6528 (void) sprintf(curr, "is online at 6.0 " 6529 "Gbps"); 6530 break; 6531 default: 6532 (void) sprintf(curr, "state is " 6533 "unknown"); 6534 break; 6535 } 6536 /* 6537 * New target device added into the system. 6538 * Set association flag according to if an 6539 * expander is used or not. 6540 */ 6541 exp_flag = 6542 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE; 6543 if (flags == 6544 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) { 6545 flags = exp_flag; 6546 } 6547 topo_node = kmem_zalloc( 6548 sizeof (mptsas_topo_change_list_t), 6549 KM_SLEEP); 6550 topo_node->mpt = mpt; 6551 topo_node->event = 6552 MPTSAS_DR_EVENT_RECONFIG_TARGET; 6553 if (expd_handle == 0) { 6554 /* 6555 * Per MPI 2, if expander dev handle 6556 * is 0, it's a directly attached 6557 * device. So driver use PHY to decide 6558 * which iport is associated 6559 */ 6560 physport = phy; 6561 mpt->m_port_chng = 1; 6562 } 6563 topo_node->un.physport = physport; 6564 topo_node->devhdl = dev_handle; 6565 topo_node->flags = flags; 6566 topo_node->object = NULL; 6567 if (topo_head == NULL) { 6568 topo_head = topo_tail = topo_node; 6569 } else { 6570 topo_tail->next = topo_node; 6571 topo_tail = topo_node; 6572 } 6573 break; 6574 } 6575 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 6576 { 6577 NDBG20(("mptsas%d phy %d physical_port %d " 6578 "dev_handle %d removed", mpt->m_instance, 6579 phy, physport, dev_handle)); 6580 /* 6581 * Set association flag according to if an 6582 * expander is used or not. 6583 */ 6584 exp_flag = 6585 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE; 6586 if (flags == 6587 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) { 6588 flags = exp_flag; 6589 } 6590 /* 6591 * Target device is removed from the system 6592 * Before the device is really offline from 6593 * from system. 6594 */ 6595 ptgt = mptsas_search_by_devhdl(tgttbl, 6596 dev_handle); 6597 /* 6598 * If ptgt is NULL here, it means that the 6599 * DevHandle is not in the hash table. This is 6600 * reasonable sometimes. For example, if a 6601 * disk was pulled, then added, then pulled 6602 * again, the disk will not have been put into 6603 * the hash table because the add event will 6604 * have an invalid phymask. BUT, this does not 6605 * mean that the DevHandle is invalid. The 6606 * controller will still have a valid DevHandle 6607 * that must be removed. To do this, use the 6608 * MPTSAS_TOPO_FLAG_REMOVE_HANDLE event. 6609 */ 6610 if (ptgt == NULL) { 6611 topo_node = kmem_zalloc( 6612 sizeof (mptsas_topo_change_list_t), 6613 KM_SLEEP); 6614 topo_node->mpt = mpt; 6615 topo_node->un.phymask = 0; 6616 topo_node->event = 6617 MPTSAS_TOPO_FLAG_REMOVE_HANDLE; 6618 topo_node->devhdl = dev_handle; 6619 topo_node->flags = flags; 6620 topo_node->object = NULL; 6621 if (topo_head == NULL) { 6622 topo_head = topo_tail = 6623 topo_node; 6624 } else { 6625 topo_tail->next = topo_node; 6626 topo_tail = topo_node; 6627 } 6628 break; 6629 } 6630 6631 /* 6632 * Update DR flag immediately avoid I/O failure 6633 * before failover finish. Pay attention to the 6634 * mutex protect, we need grab m_tx_waitq_mutex 6635 * during set m_dr_flag because we won't add 6636 * the following command into waitq, instead, 6637 * we need return TRAN_BUSY in the tran_start 6638 * context. 6639 */ 6640 mutex_enter(&mpt->m_tx_waitq_mutex); 6641 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 6642 mutex_exit(&mpt->m_tx_waitq_mutex); 6643 6644 topo_node = kmem_zalloc( 6645 sizeof (mptsas_topo_change_list_t), 6646 KM_SLEEP); 6647 topo_node->mpt = mpt; 6648 topo_node->un.phymask = ptgt->m_phymask; 6649 topo_node->event = 6650 MPTSAS_DR_EVENT_OFFLINE_TARGET; 6651 topo_node->devhdl = dev_handle; 6652 topo_node->flags = flags; 6653 topo_node->object = NULL; 6654 if (topo_head == NULL) { 6655 topo_head = topo_tail = topo_node; 6656 } else { 6657 topo_tail->next = topo_node; 6658 topo_tail = topo_node; 6659 } 6660 break; 6661 } 6662 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 6663 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl, 6664 &sas_topo_change_list->PHY[i].LinkRate); 6665 state = (link_rate & 6666 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >> 6667 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT; 6668 pSmhba = &mpt->m_phy_info[i].smhba_info; 6669 pSmhba->negotiated_link_rate = state; 6670 switch (state) { 6671 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 6672 (void) sprintf(curr, "is disabled"); 6673 mptsas_smhba_log_sysevent(mpt, 6674 ESC_SAS_PHY_EVENT, 6675 SAS_PHY_REMOVE, 6676 &mpt->m_phy_info[i].smhba_info); 6677 mpt->m_phy_info[i].smhba_info. 6678 negotiated_link_rate 6679 = 0x1; 6680 break; 6681 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 6682 (void) sprintf(curr, "is offline, " 6683 "failed speed negotiation"); 6684 mptsas_smhba_log_sysevent(mpt, 6685 ESC_SAS_PHY_EVENT, 6686 SAS_PHY_OFFLINE, 6687 &mpt->m_phy_info[i].smhba_info); 6688 break; 6689 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 6690 (void) sprintf(curr, "SATA OOB " 6691 "complete"); 6692 break; 6693 case SMP_RESET_IN_PROGRESS: 6694 (void) sprintf(curr, "SMP reset in " 6695 "progress"); 6696 break; 6697 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 6698 (void) sprintf(curr, "is online at " 6699 "1.5 Gbps"); 6700 if ((expd_handle == 0) && 6701 (enc_handle == 1)) { 6702 mpt->m_port_chng = 1; 6703 } 6704 mptsas_smhba_log_sysevent(mpt, 6705 ESC_SAS_PHY_EVENT, 6706 SAS_PHY_ONLINE, 6707 &mpt->m_phy_info[i].smhba_info); 6708 break; 6709 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 6710 (void) sprintf(curr, "is online at 3.0 " 6711 "Gbps"); 6712 if ((expd_handle == 0) && 6713 (enc_handle == 1)) { 6714 mpt->m_port_chng = 1; 6715 } 6716 mptsas_smhba_log_sysevent(mpt, 6717 ESC_SAS_PHY_EVENT, 6718 SAS_PHY_ONLINE, 6719 &mpt->m_phy_info[i].smhba_info); 6720 break; 6721 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 6722 (void) sprintf(curr, "is online at " 6723 "6.0 Gbps"); 6724 if ((expd_handle == 0) && 6725 (enc_handle == 1)) { 6726 mpt->m_port_chng = 1; 6727 } 6728 mptsas_smhba_log_sysevent(mpt, 6729 ESC_SAS_PHY_EVENT, 6730 SAS_PHY_ONLINE, 6731 &mpt->m_phy_info[i].smhba_info); 6732 break; 6733 default: 6734 (void) sprintf(curr, "state is " 6735 "unknown"); 6736 break; 6737 } 6738 6739 state = (link_rate & 6740 MPI2_EVENT_SAS_TOPO_LR_PREV_MASK) >> 6741 MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT; 6742 switch (state) { 6743 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 6744 (void) sprintf(prev, ", was disabled"); 6745 break; 6746 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 6747 (void) sprintf(prev, ", was offline, " 6748 "failed speed negotiation"); 6749 break; 6750 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 6751 (void) sprintf(prev, ", was SATA OOB " 6752 "complete"); 6753 break; 6754 case SMP_RESET_IN_PROGRESS: 6755 (void) sprintf(prev, ", was SMP reset " 6756 "in progress"); 6757 break; 6758 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 6759 (void) sprintf(prev, ", was online at " 6760 "1.5 Gbps"); 6761 break; 6762 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 6763 (void) sprintf(prev, ", was online at " 6764 "3.0 Gbps"); 6765 break; 6766 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 6767 (void) sprintf(prev, ", was online at " 6768 "6.0 Gbps"); 6769 break; 6770 default: 6771 break; 6772 } 6773 (void) sprintf(&string[strlen(string)], "link " 6774 "changed, "); 6775 break; 6776 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE: 6777 continue; 6778 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING: 6779 (void) sprintf(&string[strlen(string)], 6780 "target not responding, delaying " 6781 "removal"); 6782 break; 6783 } 6784 NDBG20(("mptsas%d phy %d DevHandle %x, %s%s%s\n", 6785 mpt->m_instance, phy, dev_handle, string, curr, 6786 prev)); 6787 } 6788 if (topo_head != NULL) { 6789 /* 6790 * Launch DR taskq to handle topology change 6791 */ 6792 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 6793 mptsas_handle_dr, (void *)topo_head, 6794 DDI_NOSLEEP)) != DDI_SUCCESS) { 6795 mptsas_log(mpt, CE_NOTE, "mptsas start taskq " 6796 "for handle SAS DR event failed. \n"); 6797 } 6798 } 6799 break; 6800 } 6801 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 6802 { 6803 Mpi2EventDataIrConfigChangeList_t *irChangeList; 6804 mptsas_topo_change_list_t *topo_head = NULL; 6805 mptsas_topo_change_list_t *topo_tail = NULL; 6806 mptsas_topo_change_list_t *topo_node = NULL; 6807 mptsas_target_t *ptgt; 6808 mptsas_hash_table_t *tgttbl; 6809 uint8_t num_entries, i, reason; 6810 uint16_t volhandle, diskhandle; 6811 6812 irChangeList = (pMpi2EventDataIrConfigChangeList_t) 6813 eventreply->EventData; 6814 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl, 6815 &irChangeList->NumElements); 6816 6817 tgttbl = &mpt->m_active->m_tgttbl; 6818 6819 NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received", 6820 mpt->m_instance)); 6821 6822 for (i = 0; i < num_entries; i++) { 6823 reason = ddi_get8(mpt->m_acc_reply_frame_hdl, 6824 &irChangeList->ConfigElement[i].ReasonCode); 6825 volhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6826 &irChangeList->ConfigElement[i].VolDevHandle); 6827 diskhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6828 &irChangeList->ConfigElement[i].PhysDiskDevHandle); 6829 6830 switch (reason) { 6831 case MPI2_EVENT_IR_CHANGE_RC_ADDED: 6832 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: 6833 { 6834 NDBG20(("mptsas %d volume added\n", 6835 mpt->m_instance)); 6836 6837 topo_node = kmem_zalloc( 6838 sizeof (mptsas_topo_change_list_t), 6839 KM_SLEEP); 6840 6841 topo_node->mpt = mpt; 6842 topo_node->event = 6843 MPTSAS_DR_EVENT_RECONFIG_TARGET; 6844 topo_node->un.physport = 0xff; 6845 topo_node->devhdl = volhandle; 6846 topo_node->flags = 6847 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED; 6848 topo_node->object = NULL; 6849 if (topo_head == NULL) { 6850 topo_head = topo_tail = topo_node; 6851 } else { 6852 topo_tail->next = topo_node; 6853 topo_tail = topo_node; 6854 } 6855 break; 6856 } 6857 case MPI2_EVENT_IR_CHANGE_RC_REMOVED: 6858 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: 6859 { 6860 NDBG20(("mptsas %d volume deleted\n", 6861 mpt->m_instance)); 6862 ptgt = mptsas_search_by_devhdl(tgttbl, 6863 volhandle); 6864 if (ptgt == NULL) 6865 break; 6866 6867 /* 6868 * Clear any flags related to volume 6869 */ 6870 (void) mptsas_delete_volume(mpt, volhandle); 6871 6872 /* 6873 * Update DR flag immediately avoid I/O failure 6874 */ 6875 mutex_enter(&mpt->m_tx_waitq_mutex); 6876 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 6877 mutex_exit(&mpt->m_tx_waitq_mutex); 6878 6879 topo_node = kmem_zalloc( 6880 sizeof (mptsas_topo_change_list_t), 6881 KM_SLEEP); 6882 topo_node->mpt = mpt; 6883 topo_node->un.phymask = ptgt->m_phymask; 6884 topo_node->event = 6885 MPTSAS_DR_EVENT_OFFLINE_TARGET; 6886 topo_node->devhdl = volhandle; 6887 topo_node->flags = 6888 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED; 6889 topo_node->object = (void *)ptgt; 6890 if (topo_head == NULL) { 6891 topo_head = topo_tail = topo_node; 6892 } else { 6893 topo_tail->next = topo_node; 6894 topo_tail = topo_node; 6895 } 6896 break; 6897 } 6898 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: 6899 case MPI2_EVENT_IR_CHANGE_RC_HIDE: 6900 { 6901 ptgt = mptsas_search_by_devhdl(tgttbl, 6902 diskhandle); 6903 if (ptgt == NULL) 6904 break; 6905 6906 /* 6907 * Update DR flag immediately avoid I/O failure 6908 */ 6909 mutex_enter(&mpt->m_tx_waitq_mutex); 6910 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 6911 mutex_exit(&mpt->m_tx_waitq_mutex); 6912 6913 topo_node = kmem_zalloc( 6914 sizeof (mptsas_topo_change_list_t), 6915 KM_SLEEP); 6916 topo_node->mpt = mpt; 6917 topo_node->un.phymask = ptgt->m_phymask; 6918 topo_node->event = 6919 MPTSAS_DR_EVENT_OFFLINE_TARGET; 6920 topo_node->devhdl = diskhandle; 6921 topo_node->flags = 6922 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED; 6923 topo_node->object = (void *)ptgt; 6924 if (topo_head == NULL) { 6925 topo_head = topo_tail = topo_node; 6926 } else { 6927 topo_tail->next = topo_node; 6928 topo_tail = topo_node; 6929 } 6930 break; 6931 } 6932 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: 6933 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: 6934 { 6935 /* 6936 * The physical drive is released by a IR 6937 * volume. But we cannot get the the physport 6938 * or phynum from the event data, so we only 6939 * can get the physport/phynum after SAS 6940 * Device Page0 request for the devhdl. 6941 */ 6942 topo_node = kmem_zalloc( 6943 sizeof (mptsas_topo_change_list_t), 6944 KM_SLEEP); 6945 topo_node->mpt = mpt; 6946 topo_node->un.phymask = 0; 6947 topo_node->event = 6948 MPTSAS_DR_EVENT_RECONFIG_TARGET; 6949 topo_node->devhdl = diskhandle; 6950 topo_node->flags = 6951 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED; 6952 topo_node->object = NULL; 6953 mpt->m_port_chng = 1; 6954 if (topo_head == NULL) { 6955 topo_head = topo_tail = topo_node; 6956 } else { 6957 topo_tail->next = topo_node; 6958 topo_tail = topo_node; 6959 } 6960 break; 6961 } 6962 default: 6963 break; 6964 } 6965 } 6966 6967 if (topo_head != NULL) { 6968 /* 6969 * Launch DR taskq to handle topology change 6970 */ 6971 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 6972 mptsas_handle_dr, (void *)topo_head, 6973 DDI_NOSLEEP)) != DDI_SUCCESS) { 6974 mptsas_log(mpt, CE_NOTE, "mptsas start taskq " 6975 "for handle SAS DR event failed. \n"); 6976 } 6977 } 6978 break; 6979 } 6980 default: 6981 return (DDI_FAILURE); 6982 } 6983 6984 return (DDI_SUCCESS); 6985 } 6986 6987 /* 6988 * handle events from ioc 6989 */ 6990 static void 6991 mptsas_handle_event(void *args) 6992 { 6993 m_replyh_arg_t *replyh_arg; 6994 pMpi2EventNotificationReply_t eventreply; 6995 uint32_t event, iocloginfo, rfm; 6996 uint32_t status; 6997 uint8_t port; 6998 mptsas_t *mpt; 6999 uint_t iocstatus; 7000 7001 replyh_arg = (m_replyh_arg_t *)args; 7002 rfm = replyh_arg->rfm; 7003 mpt = replyh_arg->mpt; 7004 7005 mutex_enter(&mpt->m_mutex); 7006 /* 7007 * If HBA is being reset, drop incoming event. 7008 */ 7009 if (mpt->m_in_reset) { 7010 NDBG20(("dropping event received prior to reset")); 7011 mutex_exit(&mpt->m_mutex); 7012 return; 7013 } 7014 7015 eventreply = (pMpi2EventNotificationReply_t) 7016 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr)); 7017 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 7018 7019 if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 7020 &eventreply->IOCStatus)) { 7021 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 7022 mptsas_log(mpt, CE_WARN, 7023 "!mptsas_handle_event: IOCStatus=0x%x, " 7024 "IOCLogInfo=0x%x", iocstatus, 7025 ddi_get32(mpt->m_acc_reply_frame_hdl, 7026 &eventreply->IOCLogInfo)); 7027 } else { 7028 mptsas_log(mpt, CE_WARN, 7029 "mptsas_handle_event: IOCStatus=0x%x, " 7030 "IOCLogInfo=0x%x", iocstatus, 7031 ddi_get32(mpt->m_acc_reply_frame_hdl, 7032 &eventreply->IOCLogInfo)); 7033 } 7034 } 7035 7036 /* 7037 * figure out what kind of event we got and handle accordingly 7038 */ 7039 switch (event) { 7040 case MPI2_EVENT_LOG_ENTRY_ADDED: 7041 break; 7042 case MPI2_EVENT_LOG_DATA: 7043 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 7044 &eventreply->IOCLogInfo); 7045 NDBG20(("mptsas %d log info %x received.\n", mpt->m_instance, 7046 iocloginfo)); 7047 break; 7048 case MPI2_EVENT_STATE_CHANGE: 7049 NDBG20(("mptsas%d state change.", mpt->m_instance)); 7050 break; 7051 case MPI2_EVENT_HARD_RESET_RECEIVED: 7052 NDBG20(("mptsas%d event change.", mpt->m_instance)); 7053 break; 7054 case MPI2_EVENT_SAS_DISCOVERY: 7055 { 7056 MPI2_EVENT_DATA_SAS_DISCOVERY *sasdiscovery; 7057 char string[80]; 7058 uint8_t rc; 7059 7060 sasdiscovery = 7061 (pMpi2EventDataSasDiscovery_t)eventreply->EventData; 7062 7063 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7064 &sasdiscovery->ReasonCode); 7065 port = ddi_get8(mpt->m_acc_reply_frame_hdl, 7066 &sasdiscovery->PhysicalPort); 7067 status = ddi_get32(mpt->m_acc_reply_frame_hdl, 7068 &sasdiscovery->DiscoveryStatus); 7069 7070 string[0] = 0; 7071 switch (rc) { 7072 case MPI2_EVENT_SAS_DISC_RC_STARTED: 7073 (void) sprintf(string, "STARTING"); 7074 break; 7075 case MPI2_EVENT_SAS_DISC_RC_COMPLETED: 7076 (void) sprintf(string, "COMPLETED"); 7077 break; 7078 default: 7079 (void) sprintf(string, "UNKNOWN"); 7080 break; 7081 } 7082 7083 NDBG20(("SAS DISCOVERY is %s for port %d, status %x", string, 7084 port, status)); 7085 7086 break; 7087 } 7088 case MPI2_EVENT_EVENT_CHANGE: 7089 NDBG20(("mptsas%d event change.", mpt->m_instance)); 7090 break; 7091 case MPI2_EVENT_TASK_SET_FULL: 7092 { 7093 pMpi2EventDataTaskSetFull_t taskfull; 7094 7095 taskfull = (pMpi2EventDataTaskSetFull_t)eventreply->EventData; 7096 7097 NDBG20(("TASK_SET_FULL received for mptsas%d, depth %d\n", 7098 mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl, 7099 &taskfull->CurrentDepth))); 7100 break; 7101 } 7102 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 7103 { 7104 /* 7105 * SAS TOPOLOGY CHANGE LIST Event has already been handled 7106 * in mptsas_handle_event_sync() of interrupt context 7107 */ 7108 break; 7109 } 7110 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: 7111 { 7112 pMpi2EventDataSasEnclDevStatusChange_t encstatus; 7113 uint8_t rc; 7114 char string[80]; 7115 7116 encstatus = (pMpi2EventDataSasEnclDevStatusChange_t) 7117 eventreply->EventData; 7118 7119 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7120 &encstatus->ReasonCode); 7121 switch (rc) { 7122 case MPI2_EVENT_SAS_ENCL_RC_ADDED: 7123 (void) sprintf(string, "added"); 7124 break; 7125 case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING: 7126 (void) sprintf(string, ", not responding"); 7127 break; 7128 default: 7129 break; 7130 } 7131 NDBG20(("mptsas%d ENCLOSURE STATUS CHANGE for enclosure %x%s\n", 7132 mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl, 7133 &encstatus->EnclosureHandle), string)); 7134 break; 7135 } 7136 7137 /* 7138 * MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE is handled by 7139 * mptsas_handle_event_sync,in here just send ack message. 7140 */ 7141 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: 7142 { 7143 pMpi2EventDataSasDeviceStatusChange_t statuschange; 7144 uint8_t rc; 7145 uint16_t devhdl; 7146 uint64_t wwn = 0; 7147 uint32_t wwn_lo, wwn_hi; 7148 7149 statuschange = (pMpi2EventDataSasDeviceStatusChange_t) 7150 eventreply->EventData; 7151 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7152 &statuschange->ReasonCode); 7153 wwn_lo = ddi_get32(mpt->m_acc_reply_frame_hdl, 7154 (uint32_t *)(void *)&statuschange->SASAddress); 7155 wwn_hi = ddi_get32(mpt->m_acc_reply_frame_hdl, 7156 (uint32_t *)(void *)&statuschange->SASAddress + 1); 7157 wwn = ((uint64_t)wwn_hi << 32) | wwn_lo; 7158 devhdl = ddi_get16(mpt->m_acc_reply_frame_hdl, 7159 &statuschange->DevHandle); 7160 7161 NDBG13(("MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE wwn is %"PRIx64, 7162 wwn)); 7163 7164 switch (rc) { 7165 case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA: 7166 NDBG20(("SMART data received, ASC/ASCQ = %02x/%02x", 7167 ddi_get8(mpt->m_acc_reply_frame_hdl, 7168 &statuschange->ASC), 7169 ddi_get8(mpt->m_acc_reply_frame_hdl, 7170 &statuschange->ASCQ))); 7171 break; 7172 7173 case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED: 7174 NDBG20(("Device not supported")); 7175 break; 7176 7177 case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: 7178 NDBG20(("IOC internally generated the Target Reset " 7179 "for devhdl:%x", devhdl)); 7180 break; 7181 7182 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET: 7183 NDBG20(("IOC's internally generated Target Reset " 7184 "completed for devhdl:%x", devhdl)); 7185 break; 7186 7187 case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: 7188 NDBG20(("IOC internally generated Abort Task")); 7189 break; 7190 7191 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL: 7192 NDBG20(("IOC's internally generated Abort Task " 7193 "completed")); 7194 break; 7195 7196 case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: 7197 NDBG20(("IOC internally generated Abort Task Set")); 7198 break; 7199 7200 case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: 7201 NDBG20(("IOC internally generated Clear Task Set")); 7202 break; 7203 7204 case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: 7205 NDBG20(("IOC internally generated Query Task")); 7206 break; 7207 7208 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION: 7209 NDBG20(("Device sent an Asynchronous Notification")); 7210 break; 7211 7212 default: 7213 break; 7214 } 7215 break; 7216 } 7217 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 7218 { 7219 /* 7220 * IR TOPOLOGY CHANGE LIST Event has already been handled 7221 * in mpt_handle_event_sync() of interrupt context 7222 */ 7223 break; 7224 } 7225 case MPI2_EVENT_IR_OPERATION_STATUS: 7226 { 7227 Mpi2EventDataIrOperationStatus_t *irOpStatus; 7228 char reason_str[80]; 7229 uint8_t rc, percent; 7230 uint16_t handle; 7231 7232 irOpStatus = (pMpi2EventDataIrOperationStatus_t) 7233 eventreply->EventData; 7234 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7235 &irOpStatus->RAIDOperation); 7236 percent = ddi_get8(mpt->m_acc_reply_frame_hdl, 7237 &irOpStatus->PercentComplete); 7238 handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7239 &irOpStatus->VolDevHandle); 7240 7241 switch (rc) { 7242 case MPI2_EVENT_IR_RAIDOP_RESYNC: 7243 (void) sprintf(reason_str, "resync"); 7244 break; 7245 case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION: 7246 (void) sprintf(reason_str, "online capacity " 7247 "expansion"); 7248 break; 7249 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK: 7250 (void) sprintf(reason_str, "consistency check"); 7251 break; 7252 default: 7253 (void) sprintf(reason_str, "unknown reason %x", 7254 rc); 7255 } 7256 7257 NDBG20(("mptsas%d raid operational status: (%s)" 7258 "\thandle(0x%04x), percent complete(%d)\n", 7259 mpt->m_instance, reason_str, handle, percent)); 7260 break; 7261 } 7262 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: 7263 { 7264 pMpi2EventDataSasBroadcastPrimitive_t sas_broadcast; 7265 uint8_t phy_num; 7266 uint8_t primitive; 7267 7268 sas_broadcast = (pMpi2EventDataSasBroadcastPrimitive_t) 7269 eventreply->EventData; 7270 7271 phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl, 7272 &sas_broadcast->PhyNum); 7273 primitive = ddi_get8(mpt->m_acc_reply_frame_hdl, 7274 &sas_broadcast->Primitive); 7275 7276 switch (primitive) { 7277 case MPI2_EVENT_PRIMITIVE_CHANGE: 7278 mptsas_smhba_log_sysevent(mpt, 7279 ESC_SAS_HBA_PORT_BROADCAST, 7280 SAS_PORT_BROADCAST_CHANGE, 7281 &mpt->m_phy_info[phy_num].smhba_info); 7282 break; 7283 case MPI2_EVENT_PRIMITIVE_SES: 7284 mptsas_smhba_log_sysevent(mpt, 7285 ESC_SAS_HBA_PORT_BROADCAST, 7286 SAS_PORT_BROADCAST_SES, 7287 &mpt->m_phy_info[phy_num].smhba_info); 7288 break; 7289 case MPI2_EVENT_PRIMITIVE_EXPANDER: 7290 mptsas_smhba_log_sysevent(mpt, 7291 ESC_SAS_HBA_PORT_BROADCAST, 7292 SAS_PORT_BROADCAST_D01_4, 7293 &mpt->m_phy_info[phy_num].smhba_info); 7294 break; 7295 case MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT: 7296 mptsas_smhba_log_sysevent(mpt, 7297 ESC_SAS_HBA_PORT_BROADCAST, 7298 SAS_PORT_BROADCAST_D04_7, 7299 &mpt->m_phy_info[phy_num].smhba_info); 7300 break; 7301 case MPI2_EVENT_PRIMITIVE_RESERVED3: 7302 mptsas_smhba_log_sysevent(mpt, 7303 ESC_SAS_HBA_PORT_BROADCAST, 7304 SAS_PORT_BROADCAST_D16_7, 7305 &mpt->m_phy_info[phy_num].smhba_info); 7306 break; 7307 case MPI2_EVENT_PRIMITIVE_RESERVED4: 7308 mptsas_smhba_log_sysevent(mpt, 7309 ESC_SAS_HBA_PORT_BROADCAST, 7310 SAS_PORT_BROADCAST_D29_7, 7311 &mpt->m_phy_info[phy_num].smhba_info); 7312 break; 7313 case MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED: 7314 mptsas_smhba_log_sysevent(mpt, 7315 ESC_SAS_HBA_PORT_BROADCAST, 7316 SAS_PORT_BROADCAST_D24_0, 7317 &mpt->m_phy_info[phy_num].smhba_info); 7318 break; 7319 case MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED: 7320 mptsas_smhba_log_sysevent(mpt, 7321 ESC_SAS_HBA_PORT_BROADCAST, 7322 SAS_PORT_BROADCAST_D27_4, 7323 &mpt->m_phy_info[phy_num].smhba_info); 7324 break; 7325 default: 7326 NDBG20(("mptsas%d: unknown BROADCAST PRIMITIVE" 7327 " %x received", 7328 mpt->m_instance, primitive)); 7329 break; 7330 } 7331 NDBG20(("mptsas%d sas broadcast primitive: " 7332 "\tprimitive(0x%04x), phy(%d) complete\n", 7333 mpt->m_instance, primitive, phy_num)); 7334 break; 7335 } 7336 case MPI2_EVENT_IR_VOLUME: 7337 { 7338 Mpi2EventDataIrVolume_t *irVolume; 7339 uint16_t devhandle; 7340 uint32_t state; 7341 int config, vol; 7342 mptsas_slots_t *slots = mpt->m_active; 7343 uint8_t found = FALSE; 7344 7345 irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData; 7346 state = ddi_get32(mpt->m_acc_reply_frame_hdl, 7347 &irVolume->NewValue); 7348 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7349 &irVolume->VolDevHandle); 7350 7351 NDBG20(("EVENT_IR_VOLUME event is received")); 7352 7353 /* 7354 * Get latest RAID info and then find the DevHandle for this 7355 * event in the configuration. If the DevHandle is not found 7356 * just exit the event. 7357 */ 7358 (void) mptsas_get_raid_info(mpt); 7359 for (config = 0; (config < slots->m_num_raid_configs) && 7360 (!found); config++) { 7361 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) { 7362 if (slots->m_raidconfig[config].m_raidvol[vol]. 7363 m_raidhandle == devhandle) { 7364 found = TRUE; 7365 break; 7366 } 7367 } 7368 } 7369 if (!found) { 7370 break; 7371 } 7372 7373 switch (irVolume->ReasonCode) { 7374 case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED: 7375 { 7376 uint32_t i; 7377 slots->m_raidconfig[config].m_raidvol[vol].m_settings = 7378 state; 7379 7380 i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING; 7381 mptsas_log(mpt, CE_NOTE, " Volume %d settings changed" 7382 ", auto-config of hot-swap drives is %s" 7383 ", write caching is %s" 7384 ", hot-spare pool mask is %02x\n", 7385 vol, state & 7386 MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE 7387 ? "disabled" : "enabled", 7388 i == MPI2_RAIDVOL0_SETTING_UNCHANGED 7389 ? "controlled by member disks" : 7390 i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING 7391 ? "disabled" : 7392 i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING 7393 ? "enabled" : 7394 "incorrectly set", 7395 (state >> 16) & 0xff); 7396 break; 7397 } 7398 case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED: 7399 { 7400 slots->m_raidconfig[config].m_raidvol[vol].m_state = 7401 (uint8_t)state; 7402 7403 mptsas_log(mpt, CE_NOTE, 7404 "Volume %d is now %s\n", vol, 7405 state == MPI2_RAID_VOL_STATE_OPTIMAL 7406 ? "optimal" : 7407 state == MPI2_RAID_VOL_STATE_DEGRADED 7408 ? "degraded" : 7409 state == MPI2_RAID_VOL_STATE_ONLINE 7410 ? "online" : 7411 state == MPI2_RAID_VOL_STATE_INITIALIZING 7412 ? "initializing" : 7413 state == MPI2_RAID_VOL_STATE_FAILED 7414 ? "failed" : 7415 state == MPI2_RAID_VOL_STATE_MISSING 7416 ? "missing" : 7417 "state unknown"); 7418 break; 7419 } 7420 case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED: 7421 { 7422 slots->m_raidconfig[config].m_raidvol[vol]. 7423 m_statusflags = state; 7424 7425 mptsas_log(mpt, CE_NOTE, 7426 " Volume %d is now %s%s%s%s%s%s%s%s%s\n", 7427 vol, 7428 state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED 7429 ? ", enabled" : ", disabled", 7430 state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED 7431 ? ", quiesced" : "", 7432 state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE 7433 ? ", inactive" : ", active", 7434 state & 7435 MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL 7436 ? ", bad block table is full" : "", 7437 state & 7438 MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS 7439 ? ", resync in progress" : "", 7440 state & MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT 7441 ? ", background initialization in progress" : "", 7442 state & 7443 MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION 7444 ? ", capacity expansion in progress" : "", 7445 state & 7446 MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK 7447 ? ", consistency check in progress" : "", 7448 state & MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB 7449 ? ", data scrub in progress" : ""); 7450 break; 7451 } 7452 default: 7453 break; 7454 } 7455 break; 7456 } 7457 case MPI2_EVENT_IR_PHYSICAL_DISK: 7458 { 7459 Mpi2EventDataIrPhysicalDisk_t *irPhysDisk; 7460 uint16_t devhandle, enchandle, slot; 7461 uint32_t status, state; 7462 uint8_t physdisknum, reason; 7463 7464 irPhysDisk = (Mpi2EventDataIrPhysicalDisk_t *) 7465 eventreply->EventData; 7466 physdisknum = ddi_get8(mpt->m_acc_reply_frame_hdl, 7467 &irPhysDisk->PhysDiskNum); 7468 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7469 &irPhysDisk->PhysDiskDevHandle); 7470 enchandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7471 &irPhysDisk->EnclosureHandle); 7472 slot = ddi_get16(mpt->m_acc_reply_frame_hdl, 7473 &irPhysDisk->Slot); 7474 state = ddi_get32(mpt->m_acc_reply_frame_hdl, 7475 &irPhysDisk->NewValue); 7476 reason = ddi_get8(mpt->m_acc_reply_frame_hdl, 7477 &irPhysDisk->ReasonCode); 7478 7479 NDBG20(("EVENT_IR_PHYSICAL_DISK event is received")); 7480 7481 switch (reason) { 7482 case MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED: 7483 mptsas_log(mpt, CE_NOTE, 7484 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 7485 "for enclosure with handle 0x%x is now in hot " 7486 "spare pool %d", 7487 physdisknum, devhandle, slot, enchandle, 7488 (state >> 16) & 0xff); 7489 break; 7490 7491 case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED: 7492 status = state; 7493 mptsas_log(mpt, CE_NOTE, 7494 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 7495 "for enclosure with handle 0x%x is now " 7496 "%s%s%s%s%s\n", physdisknum, devhandle, slot, 7497 enchandle, 7498 status & MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME 7499 ? ", inactive" : ", active", 7500 status & MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC 7501 ? ", out of sync" : "", 7502 status & MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED 7503 ? ", quiesced" : "", 7504 status & 7505 MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED 7506 ? ", write cache enabled" : "", 7507 status & MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET 7508 ? ", capacity expansion target" : ""); 7509 break; 7510 7511 case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED: 7512 mptsas_log(mpt, CE_NOTE, 7513 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 7514 "for enclosure with handle 0x%x is now %s\n", 7515 physdisknum, devhandle, slot, enchandle, 7516 state == MPI2_RAID_PD_STATE_OPTIMAL 7517 ? "optimal" : 7518 state == MPI2_RAID_PD_STATE_REBUILDING 7519 ? "rebuilding" : 7520 state == MPI2_RAID_PD_STATE_DEGRADED 7521 ? "degraded" : 7522 state == MPI2_RAID_PD_STATE_HOT_SPARE 7523 ? "a hot spare" : 7524 state == MPI2_RAID_PD_STATE_ONLINE 7525 ? "online" : 7526 state == MPI2_RAID_PD_STATE_OFFLINE 7527 ? "offline" : 7528 state == MPI2_RAID_PD_STATE_NOT_COMPATIBLE 7529 ? "not compatible" : 7530 state == MPI2_RAID_PD_STATE_NOT_CONFIGURED 7531 ? "not configured" : 7532 "state unknown"); 7533 break; 7534 } 7535 break; 7536 } 7537 default: 7538 NDBG20(("mptsas%d: unknown event %x received", 7539 mpt->m_instance, event)); 7540 break; 7541 } 7542 7543 /* 7544 * Return the reply frame to the free queue. 7545 */ 7546 ddi_put32(mpt->m_acc_free_queue_hdl, 7547 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], rfm); 7548 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 7549 DDI_DMA_SYNC_FORDEV); 7550 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 7551 mpt->m_free_index = 0; 7552 } 7553 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 7554 mpt->m_free_index); 7555 mutex_exit(&mpt->m_mutex); 7556 } 7557 7558 /* 7559 * invoked from timeout() to restart qfull cmds with throttle == 0 7560 */ 7561 static void 7562 mptsas_restart_cmd(void *arg) 7563 { 7564 mptsas_t *mpt = arg; 7565 mptsas_target_t *ptgt = NULL; 7566 7567 mutex_enter(&mpt->m_mutex); 7568 7569 mpt->m_restart_cmd_timeid = 0; 7570 7571 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 7572 MPTSAS_HASH_FIRST); 7573 while (ptgt != NULL) { 7574 if (ptgt->m_reset_delay == 0) { 7575 if (ptgt->m_t_throttle == QFULL_THROTTLE) { 7576 mptsas_set_throttle(mpt, ptgt, 7577 MAX_THROTTLE); 7578 } 7579 } 7580 7581 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 7582 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 7583 } 7584 mptsas_restart_hba(mpt); 7585 mutex_exit(&mpt->m_mutex); 7586 } 7587 7588 void 7589 mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 7590 { 7591 int slot; 7592 mptsas_slots_t *slots = mpt->m_active; 7593 int t; 7594 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 7595 7596 ASSERT(cmd != NULL); 7597 ASSERT(cmd->cmd_queued == FALSE); 7598 7599 /* 7600 * Task Management cmds are removed in their own routines. Also, 7601 * we don't want to modify timeout based on TM cmds. 7602 */ 7603 if (cmd->cmd_flags & CFLAG_TM_CMD) { 7604 return; 7605 } 7606 7607 t = Tgt(cmd); 7608 slot = cmd->cmd_slot; 7609 7610 /* 7611 * remove the cmd. 7612 */ 7613 if (cmd == slots->m_slot[slot]) { 7614 NDBG31(("mptsas_remove_cmd: removing cmd=0x%p", (void *)cmd)); 7615 slots->m_slot[slot] = NULL; 7616 mpt->m_ncmds--; 7617 7618 /* 7619 * only decrement per target ncmds if command 7620 * has a target associated with it. 7621 */ 7622 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 7623 ptgt->m_t_ncmds--; 7624 /* 7625 * reset throttle if we just ran an untagged command 7626 * to a tagged target 7627 */ 7628 if ((ptgt->m_t_ncmds == 0) && 7629 ((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0)) { 7630 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 7631 } 7632 } 7633 7634 } 7635 7636 /* 7637 * This is all we need to do for ioc commands. 7638 */ 7639 if (cmd->cmd_flags & CFLAG_CMDIOC) { 7640 mptsas_return_to_pool(mpt, cmd); 7641 return; 7642 } 7643 7644 /* 7645 * Figure out what to set tag Q timeout for... 7646 * 7647 * Optimize: If we have duplicate's of same timeout 7648 * we're using, then we'll use it again until we run 7649 * out of duplicates. This should be the normal case 7650 * for block and raw I/O. 7651 * If no duplicates, we have to scan through tag que and 7652 * find the longest timeout value and use it. This is 7653 * going to take a while... 7654 * Add 1 to m_n_slots to account for TM request. 7655 */ 7656 if (cmd->cmd_pkt->pkt_time == ptgt->m_timebase) { 7657 if (--(ptgt->m_dups) == 0) { 7658 if (ptgt->m_t_ncmds) { 7659 mptsas_cmd_t *ssp; 7660 uint_t n = 0; 7661 ushort_t nslots = (slots->m_n_slots + 1); 7662 ushort_t i; 7663 /* 7664 * This crude check assumes we don't do 7665 * this too often which seems reasonable 7666 * for block and raw I/O. 7667 */ 7668 for (i = 0; i < nslots; i++) { 7669 ssp = slots->m_slot[i]; 7670 if (ssp && (Tgt(ssp) == t) && 7671 (ssp->cmd_pkt->pkt_time > n)) { 7672 n = ssp->cmd_pkt->pkt_time; 7673 ptgt->m_dups = 1; 7674 } else if (ssp && (Tgt(ssp) == t) && 7675 (ssp->cmd_pkt->pkt_time == n)) { 7676 ptgt->m_dups++; 7677 } 7678 } 7679 ptgt->m_timebase = n; 7680 } else { 7681 ptgt->m_dups = 0; 7682 ptgt->m_timebase = 0; 7683 } 7684 } 7685 } 7686 ptgt->m_timeout = ptgt->m_timebase; 7687 7688 ASSERT(cmd != slots->m_slot[cmd->cmd_slot]); 7689 } 7690 7691 /* 7692 * accept all cmds on the tx_waitq if any and then 7693 * start a fresh request from the top of the device queue. 7694 * 7695 * since there are always cmds queued on the tx_waitq, and rare cmds on 7696 * the instance waitq, so this function should not be invoked in the ISR, 7697 * the mptsas_restart_waitq() is invoked in the ISR instead. otherwise, the 7698 * burden belongs to the IO dispatch CPUs is moved the interrupt CPU. 7699 */ 7700 static void 7701 mptsas_restart_hba(mptsas_t *mpt) 7702 { 7703 ASSERT(mutex_owned(&mpt->m_mutex)); 7704 7705 mutex_enter(&mpt->m_tx_waitq_mutex); 7706 if (mpt->m_tx_waitq) { 7707 mptsas_accept_tx_waitq(mpt); 7708 } 7709 mutex_exit(&mpt->m_tx_waitq_mutex); 7710 mptsas_restart_waitq(mpt); 7711 } 7712 7713 /* 7714 * start a fresh request from the top of the device queue 7715 */ 7716 static void 7717 mptsas_restart_waitq(mptsas_t *mpt) 7718 { 7719 mptsas_cmd_t *cmd, *next_cmd; 7720 mptsas_target_t *ptgt = NULL; 7721 7722 NDBG1(("mptsas_restart_waitq: mpt=0x%p", (void *)mpt)); 7723 7724 ASSERT(mutex_owned(&mpt->m_mutex)); 7725 7726 /* 7727 * If there is a reset delay, don't start any cmds. Otherwise, start 7728 * as many cmds as possible. 7729 * Since SMID 0 is reserved and the TM slot is reserved, the actual max 7730 * commands is m_max_requests - 2. 7731 */ 7732 cmd = mpt->m_waitq; 7733 7734 while (cmd != NULL) { 7735 next_cmd = cmd->cmd_linkp; 7736 if (cmd->cmd_flags & CFLAG_PASSTHRU) { 7737 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 7738 /* 7739 * passthru command get slot need 7740 * set CFLAG_PREPARED. 7741 */ 7742 cmd->cmd_flags |= CFLAG_PREPARED; 7743 mptsas_waitq_delete(mpt, cmd); 7744 mptsas_start_passthru(mpt, cmd); 7745 } 7746 cmd = next_cmd; 7747 continue; 7748 } 7749 if (cmd->cmd_flags & CFLAG_CONFIG) { 7750 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 7751 /* 7752 * Send the config page request and delete it 7753 * from the waitq. 7754 */ 7755 cmd->cmd_flags |= CFLAG_PREPARED; 7756 mptsas_waitq_delete(mpt, cmd); 7757 mptsas_start_config_page_access(mpt, cmd); 7758 } 7759 cmd = next_cmd; 7760 continue; 7761 } 7762 if (cmd->cmd_flags & CFLAG_FW_DIAG) { 7763 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 7764 /* 7765 * Send the FW Diag request and delete if from 7766 * the waitq. 7767 */ 7768 cmd->cmd_flags |= CFLAG_PREPARED; 7769 mptsas_waitq_delete(mpt, cmd); 7770 mptsas_start_diag(mpt, cmd); 7771 } 7772 cmd = next_cmd; 7773 continue; 7774 } 7775 7776 ptgt = cmd->cmd_tgt_addr; 7777 if (ptgt && (ptgt->m_t_throttle == DRAIN_THROTTLE) && 7778 (ptgt->m_t_ncmds == 0)) { 7779 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 7780 } 7781 if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) && 7782 (ptgt && (ptgt->m_reset_delay == 0)) && 7783 (ptgt && (ptgt->m_t_ncmds < 7784 ptgt->m_t_throttle))) { 7785 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 7786 mptsas_waitq_delete(mpt, cmd); 7787 (void) mptsas_start_cmd(mpt, cmd); 7788 } 7789 } 7790 cmd = next_cmd; 7791 } 7792 } 7793 /* 7794 * Cmds are queued if tran_start() doesn't get the m_mutexlock(no wait). 7795 * Accept all those queued cmds before new cmd is accept so that the 7796 * cmds are sent in order. 7797 */ 7798 static void 7799 mptsas_accept_tx_waitq(mptsas_t *mpt) 7800 { 7801 mptsas_cmd_t *cmd; 7802 7803 ASSERT(mutex_owned(&mpt->m_mutex)); 7804 ASSERT(mutex_owned(&mpt->m_tx_waitq_mutex)); 7805 7806 /* 7807 * A Bus Reset could occur at any time and flush the tx_waitq, 7808 * so we cannot count on the tx_waitq to contain even one cmd. 7809 * And when the m_tx_waitq_mutex is released and run 7810 * mptsas_accept_pkt(), the tx_waitq may be flushed. 7811 */ 7812 cmd = mpt->m_tx_waitq; 7813 for (;;) { 7814 if ((cmd = mpt->m_tx_waitq) == NULL) { 7815 mpt->m_tx_draining = 0; 7816 break; 7817 } 7818 if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) { 7819 mpt->m_tx_waitqtail = &mpt->m_tx_waitq; 7820 } 7821 cmd->cmd_linkp = NULL; 7822 mutex_exit(&mpt->m_tx_waitq_mutex); 7823 if (mptsas_accept_pkt(mpt, cmd) != TRAN_ACCEPT) 7824 cmn_err(CE_WARN, "mpt: mptsas_accept_tx_waitq: failed " 7825 "to accept cmd on queue\n"); 7826 mutex_enter(&mpt->m_tx_waitq_mutex); 7827 } 7828 } 7829 7830 7831 /* 7832 * mpt tag type lookup 7833 */ 7834 static char mptsas_tag_lookup[] = 7835 {0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG}; 7836 7837 static int 7838 mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 7839 { 7840 struct scsi_pkt *pkt = CMD2PKT(cmd); 7841 uint32_t control = 0; 7842 int n; 7843 caddr_t mem; 7844 pMpi2SCSIIORequest_t io_request; 7845 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; 7846 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl; 7847 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 7848 uint16_t SMID, io_flags = 0; 7849 uint32_t request_desc_low, request_desc_high; 7850 7851 NDBG1(("mptsas_start_cmd: cmd=0x%p", (void *)cmd)); 7852 7853 /* 7854 * Set SMID and increment index. Rollover to 1 instead of 0 if index 7855 * is at the max. 0 is an invalid SMID, so we call the first index 1. 7856 */ 7857 SMID = cmd->cmd_slot; 7858 7859 /* 7860 * It is possible for back to back device reset to 7861 * happen before the reset delay has expired. That's 7862 * ok, just let the device reset go out on the bus. 7863 */ 7864 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 7865 ASSERT(ptgt->m_reset_delay == 0); 7866 } 7867 7868 /* 7869 * if a non-tagged cmd is submitted to an active tagged target 7870 * then drain before submitting this cmd; SCSI-2 allows RQSENSE 7871 * to be untagged 7872 */ 7873 if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) && 7874 (ptgt->m_t_ncmds > 1) && 7875 ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) && 7876 (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) { 7877 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 7878 NDBG23(("target=%d, untagged cmd, start draining\n", 7879 ptgt->m_devhdl)); 7880 7881 if (ptgt->m_reset_delay == 0) { 7882 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 7883 } 7884 7885 mptsas_remove_cmd(mpt, cmd); 7886 cmd->cmd_pkt_flags |= FLAG_HEAD; 7887 mptsas_waitq_add(mpt, cmd); 7888 } 7889 return (DDI_FAILURE); 7890 } 7891 7892 /* 7893 * Set correct tag bits. 7894 */ 7895 if (cmd->cmd_pkt_flags & FLAG_TAGMASK) { 7896 switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags & 7897 FLAG_TAGMASK) >> 12)]) { 7898 case MSG_SIMPLE_QTAG: 7899 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 7900 break; 7901 case MSG_HEAD_QTAG: 7902 control |= MPI2_SCSIIO_CONTROL_HEADOFQ; 7903 break; 7904 case MSG_ORDERED_QTAG: 7905 control |= MPI2_SCSIIO_CONTROL_ORDEREDQ; 7906 break; 7907 default: 7908 mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n"); 7909 break; 7910 } 7911 } else { 7912 if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) { 7913 ptgt->m_t_throttle = 1; 7914 } 7915 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 7916 } 7917 7918 if (cmd->cmd_pkt_flags & FLAG_TLR) { 7919 control |= MPI2_SCSIIO_CONTROL_TLR_ON; 7920 } 7921 7922 mem = mpt->m_req_frame + (mpt->m_req_frame_size * SMID); 7923 io_request = (pMpi2SCSIIORequest_t)mem; 7924 7925 bzero(io_request, sizeof (Mpi2SCSIIORequest_t)); 7926 ddi_put8(acc_hdl, &io_request->SGLOffset0, offsetof 7927 (MPI2_SCSI_IO_REQUEST, SGL) / 4); 7928 mptsas_init_std_hdr(acc_hdl, io_request, ptgt->m_devhdl, Lun(cmd), 0, 7929 MPI2_FUNCTION_SCSI_IO_REQUEST); 7930 7931 (void) ddi_rep_put8(acc_hdl, (uint8_t *)pkt->pkt_cdbp, 7932 io_request->CDB.CDB32, cmd->cmd_cdblen, DDI_DEV_AUTOINCR); 7933 7934 io_flags = cmd->cmd_cdblen; 7935 ddi_put16(acc_hdl, &io_request->IoFlags, io_flags); 7936 /* 7937 * setup the Scatter/Gather DMA list for this request 7938 */ 7939 if (cmd->cmd_cookiec > 0) { 7940 mptsas_sge_setup(mpt, cmd, &control, io_request, acc_hdl); 7941 } else { 7942 ddi_put32(acc_hdl, &io_request->SGL.MpiSimple.FlagsLength, 7943 ((uint32_t)MPI2_SGE_FLAGS_LAST_ELEMENT | 7944 MPI2_SGE_FLAGS_END_OF_BUFFER | 7945 MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 7946 MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); 7947 } 7948 7949 /* 7950 * save ARQ information 7951 */ 7952 ddi_put8(acc_hdl, &io_request->SenseBufferLength, cmd->cmd_rqslen); 7953 if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) == 7954 (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) { 7955 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, 7956 cmd->cmd_ext_arqcookie.dmac_address); 7957 } else { 7958 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, 7959 cmd->cmd_arqcookie.dmac_address); 7960 } 7961 7962 ddi_put32(acc_hdl, &io_request->Control, control); 7963 7964 NDBG31(("starting message=0x%p, with cmd=0x%p", 7965 (void *)(uintptr_t)mpt->m_req_frame_dma_addr, (void *)cmd)); 7966 7967 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 7968 7969 /* 7970 * Build request descriptor and write it to the request desc post reg. 7971 */ 7972 request_desc_low = (SMID << 16) + MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 7973 request_desc_high = ptgt->m_devhdl << 16; 7974 MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high); 7975 7976 /* 7977 * Start timeout. 7978 */ 7979 #ifdef MPTSAS_TEST 7980 /* 7981 * Temporarily set timebase = 0; needed for 7982 * timeout torture test. 7983 */ 7984 if (mptsas_test_timeouts) { 7985 ptgt->m_timebase = 0; 7986 } 7987 #endif 7988 n = pkt->pkt_time - ptgt->m_timebase; 7989 7990 if (n == 0) { 7991 (ptgt->m_dups)++; 7992 ptgt->m_timeout = ptgt->m_timebase; 7993 } else if (n > 0) { 7994 ptgt->m_timeout = 7995 ptgt->m_timebase = pkt->pkt_time; 7996 ptgt->m_dups = 1; 7997 } else if (n < 0) { 7998 ptgt->m_timeout = ptgt->m_timebase; 7999 } 8000 #ifdef MPTSAS_TEST 8001 /* 8002 * Set back to a number higher than 8003 * mptsas_scsi_watchdog_tick 8004 * so timeouts will happen in mptsas_watchsubr 8005 */ 8006 if (mptsas_test_timeouts) { 8007 ptgt->m_timebase = 60; 8008 } 8009 #endif 8010 8011 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || 8012 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { 8013 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8014 return (DDI_FAILURE); 8015 } 8016 return (DDI_SUCCESS); 8017 } 8018 8019 /* 8020 * Select a helper thread to handle current doneq 8021 */ 8022 static void 8023 mptsas_deliver_doneq_thread(mptsas_t *mpt) 8024 { 8025 uint64_t t, i; 8026 uint32_t min = 0xffffffff; 8027 mptsas_doneq_thread_list_t *item; 8028 8029 for (i = 0; i < mpt->m_doneq_thread_n; i++) { 8030 item = &mpt->m_doneq_thread_id[i]; 8031 /* 8032 * If the completed command on help thread[i] less than 8033 * doneq_thread_threshold, then pick the thread[i]. Otherwise 8034 * pick a thread which has least completed command. 8035 */ 8036 8037 mutex_enter(&item->mutex); 8038 if (item->len < mpt->m_doneq_thread_threshold) { 8039 t = i; 8040 mutex_exit(&item->mutex); 8041 break; 8042 } 8043 if (item->len < min) { 8044 min = item->len; 8045 t = i; 8046 } 8047 mutex_exit(&item->mutex); 8048 } 8049 mutex_enter(&mpt->m_doneq_thread_id[t].mutex); 8050 mptsas_doneq_mv(mpt, t); 8051 cv_signal(&mpt->m_doneq_thread_id[t].cv); 8052 mutex_exit(&mpt->m_doneq_thread_id[t].mutex); 8053 } 8054 8055 /* 8056 * move the current global doneq to the doneq of thead[t] 8057 */ 8058 static void 8059 mptsas_doneq_mv(mptsas_t *mpt, uint64_t t) 8060 { 8061 mptsas_cmd_t *cmd; 8062 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 8063 8064 ASSERT(mutex_owned(&item->mutex)); 8065 while ((cmd = mpt->m_doneq) != NULL) { 8066 if ((mpt->m_doneq = cmd->cmd_linkp) == NULL) { 8067 mpt->m_donetail = &mpt->m_doneq; 8068 } 8069 cmd->cmd_linkp = NULL; 8070 *item->donetail = cmd; 8071 item->donetail = &cmd->cmd_linkp; 8072 mpt->m_doneq_len--; 8073 item->len++; 8074 } 8075 } 8076 8077 void 8078 mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd) 8079 { 8080 struct scsi_pkt *pkt = CMD2PKT(cmd); 8081 8082 /* Check all acc and dma handles */ 8083 if ((mptsas_check_acc_handle(mpt->m_datap) != 8084 DDI_SUCCESS) || 8085 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 8086 DDI_SUCCESS) || 8087 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) != 8088 DDI_SUCCESS) || 8089 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) != 8090 DDI_SUCCESS) || 8091 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) != 8092 DDI_SUCCESS) || 8093 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) != 8094 DDI_SUCCESS) || 8095 (mptsas_check_acc_handle(mpt->m_config_handle) != 8096 DDI_SUCCESS)) { 8097 ddi_fm_service_impact(mpt->m_dip, 8098 DDI_SERVICE_UNAFFECTED); 8099 ddi_fm_acc_err_clear(mpt->m_config_handle, 8100 DDI_FME_VER0); 8101 pkt->pkt_reason = CMD_TRAN_ERR; 8102 pkt->pkt_statistics = 0; 8103 } 8104 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 8105 DDI_SUCCESS) || 8106 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) != 8107 DDI_SUCCESS) || 8108 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) != 8109 DDI_SUCCESS) || 8110 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) != 8111 DDI_SUCCESS) || 8112 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) != 8113 DDI_SUCCESS)) { 8114 ddi_fm_service_impact(mpt->m_dip, 8115 DDI_SERVICE_UNAFFECTED); 8116 pkt->pkt_reason = CMD_TRAN_ERR; 8117 pkt->pkt_statistics = 0; 8118 } 8119 if (cmd->cmd_dmahandle && 8120 (mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS)) { 8121 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8122 pkt->pkt_reason = CMD_TRAN_ERR; 8123 pkt->pkt_statistics = 0; 8124 } 8125 if ((cmd->cmd_extra_frames && 8126 ((mptsas_check_dma_handle(cmd->cmd_extra_frames->m_dma_hdl) != 8127 DDI_SUCCESS) || 8128 (mptsas_check_acc_handle(cmd->cmd_extra_frames->m_acc_hdl) != 8129 DDI_SUCCESS)))) { 8130 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8131 pkt->pkt_reason = CMD_TRAN_ERR; 8132 pkt->pkt_statistics = 0; 8133 } 8134 if (cmd->cmd_arqhandle && 8135 (mptsas_check_dma_handle(cmd->cmd_arqhandle) != DDI_SUCCESS)) { 8136 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8137 pkt->pkt_reason = CMD_TRAN_ERR; 8138 pkt->pkt_statistics = 0; 8139 } 8140 if (cmd->cmd_ext_arqhandle && 8141 (mptsas_check_dma_handle(cmd->cmd_ext_arqhandle) != DDI_SUCCESS)) { 8142 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8143 pkt->pkt_reason = CMD_TRAN_ERR; 8144 pkt->pkt_statistics = 0; 8145 } 8146 } 8147 8148 /* 8149 * These routines manipulate the queue of commands that 8150 * are waiting for their completion routines to be called. 8151 * The queue is usually in FIFO order but on an MP system 8152 * it's possible for the completion routines to get out 8153 * of order. If that's a problem you need to add a global 8154 * mutex around the code that calls the completion routine 8155 * in the interrupt handler. 8156 */ 8157 static void 8158 mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd) 8159 { 8160 struct scsi_pkt *pkt = CMD2PKT(cmd); 8161 8162 NDBG31(("mptsas_doneq_add: cmd=0x%p", (void *)cmd)); 8163 8164 ASSERT((cmd->cmd_flags & CFLAG_COMPLETED) == 0); 8165 cmd->cmd_linkp = NULL; 8166 cmd->cmd_flags |= CFLAG_FINISHED; 8167 cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT; 8168 8169 mptsas_fma_check(mpt, cmd); 8170 8171 /* 8172 * only add scsi pkts that have completion routines to 8173 * the doneq. no intr cmds do not have callbacks. 8174 */ 8175 if (pkt && (pkt->pkt_comp)) { 8176 *mpt->m_donetail = cmd; 8177 mpt->m_donetail = &cmd->cmd_linkp; 8178 mpt->m_doneq_len++; 8179 } 8180 } 8181 8182 static mptsas_cmd_t * 8183 mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t) 8184 { 8185 mptsas_cmd_t *cmd; 8186 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 8187 8188 /* pop one off the done queue */ 8189 if ((cmd = item->doneq) != NULL) { 8190 /* if the queue is now empty fix the tail pointer */ 8191 NDBG31(("mptsas_doneq_thread_rm: cmd=0x%p", (void *)cmd)); 8192 if ((item->doneq = cmd->cmd_linkp) == NULL) { 8193 item->donetail = &item->doneq; 8194 } 8195 cmd->cmd_linkp = NULL; 8196 item->len--; 8197 } 8198 return (cmd); 8199 } 8200 8201 static void 8202 mptsas_doneq_empty(mptsas_t *mpt) 8203 { 8204 if (mpt->m_doneq && !mpt->m_in_callback) { 8205 mptsas_cmd_t *cmd, *next; 8206 struct scsi_pkt *pkt; 8207 8208 mpt->m_in_callback = 1; 8209 cmd = mpt->m_doneq; 8210 mpt->m_doneq = NULL; 8211 mpt->m_donetail = &mpt->m_doneq; 8212 mpt->m_doneq_len = 0; 8213 8214 mutex_exit(&mpt->m_mutex); 8215 /* 8216 * run the completion routines of all the 8217 * completed commands 8218 */ 8219 while (cmd != NULL) { 8220 next = cmd->cmd_linkp; 8221 cmd->cmd_linkp = NULL; 8222 /* run this command's completion routine */ 8223 cmd->cmd_flags |= CFLAG_COMPLETED; 8224 pkt = CMD2PKT(cmd); 8225 mptsas_pkt_comp(pkt, cmd); 8226 cmd = next; 8227 } 8228 mutex_enter(&mpt->m_mutex); 8229 mpt->m_in_callback = 0; 8230 } 8231 } 8232 8233 /* 8234 * These routines manipulate the target's queue of pending requests 8235 */ 8236 void 8237 mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd) 8238 { 8239 NDBG7(("mptsas_waitq_add: cmd=0x%p", (void *)cmd)); 8240 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8241 cmd->cmd_queued = TRUE; 8242 if (ptgt) 8243 ptgt->m_t_nwait++; 8244 if (cmd->cmd_pkt_flags & FLAG_HEAD) { 8245 if ((cmd->cmd_linkp = mpt->m_waitq) == NULL) { 8246 mpt->m_waitqtail = &cmd->cmd_linkp; 8247 } 8248 mpt->m_waitq = cmd; 8249 } else { 8250 cmd->cmd_linkp = NULL; 8251 *(mpt->m_waitqtail) = cmd; 8252 mpt->m_waitqtail = &cmd->cmd_linkp; 8253 } 8254 } 8255 8256 static mptsas_cmd_t * 8257 mptsas_waitq_rm(mptsas_t *mpt) 8258 { 8259 mptsas_cmd_t *cmd; 8260 mptsas_target_t *ptgt; 8261 NDBG7(("mptsas_waitq_rm")); 8262 8263 MPTSAS_WAITQ_RM(mpt, cmd); 8264 8265 NDBG7(("mptsas_waitq_rm: cmd=0x%p", (void *)cmd)); 8266 if (cmd) { 8267 ptgt = cmd->cmd_tgt_addr; 8268 if (ptgt) { 8269 ptgt->m_t_nwait--; 8270 ASSERT(ptgt->m_t_nwait >= 0); 8271 } 8272 } 8273 return (cmd); 8274 } 8275 8276 /* 8277 * remove specified cmd from the middle of the wait queue. 8278 */ 8279 static void 8280 mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd) 8281 { 8282 mptsas_cmd_t *prevp = mpt->m_waitq; 8283 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8284 8285 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8286 (void *)mpt, (void *)cmd)); 8287 if (ptgt) { 8288 ptgt->m_t_nwait--; 8289 ASSERT(ptgt->m_t_nwait >= 0); 8290 } 8291 8292 if (prevp == cmd) { 8293 if ((mpt->m_waitq = cmd->cmd_linkp) == NULL) 8294 mpt->m_waitqtail = &mpt->m_waitq; 8295 8296 cmd->cmd_linkp = NULL; 8297 cmd->cmd_queued = FALSE; 8298 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8299 (void *)mpt, (void *)cmd)); 8300 return; 8301 } 8302 8303 while (prevp != NULL) { 8304 if (prevp->cmd_linkp == cmd) { 8305 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL) 8306 mpt->m_waitqtail = &prevp->cmd_linkp; 8307 8308 cmd->cmd_linkp = NULL; 8309 cmd->cmd_queued = FALSE; 8310 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8311 (void *)mpt, (void *)cmd)); 8312 return; 8313 } 8314 prevp = prevp->cmd_linkp; 8315 } 8316 cmn_err(CE_PANIC, "mpt: mptsas_waitq_delete: queue botch"); 8317 } 8318 8319 static mptsas_cmd_t * 8320 mptsas_tx_waitq_rm(mptsas_t *mpt) 8321 { 8322 mptsas_cmd_t *cmd; 8323 NDBG7(("mptsas_tx_waitq_rm")); 8324 8325 MPTSAS_TX_WAITQ_RM(mpt, cmd); 8326 8327 NDBG7(("mptsas_tx_waitq_rm: cmd=0x%p", (void *)cmd)); 8328 8329 return (cmd); 8330 } 8331 8332 /* 8333 * remove specified cmd from the middle of the tx_waitq. 8334 */ 8335 static void 8336 mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd) 8337 { 8338 mptsas_cmd_t *prevp = mpt->m_tx_waitq; 8339 8340 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p", 8341 (void *)mpt, (void *)cmd)); 8342 8343 if (prevp == cmd) { 8344 if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) 8345 mpt->m_tx_waitqtail = &mpt->m_tx_waitq; 8346 8347 cmd->cmd_linkp = NULL; 8348 cmd->cmd_queued = FALSE; 8349 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p", 8350 (void *)mpt, (void *)cmd)); 8351 return; 8352 } 8353 8354 while (prevp != NULL) { 8355 if (prevp->cmd_linkp == cmd) { 8356 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL) 8357 mpt->m_tx_waitqtail = &prevp->cmd_linkp; 8358 8359 cmd->cmd_linkp = NULL; 8360 cmd->cmd_queued = FALSE; 8361 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p", 8362 (void *)mpt, (void *)cmd)); 8363 return; 8364 } 8365 prevp = prevp->cmd_linkp; 8366 } 8367 cmn_err(CE_PANIC, "mpt: mptsas_tx_waitq_delete: queue botch"); 8368 } 8369 8370 /* 8371 * device and bus reset handling 8372 * 8373 * Notes: 8374 * - RESET_ALL: reset the controller 8375 * - RESET_TARGET: reset the target specified in scsi_address 8376 */ 8377 static int 8378 mptsas_scsi_reset(struct scsi_address *ap, int level) 8379 { 8380 mptsas_t *mpt = ADDR2MPT(ap); 8381 int rval; 8382 mptsas_tgt_private_t *tgt_private; 8383 mptsas_target_t *ptgt = NULL; 8384 8385 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->tran_tgt_private; 8386 ptgt = tgt_private->t_private; 8387 if (ptgt == NULL) { 8388 return (FALSE); 8389 } 8390 NDBG22(("mptsas_scsi_reset: target=%d level=%d", ptgt->m_devhdl, 8391 level)); 8392 8393 mutex_enter(&mpt->m_mutex); 8394 /* 8395 * if we are not in panic set up a reset delay for this target 8396 */ 8397 if (!ddi_in_panic()) { 8398 mptsas_setup_bus_reset_delay(mpt); 8399 } else { 8400 drv_usecwait(mpt->m_scsi_reset_delay * 1000); 8401 } 8402 rval = mptsas_do_scsi_reset(mpt, ptgt->m_devhdl); 8403 mutex_exit(&mpt->m_mutex); 8404 8405 /* 8406 * The transport layer expect to only see TRUE and 8407 * FALSE. Therefore, we will adjust the return value 8408 * if mptsas_do_scsi_reset returns FAILED. 8409 */ 8410 if (rval == FAILED) 8411 rval = FALSE; 8412 return (rval); 8413 } 8414 8415 static int 8416 mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl) 8417 { 8418 int rval = FALSE; 8419 uint8_t config, disk; 8420 mptsas_slots_t *slots = mpt->m_active; 8421 8422 ASSERT(mutex_owned(&mpt->m_mutex)); 8423 8424 if (mptsas_debug_resets) { 8425 mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d", 8426 devhdl); 8427 } 8428 8429 /* 8430 * Issue a Target Reset message to the target specified but not to a 8431 * disk making up a raid volume. Just look through the RAID config 8432 * Phys Disk list of DevHandles. If the target's DevHandle is in this 8433 * list, then don't reset this target. 8434 */ 8435 for (config = 0; config < slots->m_num_raid_configs; config++) { 8436 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) { 8437 if (devhdl == slots->m_raidconfig[config]. 8438 m_physdisk_devhdl[disk]) { 8439 return (TRUE); 8440 } 8441 } 8442 } 8443 8444 rval = mptsas_ioc_task_management(mpt, 8445 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, devhdl, 0, NULL, 0, 0); 8446 8447 mptsas_doneq_empty(mpt); 8448 return (rval); 8449 } 8450 8451 static int 8452 mptsas_scsi_reset_notify(struct scsi_address *ap, int flag, 8453 void (*callback)(caddr_t), caddr_t arg) 8454 { 8455 mptsas_t *mpt = ADDR2MPT(ap); 8456 8457 NDBG22(("mptsas_scsi_reset_notify: tgt=%d", ap->a_target)); 8458 8459 return (scsi_hba_reset_notify_setup(ap, flag, callback, arg, 8460 &mpt->m_mutex, &mpt->m_reset_notify_listf)); 8461 } 8462 8463 static int 8464 mptsas_get_name(struct scsi_device *sd, char *name, int len) 8465 { 8466 dev_info_t *lun_dip = NULL; 8467 8468 ASSERT(sd != NULL); 8469 ASSERT(name != NULL); 8470 lun_dip = sd->sd_dev; 8471 ASSERT(lun_dip != NULL); 8472 8473 if (mptsas_name_child(lun_dip, name, len) == DDI_SUCCESS) { 8474 return (1); 8475 } else { 8476 return (0); 8477 } 8478 } 8479 8480 static int 8481 mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len) 8482 { 8483 return (mptsas_get_name(sd, name, len)); 8484 } 8485 8486 void 8487 mptsas_set_throttle(mptsas_t *mpt, mptsas_target_t *ptgt, int what) 8488 { 8489 8490 NDBG25(("mptsas_set_throttle: throttle=%x", what)); 8491 8492 /* 8493 * if the bus is draining/quiesced, no changes to the throttles 8494 * are allowed. Not allowing change of throttles during draining 8495 * limits error recovery but will reduce draining time 8496 * 8497 * all throttles should have been set to HOLD_THROTTLE 8498 */ 8499 if (mpt->m_softstate & (MPTSAS_SS_QUIESCED | MPTSAS_SS_DRAINING)) { 8500 return; 8501 } 8502 8503 if (what == HOLD_THROTTLE) { 8504 ptgt->m_t_throttle = HOLD_THROTTLE; 8505 } else if (ptgt->m_reset_delay == 0) { 8506 ptgt->m_t_throttle = what; 8507 } 8508 } 8509 8510 /* 8511 * Clean up from a device reset. 8512 * For the case of target reset, this function clears the waitq of all 8513 * commands for a particular target. For the case of abort task set, this 8514 * function clears the waitq of all commonds for a particular target/lun. 8515 */ 8516 static void 8517 mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype) 8518 { 8519 mptsas_slots_t *slots = mpt->m_active; 8520 mptsas_cmd_t *cmd, *next_cmd; 8521 int slot; 8522 uchar_t reason; 8523 uint_t stat; 8524 8525 NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun)); 8526 8527 /* 8528 * Make sure the I/O Controller has flushed all cmds 8529 * that are associated with this target for a target reset 8530 * and target/lun for abort task set. 8531 * Account for TM requests, which use the last SMID. 8532 */ 8533 for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) { 8534 if ((cmd = slots->m_slot[slot]) == NULL) 8535 continue; 8536 reason = CMD_RESET; 8537 stat = STAT_DEV_RESET; 8538 switch (tasktype) { 8539 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 8540 if (Tgt(cmd) == target) { 8541 NDBG25(("mptsas_flush_target discovered non-" 8542 "NULL cmd in slot %d, tasktype 0x%x", slot, 8543 tasktype)); 8544 mptsas_dump_cmd(mpt, cmd); 8545 mptsas_remove_cmd(mpt, cmd); 8546 mptsas_set_pkt_reason(mpt, cmd, reason, stat); 8547 mptsas_doneq_add(mpt, cmd); 8548 } 8549 break; 8550 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 8551 reason = CMD_ABORTED; 8552 stat = STAT_ABORTED; 8553 /*FALLTHROUGH*/ 8554 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 8555 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 8556 8557 NDBG25(("mptsas_flush_target discovered non-" 8558 "NULL cmd in slot %d, tasktype 0x%x", slot, 8559 tasktype)); 8560 mptsas_dump_cmd(mpt, cmd); 8561 mptsas_remove_cmd(mpt, cmd); 8562 mptsas_set_pkt_reason(mpt, cmd, reason, 8563 stat); 8564 mptsas_doneq_add(mpt, cmd); 8565 } 8566 break; 8567 default: 8568 break; 8569 } 8570 } 8571 8572 /* 8573 * Flush the waitq and tx_waitq of this target's cmds 8574 */ 8575 cmd = mpt->m_waitq; 8576 8577 reason = CMD_RESET; 8578 stat = STAT_DEV_RESET; 8579 8580 switch (tasktype) { 8581 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 8582 while (cmd != NULL) { 8583 next_cmd = cmd->cmd_linkp; 8584 if (Tgt(cmd) == target) { 8585 mptsas_waitq_delete(mpt, cmd); 8586 mptsas_set_pkt_reason(mpt, cmd, 8587 reason, stat); 8588 mptsas_doneq_add(mpt, cmd); 8589 } 8590 cmd = next_cmd; 8591 } 8592 mutex_enter(&mpt->m_tx_waitq_mutex); 8593 cmd = mpt->m_tx_waitq; 8594 while (cmd != NULL) { 8595 next_cmd = cmd->cmd_linkp; 8596 if (Tgt(cmd) == target) { 8597 mptsas_tx_waitq_delete(mpt, cmd); 8598 mutex_exit(&mpt->m_tx_waitq_mutex); 8599 mptsas_set_pkt_reason(mpt, cmd, 8600 reason, stat); 8601 mptsas_doneq_add(mpt, cmd); 8602 mutex_enter(&mpt->m_tx_waitq_mutex); 8603 } 8604 cmd = next_cmd; 8605 } 8606 mutex_exit(&mpt->m_tx_waitq_mutex); 8607 break; 8608 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 8609 reason = CMD_ABORTED; 8610 stat = STAT_ABORTED; 8611 /*FALLTHROUGH*/ 8612 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 8613 while (cmd != NULL) { 8614 next_cmd = cmd->cmd_linkp; 8615 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 8616 mptsas_waitq_delete(mpt, cmd); 8617 mptsas_set_pkt_reason(mpt, cmd, 8618 reason, stat); 8619 mptsas_doneq_add(mpt, cmd); 8620 } 8621 cmd = next_cmd; 8622 } 8623 mutex_enter(&mpt->m_tx_waitq_mutex); 8624 cmd = mpt->m_tx_waitq; 8625 while (cmd != NULL) { 8626 next_cmd = cmd->cmd_linkp; 8627 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 8628 mptsas_tx_waitq_delete(mpt, cmd); 8629 mutex_exit(&mpt->m_tx_waitq_mutex); 8630 mptsas_set_pkt_reason(mpt, cmd, 8631 reason, stat); 8632 mptsas_doneq_add(mpt, cmd); 8633 mutex_enter(&mpt->m_tx_waitq_mutex); 8634 } 8635 cmd = next_cmd; 8636 } 8637 mutex_exit(&mpt->m_tx_waitq_mutex); 8638 break; 8639 default: 8640 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.", 8641 tasktype); 8642 break; 8643 } 8644 } 8645 8646 /* 8647 * Clean up hba state, abort all outstanding command and commands in waitq 8648 * reset timeout of all targets. 8649 */ 8650 static void 8651 mptsas_flush_hba(mptsas_t *mpt) 8652 { 8653 mptsas_slots_t *slots = mpt->m_active; 8654 mptsas_cmd_t *cmd; 8655 int slot; 8656 8657 NDBG25(("mptsas_flush_hba")); 8658 8659 /* 8660 * The I/O Controller should have already sent back 8661 * all commands via the scsi I/O reply frame. Make 8662 * sure all commands have been flushed. 8663 * Account for TM request, which use the last SMID. 8664 */ 8665 for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) { 8666 if ((cmd = slots->m_slot[slot]) == NULL) 8667 continue; 8668 8669 if (cmd->cmd_flags & CFLAG_CMDIOC) { 8670 /* 8671 * Need to make sure to tell everyone that might be 8672 * waiting on this command that it's going to fail. If 8673 * we get here, this command will never timeout because 8674 * the active command table is going to be re-allocated, 8675 * so there will be nothing to check against a time out. 8676 * Instead, mark the command as failed due to reset. 8677 */ 8678 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, 8679 STAT_BUS_RESET); 8680 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 8681 (cmd->cmd_flags & CFLAG_CONFIG) || 8682 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 8683 cmd->cmd_flags |= CFLAG_FINISHED; 8684 cv_broadcast(&mpt->m_passthru_cv); 8685 cv_broadcast(&mpt->m_config_cv); 8686 cv_broadcast(&mpt->m_fw_diag_cv); 8687 } 8688 continue; 8689 } 8690 8691 NDBG25(("mptsas_flush_hba discovered non-NULL cmd in slot %d", 8692 slot)); 8693 mptsas_dump_cmd(mpt, cmd); 8694 8695 mptsas_remove_cmd(mpt, cmd); 8696 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 8697 mptsas_doneq_add(mpt, cmd); 8698 } 8699 8700 /* 8701 * Flush the waitq. 8702 */ 8703 while ((cmd = mptsas_waitq_rm(mpt)) != NULL) { 8704 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 8705 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 8706 (cmd->cmd_flags & CFLAG_CONFIG) || 8707 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 8708 cmd->cmd_flags |= CFLAG_FINISHED; 8709 cv_broadcast(&mpt->m_passthru_cv); 8710 cv_broadcast(&mpt->m_config_cv); 8711 cv_broadcast(&mpt->m_fw_diag_cv); 8712 } else { 8713 mptsas_doneq_add(mpt, cmd); 8714 } 8715 } 8716 8717 /* 8718 * Flush the tx_waitq 8719 */ 8720 mutex_enter(&mpt->m_tx_waitq_mutex); 8721 while ((cmd = mptsas_tx_waitq_rm(mpt)) != NULL) { 8722 mutex_exit(&mpt->m_tx_waitq_mutex); 8723 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 8724 mptsas_doneq_add(mpt, cmd); 8725 mutex_enter(&mpt->m_tx_waitq_mutex); 8726 } 8727 mutex_exit(&mpt->m_tx_waitq_mutex); 8728 8729 /* 8730 * Drain the taskqs prior to reallocating resources. 8731 */ 8732 mutex_exit(&mpt->m_mutex); 8733 ddi_taskq_wait(mpt->m_event_taskq); 8734 ddi_taskq_wait(mpt->m_dr_taskq); 8735 mutex_enter(&mpt->m_mutex); 8736 } 8737 8738 /* 8739 * set pkt_reason and OR in pkt_statistics flag 8740 */ 8741 static void 8742 mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, uchar_t reason, 8743 uint_t stat) 8744 { 8745 #ifndef __lock_lint 8746 _NOTE(ARGUNUSED(mpt)) 8747 #endif 8748 8749 NDBG25(("mptsas_set_pkt_reason: cmd=0x%p reason=%x stat=%x", 8750 (void *)cmd, reason, stat)); 8751 8752 if (cmd) { 8753 if (cmd->cmd_pkt->pkt_reason == CMD_CMPLT) { 8754 cmd->cmd_pkt->pkt_reason = reason; 8755 } 8756 cmd->cmd_pkt->pkt_statistics |= stat; 8757 } 8758 } 8759 8760 static void 8761 mptsas_start_watch_reset_delay() 8762 { 8763 NDBG22(("mptsas_start_watch_reset_delay")); 8764 8765 mutex_enter(&mptsas_global_mutex); 8766 if (mptsas_reset_watch == NULL && mptsas_timeouts_enabled) { 8767 mptsas_reset_watch = timeout(mptsas_watch_reset_delay, NULL, 8768 drv_usectohz((clock_t) 8769 MPTSAS_WATCH_RESET_DELAY_TICK * 1000)); 8770 ASSERT(mptsas_reset_watch != NULL); 8771 } 8772 mutex_exit(&mptsas_global_mutex); 8773 } 8774 8775 static void 8776 mptsas_setup_bus_reset_delay(mptsas_t *mpt) 8777 { 8778 mptsas_target_t *ptgt = NULL; 8779 8780 NDBG22(("mptsas_setup_bus_reset_delay")); 8781 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 8782 MPTSAS_HASH_FIRST); 8783 while (ptgt != NULL) { 8784 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 8785 ptgt->m_reset_delay = mpt->m_scsi_reset_delay; 8786 8787 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 8788 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 8789 } 8790 8791 mptsas_start_watch_reset_delay(); 8792 } 8793 8794 /* 8795 * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every 8796 * mpt instance for active reset delays 8797 */ 8798 static void 8799 mptsas_watch_reset_delay(void *arg) 8800 { 8801 #ifndef __lock_lint 8802 _NOTE(ARGUNUSED(arg)) 8803 #endif 8804 8805 mptsas_t *mpt; 8806 int not_done = 0; 8807 8808 NDBG22(("mptsas_watch_reset_delay")); 8809 8810 mutex_enter(&mptsas_global_mutex); 8811 mptsas_reset_watch = 0; 8812 mutex_exit(&mptsas_global_mutex); 8813 rw_enter(&mptsas_global_rwlock, RW_READER); 8814 for (mpt = mptsas_head; mpt != NULL; mpt = mpt->m_next) { 8815 if (mpt->m_tran == 0) { 8816 continue; 8817 } 8818 mutex_enter(&mpt->m_mutex); 8819 not_done += mptsas_watch_reset_delay_subr(mpt); 8820 mutex_exit(&mpt->m_mutex); 8821 } 8822 rw_exit(&mptsas_global_rwlock); 8823 8824 if (not_done) { 8825 mptsas_start_watch_reset_delay(); 8826 } 8827 } 8828 8829 static int 8830 mptsas_watch_reset_delay_subr(mptsas_t *mpt) 8831 { 8832 int done = 0; 8833 int restart = 0; 8834 mptsas_target_t *ptgt = NULL; 8835 8836 NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt)); 8837 8838 ASSERT(mutex_owned(&mpt->m_mutex)); 8839 8840 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 8841 MPTSAS_HASH_FIRST); 8842 while (ptgt != NULL) { 8843 if (ptgt->m_reset_delay != 0) { 8844 ptgt->m_reset_delay -= 8845 MPTSAS_WATCH_RESET_DELAY_TICK; 8846 if (ptgt->m_reset_delay <= 0) { 8847 ptgt->m_reset_delay = 0; 8848 mptsas_set_throttle(mpt, ptgt, 8849 MAX_THROTTLE); 8850 restart++; 8851 } else { 8852 done = -1; 8853 } 8854 } 8855 8856 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 8857 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 8858 } 8859 8860 if (restart > 0) { 8861 mptsas_restart_hba(mpt); 8862 } 8863 return (done); 8864 } 8865 8866 #ifdef MPTSAS_TEST 8867 static void 8868 mptsas_test_reset(mptsas_t *mpt, int target) 8869 { 8870 mptsas_target_t *ptgt = NULL; 8871 8872 if (mptsas_rtest == target) { 8873 if (mptsas_do_scsi_reset(mpt, target) == TRUE) { 8874 mptsas_rtest = -1; 8875 } 8876 if (mptsas_rtest == -1) { 8877 NDBG22(("mptsas_test_reset success")); 8878 } 8879 } 8880 } 8881 #endif 8882 8883 /* 8884 * abort handling: 8885 * 8886 * Notes: 8887 * - if pkt is not NULL, abort just that command 8888 * - if pkt is NULL, abort all outstanding commands for target 8889 */ 8890 static int 8891 mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt) 8892 { 8893 mptsas_t *mpt = ADDR2MPT(ap); 8894 int rval; 8895 mptsas_tgt_private_t *tgt_private; 8896 int target, lun; 8897 8898 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran-> 8899 tran_tgt_private; 8900 ASSERT(tgt_private != NULL); 8901 target = tgt_private->t_private->m_devhdl; 8902 lun = tgt_private->t_lun; 8903 8904 NDBG23(("mptsas_scsi_abort: target=%d.%d", target, lun)); 8905 8906 mutex_enter(&mpt->m_mutex); 8907 rval = mptsas_do_scsi_abort(mpt, target, lun, pkt); 8908 mutex_exit(&mpt->m_mutex); 8909 return (rval); 8910 } 8911 8912 static int 8913 mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, struct scsi_pkt *pkt) 8914 { 8915 mptsas_cmd_t *sp = NULL; 8916 mptsas_slots_t *slots = mpt->m_active; 8917 int rval = FALSE; 8918 8919 ASSERT(mutex_owned(&mpt->m_mutex)); 8920 8921 /* 8922 * Abort the command pkt on the target/lun in ap. If pkt is 8923 * NULL, abort all outstanding commands on that target/lun. 8924 * If you can abort them, return 1, else return 0. 8925 * Each packet that's aborted should be sent back to the target 8926 * driver through the callback routine, with pkt_reason set to 8927 * CMD_ABORTED. 8928 * 8929 * abort cmd pkt on HBA hardware; clean out of outstanding 8930 * command lists, etc. 8931 */ 8932 if (pkt != NULL) { 8933 /* abort the specified packet */ 8934 sp = PKT2CMD(pkt); 8935 8936 if (sp->cmd_queued) { 8937 NDBG23(("mptsas_do_scsi_abort: queued sp=0x%p aborted", 8938 (void *)sp)); 8939 mptsas_waitq_delete(mpt, sp); 8940 mptsas_set_pkt_reason(mpt, sp, CMD_ABORTED, 8941 STAT_ABORTED); 8942 mptsas_doneq_add(mpt, sp); 8943 rval = TRUE; 8944 goto done; 8945 } 8946 8947 /* 8948 * Have mpt firmware abort this command 8949 */ 8950 8951 if (slots->m_slot[sp->cmd_slot] != NULL) { 8952 rval = mptsas_ioc_task_management(mpt, 8953 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, target, 8954 lun, NULL, 0, 0); 8955 8956 /* 8957 * The transport layer expects only TRUE and FALSE. 8958 * Therefore, if mptsas_ioc_task_management returns 8959 * FAILED we will return FALSE. 8960 */ 8961 if (rval == FAILED) 8962 rval = FALSE; 8963 goto done; 8964 } 8965 } 8966 8967 /* 8968 * If pkt is NULL then abort task set 8969 */ 8970 rval = mptsas_ioc_task_management(mpt, 8971 MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, target, lun, NULL, 0, 0); 8972 8973 /* 8974 * The transport layer expects only TRUE and FALSE. 8975 * Therefore, if mptsas_ioc_task_management returns 8976 * FAILED we will return FALSE. 8977 */ 8978 if (rval == FAILED) 8979 rval = FALSE; 8980 8981 #ifdef MPTSAS_TEST 8982 if (rval && mptsas_test_stop) { 8983 debug_enter("mptsas_do_scsi_abort"); 8984 } 8985 #endif 8986 8987 done: 8988 mptsas_doneq_empty(mpt); 8989 return (rval); 8990 } 8991 8992 /* 8993 * capability handling: 8994 * (*tran_getcap). Get the capability named, and return its value. 8995 */ 8996 static int 8997 mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly) 8998 { 8999 mptsas_t *mpt = ADDR2MPT(ap); 9000 int ckey; 9001 int rval = FALSE; 9002 9003 NDBG24(("mptsas_scsi_getcap: target=%d, cap=%s tgtonly=%x", 9004 ap->a_target, cap, tgtonly)); 9005 9006 mutex_enter(&mpt->m_mutex); 9007 9008 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) { 9009 mutex_exit(&mpt->m_mutex); 9010 return (UNDEFINED); 9011 } 9012 9013 switch (ckey) { 9014 case SCSI_CAP_DMA_MAX: 9015 rval = (int)mpt->m_msg_dma_attr.dma_attr_maxxfer; 9016 break; 9017 case SCSI_CAP_ARQ: 9018 rval = TRUE; 9019 break; 9020 case SCSI_CAP_MSG_OUT: 9021 case SCSI_CAP_PARITY: 9022 case SCSI_CAP_UNTAGGED_QING: 9023 rval = TRUE; 9024 break; 9025 case SCSI_CAP_TAGGED_QING: 9026 rval = TRUE; 9027 break; 9028 case SCSI_CAP_RESET_NOTIFICATION: 9029 rval = TRUE; 9030 break; 9031 case SCSI_CAP_LINKED_CMDS: 9032 rval = FALSE; 9033 break; 9034 case SCSI_CAP_QFULL_RETRIES: 9035 rval = ((mptsas_tgt_private_t *)(ap->a_hba_tran-> 9036 tran_tgt_private))->t_private->m_qfull_retries; 9037 break; 9038 case SCSI_CAP_QFULL_RETRY_INTERVAL: 9039 rval = drv_hztousec(((mptsas_tgt_private_t *) 9040 (ap->a_hba_tran->tran_tgt_private))-> 9041 t_private->m_qfull_retry_interval) / 1000; 9042 break; 9043 case SCSI_CAP_CDB_LEN: 9044 rval = CDB_GROUP4; 9045 break; 9046 case SCSI_CAP_INTERCONNECT_TYPE: 9047 rval = INTERCONNECT_SAS; 9048 break; 9049 case SCSI_CAP_TRAN_LAYER_RETRIES: 9050 if (mpt->m_ioc_capabilities & 9051 MPI2_IOCFACTS_CAPABILITY_TLR) 9052 rval = TRUE; 9053 else 9054 rval = FALSE; 9055 break; 9056 default: 9057 rval = UNDEFINED; 9058 break; 9059 } 9060 9061 NDBG24(("mptsas_scsi_getcap: %s, rval=%x", cap, rval)); 9062 9063 mutex_exit(&mpt->m_mutex); 9064 return (rval); 9065 } 9066 9067 /* 9068 * (*tran_setcap). Set the capability named to the value given. 9069 */ 9070 static int 9071 mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, int tgtonly) 9072 { 9073 mptsas_t *mpt = ADDR2MPT(ap); 9074 int ckey; 9075 int rval = FALSE; 9076 9077 NDBG24(("mptsas_scsi_setcap: target=%d, cap=%s value=%x tgtonly=%x", 9078 ap->a_target, cap, value, tgtonly)); 9079 9080 if (!tgtonly) { 9081 return (rval); 9082 } 9083 9084 mutex_enter(&mpt->m_mutex); 9085 9086 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) { 9087 mutex_exit(&mpt->m_mutex); 9088 return (UNDEFINED); 9089 } 9090 9091 switch (ckey) { 9092 case SCSI_CAP_DMA_MAX: 9093 case SCSI_CAP_MSG_OUT: 9094 case SCSI_CAP_PARITY: 9095 case SCSI_CAP_INITIATOR_ID: 9096 case SCSI_CAP_LINKED_CMDS: 9097 case SCSI_CAP_UNTAGGED_QING: 9098 case SCSI_CAP_RESET_NOTIFICATION: 9099 /* 9100 * None of these are settable via 9101 * the capability interface. 9102 */ 9103 break; 9104 case SCSI_CAP_ARQ: 9105 /* 9106 * We cannot turn off arq so return false if asked to 9107 */ 9108 if (value) { 9109 rval = TRUE; 9110 } else { 9111 rval = FALSE; 9112 } 9113 break; 9114 case SCSI_CAP_TAGGED_QING: 9115 mptsas_set_throttle(mpt, ((mptsas_tgt_private_t *) 9116 (ap->a_hba_tran->tran_tgt_private))->t_private, 9117 MAX_THROTTLE); 9118 rval = TRUE; 9119 break; 9120 case SCSI_CAP_QFULL_RETRIES: 9121 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))-> 9122 t_private->m_qfull_retries = (uchar_t)value; 9123 rval = TRUE; 9124 break; 9125 case SCSI_CAP_QFULL_RETRY_INTERVAL: 9126 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))-> 9127 t_private->m_qfull_retry_interval = 9128 drv_usectohz(value * 1000); 9129 rval = TRUE; 9130 break; 9131 default: 9132 rval = UNDEFINED; 9133 break; 9134 } 9135 mutex_exit(&mpt->m_mutex); 9136 return (rval); 9137 } 9138 9139 /* 9140 * Utility routine for mptsas_ifsetcap/ifgetcap 9141 */ 9142 /*ARGSUSED*/ 9143 static int 9144 mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp) 9145 { 9146 NDBG24(("mptsas_scsi_capchk: cap=%s", cap)); 9147 9148 if (!cap) 9149 return (FALSE); 9150 9151 *cidxp = scsi_hba_lookup_capstr(cap); 9152 return (TRUE); 9153 } 9154 9155 static int 9156 mptsas_alloc_active_slots(mptsas_t *mpt, int flag) 9157 { 9158 mptsas_slots_t *old_active = mpt->m_active; 9159 mptsas_slots_t *new_active; 9160 size_t size; 9161 int rval = -1, i; 9162 9163 /* 9164 * if there are active commands, then we cannot 9165 * change size of active slots array. 9166 */ 9167 ASSERT(mpt->m_ncmds == 0); 9168 9169 size = MPTSAS_SLOTS_SIZE(mpt); 9170 new_active = kmem_zalloc(size, flag); 9171 if (new_active == NULL) { 9172 NDBG1(("new active alloc failed")); 9173 return (rval); 9174 } 9175 /* 9176 * Since SMID 0 is reserved and the TM slot is reserved, the 9177 * number of slots that can be used at any one time is 9178 * m_max_requests - 2. 9179 */ 9180 new_active->m_n_slots = (mpt->m_max_requests - 2); 9181 new_active->m_size = size; 9182 new_active->m_tags = 1; 9183 if (old_active) { 9184 new_active->m_tgttbl = old_active->m_tgttbl; 9185 new_active->m_smptbl = old_active->m_smptbl; 9186 new_active->m_num_raid_configs = 9187 old_active->m_num_raid_configs; 9188 for (i = 0; i < new_active->m_num_raid_configs; i++) { 9189 new_active->m_raidconfig[i] = 9190 old_active->m_raidconfig[i]; 9191 } 9192 mptsas_free_active_slots(mpt); 9193 } 9194 mpt->m_active = new_active; 9195 rval = 0; 9196 9197 return (rval); 9198 } 9199 9200 static void 9201 mptsas_free_active_slots(mptsas_t *mpt) 9202 { 9203 mptsas_slots_t *active = mpt->m_active; 9204 size_t size; 9205 9206 if (active == NULL) 9207 return; 9208 size = active->m_size; 9209 kmem_free(active, size); 9210 mpt->m_active = NULL; 9211 } 9212 9213 /* 9214 * Error logging, printing, and debug print routines. 9215 */ 9216 static char *mptsas_label = "mpt_sas"; 9217 9218 /*PRINTFLIKE3*/ 9219 void 9220 mptsas_log(mptsas_t *mpt, int level, char *fmt, ...) 9221 { 9222 dev_info_t *dev; 9223 va_list ap; 9224 9225 if (mpt) { 9226 dev = mpt->m_dip; 9227 } else { 9228 dev = 0; 9229 } 9230 9231 mutex_enter(&mptsas_log_mutex); 9232 9233 va_start(ap, fmt); 9234 (void) vsprintf(mptsas_log_buf, fmt, ap); 9235 va_end(ap); 9236 9237 if (level == CE_CONT) { 9238 scsi_log(dev, mptsas_label, level, "%s\n", mptsas_log_buf); 9239 } else { 9240 scsi_log(dev, mptsas_label, level, "%s", mptsas_log_buf); 9241 } 9242 9243 mutex_exit(&mptsas_log_mutex); 9244 } 9245 9246 #ifdef MPTSAS_DEBUG 9247 /*PRINTFLIKE1*/ 9248 void 9249 mptsas_printf(char *fmt, ...) 9250 { 9251 dev_info_t *dev = 0; 9252 va_list ap; 9253 9254 mutex_enter(&mptsas_log_mutex); 9255 9256 va_start(ap, fmt); 9257 (void) vsprintf(mptsas_log_buf, fmt, ap); 9258 va_end(ap); 9259 9260 #ifdef PROM_PRINTF 9261 prom_printf("%s:\t%s\n", mptsas_label, mptsas_log_buf); 9262 #else 9263 scsi_log(dev, mptsas_label, SCSI_DEBUG, "%s\n", mptsas_log_buf); 9264 #endif 9265 mutex_exit(&mptsas_log_mutex); 9266 } 9267 #endif 9268 9269 /* 9270 * timeout handling 9271 */ 9272 static void 9273 mptsas_watch(void *arg) 9274 { 9275 #ifndef __lock_lint 9276 _NOTE(ARGUNUSED(arg)) 9277 #endif 9278 9279 mptsas_t *mpt; 9280 uint32_t doorbell; 9281 9282 NDBG30(("mptsas_watch")); 9283 9284 rw_enter(&mptsas_global_rwlock, RW_READER); 9285 for (mpt = mptsas_head; mpt != (mptsas_t *)NULL; mpt = mpt->m_next) { 9286 9287 mutex_enter(&mpt->m_mutex); 9288 9289 /* Skip device if not powered on */ 9290 if (mpt->m_options & MPTSAS_OPT_PM) { 9291 if (mpt->m_power_level == PM_LEVEL_D0) { 9292 (void) pm_busy_component(mpt->m_dip, 0); 9293 mpt->m_busy = 1; 9294 } else { 9295 mutex_exit(&mpt->m_mutex); 9296 continue; 9297 } 9298 } 9299 9300 /* 9301 * Check if controller is in a FAULT state. If so, reset it. 9302 */ 9303 doorbell = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell); 9304 if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { 9305 doorbell &= MPI2_DOORBELL_DATA_MASK; 9306 mptsas_log(mpt, CE_WARN, "MPT Firmware Fault, " 9307 "code: %04x", doorbell); 9308 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 9309 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 9310 mptsas_log(mpt, CE_WARN, "Reset failed" 9311 "after fault was detected"); 9312 } 9313 } 9314 9315 /* 9316 * For now, always call mptsas_watchsubr. 9317 */ 9318 mptsas_watchsubr(mpt); 9319 9320 if (mpt->m_options & MPTSAS_OPT_PM) { 9321 mpt->m_busy = 0; 9322 (void) pm_idle_component(mpt->m_dip, 0); 9323 } 9324 9325 mutex_exit(&mpt->m_mutex); 9326 } 9327 rw_exit(&mptsas_global_rwlock); 9328 9329 mutex_enter(&mptsas_global_mutex); 9330 if (mptsas_timeouts_enabled) 9331 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick); 9332 mutex_exit(&mptsas_global_mutex); 9333 } 9334 9335 static void 9336 mptsas_watchsubr(mptsas_t *mpt) 9337 { 9338 int i; 9339 mptsas_cmd_t *cmd; 9340 mptsas_target_t *ptgt = NULL; 9341 9342 NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt)); 9343 9344 #ifdef MPTSAS_TEST 9345 if (mptsas_enable_untagged) { 9346 mptsas_test_untagged++; 9347 } 9348 #endif 9349 9350 /* 9351 * Check for commands stuck in active slot 9352 * Account for TM requests, which use the last SMID. 9353 */ 9354 for (i = 0; i <= mpt->m_active->m_n_slots; i++) { 9355 if ((cmd = mpt->m_active->m_slot[i]) != NULL) { 9356 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 9357 cmd->cmd_active_timeout -= 9358 mptsas_scsi_watchdog_tick; 9359 if (cmd->cmd_active_timeout <= 0) { 9360 /* 9361 * There seems to be a command stuck 9362 * in the active slot. Drain throttle. 9363 */ 9364 mptsas_set_throttle(mpt, 9365 cmd->cmd_tgt_addr, 9366 DRAIN_THROTTLE); 9367 } 9368 } 9369 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 9370 (cmd->cmd_flags & CFLAG_CONFIG) || 9371 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 9372 cmd->cmd_active_timeout -= 9373 mptsas_scsi_watchdog_tick; 9374 if (cmd->cmd_active_timeout <= 0) { 9375 /* 9376 * passthrough command timeout 9377 */ 9378 cmd->cmd_flags |= (CFLAG_FINISHED | 9379 CFLAG_TIMEOUT); 9380 cv_broadcast(&mpt->m_passthru_cv); 9381 cv_broadcast(&mpt->m_config_cv); 9382 cv_broadcast(&mpt->m_fw_diag_cv); 9383 } 9384 } 9385 } 9386 } 9387 9388 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 9389 MPTSAS_HASH_FIRST); 9390 while (ptgt != NULL) { 9391 /* 9392 * If we were draining due to a qfull condition, 9393 * go back to full throttle. 9394 */ 9395 if ((ptgt->m_t_throttle < MAX_THROTTLE) && 9396 (ptgt->m_t_throttle > HOLD_THROTTLE) && 9397 (ptgt->m_t_ncmds < ptgt->m_t_throttle)) { 9398 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 9399 mptsas_restart_hba(mpt); 9400 } 9401 9402 if ((ptgt->m_t_ncmds > 0) && 9403 (ptgt->m_timebase)) { 9404 9405 if (ptgt->m_timebase <= 9406 mptsas_scsi_watchdog_tick) { 9407 ptgt->m_timebase += 9408 mptsas_scsi_watchdog_tick; 9409 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9410 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9411 continue; 9412 } 9413 9414 ptgt->m_timeout -= mptsas_scsi_watchdog_tick; 9415 9416 if (ptgt->m_timeout < 0) { 9417 mptsas_cmd_timeout(mpt, ptgt->m_devhdl); 9418 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9419 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9420 continue; 9421 } 9422 9423 if ((ptgt->m_timeout) <= 9424 mptsas_scsi_watchdog_tick) { 9425 NDBG23(("pending timeout")); 9426 mptsas_set_throttle(mpt, ptgt, 9427 DRAIN_THROTTLE); 9428 } 9429 } 9430 9431 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9432 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9433 } 9434 } 9435 9436 /* 9437 * timeout recovery 9438 */ 9439 static void 9440 mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl) 9441 { 9442 9443 NDBG29(("mptsas_cmd_timeout: target=%d", devhdl)); 9444 mptsas_log(mpt, CE_WARN, "Disconnected command timeout for " 9445 "Target %d", devhdl); 9446 9447 /* 9448 * If the current target is not the target passed in, 9449 * try to reset that target. 9450 */ 9451 NDBG29(("mptsas_cmd_timeout: device reset")); 9452 if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) { 9453 mptsas_log(mpt, CE_WARN, "Target %d reset for command timeout " 9454 "recovery failed!", devhdl); 9455 } 9456 } 9457 9458 /* 9459 * Device / Hotplug control 9460 */ 9461 static int 9462 mptsas_scsi_quiesce(dev_info_t *dip) 9463 { 9464 mptsas_t *mpt; 9465 scsi_hba_tran_t *tran; 9466 9467 tran = ddi_get_driver_private(dip); 9468 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL) 9469 return (-1); 9470 9471 return (mptsas_quiesce_bus(mpt)); 9472 } 9473 9474 static int 9475 mptsas_scsi_unquiesce(dev_info_t *dip) 9476 { 9477 mptsas_t *mpt; 9478 scsi_hba_tran_t *tran; 9479 9480 tran = ddi_get_driver_private(dip); 9481 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL) 9482 return (-1); 9483 9484 return (mptsas_unquiesce_bus(mpt)); 9485 } 9486 9487 static int 9488 mptsas_quiesce_bus(mptsas_t *mpt) 9489 { 9490 mptsas_target_t *ptgt = NULL; 9491 9492 NDBG28(("mptsas_quiesce_bus")); 9493 mutex_enter(&mpt->m_mutex); 9494 9495 /* Set all the throttles to zero */ 9496 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 9497 MPTSAS_HASH_FIRST); 9498 while (ptgt != NULL) { 9499 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 9500 9501 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9502 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9503 } 9504 9505 /* If there are any outstanding commands in the queue */ 9506 if (mpt->m_ncmds) { 9507 mpt->m_softstate |= MPTSAS_SS_DRAINING; 9508 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain, 9509 mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000))); 9510 if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) { 9511 /* 9512 * Quiesce has been interrupted 9513 */ 9514 mpt->m_softstate &= ~MPTSAS_SS_DRAINING; 9515 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9516 &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST); 9517 while (ptgt != NULL) { 9518 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 9519 9520 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9521 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9522 } 9523 mptsas_restart_hba(mpt); 9524 if (mpt->m_quiesce_timeid != 0) { 9525 timeout_id_t tid = mpt->m_quiesce_timeid; 9526 mpt->m_quiesce_timeid = 0; 9527 mutex_exit(&mpt->m_mutex); 9528 (void) untimeout(tid); 9529 return (-1); 9530 } 9531 mutex_exit(&mpt->m_mutex); 9532 return (-1); 9533 } else { 9534 /* Bus has been quiesced */ 9535 ASSERT(mpt->m_quiesce_timeid == 0); 9536 mpt->m_softstate &= ~MPTSAS_SS_DRAINING; 9537 mpt->m_softstate |= MPTSAS_SS_QUIESCED; 9538 mutex_exit(&mpt->m_mutex); 9539 return (0); 9540 } 9541 } 9542 /* Bus was not busy - QUIESCED */ 9543 mutex_exit(&mpt->m_mutex); 9544 9545 return (0); 9546 } 9547 9548 static int 9549 mptsas_unquiesce_bus(mptsas_t *mpt) 9550 { 9551 mptsas_target_t *ptgt = NULL; 9552 9553 NDBG28(("mptsas_unquiesce_bus")); 9554 mutex_enter(&mpt->m_mutex); 9555 mpt->m_softstate &= ~MPTSAS_SS_QUIESCED; 9556 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 9557 MPTSAS_HASH_FIRST); 9558 while (ptgt != NULL) { 9559 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 9560 9561 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9562 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9563 } 9564 mptsas_restart_hba(mpt); 9565 mutex_exit(&mpt->m_mutex); 9566 return (0); 9567 } 9568 9569 static void 9570 mptsas_ncmds_checkdrain(void *arg) 9571 { 9572 mptsas_t *mpt = arg; 9573 mptsas_target_t *ptgt = NULL; 9574 9575 mutex_enter(&mpt->m_mutex); 9576 if (mpt->m_softstate & MPTSAS_SS_DRAINING) { 9577 mpt->m_quiesce_timeid = 0; 9578 if (mpt->m_ncmds == 0) { 9579 /* Command queue has been drained */ 9580 cv_signal(&mpt->m_cv); 9581 } else { 9582 /* 9583 * The throttle may have been reset because 9584 * of a SCSI bus reset 9585 */ 9586 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9587 &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST); 9588 while (ptgt != NULL) { 9589 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 9590 9591 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9592 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9593 } 9594 9595 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain, 9596 mpt, (MPTSAS_QUIESCE_TIMEOUT * 9597 drv_usectohz(1000000))); 9598 } 9599 } 9600 mutex_exit(&mpt->m_mutex); 9601 } 9602 9603 /*ARGSUSED*/ 9604 static void 9605 mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 9606 { 9607 int i; 9608 uint8_t *cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp; 9609 char buf[128]; 9610 9611 buf[0] = '\0'; 9612 NDBG25(("?Cmd (0x%p) dump for Target %d Lun %d:\n", (void *)cmd, 9613 Tgt(cmd), Lun(cmd))); 9614 (void) sprintf(&buf[0], "\tcdb=["); 9615 for (i = 0; i < (int)cmd->cmd_cdblen; i++) { 9616 (void) sprintf(&buf[strlen(buf)], " 0x%x", *cp++); 9617 } 9618 (void) sprintf(&buf[strlen(buf)], " ]"); 9619 NDBG25(("?%s\n", buf)); 9620 NDBG25(("?pkt_flags=0x%x pkt_statistics=0x%x pkt_state=0x%x\n", 9621 cmd->cmd_pkt->pkt_flags, cmd->cmd_pkt->pkt_statistics, 9622 cmd->cmd_pkt->pkt_state)); 9623 NDBG25(("?pkt_scbp=0x%x cmd_flags=0x%x\n", cmd->cmd_pkt->pkt_scbp ? 9624 *(cmd->cmd_pkt->pkt_scbp) : 0, cmd->cmd_flags)); 9625 } 9626 9627 static void 9628 mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd) 9629 { 9630 caddr_t memp; 9631 pMPI2RequestHeader_t request_hdrp; 9632 struct scsi_pkt *pkt = cmd->cmd_pkt; 9633 mptsas_pt_request_t *pt = pkt->pkt_ha_private; 9634 uint32_t request_size, data_size, dataout_size; 9635 uint32_t direction; 9636 ddi_dma_cookie_t data_cookie; 9637 ddi_dma_cookie_t dataout_cookie; 9638 uint32_t request_desc_low, request_desc_high = 0; 9639 uint32_t i, sense_bufp; 9640 uint8_t desc_type; 9641 uint8_t *request, function; 9642 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; 9643 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl; 9644 9645 desc_type = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 9646 9647 request = pt->request; 9648 direction = pt->direction; 9649 request_size = pt->request_size; 9650 data_size = pt->data_size; 9651 dataout_size = pt->dataout_size; 9652 data_cookie = pt->data_cookie; 9653 dataout_cookie = pt->dataout_cookie; 9654 9655 /* 9656 * Store the passthrough message in memory location 9657 * corresponding to our slot number 9658 */ 9659 memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot); 9660 request_hdrp = (pMPI2RequestHeader_t)memp; 9661 bzero(memp, mpt->m_req_frame_size); 9662 9663 for (i = 0; i < request_size; i++) { 9664 bcopy(request + i, memp + i, 1); 9665 } 9666 9667 if (data_size || dataout_size) { 9668 pMpi2SGESimple64_t sgep; 9669 uint32_t sge_flags; 9670 9671 sgep = (pMpi2SGESimple64_t)((uint8_t *)request_hdrp + 9672 request_size); 9673 if (dataout_size) { 9674 9675 sge_flags = dataout_size | 9676 ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 9677 MPI2_SGE_FLAGS_END_OF_BUFFER | 9678 MPI2_SGE_FLAGS_HOST_TO_IOC | 9679 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 9680 MPI2_SGE_FLAGS_SHIFT); 9681 ddi_put32(acc_hdl, &sgep->FlagsLength, sge_flags); 9682 ddi_put32(acc_hdl, &sgep->Address.Low, 9683 (uint32_t)(dataout_cookie.dmac_laddress & 9684 0xffffffffull)); 9685 ddi_put32(acc_hdl, &sgep->Address.High, 9686 (uint32_t)(dataout_cookie.dmac_laddress 9687 >> 32)); 9688 sgep++; 9689 } 9690 sge_flags = data_size; 9691 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 9692 MPI2_SGE_FLAGS_LAST_ELEMENT | 9693 MPI2_SGE_FLAGS_END_OF_BUFFER | 9694 MPI2_SGE_FLAGS_END_OF_LIST | 9695 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 9696 MPI2_SGE_FLAGS_SHIFT); 9697 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) { 9698 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_HOST_TO_IOC) << 9699 MPI2_SGE_FLAGS_SHIFT); 9700 } else { 9701 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_IOC_TO_HOST) << 9702 MPI2_SGE_FLAGS_SHIFT); 9703 } 9704 ddi_put32(acc_hdl, &sgep->FlagsLength, 9705 sge_flags); 9706 ddi_put32(acc_hdl, &sgep->Address.Low, 9707 (uint32_t)(data_cookie.dmac_laddress & 9708 0xffffffffull)); 9709 ddi_put32(acc_hdl, &sgep->Address.High, 9710 (uint32_t)(data_cookie.dmac_laddress >> 32)); 9711 } 9712 9713 function = request_hdrp->Function; 9714 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) || 9715 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 9716 pMpi2SCSIIORequest_t scsi_io_req; 9717 9718 scsi_io_req = (pMpi2SCSIIORequest_t)request_hdrp; 9719 /* 9720 * Put SGE for data and data_out buffer at the end of 9721 * scsi_io_request message header.(64 bytes in total) 9722 * Following above SGEs, the residual space will be 9723 * used by sense data. 9724 */ 9725 ddi_put8(acc_hdl, 9726 &scsi_io_req->SenseBufferLength, 9727 (uint8_t)(request_size - 64)); 9728 9729 sense_bufp = mpt->m_req_frame_dma_addr + 9730 (mpt->m_req_frame_size * cmd->cmd_slot); 9731 sense_bufp += 64; 9732 ddi_put32(acc_hdl, 9733 &scsi_io_req->SenseBufferLowAddress, sense_bufp); 9734 9735 /* 9736 * Set SGLOffset0 value 9737 */ 9738 ddi_put8(acc_hdl, &scsi_io_req->SGLOffset0, 9739 offsetof(MPI2_SCSI_IO_REQUEST, SGL) / 4); 9740 9741 /* 9742 * Setup descriptor info. RAID passthrough must use the 9743 * default request descriptor which is already set, so if this 9744 * is a SCSI IO request, change the descriptor to SCSI IO. 9745 */ 9746 if (function == MPI2_FUNCTION_SCSI_IO_REQUEST) { 9747 desc_type = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 9748 request_desc_high = (ddi_get16(acc_hdl, 9749 &scsi_io_req->DevHandle) << 16); 9750 } 9751 } 9752 9753 /* 9754 * We must wait till the message has been completed before 9755 * beginning the next message so we wait for this one to 9756 * finish. 9757 */ 9758 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 9759 request_desc_low = (cmd->cmd_slot << 16) + desc_type; 9760 cmd->cmd_rfm = NULL; 9761 MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high); 9762 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || 9763 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { 9764 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 9765 } 9766 } 9767 9768 9769 9770 static int 9771 mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply, 9772 uint8_t *data, uint32_t request_size, uint32_t reply_size, 9773 uint32_t data_size, uint32_t direction, uint8_t *dataout, 9774 uint32_t dataout_size, short timeout, int mode) 9775 { 9776 mptsas_pt_request_t pt; 9777 mptsas_dma_alloc_state_t data_dma_state; 9778 mptsas_dma_alloc_state_t dataout_dma_state; 9779 caddr_t memp; 9780 mptsas_cmd_t *cmd = NULL; 9781 struct scsi_pkt *pkt; 9782 uint32_t reply_len = 0, sense_len = 0; 9783 pMPI2RequestHeader_t request_hdrp; 9784 pMPI2RequestHeader_t request_msg; 9785 pMPI2DefaultReply_t reply_msg; 9786 Mpi2SCSIIOReply_t rep_msg; 9787 int i, status = 0, pt_flags = 0, rv = 0; 9788 int rvalue; 9789 uint8_t function; 9790 9791 ASSERT(mutex_owned(&mpt->m_mutex)); 9792 9793 reply_msg = (pMPI2DefaultReply_t)(&rep_msg); 9794 bzero(reply_msg, sizeof (MPI2_DEFAULT_REPLY)); 9795 request_msg = kmem_zalloc(request_size, KM_SLEEP); 9796 9797 mutex_exit(&mpt->m_mutex); 9798 /* 9799 * copy in the request buffer since it could be used by 9800 * another thread when the pt request into waitq 9801 */ 9802 if (ddi_copyin(request, request_msg, request_size, mode)) { 9803 mutex_enter(&mpt->m_mutex); 9804 status = EFAULT; 9805 mptsas_log(mpt, CE_WARN, "failed to copy request data"); 9806 goto out; 9807 } 9808 mutex_enter(&mpt->m_mutex); 9809 9810 function = request_msg->Function; 9811 if (function == MPI2_FUNCTION_SCSI_TASK_MGMT) { 9812 pMpi2SCSITaskManagementRequest_t task; 9813 task = (pMpi2SCSITaskManagementRequest_t)request_msg; 9814 mptsas_setup_bus_reset_delay(mpt); 9815 rv = mptsas_ioc_task_management(mpt, task->TaskType, 9816 task->DevHandle, (int)task->LUN[1], reply, reply_size, 9817 mode); 9818 9819 if (rv != TRUE) { 9820 status = EIO; 9821 mptsas_log(mpt, CE_WARN, "task management failed"); 9822 } 9823 goto out; 9824 } 9825 9826 if (data_size != 0) { 9827 data_dma_state.size = data_size; 9828 if (mptsas_dma_alloc(mpt, &data_dma_state) != DDI_SUCCESS) { 9829 status = ENOMEM; 9830 mptsas_log(mpt, CE_WARN, "failed to alloc DMA " 9831 "resource"); 9832 goto out; 9833 } 9834 pt_flags |= MPTSAS_DATA_ALLOCATED; 9835 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) { 9836 mutex_exit(&mpt->m_mutex); 9837 for (i = 0; i < data_size; i++) { 9838 if (ddi_copyin(data + i, (uint8_t *) 9839 data_dma_state.memp + i, 1, mode)) { 9840 mutex_enter(&mpt->m_mutex); 9841 status = EFAULT; 9842 mptsas_log(mpt, CE_WARN, "failed to " 9843 "copy read data"); 9844 goto out; 9845 } 9846 } 9847 mutex_enter(&mpt->m_mutex); 9848 } 9849 } 9850 9851 if (dataout_size != 0) { 9852 dataout_dma_state.size = dataout_size; 9853 if (mptsas_dma_alloc(mpt, &dataout_dma_state) != DDI_SUCCESS) { 9854 status = ENOMEM; 9855 mptsas_log(mpt, CE_WARN, "failed to alloc DMA " 9856 "resource"); 9857 goto out; 9858 } 9859 pt_flags |= MPTSAS_DATAOUT_ALLOCATED; 9860 mutex_exit(&mpt->m_mutex); 9861 for (i = 0; i < dataout_size; i++) { 9862 if (ddi_copyin(dataout + i, (uint8_t *) 9863 dataout_dma_state.memp + i, 1, mode)) { 9864 mutex_enter(&mpt->m_mutex); 9865 mptsas_log(mpt, CE_WARN, "failed to copy out" 9866 " data"); 9867 status = EFAULT; 9868 goto out; 9869 } 9870 } 9871 mutex_enter(&mpt->m_mutex); 9872 } 9873 9874 if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 9875 status = EAGAIN; 9876 mptsas_log(mpt, CE_NOTE, "event ack command pool is full"); 9877 goto out; 9878 } 9879 pt_flags |= MPTSAS_REQUEST_POOL_CMD; 9880 9881 bzero((caddr_t)cmd, sizeof (*cmd)); 9882 bzero((caddr_t)pkt, scsi_pkt_size()); 9883 bzero((caddr_t)&pt, sizeof (pt)); 9884 9885 cmd->ioc_cmd_slot = (uint32_t)(rvalue); 9886 9887 pt.request = (uint8_t *)request_msg; 9888 pt.direction = direction; 9889 pt.request_size = request_size; 9890 pt.data_size = data_size; 9891 pt.dataout_size = dataout_size; 9892 pt.data_cookie = data_dma_state.cookie; 9893 pt.dataout_cookie = dataout_dma_state.cookie; 9894 9895 /* 9896 * Form a blank cmd/pkt to store the acknowledgement message 9897 */ 9898 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb[0]; 9899 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; 9900 pkt->pkt_ha_private = (opaque_t)&pt; 9901 pkt->pkt_flags = FLAG_HEAD; 9902 pkt->pkt_time = timeout; 9903 cmd->cmd_pkt = pkt; 9904 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_PASSTHRU; 9905 9906 /* 9907 * Save the command in a slot 9908 */ 9909 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 9910 /* 9911 * Once passthru command get slot, set cmd_flags 9912 * CFLAG_PREPARED. 9913 */ 9914 cmd->cmd_flags |= CFLAG_PREPARED; 9915 mptsas_start_passthru(mpt, cmd); 9916 } else { 9917 mptsas_waitq_add(mpt, cmd); 9918 } 9919 9920 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 9921 cv_wait(&mpt->m_passthru_cv, &mpt->m_mutex); 9922 } 9923 9924 if (cmd->cmd_flags & CFLAG_PREPARED) { 9925 memp = mpt->m_req_frame + (mpt->m_req_frame_size * 9926 cmd->cmd_slot); 9927 request_hdrp = (pMPI2RequestHeader_t)memp; 9928 } 9929 9930 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 9931 status = ETIMEDOUT; 9932 mptsas_log(mpt, CE_WARN, "passthrough command timeout"); 9933 pt_flags |= MPTSAS_CMD_TIMEOUT; 9934 goto out; 9935 } 9936 9937 if (cmd->cmd_rfm) { 9938 /* 9939 * cmd_rfm is zero means the command reply is a CONTEXT 9940 * reply and no PCI Write to post the free reply SMFA 9941 * because no reply message frame is used. 9942 * cmd_rfm is non-zero means the reply is a ADDRESS 9943 * reply and reply message frame is used. 9944 */ 9945 pt_flags |= MPTSAS_ADDRESS_REPLY; 9946 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 9947 DDI_DMA_SYNC_FORCPU); 9948 reply_msg = (pMPI2DefaultReply_t) 9949 (mpt->m_reply_frame + (cmd->cmd_rfm - 9950 mpt->m_reply_frame_dma_addr)); 9951 } 9952 9953 mptsas_fma_check(mpt, cmd); 9954 if (pkt->pkt_reason == CMD_TRAN_ERR) { 9955 status = EAGAIN; 9956 mptsas_log(mpt, CE_WARN, "passthru fma error"); 9957 goto out; 9958 } 9959 if (pkt->pkt_reason == CMD_RESET) { 9960 status = EAGAIN; 9961 mptsas_log(mpt, CE_WARN, "ioc reset abort passthru"); 9962 goto out; 9963 } 9964 9965 if (pkt->pkt_reason == CMD_INCOMPLETE) { 9966 status = EIO; 9967 mptsas_log(mpt, CE_WARN, "passthrough command incomplete"); 9968 goto out; 9969 } 9970 9971 mutex_exit(&mpt->m_mutex); 9972 if (cmd->cmd_flags & CFLAG_PREPARED) { 9973 function = request_hdrp->Function; 9974 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) || 9975 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 9976 reply_len = sizeof (MPI2_SCSI_IO_REPLY); 9977 sense_len = reply_size - reply_len; 9978 } else { 9979 reply_len = reply_size; 9980 sense_len = 0; 9981 } 9982 9983 for (i = 0; i < reply_len; i++) { 9984 if (ddi_copyout((uint8_t *)reply_msg + i, reply + i, 1, 9985 mode)) { 9986 mutex_enter(&mpt->m_mutex); 9987 status = EFAULT; 9988 mptsas_log(mpt, CE_WARN, "failed to copy out " 9989 "reply data"); 9990 goto out; 9991 } 9992 } 9993 for (i = 0; i < sense_len; i++) { 9994 if (ddi_copyout((uint8_t *)request_hdrp + 64 + i, 9995 reply + reply_len + i, 1, mode)) { 9996 mutex_enter(&mpt->m_mutex); 9997 status = EFAULT; 9998 mptsas_log(mpt, CE_WARN, "failed to copy out " 9999 "sense data"); 10000 goto out; 10001 } 10002 } 10003 } 10004 10005 if (data_size) { 10006 if (direction != MPTSAS_PASS_THRU_DIRECTION_WRITE) { 10007 (void) ddi_dma_sync(data_dma_state.handle, 0, 0, 10008 DDI_DMA_SYNC_FORCPU); 10009 for (i = 0; i < data_size; i++) { 10010 if (ddi_copyout((uint8_t *)( 10011 data_dma_state.memp + i), data + i, 1, 10012 mode)) { 10013 mutex_enter(&mpt->m_mutex); 10014 status = EFAULT; 10015 mptsas_log(mpt, CE_WARN, "failed to " 10016 "copy out the reply data"); 10017 goto out; 10018 } 10019 } 10020 } 10021 } 10022 mutex_enter(&mpt->m_mutex); 10023 out: 10024 /* 10025 * Put the reply frame back on the free queue, increment the free 10026 * index, and write the new index to the free index register. But only 10027 * if this reply is an ADDRESS reply. 10028 */ 10029 if (pt_flags & MPTSAS_ADDRESS_REPLY) { 10030 ddi_put32(mpt->m_acc_free_queue_hdl, 10031 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 10032 cmd->cmd_rfm); 10033 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 10034 DDI_DMA_SYNC_FORDEV); 10035 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 10036 mpt->m_free_index = 0; 10037 } 10038 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 10039 mpt->m_free_index); 10040 } 10041 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 10042 mptsas_remove_cmd(mpt, cmd); 10043 pt_flags &= (~MPTSAS_REQUEST_POOL_CMD); 10044 } 10045 if (pt_flags & MPTSAS_REQUEST_POOL_CMD) 10046 mptsas_return_to_pool(mpt, cmd); 10047 if (pt_flags & MPTSAS_DATA_ALLOCATED) { 10048 if (mptsas_check_dma_handle(data_dma_state.handle) != 10049 DDI_SUCCESS) { 10050 ddi_fm_service_impact(mpt->m_dip, 10051 DDI_SERVICE_UNAFFECTED); 10052 status = EFAULT; 10053 } 10054 mptsas_dma_free(&data_dma_state); 10055 } 10056 if (pt_flags & MPTSAS_DATAOUT_ALLOCATED) { 10057 if (mptsas_check_dma_handle(dataout_dma_state.handle) != 10058 DDI_SUCCESS) { 10059 ddi_fm_service_impact(mpt->m_dip, 10060 DDI_SERVICE_UNAFFECTED); 10061 status = EFAULT; 10062 } 10063 mptsas_dma_free(&dataout_dma_state); 10064 } 10065 if (pt_flags & MPTSAS_CMD_TIMEOUT) { 10066 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 10067 mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed"); 10068 } 10069 } 10070 if (request_msg) 10071 kmem_free(request_msg, request_size); 10072 10073 return (status); 10074 } 10075 10076 static int 10077 mptsas_pass_thru(mptsas_t *mpt, mptsas_pass_thru_t *data, int mode) 10078 { 10079 /* 10080 * If timeout is 0, set timeout to default of 60 seconds. 10081 */ 10082 if (data->Timeout == 0) { 10083 data->Timeout = MPTSAS_PASS_THRU_TIME_DEFAULT; 10084 } 10085 10086 if (((data->DataSize == 0) && 10087 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_NONE)) || 10088 ((data->DataSize != 0) && 10089 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_READ) || 10090 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_WRITE) || 10091 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) && 10092 (data->DataOutSize != 0))))) { 10093 if (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) { 10094 data->DataDirection = MPTSAS_PASS_THRU_DIRECTION_READ; 10095 } else { 10096 data->DataOutSize = 0; 10097 } 10098 /* 10099 * Send passthru request messages 10100 */ 10101 return (mptsas_do_passthru(mpt, 10102 (uint8_t *)((uintptr_t)data->PtrRequest), 10103 (uint8_t *)((uintptr_t)data->PtrReply), 10104 (uint8_t *)((uintptr_t)data->PtrData), 10105 data->RequestSize, data->ReplySize, 10106 data->DataSize, data->DataDirection, 10107 (uint8_t *)((uintptr_t)data->PtrDataOut), 10108 data->DataOutSize, data->Timeout, mode)); 10109 } else { 10110 return (EINVAL); 10111 } 10112 } 10113 10114 static uint8_t 10115 mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, uint32_t unique_id) 10116 { 10117 uint8_t index; 10118 10119 for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) { 10120 if (mpt->m_fw_diag_buffer_list[index].unique_id == unique_id) { 10121 return (index); 10122 } 10123 } 10124 10125 return (MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND); 10126 } 10127 10128 static void 10129 mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd) 10130 { 10131 pMpi2DiagBufferPostRequest_t pDiag_post_msg; 10132 pMpi2DiagReleaseRequest_t pDiag_release_msg; 10133 struct scsi_pkt *pkt = cmd->cmd_pkt; 10134 mptsas_diag_request_t *diag = pkt->pkt_ha_private; 10135 uint32_t request_desc_low, i; 10136 10137 ASSERT(mutex_owned(&mpt->m_mutex)); 10138 10139 /* 10140 * Form the diag message depending on the post or release function. 10141 */ 10142 if (diag->function == MPI2_FUNCTION_DIAG_BUFFER_POST) { 10143 pDiag_post_msg = (pMpi2DiagBufferPostRequest_t) 10144 (mpt->m_req_frame + (mpt->m_req_frame_size * 10145 cmd->cmd_slot)); 10146 bzero(pDiag_post_msg, mpt->m_req_frame_size); 10147 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->Function, 10148 diag->function); 10149 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->BufferType, 10150 diag->pBuffer->buffer_type); 10151 ddi_put8(mpt->m_acc_req_frame_hdl, 10152 &pDiag_post_msg->ExtendedType, 10153 diag->pBuffer->extended_type); 10154 ddi_put32(mpt->m_acc_req_frame_hdl, 10155 &pDiag_post_msg->BufferLength, 10156 diag->pBuffer->buffer_data.size); 10157 for (i = 0; i < (sizeof (pDiag_post_msg->ProductSpecific) / 4); 10158 i++) { 10159 ddi_put32(mpt->m_acc_req_frame_hdl, 10160 &pDiag_post_msg->ProductSpecific[i], 10161 diag->pBuffer->product_specific[i]); 10162 } 10163 ddi_put32(mpt->m_acc_req_frame_hdl, 10164 &pDiag_post_msg->BufferAddress.Low, 10165 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress 10166 & 0xffffffffull)); 10167 ddi_put32(mpt->m_acc_req_frame_hdl, 10168 &pDiag_post_msg->BufferAddress.High, 10169 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress 10170 >> 32)); 10171 } else { 10172 pDiag_release_msg = (pMpi2DiagReleaseRequest_t) 10173 (mpt->m_req_frame + (mpt->m_req_frame_size * 10174 cmd->cmd_slot)); 10175 bzero(pDiag_release_msg, mpt->m_req_frame_size); 10176 ddi_put8(mpt->m_acc_req_frame_hdl, 10177 &pDiag_release_msg->Function, diag->function); 10178 ddi_put8(mpt->m_acc_req_frame_hdl, 10179 &pDiag_release_msg->BufferType, 10180 diag->pBuffer->buffer_type); 10181 } 10182 10183 /* 10184 * Send the message 10185 */ 10186 (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0, 10187 DDI_DMA_SYNC_FORDEV); 10188 request_desc_low = (cmd->cmd_slot << 16) + 10189 MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 10190 cmd->cmd_rfm = NULL; 10191 MPTSAS_START_CMD(mpt, request_desc_low, 0); 10192 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 10193 DDI_SUCCESS) || 10194 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 10195 DDI_SUCCESS)) { 10196 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 10197 } 10198 } 10199 10200 static int 10201 mptsas_post_fw_diag_buffer(mptsas_t *mpt, 10202 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code) 10203 { 10204 mptsas_diag_request_t diag; 10205 int status, slot_num, post_flags = 0; 10206 mptsas_cmd_t *cmd = NULL; 10207 struct scsi_pkt *pkt; 10208 pMpi2DiagBufferPostReply_t reply; 10209 uint16_t iocstatus; 10210 uint32_t iocloginfo, transfer_length; 10211 10212 /* 10213 * If buffer is not enabled, just leave. 10214 */ 10215 *return_code = MPTSAS_FW_DIAG_ERROR_POST_FAILED; 10216 if (!pBuffer->enabled) { 10217 status = DDI_FAILURE; 10218 goto out; 10219 } 10220 10221 /* 10222 * Clear some flags initially. 10223 */ 10224 pBuffer->force_release = FALSE; 10225 pBuffer->valid_data = FALSE; 10226 pBuffer->owned_by_firmware = FALSE; 10227 10228 /* 10229 * Get a cmd buffer from the cmd buffer pool 10230 */ 10231 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 10232 status = DDI_FAILURE; 10233 mptsas_log(mpt, CE_NOTE, "command pool is full: Post FW Diag"); 10234 goto out; 10235 } 10236 post_flags |= MPTSAS_REQUEST_POOL_CMD; 10237 10238 bzero((caddr_t)cmd, sizeof (*cmd)); 10239 bzero((caddr_t)pkt, scsi_pkt_size()); 10240 10241 cmd->ioc_cmd_slot = (uint32_t)(slot_num); 10242 10243 diag.pBuffer = pBuffer; 10244 diag.function = MPI2_FUNCTION_DIAG_BUFFER_POST; 10245 10246 /* 10247 * Form a blank cmd/pkt to store the acknowledgement message 10248 */ 10249 pkt->pkt_ha_private = (opaque_t)&diag; 10250 pkt->pkt_flags = FLAG_HEAD; 10251 pkt->pkt_time = 60; 10252 cmd->cmd_pkt = pkt; 10253 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG; 10254 10255 /* 10256 * Save the command in a slot 10257 */ 10258 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 10259 /* 10260 * Once passthru command get slot, set cmd_flags 10261 * CFLAG_PREPARED. 10262 */ 10263 cmd->cmd_flags |= CFLAG_PREPARED; 10264 mptsas_start_diag(mpt, cmd); 10265 } else { 10266 mptsas_waitq_add(mpt, cmd); 10267 } 10268 10269 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 10270 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex); 10271 } 10272 10273 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 10274 status = DDI_FAILURE; 10275 mptsas_log(mpt, CE_WARN, "Post FW Diag command timeout"); 10276 goto out; 10277 } 10278 10279 /* 10280 * cmd_rfm points to the reply message if a reply was given. Check the 10281 * IOCStatus to make sure everything went OK with the FW diag request 10282 * and set buffer flags. 10283 */ 10284 if (cmd->cmd_rfm) { 10285 post_flags |= MPTSAS_ADDRESS_REPLY; 10286 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 10287 DDI_DMA_SYNC_FORCPU); 10288 reply = (pMpi2DiagBufferPostReply_t)(mpt->m_reply_frame + 10289 (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr)); 10290 10291 /* 10292 * Get the reply message data 10293 */ 10294 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 10295 &reply->IOCStatus); 10296 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 10297 &reply->IOCLogInfo); 10298 transfer_length = ddi_get32(mpt->m_acc_reply_frame_hdl, 10299 &reply->TransferLength); 10300 10301 /* 10302 * If post failed quit. 10303 */ 10304 if (iocstatus != MPI2_IOCSTATUS_SUCCESS) { 10305 status = DDI_FAILURE; 10306 NDBG13(("post FW Diag Buffer failed: IOCStatus=0x%x, " 10307 "IOCLogInfo=0x%x, TransferLength=0x%x", iocstatus, 10308 iocloginfo, transfer_length)); 10309 goto out; 10310 } 10311 10312 /* 10313 * Post was successful. 10314 */ 10315 pBuffer->valid_data = TRUE; 10316 pBuffer->owned_by_firmware = TRUE; 10317 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 10318 status = DDI_SUCCESS; 10319 } 10320 10321 out: 10322 /* 10323 * Put the reply frame back on the free queue, increment the free 10324 * index, and write the new index to the free index register. But only 10325 * if this reply is an ADDRESS reply. 10326 */ 10327 if (post_flags & MPTSAS_ADDRESS_REPLY) { 10328 ddi_put32(mpt->m_acc_free_queue_hdl, 10329 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 10330 cmd->cmd_rfm); 10331 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 10332 DDI_DMA_SYNC_FORDEV); 10333 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 10334 mpt->m_free_index = 0; 10335 } 10336 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 10337 mpt->m_free_index); 10338 } 10339 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 10340 mptsas_remove_cmd(mpt, cmd); 10341 post_flags &= (~MPTSAS_REQUEST_POOL_CMD); 10342 } 10343 if (post_flags & MPTSAS_REQUEST_POOL_CMD) { 10344 mptsas_return_to_pool(mpt, cmd); 10345 } 10346 10347 return (status); 10348 } 10349 10350 static int 10351 mptsas_release_fw_diag_buffer(mptsas_t *mpt, 10352 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code, 10353 uint32_t diag_type) 10354 { 10355 mptsas_diag_request_t diag; 10356 int status, slot_num, rel_flags = 0; 10357 mptsas_cmd_t *cmd = NULL; 10358 struct scsi_pkt *pkt; 10359 pMpi2DiagReleaseReply_t reply; 10360 uint16_t iocstatus; 10361 uint32_t iocloginfo; 10362 10363 /* 10364 * If buffer is not enabled, just leave. 10365 */ 10366 *return_code = MPTSAS_FW_DIAG_ERROR_RELEASE_FAILED; 10367 if (!pBuffer->enabled) { 10368 mptsas_log(mpt, CE_NOTE, "This buffer type is not supported " 10369 "by the IOC"); 10370 status = DDI_FAILURE; 10371 goto out; 10372 } 10373 10374 /* 10375 * Clear some flags initially. 10376 */ 10377 pBuffer->force_release = FALSE; 10378 pBuffer->valid_data = FALSE; 10379 pBuffer->owned_by_firmware = FALSE; 10380 10381 /* 10382 * Get a cmd buffer from the cmd buffer pool 10383 */ 10384 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 10385 status = DDI_FAILURE; 10386 mptsas_log(mpt, CE_NOTE, "command pool is full: Release FW " 10387 "Diag"); 10388 goto out; 10389 } 10390 rel_flags |= MPTSAS_REQUEST_POOL_CMD; 10391 10392 bzero((caddr_t)cmd, sizeof (*cmd)); 10393 bzero((caddr_t)pkt, scsi_pkt_size()); 10394 10395 cmd->ioc_cmd_slot = (uint32_t)(slot_num); 10396 10397 diag.pBuffer = pBuffer; 10398 diag.function = MPI2_FUNCTION_DIAG_RELEASE; 10399 10400 /* 10401 * Form a blank cmd/pkt to store the acknowledgement message 10402 */ 10403 pkt->pkt_ha_private = (opaque_t)&diag; 10404 pkt->pkt_flags = FLAG_HEAD; 10405 pkt->pkt_time = 60; 10406 cmd->cmd_pkt = pkt; 10407 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG; 10408 10409 /* 10410 * Save the command in a slot 10411 */ 10412 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 10413 /* 10414 * Once passthru command get slot, set cmd_flags 10415 * CFLAG_PREPARED. 10416 */ 10417 cmd->cmd_flags |= CFLAG_PREPARED; 10418 mptsas_start_diag(mpt, cmd); 10419 } else { 10420 mptsas_waitq_add(mpt, cmd); 10421 } 10422 10423 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 10424 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex); 10425 } 10426 10427 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 10428 status = DDI_FAILURE; 10429 mptsas_log(mpt, CE_WARN, "Release FW Diag command timeout"); 10430 goto out; 10431 } 10432 10433 /* 10434 * cmd_rfm points to the reply message if a reply was given. Check the 10435 * IOCStatus to make sure everything went OK with the FW diag request 10436 * and set buffer flags. 10437 */ 10438 if (cmd->cmd_rfm) { 10439 rel_flags |= MPTSAS_ADDRESS_REPLY; 10440 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 10441 DDI_DMA_SYNC_FORCPU); 10442 reply = (pMpi2DiagReleaseReply_t)(mpt->m_reply_frame + 10443 (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr)); 10444 10445 /* 10446 * Get the reply message data 10447 */ 10448 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 10449 &reply->IOCStatus); 10450 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 10451 &reply->IOCLogInfo); 10452 10453 /* 10454 * If release failed quit. 10455 */ 10456 if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) || 10457 pBuffer->owned_by_firmware) { 10458 status = DDI_FAILURE; 10459 NDBG13(("release FW Diag Buffer failed: " 10460 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus, 10461 iocloginfo)); 10462 goto out; 10463 } 10464 10465 /* 10466 * Release was successful. 10467 */ 10468 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 10469 status = DDI_SUCCESS; 10470 10471 /* 10472 * If this was for an UNREGISTER diag type command, clear the 10473 * unique ID. 10474 */ 10475 if (diag_type == MPTSAS_FW_DIAG_TYPE_UNREGISTER) { 10476 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID; 10477 } 10478 } 10479 10480 out: 10481 /* 10482 * Put the reply frame back on the free queue, increment the free 10483 * index, and write the new index to the free index register. But only 10484 * if this reply is an ADDRESS reply. 10485 */ 10486 if (rel_flags & MPTSAS_ADDRESS_REPLY) { 10487 ddi_put32(mpt->m_acc_free_queue_hdl, 10488 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 10489 cmd->cmd_rfm); 10490 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 10491 DDI_DMA_SYNC_FORDEV); 10492 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 10493 mpt->m_free_index = 0; 10494 } 10495 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 10496 mpt->m_free_index); 10497 } 10498 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 10499 mptsas_remove_cmd(mpt, cmd); 10500 rel_flags &= (~MPTSAS_REQUEST_POOL_CMD); 10501 } 10502 if (rel_flags & MPTSAS_REQUEST_POOL_CMD) { 10503 mptsas_return_to_pool(mpt, cmd); 10504 } 10505 10506 return (status); 10507 } 10508 10509 static int 10510 mptsas_diag_register(mptsas_t *mpt, mptsas_fw_diag_register_t *diag_register, 10511 uint32_t *return_code) 10512 { 10513 mptsas_fw_diagnostic_buffer_t *pBuffer; 10514 uint8_t extended_type, buffer_type, i; 10515 uint32_t buffer_size; 10516 uint32_t unique_id; 10517 int status; 10518 10519 ASSERT(mutex_owned(&mpt->m_mutex)); 10520 10521 extended_type = diag_register->ExtendedType; 10522 buffer_type = diag_register->BufferType; 10523 buffer_size = diag_register->RequestedBufferSize; 10524 unique_id = diag_register->UniqueId; 10525 10526 /* 10527 * Check for valid buffer type 10528 */ 10529 if (buffer_type >= MPI2_DIAG_BUF_TYPE_COUNT) { 10530 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10531 return (DDI_FAILURE); 10532 } 10533 10534 /* 10535 * Get the current buffer and look up the unique ID. The unique ID 10536 * should not be found. If it is, the ID is already in use. 10537 */ 10538 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 10539 pBuffer = &mpt->m_fw_diag_buffer_list[buffer_type]; 10540 if (i != MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 10541 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10542 return (DDI_FAILURE); 10543 } 10544 10545 /* 10546 * The buffer's unique ID should not be registered yet, and the given 10547 * unique ID cannot be 0. 10548 */ 10549 if ((pBuffer->unique_id != MPTSAS_FW_DIAG_INVALID_UID) || 10550 (unique_id == MPTSAS_FW_DIAG_INVALID_UID)) { 10551 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10552 return (DDI_FAILURE); 10553 } 10554 10555 /* 10556 * If this buffer is already posted as immediate, just change owner. 10557 */ 10558 if (pBuffer->immediate && pBuffer->owned_by_firmware && 10559 (pBuffer->unique_id == MPTSAS_FW_DIAG_INVALID_UID)) { 10560 pBuffer->immediate = FALSE; 10561 pBuffer->unique_id = unique_id; 10562 return (DDI_SUCCESS); 10563 } 10564 10565 /* 10566 * Post a new buffer after checking if it's enabled. The DMA buffer 10567 * that is allocated will be contiguous (sgl_len = 1). 10568 */ 10569 if (!pBuffer->enabled) { 10570 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER; 10571 return (DDI_FAILURE); 10572 } 10573 bzero(&pBuffer->buffer_data, sizeof (mptsas_dma_alloc_state_t)); 10574 pBuffer->buffer_data.size = buffer_size; 10575 if (mptsas_dma_alloc(mpt, &pBuffer->buffer_data) != DDI_SUCCESS) { 10576 mptsas_log(mpt, CE_WARN, "failed to alloc DMA resource for " 10577 "diag buffer: size = %d bytes", buffer_size); 10578 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER; 10579 return (DDI_FAILURE); 10580 } 10581 10582 /* 10583 * Copy the given info to the diag buffer and post the buffer. 10584 */ 10585 pBuffer->buffer_type = buffer_type; 10586 pBuffer->immediate = FALSE; 10587 if (buffer_type == MPI2_DIAG_BUF_TYPE_TRACE) { 10588 for (i = 0; i < (sizeof (pBuffer->product_specific) / 4); 10589 i++) { 10590 pBuffer->product_specific[i] = 10591 diag_register->ProductSpecific[i]; 10592 } 10593 } 10594 pBuffer->extended_type = extended_type; 10595 pBuffer->unique_id = unique_id; 10596 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, return_code); 10597 10598 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) != 10599 DDI_SUCCESS) { 10600 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed in " 10601 "mptsas_diag_register."); 10602 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 10603 status = DDI_FAILURE; 10604 } 10605 10606 /* 10607 * In case there was a failure, free the DMA buffer. 10608 */ 10609 if (status == DDI_FAILURE) { 10610 mptsas_dma_free(&pBuffer->buffer_data); 10611 } 10612 10613 return (status); 10614 } 10615 10616 static int 10617 mptsas_diag_unregister(mptsas_t *mpt, 10618 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code) 10619 { 10620 mptsas_fw_diagnostic_buffer_t *pBuffer; 10621 uint8_t i; 10622 uint32_t unique_id; 10623 int status; 10624 10625 ASSERT(mutex_owned(&mpt->m_mutex)); 10626 10627 unique_id = diag_unregister->UniqueId; 10628 10629 /* 10630 * Get the current buffer and look up the unique ID. The unique ID 10631 * should be there. 10632 */ 10633 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 10634 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 10635 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10636 return (DDI_FAILURE); 10637 } 10638 10639 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 10640 10641 /* 10642 * Try to release the buffer from FW before freeing it. If release 10643 * fails, don't free the DMA buffer in case FW tries to access it 10644 * later. If buffer is not owned by firmware, can't release it. 10645 */ 10646 if (!pBuffer->owned_by_firmware) { 10647 status = DDI_SUCCESS; 10648 } else { 10649 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, 10650 return_code, MPTSAS_FW_DIAG_TYPE_UNREGISTER); 10651 } 10652 10653 /* 10654 * At this point, return the current status no matter what happens with 10655 * the DMA buffer. 10656 */ 10657 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID; 10658 if (status == DDI_SUCCESS) { 10659 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) != 10660 DDI_SUCCESS) { 10661 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed " 10662 "in mptsas_diag_unregister."); 10663 ddi_fm_service_impact(mpt->m_dip, 10664 DDI_SERVICE_UNAFFECTED); 10665 } 10666 mptsas_dma_free(&pBuffer->buffer_data); 10667 } 10668 10669 return (status); 10670 } 10671 10672 static int 10673 mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query, 10674 uint32_t *return_code) 10675 { 10676 mptsas_fw_diagnostic_buffer_t *pBuffer; 10677 uint8_t i; 10678 uint32_t unique_id; 10679 10680 ASSERT(mutex_owned(&mpt->m_mutex)); 10681 10682 unique_id = diag_query->UniqueId; 10683 10684 /* 10685 * If ID is valid, query on ID. 10686 * If ID is invalid, query on buffer type. 10687 */ 10688 if (unique_id == MPTSAS_FW_DIAG_INVALID_UID) { 10689 i = diag_query->BufferType; 10690 if (i >= MPI2_DIAG_BUF_TYPE_COUNT) { 10691 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10692 return (DDI_FAILURE); 10693 } 10694 } else { 10695 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 10696 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 10697 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10698 return (DDI_FAILURE); 10699 } 10700 } 10701 10702 /* 10703 * Fill query structure with the diag buffer info. 10704 */ 10705 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 10706 diag_query->BufferType = pBuffer->buffer_type; 10707 diag_query->ExtendedType = pBuffer->extended_type; 10708 if (diag_query->BufferType == MPI2_DIAG_BUF_TYPE_TRACE) { 10709 for (i = 0; i < (sizeof (diag_query->ProductSpecific) / 4); 10710 i++) { 10711 diag_query->ProductSpecific[i] = 10712 pBuffer->product_specific[i]; 10713 } 10714 } 10715 diag_query->TotalBufferSize = pBuffer->buffer_data.size; 10716 diag_query->DriverAddedBufferSize = 0; 10717 diag_query->UniqueId = pBuffer->unique_id; 10718 diag_query->ApplicationFlags = 0; 10719 diag_query->DiagnosticFlags = 0; 10720 10721 /* 10722 * Set/Clear application flags 10723 */ 10724 if (pBuffer->immediate) { 10725 diag_query->ApplicationFlags &= ~MPTSAS_FW_DIAG_FLAG_APP_OWNED; 10726 } else { 10727 diag_query->ApplicationFlags |= MPTSAS_FW_DIAG_FLAG_APP_OWNED; 10728 } 10729 if (pBuffer->valid_data || pBuffer->owned_by_firmware) { 10730 diag_query->ApplicationFlags |= 10731 MPTSAS_FW_DIAG_FLAG_BUFFER_VALID; 10732 } else { 10733 diag_query->ApplicationFlags &= 10734 ~MPTSAS_FW_DIAG_FLAG_BUFFER_VALID; 10735 } 10736 if (pBuffer->owned_by_firmware) { 10737 diag_query->ApplicationFlags |= 10738 MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS; 10739 } else { 10740 diag_query->ApplicationFlags &= 10741 ~MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS; 10742 } 10743 10744 return (DDI_SUCCESS); 10745 } 10746 10747 static int 10748 mptsas_diag_read_buffer(mptsas_t *mpt, 10749 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf, 10750 uint32_t *return_code, int ioctl_mode) 10751 { 10752 mptsas_fw_diagnostic_buffer_t *pBuffer; 10753 uint8_t i, *pData; 10754 uint32_t unique_id, byte; 10755 int status; 10756 10757 ASSERT(mutex_owned(&mpt->m_mutex)); 10758 10759 unique_id = diag_read_buffer->UniqueId; 10760 10761 /* 10762 * Get the current buffer and look up the unique ID. The unique ID 10763 * should be there. 10764 */ 10765 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 10766 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 10767 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10768 return (DDI_FAILURE); 10769 } 10770 10771 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 10772 10773 /* 10774 * Make sure requested read is within limits 10775 */ 10776 if (diag_read_buffer->StartingOffset + diag_read_buffer->BytesToRead > 10777 pBuffer->buffer_data.size) { 10778 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10779 return (DDI_FAILURE); 10780 } 10781 10782 /* 10783 * Copy the requested data from DMA to the diag_read_buffer. The DMA 10784 * buffer that was allocated is one contiguous buffer. 10785 */ 10786 pData = (uint8_t *)(pBuffer->buffer_data.memp + 10787 diag_read_buffer->StartingOffset); 10788 (void) ddi_dma_sync(pBuffer->buffer_data.handle, 0, 0, 10789 DDI_DMA_SYNC_FORCPU); 10790 for (byte = 0; byte < diag_read_buffer->BytesToRead; byte++) { 10791 if (ddi_copyout(pData + byte, ioctl_buf + byte, 1, ioctl_mode) 10792 != 0) { 10793 return (DDI_FAILURE); 10794 } 10795 } 10796 diag_read_buffer->Status = 0; 10797 10798 /* 10799 * Set or clear the Force Release flag. 10800 */ 10801 if (pBuffer->force_release) { 10802 diag_read_buffer->Flags |= MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE; 10803 } else { 10804 diag_read_buffer->Flags &= ~MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE; 10805 } 10806 10807 /* 10808 * If buffer is to be reregistered, make sure it's not already owned by 10809 * firmware first. 10810 */ 10811 status = DDI_SUCCESS; 10812 if (!pBuffer->owned_by_firmware) { 10813 if (diag_read_buffer->Flags & MPTSAS_FW_DIAG_FLAG_REREGISTER) { 10814 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, 10815 return_code); 10816 } 10817 } 10818 10819 return (status); 10820 } 10821 10822 static int 10823 mptsas_diag_release(mptsas_t *mpt, mptsas_fw_diag_release_t *diag_release, 10824 uint32_t *return_code) 10825 { 10826 mptsas_fw_diagnostic_buffer_t *pBuffer; 10827 uint8_t i; 10828 uint32_t unique_id; 10829 int status; 10830 10831 ASSERT(mutex_owned(&mpt->m_mutex)); 10832 10833 unique_id = diag_release->UniqueId; 10834 10835 /* 10836 * Get the current buffer and look up the unique ID. The unique ID 10837 * should be there. 10838 */ 10839 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 10840 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 10841 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10842 return (DDI_FAILURE); 10843 } 10844 10845 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 10846 10847 /* 10848 * If buffer is not owned by firmware, it's already been released. 10849 */ 10850 if (!pBuffer->owned_by_firmware) { 10851 *return_code = MPTSAS_FW_DIAG_ERROR_ALREADY_RELEASED; 10852 return (DDI_FAILURE); 10853 } 10854 10855 /* 10856 * Release the buffer. 10857 */ 10858 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, return_code, 10859 MPTSAS_FW_DIAG_TYPE_RELEASE); 10860 return (status); 10861 } 10862 10863 static int 10864 mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, uint8_t *diag_action, 10865 uint32_t length, uint32_t *return_code, int ioctl_mode) 10866 { 10867 mptsas_fw_diag_register_t diag_register; 10868 mptsas_fw_diag_unregister_t diag_unregister; 10869 mptsas_fw_diag_query_t diag_query; 10870 mptsas_diag_read_buffer_t diag_read_buffer; 10871 mptsas_fw_diag_release_t diag_release; 10872 int status = DDI_SUCCESS; 10873 uint32_t original_return_code, read_buf_len; 10874 10875 ASSERT(mutex_owned(&mpt->m_mutex)); 10876 10877 original_return_code = *return_code; 10878 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 10879 10880 switch (action) { 10881 case MPTSAS_FW_DIAG_TYPE_REGISTER: 10882 if (!length) { 10883 *return_code = 10884 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10885 status = DDI_FAILURE; 10886 break; 10887 } 10888 if (ddi_copyin(diag_action, &diag_register, 10889 sizeof (diag_register), ioctl_mode) != 0) { 10890 return (DDI_FAILURE); 10891 } 10892 status = mptsas_diag_register(mpt, &diag_register, 10893 return_code); 10894 break; 10895 10896 case MPTSAS_FW_DIAG_TYPE_UNREGISTER: 10897 if (length < sizeof (diag_unregister)) { 10898 *return_code = 10899 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10900 status = DDI_FAILURE; 10901 break; 10902 } 10903 if (ddi_copyin(diag_action, &diag_unregister, 10904 sizeof (diag_unregister), ioctl_mode) != 0) { 10905 return (DDI_FAILURE); 10906 } 10907 status = mptsas_diag_unregister(mpt, &diag_unregister, 10908 return_code); 10909 break; 10910 10911 case MPTSAS_FW_DIAG_TYPE_QUERY: 10912 if (length < sizeof (diag_query)) { 10913 *return_code = 10914 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10915 status = DDI_FAILURE; 10916 break; 10917 } 10918 if (ddi_copyin(diag_action, &diag_query, 10919 sizeof (diag_query), ioctl_mode) != 0) { 10920 return (DDI_FAILURE); 10921 } 10922 status = mptsas_diag_query(mpt, &diag_query, 10923 return_code); 10924 if (status == DDI_SUCCESS) { 10925 if (ddi_copyout(&diag_query, diag_action, 10926 sizeof (diag_query), ioctl_mode) != 0) { 10927 return (DDI_FAILURE); 10928 } 10929 } 10930 break; 10931 10932 case MPTSAS_FW_DIAG_TYPE_READ_BUFFER: 10933 if (ddi_copyin(diag_action, &diag_read_buffer, 10934 sizeof (diag_read_buffer) - 4, ioctl_mode) != 0) { 10935 return (DDI_FAILURE); 10936 } 10937 read_buf_len = sizeof (diag_read_buffer) - 10938 sizeof (diag_read_buffer.DataBuffer) + 10939 diag_read_buffer.BytesToRead; 10940 if (length < read_buf_len) { 10941 *return_code = 10942 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10943 status = DDI_FAILURE; 10944 break; 10945 } 10946 status = mptsas_diag_read_buffer(mpt, 10947 &diag_read_buffer, diag_action + 10948 sizeof (diag_read_buffer) - 4, return_code, 10949 ioctl_mode); 10950 if (status == DDI_SUCCESS) { 10951 if (ddi_copyout(&diag_read_buffer, diag_action, 10952 sizeof (diag_read_buffer) - 4, ioctl_mode) 10953 != 0) { 10954 return (DDI_FAILURE); 10955 } 10956 } 10957 break; 10958 10959 case MPTSAS_FW_DIAG_TYPE_RELEASE: 10960 if (length < sizeof (diag_release)) { 10961 *return_code = 10962 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10963 status = DDI_FAILURE; 10964 break; 10965 } 10966 if (ddi_copyin(diag_action, &diag_release, 10967 sizeof (diag_release), ioctl_mode) != 0) { 10968 return (DDI_FAILURE); 10969 } 10970 status = mptsas_diag_release(mpt, &diag_release, 10971 return_code); 10972 break; 10973 10974 default: 10975 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10976 status = DDI_FAILURE; 10977 break; 10978 } 10979 10980 if ((status == DDI_FAILURE) && 10981 (original_return_code == MPTSAS_FW_DIAG_NEW) && 10982 (*return_code != MPTSAS_FW_DIAG_ERROR_SUCCESS)) { 10983 status = DDI_SUCCESS; 10984 } 10985 10986 return (status); 10987 } 10988 10989 static int 10990 mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *user_data, int mode) 10991 { 10992 int status; 10993 mptsas_diag_action_t driver_data; 10994 10995 ASSERT(mutex_owned(&mpt->m_mutex)); 10996 10997 /* 10998 * Copy the user data to a driver data buffer. 10999 */ 11000 if (ddi_copyin(user_data, &driver_data, sizeof (mptsas_diag_action_t), 11001 mode) == 0) { 11002 /* 11003 * Send diag action request if Action is valid 11004 */ 11005 if (driver_data.Action == MPTSAS_FW_DIAG_TYPE_REGISTER || 11006 driver_data.Action == MPTSAS_FW_DIAG_TYPE_UNREGISTER || 11007 driver_data.Action == MPTSAS_FW_DIAG_TYPE_QUERY || 11008 driver_data.Action == MPTSAS_FW_DIAG_TYPE_READ_BUFFER || 11009 driver_data.Action == MPTSAS_FW_DIAG_TYPE_RELEASE) { 11010 status = mptsas_do_diag_action(mpt, driver_data.Action, 11011 (void *)(uintptr_t)driver_data.PtrDiagAction, 11012 driver_data.Length, &driver_data.ReturnCode, 11013 mode); 11014 if (status == DDI_SUCCESS) { 11015 if (ddi_copyout(&driver_data.ReturnCode, 11016 &user_data->ReturnCode, 11017 sizeof (user_data->ReturnCode), mode) 11018 != 0) { 11019 status = EFAULT; 11020 } else { 11021 status = 0; 11022 } 11023 } else { 11024 status = EIO; 11025 } 11026 } else { 11027 status = EINVAL; 11028 } 11029 } else { 11030 status = EFAULT; 11031 } 11032 11033 return (status); 11034 } 11035 11036 /* 11037 * This routine handles the "event query" ioctl. 11038 */ 11039 static int 11040 mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, int mode, 11041 int *rval) 11042 { 11043 int status; 11044 mptsas_event_query_t driverdata; 11045 uint8_t i; 11046 11047 driverdata.Entries = MPTSAS_EVENT_QUEUE_SIZE; 11048 11049 mutex_enter(&mpt->m_mutex); 11050 for (i = 0; i < 4; i++) { 11051 driverdata.Types[i] = mpt->m_event_mask[i]; 11052 } 11053 mutex_exit(&mpt->m_mutex); 11054 11055 if (ddi_copyout(&driverdata, data, sizeof (driverdata), mode) != 0) { 11056 status = EFAULT; 11057 } else { 11058 *rval = MPTIOCTL_STATUS_GOOD; 11059 status = 0; 11060 } 11061 11062 return (status); 11063 } 11064 11065 /* 11066 * This routine handles the "event enable" ioctl. 11067 */ 11068 static int 11069 mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, int mode, 11070 int *rval) 11071 { 11072 int status; 11073 mptsas_event_enable_t driverdata; 11074 uint8_t i; 11075 11076 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) { 11077 mutex_enter(&mpt->m_mutex); 11078 for (i = 0; i < 4; i++) { 11079 mpt->m_event_mask[i] = driverdata.Types[i]; 11080 } 11081 mutex_exit(&mpt->m_mutex); 11082 11083 *rval = MPTIOCTL_STATUS_GOOD; 11084 status = 0; 11085 } else { 11086 status = EFAULT; 11087 } 11088 return (status); 11089 } 11090 11091 /* 11092 * This routine handles the "event report" ioctl. 11093 */ 11094 static int 11095 mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, int mode, 11096 int *rval) 11097 { 11098 int status; 11099 mptsas_event_report_t driverdata; 11100 11101 mutex_enter(&mpt->m_mutex); 11102 11103 if (ddi_copyin(&data->Size, &driverdata.Size, sizeof (driverdata.Size), 11104 mode) == 0) { 11105 if (driverdata.Size >= sizeof (mpt->m_events)) { 11106 if (ddi_copyout(mpt->m_events, data->Events, 11107 sizeof (mpt->m_events), mode) != 0) { 11108 status = EFAULT; 11109 } else { 11110 if (driverdata.Size > sizeof (mpt->m_events)) { 11111 driverdata.Size = 11112 sizeof (mpt->m_events); 11113 if (ddi_copyout(&driverdata.Size, 11114 &data->Size, 11115 sizeof (driverdata.Size), 11116 mode) != 0) { 11117 status = EFAULT; 11118 } else { 11119 *rval = MPTIOCTL_STATUS_GOOD; 11120 status = 0; 11121 } 11122 } else { 11123 *rval = MPTIOCTL_STATUS_GOOD; 11124 status = 0; 11125 } 11126 } 11127 } else { 11128 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT; 11129 status = 0; 11130 } 11131 } else { 11132 status = EFAULT; 11133 } 11134 11135 mutex_exit(&mpt->m_mutex); 11136 return (status); 11137 } 11138 11139 static void 11140 mptsas_lookup_pci_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data) 11141 { 11142 int *reg_data; 11143 uint_t reglen; 11144 11145 /* 11146 * Lookup the 'reg' property and extract the other data 11147 */ 11148 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip, 11149 DDI_PROP_DONTPASS, "reg", ®_data, ®len) == 11150 DDI_PROP_SUCCESS) { 11151 /* 11152 * Extract the PCI data from the 'reg' property first DWORD. 11153 * The entry looks like the following: 11154 * First DWORD: 11155 * Bits 0 - 7 8-bit Register number 11156 * Bits 8 - 10 3-bit Function number 11157 * Bits 11 - 15 5-bit Device number 11158 * Bits 16 - 23 8-bit Bus number 11159 * Bits 24 - 25 2-bit Address Space type identifier 11160 * 11161 */ 11162 adapter_data->PciInformation.u.bits.BusNumber = 11163 (reg_data[0] & 0x00FF0000) >> 16; 11164 adapter_data->PciInformation.u.bits.DeviceNumber = 11165 (reg_data[0] & 0x0000F800) >> 11; 11166 adapter_data->PciInformation.u.bits.FunctionNumber = 11167 (reg_data[0] & 0x00000700) >> 8; 11168 ddi_prop_free((void *)reg_data); 11169 } else { 11170 /* 11171 * If we can't determine the PCI data then we fill in FF's for 11172 * the data to indicate this. 11173 */ 11174 adapter_data->PCIDeviceHwId = 0xFFFFFFFF; 11175 adapter_data->MpiPortNumber = 0xFFFFFFFF; 11176 adapter_data->PciInformation.u.AsDWORD = 0xFFFFFFFF; 11177 } 11178 11179 /* 11180 * Saved in the mpt->m_fwversion 11181 */ 11182 adapter_data->MpiFirmwareVersion = mpt->m_fwversion; 11183 } 11184 11185 static void 11186 mptsas_read_adapter_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data) 11187 { 11188 char *driver_verstr = MPTSAS_MOD_STRING; 11189 11190 mptsas_lookup_pci_data(mpt, adapter_data); 11191 adapter_data->AdapterType = MPTIOCTL_ADAPTER_TYPE_SAS2; 11192 adapter_data->PCIDeviceHwId = (uint32_t)mpt->m_devid; 11193 adapter_data->PCIDeviceHwRev = (uint32_t)mpt->m_revid; 11194 adapter_data->SubSystemId = (uint32_t)mpt->m_ssid; 11195 adapter_data->SubsystemVendorId = (uint32_t)mpt->m_svid; 11196 (void) strcpy((char *)&adapter_data->DriverVersion[0], driver_verstr); 11197 adapter_data->BiosVersion = 0; 11198 (void) mptsas_get_bios_page3(mpt, &adapter_data->BiosVersion); 11199 } 11200 11201 static void 11202 mptsas_read_pci_info(mptsas_t *mpt, mptsas_pci_info_t *pci_info) 11203 { 11204 int *reg_data, i; 11205 uint_t reglen; 11206 11207 /* 11208 * Lookup the 'reg' property and extract the other data 11209 */ 11210 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip, 11211 DDI_PROP_DONTPASS, "reg", ®_data, ®len) == 11212 DDI_PROP_SUCCESS) { 11213 /* 11214 * Extract the PCI data from the 'reg' property first DWORD. 11215 * The entry looks like the following: 11216 * First DWORD: 11217 * Bits 8 - 10 3-bit Function number 11218 * Bits 11 - 15 5-bit Device number 11219 * Bits 16 - 23 8-bit Bus number 11220 */ 11221 pci_info->BusNumber = (reg_data[0] & 0x00FF0000) >> 16; 11222 pci_info->DeviceNumber = (reg_data[0] & 0x0000F800) >> 11; 11223 pci_info->FunctionNumber = (reg_data[0] & 0x00000700) >> 8; 11224 ddi_prop_free((void *)reg_data); 11225 } else { 11226 /* 11227 * If we can't determine the PCI info then we fill in FF's for 11228 * the data to indicate this. 11229 */ 11230 pci_info->BusNumber = 0xFFFFFFFF; 11231 pci_info->DeviceNumber = 0xFF; 11232 pci_info->FunctionNumber = 0xFF; 11233 } 11234 11235 /* 11236 * Now get the interrupt vector and the pci header. The vector can 11237 * only be 0 right now. The header is the first 256 bytes of config 11238 * space. 11239 */ 11240 pci_info->InterruptVector = 0; 11241 for (i = 0; i < sizeof (pci_info->PciHeader); i++) { 11242 pci_info->PciHeader[i] = pci_config_get8(mpt->m_config_handle, 11243 i); 11244 } 11245 } 11246 11247 static int 11248 mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, int mode) 11249 { 11250 int status = 0; 11251 mptsas_reg_access_t driverdata; 11252 11253 mutex_enter(&mpt->m_mutex); 11254 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) { 11255 switch (driverdata.Command) { 11256 /* 11257 * IO access is not supported. 11258 */ 11259 case REG_IO_READ: 11260 case REG_IO_WRITE: 11261 mptsas_log(mpt, CE_WARN, "IO access is not " 11262 "supported. Use memory access."); 11263 status = EINVAL; 11264 break; 11265 11266 case REG_MEM_READ: 11267 driverdata.RegData = ddi_get32(mpt->m_datap, 11268 (uint32_t *)(void *)mpt->m_reg + 11269 driverdata.RegOffset); 11270 if (ddi_copyout(&driverdata.RegData, 11271 &data->RegData, 11272 sizeof (driverdata.RegData), mode) != 0) { 11273 mptsas_log(mpt, CE_WARN, "Register " 11274 "Read Failed"); 11275 status = EFAULT; 11276 } 11277 break; 11278 11279 case REG_MEM_WRITE: 11280 ddi_put32(mpt->m_datap, 11281 (uint32_t *)(void *)mpt->m_reg + 11282 driverdata.RegOffset, 11283 driverdata.RegData); 11284 break; 11285 11286 default: 11287 status = EINVAL; 11288 break; 11289 } 11290 } else { 11291 status = EFAULT; 11292 } 11293 11294 mutex_exit(&mpt->m_mutex); 11295 return (status); 11296 } 11297 11298 static int 11299 led_control(mptsas_t *mpt, intptr_t data, int mode) 11300 { 11301 int ret = 0; 11302 mptsas_led_control_t lc; 11303 mptsas_target_t *ptgt; 11304 11305 if (ddi_copyin((void *)data, &lc, sizeof (lc), mode) != 0) { 11306 return (EFAULT); 11307 } 11308 11309 if ((lc.Command != MPTSAS_LEDCTL_FLAG_SET && 11310 lc.Command != MPTSAS_LEDCTL_FLAG_GET) || 11311 lc.Led < MPTSAS_LEDCTL_LED_MIN || 11312 lc.Led > MPTSAS_LEDCTL_LED_MAX || 11313 (lc.Command == MPTSAS_LEDCTL_FLAG_SET && lc.LedStatus != 0 && 11314 lc.LedStatus != 1)) { 11315 return (EINVAL); 11316 } 11317 11318 if ((lc.Command == MPTSAS_LEDCTL_FLAG_SET && (mode & FWRITE) == 0) || 11319 (lc.Command == MPTSAS_LEDCTL_FLAG_GET && (mode & FREAD) == 0)) 11320 return (EACCES); 11321 11322 /* Locate the target we're interrogating... */ 11323 mutex_enter(&mpt->m_mutex); 11324 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 11325 MPTSAS_HASH_FIRST); 11326 while (ptgt != NULL) { 11327 if (ptgt->m_enclosure == lc.Enclosure && 11328 ptgt->m_slot_num == lc.Slot) { 11329 break; 11330 } 11331 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 11332 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 11333 } 11334 if (ptgt == NULL) { 11335 /* We could not find a target for that enclosure/slot. */ 11336 mutex_exit(&mpt->m_mutex); 11337 return (ENOENT); 11338 } 11339 11340 if (lc.Command == MPTSAS_LEDCTL_FLAG_SET) { 11341 /* Update our internal LED state. */ 11342 ptgt->m_led_status &= ~(1 << (lc.Led - 1)); 11343 ptgt->m_led_status |= lc.LedStatus << (lc.Led - 1); 11344 11345 /* Flush it to the controller. */ 11346 ret = mptsas_flush_led_status(mpt, ptgt); 11347 mutex_exit(&mpt->m_mutex); 11348 return (ret); 11349 } 11350 11351 /* Return our internal LED state. */ 11352 lc.LedStatus = (ptgt->m_led_status >> (lc.Led - 1)) & 1; 11353 mutex_exit(&mpt->m_mutex); 11354 11355 if (ddi_copyout(&lc, (void *)data, sizeof (lc), mode) != 0) { 11356 return (EFAULT); 11357 } 11358 11359 return (0); 11360 } 11361 11362 static int 11363 get_disk_info(mptsas_t *mpt, intptr_t data, int mode) 11364 { 11365 uint16_t i = 0; 11366 uint16_t count = 0; 11367 int ret = 0; 11368 mptsas_target_t *ptgt; 11369 mptsas_disk_info_t *di; 11370 STRUCT_DECL(mptsas_get_disk_info, gdi); 11371 11372 if ((mode & FREAD) == 0) 11373 return (EACCES); 11374 11375 STRUCT_INIT(gdi, get_udatamodel()); 11376 11377 if (ddi_copyin((void *)data, STRUCT_BUF(gdi), STRUCT_SIZE(gdi), 11378 mode) != 0) { 11379 return (EFAULT); 11380 } 11381 11382 /* Find out how many targets there are. */ 11383 mutex_enter(&mpt->m_mutex); 11384 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 11385 MPTSAS_HASH_FIRST); 11386 while (ptgt != NULL) { 11387 count++; 11388 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 11389 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 11390 } 11391 mutex_exit(&mpt->m_mutex); 11392 11393 /* 11394 * If we haven't been asked to copy out information on each target, 11395 * then just return the count. 11396 */ 11397 STRUCT_FSET(gdi, DiskCount, count); 11398 if (STRUCT_FGETP(gdi, PtrDiskInfoArray) == NULL) 11399 goto copy_out; 11400 11401 /* 11402 * If we haven't been given a large enough buffer to copy out into, 11403 * let the caller know. 11404 */ 11405 if (STRUCT_FGET(gdi, DiskInfoArraySize) < 11406 count * sizeof (mptsas_disk_info_t)) { 11407 ret = ENOSPC; 11408 goto copy_out; 11409 } 11410 11411 di = kmem_zalloc(count * sizeof (mptsas_disk_info_t), KM_SLEEP); 11412 11413 mutex_enter(&mpt->m_mutex); 11414 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 11415 MPTSAS_HASH_FIRST); 11416 while (ptgt != NULL) { 11417 if (i >= count) { 11418 /* 11419 * The number of targets changed while we weren't 11420 * looking, so give up. 11421 */ 11422 mutex_exit(&mpt->m_mutex); 11423 kmem_free(di, count * sizeof (mptsas_disk_info_t)); 11424 return (EAGAIN); 11425 } 11426 di[i].Instance = mpt->m_instance; 11427 di[i].Enclosure = ptgt->m_enclosure; 11428 di[i].Slot = ptgt->m_slot_num; 11429 di[i].SasAddress = ptgt->m_sas_wwn; 11430 11431 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 11432 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 11433 i++; 11434 } 11435 mutex_exit(&mpt->m_mutex); 11436 STRUCT_FSET(gdi, DiskCount, i); 11437 11438 /* Copy out the disk information to the caller. */ 11439 if (ddi_copyout((void *)di, STRUCT_FGETP(gdi, PtrDiskInfoArray), 11440 i * sizeof (mptsas_disk_info_t), mode) != 0) { 11441 ret = EFAULT; 11442 } 11443 11444 kmem_free(di, count * sizeof (mptsas_disk_info_t)); 11445 11446 copy_out: 11447 if (ddi_copyout(STRUCT_BUF(gdi), (void *)data, STRUCT_SIZE(gdi), 11448 mode) != 0) { 11449 ret = EFAULT; 11450 } 11451 11452 return (ret); 11453 } 11454 11455 static int 11456 mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp, 11457 int *rval) 11458 { 11459 int status = 0; 11460 mptsas_t *mpt; 11461 mptsas_update_flash_t flashdata; 11462 mptsas_pass_thru_t passthru_data; 11463 mptsas_adapter_data_t adapter_data; 11464 mptsas_pci_info_t pci_info; 11465 int copylen; 11466 11467 int iport_flag = 0; 11468 dev_info_t *dip = NULL; 11469 mptsas_phymask_t phymask = 0; 11470 struct devctl_iocdata *dcp = NULL; 11471 char *addr = NULL; 11472 mptsas_target_t *ptgt = NULL; 11473 11474 *rval = MPTIOCTL_STATUS_GOOD; 11475 if (secpolicy_sys_config(credp, B_FALSE) != 0) { 11476 return (EPERM); 11477 } 11478 11479 mpt = ddi_get_soft_state(mptsas_state, MINOR2INST(getminor(dev))); 11480 if (mpt == NULL) { 11481 /* 11482 * Called from iport node, get the states 11483 */ 11484 iport_flag = 1; 11485 dip = mptsas_get_dip_from_dev(dev, &phymask); 11486 if (dip == NULL) { 11487 return (ENXIO); 11488 } 11489 mpt = DIP2MPT(dip); 11490 } 11491 /* Make sure power level is D0 before accessing registers */ 11492 mutex_enter(&mpt->m_mutex); 11493 if (mpt->m_options & MPTSAS_OPT_PM) { 11494 (void) pm_busy_component(mpt->m_dip, 0); 11495 if (mpt->m_power_level != PM_LEVEL_D0) { 11496 mutex_exit(&mpt->m_mutex); 11497 if (pm_raise_power(mpt->m_dip, 0, PM_LEVEL_D0) != 11498 DDI_SUCCESS) { 11499 mptsas_log(mpt, CE_WARN, 11500 "mptsas%d: mptsas_ioctl: Raise power " 11501 "request failed.", mpt->m_instance); 11502 (void) pm_idle_component(mpt->m_dip, 0); 11503 return (ENXIO); 11504 } 11505 } else { 11506 mutex_exit(&mpt->m_mutex); 11507 } 11508 } else { 11509 mutex_exit(&mpt->m_mutex); 11510 } 11511 11512 if (iport_flag) { 11513 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, rval); 11514 if (status != 0) { 11515 goto out; 11516 } 11517 /* 11518 * The following code control the OK2RM LED, it doesn't affect 11519 * the ioctl return status. 11520 */ 11521 if ((cmd == DEVCTL_DEVICE_ONLINE) || 11522 (cmd == DEVCTL_DEVICE_OFFLINE)) { 11523 if (ndi_dc_allochdl((void *)data, &dcp) != 11524 NDI_SUCCESS) { 11525 goto out; 11526 } 11527 addr = ndi_dc_getaddr(dcp); 11528 ptgt = mptsas_addr_to_ptgt(mpt, addr, phymask); 11529 if (ptgt == NULL) { 11530 NDBG14(("mptsas_ioctl led control: tgt %s not " 11531 "found", addr)); 11532 ndi_dc_freehdl(dcp); 11533 goto out; 11534 } 11535 mutex_enter(&mpt->m_mutex); 11536 if (cmd == DEVCTL_DEVICE_ONLINE) { 11537 ptgt->m_tgt_unconfigured = 0; 11538 } else if (cmd == DEVCTL_DEVICE_OFFLINE) { 11539 ptgt->m_tgt_unconfigured = 1; 11540 } 11541 if (cmd == DEVCTL_DEVICE_OFFLINE) { 11542 ptgt->m_led_status |= 11543 (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1)); 11544 } else { 11545 ptgt->m_led_status &= 11546 ~(1 << (MPTSAS_LEDCTL_LED_OK2RM - 1)); 11547 } 11548 (void) mptsas_flush_led_status(mpt, ptgt); 11549 mutex_exit(&mpt->m_mutex); 11550 ndi_dc_freehdl(dcp); 11551 } 11552 goto out; 11553 } 11554 switch (cmd) { 11555 case MPTIOCTL_GET_DISK_INFO: 11556 status = get_disk_info(mpt, data, mode); 11557 break; 11558 case MPTIOCTL_LED_CONTROL: 11559 status = led_control(mpt, data, mode); 11560 break; 11561 case MPTIOCTL_UPDATE_FLASH: 11562 if (ddi_copyin((void *)data, &flashdata, 11563 sizeof (struct mptsas_update_flash), mode)) { 11564 status = EFAULT; 11565 break; 11566 } 11567 11568 mutex_enter(&mpt->m_mutex); 11569 if (mptsas_update_flash(mpt, 11570 (caddr_t)(long)flashdata.PtrBuffer, 11571 flashdata.ImageSize, flashdata.ImageType, mode)) { 11572 status = EFAULT; 11573 } 11574 11575 /* 11576 * Reset the chip to start using the new 11577 * firmware. Reset if failed also. 11578 */ 11579 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 11580 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) { 11581 status = EFAULT; 11582 } 11583 mutex_exit(&mpt->m_mutex); 11584 break; 11585 case MPTIOCTL_PASS_THRU: 11586 /* 11587 * The user has requested to pass through a command to 11588 * be executed by the MPT firmware. Call our routine 11589 * which does this. Only allow one passthru IOCTL at 11590 * one time. Other threads will block on 11591 * m_passthru_mutex, which is of adaptive variant. 11592 */ 11593 if (ddi_copyin((void *)data, &passthru_data, 11594 sizeof (mptsas_pass_thru_t), mode)) { 11595 status = EFAULT; 11596 break; 11597 } 11598 mutex_enter(&mpt->m_passthru_mutex); 11599 mutex_enter(&mpt->m_mutex); 11600 status = mptsas_pass_thru(mpt, &passthru_data, mode); 11601 mutex_exit(&mpt->m_mutex); 11602 mutex_exit(&mpt->m_passthru_mutex); 11603 11604 break; 11605 case MPTIOCTL_GET_ADAPTER_DATA: 11606 /* 11607 * The user has requested to read adapter data. Call 11608 * our routine which does this. 11609 */ 11610 bzero(&adapter_data, sizeof (mptsas_adapter_data_t)); 11611 if (ddi_copyin((void *)data, (void *)&adapter_data, 11612 sizeof (mptsas_adapter_data_t), mode)) { 11613 status = EFAULT; 11614 break; 11615 } 11616 if (adapter_data.StructureLength >= 11617 sizeof (mptsas_adapter_data_t)) { 11618 adapter_data.StructureLength = (uint32_t) 11619 sizeof (mptsas_adapter_data_t); 11620 copylen = sizeof (mptsas_adapter_data_t); 11621 mutex_enter(&mpt->m_mutex); 11622 mptsas_read_adapter_data(mpt, &adapter_data); 11623 mutex_exit(&mpt->m_mutex); 11624 } else { 11625 adapter_data.StructureLength = (uint32_t) 11626 sizeof (mptsas_adapter_data_t); 11627 copylen = sizeof (adapter_data.StructureLength); 11628 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT; 11629 } 11630 if (ddi_copyout((void *)(&adapter_data), (void *)data, 11631 copylen, mode) != 0) { 11632 status = EFAULT; 11633 } 11634 break; 11635 case MPTIOCTL_GET_PCI_INFO: 11636 /* 11637 * The user has requested to read pci info. Call 11638 * our routine which does this. 11639 */ 11640 bzero(&pci_info, sizeof (mptsas_pci_info_t)); 11641 mutex_enter(&mpt->m_mutex); 11642 mptsas_read_pci_info(mpt, &pci_info); 11643 mutex_exit(&mpt->m_mutex); 11644 if (ddi_copyout((void *)(&pci_info), (void *)data, 11645 sizeof (mptsas_pci_info_t), mode) != 0) { 11646 status = EFAULT; 11647 } 11648 break; 11649 case MPTIOCTL_RESET_ADAPTER: 11650 mutex_enter(&mpt->m_mutex); 11651 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 11652 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 11653 mptsas_log(mpt, CE_WARN, "reset adapter IOCTL " 11654 "failed"); 11655 status = EFAULT; 11656 } 11657 mutex_exit(&mpt->m_mutex); 11658 break; 11659 case MPTIOCTL_DIAG_ACTION: 11660 /* 11661 * The user has done a diag buffer action. Call our 11662 * routine which does this. Only allow one diag action 11663 * at one time. 11664 */ 11665 mutex_enter(&mpt->m_mutex); 11666 if (mpt->m_diag_action_in_progress) { 11667 mutex_exit(&mpt->m_mutex); 11668 return (EBUSY); 11669 } 11670 mpt->m_diag_action_in_progress = 1; 11671 status = mptsas_diag_action(mpt, 11672 (mptsas_diag_action_t *)data, mode); 11673 mpt->m_diag_action_in_progress = 0; 11674 mutex_exit(&mpt->m_mutex); 11675 break; 11676 case MPTIOCTL_EVENT_QUERY: 11677 /* 11678 * The user has done an event query. Call our routine 11679 * which does this. 11680 */ 11681 status = mptsas_event_query(mpt, 11682 (mptsas_event_query_t *)data, mode, rval); 11683 break; 11684 case MPTIOCTL_EVENT_ENABLE: 11685 /* 11686 * The user has done an event enable. Call our routine 11687 * which does this. 11688 */ 11689 status = mptsas_event_enable(mpt, 11690 (mptsas_event_enable_t *)data, mode, rval); 11691 break; 11692 case MPTIOCTL_EVENT_REPORT: 11693 /* 11694 * The user has done an event report. Call our routine 11695 * which does this. 11696 */ 11697 status = mptsas_event_report(mpt, 11698 (mptsas_event_report_t *)data, mode, rval); 11699 break; 11700 case MPTIOCTL_REG_ACCESS: 11701 /* 11702 * The user has requested register access. Call our 11703 * routine which does this. 11704 */ 11705 status = mptsas_reg_access(mpt, 11706 (mptsas_reg_access_t *)data, mode); 11707 break; 11708 default: 11709 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, 11710 rval); 11711 break; 11712 } 11713 11714 out: 11715 return (status); 11716 } 11717 11718 int 11719 mptsas_restart_ioc(mptsas_t *mpt) 11720 { 11721 int rval = DDI_SUCCESS; 11722 mptsas_target_t *ptgt = NULL; 11723 11724 ASSERT(mutex_owned(&mpt->m_mutex)); 11725 11726 /* 11727 * Set a flag telling I/O path that we're processing a reset. This is 11728 * needed because after the reset is complete, the hash table still 11729 * needs to be rebuilt. If I/Os are started before the hash table is 11730 * rebuilt, I/O errors will occur. This flag allows I/Os to be marked 11731 * so that they can be retried. 11732 */ 11733 mpt->m_in_reset = TRUE; 11734 11735 /* 11736 * Set all throttles to HOLD 11737 */ 11738 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 11739 MPTSAS_HASH_FIRST); 11740 while (ptgt != NULL) { 11741 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 11742 11743 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 11744 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 11745 } 11746 11747 /* 11748 * Disable interrupts 11749 */ 11750 MPTSAS_DISABLE_INTR(mpt); 11751 11752 /* 11753 * Abort all commands: outstanding commands, commands in waitq and 11754 * tx_waitq. 11755 */ 11756 mptsas_flush_hba(mpt); 11757 11758 /* 11759 * Reinitialize the chip. 11760 */ 11761 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) { 11762 rval = DDI_FAILURE; 11763 } 11764 11765 /* 11766 * Enable interrupts again 11767 */ 11768 MPTSAS_ENABLE_INTR(mpt); 11769 11770 /* 11771 * If mptsas_init_chip was successful, update the driver data. 11772 */ 11773 if (rval == DDI_SUCCESS) { 11774 mptsas_update_driver_data(mpt); 11775 } 11776 11777 /* 11778 * Reset the throttles 11779 */ 11780 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 11781 MPTSAS_HASH_FIRST); 11782 while (ptgt != NULL) { 11783 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 11784 11785 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 11786 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 11787 } 11788 11789 mptsas_doneq_empty(mpt); 11790 mptsas_restart_hba(mpt); 11791 11792 if (rval != DDI_SUCCESS) { 11793 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 11794 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 11795 } 11796 11797 /* 11798 * Clear the reset flag so that I/Os can continue. 11799 */ 11800 mpt->m_in_reset = FALSE; 11801 11802 return (rval); 11803 } 11804 11805 static int 11806 mptsas_init_chip(mptsas_t *mpt, int first_time) 11807 { 11808 ddi_dma_cookie_t cookie; 11809 uint32_t i; 11810 int rval; 11811 11812 /* 11813 * Check to see if the firmware image is valid 11814 */ 11815 if (ddi_get32(mpt->m_datap, &mpt->m_reg->HostDiagnostic) & 11816 MPI2_DIAG_FLASH_BAD_SIG) { 11817 mptsas_log(mpt, CE_WARN, "mptsas bad flash signature!"); 11818 goto fail; 11819 } 11820 11821 /* 11822 * Reset the chip 11823 */ 11824 rval = mptsas_ioc_reset(mpt, first_time); 11825 if (rval == MPTSAS_RESET_FAIL) { 11826 mptsas_log(mpt, CE_WARN, "hard reset failed!"); 11827 goto fail; 11828 } 11829 11830 if ((rval == MPTSAS_SUCCESS_MUR) && (!first_time)) { 11831 goto mur; 11832 } 11833 /* 11834 * Setup configuration space 11835 */ 11836 if (mptsas_config_space_init(mpt) == FALSE) { 11837 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init " 11838 "failed!"); 11839 goto fail; 11840 } 11841 11842 /* 11843 * IOC facts can change after a diag reset so all buffers that are 11844 * based on these numbers must be de-allocated and re-allocated. Get 11845 * new IOC facts each time chip is initialized. 11846 */ 11847 if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) { 11848 mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed"); 11849 goto fail; 11850 } 11851 11852 if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) { 11853 goto fail; 11854 } 11855 /* 11856 * Allocate request message frames, reply free queue, reply descriptor 11857 * post queue, and reply message frames using latest IOC facts. 11858 */ 11859 if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) { 11860 mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed"); 11861 goto fail; 11862 } 11863 if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) { 11864 mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue failed!"); 11865 goto fail; 11866 } 11867 if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) { 11868 mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue failed!"); 11869 goto fail; 11870 } 11871 if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) { 11872 mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames failed!"); 11873 goto fail; 11874 } 11875 11876 mur: 11877 /* 11878 * Re-Initialize ioc to operational state 11879 */ 11880 if (mptsas_ioc_init(mpt) == DDI_FAILURE) { 11881 mptsas_log(mpt, CE_WARN, "mptsas_ioc_init failed"); 11882 goto fail; 11883 } 11884 11885 mptsas_alloc_reply_args(mpt); 11886 11887 /* 11888 * Initialize reply post index. Reply free index is initialized after 11889 * the next loop. 11890 */ 11891 mpt->m_post_index = 0; 11892 11893 /* 11894 * Initialize the Reply Free Queue with the physical addresses of our 11895 * reply frames. 11896 */ 11897 cookie.dmac_address = mpt->m_reply_frame_dma_addr; 11898 for (i = 0; i < mpt->m_max_replies; i++) { 11899 ddi_put32(mpt->m_acc_free_queue_hdl, 11900 &((uint32_t *)(void *)mpt->m_free_queue)[i], 11901 cookie.dmac_address); 11902 cookie.dmac_address += mpt->m_reply_frame_size; 11903 } 11904 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 11905 DDI_DMA_SYNC_FORDEV); 11906 11907 /* 11908 * Initialize the reply free index to one past the last frame on the 11909 * queue. This will signify that the queue is empty to start with. 11910 */ 11911 mpt->m_free_index = i; 11912 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, i); 11913 11914 /* 11915 * Initialize the reply post queue to 0xFFFFFFFF,0xFFFFFFFF's. 11916 */ 11917 for (i = 0; i < mpt->m_post_queue_depth; i++) { 11918 ddi_put64(mpt->m_acc_post_queue_hdl, 11919 &((uint64_t *)(void *)mpt->m_post_queue)[i], 11920 0xFFFFFFFFFFFFFFFF); 11921 } 11922 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 11923 DDI_DMA_SYNC_FORDEV); 11924 11925 /* 11926 * Enable ports 11927 */ 11928 if (mptsas_ioc_enable_port(mpt) == DDI_FAILURE) { 11929 mptsas_log(mpt, CE_WARN, "mptsas_ioc_enable_port failed"); 11930 goto fail; 11931 } 11932 11933 /* 11934 * enable events 11935 */ 11936 if (mptsas_ioc_enable_event_notification(mpt)) { 11937 goto fail; 11938 } 11939 11940 /* 11941 * We need checks in attach and these. 11942 * chip_init is called in mult. places 11943 */ 11944 11945 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 11946 DDI_SUCCESS) || 11947 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) != 11948 DDI_SUCCESS) || 11949 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) != 11950 DDI_SUCCESS) || 11951 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) != 11952 DDI_SUCCESS) || 11953 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) != 11954 DDI_SUCCESS)) { 11955 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 11956 goto fail; 11957 } 11958 11959 /* Check all acc handles */ 11960 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) || 11961 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 11962 DDI_SUCCESS) || 11963 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) != 11964 DDI_SUCCESS) || 11965 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) != 11966 DDI_SUCCESS) || 11967 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) != 11968 DDI_SUCCESS) || 11969 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) != 11970 DDI_SUCCESS) || 11971 (mptsas_check_acc_handle(mpt->m_config_handle) != 11972 DDI_SUCCESS)) { 11973 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 11974 goto fail; 11975 } 11976 11977 return (DDI_SUCCESS); 11978 11979 fail: 11980 return (DDI_FAILURE); 11981 } 11982 11983 static int 11984 mptsas_get_pci_cap(mptsas_t *mpt) 11985 { 11986 ushort_t caps_ptr, cap, cap_count; 11987 11988 if (mpt->m_config_handle == NULL) 11989 return (FALSE); 11990 /* 11991 * Check if capabilities list is supported and if so, 11992 * get initial capabilities pointer and clear bits 0,1. 11993 */ 11994 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) 11995 & PCI_STAT_CAP) { 11996 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle, 11997 PCI_CONF_CAP_PTR), 4); 11998 } else { 11999 caps_ptr = PCI_CAP_NEXT_PTR_NULL; 12000 } 12001 12002 /* 12003 * Walk capabilities if supported. 12004 */ 12005 for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) { 12006 12007 /* 12008 * Check that we haven't exceeded the maximum number of 12009 * capabilities and that the pointer is in a valid range. 12010 */ 12011 if (++cap_count > 48) { 12012 mptsas_log(mpt, CE_WARN, 12013 "too many device capabilities.\n"); 12014 break; 12015 } 12016 if (caps_ptr < 64) { 12017 mptsas_log(mpt, CE_WARN, 12018 "capabilities pointer 0x%x out of range.\n", 12019 caps_ptr); 12020 break; 12021 } 12022 12023 /* 12024 * Get next capability and check that it is valid. 12025 * For now, we only support power management. 12026 */ 12027 cap = pci_config_get8(mpt->m_config_handle, caps_ptr); 12028 switch (cap) { 12029 case PCI_CAP_ID_PM: 12030 mptsas_log(mpt, CE_NOTE, 12031 "?mptsas%d supports power management.\n", 12032 mpt->m_instance); 12033 mpt->m_options |= MPTSAS_OPT_PM; 12034 12035 /* Save PMCSR offset */ 12036 mpt->m_pmcsr_offset = caps_ptr + PCI_PMCSR; 12037 break; 12038 /* 12039 * The following capabilities are valid. Any others 12040 * will cause a message to be logged. 12041 */ 12042 case PCI_CAP_ID_VPD: 12043 case PCI_CAP_ID_MSI: 12044 case PCI_CAP_ID_PCIX: 12045 case PCI_CAP_ID_PCI_E: 12046 case PCI_CAP_ID_MSI_X: 12047 break; 12048 default: 12049 mptsas_log(mpt, CE_NOTE, 12050 "?mptsas%d unrecognized capability " 12051 "0x%x.\n", mpt->m_instance, cap); 12052 break; 12053 } 12054 12055 /* 12056 * Get next capabilities pointer and clear bits 0,1. 12057 */ 12058 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle, 12059 (caps_ptr + PCI_CAP_NEXT_PTR)), 4); 12060 } 12061 return (TRUE); 12062 } 12063 12064 static int 12065 mptsas_init_pm(mptsas_t *mpt) 12066 { 12067 char pmc_name[16]; 12068 char *pmc[] = { 12069 NULL, 12070 "0=Off (PCI D3 State)", 12071 "3=On (PCI D0 State)", 12072 NULL 12073 }; 12074 uint16_t pmcsr_stat; 12075 12076 if (mptsas_get_pci_cap(mpt) == FALSE) { 12077 return (DDI_FAILURE); 12078 } 12079 /* 12080 * If PCI's capability does not support PM, then don't need 12081 * to registe the pm-components 12082 */ 12083 if (!(mpt->m_options & MPTSAS_OPT_PM)) 12084 return (DDI_SUCCESS); 12085 /* 12086 * If power management is supported by this chip, create 12087 * pm-components property for the power management framework 12088 */ 12089 (void) sprintf(pmc_name, "NAME=mptsas%d", mpt->m_instance); 12090 pmc[0] = pmc_name; 12091 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, mpt->m_dip, 12092 "pm-components", pmc, 3) != DDI_PROP_SUCCESS) { 12093 mpt->m_options &= ~MPTSAS_OPT_PM; 12094 mptsas_log(mpt, CE_WARN, 12095 "mptsas%d: pm-component property creation failed.", 12096 mpt->m_instance); 12097 return (DDI_FAILURE); 12098 } 12099 12100 /* 12101 * Power on device. 12102 */ 12103 (void) pm_busy_component(mpt->m_dip, 0); 12104 pmcsr_stat = pci_config_get16(mpt->m_config_handle, 12105 mpt->m_pmcsr_offset); 12106 if ((pmcsr_stat & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_D0) { 12107 mptsas_log(mpt, CE_WARN, "mptsas%d: Power up the device", 12108 mpt->m_instance); 12109 pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset, 12110 PCI_PMCSR_D0); 12111 } 12112 if (pm_power_has_changed(mpt->m_dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) { 12113 mptsas_log(mpt, CE_WARN, "pm_power_has_changed failed"); 12114 return (DDI_FAILURE); 12115 } 12116 mpt->m_power_level = PM_LEVEL_D0; 12117 /* 12118 * Set pm idle delay. 12119 */ 12120 mpt->m_pm_idle_delay = ddi_prop_get_int(DDI_DEV_T_ANY, 12121 mpt->m_dip, 0, "mptsas-pm-idle-delay", MPTSAS_PM_IDLE_TIMEOUT); 12122 12123 return (DDI_SUCCESS); 12124 } 12125 12126 static int 12127 mptsas_register_intrs(mptsas_t *mpt) 12128 { 12129 dev_info_t *dip; 12130 int intr_types; 12131 12132 dip = mpt->m_dip; 12133 12134 /* Get supported interrupt types */ 12135 if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) { 12136 mptsas_log(mpt, CE_WARN, "ddi_intr_get_supported_types " 12137 "failed\n"); 12138 return (FALSE); 12139 } 12140 12141 NDBG6(("ddi_intr_get_supported_types() returned: 0x%x", intr_types)); 12142 12143 /* 12144 * Try MSI, but fall back to FIXED 12145 */ 12146 if (mptsas_enable_msi && (intr_types & DDI_INTR_TYPE_MSI)) { 12147 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_MSI) == DDI_SUCCESS) { 12148 NDBG0(("Using MSI interrupt type")); 12149 mpt->m_intr_type = DDI_INTR_TYPE_MSI; 12150 return (TRUE); 12151 } 12152 } 12153 if (intr_types & DDI_INTR_TYPE_FIXED) { 12154 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_FIXED) == DDI_SUCCESS) { 12155 NDBG0(("Using FIXED interrupt type")); 12156 mpt->m_intr_type = DDI_INTR_TYPE_FIXED; 12157 return (TRUE); 12158 } else { 12159 NDBG0(("FIXED interrupt registration failed")); 12160 return (FALSE); 12161 } 12162 } 12163 12164 return (FALSE); 12165 } 12166 12167 static void 12168 mptsas_unregister_intrs(mptsas_t *mpt) 12169 { 12170 mptsas_rem_intrs(mpt); 12171 } 12172 12173 /* 12174 * mptsas_add_intrs: 12175 * 12176 * Register FIXED or MSI interrupts. 12177 */ 12178 static int 12179 mptsas_add_intrs(mptsas_t *mpt, int intr_type) 12180 { 12181 dev_info_t *dip = mpt->m_dip; 12182 int avail, actual, count = 0; 12183 int i, flag, ret; 12184 12185 NDBG6(("mptsas_add_intrs:interrupt type 0x%x", intr_type)); 12186 12187 /* Get number of interrupts */ 12188 ret = ddi_intr_get_nintrs(dip, intr_type, &count); 12189 if ((ret != DDI_SUCCESS) || (count <= 0)) { 12190 mptsas_log(mpt, CE_WARN, "ddi_intr_get_nintrs() failed, " 12191 "ret %d count %d\n", ret, count); 12192 12193 return (DDI_FAILURE); 12194 } 12195 12196 /* Get number of available interrupts */ 12197 ret = ddi_intr_get_navail(dip, intr_type, &avail); 12198 if ((ret != DDI_SUCCESS) || (avail == 0)) { 12199 mptsas_log(mpt, CE_WARN, "ddi_intr_get_navail() failed, " 12200 "ret %d avail %d\n", ret, avail); 12201 12202 return (DDI_FAILURE); 12203 } 12204 12205 if (avail < count) { 12206 mptsas_log(mpt, CE_NOTE, "ddi_intr_get_nvail returned %d, " 12207 "navail() returned %d", count, avail); 12208 } 12209 12210 /* Mpt only have one interrupt routine */ 12211 if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) { 12212 count = 1; 12213 } 12214 12215 /* Allocate an array of interrupt handles */ 12216 mpt->m_intr_size = count * sizeof (ddi_intr_handle_t); 12217 mpt->m_htable = kmem_alloc(mpt->m_intr_size, KM_SLEEP); 12218 12219 flag = DDI_INTR_ALLOC_NORMAL; 12220 12221 /* call ddi_intr_alloc() */ 12222 ret = ddi_intr_alloc(dip, mpt->m_htable, intr_type, 0, 12223 count, &actual, flag); 12224 12225 if ((ret != DDI_SUCCESS) || (actual == 0)) { 12226 mptsas_log(mpt, CE_WARN, "ddi_intr_alloc() failed, ret %d\n", 12227 ret); 12228 kmem_free(mpt->m_htable, mpt->m_intr_size); 12229 return (DDI_FAILURE); 12230 } 12231 12232 /* use interrupt count returned or abort? */ 12233 if (actual < count) { 12234 mptsas_log(mpt, CE_NOTE, "Requested: %d, Received: %d\n", 12235 count, actual); 12236 } 12237 12238 mpt->m_intr_cnt = actual; 12239 12240 /* 12241 * Get priority for first msi, assume remaining are all the same 12242 */ 12243 if ((ret = ddi_intr_get_pri(mpt->m_htable[0], 12244 &mpt->m_intr_pri)) != DDI_SUCCESS) { 12245 mptsas_log(mpt, CE_WARN, "ddi_intr_get_pri() failed %d\n", ret); 12246 12247 /* Free already allocated intr */ 12248 for (i = 0; i < actual; i++) { 12249 (void) ddi_intr_free(mpt->m_htable[i]); 12250 } 12251 12252 kmem_free(mpt->m_htable, mpt->m_intr_size); 12253 return (DDI_FAILURE); 12254 } 12255 12256 /* Test for high level mutex */ 12257 if (mpt->m_intr_pri >= ddi_intr_get_hilevel_pri()) { 12258 mptsas_log(mpt, CE_WARN, "mptsas_add_intrs: " 12259 "Hi level interrupt not supported\n"); 12260 12261 /* Free already allocated intr */ 12262 for (i = 0; i < actual; i++) { 12263 (void) ddi_intr_free(mpt->m_htable[i]); 12264 } 12265 12266 kmem_free(mpt->m_htable, mpt->m_intr_size); 12267 return (DDI_FAILURE); 12268 } 12269 12270 /* Call ddi_intr_add_handler() */ 12271 for (i = 0; i < actual; i++) { 12272 if ((ret = ddi_intr_add_handler(mpt->m_htable[i], mptsas_intr, 12273 (caddr_t)mpt, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) { 12274 mptsas_log(mpt, CE_WARN, "ddi_intr_add_handler() " 12275 "failed %d\n", ret); 12276 12277 /* Free already allocated intr */ 12278 for (i = 0; i < actual; i++) { 12279 (void) ddi_intr_free(mpt->m_htable[i]); 12280 } 12281 12282 kmem_free(mpt->m_htable, mpt->m_intr_size); 12283 return (DDI_FAILURE); 12284 } 12285 } 12286 12287 if ((ret = ddi_intr_get_cap(mpt->m_htable[0], &mpt->m_intr_cap)) 12288 != DDI_SUCCESS) { 12289 mptsas_log(mpt, CE_WARN, "ddi_intr_get_cap() failed %d\n", ret); 12290 12291 /* Free already allocated intr */ 12292 for (i = 0; i < actual; i++) { 12293 (void) ddi_intr_free(mpt->m_htable[i]); 12294 } 12295 12296 kmem_free(mpt->m_htable, mpt->m_intr_size); 12297 return (DDI_FAILURE); 12298 } 12299 12300 /* 12301 * Enable interrupts 12302 */ 12303 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) { 12304 /* Call ddi_intr_block_enable() for MSI interrupts */ 12305 (void) ddi_intr_block_enable(mpt->m_htable, mpt->m_intr_cnt); 12306 } else { 12307 /* Call ddi_intr_enable for MSI or FIXED interrupts */ 12308 for (i = 0; i < mpt->m_intr_cnt; i++) { 12309 (void) ddi_intr_enable(mpt->m_htable[i]); 12310 } 12311 } 12312 return (DDI_SUCCESS); 12313 } 12314 12315 /* 12316 * mptsas_rem_intrs: 12317 * 12318 * Unregister FIXED or MSI interrupts 12319 */ 12320 static void 12321 mptsas_rem_intrs(mptsas_t *mpt) 12322 { 12323 int i; 12324 12325 NDBG6(("mptsas_rem_intrs")); 12326 12327 /* Disable all interrupts */ 12328 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) { 12329 /* Call ddi_intr_block_disable() */ 12330 (void) ddi_intr_block_disable(mpt->m_htable, mpt->m_intr_cnt); 12331 } else { 12332 for (i = 0; i < mpt->m_intr_cnt; i++) { 12333 (void) ddi_intr_disable(mpt->m_htable[i]); 12334 } 12335 } 12336 12337 /* Call ddi_intr_remove_handler() */ 12338 for (i = 0; i < mpt->m_intr_cnt; i++) { 12339 (void) ddi_intr_remove_handler(mpt->m_htable[i]); 12340 (void) ddi_intr_free(mpt->m_htable[i]); 12341 } 12342 12343 kmem_free(mpt->m_htable, mpt->m_intr_size); 12344 } 12345 12346 /* 12347 * The IO fault service error handling callback function 12348 */ 12349 /*ARGSUSED*/ 12350 static int 12351 mptsas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data) 12352 { 12353 /* 12354 * as the driver can always deal with an error in any dma or 12355 * access handle, we can just return the fme_status value. 12356 */ 12357 pci_ereport_post(dip, err, NULL); 12358 return (err->fme_status); 12359 } 12360 12361 /* 12362 * mptsas_fm_init - initialize fma capabilities and register with IO 12363 * fault services. 12364 */ 12365 static void 12366 mptsas_fm_init(mptsas_t *mpt) 12367 { 12368 /* 12369 * Need to change iblock to priority for new MSI intr 12370 */ 12371 ddi_iblock_cookie_t fm_ibc; 12372 12373 /* Only register with IO Fault Services if we have some capability */ 12374 if (mpt->m_fm_capabilities) { 12375 /* Adjust access and dma attributes for FMA */ 12376 mpt->m_reg_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC; 12377 mpt->m_msg_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 12378 mpt->m_io_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 12379 12380 /* 12381 * Register capabilities with IO Fault Services. 12382 * mpt->m_fm_capabilities will be updated to indicate 12383 * capabilities actually supported (not requested.) 12384 */ 12385 ddi_fm_init(mpt->m_dip, &mpt->m_fm_capabilities, &fm_ibc); 12386 12387 /* 12388 * Initialize pci ereport capabilities if ereport 12389 * capable (should always be.) 12390 */ 12391 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) || 12392 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 12393 pci_ereport_setup(mpt->m_dip); 12394 } 12395 12396 /* 12397 * Register error callback if error callback capable. 12398 */ 12399 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 12400 ddi_fm_handler_register(mpt->m_dip, 12401 mptsas_fm_error_cb, (void *) mpt); 12402 } 12403 } 12404 } 12405 12406 /* 12407 * mptsas_fm_fini - Releases fma capabilities and un-registers with IO 12408 * fault services. 12409 * 12410 */ 12411 static void 12412 mptsas_fm_fini(mptsas_t *mpt) 12413 { 12414 /* Only unregister FMA capabilities if registered */ 12415 if (mpt->m_fm_capabilities) { 12416 12417 /* 12418 * Un-register error callback if error callback capable. 12419 */ 12420 12421 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 12422 ddi_fm_handler_unregister(mpt->m_dip); 12423 } 12424 12425 /* 12426 * Release any resources allocated by pci_ereport_setup() 12427 */ 12428 12429 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) || 12430 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 12431 pci_ereport_teardown(mpt->m_dip); 12432 } 12433 12434 /* Unregister from IO Fault Services */ 12435 ddi_fm_fini(mpt->m_dip); 12436 12437 /* Adjust access and dma attributes for FMA */ 12438 mpt->m_reg_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC; 12439 mpt->m_msg_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 12440 mpt->m_io_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 12441 12442 } 12443 } 12444 12445 int 12446 mptsas_check_acc_handle(ddi_acc_handle_t handle) 12447 { 12448 ddi_fm_error_t de; 12449 12450 if (handle == NULL) 12451 return (DDI_FAILURE); 12452 ddi_fm_acc_err_get(handle, &de, DDI_FME_VER0); 12453 return (de.fme_status); 12454 } 12455 12456 int 12457 mptsas_check_dma_handle(ddi_dma_handle_t handle) 12458 { 12459 ddi_fm_error_t de; 12460 12461 if (handle == NULL) 12462 return (DDI_FAILURE); 12463 ddi_fm_dma_err_get(handle, &de, DDI_FME_VER0); 12464 return (de.fme_status); 12465 } 12466 12467 void 12468 mptsas_fm_ereport(mptsas_t *mpt, char *detail) 12469 { 12470 uint64_t ena; 12471 char buf[FM_MAX_CLASS]; 12472 12473 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail); 12474 ena = fm_ena_generate(0, FM_ENA_FMT1); 12475 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities)) { 12476 ddi_fm_ereport_post(mpt->m_dip, buf, ena, DDI_NOSLEEP, 12477 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL); 12478 } 12479 } 12480 12481 static int 12482 mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address, 12483 uint16_t *dev_handle, mptsas_target_t **pptgt) 12484 { 12485 int rval; 12486 uint32_t dev_info; 12487 uint64_t sas_wwn; 12488 mptsas_phymask_t phymask; 12489 uint8_t physport, phynum, config, disk; 12490 mptsas_slots_t *slots = mpt->m_active; 12491 uint64_t devicename; 12492 uint16_t pdev_hdl; 12493 mptsas_target_t *tmp_tgt = NULL; 12494 uint16_t bay_num, enclosure; 12495 12496 ASSERT(*pptgt == NULL); 12497 12498 rval = mptsas_get_sas_device_page0(mpt, page_address, dev_handle, 12499 &sas_wwn, &dev_info, &physport, &phynum, &pdev_hdl, 12500 &bay_num, &enclosure); 12501 if (rval != DDI_SUCCESS) { 12502 rval = DEV_INFO_FAIL_PAGE0; 12503 return (rval); 12504 } 12505 12506 if ((dev_info & (MPI2_SAS_DEVICE_INFO_SSP_TARGET | 12507 MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 12508 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) == NULL) { 12509 rval = DEV_INFO_WRONG_DEVICE_TYPE; 12510 return (rval); 12511 } 12512 12513 /* 12514 * Check if the dev handle is for a Phys Disk. If so, set return value 12515 * and exit. Don't add Phys Disks to hash. 12516 */ 12517 for (config = 0; config < slots->m_num_raid_configs; config++) { 12518 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) { 12519 if (*dev_handle == slots->m_raidconfig[config]. 12520 m_physdisk_devhdl[disk]) { 12521 rval = DEV_INFO_PHYS_DISK; 12522 return (rval); 12523 } 12524 } 12525 } 12526 12527 /* 12528 * Get SATA Device Name from SAS device page0 for 12529 * sata device, if device name doesn't exist, set m_sas_wwn to 12530 * 0 for direct attached SATA. For the device behind the expander 12531 * we still can use STP address assigned by expander. 12532 */ 12533 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 12534 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 12535 mutex_exit(&mpt->m_mutex); 12536 /* alloc a tmp_tgt to send the cmd */ 12537 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), 12538 KM_SLEEP); 12539 tmp_tgt->m_devhdl = *dev_handle; 12540 tmp_tgt->m_deviceinfo = dev_info; 12541 tmp_tgt->m_qfull_retries = QFULL_RETRIES; 12542 tmp_tgt->m_qfull_retry_interval = 12543 drv_usectohz(QFULL_RETRY_INTERVAL * 1000); 12544 tmp_tgt->m_t_throttle = MAX_THROTTLE; 12545 devicename = mptsas_get_sata_guid(mpt, tmp_tgt, 0); 12546 kmem_free(tmp_tgt, sizeof (struct mptsas_target)); 12547 mutex_enter(&mpt->m_mutex); 12548 if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) { 12549 sas_wwn = devicename; 12550 } else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) { 12551 sas_wwn = 0; 12552 } 12553 } 12554 12555 phymask = mptsas_physport_to_phymask(mpt, physport); 12556 *pptgt = mptsas_tgt_alloc(&slots->m_tgttbl, *dev_handle, sas_wwn, 12557 dev_info, phymask, phynum); 12558 if (*pptgt == NULL) { 12559 mptsas_log(mpt, CE_WARN, "Failed to allocated target" 12560 "structure!"); 12561 rval = DEV_INFO_FAIL_ALLOC; 12562 return (rval); 12563 } 12564 (*pptgt)->m_enclosure = enclosure; 12565 (*pptgt)->m_slot_num = bay_num; 12566 return (DEV_INFO_SUCCESS); 12567 } 12568 12569 uint64_t 12570 mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun) 12571 { 12572 uint64_t sata_guid = 0, *pwwn = NULL; 12573 int target = ptgt->m_devhdl; 12574 uchar_t *inq83 = NULL; 12575 int inq83_len = 0xFF; 12576 uchar_t *dblk = NULL; 12577 int inq83_retry = 3; 12578 int rval = DDI_FAILURE; 12579 12580 inq83 = kmem_zalloc(inq83_len, KM_SLEEP); 12581 12582 inq83_retry: 12583 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83, 12584 inq83_len, NULL, 1); 12585 if (rval != DDI_SUCCESS) { 12586 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 12587 "0x83 for target:%x, lun:%x failed!", target, lun); 12588 goto out; 12589 } 12590 /* According to SAT2, the first descriptor is logic unit name */ 12591 dblk = &inq83[4]; 12592 if ((dblk[1] & 0x30) != 0) { 12593 mptsas_log(mpt, CE_WARN, "!Descriptor is not lun associated."); 12594 goto out; 12595 } 12596 pwwn = (uint64_t *)(void *)(&dblk[4]); 12597 if ((dblk[4] & 0xf0) == 0x50) { 12598 sata_guid = BE_64(*pwwn); 12599 goto out; 12600 } else if (dblk[4] == 'A') { 12601 NDBG20(("SATA drive has no NAA format GUID.")); 12602 goto out; 12603 } else { 12604 /* The data is not ready, wait and retry */ 12605 inq83_retry--; 12606 if (inq83_retry <= 0) { 12607 goto out; 12608 } 12609 NDBG20(("The GUID is not ready, retry...")); 12610 delay(1 * drv_usectohz(1000000)); 12611 goto inq83_retry; 12612 } 12613 out: 12614 kmem_free(inq83, inq83_len); 12615 return (sata_guid); 12616 } 12617 12618 static int 12619 mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, uchar_t page, 12620 unsigned char *buf, int len, int *reallen, uchar_t evpd) 12621 { 12622 uchar_t cdb[CDB_GROUP0]; 12623 struct scsi_address ap; 12624 struct buf *data_bp = NULL; 12625 int resid = 0; 12626 int ret = DDI_FAILURE; 12627 12628 ASSERT(len <= 0xffff); 12629 12630 ap.a_target = MPTSAS_INVALID_DEVHDL; 12631 ap.a_lun = (uchar_t)(lun); 12632 ap.a_hba_tran = mpt->m_tran; 12633 12634 data_bp = scsi_alloc_consistent_buf(&ap, 12635 (struct buf *)NULL, len, B_READ, NULL_FUNC, NULL); 12636 if (data_bp == NULL) { 12637 return (ret); 12638 } 12639 bzero(cdb, CDB_GROUP0); 12640 cdb[0] = SCMD_INQUIRY; 12641 cdb[1] = evpd; 12642 cdb[2] = page; 12643 cdb[3] = (len & 0xff00) >> 8; 12644 cdb[4] = (len & 0x00ff); 12645 cdb[5] = 0; 12646 12647 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP0, data_bp, 12648 &resid); 12649 if (ret == DDI_SUCCESS) { 12650 if (reallen) { 12651 *reallen = len - resid; 12652 } 12653 bcopy((caddr_t)data_bp->b_un.b_addr, buf, len); 12654 } 12655 if (data_bp) { 12656 scsi_free_consistent_buf(data_bp); 12657 } 12658 return (ret); 12659 } 12660 12661 static int 12662 mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap, 12663 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp, 12664 int *resid) 12665 { 12666 struct scsi_pkt *pktp = NULL; 12667 scsi_hba_tran_t *tran_clone = NULL; 12668 mptsas_tgt_private_t *tgt_private = NULL; 12669 int ret = DDI_FAILURE; 12670 12671 /* 12672 * scsi_hba_tran_t->tran_tgt_private is used to pass the address 12673 * information to scsi_init_pkt, allocate a scsi_hba_tran structure 12674 * to simulate the cmds from sd 12675 */ 12676 tran_clone = kmem_alloc( 12677 sizeof (scsi_hba_tran_t), KM_SLEEP); 12678 if (tran_clone == NULL) { 12679 goto out; 12680 } 12681 bcopy((caddr_t)mpt->m_tran, 12682 (caddr_t)tran_clone, sizeof (scsi_hba_tran_t)); 12683 tgt_private = kmem_alloc( 12684 sizeof (mptsas_tgt_private_t), KM_SLEEP); 12685 if (tgt_private == NULL) { 12686 goto out; 12687 } 12688 tgt_private->t_lun = ap->a_lun; 12689 tgt_private->t_private = ptgt; 12690 tran_clone->tran_tgt_private = tgt_private; 12691 ap->a_hba_tran = tran_clone; 12692 12693 pktp = scsi_init_pkt(ap, (struct scsi_pkt *)NULL, 12694 data_bp, cdblen, sizeof (struct scsi_arq_status), 12695 0, PKT_CONSISTENT, NULL, NULL); 12696 if (pktp == NULL) { 12697 goto out; 12698 } 12699 bcopy(cdb, pktp->pkt_cdbp, cdblen); 12700 pktp->pkt_flags = FLAG_NOPARITY; 12701 if (scsi_poll(pktp) < 0) { 12702 goto out; 12703 } 12704 if (((struct scsi_status *)pktp->pkt_scbp)->sts_chk) { 12705 goto out; 12706 } 12707 if (resid != NULL) { 12708 *resid = pktp->pkt_resid; 12709 } 12710 12711 ret = DDI_SUCCESS; 12712 out: 12713 if (pktp) { 12714 scsi_destroy_pkt(pktp); 12715 } 12716 if (tran_clone) { 12717 kmem_free(tran_clone, sizeof (scsi_hba_tran_t)); 12718 } 12719 if (tgt_private) { 12720 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t)); 12721 } 12722 return (ret); 12723 } 12724 static int 12725 mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, int *lun) 12726 { 12727 char *cp = NULL; 12728 char *ptr = NULL; 12729 size_t s = 0; 12730 char *wwid_str = NULL; 12731 char *lun_str = NULL; 12732 long lunnum; 12733 long phyid = -1; 12734 int rc = DDI_FAILURE; 12735 12736 ptr = name; 12737 ASSERT(ptr[0] == 'w' || ptr[0] == 'p'); 12738 ptr++; 12739 if ((cp = strchr(ptr, ',')) == NULL) { 12740 return (DDI_FAILURE); 12741 } 12742 12743 wwid_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 12744 s = (uintptr_t)cp - (uintptr_t)ptr; 12745 12746 bcopy(ptr, wwid_str, s); 12747 wwid_str[s] = '\0'; 12748 12749 ptr = ++cp; 12750 12751 if ((cp = strchr(ptr, '\0')) == NULL) { 12752 goto out; 12753 } 12754 lun_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 12755 s = (uintptr_t)cp - (uintptr_t)ptr; 12756 12757 bcopy(ptr, lun_str, s); 12758 lun_str[s] = '\0'; 12759 12760 if (name[0] == 'p') { 12761 rc = ddi_strtol(wwid_str, NULL, 0x10, &phyid); 12762 } else { 12763 rc = scsi_wwnstr_to_wwn(wwid_str, wwid); 12764 } 12765 if (rc != DDI_SUCCESS) 12766 goto out; 12767 12768 if (phyid != -1) { 12769 ASSERT(phyid < MPTSAS_MAX_PHYS); 12770 *phy = (uint8_t)phyid; 12771 } 12772 rc = ddi_strtol(lun_str, NULL, 0x10, &lunnum); 12773 if (rc != 0) 12774 goto out; 12775 12776 *lun = (int)lunnum; 12777 rc = DDI_SUCCESS; 12778 out: 12779 if (wwid_str) 12780 kmem_free(wwid_str, SCSI_MAXNAMELEN); 12781 if (lun_str) 12782 kmem_free(lun_str, SCSI_MAXNAMELEN); 12783 12784 return (rc); 12785 } 12786 12787 /* 12788 * mptsas_parse_smp_name() is to parse sas wwn string 12789 * which format is "wWWN" 12790 */ 12791 static int 12792 mptsas_parse_smp_name(char *name, uint64_t *wwn) 12793 { 12794 char *ptr = name; 12795 12796 if (*ptr != 'w') { 12797 return (DDI_FAILURE); 12798 } 12799 12800 ptr++; 12801 if (scsi_wwnstr_to_wwn(ptr, wwn)) { 12802 return (DDI_FAILURE); 12803 } 12804 return (DDI_SUCCESS); 12805 } 12806 12807 static int 12808 mptsas_bus_config(dev_info_t *pdip, uint_t flag, 12809 ddi_bus_config_op_t op, void *arg, dev_info_t **childp) 12810 { 12811 int ret = NDI_FAILURE; 12812 int circ = 0; 12813 int circ1 = 0; 12814 mptsas_t *mpt; 12815 char *ptr = NULL; 12816 char *devnm = NULL; 12817 uint64_t wwid = 0; 12818 uint8_t phy = 0xFF; 12819 int lun = 0; 12820 uint_t mflags = flag; 12821 int bconfig = TRUE; 12822 12823 if (scsi_hba_iport_unit_address(pdip) == 0) { 12824 return (DDI_FAILURE); 12825 } 12826 12827 mpt = DIP2MPT(pdip); 12828 if (!mpt) { 12829 return (DDI_FAILURE); 12830 } 12831 /* 12832 * Hold the nexus across the bus_config 12833 */ 12834 ndi_devi_enter(scsi_vhci_dip, &circ); 12835 ndi_devi_enter(pdip, &circ1); 12836 switch (op) { 12837 case BUS_CONFIG_ONE: 12838 /* parse wwid/target name out of name given */ 12839 if ((ptr = strchr((char *)arg, '@')) == NULL) { 12840 ret = NDI_FAILURE; 12841 break; 12842 } 12843 ptr++; 12844 if (strncmp((char *)arg, "smp", 3) == 0) { 12845 /* 12846 * This is a SMP target device 12847 */ 12848 ret = mptsas_parse_smp_name(ptr, &wwid); 12849 if (ret != DDI_SUCCESS) { 12850 ret = NDI_FAILURE; 12851 break; 12852 } 12853 ret = mptsas_config_smp(pdip, wwid, childp); 12854 } else if ((ptr[0] == 'w') || (ptr[0] == 'p')) { 12855 /* 12856 * OBP could pass down a non-canonical form 12857 * bootpath without LUN part when LUN is 0. 12858 * So driver need adjust the string. 12859 */ 12860 if (strchr(ptr, ',') == NULL) { 12861 devnm = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 12862 (void) sprintf(devnm, "%s,0", (char *)arg); 12863 ptr = strchr(devnm, '@'); 12864 ptr++; 12865 } 12866 12867 /* 12868 * The device path is wWWID format and the device 12869 * is not SMP target device. 12870 */ 12871 ret = mptsas_parse_address(ptr, &wwid, &phy, &lun); 12872 if (ret != DDI_SUCCESS) { 12873 ret = NDI_FAILURE; 12874 break; 12875 } 12876 *childp = NULL; 12877 if (ptr[0] == 'w') { 12878 ret = mptsas_config_one_addr(pdip, wwid, 12879 lun, childp); 12880 } else if (ptr[0] == 'p') { 12881 ret = mptsas_config_one_phy(pdip, phy, lun, 12882 childp); 12883 } 12884 12885 /* 12886 * If this is CD/DVD device in OBP path, the 12887 * ndi_busop_bus_config can be skipped as config one 12888 * operation is done above. 12889 */ 12890 if ((ret == NDI_SUCCESS) && (*childp != NULL) && 12891 (strcmp(ddi_node_name(*childp), "cdrom") == 0) && 12892 (strncmp((char *)arg, "disk", 4) == 0)) { 12893 bconfig = FALSE; 12894 ndi_hold_devi(*childp); 12895 } 12896 } else { 12897 ret = NDI_FAILURE; 12898 break; 12899 } 12900 12901 /* 12902 * DDI group instructed us to use this flag. 12903 */ 12904 mflags |= NDI_MDI_FALLBACK; 12905 break; 12906 case BUS_CONFIG_DRIVER: 12907 case BUS_CONFIG_ALL: 12908 mptsas_config_all(pdip); 12909 ret = NDI_SUCCESS; 12910 break; 12911 } 12912 12913 if ((ret == NDI_SUCCESS) && bconfig) { 12914 ret = ndi_busop_bus_config(pdip, mflags, op, 12915 (devnm == NULL) ? arg : devnm, childp, 0); 12916 } 12917 12918 ndi_devi_exit(pdip, circ1); 12919 ndi_devi_exit(scsi_vhci_dip, circ); 12920 if (devnm != NULL) 12921 kmem_free(devnm, SCSI_MAXNAMELEN); 12922 return (ret); 12923 } 12924 12925 static int 12926 mptsas_probe_lun(dev_info_t *pdip, int lun, dev_info_t **dip, 12927 mptsas_target_t *ptgt) 12928 { 12929 int rval = DDI_FAILURE; 12930 struct scsi_inquiry *sd_inq = NULL; 12931 mptsas_t *mpt = DIP2MPT(pdip); 12932 12933 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP); 12934 12935 rval = mptsas_inquiry(mpt, ptgt, lun, 0, (uchar_t *)sd_inq, 12936 SUN_INQSIZE, 0, (uchar_t)0); 12937 12938 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) { 12939 rval = mptsas_create_lun(pdip, sd_inq, dip, ptgt, lun); 12940 } else { 12941 rval = DDI_FAILURE; 12942 } 12943 12944 kmem_free(sd_inq, SUN_INQSIZE); 12945 return (rval); 12946 } 12947 12948 static int 12949 mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun, 12950 dev_info_t **lundip) 12951 { 12952 int rval; 12953 mptsas_t *mpt = DIP2MPT(pdip); 12954 int phymask; 12955 mptsas_target_t *ptgt = NULL; 12956 12957 /* 12958 * Get the physical port associated to the iport 12959 */ 12960 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 12961 "phymask", 0); 12962 12963 ptgt = mptsas_wwid_to_ptgt(mpt, phymask, sasaddr); 12964 if (ptgt == NULL) { 12965 /* 12966 * didn't match any device by searching 12967 */ 12968 return (DDI_FAILURE); 12969 } 12970 /* 12971 * If the LUN already exists and the status is online, 12972 * we just return the pointer to dev_info_t directly. 12973 * For the mdi_pathinfo node, we'll handle it in 12974 * mptsas_create_virt_lun() 12975 * TODO should be also in mptsas_handle_dr 12976 */ 12977 12978 *lundip = mptsas_find_child_addr(pdip, sasaddr, lun); 12979 if (*lundip != NULL) { 12980 /* 12981 * TODO Another senario is, we hotplug the same disk 12982 * on the same slot, the devhdl changed, is this 12983 * possible? 12984 * tgt_private->t_private != ptgt 12985 */ 12986 if (sasaddr != ptgt->m_sas_wwn) { 12987 /* 12988 * The device has changed although the devhdl is the 12989 * same (Enclosure mapping mode, change drive on the 12990 * same slot) 12991 */ 12992 return (DDI_FAILURE); 12993 } 12994 return (DDI_SUCCESS); 12995 } 12996 12997 if (phymask == 0) { 12998 /* 12999 * Configure IR volume 13000 */ 13001 rval = mptsas_config_raid(pdip, ptgt->m_devhdl, lundip); 13002 return (rval); 13003 } 13004 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt); 13005 13006 return (rval); 13007 } 13008 13009 static int 13010 mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun, 13011 dev_info_t **lundip) 13012 { 13013 int rval; 13014 mptsas_t *mpt = DIP2MPT(pdip); 13015 int phymask; 13016 mptsas_target_t *ptgt = NULL; 13017 13018 /* 13019 * Get the physical port associated to the iport 13020 */ 13021 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 13022 "phymask", 0); 13023 13024 ptgt = mptsas_phy_to_tgt(mpt, phymask, phy); 13025 if (ptgt == NULL) { 13026 /* 13027 * didn't match any device by searching 13028 */ 13029 return (DDI_FAILURE); 13030 } 13031 13032 /* 13033 * If the LUN already exists and the status is online, 13034 * we just return the pointer to dev_info_t directly. 13035 * For the mdi_pathinfo node, we'll handle it in 13036 * mptsas_create_virt_lun(). 13037 */ 13038 13039 *lundip = mptsas_find_child_phy(pdip, phy); 13040 if (*lundip != NULL) { 13041 return (DDI_SUCCESS); 13042 } 13043 13044 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt); 13045 13046 return (rval); 13047 } 13048 13049 static int 13050 mptsas_retrieve_lundata(int lun_cnt, uint8_t *buf, uint16_t *lun_num, 13051 uint8_t *lun_addr_type) 13052 { 13053 uint32_t lun_idx = 0; 13054 13055 ASSERT(lun_num != NULL); 13056 ASSERT(lun_addr_type != NULL); 13057 13058 lun_idx = (lun_cnt + 1) * MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE; 13059 /* determine report luns addressing type */ 13060 switch (buf[lun_idx] & MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) { 13061 /* 13062 * Vendors in the field have been found to be concatenating 13063 * bus/target/lun to equal the complete lun value instead 13064 * of switching to flat space addressing 13065 */ 13066 /* 00b - peripheral device addressing method */ 13067 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_PERIPHERAL: 13068 /* FALLTHRU */ 13069 /* 10b - logical unit addressing method */ 13070 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT: 13071 /* FALLTHRU */ 13072 /* 01b - flat space addressing method */ 13073 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE: 13074 /* byte0 bit0-5=msb lun byte1 bit0-7=lsb lun */ 13075 *lun_addr_type = (buf[lun_idx] & 13076 MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) >> 6; 13077 *lun_num = (buf[lun_idx] & 0x3F) << 8; 13078 *lun_num |= buf[lun_idx + 1]; 13079 return (DDI_SUCCESS); 13080 default: 13081 return (DDI_FAILURE); 13082 } 13083 } 13084 13085 static int 13086 mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt) 13087 { 13088 struct buf *repluns_bp = NULL; 13089 struct scsi_address ap; 13090 uchar_t cdb[CDB_GROUP5]; 13091 int ret = DDI_FAILURE; 13092 int retry = 0; 13093 int lun_list_len = 0; 13094 uint16_t lun_num = 0; 13095 uint8_t lun_addr_type = 0; 13096 uint32_t lun_cnt = 0; 13097 uint32_t lun_total = 0; 13098 dev_info_t *cdip = NULL; 13099 uint16_t *saved_repluns = NULL; 13100 char *buffer = NULL; 13101 int buf_len = 128; 13102 mptsas_t *mpt = DIP2MPT(pdip); 13103 uint64_t sas_wwn = 0; 13104 uint8_t phy = 0xFF; 13105 uint32_t dev_info = 0; 13106 13107 mutex_enter(&mpt->m_mutex); 13108 sas_wwn = ptgt->m_sas_wwn; 13109 phy = ptgt->m_phynum; 13110 dev_info = ptgt->m_deviceinfo; 13111 mutex_exit(&mpt->m_mutex); 13112 13113 if (sas_wwn == 0) { 13114 /* 13115 * It's a SATA without Device Name 13116 * So don't try multi-LUNs 13117 */ 13118 if (mptsas_find_child_phy(pdip, phy)) { 13119 return (DDI_SUCCESS); 13120 } else { 13121 /* 13122 * need configure and create node 13123 */ 13124 return (DDI_FAILURE); 13125 } 13126 } 13127 13128 /* 13129 * WWN (SAS address or Device Name exist) 13130 */ 13131 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 13132 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 13133 /* 13134 * SATA device with Device Name 13135 * So don't try multi-LUNs 13136 */ 13137 if (mptsas_find_child_addr(pdip, sas_wwn, 0)) { 13138 return (DDI_SUCCESS); 13139 } else { 13140 return (DDI_FAILURE); 13141 } 13142 } 13143 13144 do { 13145 ap.a_target = MPTSAS_INVALID_DEVHDL; 13146 ap.a_lun = 0; 13147 ap.a_hba_tran = mpt->m_tran; 13148 repluns_bp = scsi_alloc_consistent_buf(&ap, 13149 (struct buf *)NULL, buf_len, B_READ, NULL_FUNC, NULL); 13150 if (repluns_bp == NULL) { 13151 retry++; 13152 continue; 13153 } 13154 bzero(cdb, CDB_GROUP5); 13155 cdb[0] = SCMD_REPORT_LUNS; 13156 cdb[6] = (buf_len & 0xff000000) >> 24; 13157 cdb[7] = (buf_len & 0x00ff0000) >> 16; 13158 cdb[8] = (buf_len & 0x0000ff00) >> 8; 13159 cdb[9] = (buf_len & 0x000000ff); 13160 13161 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP5, 13162 repluns_bp, NULL); 13163 if (ret != DDI_SUCCESS) { 13164 scsi_free_consistent_buf(repluns_bp); 13165 retry++; 13166 continue; 13167 } 13168 lun_list_len = BE_32(*(int *)((void *)( 13169 repluns_bp->b_un.b_addr))); 13170 if (buf_len >= lun_list_len + 8) { 13171 ret = DDI_SUCCESS; 13172 break; 13173 } 13174 scsi_free_consistent_buf(repluns_bp); 13175 buf_len = lun_list_len + 8; 13176 13177 } while (retry < 3); 13178 13179 if (ret != DDI_SUCCESS) 13180 return (ret); 13181 buffer = (char *)repluns_bp->b_un.b_addr; 13182 /* 13183 * find out the number of luns returned by the SCSI ReportLun call 13184 * and allocate buffer space 13185 */ 13186 lun_total = lun_list_len / MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE; 13187 saved_repluns = kmem_zalloc(sizeof (uint16_t) * lun_total, KM_SLEEP); 13188 if (saved_repluns == NULL) { 13189 scsi_free_consistent_buf(repluns_bp); 13190 return (DDI_FAILURE); 13191 } 13192 for (lun_cnt = 0; lun_cnt < lun_total; lun_cnt++) { 13193 if (mptsas_retrieve_lundata(lun_cnt, (uint8_t *)(buffer), 13194 &lun_num, &lun_addr_type) != DDI_SUCCESS) { 13195 continue; 13196 } 13197 saved_repluns[lun_cnt] = lun_num; 13198 if (cdip = mptsas_find_child_addr(pdip, sas_wwn, lun_num)) 13199 ret = DDI_SUCCESS; 13200 else 13201 ret = mptsas_probe_lun(pdip, lun_num, &cdip, 13202 ptgt); 13203 if ((ret == DDI_SUCCESS) && (cdip != NULL)) { 13204 (void) ndi_prop_remove(DDI_DEV_T_NONE, cdip, 13205 MPTSAS_DEV_GONE); 13206 } 13207 } 13208 mptsas_offline_missed_luns(pdip, saved_repluns, lun_total, ptgt); 13209 kmem_free(saved_repluns, sizeof (uint16_t) * lun_total); 13210 scsi_free_consistent_buf(repluns_bp); 13211 return (DDI_SUCCESS); 13212 } 13213 13214 static int 13215 mptsas_config_raid(dev_info_t *pdip, uint16_t target, dev_info_t **dip) 13216 { 13217 int rval = DDI_FAILURE; 13218 struct scsi_inquiry *sd_inq = NULL; 13219 mptsas_t *mpt = DIP2MPT(pdip); 13220 mptsas_target_t *ptgt = NULL; 13221 13222 mutex_enter(&mpt->m_mutex); 13223 ptgt = mptsas_search_by_devhdl(&mpt->m_active->m_tgttbl, target); 13224 mutex_exit(&mpt->m_mutex); 13225 if (ptgt == NULL) { 13226 mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x " 13227 "not found.", target); 13228 return (rval); 13229 } 13230 13231 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP); 13232 rval = mptsas_inquiry(mpt, ptgt, 0, 0, (uchar_t *)sd_inq, 13233 SUN_INQSIZE, 0, (uchar_t)0); 13234 13235 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) { 13236 rval = mptsas_create_phys_lun(pdip, sd_inq, NULL, dip, ptgt, 13237 0); 13238 } else { 13239 rval = DDI_FAILURE; 13240 } 13241 13242 kmem_free(sd_inq, SUN_INQSIZE); 13243 return (rval); 13244 } 13245 13246 /* 13247 * configure all RAID volumes for virtual iport 13248 */ 13249 static void 13250 mptsas_config_all_viport(dev_info_t *pdip) 13251 { 13252 mptsas_t *mpt = DIP2MPT(pdip); 13253 int config, vol; 13254 int target; 13255 dev_info_t *lundip = NULL; 13256 mptsas_slots_t *slots = mpt->m_active; 13257 13258 /* 13259 * Get latest RAID info and search for any Volume DevHandles. If any 13260 * are found, configure the volume. 13261 */ 13262 mutex_enter(&mpt->m_mutex); 13263 for (config = 0; config < slots->m_num_raid_configs; config++) { 13264 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) { 13265 if (slots->m_raidconfig[config].m_raidvol[vol].m_israid 13266 == 1) { 13267 target = slots->m_raidconfig[config]. 13268 m_raidvol[vol].m_raidhandle; 13269 mutex_exit(&mpt->m_mutex); 13270 (void) mptsas_config_raid(pdip, target, 13271 &lundip); 13272 mutex_enter(&mpt->m_mutex); 13273 } 13274 } 13275 } 13276 mutex_exit(&mpt->m_mutex); 13277 } 13278 13279 static void 13280 mptsas_offline_missed_luns(dev_info_t *pdip, uint16_t *repluns, 13281 int lun_cnt, mptsas_target_t *ptgt) 13282 { 13283 dev_info_t *child = NULL, *savechild = NULL; 13284 mdi_pathinfo_t *pip = NULL, *savepip = NULL; 13285 uint64_t sas_wwn, wwid; 13286 uint8_t phy; 13287 int lun; 13288 int i; 13289 int find; 13290 char *addr; 13291 char *nodename; 13292 mptsas_t *mpt = DIP2MPT(pdip); 13293 13294 mutex_enter(&mpt->m_mutex); 13295 wwid = ptgt->m_sas_wwn; 13296 mutex_exit(&mpt->m_mutex); 13297 13298 child = ddi_get_child(pdip); 13299 while (child) { 13300 find = 0; 13301 savechild = child; 13302 child = ddi_get_next_sibling(child); 13303 13304 nodename = ddi_node_name(savechild); 13305 if (strcmp(nodename, "smp") == 0) { 13306 continue; 13307 } 13308 13309 addr = ddi_get_name_addr(savechild); 13310 if (addr == NULL) { 13311 continue; 13312 } 13313 13314 if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) != 13315 DDI_SUCCESS) { 13316 continue; 13317 } 13318 13319 if (wwid == sas_wwn) { 13320 for (i = 0; i < lun_cnt; i++) { 13321 if (repluns[i] == lun) { 13322 find = 1; 13323 break; 13324 } 13325 } 13326 } else { 13327 continue; 13328 } 13329 if (find == 0) { 13330 /* 13331 * The lun has not been there already 13332 */ 13333 (void) mptsas_offline_lun(pdip, savechild, NULL, 13334 NDI_DEVI_REMOVE); 13335 } 13336 } 13337 13338 pip = mdi_get_next_client_path(pdip, NULL); 13339 while (pip) { 13340 find = 0; 13341 savepip = pip; 13342 addr = MDI_PI(pip)->pi_addr; 13343 13344 pip = mdi_get_next_client_path(pdip, pip); 13345 13346 if (addr == NULL) { 13347 continue; 13348 } 13349 13350 if (mptsas_parse_address(addr, &sas_wwn, &phy, 13351 &lun) != DDI_SUCCESS) { 13352 continue; 13353 } 13354 13355 if (sas_wwn == wwid) { 13356 for (i = 0; i < lun_cnt; i++) { 13357 if (repluns[i] == lun) { 13358 find = 1; 13359 break; 13360 } 13361 } 13362 } else { 13363 continue; 13364 } 13365 13366 if (find == 0) { 13367 /* 13368 * The lun has not been there already 13369 */ 13370 (void) mptsas_offline_lun(pdip, NULL, savepip, 13371 NDI_DEVI_REMOVE); 13372 } 13373 } 13374 } 13375 13376 void 13377 mptsas_update_hashtab(struct mptsas *mpt) 13378 { 13379 uint32_t page_address; 13380 int rval = 0; 13381 uint16_t dev_handle; 13382 mptsas_target_t *ptgt = NULL; 13383 mptsas_smp_t smp_node; 13384 13385 /* 13386 * Get latest RAID info. 13387 */ 13388 (void) mptsas_get_raid_info(mpt); 13389 13390 dev_handle = mpt->m_smp_devhdl; 13391 for (; mpt->m_done_traverse_smp == 0; ) { 13392 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL & 13393 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)dev_handle; 13394 if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node) 13395 != DDI_SUCCESS) { 13396 break; 13397 } 13398 mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl; 13399 (void) mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node); 13400 } 13401 13402 /* 13403 * Config target devices 13404 */ 13405 dev_handle = mpt->m_dev_handle; 13406 13407 /* 13408 * Do loop to get sas device page 0 by GetNextHandle till the 13409 * the last handle. If the sas device is a SATA/SSP target, 13410 * we try to config it. 13411 */ 13412 for (; mpt->m_done_traverse_dev == 0; ) { 13413 ptgt = NULL; 13414 page_address = 13415 (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 13416 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 13417 (uint32_t)dev_handle; 13418 rval = mptsas_get_target_device_info(mpt, page_address, 13419 &dev_handle, &ptgt); 13420 if ((rval == DEV_INFO_FAIL_PAGE0) || 13421 (rval == DEV_INFO_FAIL_ALLOC)) { 13422 break; 13423 } 13424 13425 mpt->m_dev_handle = dev_handle; 13426 } 13427 13428 } 13429 13430 void 13431 mptsas_invalid_hashtab(mptsas_hash_table_t *hashtab) 13432 { 13433 mptsas_hash_data_t *data; 13434 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST); 13435 while (data != NULL) { 13436 data->devhdl = MPTSAS_INVALID_DEVHDL; 13437 data->device_info = 0; 13438 /* 13439 * For tgttbl, clear dr_flag. 13440 */ 13441 data->dr_flag = MPTSAS_DR_INACTIVE; 13442 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT); 13443 } 13444 } 13445 13446 void 13447 mptsas_update_driver_data(struct mptsas *mpt) 13448 { 13449 /* 13450 * TODO after hard reset, update the driver data structures 13451 * 1. update port/phymask mapping table mpt->m_phy_info 13452 * 2. invalid all the entries in hash table 13453 * m_devhdl = 0xffff and m_deviceinfo = 0 13454 * 3. call sas_device_page/expander_page to update hash table 13455 */ 13456 mptsas_update_phymask(mpt); 13457 /* 13458 * Invalid the existing entries 13459 */ 13460 mptsas_invalid_hashtab(&mpt->m_active->m_tgttbl); 13461 mptsas_invalid_hashtab(&mpt->m_active->m_smptbl); 13462 mpt->m_done_traverse_dev = 0; 13463 mpt->m_done_traverse_smp = 0; 13464 mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL; 13465 mptsas_update_hashtab(mpt); 13466 } 13467 13468 static void 13469 mptsas_config_all(dev_info_t *pdip) 13470 { 13471 dev_info_t *smpdip = NULL; 13472 mptsas_t *mpt = DIP2MPT(pdip); 13473 int phymask = 0; 13474 mptsas_phymask_t phy_mask; 13475 mptsas_target_t *ptgt = NULL; 13476 mptsas_smp_t *psmp; 13477 13478 /* 13479 * Get the phymask associated to the iport 13480 */ 13481 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 13482 "phymask", 0); 13483 13484 /* 13485 * Enumerate RAID volumes here (phymask == 0). 13486 */ 13487 if (phymask == 0) { 13488 mptsas_config_all_viport(pdip); 13489 return; 13490 } 13491 13492 mutex_enter(&mpt->m_mutex); 13493 13494 if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp) { 13495 mptsas_update_hashtab(mpt); 13496 } 13497 13498 psmp = (mptsas_smp_t *)mptsas_hash_traverse(&mpt->m_active->m_smptbl, 13499 MPTSAS_HASH_FIRST); 13500 while (psmp != NULL) { 13501 phy_mask = psmp->m_phymask; 13502 if (phy_mask == phymask) { 13503 smpdip = NULL; 13504 mutex_exit(&mpt->m_mutex); 13505 (void) mptsas_online_smp(pdip, psmp, &smpdip); 13506 mutex_enter(&mpt->m_mutex); 13507 } 13508 psmp = (mptsas_smp_t *)mptsas_hash_traverse( 13509 &mpt->m_active->m_smptbl, MPTSAS_HASH_NEXT); 13510 } 13511 13512 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 13513 MPTSAS_HASH_FIRST); 13514 while (ptgt != NULL) { 13515 phy_mask = ptgt->m_phymask; 13516 if (phy_mask == phymask) { 13517 mutex_exit(&mpt->m_mutex); 13518 (void) mptsas_config_target(pdip, ptgt); 13519 mutex_enter(&mpt->m_mutex); 13520 } 13521 13522 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 13523 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 13524 } 13525 mutex_exit(&mpt->m_mutex); 13526 } 13527 13528 static int 13529 mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt) 13530 { 13531 int rval = DDI_FAILURE; 13532 dev_info_t *tdip; 13533 13534 rval = mptsas_config_luns(pdip, ptgt); 13535 if (rval != DDI_SUCCESS) { 13536 /* 13537 * The return value means the SCMD_REPORT_LUNS 13538 * did not execute successfully. The target maybe 13539 * doesn't support such command. 13540 */ 13541 rval = mptsas_probe_lun(pdip, 0, &tdip, ptgt); 13542 } 13543 return (rval); 13544 } 13545 13546 /* 13547 * Return fail if not all the childs/paths are freed. 13548 * if there is any path under the HBA, the return value will be always fail 13549 * because we didn't call mdi_pi_free for path 13550 */ 13551 static int 13552 mptsas_offline_target(dev_info_t *pdip, char *name) 13553 { 13554 dev_info_t *child = NULL, *prechild = NULL; 13555 mdi_pathinfo_t *pip = NULL, *savepip = NULL; 13556 int tmp_rval, rval = DDI_SUCCESS; 13557 char *addr, *cp; 13558 size_t s; 13559 mptsas_t *mpt = DIP2MPT(pdip); 13560 13561 child = ddi_get_child(pdip); 13562 while (child) { 13563 addr = ddi_get_name_addr(child); 13564 prechild = child; 13565 child = ddi_get_next_sibling(child); 13566 13567 if (addr == NULL) { 13568 continue; 13569 } 13570 if ((cp = strchr(addr, ',')) == NULL) { 13571 continue; 13572 } 13573 13574 s = (uintptr_t)cp - (uintptr_t)addr; 13575 13576 if (strncmp(addr, name, s) != 0) { 13577 continue; 13578 } 13579 13580 tmp_rval = mptsas_offline_lun(pdip, prechild, NULL, 13581 NDI_DEVI_REMOVE); 13582 if (tmp_rval != DDI_SUCCESS) { 13583 rval = DDI_FAILURE; 13584 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 13585 prechild, MPTSAS_DEV_GONE) != 13586 DDI_PROP_SUCCESS) { 13587 mptsas_log(mpt, CE_WARN, "mptsas driver " 13588 "unable to create property for " 13589 "SAS %s (MPTSAS_DEV_GONE)", addr); 13590 } 13591 } 13592 } 13593 13594 pip = mdi_get_next_client_path(pdip, NULL); 13595 while (pip) { 13596 addr = MDI_PI(pip)->pi_addr; 13597 savepip = pip; 13598 pip = mdi_get_next_client_path(pdip, pip); 13599 if (addr == NULL) { 13600 continue; 13601 } 13602 13603 if ((cp = strchr(addr, ',')) == NULL) { 13604 continue; 13605 } 13606 13607 s = (uintptr_t)cp - (uintptr_t)addr; 13608 13609 if (strncmp(addr, name, s) != 0) { 13610 continue; 13611 } 13612 13613 (void) mptsas_offline_lun(pdip, NULL, savepip, 13614 NDI_DEVI_REMOVE); 13615 /* 13616 * driver will not invoke mdi_pi_free, so path will not 13617 * be freed forever, return DDI_FAILURE. 13618 */ 13619 rval = DDI_FAILURE; 13620 } 13621 return (rval); 13622 } 13623 13624 static int 13625 mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip, 13626 mdi_pathinfo_t *rpip, uint_t flags) 13627 { 13628 int rval = DDI_FAILURE; 13629 char *devname; 13630 dev_info_t *cdip, *parent; 13631 13632 if (rpip != NULL) { 13633 parent = scsi_vhci_dip; 13634 cdip = mdi_pi_get_client(rpip); 13635 } else if (rdip != NULL) { 13636 parent = pdip; 13637 cdip = rdip; 13638 } else { 13639 return (DDI_FAILURE); 13640 } 13641 13642 /* 13643 * Make sure node is attached otherwise 13644 * it won't have related cache nodes to 13645 * clean up. i_ddi_devi_attached is 13646 * similiar to i_ddi_node_state(cdip) >= 13647 * DS_ATTACHED. 13648 */ 13649 if (i_ddi_devi_attached(cdip)) { 13650 13651 /* Get full devname */ 13652 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 13653 (void) ddi_deviname(cdip, devname); 13654 /* Clean cache */ 13655 (void) devfs_clean(parent, devname + 1, 13656 DV_CLEAN_FORCE); 13657 kmem_free(devname, MAXNAMELEN + 1); 13658 } 13659 if (rpip != NULL) { 13660 if (MDI_PI_IS_OFFLINE(rpip)) { 13661 rval = DDI_SUCCESS; 13662 } else { 13663 rval = mdi_pi_offline(rpip, 0); 13664 } 13665 } else { 13666 rval = ndi_devi_offline(cdip, flags); 13667 } 13668 13669 return (rval); 13670 } 13671 13672 static dev_info_t * 13673 mptsas_find_smp_child(dev_info_t *parent, char *str_wwn) 13674 { 13675 dev_info_t *child = NULL; 13676 char *smp_wwn = NULL; 13677 13678 child = ddi_get_child(parent); 13679 while (child) { 13680 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child, 13681 DDI_PROP_DONTPASS, SMP_WWN, &smp_wwn) 13682 != DDI_SUCCESS) { 13683 child = ddi_get_next_sibling(child); 13684 continue; 13685 } 13686 13687 if (strcmp(smp_wwn, str_wwn) == 0) { 13688 ddi_prop_free(smp_wwn); 13689 break; 13690 } 13691 child = ddi_get_next_sibling(child); 13692 ddi_prop_free(smp_wwn); 13693 } 13694 return (child); 13695 } 13696 13697 static int 13698 mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags) 13699 { 13700 int rval = DDI_FAILURE; 13701 char *devname; 13702 char wwn_str[MPTSAS_WWN_STRLEN]; 13703 dev_info_t *cdip; 13704 13705 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr); 13706 13707 cdip = mptsas_find_smp_child(pdip, wwn_str); 13708 13709 if (cdip == NULL) 13710 return (DDI_SUCCESS); 13711 13712 /* 13713 * Make sure node is attached otherwise 13714 * it won't have related cache nodes to 13715 * clean up. i_ddi_devi_attached is 13716 * similiar to i_ddi_node_state(cdip) >= 13717 * DS_ATTACHED. 13718 */ 13719 if (i_ddi_devi_attached(cdip)) { 13720 13721 /* Get full devname */ 13722 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 13723 (void) ddi_deviname(cdip, devname); 13724 /* Clean cache */ 13725 (void) devfs_clean(pdip, devname + 1, 13726 DV_CLEAN_FORCE); 13727 kmem_free(devname, MAXNAMELEN + 1); 13728 } 13729 13730 rval = ndi_devi_offline(cdip, flags); 13731 13732 return (rval); 13733 } 13734 13735 static dev_info_t * 13736 mptsas_find_child(dev_info_t *pdip, char *name) 13737 { 13738 dev_info_t *child = NULL; 13739 char *rname = NULL; 13740 int rval = DDI_FAILURE; 13741 13742 rname = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13743 13744 child = ddi_get_child(pdip); 13745 while (child) { 13746 rval = mptsas_name_child(child, rname, SCSI_MAXNAMELEN); 13747 if (rval != DDI_SUCCESS) { 13748 child = ddi_get_next_sibling(child); 13749 bzero(rname, SCSI_MAXNAMELEN); 13750 continue; 13751 } 13752 13753 if (strcmp(rname, name) == 0) { 13754 break; 13755 } 13756 child = ddi_get_next_sibling(child); 13757 bzero(rname, SCSI_MAXNAMELEN); 13758 } 13759 13760 kmem_free(rname, SCSI_MAXNAMELEN); 13761 13762 return (child); 13763 } 13764 13765 13766 static dev_info_t * 13767 mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, int lun) 13768 { 13769 dev_info_t *child = NULL; 13770 char *name = NULL; 13771 char *addr = NULL; 13772 13773 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13774 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13775 (void) sprintf(name, "%016"PRIx64, sasaddr); 13776 (void) sprintf(addr, "w%s,%x", name, lun); 13777 child = mptsas_find_child(pdip, addr); 13778 kmem_free(name, SCSI_MAXNAMELEN); 13779 kmem_free(addr, SCSI_MAXNAMELEN); 13780 return (child); 13781 } 13782 13783 static dev_info_t * 13784 mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy) 13785 { 13786 dev_info_t *child; 13787 char *addr; 13788 13789 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13790 (void) sprintf(addr, "p%x,0", phy); 13791 child = mptsas_find_child(pdip, addr); 13792 kmem_free(addr, SCSI_MAXNAMELEN); 13793 return (child); 13794 } 13795 13796 static mdi_pathinfo_t * 13797 mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy) 13798 { 13799 mdi_pathinfo_t *path; 13800 char *addr = NULL; 13801 13802 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13803 (void) sprintf(addr, "p%x,0", phy); 13804 path = mdi_pi_find(pdip, NULL, addr); 13805 kmem_free(addr, SCSI_MAXNAMELEN); 13806 return (path); 13807 } 13808 13809 static mdi_pathinfo_t * 13810 mptsas_find_path_addr(dev_info_t *parent, uint64_t sasaddr, int lun) 13811 { 13812 mdi_pathinfo_t *path; 13813 char *name = NULL; 13814 char *addr = NULL; 13815 13816 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13817 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13818 (void) sprintf(name, "%016"PRIx64, sasaddr); 13819 (void) sprintf(addr, "w%s,%x", name, lun); 13820 path = mdi_pi_find(parent, NULL, addr); 13821 kmem_free(name, SCSI_MAXNAMELEN); 13822 kmem_free(addr, SCSI_MAXNAMELEN); 13823 13824 return (path); 13825 } 13826 13827 static int 13828 mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq, 13829 dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun) 13830 { 13831 int i = 0; 13832 uchar_t *inq83 = NULL; 13833 int inq83_len1 = 0xFF; 13834 int inq83_len = 0; 13835 int rval = DDI_FAILURE; 13836 ddi_devid_t devid; 13837 char *guid = NULL; 13838 int target = ptgt->m_devhdl; 13839 mdi_pathinfo_t *pip = NULL; 13840 mptsas_t *mpt = DIP2MPT(pdip); 13841 13842 /* 13843 * For DVD/CD ROM and tape devices and optical 13844 * devices, we won't try to enumerate them under 13845 * scsi_vhci, so no need to try page83 13846 */ 13847 if (sd_inq && (sd_inq->inq_dtype == DTYPE_RODIRECT || 13848 sd_inq->inq_dtype == DTYPE_OPTICAL || 13849 sd_inq->inq_dtype == DTYPE_ESI)) 13850 goto create_lun; 13851 13852 /* 13853 * The LCA returns good SCSI status, but corrupt page 83 data the first 13854 * time it is queried. The solution is to keep trying to request page83 13855 * and verify the GUID is not (DDI_NOT_WELL_FORMED) in 13856 * mptsas_inq83_retry_timeout seconds. If the timeout expires, driver 13857 * give up to get VPD page at this stage and fail the enumeration. 13858 */ 13859 13860 inq83 = kmem_zalloc(inq83_len1, KM_SLEEP); 13861 13862 for (i = 0; i < mptsas_inq83_retry_timeout; i++) { 13863 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83, 13864 inq83_len1, &inq83_len, 1); 13865 if (rval != 0) { 13866 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 13867 "0x83 for target:%x, lun:%x failed!", target, lun); 13868 if (mptsas_physical_bind_failed_page_83 != B_FALSE) 13869 goto create_lun; 13870 goto out; 13871 } 13872 /* 13873 * create DEVID from inquiry data 13874 */ 13875 if ((rval = ddi_devid_scsi_encode( 13876 DEVID_SCSI_ENCODE_VERSION_LATEST, NULL, (uchar_t *)sd_inq, 13877 sizeof (struct scsi_inquiry), NULL, 0, inq83, 13878 (size_t)inq83_len, &devid)) == DDI_SUCCESS) { 13879 /* 13880 * extract GUID from DEVID 13881 */ 13882 guid = ddi_devid_to_guid(devid); 13883 13884 /* 13885 * Do not enable MPXIO if the strlen(guid) is greater 13886 * than MPTSAS_MAX_GUID_LEN, this constrain would be 13887 * handled by framework later. 13888 */ 13889 if (guid && (strlen(guid) > MPTSAS_MAX_GUID_LEN)) { 13890 ddi_devid_free_guid(guid); 13891 guid = NULL; 13892 if (mpt->m_mpxio_enable == TRUE) { 13893 mptsas_log(mpt, CE_NOTE, "!Target:%x, " 13894 "lun:%x doesn't have a valid GUID, " 13895 "multipathing for this drive is " 13896 "not enabled", target, lun); 13897 } 13898 } 13899 13900 /* 13901 * devid no longer needed 13902 */ 13903 ddi_devid_free(devid); 13904 break; 13905 } else if (rval == DDI_NOT_WELL_FORMED) { 13906 /* 13907 * return value of ddi_devid_scsi_encode equal to 13908 * DDI_NOT_WELL_FORMED means DEVID_RETRY, it worth 13909 * to retry inquiry page 0x83 and get GUID. 13910 */ 13911 NDBG20(("Not well formed devid, retry...")); 13912 delay(1 * drv_usectohz(1000000)); 13913 continue; 13914 } else { 13915 mptsas_log(mpt, CE_WARN, "!Encode devid failed for " 13916 "path target:%x, lun:%x", target, lun); 13917 rval = DDI_FAILURE; 13918 goto create_lun; 13919 } 13920 } 13921 13922 if (i == mptsas_inq83_retry_timeout) { 13923 mptsas_log(mpt, CE_WARN, "!Repeated page83 requests timeout " 13924 "for path target:%x, lun:%x", target, lun); 13925 } 13926 13927 rval = DDI_FAILURE; 13928 13929 create_lun: 13930 if ((guid != NULL) && (mpt->m_mpxio_enable == TRUE)) { 13931 rval = mptsas_create_virt_lun(pdip, sd_inq, guid, lun_dip, &pip, 13932 ptgt, lun); 13933 } 13934 if (rval != DDI_SUCCESS) { 13935 rval = mptsas_create_phys_lun(pdip, sd_inq, guid, lun_dip, 13936 ptgt, lun); 13937 13938 } 13939 out: 13940 if (guid != NULL) { 13941 /* 13942 * guid no longer needed 13943 */ 13944 ddi_devid_free_guid(guid); 13945 } 13946 if (inq83 != NULL) 13947 kmem_free(inq83, inq83_len1); 13948 return (rval); 13949 } 13950 13951 static int 13952 mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *inq, char *guid, 13953 dev_info_t **lun_dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, int lun) 13954 { 13955 int target; 13956 char *nodename = NULL; 13957 char **compatible = NULL; 13958 int ncompatible = 0; 13959 int mdi_rtn = MDI_FAILURE; 13960 int rval = DDI_FAILURE; 13961 char *old_guid = NULL; 13962 mptsas_t *mpt = DIP2MPT(pdip); 13963 char *lun_addr = NULL; 13964 char *wwn_str = NULL; 13965 char *attached_wwn_str = NULL; 13966 char *component = NULL; 13967 uint8_t phy = 0xFF; 13968 uint64_t sas_wwn; 13969 int64_t lun64 = 0; 13970 uint32_t devinfo; 13971 uint16_t dev_hdl; 13972 uint16_t pdev_hdl; 13973 uint64_t dev_sas_wwn; 13974 uint64_t pdev_sas_wwn; 13975 uint32_t pdev_info; 13976 uint8_t physport; 13977 uint8_t phy_id; 13978 uint32_t page_address; 13979 uint16_t bay_num, enclosure; 13980 char pdev_wwn_str[MPTSAS_WWN_STRLEN]; 13981 uint32_t dev_info; 13982 13983 mutex_enter(&mpt->m_mutex); 13984 target = ptgt->m_devhdl; 13985 sas_wwn = ptgt->m_sas_wwn; 13986 devinfo = ptgt->m_deviceinfo; 13987 phy = ptgt->m_phynum; 13988 mutex_exit(&mpt->m_mutex); 13989 13990 if (sas_wwn) { 13991 *pip = mptsas_find_path_addr(pdip, sas_wwn, lun); 13992 } else { 13993 *pip = mptsas_find_path_phy(pdip, phy); 13994 } 13995 13996 if (*pip != NULL) { 13997 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip; 13998 ASSERT(*lun_dip != NULL); 13999 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip, 14000 (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM), 14001 MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) { 14002 if (strncmp(guid, old_guid, strlen(guid)) == 0) { 14003 /* 14004 * Same path back online again. 14005 */ 14006 (void) ddi_prop_free(old_guid); 14007 if ((!MDI_PI_IS_ONLINE(*pip)) && 14008 (!MDI_PI_IS_STANDBY(*pip)) && 14009 (ptgt->m_tgt_unconfigured == 0)) { 14010 rval = mdi_pi_online(*pip, 0); 14011 mutex_enter(&mpt->m_mutex); 14012 ptgt->m_led_status = 0; 14013 (void) mptsas_flush_led_status(mpt, 14014 ptgt); 14015 mutex_exit(&mpt->m_mutex); 14016 } else { 14017 rval = DDI_SUCCESS; 14018 } 14019 if (rval != DDI_SUCCESS) { 14020 mptsas_log(mpt, CE_WARN, "path:target: " 14021 "%x, lun:%x online failed!", target, 14022 lun); 14023 *pip = NULL; 14024 *lun_dip = NULL; 14025 } 14026 return (rval); 14027 } else { 14028 /* 14029 * The GUID of the LUN has changed which maybe 14030 * because customer mapped another volume to the 14031 * same LUN. 14032 */ 14033 mptsas_log(mpt, CE_WARN, "The GUID of the " 14034 "target:%x, lun:%x was changed, maybe " 14035 "because someone mapped another volume " 14036 "to the same LUN", target, lun); 14037 (void) ddi_prop_free(old_guid); 14038 if (!MDI_PI_IS_OFFLINE(*pip)) { 14039 rval = mdi_pi_offline(*pip, 0); 14040 if (rval != MDI_SUCCESS) { 14041 mptsas_log(mpt, CE_WARN, "path:" 14042 "target:%x, lun:%x offline " 14043 "failed!", target, lun); 14044 *pip = NULL; 14045 *lun_dip = NULL; 14046 return (DDI_FAILURE); 14047 } 14048 } 14049 if (mdi_pi_free(*pip, 0) != MDI_SUCCESS) { 14050 mptsas_log(mpt, CE_WARN, "path:target:" 14051 "%x, lun:%x free failed!", target, 14052 lun); 14053 *pip = NULL; 14054 *lun_dip = NULL; 14055 return (DDI_FAILURE); 14056 } 14057 } 14058 } else { 14059 mptsas_log(mpt, CE_WARN, "Can't get client-guid " 14060 "property for path:target:%x, lun:%x", target, lun); 14061 *pip = NULL; 14062 *lun_dip = NULL; 14063 return (DDI_FAILURE); 14064 } 14065 } 14066 scsi_hba_nodename_compatible_get(inq, NULL, 14067 inq->inq_dtype, NULL, &nodename, &compatible, &ncompatible); 14068 14069 /* 14070 * if nodename can't be determined then print a message and skip it 14071 */ 14072 if (nodename == NULL) { 14073 mptsas_log(mpt, CE_WARN, "mptsas driver found no compatible " 14074 "driver for target%d lun %d dtype:0x%02x", target, lun, 14075 inq->inq_dtype); 14076 return (DDI_FAILURE); 14077 } 14078 14079 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP); 14080 /* The property is needed by MPAPI */ 14081 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn); 14082 14083 lun_addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14084 if (guid) { 14085 (void) sprintf(lun_addr, "w%s,%x", wwn_str, lun); 14086 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 14087 } else { 14088 (void) sprintf(lun_addr, "p%x,%x", phy, lun); 14089 (void) sprintf(wwn_str, "p%x", phy); 14090 } 14091 14092 mdi_rtn = mdi_pi_alloc_compatible(pdip, nodename, 14093 guid, lun_addr, compatible, ncompatible, 14094 0, pip); 14095 if (mdi_rtn == MDI_SUCCESS) { 14096 14097 if (mdi_prop_update_string(*pip, MDI_GUID, 14098 guid) != DDI_SUCCESS) { 14099 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14100 "create prop for target %d lun %d (MDI_GUID)", 14101 target, lun); 14102 mdi_rtn = MDI_FAILURE; 14103 goto virt_create_done; 14104 } 14105 14106 if (mdi_prop_update_int(*pip, LUN_PROP, 14107 lun) != DDI_SUCCESS) { 14108 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14109 "create prop for target %d lun %d (LUN_PROP)", 14110 target, lun); 14111 mdi_rtn = MDI_FAILURE; 14112 goto virt_create_done; 14113 } 14114 lun64 = (int64_t)lun; 14115 if (mdi_prop_update_int64(*pip, LUN64_PROP, 14116 lun64) != DDI_SUCCESS) { 14117 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14118 "create prop for target %d (LUN64_PROP)", 14119 target); 14120 mdi_rtn = MDI_FAILURE; 14121 goto virt_create_done; 14122 } 14123 if (mdi_prop_update_string_array(*pip, "compatible", 14124 compatible, ncompatible) != 14125 DDI_PROP_SUCCESS) { 14126 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14127 "create prop for target %d lun %d (COMPATIBLE)", 14128 target, lun); 14129 mdi_rtn = MDI_FAILURE; 14130 goto virt_create_done; 14131 } 14132 if (sas_wwn && (mdi_prop_update_string(*pip, 14133 SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != DDI_PROP_SUCCESS)) { 14134 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14135 "create prop for target %d lun %d " 14136 "(target-port)", target, lun); 14137 mdi_rtn = MDI_FAILURE; 14138 goto virt_create_done; 14139 } else if ((sas_wwn == 0) && (mdi_prop_update_int(*pip, 14140 "sata-phy", phy) != DDI_PROP_SUCCESS)) { 14141 /* 14142 * Direct attached SATA device without DeviceName 14143 */ 14144 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14145 "create prop for SAS target %d lun %d " 14146 "(sata-phy)", target, lun); 14147 mdi_rtn = MDI_FAILURE; 14148 goto virt_create_done; 14149 } 14150 mutex_enter(&mpt->m_mutex); 14151 14152 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14153 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14154 (uint32_t)ptgt->m_devhdl; 14155 rval = mptsas_get_sas_device_page0(mpt, page_address, 14156 &dev_hdl, &dev_sas_wwn, &dev_info, &physport, 14157 &phy_id, &pdev_hdl, &bay_num, &enclosure); 14158 if (rval != DDI_SUCCESS) { 14159 mutex_exit(&mpt->m_mutex); 14160 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 14161 "parent device for handle %d", page_address); 14162 mdi_rtn = MDI_FAILURE; 14163 goto virt_create_done; 14164 } 14165 14166 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14167 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl; 14168 rval = mptsas_get_sas_device_page0(mpt, page_address, 14169 &dev_hdl, &pdev_sas_wwn, &pdev_info, &physport, 14170 &phy_id, &pdev_hdl, &bay_num, &enclosure); 14171 if (rval != DDI_SUCCESS) { 14172 mutex_exit(&mpt->m_mutex); 14173 mptsas_log(mpt, CE_WARN, "mptsas unable to get" 14174 "device info for handle %d", page_address); 14175 mdi_rtn = MDI_FAILURE; 14176 goto virt_create_done; 14177 } 14178 14179 mutex_exit(&mpt->m_mutex); 14180 14181 /* 14182 * If this device direct attached to the controller 14183 * set the attached-port to the base wwid 14184 */ 14185 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 14186 != DEVINFO_DIRECT_ATTACHED) { 14187 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 14188 pdev_sas_wwn); 14189 } else { 14190 /* 14191 * Update the iport's attached-port to guid 14192 */ 14193 if (sas_wwn == 0) { 14194 (void) sprintf(wwn_str, "p%x", phy); 14195 } else { 14196 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 14197 } 14198 if (ddi_prop_update_string(DDI_DEV_T_NONE, 14199 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 14200 DDI_PROP_SUCCESS) { 14201 mptsas_log(mpt, CE_WARN, 14202 "mptsas unable to create " 14203 "property for iport target-port" 14204 " %s (sas_wwn)", 14205 wwn_str); 14206 mdi_rtn = MDI_FAILURE; 14207 goto virt_create_done; 14208 } 14209 14210 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 14211 mpt->un.m_base_wwid); 14212 } 14213 14214 if (mdi_prop_update_string(*pip, 14215 SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) != 14216 DDI_PROP_SUCCESS) { 14217 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14218 "property for iport attached-port %s (sas_wwn)", 14219 attached_wwn_str); 14220 mdi_rtn = MDI_FAILURE; 14221 goto virt_create_done; 14222 } 14223 14224 14225 if (inq->inq_dtype == 0) { 14226 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 14227 /* 14228 * set obp path for pathinfo 14229 */ 14230 (void) snprintf(component, MAXPATHLEN, 14231 "disk@%s", lun_addr); 14232 14233 if (mdi_pi_pathname_obp_set(*pip, component) != 14234 DDI_SUCCESS) { 14235 mptsas_log(mpt, CE_WARN, "mpt_sas driver " 14236 "unable to set obp-path for object %s", 14237 component); 14238 mdi_rtn = MDI_FAILURE; 14239 goto virt_create_done; 14240 } 14241 } 14242 14243 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip; 14244 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 14245 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 14246 if ((ndi_prop_update_int(DDI_DEV_T_NONE, *lun_dip, 14247 "pm-capable", 1)) != 14248 DDI_PROP_SUCCESS) { 14249 mptsas_log(mpt, CE_WARN, "mptsas driver" 14250 "failed to create pm-capable " 14251 "property, target %d", target); 14252 mdi_rtn = MDI_FAILURE; 14253 goto virt_create_done; 14254 } 14255 } 14256 /* 14257 * Create the phy-num property 14258 */ 14259 if (mdi_prop_update_int(*pip, "phy-num", 14260 ptgt->m_phynum) != DDI_SUCCESS) { 14261 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14262 "create phy-num property for target %d lun %d", 14263 target, lun); 14264 mdi_rtn = MDI_FAILURE; 14265 goto virt_create_done; 14266 } 14267 NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr)); 14268 mdi_rtn = mdi_pi_online(*pip, 0); 14269 if (mdi_rtn == MDI_SUCCESS) { 14270 mutex_enter(&mpt->m_mutex); 14271 ptgt->m_led_status = 0; 14272 (void) mptsas_flush_led_status(mpt, ptgt); 14273 mutex_exit(&mpt->m_mutex); 14274 } 14275 if (mdi_rtn == MDI_NOT_SUPPORTED) { 14276 mdi_rtn = MDI_FAILURE; 14277 } 14278 virt_create_done: 14279 if (*pip && mdi_rtn != MDI_SUCCESS) { 14280 (void) mdi_pi_free(*pip, 0); 14281 *pip = NULL; 14282 *lun_dip = NULL; 14283 } 14284 } 14285 14286 scsi_hba_nodename_compatible_free(nodename, compatible); 14287 if (lun_addr != NULL) { 14288 kmem_free(lun_addr, SCSI_MAXNAMELEN); 14289 } 14290 if (wwn_str != NULL) { 14291 kmem_free(wwn_str, MPTSAS_WWN_STRLEN); 14292 } 14293 if (component != NULL) { 14294 kmem_free(component, MAXPATHLEN); 14295 } 14296 14297 return ((mdi_rtn == MDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 14298 } 14299 14300 static int 14301 mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *inq, 14302 char *guid, dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun) 14303 { 14304 int target; 14305 int rval; 14306 int ndi_rtn = NDI_FAILURE; 14307 uint64_t be_sas_wwn; 14308 char *nodename = NULL; 14309 char **compatible = NULL; 14310 int ncompatible = 0; 14311 int instance = 0; 14312 mptsas_t *mpt = DIP2MPT(pdip); 14313 char *wwn_str = NULL; 14314 char *component = NULL; 14315 char *attached_wwn_str = NULL; 14316 uint8_t phy = 0xFF; 14317 uint64_t sas_wwn; 14318 uint32_t devinfo; 14319 uint16_t dev_hdl; 14320 uint16_t pdev_hdl; 14321 uint64_t pdev_sas_wwn; 14322 uint64_t dev_sas_wwn; 14323 uint32_t pdev_info; 14324 uint8_t physport; 14325 uint8_t phy_id; 14326 uint32_t page_address; 14327 uint16_t bay_num, enclosure; 14328 char pdev_wwn_str[MPTSAS_WWN_STRLEN]; 14329 uint32_t dev_info; 14330 int64_t lun64 = 0; 14331 14332 mutex_enter(&mpt->m_mutex); 14333 target = ptgt->m_devhdl; 14334 sas_wwn = ptgt->m_sas_wwn; 14335 devinfo = ptgt->m_deviceinfo; 14336 phy = ptgt->m_phynum; 14337 mutex_exit(&mpt->m_mutex); 14338 14339 /* 14340 * generate compatible property with binding-set "mpt" 14341 */ 14342 scsi_hba_nodename_compatible_get(inq, NULL, inq->inq_dtype, NULL, 14343 &nodename, &compatible, &ncompatible); 14344 14345 /* 14346 * if nodename can't be determined then print a message and skip it 14347 */ 14348 if (nodename == NULL) { 14349 mptsas_log(mpt, CE_WARN, "mptsas found no compatible driver " 14350 "for target %d lun %d", target, lun); 14351 return (DDI_FAILURE); 14352 } 14353 14354 ndi_rtn = ndi_devi_alloc(pdip, nodename, 14355 DEVI_SID_NODEID, lun_dip); 14356 14357 /* 14358 * if lun alloc success, set props 14359 */ 14360 if (ndi_rtn == NDI_SUCCESS) { 14361 14362 if (ndi_prop_update_int(DDI_DEV_T_NONE, 14363 *lun_dip, LUN_PROP, lun) != 14364 DDI_PROP_SUCCESS) { 14365 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14366 "property for target %d lun %d (LUN_PROP)", 14367 target, lun); 14368 ndi_rtn = NDI_FAILURE; 14369 goto phys_create_done; 14370 } 14371 14372 lun64 = (int64_t)lun; 14373 if (ndi_prop_update_int64(DDI_DEV_T_NONE, 14374 *lun_dip, LUN64_PROP, lun64) != 14375 DDI_PROP_SUCCESS) { 14376 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14377 "property for target %d lun64 %d (LUN64_PROP)", 14378 target, lun); 14379 ndi_rtn = NDI_FAILURE; 14380 goto phys_create_done; 14381 } 14382 if (ndi_prop_update_string_array(DDI_DEV_T_NONE, 14383 *lun_dip, "compatible", compatible, ncompatible) 14384 != DDI_PROP_SUCCESS) { 14385 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14386 "property for target %d lun %d (COMPATIBLE)", 14387 target, lun); 14388 ndi_rtn = NDI_FAILURE; 14389 goto phys_create_done; 14390 } 14391 14392 /* 14393 * We need the SAS WWN for non-multipath devices, so 14394 * we'll use the same property as that multipathing 14395 * devices need to present for MPAPI. If we don't have 14396 * a WWN (e.g. parallel SCSI), don't create the prop. 14397 */ 14398 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP); 14399 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 14400 if (sas_wwn && ndi_prop_update_string(DDI_DEV_T_NONE, 14401 *lun_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) 14402 != DDI_PROP_SUCCESS) { 14403 mptsas_log(mpt, CE_WARN, "mptsas unable to " 14404 "create property for SAS target %d lun %d " 14405 "(target-port)", target, lun); 14406 ndi_rtn = NDI_FAILURE; 14407 goto phys_create_done; 14408 } 14409 14410 be_sas_wwn = BE_64(sas_wwn); 14411 if (sas_wwn && ndi_prop_update_byte_array( 14412 DDI_DEV_T_NONE, *lun_dip, "port-wwn", 14413 (uchar_t *)&be_sas_wwn, 8) != DDI_PROP_SUCCESS) { 14414 mptsas_log(mpt, CE_WARN, "mptsas unable to " 14415 "create property for SAS target %d lun %d " 14416 "(port-wwn)", target, lun); 14417 ndi_rtn = NDI_FAILURE; 14418 goto phys_create_done; 14419 } else if ((sas_wwn == 0) && (ndi_prop_update_int( 14420 DDI_DEV_T_NONE, *lun_dip, "sata-phy", phy) != 14421 DDI_PROP_SUCCESS)) { 14422 /* 14423 * Direct attached SATA device without DeviceName 14424 */ 14425 mptsas_log(mpt, CE_WARN, "mptsas unable to " 14426 "create property for SAS target %d lun %d " 14427 "(sata-phy)", target, lun); 14428 ndi_rtn = NDI_FAILURE; 14429 goto phys_create_done; 14430 } 14431 14432 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 14433 *lun_dip, SAS_PROP) != DDI_PROP_SUCCESS) { 14434 mptsas_log(mpt, CE_WARN, "mptsas unable to" 14435 "create property for SAS target %d lun %d" 14436 " (SAS_PROP)", target, lun); 14437 ndi_rtn = NDI_FAILURE; 14438 goto phys_create_done; 14439 } 14440 if (guid && (ndi_prop_update_string(DDI_DEV_T_NONE, 14441 *lun_dip, NDI_GUID, guid) != DDI_SUCCESS)) { 14442 mptsas_log(mpt, CE_WARN, "mptsas unable " 14443 "to create guid property for target %d " 14444 "lun %d", target, lun); 14445 ndi_rtn = NDI_FAILURE; 14446 goto phys_create_done; 14447 } 14448 14449 /* 14450 * The following code is to set properties for SM-HBA support, 14451 * it doesn't apply to RAID volumes 14452 */ 14453 if (ptgt->m_phymask == 0) 14454 goto phys_raid_lun; 14455 14456 mutex_enter(&mpt->m_mutex); 14457 14458 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14459 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14460 (uint32_t)ptgt->m_devhdl; 14461 rval = mptsas_get_sas_device_page0(mpt, page_address, 14462 &dev_hdl, &dev_sas_wwn, &dev_info, 14463 &physport, &phy_id, &pdev_hdl, 14464 &bay_num, &enclosure); 14465 if (rval != DDI_SUCCESS) { 14466 mutex_exit(&mpt->m_mutex); 14467 mptsas_log(mpt, CE_WARN, "mptsas unable to get" 14468 "parent device for handle %d.", page_address); 14469 ndi_rtn = NDI_FAILURE; 14470 goto phys_create_done; 14471 } 14472 14473 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14474 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl; 14475 rval = mptsas_get_sas_device_page0(mpt, page_address, 14476 &dev_hdl, &pdev_sas_wwn, &pdev_info, 14477 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure); 14478 if (rval != DDI_SUCCESS) { 14479 mutex_exit(&mpt->m_mutex); 14480 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14481 "device for handle %d.", page_address); 14482 ndi_rtn = NDI_FAILURE; 14483 goto phys_create_done; 14484 } 14485 14486 mutex_exit(&mpt->m_mutex); 14487 14488 /* 14489 * If this device direct attached to the controller 14490 * set the attached-port to the base wwid 14491 */ 14492 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 14493 != DEVINFO_DIRECT_ATTACHED) { 14494 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 14495 pdev_sas_wwn); 14496 } else { 14497 /* 14498 * Update the iport's attached-port to guid 14499 */ 14500 if (sas_wwn == 0) { 14501 (void) sprintf(wwn_str, "p%x", phy); 14502 } else { 14503 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 14504 } 14505 if (ddi_prop_update_string(DDI_DEV_T_NONE, 14506 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 14507 DDI_PROP_SUCCESS) { 14508 mptsas_log(mpt, CE_WARN, 14509 "mptsas unable to create " 14510 "property for iport target-port" 14511 " %s (sas_wwn)", 14512 wwn_str); 14513 ndi_rtn = NDI_FAILURE; 14514 goto phys_create_done; 14515 } 14516 14517 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 14518 mpt->un.m_base_wwid); 14519 } 14520 14521 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14522 *lun_dip, SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) != 14523 DDI_PROP_SUCCESS) { 14524 mptsas_log(mpt, CE_WARN, 14525 "mptsas unable to create " 14526 "property for iport attached-port %s (sas_wwn)", 14527 attached_wwn_str); 14528 ndi_rtn = NDI_FAILURE; 14529 goto phys_create_done; 14530 } 14531 14532 if (IS_SATA_DEVICE(dev_info)) { 14533 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14534 *lun_dip, MPTSAS_VARIANT, "sata") != 14535 DDI_PROP_SUCCESS) { 14536 mptsas_log(mpt, CE_WARN, 14537 "mptsas unable to create " 14538 "property for device variant "); 14539 ndi_rtn = NDI_FAILURE; 14540 goto phys_create_done; 14541 } 14542 } 14543 14544 if (IS_ATAPI_DEVICE(dev_info)) { 14545 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14546 *lun_dip, MPTSAS_VARIANT, "atapi") != 14547 DDI_PROP_SUCCESS) { 14548 mptsas_log(mpt, CE_WARN, 14549 "mptsas unable to create " 14550 "property for device variant "); 14551 ndi_rtn = NDI_FAILURE; 14552 goto phys_create_done; 14553 } 14554 } 14555 14556 phys_raid_lun: 14557 /* 14558 * if this is a SAS controller, and the target is a SATA 14559 * drive, set the 'pm-capable' property for sd and if on 14560 * an OPL platform, also check if this is an ATAPI 14561 * device. 14562 */ 14563 instance = ddi_get_instance(mpt->m_dip); 14564 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 14565 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 14566 NDBG2(("mptsas%d: creating pm-capable property, " 14567 "target %d", instance, target)); 14568 14569 if ((ndi_prop_update_int(DDI_DEV_T_NONE, 14570 *lun_dip, "pm-capable", 1)) != 14571 DDI_PROP_SUCCESS) { 14572 mptsas_log(mpt, CE_WARN, "mptsas " 14573 "failed to create pm-capable " 14574 "property, target %d", target); 14575 ndi_rtn = NDI_FAILURE; 14576 goto phys_create_done; 14577 } 14578 14579 } 14580 14581 if ((inq->inq_dtype == 0) || (inq->inq_dtype == 5)) { 14582 /* 14583 * add 'obp-path' properties for devinfo 14584 */ 14585 bzero(wwn_str, sizeof (wwn_str)); 14586 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn); 14587 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 14588 if (guid) { 14589 (void) snprintf(component, MAXPATHLEN, 14590 "disk@w%s,%x", wwn_str, lun); 14591 } else { 14592 (void) snprintf(component, MAXPATHLEN, 14593 "disk@p%x,%x", phy, lun); 14594 } 14595 if (ddi_pathname_obp_set(*lun_dip, component) 14596 != DDI_SUCCESS) { 14597 mptsas_log(mpt, CE_WARN, "mpt_sas driver " 14598 "unable to set obp-path for SAS " 14599 "object %s", component); 14600 ndi_rtn = NDI_FAILURE; 14601 goto phys_create_done; 14602 } 14603 } 14604 /* 14605 * Create the phy-num property for non-raid disk 14606 */ 14607 if (ptgt->m_phymask != 0) { 14608 if (ndi_prop_update_int(DDI_DEV_T_NONE, 14609 *lun_dip, "phy-num", ptgt->m_phynum) != 14610 DDI_PROP_SUCCESS) { 14611 mptsas_log(mpt, CE_WARN, "mptsas driver " 14612 "failed to create phy-num property for " 14613 "target %d", target); 14614 ndi_rtn = NDI_FAILURE; 14615 goto phys_create_done; 14616 } 14617 } 14618 phys_create_done: 14619 /* 14620 * If props were setup ok, online the lun 14621 */ 14622 if (ndi_rtn == NDI_SUCCESS) { 14623 /* 14624 * Try to online the new node 14625 */ 14626 ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH); 14627 } 14628 if (ndi_rtn == NDI_SUCCESS) { 14629 mutex_enter(&mpt->m_mutex); 14630 ptgt->m_led_status = 0; 14631 (void) mptsas_flush_led_status(mpt, ptgt); 14632 mutex_exit(&mpt->m_mutex); 14633 } 14634 14635 /* 14636 * If success set rtn flag, else unwire alloc'd lun 14637 */ 14638 if (ndi_rtn != NDI_SUCCESS) { 14639 NDBG12(("mptsas driver unable to online " 14640 "target %d lun %d", target, lun)); 14641 ndi_prop_remove_all(*lun_dip); 14642 (void) ndi_devi_free(*lun_dip); 14643 *lun_dip = NULL; 14644 } 14645 } 14646 14647 scsi_hba_nodename_compatible_free(nodename, compatible); 14648 14649 if (wwn_str != NULL) { 14650 kmem_free(wwn_str, MPTSAS_WWN_STRLEN); 14651 } 14652 if (component != NULL) { 14653 kmem_free(component, MAXPATHLEN); 14654 } 14655 14656 14657 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 14658 } 14659 14660 static int 14661 mptsas_probe_smp(dev_info_t *pdip, uint64_t wwn) 14662 { 14663 mptsas_t *mpt = DIP2MPT(pdip); 14664 struct smp_device smp_sd; 14665 14666 /* XXX An HBA driver should not be allocating an smp_device. */ 14667 bzero(&smp_sd, sizeof (struct smp_device)); 14668 smp_sd.smp_sd_address.smp_a_hba_tran = mpt->m_smptran; 14669 bcopy(&wwn, smp_sd.smp_sd_address.smp_a_wwn, SAS_WWN_BYTE_SIZE); 14670 14671 if (smp_probe(&smp_sd) != DDI_PROBE_SUCCESS) 14672 return (NDI_FAILURE); 14673 return (NDI_SUCCESS); 14674 } 14675 14676 static int 14677 mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, dev_info_t **smp_dip) 14678 { 14679 mptsas_t *mpt = DIP2MPT(pdip); 14680 mptsas_smp_t *psmp = NULL; 14681 int rval; 14682 int phymask; 14683 14684 /* 14685 * Get the physical port associated to the iport 14686 * PHYMASK TODO 14687 */ 14688 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 14689 "phymask", 0); 14690 /* 14691 * Find the smp node in hash table with specified sas address and 14692 * physical port 14693 */ 14694 psmp = mptsas_wwid_to_psmp(mpt, phymask, sas_wwn); 14695 if (psmp == NULL) { 14696 return (DDI_FAILURE); 14697 } 14698 14699 rval = mptsas_online_smp(pdip, psmp, smp_dip); 14700 14701 return (rval); 14702 } 14703 14704 static int 14705 mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 14706 dev_info_t **smp_dip) 14707 { 14708 char wwn_str[MPTSAS_WWN_STRLEN]; 14709 char attached_wwn_str[MPTSAS_WWN_STRLEN]; 14710 int ndi_rtn = NDI_FAILURE; 14711 int rval = 0; 14712 mptsas_smp_t dev_info; 14713 uint32_t page_address; 14714 mptsas_t *mpt = DIP2MPT(pdip); 14715 uint16_t dev_hdl; 14716 uint64_t sas_wwn; 14717 uint64_t smp_sas_wwn; 14718 uint8_t physport; 14719 uint8_t phy_id; 14720 uint16_t pdev_hdl; 14721 uint8_t numphys = 0; 14722 uint16_t i = 0; 14723 char phymask[MPTSAS_MAX_PHYS]; 14724 char *iport = NULL; 14725 mptsas_phymask_t phy_mask = 0; 14726 uint16_t attached_devhdl; 14727 uint16_t bay_num, enclosure; 14728 14729 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr); 14730 14731 /* 14732 * Probe smp device, prevent the node of removed device from being 14733 * configured succesfully 14734 */ 14735 if (mptsas_probe_smp(pdip, smp_node->m_sasaddr) != NDI_SUCCESS) { 14736 return (DDI_FAILURE); 14737 } 14738 14739 if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) { 14740 return (DDI_SUCCESS); 14741 } 14742 14743 ndi_rtn = ndi_devi_alloc(pdip, "smp", DEVI_SID_NODEID, smp_dip); 14744 14745 /* 14746 * if lun alloc success, set props 14747 */ 14748 if (ndi_rtn == NDI_SUCCESS) { 14749 /* 14750 * Set the flavor of the child to be SMP flavored 14751 */ 14752 ndi_flavor_set(*smp_dip, SCSA_FLAVOR_SMP); 14753 14754 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14755 *smp_dip, SMP_WWN, wwn_str) != 14756 DDI_PROP_SUCCESS) { 14757 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14758 "property for smp device %s (sas_wwn)", 14759 wwn_str); 14760 ndi_rtn = NDI_FAILURE; 14761 goto smp_create_done; 14762 } 14763 (void) sprintf(wwn_str, "w%"PRIx64, smp_node->m_sasaddr); 14764 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14765 *smp_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != 14766 DDI_PROP_SUCCESS) { 14767 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14768 "property for iport target-port %s (sas_wwn)", 14769 wwn_str); 14770 ndi_rtn = NDI_FAILURE; 14771 goto smp_create_done; 14772 } 14773 14774 mutex_enter(&mpt->m_mutex); 14775 14776 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL & 14777 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | smp_node->m_devhdl; 14778 rval = mptsas_get_sas_expander_page0(mpt, page_address, 14779 &dev_info); 14780 if (rval != DDI_SUCCESS) { 14781 mutex_exit(&mpt->m_mutex); 14782 mptsas_log(mpt, CE_WARN, 14783 "mptsas unable to get expander " 14784 "parent device info for %x", page_address); 14785 ndi_rtn = NDI_FAILURE; 14786 goto smp_create_done; 14787 } 14788 14789 smp_node->m_pdevhdl = dev_info.m_pdevhdl; 14790 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14791 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14792 (uint32_t)dev_info.m_pdevhdl; 14793 rval = mptsas_get_sas_device_page0(mpt, page_address, 14794 &dev_hdl, &sas_wwn, &smp_node->m_pdevinfo, 14795 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure); 14796 if (rval != DDI_SUCCESS) { 14797 mutex_exit(&mpt->m_mutex); 14798 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 14799 "device info for %x", page_address); 14800 ndi_rtn = NDI_FAILURE; 14801 goto smp_create_done; 14802 } 14803 14804 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14805 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14806 (uint32_t)dev_info.m_devhdl; 14807 rval = mptsas_get_sas_device_page0(mpt, page_address, 14808 &dev_hdl, &smp_sas_wwn, &smp_node->m_deviceinfo, 14809 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure); 14810 if (rval != DDI_SUCCESS) { 14811 mutex_exit(&mpt->m_mutex); 14812 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 14813 "device info for %x", page_address); 14814 ndi_rtn = NDI_FAILURE; 14815 goto smp_create_done; 14816 } 14817 mutex_exit(&mpt->m_mutex); 14818 14819 /* 14820 * If this smp direct attached to the controller 14821 * set the attached-port to the base wwid 14822 */ 14823 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 14824 != DEVINFO_DIRECT_ATTACHED) { 14825 (void) sprintf(attached_wwn_str, "w%016"PRIx64, 14826 sas_wwn); 14827 } else { 14828 (void) sprintf(attached_wwn_str, "w%016"PRIx64, 14829 mpt->un.m_base_wwid); 14830 } 14831 14832 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14833 *smp_dip, SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwn_str) != 14834 DDI_PROP_SUCCESS) { 14835 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14836 "property for smp attached-port %s (sas_wwn)", 14837 attached_wwn_str); 14838 ndi_rtn = NDI_FAILURE; 14839 goto smp_create_done; 14840 } 14841 14842 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 14843 *smp_dip, SMP_PROP) != DDI_PROP_SUCCESS) { 14844 mptsas_log(mpt, CE_WARN, "mptsas unable to " 14845 "create property for SMP %s (SMP_PROP) ", 14846 wwn_str); 14847 ndi_rtn = NDI_FAILURE; 14848 goto smp_create_done; 14849 } 14850 14851 /* 14852 * check the smp to see whether it direct 14853 * attached to the controller 14854 */ 14855 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 14856 != DEVINFO_DIRECT_ATTACHED) { 14857 goto smp_create_done; 14858 } 14859 numphys = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 14860 DDI_PROP_DONTPASS, MPTSAS_NUM_PHYS, -1); 14861 if (numphys > 0) { 14862 goto smp_create_done; 14863 } 14864 /* 14865 * this iport is an old iport, we need to 14866 * reconfig the props for it. 14867 */ 14868 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip, 14869 MPTSAS_VIRTUAL_PORT, 0) != 14870 DDI_PROP_SUCCESS) { 14871 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 14872 MPTSAS_VIRTUAL_PORT); 14873 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 14874 "prop update failed"); 14875 goto smp_create_done; 14876 } 14877 14878 mutex_enter(&mpt->m_mutex); 14879 numphys = 0; 14880 iport = ddi_get_name_addr(pdip); 14881 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 14882 bzero(phymask, sizeof (phymask)); 14883 (void) sprintf(phymask, 14884 "%x", mpt->m_phy_info[i].phy_mask); 14885 if (strcmp(phymask, iport) == 0) { 14886 phy_mask = mpt->m_phy_info[i].phy_mask; 14887 break; 14888 } 14889 } 14890 14891 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 14892 if ((phy_mask >> i) & 0x01) { 14893 numphys++; 14894 } 14895 } 14896 /* 14897 * Update PHY info for smhba 14898 */ 14899 if (mptsas_smhba_phy_init(mpt)) { 14900 mutex_exit(&mpt->m_mutex); 14901 mptsas_log(mpt, CE_WARN, "mptsas phy update " 14902 "failed"); 14903 goto smp_create_done; 14904 } 14905 mutex_exit(&mpt->m_mutex); 14906 14907 mptsas_smhba_set_all_phy_props(mpt, pdip, numphys, phy_mask, 14908 &attached_devhdl); 14909 14910 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip, 14911 MPTSAS_NUM_PHYS, numphys) != 14912 DDI_PROP_SUCCESS) { 14913 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 14914 MPTSAS_NUM_PHYS); 14915 mptsas_log(mpt, CE_WARN, "mptsas update " 14916 "num phys props failed"); 14917 goto smp_create_done; 14918 } 14919 /* 14920 * Add parent's props for SMHBA support 14921 */ 14922 if (ddi_prop_update_string(DDI_DEV_T_NONE, pdip, 14923 SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 14924 DDI_PROP_SUCCESS) { 14925 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 14926 SCSI_ADDR_PROP_ATTACHED_PORT); 14927 mptsas_log(mpt, CE_WARN, "mptsas update iport" 14928 "attached-port failed"); 14929 goto smp_create_done; 14930 } 14931 14932 smp_create_done: 14933 /* 14934 * If props were setup ok, online the lun 14935 */ 14936 if (ndi_rtn == NDI_SUCCESS) { 14937 /* 14938 * Try to online the new node 14939 */ 14940 ndi_rtn = ndi_devi_online(*smp_dip, NDI_ONLINE_ATTACH); 14941 } 14942 14943 /* 14944 * If success set rtn flag, else unwire alloc'd lun 14945 */ 14946 if (ndi_rtn != NDI_SUCCESS) { 14947 NDBG12(("mptsas unable to online " 14948 "SMP target %s", wwn_str)); 14949 ndi_prop_remove_all(*smp_dip); 14950 (void) ndi_devi_free(*smp_dip); 14951 } 14952 } 14953 14954 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 14955 } 14956 14957 /* smp transport routine */ 14958 static int mptsas_smp_start(struct smp_pkt *smp_pkt) 14959 { 14960 uint64_t wwn; 14961 Mpi2SmpPassthroughRequest_t req; 14962 Mpi2SmpPassthroughReply_t rep; 14963 uint32_t direction = 0; 14964 mptsas_t *mpt; 14965 int ret; 14966 uint64_t tmp64; 14967 14968 mpt = (mptsas_t *)smp_pkt->smp_pkt_address-> 14969 smp_a_hba_tran->smp_tran_hba_private; 14970 14971 bcopy(smp_pkt->smp_pkt_address->smp_a_wwn, &wwn, SAS_WWN_BYTE_SIZE); 14972 /* 14973 * Need to compose a SMP request message 14974 * and call mptsas_do_passthru() function 14975 */ 14976 bzero(&req, sizeof (req)); 14977 bzero(&rep, sizeof (rep)); 14978 req.PassthroughFlags = 0; 14979 req.PhysicalPort = 0xff; 14980 req.ChainOffset = 0; 14981 req.Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 14982 14983 if ((smp_pkt->smp_pkt_reqsize & 0xffff0000ul) != 0) { 14984 smp_pkt->smp_pkt_reason = ERANGE; 14985 return (DDI_FAILURE); 14986 } 14987 req.RequestDataLength = LE_16((uint16_t)(smp_pkt->smp_pkt_reqsize - 4)); 14988 14989 req.MsgFlags = 0; 14990 tmp64 = LE_64(wwn); 14991 bcopy(&tmp64, &req.SASAddress, SAS_WWN_BYTE_SIZE); 14992 if (smp_pkt->smp_pkt_rspsize > 0) { 14993 direction |= MPTSAS_PASS_THRU_DIRECTION_READ; 14994 } 14995 if (smp_pkt->smp_pkt_reqsize > 0) { 14996 direction |= MPTSAS_PASS_THRU_DIRECTION_WRITE; 14997 } 14998 14999 mutex_enter(&mpt->m_mutex); 15000 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, 15001 (uint8_t *)smp_pkt->smp_pkt_rsp, 15002 offsetof(Mpi2SmpPassthroughRequest_t, SGL), sizeof (rep), 15003 smp_pkt->smp_pkt_rspsize - 4, direction, 15004 (uint8_t *)smp_pkt->smp_pkt_req, smp_pkt->smp_pkt_reqsize - 4, 15005 smp_pkt->smp_pkt_timeout, FKIOCTL); 15006 mutex_exit(&mpt->m_mutex); 15007 if (ret != 0) { 15008 cmn_err(CE_WARN, "smp_start do passthru error %d", ret); 15009 smp_pkt->smp_pkt_reason = (uchar_t)(ret); 15010 return (DDI_FAILURE); 15011 } 15012 /* do passthrough success, check the smp status */ 15013 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 15014 switch (LE_16(rep.IOCStatus)) { 15015 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 15016 smp_pkt->smp_pkt_reason = ENODEV; 15017 break; 15018 case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN: 15019 smp_pkt->smp_pkt_reason = EOVERFLOW; 15020 break; 15021 case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED: 15022 smp_pkt->smp_pkt_reason = EIO; 15023 break; 15024 default: 15025 mptsas_log(mpt, CE_NOTE, "smp_start: get unknown ioc" 15026 "status:%x", LE_16(rep.IOCStatus)); 15027 smp_pkt->smp_pkt_reason = EIO; 15028 break; 15029 } 15030 return (DDI_FAILURE); 15031 } 15032 if (rep.SASStatus != MPI2_SASSTATUS_SUCCESS) { 15033 mptsas_log(mpt, CE_NOTE, "smp_start: get error SAS status:%x", 15034 rep.SASStatus); 15035 smp_pkt->smp_pkt_reason = EIO; 15036 return (DDI_FAILURE); 15037 } 15038 15039 return (DDI_SUCCESS); 15040 } 15041 15042 /* 15043 * If we didn't get a match, we need to get sas page0 for each device, and 15044 * untill we get a match. If failed, return NULL 15045 */ 15046 static mptsas_target_t * 15047 mptsas_phy_to_tgt(mptsas_t *mpt, int phymask, uint8_t phy) 15048 { 15049 int i, j = 0; 15050 int rval = 0; 15051 uint16_t cur_handle; 15052 uint32_t page_address; 15053 mptsas_target_t *ptgt = NULL; 15054 15055 /* 15056 * PHY named device must be direct attached and attaches to 15057 * narrow port, if the iport is not parent of the device which 15058 * we are looking for. 15059 */ 15060 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 15061 if ((1 << i) & phymask) 15062 j++; 15063 } 15064 15065 if (j > 1) 15066 return (NULL); 15067 15068 /* 15069 * Must be a narrow port and single device attached to the narrow port 15070 * So the physical port num of device which is equal to the iport's 15071 * port num is the device what we are looking for. 15072 */ 15073 15074 if (mpt->m_phy_info[phy].phy_mask != phymask) 15075 return (NULL); 15076 15077 mutex_enter(&mpt->m_mutex); 15078 15079 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 15080 MPTSAS_HASH_FIRST); 15081 while (ptgt != NULL) { 15082 if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) { 15083 mutex_exit(&mpt->m_mutex); 15084 return (ptgt); 15085 } 15086 15087 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 15088 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 15089 } 15090 15091 if (mpt->m_done_traverse_dev) { 15092 mutex_exit(&mpt->m_mutex); 15093 return (NULL); 15094 } 15095 15096 /* If didn't get a match, come here */ 15097 cur_handle = mpt->m_dev_handle; 15098 for (; ; ) { 15099 ptgt = NULL; 15100 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 15101 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)cur_handle; 15102 rval = mptsas_get_target_device_info(mpt, page_address, 15103 &cur_handle, &ptgt); 15104 if ((rval == DEV_INFO_FAIL_PAGE0) || 15105 (rval == DEV_INFO_FAIL_ALLOC)) { 15106 break; 15107 } 15108 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) || 15109 (rval == DEV_INFO_PHYS_DISK)) { 15110 continue; 15111 } 15112 mpt->m_dev_handle = cur_handle; 15113 15114 if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) { 15115 break; 15116 } 15117 } 15118 15119 mutex_exit(&mpt->m_mutex); 15120 return (ptgt); 15121 } 15122 15123 /* 15124 * The ptgt->m_sas_wwn contains the wwid for each disk. 15125 * For Raid volumes, we need to check m_raidvol[x].m_raidwwid 15126 * If we didn't get a match, we need to get sas page0 for each device, and 15127 * untill we get a match 15128 * If failed, return NULL 15129 */ 15130 static mptsas_target_t * 15131 mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask, uint64_t wwid) 15132 { 15133 int rval = 0; 15134 uint16_t cur_handle; 15135 uint32_t page_address; 15136 mptsas_target_t *tmp_tgt = NULL; 15137 15138 mutex_enter(&mpt->m_mutex); 15139 tmp_tgt = (struct mptsas_target *)mptsas_hash_search( 15140 &mpt->m_active->m_tgttbl, wwid, phymask); 15141 if (tmp_tgt != NULL) { 15142 mutex_exit(&mpt->m_mutex); 15143 return (tmp_tgt); 15144 } 15145 15146 if (phymask == 0) { 15147 /* 15148 * It's IR volume 15149 */ 15150 rval = mptsas_get_raid_info(mpt); 15151 if (rval) { 15152 tmp_tgt = (struct mptsas_target *)mptsas_hash_search( 15153 &mpt->m_active->m_tgttbl, wwid, phymask); 15154 } 15155 mutex_exit(&mpt->m_mutex); 15156 return (tmp_tgt); 15157 } 15158 15159 if (mpt->m_done_traverse_dev) { 15160 mutex_exit(&mpt->m_mutex); 15161 return (NULL); 15162 } 15163 15164 /* If didn't get a match, come here */ 15165 cur_handle = mpt->m_dev_handle; 15166 for (; ; ) { 15167 tmp_tgt = NULL; 15168 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 15169 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle; 15170 rval = mptsas_get_target_device_info(mpt, page_address, 15171 &cur_handle, &tmp_tgt); 15172 if ((rval == DEV_INFO_FAIL_PAGE0) || 15173 (rval == DEV_INFO_FAIL_ALLOC)) { 15174 tmp_tgt = NULL; 15175 break; 15176 } 15177 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) || 15178 (rval == DEV_INFO_PHYS_DISK)) { 15179 continue; 15180 } 15181 mpt->m_dev_handle = cur_handle; 15182 if ((tmp_tgt->m_sas_wwn) && (tmp_tgt->m_sas_wwn == wwid) && 15183 (tmp_tgt->m_phymask == phymask)) { 15184 break; 15185 } 15186 } 15187 15188 mutex_exit(&mpt->m_mutex); 15189 return (tmp_tgt); 15190 } 15191 15192 static mptsas_smp_t * 15193 mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask, uint64_t wwid) 15194 { 15195 int rval = 0; 15196 uint16_t cur_handle; 15197 uint32_t page_address; 15198 mptsas_smp_t smp_node, *psmp = NULL; 15199 15200 mutex_enter(&mpt->m_mutex); 15201 psmp = (struct mptsas_smp *)mptsas_hash_search(&mpt->m_active->m_smptbl, 15202 wwid, phymask); 15203 if (psmp != NULL) { 15204 mutex_exit(&mpt->m_mutex); 15205 return (psmp); 15206 } 15207 15208 if (mpt->m_done_traverse_smp) { 15209 mutex_exit(&mpt->m_mutex); 15210 return (NULL); 15211 } 15212 15213 /* If didn't get a match, come here */ 15214 cur_handle = mpt->m_smp_devhdl; 15215 for (; ; ) { 15216 psmp = NULL; 15217 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL & 15218 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle; 15219 rval = mptsas_get_sas_expander_page0(mpt, page_address, 15220 &smp_node); 15221 if (rval != DDI_SUCCESS) { 15222 break; 15223 } 15224 mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl; 15225 psmp = mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node); 15226 ASSERT(psmp); 15227 if ((psmp->m_sasaddr) && (psmp->m_sasaddr == wwid) && 15228 (psmp->m_phymask == phymask)) { 15229 break; 15230 } 15231 } 15232 15233 mutex_exit(&mpt->m_mutex); 15234 return (psmp); 15235 } 15236 15237 /* helper functions using hash */ 15238 15239 /* 15240 * Can't have duplicate entries for same devhdl, 15241 * if there are invalid entries, the devhdl should be set to 0xffff 15242 */ 15243 static void * 15244 mptsas_search_by_devhdl(mptsas_hash_table_t *hashtab, uint16_t devhdl) 15245 { 15246 mptsas_hash_data_t *data; 15247 15248 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST); 15249 while (data != NULL) { 15250 if (data->devhdl == devhdl) { 15251 break; 15252 } 15253 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT); 15254 } 15255 return (data); 15256 } 15257 15258 mptsas_target_t * 15259 mptsas_tgt_alloc(mptsas_hash_table_t *hashtab, 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 15264 tmp_tgt = mptsas_hash_search(hashtab, wwid, phymask); 15265 if (tmp_tgt != NULL) { 15266 NDBG20(("Hash item already exist")); 15267 tmp_tgt->m_deviceinfo = devinfo; 15268 tmp_tgt->m_devhdl = devhdl; 15269 return (tmp_tgt); 15270 } 15271 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP); 15272 if (tmp_tgt == NULL) { 15273 cmn_err(CE_WARN, "Fatal, allocated tgt failed"); 15274 return (NULL); 15275 } 15276 tmp_tgt->m_devhdl = devhdl; 15277 tmp_tgt->m_sas_wwn = wwid; 15278 tmp_tgt->m_deviceinfo = devinfo; 15279 tmp_tgt->m_phymask = phymask; 15280 tmp_tgt->m_phynum = phynum; 15281 /* Initialized the tgt structure */ 15282 tmp_tgt->m_qfull_retries = QFULL_RETRIES; 15283 tmp_tgt->m_qfull_retry_interval = 15284 drv_usectohz(QFULL_RETRY_INTERVAL * 1000); 15285 tmp_tgt->m_t_throttle = MAX_THROTTLE; 15286 15287 mptsas_hash_add(hashtab, tmp_tgt); 15288 15289 return (tmp_tgt); 15290 } 15291 15292 static void 15293 mptsas_tgt_free(mptsas_hash_table_t *hashtab, uint64_t wwid, 15294 mptsas_phymask_t phymask) 15295 { 15296 mptsas_target_t *tmp_tgt; 15297 tmp_tgt = mptsas_hash_rem(hashtab, wwid, phymask); 15298 if (tmp_tgt == NULL) { 15299 cmn_err(CE_WARN, "Tgt not found, nothing to free"); 15300 } else { 15301 kmem_free(tmp_tgt, sizeof (struct mptsas_target)); 15302 } 15303 } 15304 15305 /* 15306 * Return the entry in the hash table 15307 */ 15308 static mptsas_smp_t * 15309 mptsas_smp_alloc(mptsas_hash_table_t *hashtab, mptsas_smp_t *data) 15310 { 15311 uint64_t key1 = data->m_sasaddr; 15312 mptsas_phymask_t key2 = data->m_phymask; 15313 mptsas_smp_t *ret_data; 15314 15315 ret_data = mptsas_hash_search(hashtab, key1, key2); 15316 if (ret_data != NULL) { 15317 bcopy(data, ret_data, sizeof (mptsas_smp_t)); 15318 return (ret_data); 15319 } 15320 15321 ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP); 15322 bcopy(data, ret_data, sizeof (mptsas_smp_t)); 15323 mptsas_hash_add(hashtab, ret_data); 15324 return (ret_data); 15325 } 15326 15327 static void 15328 mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid, 15329 mptsas_phymask_t phymask) 15330 { 15331 mptsas_smp_t *tmp_smp; 15332 tmp_smp = mptsas_hash_rem(hashtab, wwid, phymask); 15333 if (tmp_smp == NULL) { 15334 cmn_err(CE_WARN, "Smp element not found, nothing to free"); 15335 } else { 15336 kmem_free(tmp_smp, sizeof (struct mptsas_smp)); 15337 } 15338 } 15339 15340 /* 15341 * Hash operation functions 15342 * key1 is the sas_wwn, key2 is the phymask 15343 */ 15344 static void 15345 mptsas_hash_init(mptsas_hash_table_t *hashtab) 15346 { 15347 if (hashtab == NULL) { 15348 return; 15349 } 15350 bzero(hashtab->head, sizeof (mptsas_hash_node_t) * 15351 MPTSAS_HASH_ARRAY_SIZE); 15352 hashtab->cur = NULL; 15353 hashtab->line = 0; 15354 } 15355 15356 static void 15357 mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen) 15358 { 15359 uint16_t line = 0; 15360 mptsas_hash_node_t *cur = NULL, *last = NULL; 15361 15362 if (hashtab == NULL) { 15363 return; 15364 } 15365 for (line = 0; line < MPTSAS_HASH_ARRAY_SIZE; line++) { 15366 cur = hashtab->head[line]; 15367 while (cur != NULL) { 15368 last = cur; 15369 cur = cur->next; 15370 kmem_free(last->data, datalen); 15371 kmem_free(last, sizeof (mptsas_hash_node_t)); 15372 } 15373 } 15374 } 15375 15376 /* 15377 * You must guarantee the element doesn't exist in the hash table 15378 * before you call mptsas_hash_add() 15379 */ 15380 static void 15381 mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data) 15382 { 15383 uint64_t key1 = ((mptsas_hash_data_t *)data)->key1; 15384 mptsas_phymask_t key2 = ((mptsas_hash_data_t *)data)->key2; 15385 mptsas_hash_node_t **head = NULL; 15386 mptsas_hash_node_t *node = NULL; 15387 15388 if (hashtab == NULL) { 15389 return; 15390 } 15391 ASSERT(mptsas_hash_search(hashtab, key1, key2) == NULL); 15392 node = kmem_zalloc(sizeof (mptsas_hash_node_t), KM_NOSLEEP); 15393 node->data = data; 15394 15395 head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]); 15396 if (*head == NULL) { 15397 *head = node; 15398 } else { 15399 node->next = *head; 15400 *head = node; 15401 } 15402 } 15403 15404 static void * 15405 mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1, 15406 mptsas_phymask_t key2) 15407 { 15408 mptsas_hash_node_t **head = NULL; 15409 mptsas_hash_node_t *last = NULL, *cur = NULL; 15410 mptsas_hash_data_t *data; 15411 if (hashtab == NULL) { 15412 return (NULL); 15413 } 15414 head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]); 15415 cur = *head; 15416 while (cur != NULL) { 15417 data = cur->data; 15418 if ((data->key1 == key1) && (data->key2 == key2)) { 15419 if (last == NULL) { 15420 (*head) = cur->next; 15421 } else { 15422 last->next = cur->next; 15423 } 15424 kmem_free(cur, sizeof (mptsas_hash_node_t)); 15425 return (data); 15426 } else { 15427 last = cur; 15428 cur = cur->next; 15429 } 15430 } 15431 return (NULL); 15432 } 15433 15434 static void * 15435 mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1, 15436 mptsas_phymask_t key2) 15437 { 15438 mptsas_hash_node_t *cur = NULL; 15439 mptsas_hash_data_t *data; 15440 if (hashtab == NULL) { 15441 return (NULL); 15442 } 15443 cur = hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]; 15444 while (cur != NULL) { 15445 data = cur->data; 15446 if ((data->key1 == key1) && (data->key2 == key2)) { 15447 return (data); 15448 } else { 15449 cur = cur->next; 15450 } 15451 } 15452 return (NULL); 15453 } 15454 15455 static void * 15456 mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos) 15457 { 15458 mptsas_hash_node_t *this = NULL; 15459 15460 if (hashtab == NULL) { 15461 return (NULL); 15462 } 15463 15464 if (pos == MPTSAS_HASH_FIRST) { 15465 hashtab->line = 0; 15466 hashtab->cur = NULL; 15467 this = hashtab->head[0]; 15468 } else { 15469 if (hashtab->cur == NULL) { 15470 return (NULL); 15471 } else { 15472 this = hashtab->cur->next; 15473 } 15474 } 15475 15476 while (this == NULL) { 15477 hashtab->line++; 15478 if (hashtab->line >= MPTSAS_HASH_ARRAY_SIZE) { 15479 /* the traverse reaches the end */ 15480 hashtab->cur = NULL; 15481 return (NULL); 15482 } else { 15483 this = hashtab->head[hashtab->line]; 15484 } 15485 } 15486 hashtab->cur = this; 15487 return (this->data); 15488 } 15489 15490 /* 15491 * Functions for SGPIO LED support 15492 */ 15493 static dev_info_t * 15494 mptsas_get_dip_from_dev(dev_t dev, mptsas_phymask_t *phymask) 15495 { 15496 dev_info_t *dip; 15497 int prop; 15498 dip = e_ddi_hold_devi_by_dev(dev, 0); 15499 if (dip == NULL) 15500 return (dip); 15501 prop = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 15502 "phymask", 0); 15503 *phymask = (mptsas_phymask_t)prop; 15504 ddi_release_devi(dip); 15505 return (dip); 15506 } 15507 static mptsas_target_t * 15508 mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask) 15509 { 15510 uint8_t phynum; 15511 uint64_t wwn; 15512 int lun; 15513 mptsas_target_t *ptgt = NULL; 15514 15515 if (mptsas_parse_address(addr, &wwn, &phynum, &lun) != DDI_SUCCESS) { 15516 return (NULL); 15517 } 15518 if (addr[0] == 'w') { 15519 ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn); 15520 } else { 15521 ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum); 15522 } 15523 return (ptgt); 15524 } 15525 15526 static int 15527 mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt) 15528 { 15529 uint32_t slotstatus = 0; 15530 15531 /* Build an MPI2 Slot Status based on our view of the world */ 15532 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_IDENT - 1))) 15533 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST; 15534 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_FAIL - 1))) 15535 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT; 15536 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1))) 15537 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE; 15538 15539 /* Write it to the controller */ 15540 NDBG14(("mptsas_ioctl: set LED status %x for slot %x", 15541 slotstatus, ptgt->m_slot_num)); 15542 return (mptsas_send_sep(mpt, ptgt, &slotstatus, 15543 MPI2_SEP_REQ_ACTION_WRITE_STATUS)); 15544 } 15545 15546 /* 15547 * send sep request, use enclosure/slot addressing 15548 */ 15549 static int 15550 mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt, 15551 uint32_t *status, uint8_t act) 15552 { 15553 Mpi2SepRequest_t req; 15554 Mpi2SepReply_t rep; 15555 int ret; 15556 15557 ASSERT(mutex_owned(&mpt->m_mutex)); 15558 15559 /* 15560 * We only support SEP control of directly-attached targets, in which 15561 * case the "SEP" we're talking to is a virtual one contained within 15562 * the HBA itself. This is necessary because DA targets typically have 15563 * no other mechanism for LED control. Targets for which a separate 15564 * enclosure service processor exists should be controlled via ses(7d) 15565 * or sgen(7d). Furthermore, since such requests can time out, they 15566 * should be made in user context rather than in response to 15567 * asynchronous fabric changes. 15568 * 15569 * In addition, we do not support this operation for RAID volumes, 15570 * since there is no slot associated with them. 15571 */ 15572 if (!(ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) || 15573 ptgt->m_phymask == 0) { 15574 return (ENOTTY); 15575 } 15576 15577 bzero(&req, sizeof (req)); 15578 bzero(&rep, sizeof (rep)); 15579 15580 req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; 15581 req.Action = act; 15582 req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS; 15583 req.EnclosureHandle = LE_16(ptgt->m_enclosure); 15584 req.Slot = LE_16(ptgt->m_slot_num); 15585 if (act == MPI2_SEP_REQ_ACTION_WRITE_STATUS) { 15586 req.SlotStatus = LE_32(*status); 15587 } 15588 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL, 15589 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL); 15590 if (ret != 0) { 15591 mptsas_log(mpt, CE_NOTE, "mptsas_send_sep: passthru SEP " 15592 "Processor Request message error %d", ret); 15593 return (ret); 15594 } 15595 /* do passthrough success, check the ioc status */ 15596 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 15597 mptsas_log(mpt, CE_NOTE, "send_sep act %x: ioc " 15598 "status:%x loginfo %x", act, LE_16(rep.IOCStatus), 15599 LE_32(rep.IOCLogInfo)); 15600 switch (LE_16(rep.IOCStatus) & MPI2_IOCSTATUS_MASK) { 15601 case MPI2_IOCSTATUS_INVALID_FUNCTION: 15602 case MPI2_IOCSTATUS_INVALID_VPID: 15603 case MPI2_IOCSTATUS_INVALID_FIELD: 15604 case MPI2_IOCSTATUS_INVALID_STATE: 15605 case MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED: 15606 case MPI2_IOCSTATUS_CONFIG_INVALID_ACTION: 15607 case MPI2_IOCSTATUS_CONFIG_INVALID_TYPE: 15608 case MPI2_IOCSTATUS_CONFIG_INVALID_PAGE: 15609 case MPI2_IOCSTATUS_CONFIG_INVALID_DATA: 15610 case MPI2_IOCSTATUS_CONFIG_NO_DEFAULTS: 15611 return (EINVAL); 15612 case MPI2_IOCSTATUS_BUSY: 15613 return (EBUSY); 15614 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: 15615 return (EAGAIN); 15616 case MPI2_IOCSTATUS_INVALID_SGL: 15617 case MPI2_IOCSTATUS_INTERNAL_ERROR: 15618 case MPI2_IOCSTATUS_CONFIG_CANT_COMMIT: 15619 default: 15620 return (EIO); 15621 } 15622 } 15623 if (act != MPI2_SEP_REQ_ACTION_WRITE_STATUS) { 15624 *status = LE_32(rep.SlotStatus); 15625 } 15626 15627 return (0); 15628 } 15629 15630 int 15631 mptsas_dma_addr_create(mptsas_t *mpt, ddi_dma_attr_t dma_attr, 15632 ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp, caddr_t *dma_memp, 15633 uint32_t alloc_size, ddi_dma_cookie_t *cookiep) 15634 { 15635 ddi_dma_cookie_t new_cookie; 15636 size_t alloc_len; 15637 uint_t ncookie; 15638 15639 if (cookiep == NULL) 15640 cookiep = &new_cookie; 15641 15642 if (ddi_dma_alloc_handle(mpt->m_dip, &dma_attr, DDI_DMA_SLEEP, 15643 NULL, dma_hdp) != DDI_SUCCESS) { 15644 dma_hdp = NULL; 15645 return (FALSE); 15646 } 15647 15648 if (ddi_dma_mem_alloc(*dma_hdp, alloc_size, &mpt->m_dev_acc_attr, 15649 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, dma_memp, &alloc_len, 15650 acc_hdp) != DDI_SUCCESS) { 15651 ddi_dma_free_handle(dma_hdp); 15652 dma_hdp = NULL; 15653 return (FALSE); 15654 } 15655 15656 if (ddi_dma_addr_bind_handle(*dma_hdp, NULL, *dma_memp, alloc_len, 15657 (DDI_DMA_RDWR | DDI_DMA_CONSISTENT), DDI_DMA_SLEEP, NULL, 15658 cookiep, &ncookie) != DDI_DMA_MAPPED) { 15659 (void) ddi_dma_mem_free(acc_hdp); 15660 ddi_dma_free_handle(dma_hdp); 15661 dma_hdp = NULL; 15662 return (FALSE); 15663 } 15664 15665 return (TRUE); 15666 } 15667 15668 void 15669 mptsas_dma_addr_destroy(ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp) 15670 { 15671 if (*dma_hdp == NULL) 15672 return; 15673 15674 (void) ddi_dma_unbind_handle(*dma_hdp); 15675 (void) ddi_dma_mem_free(acc_hdp); 15676 ddi_dma_free_handle(dma_hdp); 15677 dma_hdp = NULL; 15678 }