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/cpuvar.h> 72 #include <sys/policy.h> 73 #include <sys/model.h> 74 #include <sys/sysevent.h> 75 #include <sys/sysevent/eventdefs.h> 76 #include <sys/sysevent/dr.h> 77 #include <sys/sata/sata_defs.h> 78 #include <sys/scsi/generic/sas.h> 79 #include <sys/scsi/impl/scsi_sas.h> 80 81 #pragma pack(1) 82 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h> 83 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h> 84 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h> 85 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h> 86 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h> 87 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h> 88 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h> 89 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h> 90 #pragma pack() 91 92 /* 93 * private header files. 94 * 95 */ 96 #include <sys/scsi/impl/scsi_reset_notify.h> 97 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h> 98 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h> 99 #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h> 100 101 #include <sys/raidioctl.h> 102 103 #include <sys/fs/dv_node.h> /* devfs_clean */ 104 105 /* 106 * FMA header files 107 */ 108 #include <sys/ddifm.h> 109 #include <sys/fm/protocol.h> 110 #include <sys/fm/util.h> 111 #include <sys/fm/io/ddi.h> 112 113 /* 114 * For anyone who would modify the code in mptsas_driver, it must be awared 115 * that from snv_145 where CR6910752(mpt_sas driver performance can be 116 * improved) is integrated, the per_instance mutex m_mutex is not hold 117 * in the key IO code path, including mptsas_scsi_start(), mptsas_intr() 118 * and all of the recursive functions called in them, so don't 119 * make it for granted that all operations are sync/exclude correctly. Before 120 * doing any modification in key code path, and even other code path such as 121 * DR, watchsubr, ioctl, passthrough etc, make sure the elements modified have 122 * no releationship to elements shown in the fastpath 123 * (function mptsas_handle_io_fastpath()) in ISR and its recursive functions. 124 * otherwise, you have to use the new introduced mutex to protect them. 125 * As to how to do correctly, refer to the comments in mptsas_intr(). 126 */ 127 128 /* 129 * autoconfiguration data and routines. 130 */ 131 static int mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 132 static int mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd); 133 static int mptsas_power(dev_info_t *dip, int component, int level); 134 135 /* 136 * cb_ops function 137 */ 138 static int mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, 139 cred_t *credp, int *rval); 140 #ifdef __sparc 141 static int mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd); 142 #else /* __sparc */ 143 static int mptsas_quiesce(dev_info_t *devi); 144 #endif /* __sparc */ 145 146 /* 147 * Resource initilaization for hardware 148 */ 149 static void mptsas_setup_cmd_reg(mptsas_t *mpt); 150 static void mptsas_disable_bus_master(mptsas_t *mpt); 151 static void mptsas_hba_fini(mptsas_t *mpt); 152 static void mptsas_cfg_fini(mptsas_t *mptsas_blkp); 153 static int mptsas_hba_setup(mptsas_t *mpt); 154 static void mptsas_hba_teardown(mptsas_t *mpt); 155 static int mptsas_config_space_init(mptsas_t *mpt); 156 static void mptsas_config_space_fini(mptsas_t *mpt); 157 static void mptsas_iport_register(mptsas_t *mpt); 158 static int mptsas_smp_setup(mptsas_t *mpt); 159 static void mptsas_smp_teardown(mptsas_t *mpt); 160 static int mptsas_cache_create(mptsas_t *mpt); 161 static void mptsas_cache_destroy(mptsas_t *mpt); 162 static int mptsas_alloc_request_frames(mptsas_t *mpt); 163 static int mptsas_alloc_reply_frames(mptsas_t *mpt); 164 static int mptsas_alloc_free_queue(mptsas_t *mpt); 165 static int mptsas_alloc_post_queue(mptsas_t *mpt); 166 static void mptsas_alloc_reply_args(mptsas_t *mpt); 167 static int mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd); 168 static void mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd); 169 static int mptsas_init_chip(mptsas_t *mpt, int first_time); 170 171 /* 172 * SCSA function prototypes 173 */ 174 static int mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt); 175 static int mptsas_scsi_reset(struct scsi_address *ap, int level); 176 static int mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt); 177 static int mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly); 178 static int mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, 179 int tgtonly); 180 static void mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt); 181 static struct scsi_pkt *mptsas_scsi_init_pkt(struct scsi_address *ap, 182 struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen, 183 int tgtlen, int flags, int (*callback)(), caddr_t arg); 184 static void mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt); 185 static void mptsas_scsi_destroy_pkt(struct scsi_address *ap, 186 struct scsi_pkt *pkt); 187 static int mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 188 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 189 static void mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 190 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 191 static int mptsas_scsi_reset_notify(struct scsi_address *ap, int flag, 192 void (*callback)(caddr_t), caddr_t arg); 193 static int mptsas_get_name(struct scsi_device *sd, char *name, int len); 194 static int mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len); 195 static int mptsas_scsi_quiesce(dev_info_t *dip); 196 static int mptsas_scsi_unquiesce(dev_info_t *dip); 197 static int mptsas_bus_config(dev_info_t *pdip, uint_t flags, 198 ddi_bus_config_op_t op, void *arg, dev_info_t **childp); 199 200 /* 201 * SMP functions 202 */ 203 static int mptsas_smp_start(struct smp_pkt *smp_pkt); 204 205 /* 206 * internal function prototypes. 207 */ 208 static void mptsas_list_add(mptsas_t *mpt); 209 static void mptsas_list_del(mptsas_t *mpt); 210 211 static int mptsas_quiesce_bus(mptsas_t *mpt); 212 static int mptsas_unquiesce_bus(mptsas_t *mpt); 213 214 static int mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size); 215 static void mptsas_free_handshake_msg(mptsas_t *mpt); 216 217 static void mptsas_ncmds_checkdrain(void *arg); 218 219 static int mptsas_prepare_pkt(mptsas_cmd_t *cmd); 220 static int mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *sp); 221 222 static int mptsas_do_detach(dev_info_t *dev); 223 static int mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl); 224 static int mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, 225 struct scsi_pkt *pkt); 226 static int mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp); 227 228 static void mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd); 229 static void mptsas_handle_event(void *args); 230 static int mptsas_handle_event_sync(void *args); 231 static void mptsas_handle_dr(void *args); 232 static void mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node, 233 dev_info_t *pdip); 234 235 static void mptsas_restart_cmd(void *); 236 237 static void mptsas_flush_hba(mptsas_t *mpt); 238 static void mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, 239 uint8_t tasktype); 240 static void mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, 241 uchar_t reason, uint_t stat); 242 243 static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2); 244 static void mptsas_process_intr(mptsas_t *mpt, 245 pMpi2ReplyDescriptorsUnion_t reply_desc_union); 246 static int mptsas_handle_io_fastpath(mptsas_t *mpt, uint16_t SMID); 247 static void mptsas_handle_scsi_io_success(mptsas_t *mpt, 248 pMpi2ReplyDescriptorsUnion_t reply_desc); 249 static void mptsas_handle_address_reply(mptsas_t *mpt, 250 pMpi2ReplyDescriptorsUnion_t reply_desc); 251 static int mptsas_wait_intr(mptsas_t *mpt, int polltime); 252 static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, 253 uint32_t *control, pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl); 254 255 static void mptsas_watch(void *arg); 256 static void mptsas_watchsubr(mptsas_t *mpt); 257 static void mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl); 258 259 static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd); 260 static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply, 261 uint8_t *data, uint32_t request_size, uint32_t reply_size, 262 uint32_t data_size, uint32_t direction, uint8_t *dataout, 263 uint32_t dataout_size, short timeout, int mode); 264 static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl); 265 266 static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, 267 uint32_t unique_id); 268 static void mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd); 269 static int mptsas_post_fw_diag_buffer(mptsas_t *mpt, 270 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code); 271 static int mptsas_release_fw_diag_buffer(mptsas_t *mpt, 272 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code, 273 uint32_t diag_type); 274 static int mptsas_diag_register(mptsas_t *mpt, 275 mptsas_fw_diag_register_t *diag_register, uint32_t *return_code); 276 static int mptsas_diag_unregister(mptsas_t *mpt, 277 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code); 278 static int mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query, 279 uint32_t *return_code); 280 static int mptsas_diag_read_buffer(mptsas_t *mpt, 281 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf, 282 uint32_t *return_code, int ioctl_mode); 283 static int mptsas_diag_release(mptsas_t *mpt, 284 mptsas_fw_diag_release_t *diag_release, uint32_t *return_code); 285 static int mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, 286 uint8_t *diag_action, uint32_t length, uint32_t *return_code, 287 int ioctl_mode); 288 static int mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *data, 289 int mode); 290 291 static int mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd, 292 int cmdlen, int tgtlen, int statuslen, int kf); 293 static void mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd); 294 295 static int mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags); 296 static void mptsas_kmem_cache_destructor(void *buf, void *cdrarg); 297 298 static int mptsas_cache_frames_constructor(void *buf, void *cdrarg, 299 int kmflags); 300 static void mptsas_cache_frames_destructor(void *buf, void *cdrarg); 301 302 static void mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, 303 mptsas_cmd_t *cmd); 304 static void mptsas_check_task_mgt(mptsas_t *mpt, 305 pMpi2SCSIManagementReply_t reply, mptsas_cmd_t *cmd); 306 static int mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap, 307 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp, 308 int *resid); 309 310 static int mptsas_alloc_active_slots(mptsas_t *mpt, int flag); 311 static void mptsas_free_active_slots(mptsas_t *mpt); 312 static int mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd); 313 static int mptsas_start_cmd0(mptsas_t *mpt, mptsas_cmd_t *cmd); 314 315 static void mptsas_restart_hba(mptsas_t *mpt); 316 317 static void mptsas_deliver_doneq_thread(mptsas_t *mpt); 318 static void mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd); 319 static inline void mptsas_doneq_add0(mptsas_t *mpt, mptsas_cmd_t *cmd); 320 static void mptsas_doneq_mv(mptsas_t *mpt, uint64_t t); 321 322 static mptsas_cmd_t *mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t); 323 static void mptsas_doneq_empty(mptsas_t *mpt); 324 static void mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg); 325 326 static mptsas_cmd_t *mptsas_waitq_rm(mptsas_t *mpt); 327 static void mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd); 328 329 static void mptsas_start_watch_reset_delay(); 330 static void mptsas_setup_bus_reset_delay(mptsas_t *mpt); 331 static void mptsas_watch_reset_delay(void *arg); 332 static int mptsas_watch_reset_delay_subr(mptsas_t *mpt); 333 334 static int mptsas_outstanding_cmds_n(mptsas_t *mpt); 335 /* 336 * helper functions 337 */ 338 static void mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd); 339 340 static dev_info_t *mptsas_find_child(dev_info_t *pdip, char *name); 341 static dev_info_t *mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy); 342 static dev_info_t *mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, 343 int lun); 344 static mdi_pathinfo_t *mptsas_find_path_addr(dev_info_t *pdip, uint64_t sasaddr, 345 int lun); 346 static mdi_pathinfo_t *mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy); 347 static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn); 348 349 static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, 350 int *lun); 351 static int mptsas_parse_smp_name(char *name, uint64_t *wwn); 352 353 static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt, int phymask, 354 uint8_t phy); 355 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask, 356 uint64_t wwid); 357 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask, 358 uint64_t wwid); 359 360 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, 361 uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd); 362 363 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address, 364 uint16_t *handle, mptsas_target_t **pptgt); 365 static void mptsas_update_phymask(mptsas_t *mpt); 366 static inline void mptsas_remove_cmd0(mptsas_t *mpt, mptsas_cmd_t *cmd); 367 368 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt, 369 uint32_t *status, uint8_t cmd); 370 static dev_info_t *mptsas_get_dip_from_dev(dev_t dev, 371 mptsas_phymask_t *phymask); 372 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, 373 mptsas_phymask_t phymask); 374 static int mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt); 375 376 377 /* 378 * Enumeration / DR functions 379 */ 380 static void mptsas_config_all(dev_info_t *pdip); 381 static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun, 382 dev_info_t **lundip); 383 static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun, 384 dev_info_t **lundip); 385 386 static int mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt); 387 static int mptsas_offline_target(dev_info_t *pdip, char *name); 388 389 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target, 390 dev_info_t **dip); 391 392 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt); 393 static int mptsas_probe_lun(dev_info_t *pdip, int lun, 394 dev_info_t **dip, mptsas_target_t *ptgt); 395 396 static int mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq, 397 dev_info_t **dip, mptsas_target_t *ptgt, int lun); 398 399 static int mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *sd, 400 char *guid, dev_info_t **dip, mptsas_target_t *ptgt, int lun); 401 static int mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *sd, 402 char *guid, dev_info_t **dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, 403 int lun); 404 405 static void mptsas_offline_missed_luns(dev_info_t *pdip, 406 uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt); 407 static int mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip, 408 mdi_pathinfo_t *rpip, uint_t flags); 409 410 static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, 411 dev_info_t **smp_dip); 412 static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 413 uint_t flags); 414 415 static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, 416 int mode, int *rval); 417 static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, 418 int mode, int *rval); 419 static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, 420 int mode, int *rval); 421 static void mptsas_record_event(void *args); 422 static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, 423 int mode); 424 425 static void mptsas_hash_init(mptsas_hash_table_t *hashtab); 426 static void mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen); 427 static void mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data); 428 static void * mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1, 429 mptsas_phymask_t key2); 430 static void * mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1, 431 mptsas_phymask_t key2); 432 static void * mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos); 433 434 mptsas_target_t *mptsas_tgt_alloc(mptsas_hash_table_t *, uint16_t, uint64_t, 435 uint32_t, mptsas_phymask_t, uint8_t, mptsas_t *); 436 static mptsas_smp_t *mptsas_smp_alloc(mptsas_hash_table_t *hashtab, 437 mptsas_smp_t *data); 438 static void mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid, 439 mptsas_phymask_t phymask); 440 static void mptsas_tgt_free(mptsas_hash_table_t *, uint64_t, mptsas_phymask_t); 441 static void * mptsas_search_by_devhdl(mptsas_hash_table_t *, uint16_t); 442 static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 443 dev_info_t **smp_dip); 444 445 /* 446 * Power management functions 447 */ 448 static int mptsas_get_pci_cap(mptsas_t *mpt); 449 static int mptsas_init_pm(mptsas_t *mpt); 450 451 /* 452 * MPT MSI tunable: 453 * 454 * By default MSI is enabled on all supported platforms. 455 */ 456 boolean_t mptsas_enable_msi = B_TRUE; 457 boolean_t mptsas_physical_bind_failed_page_83 = B_FALSE; 458 459 static int mptsas_register_intrs(mptsas_t *); 460 static void mptsas_unregister_intrs(mptsas_t *); 461 static int mptsas_add_intrs(mptsas_t *, int); 462 static void mptsas_rem_intrs(mptsas_t *); 463 464 /* 465 * FMA Prototypes 466 */ 467 static void mptsas_fm_init(mptsas_t *mpt); 468 static void mptsas_fm_fini(mptsas_t *mpt); 469 static int mptsas_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *); 470 471 extern pri_t minclsyspri, maxclsyspri; 472 473 /* 474 * This device is created by the SCSI pseudo nexus driver (SCSI vHCI). It is 475 * under this device that the paths to a physical device are created when 476 * MPxIO is used. 477 */ 478 extern dev_info_t *scsi_vhci_dip; 479 480 /* 481 * Tunable timeout value for Inquiry VPD page 0x83 482 * By default the value is 30 seconds. 483 */ 484 int mptsas_inq83_retry_timeout = 30; 485 486 /* 487 * This is used to allocate memory for message frame storage, not for 488 * data I/O DMA. All message frames must be stored in the first 4G of 489 * physical memory. 490 */ 491 ddi_dma_attr_t mptsas_dma_attrs = { 492 DMA_ATTR_V0, /* attribute layout version */ 493 0x0ull, /* address low - should be 0 (longlong) */ 494 0xffffffffull, /* address high - 32-bit max range */ 495 0x00ffffffull, /* count max - max DMA object size */ 496 4, /* allocation alignment requirements */ 497 0x78, /* burstsizes - binary encoded values */ 498 1, /* minxfer - gran. of DMA engine */ 499 0x00ffffffull, /* maxxfer - gran. of DMA engine */ 500 0xffffffffull, /* max segment size (DMA boundary) */ 501 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */ 502 512, /* granularity - device transfer size */ 503 0 /* flags, set to 0 */ 504 }; 505 506 /* 507 * This is used for data I/O DMA memory allocation. (full 64-bit DMA 508 * physical addresses are supported.) 509 */ 510 ddi_dma_attr_t mptsas_dma_attrs64 = { 511 DMA_ATTR_V0, /* attribute layout version */ 512 0x0ull, /* address low - should be 0 (longlong) */ 513 0xffffffffffffffffull, /* address high - 64-bit max */ 514 0x00ffffffull, /* count max - max DMA object size */ 515 4, /* allocation alignment requirements */ 516 0x78, /* burstsizes - binary encoded values */ 517 1, /* minxfer - gran. of DMA engine */ 518 0x00ffffffull, /* maxxfer - gran. of DMA engine */ 519 0xffffffffull, /* max segment size (DMA boundary) */ 520 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */ 521 512, /* granularity - device transfer size */ 522 DDI_DMA_RELAXED_ORDERING /* flags, enable relaxed ordering */ 523 }; 524 525 ddi_device_acc_attr_t mptsas_dev_attr = { 526 DDI_DEVICE_ATTR_V1, 527 DDI_STRUCTURE_LE_ACC, 528 DDI_STRICTORDER_ACC, 529 DDI_DEFAULT_ACC 530 }; 531 532 static struct cb_ops mptsas_cb_ops = { 533 scsi_hba_open, /* open */ 534 scsi_hba_close, /* close */ 535 nodev, /* strategy */ 536 nodev, /* print */ 537 nodev, /* dump */ 538 nodev, /* read */ 539 nodev, /* write */ 540 mptsas_ioctl, /* ioctl */ 541 nodev, /* devmap */ 542 nodev, /* mmap */ 543 nodev, /* segmap */ 544 nochpoll, /* chpoll */ 545 ddi_prop_op, /* cb_prop_op */ 546 NULL, /* streamtab */ 547 D_MP, /* cb_flag */ 548 CB_REV, /* rev */ 549 nodev, /* aread */ 550 nodev /* awrite */ 551 }; 552 553 static struct dev_ops mptsas_ops = { 554 DEVO_REV, /* devo_rev, */ 555 0, /* refcnt */ 556 ddi_no_info, /* info */ 557 nulldev, /* identify */ 558 nulldev, /* probe */ 559 mptsas_attach, /* attach */ 560 mptsas_detach, /* detach */ 561 #ifdef __sparc 562 mptsas_reset, 563 #else 564 nodev, /* reset */ 565 #endif /* __sparc */ 566 &mptsas_cb_ops, /* driver operations */ 567 NULL, /* bus operations */ 568 mptsas_power, /* power management */ 569 #ifdef __sparc 570 ddi_quiesce_not_needed 571 #else 572 mptsas_quiesce /* quiesce */ 573 #endif /* __sparc */ 574 }; 575 576 577 #define MPTSAS_MOD_STRING "MPTSAS HBA Driver 00.00.00.24" 578 579 static struct modldrv modldrv = { 580 &mod_driverops, /* Type of module. This one is a driver */ 581 MPTSAS_MOD_STRING, /* Name of the module. */ 582 &mptsas_ops, /* driver ops */ 583 }; 584 585 static struct modlinkage modlinkage = { 586 MODREV_1, &modldrv, NULL 587 }; 588 #define TARGET_PROP "target" 589 #define LUN_PROP "lun" 590 #define LUN64_PROP "lun64" 591 #define SAS_PROP "sas-mpt" 592 #define MDI_GUID "wwn" 593 #define NDI_GUID "guid" 594 #define MPTSAS_DEV_GONE "mptsas_dev_gone" 595 596 /* 597 * Local static data 598 */ 599 #if defined(MPTSAS_DEBUG) 600 uint32_t mptsas_debug_flags = 0; 601 #endif /* defined(MPTSAS_DEBUG) */ 602 uint32_t mptsas_debug_resets = 0; 603 604 static kmutex_t mptsas_global_mutex; 605 static void *mptsas_state; /* soft state ptr */ 606 static krwlock_t mptsas_global_rwlock; 607 608 static kmutex_t mptsas_log_mutex; 609 static char mptsas_log_buf[256]; 610 _NOTE(MUTEX_PROTECTS_DATA(mptsas_log_mutex, mptsas_log_buf)) 611 612 static mptsas_t *mptsas_head, *mptsas_tail; 613 static clock_t mptsas_scsi_watchdog_tick; 614 static clock_t mptsas_tick; 615 static timeout_id_t mptsas_reset_watch; 616 static timeout_id_t mptsas_timeout_id; 617 static int mptsas_timeouts_enabled = 0; 618 /* 619 * warlock directives 620 */ 621 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt \ 622 mptsas_cmd NcrTableIndirect buf scsi_cdb scsi_status)) 623 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", smp_pkt)) 624 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address)) 625 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", mptsas_tgt_private)) 626 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_hba_tran::tran_tgt_private)) 627 628 /* 629 * SM - HBA statics 630 */ 631 char *mptsas_driver_rev = MPTSAS_MOD_STRING; 632 633 #ifdef MPTSAS_DEBUG 634 void debug_enter(char *); 635 #endif 636 637 /* 638 * Notes: 639 * - scsi_hba_init(9F) initializes SCSI HBA modules 640 * - must call scsi_hba_fini(9F) if modload() fails 641 */ 642 int 643 _init(void) 644 { 645 int status; 646 /* CONSTCOND */ 647 ASSERT(NO_COMPETING_THREADS); 648 649 NDBG0(("_init")); 650 651 status = ddi_soft_state_init(&mptsas_state, MPTSAS_SIZE, 652 MPTSAS_INITIAL_SOFT_SPACE); 653 if (status != 0) { 654 return (status); 655 } 656 657 if ((status = scsi_hba_init(&modlinkage)) != 0) { 658 ddi_soft_state_fini(&mptsas_state); 659 return (status); 660 } 661 662 mutex_init(&mptsas_global_mutex, NULL, MUTEX_DRIVER, NULL); 663 rw_init(&mptsas_global_rwlock, NULL, RW_DRIVER, NULL); 664 mutex_init(&mptsas_log_mutex, NULL, MUTEX_DRIVER, NULL); 665 666 if ((status = mod_install(&modlinkage)) != 0) { 667 mutex_destroy(&mptsas_log_mutex); 668 rw_destroy(&mptsas_global_rwlock); 669 mutex_destroy(&mptsas_global_mutex); 670 ddi_soft_state_fini(&mptsas_state); 671 scsi_hba_fini(&modlinkage); 672 } 673 674 return (status); 675 } 676 677 /* 678 * Notes: 679 * - scsi_hba_fini(9F) uninitializes SCSI HBA modules 680 */ 681 int 682 _fini(void) 683 { 684 int status; 685 /* CONSTCOND */ 686 ASSERT(NO_COMPETING_THREADS); 687 688 NDBG0(("_fini")); 689 690 if ((status = mod_remove(&modlinkage)) == 0) { 691 ddi_soft_state_fini(&mptsas_state); 692 scsi_hba_fini(&modlinkage); 693 mutex_destroy(&mptsas_global_mutex); 694 rw_destroy(&mptsas_global_rwlock); 695 mutex_destroy(&mptsas_log_mutex); 696 } 697 return (status); 698 } 699 700 /* 701 * The loadable-module _info(9E) entry point 702 */ 703 int 704 _info(struct modinfo *modinfop) 705 { 706 /* CONSTCOND */ 707 ASSERT(NO_COMPETING_THREADS); 708 NDBG0(("mptsas _info")); 709 710 return (mod_info(&modlinkage, modinfop)); 711 } 712 713 714 static int 715 mptsas_iport_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 716 { 717 dev_info_t *pdip; 718 mptsas_t *mpt; 719 scsi_hba_tran_t *hba_tran; 720 char *iport = NULL; 721 char phymask[MPTSAS_MAX_PHYS]; 722 mptsas_phymask_t phy_mask = 0; 723 int dynamic_port = 0; 724 uint32_t page_address; 725 char initiator_wwnstr[MPTSAS_WWN_STRLEN]; 726 int rval = DDI_FAILURE; 727 int i = 0; 728 uint8_t numphys = 0; 729 uint8_t phy_id; 730 uint8_t phy_port = 0; 731 uint16_t attached_devhdl = 0; 732 uint32_t dev_info; 733 uint64_t attached_sas_wwn; 734 uint16_t dev_hdl; 735 uint16_t pdev_hdl; 736 uint16_t bay_num, enclosure; 737 char attached_wwnstr[MPTSAS_WWN_STRLEN]; 738 739 /* CONSTCOND */ 740 ASSERT(NO_COMPETING_THREADS); 741 742 switch (cmd) { 743 case DDI_ATTACH: 744 break; 745 746 case DDI_RESUME: 747 /* 748 * If this a scsi-iport node, nothing to do here. 749 */ 750 return (DDI_SUCCESS); 751 752 default: 753 return (DDI_FAILURE); 754 } 755 756 pdip = ddi_get_parent(dip); 757 758 if ((hba_tran = ndi_flavorv_get(pdip, SCSA_FLAVOR_SCSI_DEVICE)) == 759 NULL) { 760 cmn_err(CE_WARN, "Failed attach iport because fail to " 761 "get tran vector for the HBA node"); 762 return (DDI_FAILURE); 763 } 764 765 mpt = TRAN2MPT(hba_tran); 766 ASSERT(mpt != NULL); 767 if (mpt == NULL) 768 return (DDI_FAILURE); 769 770 if ((hba_tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == 771 NULL) { 772 mptsas_log(mpt, CE_WARN, "Failed attach iport because fail to " 773 "get tran vector for the iport node"); 774 return (DDI_FAILURE); 775 } 776 777 /* 778 * Overwrite parent's tran_hba_private to iport's tran vector 779 */ 780 hba_tran->tran_hba_private = mpt; 781 782 ddi_report_dev(dip); 783 784 /* 785 * Get SAS address for initiator port according dev_handle 786 */ 787 iport = ddi_get_name_addr(dip); 788 if (iport && strncmp(iport, "v0", 2) == 0) { 789 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 790 MPTSAS_VIRTUAL_PORT, 1) != 791 DDI_PROP_SUCCESS) { 792 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, 793 MPTSAS_VIRTUAL_PORT); 794 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 795 "prop update failed"); 796 return (DDI_FAILURE); 797 } 798 return (DDI_SUCCESS); 799 } 800 801 mutex_enter(&mpt->m_mutex); 802 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 803 bzero(phymask, sizeof (phymask)); 804 (void) sprintf(phymask, 805 "%x", mpt->m_phy_info[i].phy_mask); 806 if (strcmp(phymask, iport) == 0) { 807 break; 808 } 809 } 810 811 if (i == MPTSAS_MAX_PHYS) { 812 mptsas_log(mpt, CE_WARN, "Failed attach port %s because port" 813 "seems not exist", iport); 814 mutex_exit(&mpt->m_mutex); 815 return (DDI_FAILURE); 816 } 817 818 phy_mask = mpt->m_phy_info[i].phy_mask; 819 820 if (mpt->m_phy_info[i].port_flags & AUTO_PORT_CONFIGURATION) 821 dynamic_port = 1; 822 else 823 dynamic_port = 0; 824 825 /* 826 * Update PHY info for smhba 827 */ 828 if (mptsas_smhba_phy_init(mpt)) { 829 mutex_exit(&mpt->m_mutex); 830 mptsas_log(mpt, CE_WARN, "mptsas phy update " 831 "failed"); 832 return (DDI_FAILURE); 833 } 834 835 mutex_exit(&mpt->m_mutex); 836 837 numphys = 0; 838 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 839 if ((phy_mask >> i) & 0x01) { 840 numphys++; 841 } 842 } 843 844 bzero(initiator_wwnstr, sizeof (initiator_wwnstr)); 845 (void) sprintf(initiator_wwnstr, "w%016"PRIx64, 846 mpt->un.m_base_wwid); 847 848 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, 849 SCSI_ADDR_PROP_INITIATOR_PORT, initiator_wwnstr) != 850 DDI_PROP_SUCCESS) { 851 (void) ddi_prop_remove(DDI_DEV_T_NONE, 852 dip, SCSI_ADDR_PROP_INITIATOR_PORT); 853 mptsas_log(mpt, CE_WARN, "mptsas Initiator port " 854 "prop update failed"); 855 return (DDI_FAILURE); 856 } 857 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 858 MPTSAS_NUM_PHYS, numphys) != 859 DDI_PROP_SUCCESS) { 860 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, MPTSAS_NUM_PHYS); 861 return (DDI_FAILURE); 862 } 863 864 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 865 "phymask", phy_mask) != 866 DDI_PROP_SUCCESS) { 867 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "phymask"); 868 mptsas_log(mpt, CE_WARN, "mptsas phy mask " 869 "prop update failed"); 870 return (DDI_FAILURE); 871 } 872 873 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 874 "dynamic-port", dynamic_port) != 875 DDI_PROP_SUCCESS) { 876 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "dynamic-port"); 877 mptsas_log(mpt, CE_WARN, "mptsas dynamic port " 878 "prop update failed"); 879 return (DDI_FAILURE); 880 } 881 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 882 MPTSAS_VIRTUAL_PORT, 0) != 883 DDI_PROP_SUCCESS) { 884 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, 885 MPTSAS_VIRTUAL_PORT); 886 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 887 "prop update failed"); 888 return (DDI_FAILURE); 889 } 890 mptsas_smhba_set_phy_props(mpt, 891 iport, dip, numphys, &attached_devhdl); 892 893 mutex_enter(&mpt->m_mutex); 894 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 895 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)attached_devhdl; 896 rval = mptsas_get_sas_device_page0(mpt, page_address, &dev_hdl, 897 &attached_sas_wwn, &dev_info, &phy_port, &phy_id, 898 &pdev_hdl, &bay_num, &enclosure); 899 if (rval != DDI_SUCCESS) { 900 mptsas_log(mpt, CE_WARN, 901 "Failed to get device page0 for handle:%d", 902 attached_devhdl); 903 mutex_exit(&mpt->m_mutex); 904 return (DDI_FAILURE); 905 } 906 907 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 908 bzero(phymask, sizeof (phymask)); 909 (void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask); 910 if (strcmp(phymask, iport) == 0) { 911 (void) sprintf(&mpt->m_phy_info[i].smhba_info.path[0], 912 "%x", 913 mpt->m_phy_info[i].phy_mask); 914 } 915 } 916 mutex_exit(&mpt->m_mutex); 917 918 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 919 (void) sprintf(attached_wwnstr, "w%016"PRIx64, 920 attached_sas_wwn); 921 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, 922 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 923 DDI_PROP_SUCCESS) { 924 (void) ddi_prop_remove(DDI_DEV_T_NONE, 925 dip, SCSI_ADDR_PROP_ATTACHED_PORT); 926 return (DDI_FAILURE); 927 } 928 929 /* Create kstats for each phy on this iport */ 930 931 mptsas_create_phy_stats(mpt, iport, dip); 932 933 /* 934 * register sas hba iport with mdi (MPxIO/vhci) 935 */ 936 if (mdi_phci_register(MDI_HCI_CLASS_SCSI, 937 dip, 0) == MDI_SUCCESS) { 938 mpt->m_mpxio_enable = TRUE; 939 } 940 return (DDI_SUCCESS); 941 } 942 943 /* 944 * Notes: 945 * Set up all device state and allocate data structures, 946 * mutexes, condition variables, etc. for device operation. 947 * Add interrupts needed. 948 * Return DDI_SUCCESS if device is ready, else return DDI_FAILURE. 949 */ 950 static int 951 mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 952 { 953 mptsas_t *mpt = NULL; 954 int instance, i, j; 955 int doneq_thread_num; 956 char intr_added = 0; 957 char map_setup = 0; 958 char config_setup = 0; 959 char hba_attach_setup = 0; 960 char smp_attach_setup = 0; 961 char mutex_init_done = 0; 962 char event_taskq_create = 0; 963 char dr_taskq_create = 0; 964 char doneq_thread_create = 0; 965 scsi_hba_tran_t *hba_tran; 966 uint_t mem_bar = MEM_SPACE; 967 int rval = DDI_FAILURE; 968 969 /* CONSTCOND */ 970 ASSERT(NO_COMPETING_THREADS); 971 972 if (scsi_hba_iport_unit_address(dip)) { 973 return (mptsas_iport_attach(dip, cmd)); 974 } 975 976 switch (cmd) { 977 case DDI_ATTACH: 978 break; 979 980 case DDI_RESUME: 981 if ((hba_tran = ddi_get_driver_private(dip)) == NULL) 982 return (DDI_FAILURE); 983 984 mpt = TRAN2MPT(hba_tran); 985 986 if (!mpt) { 987 return (DDI_FAILURE); 988 } 989 990 /* 991 * Reset hardware and softc to "no outstanding commands" 992 * Note that a check condition can result on first command 993 * to a target. 994 */ 995 mutex_enter(&mpt->m_mutex); 996 997 /* 998 * raise power. 999 */ 1000 if (mpt->m_options & MPTSAS_OPT_PM) { 1001 mutex_exit(&mpt->m_mutex); 1002 (void) pm_busy_component(dip, 0); 1003 rval = pm_power_has_changed(dip, 0, PM_LEVEL_D0); 1004 if (rval == DDI_SUCCESS) { 1005 mutex_enter(&mpt->m_mutex); 1006 } else { 1007 /* 1008 * The pm_raise_power() call above failed, 1009 * and that can only occur if we were unable 1010 * to reset the hardware. This is probably 1011 * due to unhealty hardware, and because 1012 * important filesystems(such as the root 1013 * filesystem) could be on the attached disks, 1014 * it would not be a good idea to continue, 1015 * as we won't be entirely certain we are 1016 * writing correct data. So we panic() here 1017 * to not only prevent possible data corruption, 1018 * but to give developers or end users a hope 1019 * of identifying and correcting any problems. 1020 */ 1021 fm_panic("mptsas could not reset hardware " 1022 "during resume"); 1023 } 1024 } 1025 1026 mpt->m_suspended = 0; 1027 1028 /* 1029 * Reinitialize ioc 1030 */ 1031 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1032 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) { 1033 mutex_exit(&mpt->m_mutex); 1034 if (mpt->m_options & MPTSAS_OPT_PM) { 1035 (void) pm_idle_component(dip, 0); 1036 } 1037 fm_panic("mptsas init chip fail during resume"); 1038 } 1039 /* 1040 * mptsas_update_driver_data needs interrupts so enable them 1041 * first. 1042 */ 1043 MPTSAS_ENABLE_INTR(mpt); 1044 mptsas_update_driver_data(mpt); 1045 1046 /* start requests, if possible */ 1047 mptsas_restart_hba(mpt); 1048 1049 mutex_exit(&mpt->m_mutex); 1050 1051 /* 1052 * Restart watch thread 1053 */ 1054 mutex_enter(&mptsas_global_mutex); 1055 if (mptsas_timeout_id == 0) { 1056 mptsas_timeout_id = timeout(mptsas_watch, NULL, 1057 mptsas_tick); 1058 mptsas_timeouts_enabled = 1; 1059 } 1060 mutex_exit(&mptsas_global_mutex); 1061 1062 /* report idle status to pm framework */ 1063 if (mpt->m_options & MPTSAS_OPT_PM) { 1064 (void) pm_idle_component(dip, 0); 1065 } 1066 1067 return (DDI_SUCCESS); 1068 1069 default: 1070 return (DDI_FAILURE); 1071 1072 } 1073 1074 instance = ddi_get_instance(dip); 1075 1076 /* 1077 * Allocate softc information. 1078 */ 1079 if (ddi_soft_state_zalloc(mptsas_state, instance) != DDI_SUCCESS) { 1080 mptsas_log(NULL, CE_WARN, 1081 "mptsas%d: cannot allocate soft state", instance); 1082 goto fail; 1083 } 1084 1085 mpt = ddi_get_soft_state(mptsas_state, instance); 1086 1087 if (mpt == NULL) { 1088 mptsas_log(NULL, CE_WARN, 1089 "mptsas%d: cannot get soft state", instance); 1090 goto fail; 1091 } 1092 1093 /* Indicate that we are 'sizeof (scsi_*(9S))' clean. */ 1094 scsi_size_clean(dip); 1095 1096 mpt->m_dip = dip; 1097 mpt->m_instance = instance; 1098 1099 /* Make a per-instance copy of the structures */ 1100 mpt->m_io_dma_attr = mptsas_dma_attrs64; 1101 mpt->m_msg_dma_attr = mptsas_dma_attrs; 1102 mpt->m_reg_acc_attr = mptsas_dev_attr; 1103 mpt->m_dev_acc_attr = mptsas_dev_attr; 1104 1105 /* 1106 * Initialize FMA 1107 */ 1108 mpt->m_fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, mpt->m_dip, 1109 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable", 1110 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE | 1111 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE); 1112 1113 mptsas_fm_init(mpt); 1114 1115 if (mptsas_alloc_handshake_msg(mpt, 1116 sizeof (Mpi2SCSITaskManagementRequest_t)) == DDI_FAILURE) { 1117 mptsas_log(mpt, CE_WARN, "cannot initialize handshake msg."); 1118 goto fail; 1119 } 1120 1121 /* 1122 * Setup configuration space 1123 */ 1124 if (mptsas_config_space_init(mpt) == FALSE) { 1125 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init failed"); 1126 goto fail; 1127 } 1128 config_setup++; 1129 1130 if (ddi_regs_map_setup(dip, mem_bar, (caddr_t *)&mpt->m_reg, 1131 0, 0, &mpt->m_reg_acc_attr, &mpt->m_datap) != DDI_SUCCESS) { 1132 mptsas_log(mpt, CE_WARN, "map setup failed"); 1133 goto fail; 1134 } 1135 map_setup++; 1136 1137 /* 1138 * A taskq is created for dealing with the event handler 1139 */ 1140 if ((mpt->m_event_taskq = ddi_taskq_create(dip, "mptsas_event_taskq", 1141 1, TASKQ_DEFAULTPRI, 0)) == NULL) { 1142 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create failed"); 1143 goto fail; 1144 } 1145 event_taskq_create++; 1146 1147 /* 1148 * A taskq is created for dealing with dr events 1149 */ 1150 if ((mpt->m_dr_taskq = ddi_taskq_create(dip, 1151 "mptsas_dr_taskq", 1152 1, TASKQ_DEFAULTPRI, 0)) == NULL) { 1153 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create for discovery " 1154 "failed"); 1155 goto fail; 1156 } 1157 dr_taskq_create++; 1158 1159 mpt->m_doneq_thread_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1160 0, "mptsas_doneq_thread_threshold_prop", 10); 1161 mpt->m_doneq_length_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1162 0, "mptsas_doneq_length_threshold_prop", 8); 1163 mpt->m_doneq_thread_n = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1164 0, "mptsas_doneq_thread_n_prop", 8); 1165 1166 if (mpt->m_doneq_thread_n) { 1167 cv_init(&mpt->m_doneq_thread_cv, NULL, CV_DRIVER, NULL); 1168 mutex_init(&mpt->m_doneq_mutex, NULL, MUTEX_DRIVER, NULL); 1169 1170 mutex_enter(&mpt->m_doneq_mutex); 1171 mpt->m_doneq_thread_id = 1172 kmem_zalloc(sizeof (mptsas_doneq_thread_list_t) 1173 * mpt->m_doneq_thread_n, KM_SLEEP); 1174 1175 for (j = 0; j < mpt->m_doneq_thread_n; j++) { 1176 cv_init(&mpt->m_doneq_thread_id[j].cv, NULL, 1177 CV_DRIVER, NULL); 1178 mutex_init(&mpt->m_doneq_thread_id[j].mutex, NULL, 1179 MUTEX_DRIVER, NULL); 1180 mutex_enter(&mpt->m_doneq_thread_id[j].mutex); 1181 mpt->m_doneq_thread_id[j].flag |= 1182 MPTSAS_DONEQ_THREAD_ACTIVE; 1183 mpt->m_doneq_thread_id[j].arg.mpt = mpt; 1184 mpt->m_doneq_thread_id[j].arg.t = j; 1185 mpt->m_doneq_thread_id[j].threadp = 1186 thread_create(NULL, 0, mptsas_doneq_thread, 1187 &mpt->m_doneq_thread_id[j].arg, 1188 0, &p0, TS_RUN, minclsyspri); 1189 mpt->m_doneq_thread_id[j].donetail = 1190 &mpt->m_doneq_thread_id[j].doneq; 1191 mutex_exit(&mpt->m_doneq_thread_id[j].mutex); 1192 } 1193 mutex_exit(&mpt->m_doneq_mutex); 1194 doneq_thread_create++; 1195 } 1196 1197 /* Initialize mutex used in interrupt handler */ 1198 mutex_init(&mpt->m_mutex, NULL, MUTEX_DRIVER, 1199 DDI_INTR_PRI(mpt->m_intr_pri)); 1200 mutex_init(&mpt->m_passthru_mutex, NULL, MUTEX_DRIVER, NULL); 1201 mutex_init(&mpt->m_intr_mutex, NULL, MUTEX_DRIVER, 1202 DDI_INTR_PRI(mpt->m_intr_pri)); 1203 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1204 mutex_init(&mpt->m_phy_info[i].smhba_info.phy_mutex, 1205 NULL, MUTEX_DRIVER, 1206 DDI_INTR_PRI(mpt->m_intr_pri)); 1207 } 1208 1209 cv_init(&mpt->m_cv, NULL, CV_DRIVER, NULL); 1210 cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL); 1211 cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL); 1212 cv_init(&mpt->m_config_cv, NULL, CV_DRIVER, NULL); 1213 cv_init(&mpt->m_fw_diag_cv, NULL, CV_DRIVER, NULL); 1214 mutex_init_done++; 1215 1216 /* 1217 * Disable hardware interrupt since we're not ready to 1218 * handle it yet. 1219 */ 1220 MPTSAS_DISABLE_INTR(mpt); 1221 if (mptsas_register_intrs(mpt) == FALSE) 1222 goto fail; 1223 intr_added++; 1224 1225 mutex_enter(&mpt->m_mutex); 1226 /* 1227 * Initialize power management component 1228 */ 1229 if (mpt->m_options & MPTSAS_OPT_PM) { 1230 if (mptsas_init_pm(mpt)) { 1231 mutex_exit(&mpt->m_mutex); 1232 mptsas_log(mpt, CE_WARN, "mptsas pm initialization " 1233 "failed"); 1234 goto fail; 1235 } 1236 } 1237 1238 /* 1239 * Initialize chip using Message Unit Reset, if allowed 1240 */ 1241 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1242 if (mptsas_init_chip(mpt, TRUE) == DDI_FAILURE) { 1243 mutex_exit(&mpt->m_mutex); 1244 mptsas_log(mpt, CE_WARN, "mptsas chip initialization failed"); 1245 goto fail; 1246 } 1247 1248 /* 1249 * Fill in the phy_info structure and get the base WWID 1250 */ 1251 if (mptsas_get_manufacture_page5(mpt) == DDI_FAILURE) { 1252 mptsas_log(mpt, CE_WARN, 1253 "mptsas_get_manufacture_page5 failed!"); 1254 goto fail; 1255 } 1256 1257 if (mptsas_get_sas_io_unit_page_hndshk(mpt)) { 1258 mptsas_log(mpt, CE_WARN, 1259 "mptsas_get_sas_io_unit_page_hndshk failed!"); 1260 goto fail; 1261 } 1262 1263 if (mptsas_get_manufacture_page0(mpt) == DDI_FAILURE) { 1264 mptsas_log(mpt, CE_WARN, 1265 "mptsas_get_manufacture_page0 failed!"); 1266 goto fail; 1267 } 1268 1269 mutex_exit(&mpt->m_mutex); 1270 1271 /* 1272 * Register the iport for multiple port HBA 1273 */ 1274 mptsas_iport_register(mpt); 1275 1276 /* 1277 * initialize SCSI HBA transport structure 1278 */ 1279 if (mptsas_hba_setup(mpt) == FALSE) 1280 goto fail; 1281 hba_attach_setup++; 1282 1283 if (mptsas_smp_setup(mpt) == FALSE) 1284 goto fail; 1285 smp_attach_setup++; 1286 1287 if (mptsas_cache_create(mpt) == FALSE) 1288 goto fail; 1289 1290 mpt->m_scsi_reset_delay = ddi_prop_get_int(DDI_DEV_T_ANY, 1291 dip, 0, "scsi-reset-delay", SCSI_DEFAULT_RESET_DELAY); 1292 if (mpt->m_scsi_reset_delay == 0) { 1293 mptsas_log(mpt, CE_NOTE, 1294 "scsi_reset_delay of 0 is not recommended," 1295 " resetting to SCSI_DEFAULT_RESET_DELAY\n"); 1296 mpt->m_scsi_reset_delay = SCSI_DEFAULT_RESET_DELAY; 1297 } 1298 1299 /* 1300 * Initialize the wait and done FIFO queue 1301 */ 1302 mpt->m_donetail = &mpt->m_doneq; 1303 mpt->m_waitqtail = &mpt->m_waitq; 1304 1305 /* 1306 * ioc cmd queue initialize 1307 */ 1308 mpt->m_ioc_event_cmdtail = &mpt->m_ioc_event_cmdq; 1309 mpt->m_dev_handle = 0xFFFF; 1310 1311 MPTSAS_ENABLE_INTR(mpt); 1312 1313 /* 1314 * enable event notification 1315 */ 1316 mutex_enter(&mpt->m_mutex); 1317 if (mptsas_ioc_enable_event_notification(mpt)) { 1318 mutex_exit(&mpt->m_mutex); 1319 goto fail; 1320 } 1321 mutex_exit(&mpt->m_mutex); 1322 1323 /* 1324 * Initialize PHY info for smhba 1325 */ 1326 if (mptsas_smhba_setup(mpt)) { 1327 mptsas_log(mpt, CE_WARN, "mptsas phy initialization " 1328 "failed"); 1329 goto fail; 1330 } 1331 1332 /* Check all dma handles allocated in attach */ 1333 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) 1334 != DDI_SUCCESS) || 1335 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) 1336 != DDI_SUCCESS) || 1337 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) 1338 != DDI_SUCCESS) || 1339 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) 1340 != DDI_SUCCESS) || 1341 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) 1342 != DDI_SUCCESS)) { 1343 goto fail; 1344 } 1345 1346 /* Check all acc handles allocated in attach */ 1347 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) || 1348 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) 1349 != DDI_SUCCESS) || 1350 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) 1351 != DDI_SUCCESS) || 1352 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) 1353 != DDI_SUCCESS) || 1354 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) 1355 != DDI_SUCCESS) || 1356 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) 1357 != DDI_SUCCESS) || 1358 (mptsas_check_acc_handle(mpt->m_config_handle) 1359 != DDI_SUCCESS)) { 1360 goto fail; 1361 } 1362 1363 /* 1364 * After this point, we are not going to fail the attach. 1365 */ 1366 /* 1367 * used for mptsas_watch 1368 */ 1369 mptsas_list_add(mpt); 1370 1371 mutex_enter(&mptsas_global_mutex); 1372 if (mptsas_timeouts_enabled == 0) { 1373 mptsas_scsi_watchdog_tick = ddi_prop_get_int(DDI_DEV_T_ANY, 1374 dip, 0, "scsi-watchdog-tick", DEFAULT_WD_TICK); 1375 1376 mptsas_tick = mptsas_scsi_watchdog_tick * 1377 drv_usectohz((clock_t)1000000); 1378 1379 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick); 1380 mptsas_timeouts_enabled = 1; 1381 } 1382 mutex_exit(&mptsas_global_mutex); 1383 1384 /* Print message of HBA present */ 1385 ddi_report_dev(dip); 1386 1387 /* report idle status to pm framework */ 1388 if (mpt->m_options & MPTSAS_OPT_PM) { 1389 (void) pm_idle_component(dip, 0); 1390 } 1391 1392 return (DDI_SUCCESS); 1393 1394 fail: 1395 mptsas_log(mpt, CE_WARN, "attach failed"); 1396 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 1397 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 1398 if (mpt) { 1399 mutex_enter(&mptsas_global_mutex); 1400 1401 if (mptsas_timeout_id && (mptsas_head == NULL)) { 1402 timeout_id_t tid = mptsas_timeout_id; 1403 mptsas_timeouts_enabled = 0; 1404 mptsas_timeout_id = 0; 1405 mutex_exit(&mptsas_global_mutex); 1406 (void) untimeout(tid); 1407 mutex_enter(&mptsas_global_mutex); 1408 } 1409 mutex_exit(&mptsas_global_mutex); 1410 /* deallocate in reverse order */ 1411 mptsas_cache_destroy(mpt); 1412 1413 if (smp_attach_setup) { 1414 mptsas_smp_teardown(mpt); 1415 } 1416 if (hba_attach_setup) { 1417 mptsas_hba_teardown(mpt); 1418 } 1419 1420 if (mpt->m_active) { 1421 mptsas_hash_uninit(&mpt->m_active->m_smptbl, 1422 sizeof (mptsas_smp_t)); 1423 mptsas_hash_uninit(&mpt->m_active->m_tgttbl, 1424 sizeof (mptsas_target_t)); 1425 mptsas_free_active_slots(mpt); 1426 } 1427 if (intr_added) { 1428 mptsas_unregister_intrs(mpt); 1429 } 1430 1431 if (doneq_thread_create) { 1432 mutex_enter(&mpt->m_doneq_mutex); 1433 doneq_thread_num = mpt->m_doneq_thread_n; 1434 for (j = 0; j < mpt->m_doneq_thread_n; j++) { 1435 mutex_enter(&mpt->m_doneq_thread_id[j].mutex); 1436 mpt->m_doneq_thread_id[j].flag &= 1437 (~MPTSAS_DONEQ_THREAD_ACTIVE); 1438 cv_signal(&mpt->m_doneq_thread_id[j].cv); 1439 mutex_exit(&mpt->m_doneq_thread_id[j].mutex); 1440 } 1441 while (mpt->m_doneq_thread_n) { 1442 cv_wait(&mpt->m_doneq_thread_cv, 1443 &mpt->m_doneq_mutex); 1444 } 1445 for (j = 0; j < doneq_thread_num; j++) { 1446 cv_destroy(&mpt->m_doneq_thread_id[j].cv); 1447 mutex_destroy(&mpt->m_doneq_thread_id[j].mutex); 1448 } 1449 kmem_free(mpt->m_doneq_thread_id, 1450 sizeof (mptsas_doneq_thread_list_t) 1451 * doneq_thread_num); 1452 mutex_exit(&mpt->m_doneq_mutex); 1453 cv_destroy(&mpt->m_doneq_thread_cv); 1454 mutex_destroy(&mpt->m_doneq_mutex); 1455 } 1456 if (event_taskq_create) { 1457 ddi_taskq_destroy(mpt->m_event_taskq); 1458 } 1459 if (dr_taskq_create) { 1460 ddi_taskq_destroy(mpt->m_dr_taskq); 1461 } 1462 if (mutex_init_done) { 1463 mutex_destroy(&mpt->m_intr_mutex); 1464 mutex_destroy(&mpt->m_passthru_mutex); 1465 mutex_destroy(&mpt->m_mutex); 1466 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1467 mutex_destroy( 1468 &mpt->m_phy_info[i].smhba_info.phy_mutex); 1469 } 1470 cv_destroy(&mpt->m_cv); 1471 cv_destroy(&mpt->m_passthru_cv); 1472 cv_destroy(&mpt->m_fw_cv); 1473 cv_destroy(&mpt->m_config_cv); 1474 cv_destroy(&mpt->m_fw_diag_cv); 1475 } 1476 1477 if (map_setup) { 1478 mptsas_cfg_fini(mpt); 1479 } 1480 if (config_setup) { 1481 mptsas_config_space_fini(mpt); 1482 } 1483 mptsas_free_handshake_msg(mpt); 1484 mptsas_hba_fini(mpt); 1485 1486 mptsas_fm_fini(mpt); 1487 ddi_soft_state_free(mptsas_state, instance); 1488 ddi_prop_remove_all(dip); 1489 } 1490 return (DDI_FAILURE); 1491 } 1492 1493 static int 1494 mptsas_suspend(dev_info_t *devi) 1495 { 1496 mptsas_t *mpt, *g; 1497 scsi_hba_tran_t *tran; 1498 1499 if (scsi_hba_iport_unit_address(devi)) { 1500 return (DDI_SUCCESS); 1501 } 1502 1503 if ((tran = ddi_get_driver_private(devi)) == NULL) 1504 return (DDI_SUCCESS); 1505 1506 mpt = TRAN2MPT(tran); 1507 if (!mpt) { 1508 return (DDI_SUCCESS); 1509 } 1510 1511 mutex_enter(&mpt->m_mutex); 1512 1513 if (mpt->m_suspended++) { 1514 mutex_exit(&mpt->m_mutex); 1515 return (DDI_SUCCESS); 1516 } 1517 1518 /* 1519 * Cancel timeout threads for this mpt 1520 */ 1521 if (mpt->m_quiesce_timeid) { 1522 timeout_id_t tid = mpt->m_quiesce_timeid; 1523 mpt->m_quiesce_timeid = 0; 1524 mutex_exit(&mpt->m_mutex); 1525 (void) untimeout(tid); 1526 mutex_enter(&mpt->m_mutex); 1527 } 1528 1529 if (mpt->m_restart_cmd_timeid) { 1530 timeout_id_t tid = mpt->m_restart_cmd_timeid; 1531 mpt->m_restart_cmd_timeid = 0; 1532 mutex_exit(&mpt->m_mutex); 1533 (void) untimeout(tid); 1534 mutex_enter(&mpt->m_mutex); 1535 } 1536 1537 mutex_exit(&mpt->m_mutex); 1538 1539 (void) pm_idle_component(mpt->m_dip, 0); 1540 1541 /* 1542 * Cancel watch threads if all mpts suspended 1543 */ 1544 rw_enter(&mptsas_global_rwlock, RW_WRITER); 1545 for (g = mptsas_head; g != NULL; g = g->m_next) { 1546 if (!g->m_suspended) 1547 break; 1548 } 1549 rw_exit(&mptsas_global_rwlock); 1550 1551 mutex_enter(&mptsas_global_mutex); 1552 if (g == NULL) { 1553 timeout_id_t tid; 1554 1555 mptsas_timeouts_enabled = 0; 1556 if (mptsas_timeout_id) { 1557 tid = mptsas_timeout_id; 1558 mptsas_timeout_id = 0; 1559 mutex_exit(&mptsas_global_mutex); 1560 (void) untimeout(tid); 1561 mutex_enter(&mptsas_global_mutex); 1562 } 1563 if (mptsas_reset_watch) { 1564 tid = mptsas_reset_watch; 1565 mptsas_reset_watch = 0; 1566 mutex_exit(&mptsas_global_mutex); 1567 (void) untimeout(tid); 1568 mutex_enter(&mptsas_global_mutex); 1569 } 1570 } 1571 mutex_exit(&mptsas_global_mutex); 1572 1573 mutex_enter(&mpt->m_mutex); 1574 1575 /* 1576 * If this mpt is not in full power(PM_LEVEL_D0), just return. 1577 */ 1578 if ((mpt->m_options & MPTSAS_OPT_PM) && 1579 (mpt->m_power_level != PM_LEVEL_D0)) { 1580 mutex_exit(&mpt->m_mutex); 1581 return (DDI_SUCCESS); 1582 } 1583 1584 /* Disable HBA interrupts in hardware */ 1585 MPTSAS_DISABLE_INTR(mpt); 1586 /* 1587 * Send RAID action system shutdown to sync IR 1588 */ 1589 mptsas_raid_action_system_shutdown(mpt); 1590 1591 mutex_exit(&mpt->m_mutex); 1592 1593 /* drain the taskq */ 1594 ddi_taskq_wait(mpt->m_event_taskq); 1595 ddi_taskq_wait(mpt->m_dr_taskq); 1596 1597 return (DDI_SUCCESS); 1598 } 1599 1600 #ifdef __sparc 1601 /*ARGSUSED*/ 1602 static int 1603 mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd) 1604 { 1605 mptsas_t *mpt; 1606 scsi_hba_tran_t *tran; 1607 1608 /* 1609 * If this call is for iport, just return. 1610 */ 1611 if (scsi_hba_iport_unit_address(devi)) 1612 return (DDI_SUCCESS); 1613 1614 if ((tran = ddi_get_driver_private(devi)) == NULL) 1615 return (DDI_SUCCESS); 1616 1617 if ((mpt = TRAN2MPT(tran)) == NULL) 1618 return (DDI_SUCCESS); 1619 1620 /* 1621 * Send RAID action system shutdown to sync IR. Disable HBA 1622 * interrupts in hardware first. 1623 */ 1624 MPTSAS_DISABLE_INTR(mpt); 1625 mptsas_raid_action_system_shutdown(mpt); 1626 1627 return (DDI_SUCCESS); 1628 } 1629 #else /* __sparc */ 1630 /* 1631 * quiesce(9E) entry point. 1632 * 1633 * This function is called when the system is single-threaded at high 1634 * PIL with preemption disabled. Therefore, this function must not be 1635 * blocked. 1636 * 1637 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 1638 * DDI_FAILURE indicates an error condition and should almost never happen. 1639 */ 1640 static int 1641 mptsas_quiesce(dev_info_t *devi) 1642 { 1643 mptsas_t *mpt; 1644 scsi_hba_tran_t *tran; 1645 1646 /* 1647 * If this call is for iport, just return. 1648 */ 1649 if (scsi_hba_iport_unit_address(devi)) 1650 return (DDI_SUCCESS); 1651 1652 if ((tran = ddi_get_driver_private(devi)) == NULL) 1653 return (DDI_SUCCESS); 1654 1655 if ((mpt = TRAN2MPT(tran)) == NULL) 1656 return (DDI_SUCCESS); 1657 1658 /* Disable HBA interrupts in hardware */ 1659 MPTSAS_DISABLE_INTR(mpt); 1660 /* Send RAID action system shutdonw to sync IR */ 1661 mptsas_raid_action_system_shutdown(mpt); 1662 1663 return (DDI_SUCCESS); 1664 } 1665 #endif /* __sparc */ 1666 1667 /* 1668 * detach(9E). Remove all device allocations and system resources; 1669 * disable device interrupts. 1670 * Return DDI_SUCCESS if done; DDI_FAILURE if there's a problem. 1671 */ 1672 static int 1673 mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 1674 { 1675 /* CONSTCOND */ 1676 ASSERT(NO_COMPETING_THREADS); 1677 NDBG0(("mptsas_detach: dip=0x%p cmd=0x%p", (void *)devi, (void *)cmd)); 1678 1679 switch (cmd) { 1680 case DDI_DETACH: 1681 return (mptsas_do_detach(devi)); 1682 1683 case DDI_SUSPEND: 1684 return (mptsas_suspend(devi)); 1685 1686 default: 1687 return (DDI_FAILURE); 1688 } 1689 /* NOTREACHED */ 1690 } 1691 1692 static int 1693 mptsas_do_detach(dev_info_t *dip) 1694 { 1695 mptsas_t *mpt; 1696 scsi_hba_tran_t *tran; 1697 int circ = 0; 1698 int circ1 = 0; 1699 mdi_pathinfo_t *pip = NULL; 1700 int i; 1701 int doneq_thread_num = 0; 1702 1703 NDBG0(("mptsas_do_detach: dip=0x%p", (void *)dip)); 1704 1705 if ((tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == NULL) 1706 return (DDI_FAILURE); 1707 1708 mpt = TRAN2MPT(tran); 1709 if (!mpt) { 1710 return (DDI_FAILURE); 1711 } 1712 /* 1713 * Still have pathinfo child, should not detach mpt driver 1714 */ 1715 if (scsi_hba_iport_unit_address(dip)) { 1716 if (mpt->m_mpxio_enable) { 1717 /* 1718 * MPxIO enabled for the iport 1719 */ 1720 ndi_devi_enter(scsi_vhci_dip, &circ1); 1721 ndi_devi_enter(dip, &circ); 1722 while (pip = mdi_get_next_client_path(dip, NULL)) { 1723 if (mdi_pi_free(pip, 0) == MDI_SUCCESS) { 1724 continue; 1725 } 1726 ndi_devi_exit(dip, circ); 1727 ndi_devi_exit(scsi_vhci_dip, circ1); 1728 NDBG12(("detach failed because of " 1729 "outstanding path info")); 1730 return (DDI_FAILURE); 1731 } 1732 ndi_devi_exit(dip, circ); 1733 ndi_devi_exit(scsi_vhci_dip, circ1); 1734 (void) mdi_phci_unregister(dip, 0); 1735 } 1736 1737 ddi_prop_remove_all(dip); 1738 1739 return (DDI_SUCCESS); 1740 } 1741 1742 /* Make sure power level is D0 before accessing registers */ 1743 if (mpt->m_options & MPTSAS_OPT_PM) { 1744 (void) pm_busy_component(dip, 0); 1745 if (mpt->m_power_level != PM_LEVEL_D0) { 1746 if (pm_raise_power(dip, 0, PM_LEVEL_D0) != 1747 DDI_SUCCESS) { 1748 mptsas_log(mpt, CE_WARN, 1749 "mptsas%d: Raise power request failed.", 1750 mpt->m_instance); 1751 (void) pm_idle_component(dip, 0); 1752 return (DDI_FAILURE); 1753 } 1754 } 1755 } 1756 1757 /* 1758 * Send RAID action system shutdown to sync IR. After action, send a 1759 * Message Unit Reset. Since after that DMA resource will be freed, 1760 * set ioc to READY state will avoid HBA initiated DMA operation. 1761 */ 1762 mutex_enter(&mpt->m_mutex); 1763 MPTSAS_DISABLE_INTR(mpt); 1764 mptsas_raid_action_system_shutdown(mpt); 1765 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1766 (void) mptsas_ioc_reset(mpt, FALSE); 1767 mutex_exit(&mpt->m_mutex); 1768 mptsas_rem_intrs(mpt); 1769 ddi_taskq_destroy(mpt->m_event_taskq); 1770 ddi_taskq_destroy(mpt->m_dr_taskq); 1771 1772 if (mpt->m_doneq_thread_n) { 1773 mutex_enter(&mpt->m_doneq_mutex); 1774 doneq_thread_num = mpt->m_doneq_thread_n; 1775 for (i = 0; i < mpt->m_doneq_thread_n; i++) { 1776 mutex_enter(&mpt->m_doneq_thread_id[i].mutex); 1777 mpt->m_doneq_thread_id[i].flag &= 1778 (~MPTSAS_DONEQ_THREAD_ACTIVE); 1779 cv_signal(&mpt->m_doneq_thread_id[i].cv); 1780 mutex_exit(&mpt->m_doneq_thread_id[i].mutex); 1781 } 1782 while (mpt->m_doneq_thread_n) { 1783 cv_wait(&mpt->m_doneq_thread_cv, 1784 &mpt->m_doneq_mutex); 1785 } 1786 for (i = 0; i < doneq_thread_num; i++) { 1787 cv_destroy(&mpt->m_doneq_thread_id[i].cv); 1788 mutex_destroy(&mpt->m_doneq_thread_id[i].mutex); 1789 } 1790 kmem_free(mpt->m_doneq_thread_id, 1791 sizeof (mptsas_doneq_thread_list_t) 1792 * doneq_thread_num); 1793 mutex_exit(&mpt->m_doneq_mutex); 1794 cv_destroy(&mpt->m_doneq_thread_cv); 1795 mutex_destroy(&mpt->m_doneq_mutex); 1796 } 1797 1798 scsi_hba_reset_notify_tear_down(mpt->m_reset_notify_listf); 1799 1800 mptsas_list_del(mpt); 1801 1802 /* 1803 * Cancel timeout threads for this mpt 1804 */ 1805 mutex_enter(&mpt->m_mutex); 1806 if (mpt->m_quiesce_timeid) { 1807 timeout_id_t tid = mpt->m_quiesce_timeid; 1808 mpt->m_quiesce_timeid = 0; 1809 mutex_exit(&mpt->m_mutex); 1810 (void) untimeout(tid); 1811 mutex_enter(&mpt->m_mutex); 1812 } 1813 1814 if (mpt->m_restart_cmd_timeid) { 1815 timeout_id_t tid = mpt->m_restart_cmd_timeid; 1816 mpt->m_restart_cmd_timeid = 0; 1817 mutex_exit(&mpt->m_mutex); 1818 (void) untimeout(tid); 1819 mutex_enter(&mpt->m_mutex); 1820 } 1821 1822 mutex_exit(&mpt->m_mutex); 1823 1824 /* 1825 * last mpt? ... if active, CANCEL watch threads. 1826 */ 1827 mutex_enter(&mptsas_global_mutex); 1828 if (mptsas_head == NULL) { 1829 timeout_id_t tid; 1830 /* 1831 * Clear mptsas_timeouts_enable so that the watch thread 1832 * gets restarted on DDI_ATTACH 1833 */ 1834 mptsas_timeouts_enabled = 0; 1835 if (mptsas_timeout_id) { 1836 tid = mptsas_timeout_id; 1837 mptsas_timeout_id = 0; 1838 mutex_exit(&mptsas_global_mutex); 1839 (void) untimeout(tid); 1840 mutex_enter(&mptsas_global_mutex); 1841 } 1842 if (mptsas_reset_watch) { 1843 tid = mptsas_reset_watch; 1844 mptsas_reset_watch = 0; 1845 mutex_exit(&mptsas_global_mutex); 1846 (void) untimeout(tid); 1847 mutex_enter(&mptsas_global_mutex); 1848 } 1849 } 1850 mutex_exit(&mptsas_global_mutex); 1851 1852 /* 1853 * Delete Phy stats 1854 */ 1855 mptsas_destroy_phy_stats(mpt); 1856 1857 /* 1858 * Delete nt_active. 1859 */ 1860 mutex_enter(&mpt->m_mutex); 1861 mptsas_hash_uninit(&mpt->m_active->m_tgttbl, sizeof (mptsas_target_t)); 1862 mptsas_hash_uninit(&mpt->m_active->m_smptbl, sizeof (mptsas_smp_t)); 1863 mptsas_free_active_slots(mpt); 1864 mutex_exit(&mpt->m_mutex); 1865 1866 /* deallocate everything that was allocated in mptsas_attach */ 1867 mptsas_cache_destroy(mpt); 1868 1869 mptsas_hba_fini(mpt); 1870 mptsas_cfg_fini(mpt); 1871 1872 /* Lower the power informing PM Framework */ 1873 if (mpt->m_options & MPTSAS_OPT_PM) { 1874 if (pm_lower_power(dip, 0, PM_LEVEL_D3) != DDI_SUCCESS) 1875 mptsas_log(mpt, CE_WARN, 1876 "!mptsas%d: Lower power request failed " 1877 "during detach, ignoring.", 1878 mpt->m_instance); 1879 } 1880 1881 mutex_destroy(&mpt->m_intr_mutex); 1882 mutex_destroy(&mpt->m_passthru_mutex); 1883 mutex_destroy(&mpt->m_mutex); 1884 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1885 mutex_destroy(&mpt->m_phy_info[i].smhba_info.phy_mutex); 1886 } 1887 cv_destroy(&mpt->m_cv); 1888 cv_destroy(&mpt->m_passthru_cv); 1889 cv_destroy(&mpt->m_fw_cv); 1890 cv_destroy(&mpt->m_config_cv); 1891 cv_destroy(&mpt->m_fw_diag_cv); 1892 1893 1894 mptsas_smp_teardown(mpt); 1895 mptsas_hba_teardown(mpt); 1896 1897 mptsas_config_space_fini(mpt); 1898 1899 mptsas_free_handshake_msg(mpt); 1900 1901 mptsas_fm_fini(mpt); 1902 ddi_soft_state_free(mptsas_state, ddi_get_instance(dip)); 1903 ddi_prop_remove_all(dip); 1904 1905 return (DDI_SUCCESS); 1906 } 1907 1908 static void 1909 mptsas_list_add(mptsas_t *mpt) 1910 { 1911 rw_enter(&mptsas_global_rwlock, RW_WRITER); 1912 1913 if (mptsas_head == NULL) { 1914 mptsas_head = mpt; 1915 } else { 1916 mptsas_tail->m_next = mpt; 1917 } 1918 mptsas_tail = mpt; 1919 rw_exit(&mptsas_global_rwlock); 1920 } 1921 1922 static void 1923 mptsas_list_del(mptsas_t *mpt) 1924 { 1925 mptsas_t *m; 1926 /* 1927 * Remove device instance from the global linked list 1928 */ 1929 rw_enter(&mptsas_global_rwlock, RW_WRITER); 1930 if (mptsas_head == mpt) { 1931 m = mptsas_head = mpt->m_next; 1932 } else { 1933 for (m = mptsas_head; m != NULL; m = m->m_next) { 1934 if (m->m_next == mpt) { 1935 m->m_next = mpt->m_next; 1936 break; 1937 } 1938 } 1939 if (m == NULL) { 1940 mptsas_log(mpt, CE_PANIC, "Not in softc list!"); 1941 } 1942 } 1943 1944 if (mptsas_tail == mpt) { 1945 mptsas_tail = m; 1946 } 1947 rw_exit(&mptsas_global_rwlock); 1948 } 1949 1950 static int 1951 mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size) 1952 { 1953 ddi_dma_attr_t task_dma_attrs; 1954 1955 task_dma_attrs = mpt->m_msg_dma_attr; 1956 task_dma_attrs.dma_attr_sgllen = 1; 1957 task_dma_attrs.dma_attr_granular = (uint32_t)(alloc_size); 1958 1959 /* allocate Task Management ddi_dma resources */ 1960 if (mptsas_dma_addr_create(mpt, task_dma_attrs, 1961 &mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl, &mpt->m_hshk_memp, 1962 alloc_size, NULL) == FALSE) { 1963 return (DDI_FAILURE); 1964 } 1965 mpt->m_hshk_dma_size = alloc_size; 1966 1967 return (DDI_SUCCESS); 1968 } 1969 1970 static void 1971 mptsas_free_handshake_msg(mptsas_t *mpt) 1972 { 1973 mptsas_dma_addr_destroy(&mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl); 1974 mpt->m_hshk_dma_size = 0; 1975 } 1976 1977 static int 1978 mptsas_hba_setup(mptsas_t *mpt) 1979 { 1980 scsi_hba_tran_t *hba_tran; 1981 int tran_flags; 1982 1983 /* Allocate a transport structure */ 1984 hba_tran = mpt->m_tran = scsi_hba_tran_alloc(mpt->m_dip, 1985 SCSI_HBA_CANSLEEP); 1986 ASSERT(mpt->m_tran != NULL); 1987 1988 hba_tran->tran_hba_private = mpt; 1989 hba_tran->tran_tgt_private = NULL; 1990 1991 hba_tran->tran_tgt_init = mptsas_scsi_tgt_init; 1992 hba_tran->tran_tgt_free = mptsas_scsi_tgt_free; 1993 1994 hba_tran->tran_start = mptsas_scsi_start; 1995 hba_tran->tran_reset = mptsas_scsi_reset; 1996 hba_tran->tran_abort = mptsas_scsi_abort; 1997 hba_tran->tran_getcap = mptsas_scsi_getcap; 1998 hba_tran->tran_setcap = mptsas_scsi_setcap; 1999 hba_tran->tran_init_pkt = mptsas_scsi_init_pkt; 2000 hba_tran->tran_destroy_pkt = mptsas_scsi_destroy_pkt; 2001 2002 hba_tran->tran_dmafree = mptsas_scsi_dmafree; 2003 hba_tran->tran_sync_pkt = mptsas_scsi_sync_pkt; 2004 hba_tran->tran_reset_notify = mptsas_scsi_reset_notify; 2005 2006 hba_tran->tran_get_bus_addr = mptsas_get_bus_addr; 2007 hba_tran->tran_get_name = mptsas_get_name; 2008 2009 hba_tran->tran_quiesce = mptsas_scsi_quiesce; 2010 hba_tran->tran_unquiesce = mptsas_scsi_unquiesce; 2011 hba_tran->tran_bus_reset = NULL; 2012 2013 hba_tran->tran_add_eventcall = NULL; 2014 hba_tran->tran_get_eventcookie = NULL; 2015 hba_tran->tran_post_event = NULL; 2016 hba_tran->tran_remove_eventcall = NULL; 2017 2018 hba_tran->tran_bus_config = mptsas_bus_config; 2019 2020 hba_tran->tran_interconnect_type = INTERCONNECT_SAS; 2021 2022 /* 2023 * All children of the HBA are iports. We need tran was cloned. 2024 * So we pass the flags to SCSA. SCSI_HBA_TRAN_CLONE will be 2025 * inherited to iport's tran vector. 2026 */ 2027 tran_flags = (SCSI_HBA_HBA | SCSI_HBA_TRAN_CLONE); 2028 2029 if (scsi_hba_attach_setup(mpt->m_dip, &mpt->m_msg_dma_attr, 2030 hba_tran, tran_flags) != DDI_SUCCESS) { 2031 mptsas_log(mpt, CE_WARN, "hba attach setup failed"); 2032 scsi_hba_tran_free(hba_tran); 2033 mpt->m_tran = NULL; 2034 return (FALSE); 2035 } 2036 return (TRUE); 2037 } 2038 2039 static void 2040 mptsas_hba_teardown(mptsas_t *mpt) 2041 { 2042 (void) scsi_hba_detach(mpt->m_dip); 2043 if (mpt->m_tran != NULL) { 2044 scsi_hba_tran_free(mpt->m_tran); 2045 mpt->m_tran = NULL; 2046 } 2047 } 2048 2049 static void 2050 mptsas_iport_register(mptsas_t *mpt) 2051 { 2052 int i, j; 2053 mptsas_phymask_t mask = 0x0; 2054 /* 2055 * initial value of mask is 0 2056 */ 2057 mutex_enter(&mpt->m_mutex); 2058 for (i = 0; i < mpt->m_num_phys; i++) { 2059 mptsas_phymask_t phy_mask = 0x0; 2060 char phy_mask_name[MPTSAS_MAX_PHYS]; 2061 uint8_t current_port; 2062 2063 if (mpt->m_phy_info[i].attached_devhdl == 0) 2064 continue; 2065 2066 bzero(phy_mask_name, sizeof (phy_mask_name)); 2067 2068 current_port = mpt->m_phy_info[i].port_num; 2069 2070 if ((mask & (1 << i)) != 0) 2071 continue; 2072 2073 for (j = 0; j < mpt->m_num_phys; j++) { 2074 if (mpt->m_phy_info[j].attached_devhdl && 2075 (mpt->m_phy_info[j].port_num == current_port)) { 2076 phy_mask |= (1 << j); 2077 } 2078 } 2079 mask = mask | phy_mask; 2080 2081 for (j = 0; j < mpt->m_num_phys; j++) { 2082 if ((phy_mask >> j) & 0x01) { 2083 mpt->m_phy_info[j].phy_mask = phy_mask; 2084 } 2085 } 2086 2087 (void) sprintf(phy_mask_name, "%x", phy_mask); 2088 2089 mutex_exit(&mpt->m_mutex); 2090 /* 2091 * register a iport 2092 */ 2093 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name); 2094 mutex_enter(&mpt->m_mutex); 2095 } 2096 mutex_exit(&mpt->m_mutex); 2097 /* 2098 * register a virtual port for RAID volume always 2099 */ 2100 (void) scsi_hba_iport_register(mpt->m_dip, "v0"); 2101 2102 } 2103 2104 static int 2105 mptsas_smp_setup(mptsas_t *mpt) 2106 { 2107 mpt->m_smptran = smp_hba_tran_alloc(mpt->m_dip); 2108 ASSERT(mpt->m_smptran != NULL); 2109 mpt->m_smptran->smp_tran_hba_private = mpt; 2110 mpt->m_smptran->smp_tran_start = mptsas_smp_start; 2111 if (smp_hba_attach_setup(mpt->m_dip, mpt->m_smptran) != DDI_SUCCESS) { 2112 mptsas_log(mpt, CE_WARN, "smp attach setup failed"); 2113 smp_hba_tran_free(mpt->m_smptran); 2114 mpt->m_smptran = NULL; 2115 return (FALSE); 2116 } 2117 /* 2118 * Initialize smp hash table 2119 */ 2120 mptsas_hash_init(&mpt->m_active->m_smptbl); 2121 mpt->m_smp_devhdl = 0xFFFF; 2122 2123 return (TRUE); 2124 } 2125 2126 static void 2127 mptsas_smp_teardown(mptsas_t *mpt) 2128 { 2129 (void) smp_hba_detach(mpt->m_dip); 2130 if (mpt->m_smptran != NULL) { 2131 smp_hba_tran_free(mpt->m_smptran); 2132 mpt->m_smptran = NULL; 2133 } 2134 mpt->m_smp_devhdl = 0; 2135 } 2136 2137 static int 2138 mptsas_cache_create(mptsas_t *mpt) 2139 { 2140 int instance = mpt->m_instance; 2141 char buf[64]; 2142 2143 /* 2144 * create kmem cache for packets 2145 */ 2146 (void) sprintf(buf, "mptsas%d_cache", instance); 2147 mpt->m_kmem_cache = kmem_cache_create(buf, 2148 sizeof (struct mptsas_cmd) + scsi_pkt_size(), 8, 2149 mptsas_kmem_cache_constructor, mptsas_kmem_cache_destructor, 2150 NULL, (void *)mpt, NULL, 0); 2151 2152 if (mpt->m_kmem_cache == NULL) { 2153 mptsas_log(mpt, CE_WARN, "creating kmem cache failed"); 2154 return (FALSE); 2155 } 2156 2157 /* 2158 * create kmem cache for extra SGL frames if SGL cannot 2159 * be accomodated into main request frame. 2160 */ 2161 (void) sprintf(buf, "mptsas%d_cache_frames", instance); 2162 mpt->m_cache_frames = kmem_cache_create(buf, 2163 sizeof (mptsas_cache_frames_t), 8, 2164 mptsas_cache_frames_constructor, mptsas_cache_frames_destructor, 2165 NULL, (void *)mpt, NULL, 0); 2166 2167 if (mpt->m_cache_frames == NULL) { 2168 mptsas_log(mpt, CE_WARN, "creating cache for frames failed"); 2169 return (FALSE); 2170 } 2171 2172 return (TRUE); 2173 } 2174 2175 static void 2176 mptsas_cache_destroy(mptsas_t *mpt) 2177 { 2178 /* deallocate in reverse order */ 2179 if (mpt->m_cache_frames) { 2180 kmem_cache_destroy(mpt->m_cache_frames); 2181 mpt->m_cache_frames = NULL; 2182 } 2183 if (mpt->m_kmem_cache) { 2184 kmem_cache_destroy(mpt->m_kmem_cache); 2185 mpt->m_kmem_cache = NULL; 2186 } 2187 } 2188 2189 static int 2190 mptsas_power(dev_info_t *dip, int component, int level) 2191 { 2192 #ifndef __lock_lint 2193 _NOTE(ARGUNUSED(component)) 2194 #endif 2195 mptsas_t *mpt; 2196 int rval = DDI_SUCCESS; 2197 int polls = 0; 2198 uint32_t ioc_status; 2199 2200 if (scsi_hba_iport_unit_address(dip) != 0) 2201 return (DDI_SUCCESS); 2202 2203 mpt = ddi_get_soft_state(mptsas_state, ddi_get_instance(dip)); 2204 if (mpt == NULL) { 2205 return (DDI_FAILURE); 2206 } 2207 2208 mutex_enter(&mpt->m_mutex); 2209 2210 /* 2211 * If the device is busy, don't lower its power level 2212 */ 2213 if (mpt->m_busy && (mpt->m_power_level > level)) { 2214 mutex_exit(&mpt->m_mutex); 2215 return (DDI_FAILURE); 2216 } 2217 switch (level) { 2218 case PM_LEVEL_D0: 2219 NDBG11(("mptsas%d: turning power ON.", mpt->m_instance)); 2220 MPTSAS_POWER_ON(mpt); 2221 /* 2222 * Wait up to 30 seconds for IOC to come out of reset. 2223 */ 2224 while (((ioc_status = ddi_get32(mpt->m_datap, 2225 &mpt->m_reg->Doorbell)) & 2226 MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_RESET) { 2227 if (polls++ > 3000) { 2228 break; 2229 } 2230 delay(drv_usectohz(10000)); 2231 } 2232 /* 2233 * If IOC is not in operational state, try to hard reset it. 2234 */ 2235 if ((ioc_status & MPI2_IOC_STATE_MASK) != 2236 MPI2_IOC_STATE_OPERATIONAL) { 2237 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 2238 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) { 2239 mptsas_log(mpt, CE_WARN, 2240 "mptsas_power: hard reset failed"); 2241 mutex_exit(&mpt->m_mutex); 2242 return (DDI_FAILURE); 2243 } 2244 } 2245 mutex_enter(&mpt->m_intr_mutex); 2246 mpt->m_power_level = PM_LEVEL_D0; 2247 mutex_exit(&mpt->m_intr_mutex); 2248 break; 2249 case PM_LEVEL_D3: 2250 NDBG11(("mptsas%d: turning power OFF.", mpt->m_instance)); 2251 MPTSAS_POWER_OFF(mpt); 2252 break; 2253 default: 2254 mptsas_log(mpt, CE_WARN, "mptsas%d: unknown power level <%x>.", 2255 mpt->m_instance, level); 2256 rval = DDI_FAILURE; 2257 break; 2258 } 2259 mutex_exit(&mpt->m_mutex); 2260 return (rval); 2261 } 2262 2263 /* 2264 * Initialize configuration space and figure out which 2265 * chip and revison of the chip the mpt driver is using. 2266 */ 2267 static int 2268 mptsas_config_space_init(mptsas_t *mpt) 2269 { 2270 NDBG0(("mptsas_config_space_init")); 2271 2272 if (mpt->m_config_handle != NULL) 2273 return (TRUE); 2274 2275 if (pci_config_setup(mpt->m_dip, 2276 &mpt->m_config_handle) != DDI_SUCCESS) { 2277 mptsas_log(mpt, CE_WARN, "cannot map configuration space."); 2278 return (FALSE); 2279 } 2280 2281 /* 2282 * This is a workaround for a XMITS ASIC bug which does not 2283 * drive the CBE upper bits. 2284 */ 2285 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) & 2286 PCI_STAT_PERROR) { 2287 pci_config_put16(mpt->m_config_handle, PCI_CONF_STAT, 2288 PCI_STAT_PERROR); 2289 } 2290 2291 mptsas_setup_cmd_reg(mpt); 2292 2293 /* 2294 * Get the chip device id: 2295 */ 2296 mpt->m_devid = pci_config_get16(mpt->m_config_handle, PCI_CONF_DEVID); 2297 2298 /* 2299 * Save the revision. 2300 */ 2301 mpt->m_revid = pci_config_get8(mpt->m_config_handle, PCI_CONF_REVID); 2302 2303 /* 2304 * Save the SubSystem Vendor and Device IDs 2305 */ 2306 mpt->m_svid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBVENID); 2307 mpt->m_ssid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBSYSID); 2308 2309 /* 2310 * Set the latency timer to 0x40 as specified by the upa -> pci 2311 * bridge chip design team. This may be done by the sparc pci 2312 * bus nexus driver, but the driver should make sure the latency 2313 * timer is correct for performance reasons. 2314 */ 2315 pci_config_put8(mpt->m_config_handle, PCI_CONF_LATENCY_TIMER, 2316 MPTSAS_LATENCY_TIMER); 2317 2318 (void) mptsas_get_pci_cap(mpt); 2319 return (TRUE); 2320 } 2321 2322 static void 2323 mptsas_config_space_fini(mptsas_t *mpt) 2324 { 2325 if (mpt->m_config_handle != NULL) { 2326 mptsas_disable_bus_master(mpt); 2327 pci_config_teardown(&mpt->m_config_handle); 2328 mpt->m_config_handle = NULL; 2329 } 2330 } 2331 2332 static void 2333 mptsas_setup_cmd_reg(mptsas_t *mpt) 2334 { 2335 ushort_t cmdreg; 2336 2337 /* 2338 * Set the command register to the needed values. 2339 */ 2340 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM); 2341 cmdreg |= (PCI_COMM_ME | PCI_COMM_SERR_ENABLE | 2342 PCI_COMM_PARITY_DETECT | PCI_COMM_MAE); 2343 cmdreg &= ~PCI_COMM_IO; 2344 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg); 2345 } 2346 2347 static void 2348 mptsas_disable_bus_master(mptsas_t *mpt) 2349 { 2350 ushort_t cmdreg; 2351 2352 /* 2353 * Clear the master enable bit in the PCI command register. 2354 * This prevents any bus mastering activity like DMA. 2355 */ 2356 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM); 2357 cmdreg &= ~PCI_COMM_ME; 2358 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg); 2359 } 2360 2361 int 2362 mptsas_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep) 2363 { 2364 ddi_dma_attr_t attrs; 2365 2366 attrs = mpt->m_io_dma_attr; 2367 attrs.dma_attr_sgllen = 1; 2368 2369 ASSERT(dma_statep != NULL); 2370 2371 if (mptsas_dma_addr_create(mpt, attrs, &dma_statep->handle, 2372 &dma_statep->accessp, &dma_statep->memp, dma_statep->size, 2373 &dma_statep->cookie) == FALSE) { 2374 return (DDI_FAILURE); 2375 } 2376 2377 return (DDI_SUCCESS); 2378 } 2379 2380 void 2381 mptsas_dma_free(mptsas_dma_alloc_state_t *dma_statep) 2382 { 2383 ASSERT(dma_statep != NULL); 2384 mptsas_dma_addr_destroy(&dma_statep->handle, &dma_statep->accessp); 2385 dma_statep->size = 0; 2386 } 2387 2388 int 2389 mptsas_do_dma(mptsas_t *mpt, uint32_t size, int var, int (*callback)()) 2390 { 2391 ddi_dma_attr_t attrs; 2392 ddi_dma_handle_t dma_handle; 2393 caddr_t memp; 2394 ddi_acc_handle_t accessp; 2395 int rval; 2396 2397 ASSERT(mutex_owned(&mpt->m_mutex)); 2398 2399 attrs = mpt->m_msg_dma_attr; 2400 attrs.dma_attr_sgllen = 1; 2401 attrs.dma_attr_granular = size; 2402 2403 if (mptsas_dma_addr_create(mpt, attrs, &dma_handle, 2404 &accessp, &memp, size, NULL) == FALSE) { 2405 return (DDI_FAILURE); 2406 } 2407 2408 rval = (*callback) (mpt, memp, var, accessp); 2409 2410 if ((mptsas_check_dma_handle(dma_handle) != DDI_SUCCESS) || 2411 (mptsas_check_acc_handle(accessp) != DDI_SUCCESS)) { 2412 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 2413 rval = DDI_FAILURE; 2414 } 2415 2416 mptsas_dma_addr_destroy(&dma_handle, &accessp); 2417 return (rval); 2418 2419 } 2420 2421 static int 2422 mptsas_alloc_request_frames(mptsas_t *mpt) 2423 { 2424 ddi_dma_attr_t frame_dma_attrs; 2425 caddr_t memp; 2426 ddi_dma_cookie_t cookie; 2427 size_t mem_size; 2428 2429 /* 2430 * re-alloc when it has already alloced 2431 */ 2432 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl, 2433 &mpt->m_acc_req_frame_hdl); 2434 2435 /* 2436 * The size of the request frame pool is: 2437 * Number of Request Frames * Request Frame Size 2438 */ 2439 mem_size = mpt->m_max_requests * mpt->m_req_frame_size; 2440 2441 /* 2442 * set the DMA attributes. System Request Message Frames must be 2443 * aligned on a 16-byte boundry. 2444 */ 2445 frame_dma_attrs = mpt->m_msg_dma_attr; 2446 frame_dma_attrs.dma_attr_align = 16; 2447 frame_dma_attrs.dma_attr_sgllen = 1; 2448 2449 /* 2450 * allocate the request frame pool. 2451 */ 2452 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2453 &mpt->m_dma_req_frame_hdl, &mpt->m_acc_req_frame_hdl, &memp, 2454 mem_size, &cookie) == FALSE) { 2455 return (DDI_FAILURE); 2456 } 2457 2458 /* 2459 * Store the request frame memory address. This chip uses this 2460 * address to dma to and from the driver's frame. The second 2461 * address is the address mpt uses to fill in the frame. 2462 */ 2463 mpt->m_req_frame_dma_addr = cookie.dmac_laddress; 2464 mpt->m_req_frame = memp; 2465 2466 /* 2467 * Clear the request frame pool. 2468 */ 2469 bzero(mpt->m_req_frame, mem_size); 2470 2471 return (DDI_SUCCESS); 2472 } 2473 2474 static int 2475 mptsas_alloc_reply_frames(mptsas_t *mpt) 2476 { 2477 ddi_dma_attr_t frame_dma_attrs; 2478 caddr_t memp; 2479 ddi_dma_cookie_t cookie; 2480 size_t mem_size; 2481 2482 /* 2483 * re-alloc when it has already alloced 2484 */ 2485 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl, 2486 &mpt->m_acc_reply_frame_hdl); 2487 2488 /* 2489 * The size of the reply frame pool is: 2490 * Number of Reply Frames * Reply Frame Size 2491 */ 2492 mem_size = mpt->m_max_replies * mpt->m_reply_frame_size; 2493 2494 /* 2495 * set the DMA attributes. System Reply Message Frames must be 2496 * aligned on a 4-byte boundry. This is the default. 2497 */ 2498 frame_dma_attrs = mpt->m_msg_dma_attr; 2499 frame_dma_attrs.dma_attr_sgllen = 1; 2500 2501 /* 2502 * allocate the reply frame pool 2503 */ 2504 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2505 &mpt->m_dma_reply_frame_hdl, &mpt->m_acc_reply_frame_hdl, &memp, 2506 mem_size, &cookie) == FALSE) { 2507 return (DDI_FAILURE); 2508 } 2509 2510 /* 2511 * Store the reply frame memory address. This chip uses this 2512 * address to dma to and from the driver's frame. The second 2513 * address is the address mpt uses to process the frame. 2514 */ 2515 mpt->m_reply_frame_dma_addr = cookie.dmac_laddress; 2516 mpt->m_reply_frame = memp; 2517 2518 /* 2519 * Clear the reply frame pool. 2520 */ 2521 bzero(mpt->m_reply_frame, mem_size); 2522 2523 return (DDI_SUCCESS); 2524 } 2525 2526 static int 2527 mptsas_alloc_free_queue(mptsas_t *mpt) 2528 { 2529 ddi_dma_attr_t frame_dma_attrs; 2530 caddr_t memp; 2531 ddi_dma_cookie_t cookie; 2532 size_t mem_size; 2533 2534 /* 2535 * re-alloc when it has already alloced 2536 */ 2537 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl, 2538 &mpt->m_acc_free_queue_hdl); 2539 2540 /* 2541 * The reply free queue size is: 2542 * Reply Free Queue Depth * 4 2543 * The "4" is the size of one 32 bit address (low part of 64-bit 2544 * address) 2545 */ 2546 mem_size = mpt->m_free_queue_depth * 4; 2547 2548 /* 2549 * set the DMA attributes The Reply Free Queue must be aligned on a 2550 * 16-byte boundry. 2551 */ 2552 frame_dma_attrs = mpt->m_msg_dma_attr; 2553 frame_dma_attrs.dma_attr_align = 16; 2554 frame_dma_attrs.dma_attr_sgllen = 1; 2555 2556 /* 2557 * allocate the reply free queue 2558 */ 2559 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2560 &mpt->m_dma_free_queue_hdl, &mpt->m_acc_free_queue_hdl, &memp, 2561 mem_size, &cookie) == FALSE) { 2562 return (DDI_FAILURE); 2563 } 2564 2565 /* 2566 * Store the reply free queue memory address. This chip uses this 2567 * address to read from the reply free queue. The second address 2568 * is the address mpt uses to manage the queue. 2569 */ 2570 mpt->m_free_queue_dma_addr = cookie.dmac_laddress; 2571 mpt->m_free_queue = memp; 2572 2573 /* 2574 * Clear the reply free queue memory. 2575 */ 2576 bzero(mpt->m_free_queue, mem_size); 2577 2578 return (DDI_SUCCESS); 2579 } 2580 2581 static int 2582 mptsas_alloc_post_queue(mptsas_t *mpt) 2583 { 2584 ddi_dma_attr_t frame_dma_attrs; 2585 caddr_t memp; 2586 ddi_dma_cookie_t cookie; 2587 size_t mem_size; 2588 2589 /* 2590 * re-alloc when it has already alloced 2591 */ 2592 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl, 2593 &mpt->m_acc_post_queue_hdl); 2594 2595 /* 2596 * The reply descriptor post queue size is: 2597 * Reply Descriptor Post Queue Depth * 8 2598 * The "8" is the size of each descriptor (8 bytes or 64 bits). 2599 */ 2600 mem_size = mpt->m_post_queue_depth * 8; 2601 2602 /* 2603 * set the DMA attributes. The Reply Descriptor Post Queue must be 2604 * aligned on a 16-byte boundry. 2605 */ 2606 frame_dma_attrs = mpt->m_msg_dma_attr; 2607 frame_dma_attrs.dma_attr_align = 16; 2608 frame_dma_attrs.dma_attr_sgllen = 1; 2609 2610 /* 2611 * allocate the reply post queue 2612 */ 2613 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2614 &mpt->m_dma_post_queue_hdl, &mpt->m_acc_post_queue_hdl, &memp, 2615 mem_size, &cookie) == FALSE) { 2616 return (DDI_FAILURE); 2617 } 2618 2619 /* 2620 * Store the reply descriptor post queue memory address. This chip 2621 * uses this address to write to the reply descriptor post queue. The 2622 * second address is the address mpt uses to manage the queue. 2623 */ 2624 mpt->m_post_queue_dma_addr = cookie.dmac_laddress; 2625 mpt->m_post_queue = memp; 2626 2627 /* 2628 * Clear the reply post queue memory. 2629 */ 2630 bzero(mpt->m_post_queue, mem_size); 2631 2632 return (DDI_SUCCESS); 2633 } 2634 2635 static void 2636 mptsas_alloc_reply_args(mptsas_t *mpt) 2637 { 2638 if (mpt->m_replyh_args != NULL) { 2639 kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t) 2640 * mpt->m_max_replies); 2641 mpt->m_replyh_args = NULL; 2642 } 2643 mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) * 2644 mpt->m_max_replies, KM_SLEEP); 2645 } 2646 2647 static int 2648 mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd) 2649 { 2650 mptsas_cache_frames_t *frames = NULL; 2651 if (cmd->cmd_extra_frames == NULL) { 2652 frames = kmem_cache_alloc(mpt->m_cache_frames, KM_NOSLEEP); 2653 if (frames == NULL) { 2654 return (DDI_FAILURE); 2655 } 2656 cmd->cmd_extra_frames = frames; 2657 } 2658 return (DDI_SUCCESS); 2659 } 2660 2661 static void 2662 mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd) 2663 { 2664 if (cmd->cmd_extra_frames) { 2665 kmem_cache_free(mpt->m_cache_frames, 2666 (void *)cmd->cmd_extra_frames); 2667 cmd->cmd_extra_frames = NULL; 2668 } 2669 } 2670 2671 static void 2672 mptsas_cfg_fini(mptsas_t *mpt) 2673 { 2674 NDBG0(("mptsas_cfg_fini")); 2675 ddi_regs_map_free(&mpt->m_datap); 2676 } 2677 2678 static void 2679 mptsas_hba_fini(mptsas_t *mpt) 2680 { 2681 NDBG0(("mptsas_hba_fini")); 2682 2683 /* 2684 * Free up any allocated memory 2685 */ 2686 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl, 2687 &mpt->m_acc_req_frame_hdl); 2688 2689 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl, 2690 &mpt->m_acc_reply_frame_hdl); 2691 2692 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl, 2693 &mpt->m_acc_free_queue_hdl); 2694 2695 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl, 2696 &mpt->m_acc_post_queue_hdl); 2697 2698 if (mpt->m_replyh_args != NULL) { 2699 kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t) 2700 * mpt->m_max_replies); 2701 } 2702 } 2703 2704 static int 2705 mptsas_name_child(dev_info_t *lun_dip, char *name, int len) 2706 { 2707 int lun = 0; 2708 char *sas_wwn = NULL; 2709 int phynum = -1; 2710 int reallen = 0; 2711 2712 /* Get the target num */ 2713 lun = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, DDI_PROP_DONTPASS, 2714 LUN_PROP, 0); 2715 2716 if ((phynum = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, 2717 DDI_PROP_DONTPASS, "sata-phy", -1)) != -1) { 2718 /* 2719 * Stick in the address of form "pPHY,LUN" 2720 */ 2721 reallen = snprintf(name, len, "p%x,%x", phynum, lun); 2722 } else if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lun_dip, 2723 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &sas_wwn) 2724 == DDI_PROP_SUCCESS) { 2725 /* 2726 * Stick in the address of the form "wWWN,LUN" 2727 */ 2728 reallen = snprintf(name, len, "%s,%x", sas_wwn, lun); 2729 ddi_prop_free(sas_wwn); 2730 } else { 2731 return (DDI_FAILURE); 2732 } 2733 2734 ASSERT(reallen < len); 2735 if (reallen >= len) { 2736 mptsas_log(0, CE_WARN, "!mptsas_get_name: name parameter " 2737 "length too small, it needs to be %d bytes", reallen + 1); 2738 } 2739 return (DDI_SUCCESS); 2740 } 2741 2742 /* 2743 * tran_tgt_init(9E) - target device instance initialization 2744 */ 2745 static int 2746 mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 2747 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 2748 { 2749 #ifndef __lock_lint 2750 _NOTE(ARGUNUSED(hba_tran)) 2751 #endif 2752 2753 /* 2754 * At this point, the scsi_device structure already exists 2755 * and has been initialized. 2756 * 2757 * Use this function to allocate target-private data structures, 2758 * if needed by this HBA. Add revised flow-control and queue 2759 * properties for child here, if desired and if you can tell they 2760 * support tagged queueing by now. 2761 */ 2762 mptsas_t *mpt; 2763 int lun = sd->sd_address.a_lun; 2764 mdi_pathinfo_t *pip = NULL; 2765 mptsas_tgt_private_t *tgt_private = NULL; 2766 mptsas_target_t *ptgt = NULL; 2767 char *psas_wwn = NULL; 2768 int phymask = 0; 2769 uint64_t sas_wwn = 0; 2770 mpt = SDEV2MPT(sd); 2771 2772 ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0); 2773 2774 NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d", 2775 (void *)hba_dip, (void *)tgt_dip, lun)); 2776 2777 if (ndi_dev_is_persistent_node(tgt_dip) == 0) { 2778 (void) ndi_merge_node(tgt_dip, mptsas_name_child); 2779 ddi_set_name_addr(tgt_dip, NULL); 2780 return (DDI_FAILURE); 2781 } 2782 /* 2783 * phymask is 0 means the virtual port for RAID 2784 */ 2785 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0, 2786 "phymask", 0); 2787 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) { 2788 if ((pip = (void *)(sd->sd_private)) == NULL) { 2789 /* 2790 * Very bad news if this occurs. Somehow scsi_vhci has 2791 * lost the pathinfo node for this target. 2792 */ 2793 return (DDI_NOT_WELL_FORMED); 2794 } 2795 2796 if (mdi_prop_lookup_int(pip, LUN_PROP, &lun) != 2797 DDI_PROP_SUCCESS) { 2798 mptsas_log(mpt, CE_WARN, "Get lun property failed\n"); 2799 return (DDI_FAILURE); 2800 } 2801 2802 if (mdi_prop_lookup_string(pip, SCSI_ADDR_PROP_TARGET_PORT, 2803 &psas_wwn) == MDI_SUCCESS) { 2804 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) { 2805 sas_wwn = 0; 2806 } 2807 (void) mdi_prop_free(psas_wwn); 2808 } 2809 } else { 2810 lun = ddi_prop_get_int(DDI_DEV_T_ANY, tgt_dip, 2811 DDI_PROP_DONTPASS, LUN_PROP, 0); 2812 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, tgt_dip, 2813 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &psas_wwn) == 2814 DDI_PROP_SUCCESS) { 2815 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) { 2816 sas_wwn = 0; 2817 } 2818 ddi_prop_free(psas_wwn); 2819 } else { 2820 sas_wwn = 0; 2821 } 2822 } 2823 ASSERT((sas_wwn != 0) || (phymask != 0)); 2824 mutex_enter(&mpt->m_mutex); 2825 ptgt = mptsas_hash_search(&mpt->m_active->m_tgttbl, sas_wwn, phymask); 2826 mutex_exit(&mpt->m_mutex); 2827 if (ptgt == NULL) { 2828 mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or " 2829 "gone already! phymask:%x, saswwn %"PRIx64, phymask, 2830 sas_wwn); 2831 return (DDI_FAILURE); 2832 } 2833 if (hba_tran->tran_tgt_private == NULL) { 2834 tgt_private = kmem_zalloc(sizeof (mptsas_tgt_private_t), 2835 KM_SLEEP); 2836 tgt_private->t_lun = lun; 2837 tgt_private->t_private = ptgt; 2838 hba_tran->tran_tgt_private = tgt_private; 2839 } 2840 2841 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) { 2842 return (DDI_SUCCESS); 2843 } 2844 mutex_enter(&mpt->m_mutex); 2845 2846 if (ptgt->m_deviceinfo & 2847 (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 2848 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 2849 uchar_t *inq89 = NULL; 2850 int inq89_len = 0x238; 2851 int reallen = 0; 2852 int rval = 0; 2853 struct sata_id *sid = NULL; 2854 char model[SATA_ID_MODEL_LEN + 1]; 2855 char fw[SATA_ID_FW_LEN + 1]; 2856 char *vid, *pid; 2857 int i; 2858 2859 mutex_exit(&mpt->m_mutex); 2860 /* 2861 * According SCSI/ATA Translation -2 (SAT-2) revision 01a 2862 * chapter 12.4.2 VPD page 89h includes 512 bytes ATA IDENTIFY 2863 * DEVICE data or ATA IDENTIFY PACKET DEVICE data. 2864 */ 2865 inq89 = kmem_zalloc(inq89_len, KM_SLEEP); 2866 rval = mptsas_inquiry(mpt, ptgt, 0, 0x89, 2867 inq89, inq89_len, &reallen, 1); 2868 2869 if (rval != 0) { 2870 if (inq89 != NULL) { 2871 kmem_free(inq89, inq89_len); 2872 } 2873 2874 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 2875 "0x89 for SATA target:%x failed!", ptgt->m_devhdl); 2876 return (DDI_SUCCESS); 2877 } 2878 sid = (void *)(&inq89[60]); 2879 2880 swab(sid->ai_model, model, SATA_ID_MODEL_LEN); 2881 swab(sid->ai_fw, fw, SATA_ID_FW_LEN); 2882 2883 model[SATA_ID_MODEL_LEN] = 0; 2884 fw[SATA_ID_FW_LEN] = 0; 2885 2886 /* 2887 * split model into into vid/pid 2888 */ 2889 for (i = 0, pid = model; i < SATA_ID_MODEL_LEN; i++, pid++) 2890 if ((*pid == ' ') || (*pid == '\t')) 2891 break; 2892 if (i < SATA_ID_MODEL_LEN) { 2893 vid = model; 2894 /* 2895 * terminate vid, establish pid 2896 */ 2897 *pid++ = 0; 2898 } else { 2899 /* 2900 * vid will stay "ATA ", the rule is same 2901 * as sata framework implementation. 2902 */ 2903 vid = NULL; 2904 /* 2905 * model is all pid 2906 */ 2907 pid = model; 2908 } 2909 2910 /* 2911 * override SCSA "inquiry-*" properties 2912 */ 2913 if (vid) 2914 (void) scsi_device_prop_update_inqstring(sd, 2915 INQUIRY_VENDOR_ID, vid, strlen(vid)); 2916 if (pid) 2917 (void) scsi_device_prop_update_inqstring(sd, 2918 INQUIRY_PRODUCT_ID, pid, strlen(pid)); 2919 (void) scsi_device_prop_update_inqstring(sd, 2920 INQUIRY_REVISION_ID, fw, strlen(fw)); 2921 2922 if (inq89 != NULL) { 2923 kmem_free(inq89, inq89_len); 2924 } 2925 } else { 2926 mutex_exit(&mpt->m_mutex); 2927 } 2928 2929 return (DDI_SUCCESS); 2930 } 2931 /* 2932 * tran_tgt_free(9E) - target device instance deallocation 2933 */ 2934 static void 2935 mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 2936 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 2937 { 2938 #ifndef __lock_lint 2939 _NOTE(ARGUNUSED(hba_dip, tgt_dip, hba_tran, sd)) 2940 #endif 2941 2942 mptsas_tgt_private_t *tgt_private = hba_tran->tran_tgt_private; 2943 2944 if (tgt_private != NULL) { 2945 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t)); 2946 hba_tran->tran_tgt_private = NULL; 2947 } 2948 } 2949 2950 /* 2951 * scsi_pkt handling 2952 * 2953 * Visible to the external world via the transport structure. 2954 */ 2955 2956 /* 2957 * Notes: 2958 * - transport the command to the addressed SCSI target/lun device 2959 * - normal operation is to schedule the command to be transported, 2960 * and return TRAN_ACCEPT if this is successful. 2961 * - if NO_INTR, tran_start must poll device for command completion 2962 */ 2963 static int 2964 mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt) 2965 { 2966 #ifndef __lock_lint 2967 _NOTE(ARGUNUSED(ap)) 2968 #endif 2969 mptsas_t *mpt = PKT2MPT(pkt); 2970 mptsas_cmd_t *cmd = PKT2CMD(pkt); 2971 int rval; 2972 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 2973 2974 NDBG1(("mptsas_scsi_start: pkt=0x%p", (void *)pkt)); 2975 ASSERT(ptgt); 2976 if (ptgt == NULL) 2977 return (TRAN_FATAL_ERROR); 2978 2979 /* 2980 * prepare the pkt before taking mutex. 2981 */ 2982 rval = mptsas_prepare_pkt(cmd); 2983 if (rval != TRAN_ACCEPT) { 2984 return (rval); 2985 } 2986 2987 /* 2988 * Send the command to target/lun, however your HBA requires it. 2989 * If busy, return TRAN_BUSY; if there's some other formatting error 2990 * in the packet, return TRAN_BADPKT; otherwise, fall through to the 2991 * return of TRAN_ACCEPT. 2992 * 2993 * Remember that access to shared resources, including the mptsas_t 2994 * data structure and the HBA hardware registers, must be protected 2995 * with mutexes, here and everywhere. 2996 * 2997 * Also remember that at interrupt time, you'll get an argument 2998 * to the interrupt handler which is a pointer to your mptsas_t 2999 * structure; you'll have to remember which commands are outstanding 3000 * and which scsi_pkt is the currently-running command so the 3001 * interrupt handler can refer to the pkt to set completion 3002 * status, call the target driver back through pkt_comp, etc. 3003 */ 3004 3005 mutex_enter(&ptgt->m_tgt_intr_mutex); 3006 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3007 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3008 /* 3009 * commands should be allowed to retry by 3010 * returning TRAN_BUSY to stall the I/O's 3011 * which come from scsi_vhci since the device/ 3012 * path is in unstable state now. 3013 */ 3014 mutex_exit(&ptgt->m_tgt_intr_mutex); 3015 return (TRAN_BUSY); 3016 } else { 3017 /* 3018 * The device is offline, just fail the 3019 * command by returning TRAN_FATAL_ERROR. 3020 */ 3021 mutex_exit(&ptgt->m_tgt_intr_mutex); 3022 return (TRAN_FATAL_ERROR); 3023 } 3024 } 3025 mutex_exit(&ptgt->m_tgt_intr_mutex); 3026 rval = mptsas_accept_pkt(mpt, cmd); 3027 3028 return (rval); 3029 } 3030 3031 static int 3032 mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd) 3033 { 3034 int rval = TRAN_ACCEPT; 3035 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3036 3037 NDBG1(("mptsas_accept_pkt: cmd=0x%p", (void *)cmd)); 3038 3039 if ((cmd->cmd_flags & CFLAG_PREPARED) == 0) { 3040 rval = mptsas_prepare_pkt(cmd); 3041 if (rval != TRAN_ACCEPT) { 3042 cmd->cmd_flags &= ~CFLAG_TRANFLAG; 3043 return (rval); 3044 } 3045 } 3046 3047 /* 3048 * reset the throttle if we were draining 3049 */ 3050 mutex_enter(&ptgt->m_tgt_intr_mutex); 3051 if ((ptgt->m_t_ncmds == 0) && 3052 (ptgt->m_t_throttle == DRAIN_THROTTLE)) { 3053 NDBG23(("reset throttle")); 3054 ASSERT(ptgt->m_reset_delay == 0); 3055 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 3056 } 3057 3058 /* 3059 * If device handle has already been invalidated, just 3060 * fail the command. In theory, command from scsi_vhci 3061 * client is impossible send down command with invalid 3062 * devhdl since devhdl is set after path offline, target 3063 * driver is not suppose to select a offlined path. 3064 */ 3065 if (ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) { 3066 NDBG20(("rejecting command, it might because invalid devhdl " 3067 "request.")); 3068 mutex_exit(&ptgt->m_tgt_intr_mutex); 3069 mutex_enter(&mpt->m_mutex); 3070 /* 3071 * If HBA is being reset, the DevHandles are being 3072 * re-initialized, which means that they could be invalid 3073 * even if the target is still attached. Check if being reset 3074 * and if DevHandle is being re-initialized. If this is the 3075 * case, return BUSY so the I/O can be retried later. 3076 */ 3077 if (mpt->m_in_reset) { 3078 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, 3079 STAT_BUS_RESET); 3080 if (cmd->cmd_flags & CFLAG_TXQ) { 3081 mptsas_doneq_add(mpt, cmd); 3082 mptsas_doneq_empty(mpt); 3083 mutex_exit(&mpt->m_mutex); 3084 return (rval); 3085 } else { 3086 mutex_exit(&mpt->m_mutex); 3087 return (TRAN_BUSY); 3088 } 3089 } 3090 mptsas_set_pkt_reason(mpt, cmd, CMD_DEV_GONE, STAT_TERMINATED); 3091 if (cmd->cmd_flags & CFLAG_TXQ) { 3092 mptsas_doneq_add(mpt, cmd); 3093 mptsas_doneq_empty(mpt); 3094 mutex_exit(&mpt->m_mutex); 3095 return (rval); 3096 } else { 3097 mutex_exit(&mpt->m_mutex); 3098 return (TRAN_FATAL_ERROR); 3099 } 3100 } 3101 mutex_exit(&ptgt->m_tgt_intr_mutex); 3102 /* 3103 * The first case is the normal case. mpt gets a command from the 3104 * target driver and starts it. 3105 * Since SMID 0 is reserved and the TM slot is reserved, the actual max 3106 * commands is m_max_requests - 2. 3107 */ 3108 mutex_enter(&ptgt->m_tgt_intr_mutex); 3109 if ((ptgt->m_t_throttle > HOLD_THROTTLE) && 3110 (ptgt->m_t_ncmds < ptgt->m_t_throttle) && 3111 (ptgt->m_reset_delay == 0) && 3112 (ptgt->m_t_nwait == 0) && 3113 ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0)) { 3114 mutex_exit(&ptgt->m_tgt_intr_mutex); 3115 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 3116 (void) mptsas_start_cmd0(mpt, cmd); 3117 } else { 3118 mutex_enter(&mpt->m_mutex); 3119 mptsas_waitq_add(mpt, cmd); 3120 mutex_exit(&mpt->m_mutex); 3121 } 3122 } else { 3123 /* 3124 * Add this pkt to the work queue 3125 */ 3126 mutex_exit(&ptgt->m_tgt_intr_mutex); 3127 mutex_enter(&mpt->m_mutex); 3128 mptsas_waitq_add(mpt, cmd); 3129 3130 if (cmd->cmd_pkt_flags & FLAG_NOINTR) { 3131 (void) mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME); 3132 3133 /* 3134 * Only flush the doneq if this is not a TM 3135 * cmd. For TM cmds the flushing of the 3136 * doneq will be done in those routines. 3137 */ 3138 if ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) { 3139 mptsas_doneq_empty(mpt); 3140 } 3141 } 3142 mutex_exit(&mpt->m_mutex); 3143 } 3144 return (rval); 3145 } 3146 3147 int 3148 mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 3149 { 3150 mptsas_slots_t *slots; 3151 int slot; 3152 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3153 mptsas_slot_free_e_t *pe; 3154 int qn, qn_first; 3155 3156 slots = mpt->m_active; 3157 3158 /* 3159 * Account for reserved TM request slot and reserved SMID of 0. 3160 */ 3161 ASSERT(slots->m_n_slots == (mpt->m_max_requests - 2)); 3162 3163 qn = qn_first = CPU->cpu_seqid & (mpt->m_slot_freeq_pair_n - 1); 3164 3165 qpair_retry: 3166 ASSERT(qn < mpt->m_slot_freeq_pair_n); 3167 mutex_enter(&mpt->m_slot_freeq_pairp[qn].m_slot_allocq.s.m_fq_mutex); 3168 pe = list_head(&mpt->m_slot_freeq_pairp[qn].m_slot_allocq. 3169 s.m_fq_list); 3170 if (!pe) { /* switch the allocq and releq */ 3171 mutex_enter(&mpt->m_slot_freeq_pairp[qn].m_slot_releq. 3172 s.m_fq_mutex); 3173 if (mpt->m_slot_freeq_pairp[qn].m_slot_releq.s.m_fq_n) { 3174 mpt->m_slot_freeq_pairp[qn]. 3175 m_slot_allocq.s.m_fq_n = 3176 mpt->m_slot_freeq_pairp[qn]. 3177 m_slot_releq.s.m_fq_n; 3178 mpt->m_slot_freeq_pairp[qn]. 3179 m_slot_allocq.s.m_fq_list.list_head.list_next = 3180 mpt->m_slot_freeq_pairp[qn]. 3181 m_slot_releq.s.m_fq_list.list_head.list_next; 3182 mpt->m_slot_freeq_pairp[qn]. 3183 m_slot_allocq.s.m_fq_list.list_head.list_prev = 3184 mpt->m_slot_freeq_pairp[qn]. 3185 m_slot_releq.s.m_fq_list.list_head.list_prev; 3186 mpt->m_slot_freeq_pairp[qn]. 3187 m_slot_releq.s.m_fq_list.list_head.list_prev-> 3188 list_next = 3189 &mpt->m_slot_freeq_pairp[qn]. 3190 m_slot_allocq.s.m_fq_list.list_head; 3191 mpt->m_slot_freeq_pairp[qn]. 3192 m_slot_releq.s.m_fq_list.list_head.list_next-> 3193 list_prev = 3194 &mpt->m_slot_freeq_pairp[qn]. 3195 m_slot_allocq.s.m_fq_list.list_head; 3196 3197 mpt->m_slot_freeq_pairp[qn]. 3198 m_slot_releq.s.m_fq_list.list_head.list_next = 3199 mpt->m_slot_freeq_pairp[qn]. 3200 m_slot_releq.s.m_fq_list.list_head.list_prev = 3201 &mpt->m_slot_freeq_pairp[qn]. 3202 m_slot_releq.s.m_fq_list.list_head; 3203 mpt->m_slot_freeq_pairp[qn]. 3204 m_slot_releq.s.m_fq_n = 0; 3205 } else { 3206 mutex_exit(&mpt->m_slot_freeq_pairp[qn]. 3207 m_slot_releq.s.m_fq_mutex); 3208 mutex_exit(&mpt->m_slot_freeq_pairp[qn]. 3209 m_slot_allocq.s.m_fq_mutex); 3210 qn = (qn + 1) & (mpt->m_slot_freeq_pair_n - 1); 3211 if (qn == qn_first) 3212 return (FALSE); 3213 else 3214 goto qpair_retry; 3215 } 3216 mutex_exit(&mpt->m_slot_freeq_pairp[qn]. 3217 m_slot_releq.s.m_fq_mutex); 3218 pe = list_head(&mpt->m_slot_freeq_pairp[qn]. 3219 m_slot_allocq.s.m_fq_list); 3220 ASSERT(pe); 3221 } 3222 list_remove(&mpt->m_slot_freeq_pairp[qn]. 3223 m_slot_allocq.s.m_fq_list, pe); 3224 slot = pe->slot; 3225 /* 3226 * Make sure SMID is not using reserved value of 0 3227 * and the TM request slot. 3228 */ 3229 ASSERT((slot > 0) && (slot <= slots->m_n_slots) && 3230 mpt->m_slot_freeq_pairp[qn].m_slot_allocq.s.m_fq_n > 0); 3231 cmd->cmd_slot = slot; 3232 mpt->m_slot_freeq_pairp[qn].m_slot_allocq.s.m_fq_n--; 3233 ASSERT(mpt->m_slot_freeq_pairp[qn].m_slot_allocq.s.m_fq_n >= 0); 3234 3235 mutex_exit(&mpt->m_slot_freeq_pairp[qn].m_slot_allocq.s.m_fq_mutex); 3236 /* 3237 * only increment per target ncmds if this is not a 3238 * command that has no target associated with it (i.e. a 3239 * event acknoledgment) 3240 */ 3241 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 3242 mutex_enter(&ptgt->m_tgt_intr_mutex); 3243 ptgt->m_t_ncmds++; 3244 mutex_exit(&ptgt->m_tgt_intr_mutex); 3245 } 3246 cmd->cmd_active_timeout = cmd->cmd_pkt->pkt_time; 3247 3248 /* 3249 * If initial timout is less than or equal to one tick, bump 3250 * the timeout by a tick so that command doesn't timeout before 3251 * its allotted time. 3252 */ 3253 if (cmd->cmd_active_timeout <= mptsas_scsi_watchdog_tick) { 3254 cmd->cmd_active_timeout += mptsas_scsi_watchdog_tick; 3255 } 3256 return (TRUE); 3257 } 3258 3259 /* 3260 * prepare the pkt: 3261 * the pkt may have been resubmitted or just reused so 3262 * initialize some fields and do some checks. 3263 */ 3264 static int 3265 mptsas_prepare_pkt(mptsas_cmd_t *cmd) 3266 { 3267 struct scsi_pkt *pkt = CMD2PKT(cmd); 3268 3269 NDBG1(("mptsas_prepare_pkt: cmd=0x%p", (void *)cmd)); 3270 3271 /* 3272 * Reinitialize some fields that need it; the packet may 3273 * have been resubmitted 3274 */ 3275 pkt->pkt_reason = CMD_CMPLT; 3276 pkt->pkt_state = 0; 3277 pkt->pkt_statistics = 0; 3278 pkt->pkt_resid = 0; 3279 cmd->cmd_age = 0; 3280 cmd->cmd_pkt_flags = pkt->pkt_flags; 3281 3282 /* 3283 * zero status byte. 3284 */ 3285 *(pkt->pkt_scbp) = 0; 3286 3287 if (cmd->cmd_flags & CFLAG_DMAVALID) { 3288 pkt->pkt_resid = cmd->cmd_dmacount; 3289 3290 /* 3291 * consistent packets need to be sync'ed first 3292 * (only for data going out) 3293 */ 3294 if ((cmd->cmd_flags & CFLAG_CMDIOPB) && 3295 (cmd->cmd_flags & CFLAG_DMASEND)) { 3296 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 3297 DDI_DMA_SYNC_FORDEV); 3298 } 3299 } 3300 3301 cmd->cmd_flags = 3302 (cmd->cmd_flags & ~(CFLAG_TRANFLAG)) | 3303 CFLAG_PREPARED | CFLAG_IN_TRANSPORT; 3304 3305 return (TRAN_ACCEPT); 3306 } 3307 3308 /* 3309 * tran_init_pkt(9E) - allocate scsi_pkt(9S) for command 3310 * 3311 * One of three possibilities: 3312 * - allocate scsi_pkt 3313 * - allocate scsi_pkt and DMA resources 3314 * - allocate DMA resources to an already-allocated pkt 3315 */ 3316 static struct scsi_pkt * 3317 mptsas_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt, 3318 struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags, 3319 int (*callback)(), caddr_t arg) 3320 { 3321 mptsas_cmd_t *cmd, *new_cmd; 3322 mptsas_t *mpt = ADDR2MPT(ap); 3323 int failure = 1; 3324 #ifndef __sparc 3325 uint_t oldcookiec; 3326 #endif /* __sparc */ 3327 mptsas_target_t *ptgt = NULL; 3328 int rval; 3329 mptsas_tgt_private_t *tgt_private; 3330 int kf; 3331 3332 kf = (callback == SLEEP_FUNC)? KM_SLEEP: KM_NOSLEEP; 3333 3334 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran-> 3335 tran_tgt_private; 3336 ASSERT(tgt_private != NULL); 3337 if (tgt_private == NULL) { 3338 return (NULL); 3339 } 3340 ptgt = tgt_private->t_private; 3341 ASSERT(ptgt != NULL); 3342 if (ptgt == NULL) 3343 return (NULL); 3344 ap->a_target = ptgt->m_devhdl; 3345 ap->a_lun = tgt_private->t_lun; 3346 3347 ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC); 3348 #ifdef MPTSAS_TEST_EXTRN_ALLOC 3349 statuslen *= 100; tgtlen *= 4; 3350 #endif 3351 NDBG3(("mptsas_scsi_init_pkt:\n" 3352 "\ttgt=%d in=0x%p bp=0x%p clen=%d slen=%d tlen=%d flags=%x", 3353 ap->a_target, (void *)pkt, (void *)bp, 3354 cmdlen, statuslen, tgtlen, flags)); 3355 3356 /* 3357 * Allocate the new packet. 3358 */ 3359 if (pkt == NULL) { 3360 ddi_dma_handle_t save_dma_handle; 3361 ddi_dma_handle_t save_arq_dma_handle; 3362 struct buf *save_arq_bp; 3363 ddi_dma_cookie_t save_arqcookie; 3364 #ifdef __sparc 3365 mptti_t *save_sg; 3366 #endif /* __sparc */ 3367 3368 cmd = kmem_cache_alloc(mpt->m_kmem_cache, kf); 3369 3370 if (cmd) { 3371 save_dma_handle = cmd->cmd_dmahandle; 3372 save_arq_dma_handle = cmd->cmd_arqhandle; 3373 save_arq_bp = cmd->cmd_arq_buf; 3374 save_arqcookie = cmd->cmd_arqcookie; 3375 #ifdef __sparc 3376 save_sg = cmd->cmd_sg; 3377 #endif /* __sparc */ 3378 bzero(cmd, sizeof (*cmd) + scsi_pkt_size()); 3379 cmd->cmd_dmahandle = save_dma_handle; 3380 cmd->cmd_arqhandle = save_arq_dma_handle; 3381 cmd->cmd_arq_buf = save_arq_bp; 3382 cmd->cmd_arqcookie = save_arqcookie; 3383 #ifdef __sparc 3384 cmd->cmd_sg = save_sg; 3385 #endif /* __sparc */ 3386 pkt = (void *)((uchar_t *)cmd + 3387 sizeof (struct mptsas_cmd)); 3388 pkt->pkt_ha_private = (opaque_t)cmd; 3389 pkt->pkt_address = *ap; 3390 pkt->pkt_private = (opaque_t)cmd->cmd_pkt_private; 3391 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; 3392 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb; 3393 cmd->cmd_pkt = (struct scsi_pkt *)pkt; 3394 cmd->cmd_cdblen = (uchar_t)cmdlen; 3395 cmd->cmd_scblen = statuslen; 3396 cmd->cmd_rqslen = SENSE_LENGTH; 3397 cmd->cmd_tgt_addr = ptgt; 3398 failure = 0; 3399 } 3400 3401 if (failure || (cmdlen > sizeof (cmd->cmd_cdb)) || 3402 (tgtlen > PKT_PRIV_LEN) || 3403 (statuslen > EXTCMDS_STATUS_SIZE)) { 3404 if (failure == 0) { 3405 /* 3406 * if extern alloc fails, all will be 3407 * deallocated, including cmd 3408 */ 3409 failure = mptsas_pkt_alloc_extern(mpt, cmd, 3410 cmdlen, tgtlen, statuslen, kf); 3411 } 3412 if (failure) { 3413 /* 3414 * if extern allocation fails, it will 3415 * deallocate the new pkt as well 3416 */ 3417 return (NULL); 3418 } 3419 } 3420 new_cmd = cmd; 3421 3422 } else { 3423 cmd = PKT2CMD(pkt); 3424 new_cmd = NULL; 3425 } 3426 3427 3428 #ifndef __sparc 3429 /* grab cmd->cmd_cookiec here as oldcookiec */ 3430 3431 oldcookiec = cmd->cmd_cookiec; 3432 #endif /* __sparc */ 3433 3434 /* 3435 * If the dma was broken up into PARTIAL transfers cmd_nwin will be 3436 * greater than 0 and we'll need to grab the next dma window 3437 */ 3438 /* 3439 * SLM-not doing extra command frame right now; may add later 3440 */ 3441 3442 if (cmd->cmd_nwin > 0) { 3443 3444 /* 3445 * Make sure we havn't gone past the the total number 3446 * of windows 3447 */ 3448 if (++cmd->cmd_winindex >= cmd->cmd_nwin) { 3449 return (NULL); 3450 } 3451 if (ddi_dma_getwin(cmd->cmd_dmahandle, cmd->cmd_winindex, 3452 &cmd->cmd_dma_offset, &cmd->cmd_dma_len, 3453 &cmd->cmd_cookie, &cmd->cmd_cookiec) == DDI_FAILURE) { 3454 return (NULL); 3455 } 3456 goto get_dma_cookies; 3457 } 3458 3459 3460 if (flags & PKT_XARQ) { 3461 cmd->cmd_flags |= CFLAG_XARQ; 3462 } 3463 3464 /* 3465 * DMA resource allocation. This version assumes your 3466 * HBA has some sort of bus-mastering or onboard DMA capability, with a 3467 * scatter-gather list of length MPTSAS_MAX_DMA_SEGS, as given in the 3468 * ddi_dma_attr_t structure and passed to scsi_impl_dmaget. 3469 */ 3470 if (bp && (bp->b_bcount != 0) && 3471 (cmd->cmd_flags & CFLAG_DMAVALID) == 0) { 3472 3473 int cnt, dma_flags; 3474 mptti_t *dmap; /* ptr to the S/G list */ 3475 3476 /* 3477 * Set up DMA memory and position to the next DMA segment. 3478 */ 3479 ASSERT(cmd->cmd_dmahandle != NULL); 3480 3481 if (bp->b_flags & B_READ) { 3482 dma_flags = DDI_DMA_READ; 3483 cmd->cmd_flags &= ~CFLAG_DMASEND; 3484 } else { 3485 dma_flags = DDI_DMA_WRITE; 3486 cmd->cmd_flags |= CFLAG_DMASEND; 3487 } 3488 if (flags & PKT_CONSISTENT) { 3489 cmd->cmd_flags |= CFLAG_CMDIOPB; 3490 dma_flags |= DDI_DMA_CONSISTENT; 3491 } 3492 3493 if (flags & PKT_DMA_PARTIAL) { 3494 dma_flags |= DDI_DMA_PARTIAL; 3495 } 3496 3497 /* 3498 * workaround for byte hole issue on psycho and 3499 * schizo pre 2.1 3500 */ 3501 if ((bp->b_flags & B_READ) && ((bp->b_flags & 3502 (B_PAGEIO|B_REMAPPED)) != B_PAGEIO) && 3503 ((uintptr_t)bp->b_un.b_addr & 0x7)) { 3504 dma_flags |= DDI_DMA_CONSISTENT; 3505 } 3506 3507 rval = ddi_dma_buf_bind_handle(cmd->cmd_dmahandle, bp, 3508 dma_flags, callback, arg, 3509 &cmd->cmd_cookie, &cmd->cmd_cookiec); 3510 if (rval == DDI_DMA_PARTIAL_MAP) { 3511 (void) ddi_dma_numwin(cmd->cmd_dmahandle, 3512 &cmd->cmd_nwin); 3513 cmd->cmd_winindex = 0; 3514 (void) ddi_dma_getwin(cmd->cmd_dmahandle, 3515 cmd->cmd_winindex, &cmd->cmd_dma_offset, 3516 &cmd->cmd_dma_len, &cmd->cmd_cookie, 3517 &cmd->cmd_cookiec); 3518 } else if (rval && (rval != DDI_DMA_MAPPED)) { 3519 switch (rval) { 3520 case DDI_DMA_NORESOURCES: 3521 bioerror(bp, 0); 3522 break; 3523 case DDI_DMA_BADATTR: 3524 case DDI_DMA_NOMAPPING: 3525 bioerror(bp, EFAULT); 3526 break; 3527 case DDI_DMA_TOOBIG: 3528 default: 3529 bioerror(bp, EINVAL); 3530 break; 3531 } 3532 cmd->cmd_flags &= ~CFLAG_DMAVALID; 3533 if (new_cmd) { 3534 mptsas_scsi_destroy_pkt(ap, pkt); 3535 } 3536 return ((struct scsi_pkt *)NULL); 3537 } 3538 3539 get_dma_cookies: 3540 cmd->cmd_flags |= CFLAG_DMAVALID; 3541 ASSERT(cmd->cmd_cookiec > 0); 3542 3543 if (cmd->cmd_cookiec > MPTSAS_MAX_CMD_SEGS) { 3544 mptsas_log(mpt, CE_NOTE, "large cookiec received %d\n", 3545 cmd->cmd_cookiec); 3546 bioerror(bp, EINVAL); 3547 if (new_cmd) { 3548 mptsas_scsi_destroy_pkt(ap, pkt); 3549 } 3550 return ((struct scsi_pkt *)NULL); 3551 } 3552 3553 /* 3554 * Allocate extra SGL buffer if needed. 3555 */ 3556 if ((cmd->cmd_cookiec > MPTSAS_MAX_FRAME_SGES64(mpt)) && 3557 (cmd->cmd_extra_frames == NULL)) { 3558 if (mptsas_alloc_extra_sgl_frame(mpt, cmd) == 3559 DDI_FAILURE) { 3560 mptsas_log(mpt, CE_WARN, "MPT SGL mem alloc " 3561 "failed"); 3562 bioerror(bp, ENOMEM); 3563 if (new_cmd) { 3564 mptsas_scsi_destroy_pkt(ap, pkt); 3565 } 3566 return ((struct scsi_pkt *)NULL); 3567 } 3568 } 3569 3570 /* 3571 * Always use scatter-gather transfer 3572 * Use the loop below to store physical addresses of 3573 * DMA segments, from the DMA cookies, into your HBA's 3574 * scatter-gather list. 3575 * We need to ensure we have enough kmem alloc'd 3576 * for the sg entries since we are no longer using an 3577 * array inside mptsas_cmd_t. 3578 * 3579 * We check cmd->cmd_cookiec against oldcookiec so 3580 * the scatter-gather list is correctly allocated 3581 */ 3582 #ifndef __sparc 3583 if (oldcookiec != cmd->cmd_cookiec) { 3584 if (cmd->cmd_sg != (mptti_t *)NULL) { 3585 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * 3586 oldcookiec); 3587 cmd->cmd_sg = NULL; 3588 } 3589 } 3590 3591 if (cmd->cmd_sg == (mptti_t *)NULL) { 3592 cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)* 3593 cmd->cmd_cookiec), kf); 3594 3595 if (cmd->cmd_sg == (mptti_t *)NULL) { 3596 mptsas_log(mpt, CE_WARN, 3597 "unable to kmem_alloc enough memory " 3598 "for scatter/gather list"); 3599 /* 3600 * if we have an ENOMEM condition we need to behave 3601 * the same way as the rest of this routine 3602 */ 3603 3604 bioerror(bp, ENOMEM); 3605 if (new_cmd) { 3606 mptsas_scsi_destroy_pkt(ap, pkt); 3607 } 3608 return ((struct scsi_pkt *)NULL); 3609 } 3610 } 3611 #endif /* __sparc */ 3612 dmap = cmd->cmd_sg; 3613 3614 ASSERT(cmd->cmd_cookie.dmac_size != 0); 3615 3616 /* 3617 * store the first segment into the S/G list 3618 */ 3619 dmap->count = cmd->cmd_cookie.dmac_size; 3620 dmap->addr.address64.Low = (uint32_t) 3621 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull); 3622 dmap->addr.address64.High = (uint32_t) 3623 (cmd->cmd_cookie.dmac_laddress >> 32); 3624 3625 /* 3626 * dmacount counts the size of the dma for this window 3627 * (if partial dma is being used). totaldmacount 3628 * keeps track of the total amount of dma we have 3629 * transferred for all the windows (needed to calculate 3630 * the resid value below). 3631 */ 3632 cmd->cmd_dmacount = cmd->cmd_cookie.dmac_size; 3633 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size; 3634 3635 /* 3636 * We already stored the first DMA scatter gather segment, 3637 * start at 1 if we need to store more. 3638 */ 3639 for (cnt = 1; cnt < cmd->cmd_cookiec; cnt++) { 3640 /* 3641 * Get next DMA cookie 3642 */ 3643 ddi_dma_nextcookie(cmd->cmd_dmahandle, 3644 &cmd->cmd_cookie); 3645 dmap++; 3646 3647 cmd->cmd_dmacount += cmd->cmd_cookie.dmac_size; 3648 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size; 3649 3650 /* 3651 * store the segment parms into the S/G list 3652 */ 3653 dmap->count = cmd->cmd_cookie.dmac_size; 3654 dmap->addr.address64.Low = (uint32_t) 3655 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull); 3656 dmap->addr.address64.High = (uint32_t) 3657 (cmd->cmd_cookie.dmac_laddress >> 32); 3658 } 3659 3660 /* 3661 * If this was partially allocated we set the resid 3662 * the amount of data NOT transferred in this window 3663 * If there is only one window, the resid will be 0 3664 */ 3665 pkt->pkt_resid = (bp->b_bcount - cmd->cmd_totaldmacount); 3666 NDBG16(("mptsas_dmaget: cmd_dmacount=%d.", cmd->cmd_dmacount)); 3667 } 3668 return (pkt); 3669 } 3670 3671 /* 3672 * tran_destroy_pkt(9E) - scsi_pkt(9s) deallocation 3673 * 3674 * Notes: 3675 * - also frees DMA resources if allocated 3676 * - implicit DMA synchonization 3677 */ 3678 static void 3679 mptsas_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 3680 { 3681 mptsas_cmd_t *cmd = PKT2CMD(pkt); 3682 mptsas_t *mpt = ADDR2MPT(ap); 3683 3684 NDBG3(("mptsas_scsi_destroy_pkt: target=%d pkt=0x%p", 3685 ap->a_target, (void *)pkt)); 3686 3687 if (cmd->cmd_flags & CFLAG_DMAVALID) { 3688 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle); 3689 cmd->cmd_flags &= ~CFLAG_DMAVALID; 3690 } 3691 #ifndef __sparc 3692 if (cmd->cmd_sg) { 3693 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * cmd->cmd_cookiec); 3694 cmd->cmd_sg = NULL; 3695 } 3696 #endif /* __sparc */ 3697 mptsas_free_extra_sgl_frame(mpt, cmd); 3698 3699 if ((cmd->cmd_flags & 3700 (CFLAG_FREE | CFLAG_CDBEXTERN | CFLAG_PRIVEXTERN | 3701 CFLAG_SCBEXTERN)) == 0) { 3702 cmd->cmd_flags = CFLAG_FREE; 3703 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd); 3704 } else { 3705 mptsas_pkt_destroy_extern(mpt, cmd); 3706 } 3707 } 3708 3709 /* 3710 * kmem cache constructor and destructor: 3711 * When constructing, we bzero the cmd and allocate the dma handle 3712 * When destructing, just free the dma handle 3713 */ 3714 static int 3715 mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags) 3716 { 3717 mptsas_cmd_t *cmd = buf; 3718 mptsas_t *mpt = cdrarg; 3719 struct scsi_address ap; 3720 uint_t cookiec; 3721 ddi_dma_attr_t arq_dma_attr; 3722 int (*callback)(caddr_t); 3723 3724 callback = (kmflags == KM_SLEEP)? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT; 3725 3726 NDBG4(("mptsas_kmem_cache_constructor")); 3727 3728 ap.a_hba_tran = mpt->m_tran; 3729 ap.a_target = 0; 3730 ap.a_lun = 0; 3731 3732 /* 3733 * allocate a dma handle 3734 */ 3735 if ((ddi_dma_alloc_handle(mpt->m_dip, &mpt->m_io_dma_attr, callback, 3736 NULL, &cmd->cmd_dmahandle)) != DDI_SUCCESS) { 3737 cmd->cmd_dmahandle = NULL; 3738 return (-1); 3739 } 3740 3741 cmd->cmd_arq_buf = scsi_alloc_consistent_buf(&ap, (struct buf *)NULL, 3742 SENSE_LENGTH, B_READ, callback, NULL); 3743 if (cmd->cmd_arq_buf == NULL) { 3744 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3745 cmd->cmd_dmahandle = NULL; 3746 return (-1); 3747 } 3748 3749 /* 3750 * allocate a arq handle 3751 */ 3752 arq_dma_attr = mpt->m_msg_dma_attr; 3753 arq_dma_attr.dma_attr_sgllen = 1; 3754 if ((ddi_dma_alloc_handle(mpt->m_dip, &arq_dma_attr, callback, 3755 NULL, &cmd->cmd_arqhandle)) != DDI_SUCCESS) { 3756 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3757 scsi_free_consistent_buf(cmd->cmd_arq_buf); 3758 cmd->cmd_dmahandle = NULL; 3759 cmd->cmd_arqhandle = NULL; 3760 return (-1); 3761 } 3762 3763 if (ddi_dma_buf_bind_handle(cmd->cmd_arqhandle, 3764 cmd->cmd_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT), 3765 callback, NULL, &cmd->cmd_arqcookie, &cookiec) != DDI_SUCCESS) { 3766 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3767 ddi_dma_free_handle(&cmd->cmd_arqhandle); 3768 scsi_free_consistent_buf(cmd->cmd_arq_buf); 3769 cmd->cmd_dmahandle = NULL; 3770 cmd->cmd_arqhandle = NULL; 3771 cmd->cmd_arq_buf = NULL; 3772 return (-1); 3773 } 3774 /* 3775 * In sparc, the sgl length in most of the cases would be 1, so we 3776 * pre-allocate it in cache. On x86, the max number would be 256, 3777 * pre-allocate a maximum would waste a lot of memory especially 3778 * when many cmds are put onto waitq. 3779 */ 3780 #ifdef __sparc 3781 cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)* 3782 MPTSAS_MAX_CMD_SEGS), KM_SLEEP); 3783 #endif /* __sparc */ 3784 3785 return (0); 3786 } 3787 3788 static void 3789 mptsas_kmem_cache_destructor(void *buf, void *cdrarg) 3790 { 3791 #ifndef __lock_lint 3792 _NOTE(ARGUNUSED(cdrarg)) 3793 #endif 3794 mptsas_cmd_t *cmd = buf; 3795 3796 NDBG4(("mptsas_kmem_cache_destructor")); 3797 3798 if (cmd->cmd_arqhandle) { 3799 (void) ddi_dma_unbind_handle(cmd->cmd_arqhandle); 3800 ddi_dma_free_handle(&cmd->cmd_arqhandle); 3801 cmd->cmd_arqhandle = NULL; 3802 } 3803 if (cmd->cmd_arq_buf) { 3804 scsi_free_consistent_buf(cmd->cmd_arq_buf); 3805 cmd->cmd_arq_buf = NULL; 3806 } 3807 if (cmd->cmd_dmahandle) { 3808 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3809 cmd->cmd_dmahandle = NULL; 3810 } 3811 #ifdef __sparc 3812 if (cmd->cmd_sg) { 3813 kmem_free(cmd->cmd_sg, sizeof (mptti_t)* MPTSAS_MAX_CMD_SEGS); 3814 cmd->cmd_sg = NULL; 3815 } 3816 #endif /* __sparc */ 3817 } 3818 3819 static int 3820 mptsas_cache_frames_constructor(void *buf, void *cdrarg, int kmflags) 3821 { 3822 mptsas_cache_frames_t *p = buf; 3823 mptsas_t *mpt = cdrarg; 3824 ddi_dma_attr_t frame_dma_attr; 3825 size_t mem_size, alloc_len; 3826 ddi_dma_cookie_t cookie; 3827 uint_t ncookie; 3828 int (*callback)(caddr_t) = (kmflags == KM_SLEEP) 3829 ? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT; 3830 3831 frame_dma_attr = mpt->m_msg_dma_attr; 3832 frame_dma_attr.dma_attr_align = 0x10; 3833 frame_dma_attr.dma_attr_sgllen = 1; 3834 3835 if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attr, callback, NULL, 3836 &p->m_dma_hdl) != DDI_SUCCESS) { 3837 mptsas_log(mpt, CE_WARN, "Unable to allocate dma handle for" 3838 " extra SGL."); 3839 return (DDI_FAILURE); 3840 } 3841 3842 mem_size = (mpt->m_max_request_frames - 1) * mpt->m_req_frame_size; 3843 3844 if (ddi_dma_mem_alloc(p->m_dma_hdl, mem_size, &mpt->m_dev_acc_attr, 3845 DDI_DMA_CONSISTENT, callback, NULL, (caddr_t *)&p->m_frames_addr, 3846 &alloc_len, &p->m_acc_hdl) != DDI_SUCCESS) { 3847 ddi_dma_free_handle(&p->m_dma_hdl); 3848 p->m_dma_hdl = NULL; 3849 mptsas_log(mpt, CE_WARN, "Unable to allocate dma memory for" 3850 " extra SGL."); 3851 return (DDI_FAILURE); 3852 } 3853 3854 if (ddi_dma_addr_bind_handle(p->m_dma_hdl, NULL, p->m_frames_addr, 3855 alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, callback, NULL, 3856 &cookie, &ncookie) != DDI_DMA_MAPPED) { 3857 (void) ddi_dma_mem_free(&p->m_acc_hdl); 3858 ddi_dma_free_handle(&p->m_dma_hdl); 3859 p->m_dma_hdl = NULL; 3860 mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources for" 3861 " extra SGL"); 3862 return (DDI_FAILURE); 3863 } 3864 3865 /* 3866 * Store the SGL memory address. This chip uses this 3867 * address to dma to and from the driver. The second 3868 * address is the address mpt uses to fill in the SGL. 3869 */ 3870 p->m_phys_addr = cookie.dmac_address; 3871 3872 return (DDI_SUCCESS); 3873 } 3874 3875 static void 3876 mptsas_cache_frames_destructor(void *buf, void *cdrarg) 3877 { 3878 #ifndef __lock_lint 3879 _NOTE(ARGUNUSED(cdrarg)) 3880 #endif 3881 mptsas_cache_frames_t *p = buf; 3882 if (p->m_dma_hdl != NULL) { 3883 (void) ddi_dma_unbind_handle(p->m_dma_hdl); 3884 (void) ddi_dma_mem_free(&p->m_acc_hdl); 3885 ddi_dma_free_handle(&p->m_dma_hdl); 3886 p->m_phys_addr = NULL; 3887 p->m_frames_addr = NULL; 3888 p->m_dma_hdl = NULL; 3889 p->m_acc_hdl = NULL; 3890 } 3891 3892 } 3893 3894 /* 3895 * allocate and deallocate external pkt space (ie. not part of mptsas_cmd) 3896 * for non-standard length cdb, pkt_private, status areas 3897 * if allocation fails, then deallocate all external space and the pkt 3898 */ 3899 /* ARGSUSED */ 3900 static int 3901 mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd, 3902 int cmdlen, int tgtlen, int statuslen, int kf) 3903 { 3904 caddr_t cdbp, scbp, tgt; 3905 int (*callback)(caddr_t) = (kf == KM_SLEEP) ? 3906 DDI_DMA_SLEEP : DDI_DMA_DONTWAIT; 3907 struct scsi_address ap; 3908 size_t senselength; 3909 ddi_dma_attr_t ext_arq_dma_attr; 3910 uint_t cookiec; 3911 3912 NDBG3(("mptsas_pkt_alloc_extern: " 3913 "cmd=0x%p cmdlen=%d tgtlen=%d statuslen=%d kf=%x", 3914 (void *)cmd, cmdlen, tgtlen, statuslen, kf)); 3915 3916 tgt = cdbp = scbp = NULL; 3917 cmd->cmd_scblen = statuslen; 3918 cmd->cmd_privlen = (uchar_t)tgtlen; 3919 3920 if (cmdlen > sizeof (cmd->cmd_cdb)) { 3921 if ((cdbp = kmem_zalloc((size_t)cmdlen, kf)) == NULL) { 3922 goto fail; 3923 } 3924 cmd->cmd_pkt->pkt_cdbp = (opaque_t)cdbp; 3925 cmd->cmd_flags |= CFLAG_CDBEXTERN; 3926 } 3927 if (tgtlen > PKT_PRIV_LEN) { 3928 if ((tgt = kmem_zalloc((size_t)tgtlen, kf)) == NULL) { 3929 goto fail; 3930 } 3931 cmd->cmd_flags |= CFLAG_PRIVEXTERN; 3932 cmd->cmd_pkt->pkt_private = tgt; 3933 } 3934 if (statuslen > EXTCMDS_STATUS_SIZE) { 3935 if ((scbp = kmem_zalloc((size_t)statuslen, kf)) == NULL) { 3936 goto fail; 3937 } 3938 cmd->cmd_flags |= CFLAG_SCBEXTERN; 3939 cmd->cmd_pkt->pkt_scbp = (opaque_t)scbp; 3940 3941 /* allocate sense data buf for DMA */ 3942 3943 senselength = statuslen - MPTSAS_GET_ITEM_OFF( 3944 struct scsi_arq_status, sts_sensedata); 3945 cmd->cmd_rqslen = (uchar_t)senselength; 3946 3947 ap.a_hba_tran = mpt->m_tran; 3948 ap.a_target = 0; 3949 ap.a_lun = 0; 3950 3951 cmd->cmd_ext_arq_buf = scsi_alloc_consistent_buf(&ap, 3952 (struct buf *)NULL, senselength, B_READ, 3953 callback, NULL); 3954 3955 if (cmd->cmd_ext_arq_buf == NULL) { 3956 goto fail; 3957 } 3958 /* 3959 * allocate a extern arq handle and bind the buf 3960 */ 3961 ext_arq_dma_attr = mpt->m_msg_dma_attr; 3962 ext_arq_dma_attr.dma_attr_sgllen = 1; 3963 if ((ddi_dma_alloc_handle(mpt->m_dip, 3964 &ext_arq_dma_attr, callback, 3965 NULL, &cmd->cmd_ext_arqhandle)) != DDI_SUCCESS) { 3966 goto fail; 3967 } 3968 3969 if (ddi_dma_buf_bind_handle(cmd->cmd_ext_arqhandle, 3970 cmd->cmd_ext_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT), 3971 callback, NULL, &cmd->cmd_ext_arqcookie, 3972 &cookiec) 3973 != DDI_SUCCESS) { 3974 goto fail; 3975 } 3976 cmd->cmd_flags |= CFLAG_EXTARQBUFVALID; 3977 } 3978 return (0); 3979 fail: 3980 mptsas_pkt_destroy_extern(mpt, cmd); 3981 return (1); 3982 } 3983 3984 /* 3985 * deallocate external pkt space and deallocate the pkt 3986 */ 3987 static void 3988 mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd) 3989 { 3990 NDBG3(("mptsas_pkt_destroy_extern: cmd=0x%p", (void *)cmd)); 3991 3992 if (cmd->cmd_flags & CFLAG_FREE) { 3993 mptsas_log(mpt, CE_PANIC, 3994 "mptsas_pkt_destroy_extern: freeing free packet"); 3995 _NOTE(NOT_REACHED) 3996 /* NOTREACHED */ 3997 } 3998 if (cmd->cmd_flags & CFLAG_CDBEXTERN) { 3999 kmem_free(cmd->cmd_pkt->pkt_cdbp, (size_t)cmd->cmd_cdblen); 4000 } 4001 if (cmd->cmd_flags & CFLAG_SCBEXTERN) { 4002 kmem_free(cmd->cmd_pkt->pkt_scbp, (size_t)cmd->cmd_scblen); 4003 if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) { 4004 (void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle); 4005 } 4006 if (cmd->cmd_ext_arqhandle) { 4007 ddi_dma_free_handle(&cmd->cmd_ext_arqhandle); 4008 cmd->cmd_ext_arqhandle = NULL; 4009 } 4010 if (cmd->cmd_ext_arq_buf) 4011 scsi_free_consistent_buf(cmd->cmd_ext_arq_buf); 4012 } 4013 if (cmd->cmd_flags & CFLAG_PRIVEXTERN) { 4014 kmem_free(cmd->cmd_pkt->pkt_private, (size_t)cmd->cmd_privlen); 4015 } 4016 cmd->cmd_flags = CFLAG_FREE; 4017 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd); 4018 } 4019 4020 /* 4021 * tran_sync_pkt(9E) - explicit DMA synchronization 4022 */ 4023 /*ARGSUSED*/ 4024 static void 4025 mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 4026 { 4027 mptsas_cmd_t *cmd = PKT2CMD(pkt); 4028 4029 NDBG3(("mptsas_scsi_sync_pkt: target=%d, pkt=0x%p", 4030 ap->a_target, (void *)pkt)); 4031 4032 if (cmd->cmd_dmahandle) { 4033 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 4034 (cmd->cmd_flags & CFLAG_DMASEND) ? 4035 DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU); 4036 } 4037 } 4038 4039 /* 4040 * tran_dmafree(9E) - deallocate DMA resources allocated for command 4041 */ 4042 /*ARGSUSED*/ 4043 static void 4044 mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt) 4045 { 4046 mptsas_cmd_t *cmd = PKT2CMD(pkt); 4047 mptsas_t *mpt = ADDR2MPT(ap); 4048 4049 NDBG3(("mptsas_scsi_dmafree: target=%d pkt=0x%p", 4050 ap->a_target, (void *)pkt)); 4051 4052 if (cmd->cmd_flags & CFLAG_DMAVALID) { 4053 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle); 4054 cmd->cmd_flags &= ~CFLAG_DMAVALID; 4055 } 4056 4057 if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) { 4058 (void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle); 4059 cmd->cmd_flags &= ~CFLAG_EXTARQBUFVALID; 4060 } 4061 4062 mptsas_free_extra_sgl_frame(mpt, cmd); 4063 } 4064 4065 static void 4066 mptsas_pkt_comp(struct scsi_pkt *pkt, mptsas_cmd_t *cmd) 4067 { 4068 if ((cmd->cmd_flags & CFLAG_CMDIOPB) && 4069 (!(cmd->cmd_flags & CFLAG_DMASEND))) { 4070 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 4071 DDI_DMA_SYNC_FORCPU); 4072 } 4073 (*pkt->pkt_comp)(pkt); 4074 } 4075 4076 static void 4077 mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, uint32_t *control, 4078 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl) 4079 { 4080 uint_t cookiec; 4081 mptti_t *dmap; 4082 uint32_t flags; 4083 pMpi2SGESimple64_t sge; 4084 pMpi2SGEChain64_t sgechain; 4085 ASSERT(cmd->cmd_flags & CFLAG_DMAVALID); 4086 4087 /* 4088 * Save the number of entries in the DMA 4089 * Scatter/Gather list 4090 */ 4091 cookiec = cmd->cmd_cookiec; 4092 4093 NDBG1(("mptsas_sge_setup: cookiec=%d", cookiec)); 4094 4095 /* 4096 * Set read/write bit in control. 4097 */ 4098 if (cmd->cmd_flags & CFLAG_DMASEND) { 4099 *control |= MPI2_SCSIIO_CONTROL_WRITE; 4100 } else { 4101 *control |= MPI2_SCSIIO_CONTROL_READ; 4102 } 4103 4104 ddi_put32(acc_hdl, &frame->DataLength, cmd->cmd_dmacount); 4105 4106 /* 4107 * We have 2 cases here. First where we can fit all the 4108 * SG elements into the main frame, and the case 4109 * where we can't. 4110 * If we have more cookies than we can attach to a frame 4111 * we will need to use a chain element to point 4112 * a location of memory where the rest of the S/G 4113 * elements reside. 4114 */ 4115 if (cookiec <= MPTSAS_MAX_FRAME_SGES64(mpt)) { 4116 dmap = cmd->cmd_sg; 4117 sge = (pMpi2SGESimple64_t)(&frame->SGL); 4118 while (cookiec--) { 4119 ddi_put32(acc_hdl, 4120 &sge->Address.Low, dmap->addr.address64.Low); 4121 ddi_put32(acc_hdl, 4122 &sge->Address.High, dmap->addr.address64.High); 4123 ddi_put32(acc_hdl, &sge->FlagsLength, 4124 dmap->count); 4125 flags = ddi_get32(acc_hdl, &sge->FlagsLength); 4126 flags |= ((uint32_t) 4127 (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4128 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4129 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4130 MPI2_SGE_FLAGS_SHIFT); 4131 4132 /* 4133 * If this is the last cookie, we set the flags 4134 * to indicate so 4135 */ 4136 if (cookiec == 0) { 4137 flags |= 4138 ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT 4139 | MPI2_SGE_FLAGS_END_OF_BUFFER 4140 | MPI2_SGE_FLAGS_END_OF_LIST) << 4141 MPI2_SGE_FLAGS_SHIFT); 4142 } 4143 if (cmd->cmd_flags & CFLAG_DMASEND) { 4144 flags |= (MPI2_SGE_FLAGS_HOST_TO_IOC << 4145 MPI2_SGE_FLAGS_SHIFT); 4146 } else { 4147 flags |= (MPI2_SGE_FLAGS_IOC_TO_HOST << 4148 MPI2_SGE_FLAGS_SHIFT); 4149 } 4150 ddi_put32(acc_hdl, &sge->FlagsLength, flags); 4151 dmap++; 4152 sge++; 4153 } 4154 } else { 4155 /* 4156 * Hereby we start to deal with multiple frames. 4157 * The process is as follows: 4158 * 1. Determine how many frames are needed for SGL element 4159 * storage; Note that all frames are stored in contiguous 4160 * memory space and in 64-bit DMA mode each element is 4161 * 3 double-words (12 bytes) long. 4162 * 2. Fill up the main frame. We need to do this separately 4163 * since it contains the SCSI IO request header and needs 4164 * dedicated processing. Note that the last 4 double-words 4165 * of the SCSI IO header is for SGL element storage 4166 * (MPI2_SGE_IO_UNION). 4167 * 3. Fill the chain element in the main frame, so the DMA 4168 * engine can use the following frames. 4169 * 4. Enter a loop to fill the remaining frames. Note that the 4170 * last frame contains no chain element. The remaining 4171 * frames go into the mpt SGL buffer allocated on the fly, 4172 * not immediately following the main message frame, as in 4173 * Gen1. 4174 * Some restrictions: 4175 * 1. For 64-bit DMA, the simple element and chain element 4176 * are both of 3 double-words (12 bytes) in size, even 4177 * though all frames are stored in the first 4G of mem 4178 * range and the higher 32-bits of the address are always 0. 4179 * 2. On some controllers (like the 1064/1068), a frame can 4180 * hold SGL elements with the last 1 or 2 double-words 4181 * (4 or 8 bytes) un-used. On these controllers, we should 4182 * recognize that there's not enough room for another SGL 4183 * element and move the sge pointer to the next frame. 4184 */ 4185 int i, j, k, l, frames, sgemax; 4186 int temp; 4187 uint8_t chainflags; 4188 uint16_t chainlength; 4189 mptsas_cache_frames_t *p; 4190 4191 /* 4192 * Sgemax is the number of SGE's that will fit 4193 * each extra frame and frames is total 4194 * number of frames we'll need. 1 sge entry per 4195 * frame is reseverd for the chain element thus the -1 below. 4196 */ 4197 sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_SGE_SIMPLE64)) 4198 - 1); 4199 temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax; 4200 4201 /* 4202 * A little check to see if we need to round up the number 4203 * of frames we need 4204 */ 4205 if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp * 4206 sgemax) > 1) { 4207 frames = (temp + 1); 4208 } else { 4209 frames = temp; 4210 } 4211 dmap = cmd->cmd_sg; 4212 sge = (pMpi2SGESimple64_t)(&frame->SGL); 4213 4214 /* 4215 * First fill in the main frame 4216 */ 4217 for (j = 1; j < MPTSAS_MAX_FRAME_SGES64(mpt); j++) { 4218 ddi_put32(acc_hdl, &sge->Address.Low, 4219 dmap->addr.address64.Low); 4220 ddi_put32(acc_hdl, &sge->Address.High, 4221 dmap->addr.address64.High); 4222 ddi_put32(acc_hdl, &sge->FlagsLength, dmap->count); 4223 flags = ddi_get32(acc_hdl, &sge->FlagsLength); 4224 flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4225 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4226 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4227 MPI2_SGE_FLAGS_SHIFT); 4228 4229 /* 4230 * If this is the last SGE of this frame 4231 * we set the end of list flag 4232 */ 4233 if (j == (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) { 4234 flags |= ((uint32_t) 4235 (MPI2_SGE_FLAGS_LAST_ELEMENT) << 4236 MPI2_SGE_FLAGS_SHIFT); 4237 } 4238 if (cmd->cmd_flags & CFLAG_DMASEND) { 4239 flags |= 4240 (MPI2_SGE_FLAGS_HOST_TO_IOC << 4241 MPI2_SGE_FLAGS_SHIFT); 4242 } else { 4243 flags |= 4244 (MPI2_SGE_FLAGS_IOC_TO_HOST << 4245 MPI2_SGE_FLAGS_SHIFT); 4246 } 4247 ddi_put32(acc_hdl, &sge->FlagsLength, flags); 4248 dmap++; 4249 sge++; 4250 } 4251 4252 /* 4253 * Fill in the chain element in the main frame. 4254 * About calculation on ChainOffset: 4255 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes) 4256 * in the end reserved for SGL element storage 4257 * (MPI2_SGE_IO_UNION); we should count it in our 4258 * calculation. See its definition in the header file. 4259 * 2. Constant j is the counter of the current SGL element 4260 * that will be processed, and (j - 1) is the number of 4261 * SGL elements that have been processed (stored in the 4262 * main frame). 4263 * 3. ChainOffset value should be in units of double-words (4 4264 * bytes) so the last value should be divided by 4. 4265 */ 4266 ddi_put8(acc_hdl, &frame->ChainOffset, 4267 (sizeof (MPI2_SCSI_IO_REQUEST) - 4268 sizeof (MPI2_SGE_IO_UNION) + 4269 (j - 1) * sizeof (MPI2_SGE_SIMPLE64)) >> 2); 4270 sgechain = (pMpi2SGEChain64_t)sge; 4271 chainflags = (MPI2_SGE_FLAGS_CHAIN_ELEMENT | 4272 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4273 MPI2_SGE_FLAGS_64_BIT_ADDRESSING); 4274 ddi_put8(acc_hdl, &sgechain->Flags, chainflags); 4275 4276 /* 4277 * The size of the next frame is the accurate size of space 4278 * (in bytes) used to store the SGL elements. j is the counter 4279 * of SGL elements. (j - 1) is the number of SGL elements that 4280 * have been processed (stored in frames). 4281 */ 4282 if (frames >= 2) { 4283 chainlength = mpt->m_req_frame_size / 4284 sizeof (MPI2_SGE_SIMPLE64) * 4285 sizeof (MPI2_SGE_SIMPLE64); 4286 } else { 4287 chainlength = ((cookiec - (j - 1)) * 4288 sizeof (MPI2_SGE_SIMPLE64)); 4289 } 4290 4291 p = cmd->cmd_extra_frames; 4292 4293 ddi_put16(acc_hdl, &sgechain->Length, chainlength); 4294 ddi_put32(acc_hdl, &sgechain->Address.Low, 4295 p->m_phys_addr); 4296 /* SGL is allocated in the first 4G mem range */ 4297 ddi_put32(acc_hdl, &sgechain->Address.High, 0); 4298 4299 /* 4300 * If there are more than 2 frames left we have to 4301 * fill in the next chain offset to the location of 4302 * the chain element in the next frame. 4303 * sgemax is the number of simple elements in an extra 4304 * frame. Note that the value NextChainOffset should be 4305 * in double-words (4 bytes). 4306 */ 4307 if (frames >= 2) { 4308 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 4309 (sgemax * sizeof (MPI2_SGE_SIMPLE64)) >> 2); 4310 } else { 4311 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 0); 4312 } 4313 4314 /* 4315 * Jump to next frame; 4316 * Starting here, chain buffers go into the per command SGL. 4317 * This buffer is allocated when chain buffers are needed. 4318 */ 4319 sge = (pMpi2SGESimple64_t)p->m_frames_addr; 4320 i = cookiec; 4321 4322 /* 4323 * Start filling in frames with SGE's. If we 4324 * reach the end of frame and still have SGE's 4325 * to fill we need to add a chain element and 4326 * use another frame. j will be our counter 4327 * for what cookie we are at and i will be 4328 * the total cookiec. k is the current frame 4329 */ 4330 for (k = 1; k <= frames; k++) { 4331 for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) { 4332 4333 /* 4334 * If we have reached the end of frame 4335 * and we have more SGE's to fill in 4336 * we have to fill the final entry 4337 * with a chain element and then 4338 * continue to the next frame 4339 */ 4340 if ((l == (sgemax + 1)) && (k != frames)) { 4341 sgechain = (pMpi2SGEChain64_t)sge; 4342 j--; 4343 chainflags = ( 4344 MPI2_SGE_FLAGS_CHAIN_ELEMENT | 4345 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4346 MPI2_SGE_FLAGS_64_BIT_ADDRESSING); 4347 ddi_put8(p->m_acc_hdl, 4348 &sgechain->Flags, chainflags); 4349 /* 4350 * k is the frame counter and (k + 1) 4351 * is the number of the next frame. 4352 * Note that frames are in contiguous 4353 * memory space. 4354 */ 4355 ddi_put32(p->m_acc_hdl, 4356 &sgechain->Address.Low, 4357 (p->m_phys_addr + 4358 (mpt->m_req_frame_size * k))); 4359 ddi_put32(p->m_acc_hdl, 4360 &sgechain->Address.High, 0); 4361 4362 /* 4363 * If there are more than 2 frames left 4364 * we have to next chain offset to 4365 * the location of the chain element 4366 * in the next frame and fill in the 4367 * length of the next chain 4368 */ 4369 if ((frames - k) >= 2) { 4370 ddi_put8(p->m_acc_hdl, 4371 &sgechain->NextChainOffset, 4372 (sgemax * 4373 sizeof (MPI2_SGE_SIMPLE64)) 4374 >> 2); 4375 ddi_put16(p->m_acc_hdl, 4376 &sgechain->Length, 4377 mpt->m_req_frame_size / 4378 sizeof (MPI2_SGE_SIMPLE64) * 4379 sizeof (MPI2_SGE_SIMPLE64)); 4380 } else { 4381 /* 4382 * This is the last frame. Set 4383 * the NextChainOffset to 0 and 4384 * Length is the total size of 4385 * all remaining simple elements 4386 */ 4387 ddi_put8(p->m_acc_hdl, 4388 &sgechain->NextChainOffset, 4389 0); 4390 ddi_put16(p->m_acc_hdl, 4391 &sgechain->Length, 4392 (cookiec - j) * 4393 sizeof (MPI2_SGE_SIMPLE64)); 4394 } 4395 4396 /* Jump to the next frame */ 4397 sge = (pMpi2SGESimple64_t) 4398 ((char *)p->m_frames_addr + 4399 (int)mpt->m_req_frame_size * k); 4400 4401 continue; 4402 } 4403 4404 ddi_put32(p->m_acc_hdl, 4405 &sge->Address.Low, 4406 dmap->addr.address64.Low); 4407 ddi_put32(p->m_acc_hdl, 4408 &sge->Address.High, 4409 dmap->addr.address64.High); 4410 ddi_put32(p->m_acc_hdl, 4411 &sge->FlagsLength, dmap->count); 4412 flags = ddi_get32(p->m_acc_hdl, 4413 &sge->FlagsLength); 4414 flags |= ((uint32_t)( 4415 MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4416 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4417 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4418 MPI2_SGE_FLAGS_SHIFT); 4419 4420 /* 4421 * If we are at the end of the frame and 4422 * there is another frame to fill in 4423 * we set the last simple element as last 4424 * element 4425 */ 4426 if ((l == sgemax) && (k != frames)) { 4427 flags |= ((uint32_t) 4428 (MPI2_SGE_FLAGS_LAST_ELEMENT) << 4429 MPI2_SGE_FLAGS_SHIFT); 4430 } 4431 4432 /* 4433 * If this is the final cookie we 4434 * indicate it by setting the flags 4435 */ 4436 if (j == i) { 4437 flags |= ((uint32_t) 4438 (MPI2_SGE_FLAGS_LAST_ELEMENT | 4439 MPI2_SGE_FLAGS_END_OF_BUFFER | 4440 MPI2_SGE_FLAGS_END_OF_LIST) << 4441 MPI2_SGE_FLAGS_SHIFT); 4442 } 4443 if (cmd->cmd_flags & CFLAG_DMASEND) { 4444 flags |= 4445 (MPI2_SGE_FLAGS_HOST_TO_IOC << 4446 MPI2_SGE_FLAGS_SHIFT); 4447 } else { 4448 flags |= 4449 (MPI2_SGE_FLAGS_IOC_TO_HOST << 4450 MPI2_SGE_FLAGS_SHIFT); 4451 } 4452 ddi_put32(p->m_acc_hdl, 4453 &sge->FlagsLength, flags); 4454 dmap++; 4455 sge++; 4456 } 4457 } 4458 4459 /* 4460 * Sync DMA with the chain buffers that were just created 4461 */ 4462 (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 4463 } 4464 } 4465 4466 /* 4467 * Interrupt handling 4468 * Utility routine. Poll for status of a command sent to HBA 4469 * without interrupts (a FLAG_NOINTR command). 4470 */ 4471 int 4472 mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime) 4473 { 4474 int rval = TRUE; 4475 4476 NDBG5(("mptsas_poll: cmd=0x%p", (void *)poll_cmd)); 4477 4478 /* 4479 * In order to avoid using m_mutex in ISR(a new separate mutex 4480 * m_intr_mutex is introduced) and keep the same lock logic, 4481 * the m_intr_mutex should be used to protect the getting and 4482 * setting of the ReplyDescriptorIndex. 4483 * 4484 * Since the m_intr_mutex would be released during processing the poll 4485 * cmd, so we should set the poll flag earlier here to make sure the 4486 * polled cmd be handled in this thread/context. A side effect is other 4487 * cmds during the period between the flag set and reset are also 4488 * handled in this thread and not the ISR. Since the poll cmd is not 4489 * so common, so the performance degradation in this case is not a big 4490 * issue. 4491 */ 4492 mutex_enter(&mpt->m_intr_mutex); 4493 mpt->m_polled_intr = 1; 4494 mutex_exit(&mpt->m_intr_mutex); 4495 4496 if ((poll_cmd->cmd_flags & CFLAG_TM_CMD) == 0) { 4497 mptsas_restart_hba(mpt); 4498 } 4499 4500 /* 4501 * Wait, using drv_usecwait(), long enough for the command to 4502 * reasonably return from the target if the target isn't 4503 * "dead". A polled command may well be sent from scsi_poll, and 4504 * there are retries built in to scsi_poll if the transport 4505 * accepted the packet (TRAN_ACCEPT). scsi_poll waits 1 second 4506 * and retries the transport up to scsi_poll_busycnt times 4507 * (currently 60) if 4508 * 1. pkt_reason is CMD_INCOMPLETE and pkt_state is 0, or 4509 * 2. pkt_reason is CMD_CMPLT and *pkt_scbp has STATUS_BUSY 4510 * 4511 * limit the waiting to avoid a hang in the event that the 4512 * cmd never gets started but we are still receiving interrupts 4513 */ 4514 while (!(poll_cmd->cmd_flags & CFLAG_FINISHED)) { 4515 if (mptsas_wait_intr(mpt, polltime) == FALSE) { 4516 NDBG5(("mptsas_poll: command incomplete")); 4517 rval = FALSE; 4518 break; 4519 } 4520 } 4521 4522 mutex_enter(&mpt->m_intr_mutex); 4523 mpt->m_polled_intr = 0; 4524 mutex_exit(&mpt->m_intr_mutex); 4525 4526 if (rval == FALSE) { 4527 4528 /* 4529 * this isn't supposed to happen, the hba must be wedged 4530 * Mark this cmd as a timeout. 4531 */ 4532 mptsas_set_pkt_reason(mpt, poll_cmd, CMD_TIMEOUT, 4533 (STAT_TIMEOUT|STAT_ABORTED)); 4534 4535 if (poll_cmd->cmd_queued == FALSE) { 4536 4537 NDBG5(("mptsas_poll: not on waitq")); 4538 4539 poll_cmd->cmd_pkt->pkt_state |= 4540 (STATE_GOT_BUS|STATE_GOT_TARGET|STATE_SENT_CMD); 4541 } else { 4542 4543 /* find and remove it from the waitq */ 4544 NDBG5(("mptsas_poll: delete from waitq")); 4545 mptsas_waitq_delete(mpt, poll_cmd); 4546 } 4547 4548 } 4549 mptsas_fma_check(mpt, poll_cmd); 4550 NDBG5(("mptsas_poll: done")); 4551 return (rval); 4552 } 4553 4554 /* 4555 * Used for polling cmds and TM function 4556 */ 4557 static int 4558 mptsas_wait_intr(mptsas_t *mpt, int polltime) 4559 { 4560 int cnt; 4561 pMpi2ReplyDescriptorsUnion_t reply_desc_union; 4562 Mpi2ReplyDescriptorsUnion_t reply_desc_union_v; 4563 uint32_t int_mask; 4564 uint8_t reply_type; 4565 4566 NDBG5(("mptsas_wait_intr")); 4567 4568 4569 /* 4570 * Get the current interrupt mask and disable interrupts. When 4571 * re-enabling ints, set mask to saved value. 4572 */ 4573 int_mask = ddi_get32(mpt->m_datap, &mpt->m_reg->HostInterruptMask); 4574 MPTSAS_DISABLE_INTR(mpt); 4575 4576 /* 4577 * Keep polling for at least (polltime * 1000) seconds 4578 */ 4579 for (cnt = 0; cnt < polltime; cnt++) { 4580 mutex_enter(&mpt->m_intr_mutex); 4581 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 4582 DDI_DMA_SYNC_FORCPU); 4583 4584 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t) 4585 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index); 4586 4587 if (ddi_get32(mpt->m_acc_post_queue_hdl, 4588 &reply_desc_union->Words.Low) == 0xFFFFFFFF || 4589 ddi_get32(mpt->m_acc_post_queue_hdl, 4590 &reply_desc_union->Words.High) == 0xFFFFFFFF) { 4591 mutex_exit(&mpt->m_intr_mutex); 4592 drv_usecwait(1000); 4593 continue; 4594 } 4595 4596 reply_type = ddi_get8(mpt->m_acc_post_queue_hdl, 4597 &reply_desc_union->Default.ReplyFlags); 4598 reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; 4599 reply_desc_union_v.Default.ReplyFlags = reply_type; 4600 if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) { 4601 reply_desc_union_v.SCSIIOSuccess.SMID = 4602 ddi_get16(mpt->m_acc_post_queue_hdl, 4603 &reply_desc_union->SCSIIOSuccess.SMID); 4604 } else if (reply_type == 4605 MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { 4606 reply_desc_union_v.AddressReply.ReplyFrameAddress = 4607 ddi_get32(mpt->m_acc_post_queue_hdl, 4608 &reply_desc_union->AddressReply.ReplyFrameAddress); 4609 reply_desc_union_v.AddressReply.SMID = 4610 ddi_get16(mpt->m_acc_post_queue_hdl, 4611 &reply_desc_union->AddressReply.SMID); 4612 } 4613 /* 4614 * Clear the reply descriptor for re-use and increment 4615 * index. 4616 */ 4617 ddi_put64(mpt->m_acc_post_queue_hdl, 4618 &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index], 4619 0xFFFFFFFFFFFFFFFF); 4620 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 4621 DDI_DMA_SYNC_FORDEV); 4622 4623 if (++mpt->m_post_index == mpt->m_post_queue_depth) { 4624 mpt->m_post_index = 0; 4625 } 4626 4627 /* 4628 * Update the global reply index 4629 */ 4630 ddi_put32(mpt->m_datap, 4631 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); 4632 mutex_exit(&mpt->m_intr_mutex); 4633 4634 /* 4635 * The reply is valid, process it according to its 4636 * type. 4637 */ 4638 mptsas_process_intr(mpt, &reply_desc_union_v); 4639 4640 4641 /* 4642 * Re-enable interrupts and quit. 4643 */ 4644 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, 4645 int_mask); 4646 return (TRUE); 4647 4648 } 4649 4650 /* 4651 * Clear polling flag, re-enable interrupts and quit. 4652 */ 4653 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, int_mask); 4654 return (FALSE); 4655 } 4656 4657 /* 4658 * For fastpath, the m_intr_mutex should be held from the begining to the end, 4659 * so we only treat those cmds that need not release m_intr_mutex(even just for 4660 * a moment) as candidate for fast processing. otherwise, we don't handle them 4661 * and just return, then in ISR, those cmds would be handled later with m_mutex 4662 * held and m_intr_mutex not held. 4663 */ 4664 static int 4665 mptsas_handle_io_fastpath(mptsas_t *mpt, 4666 uint16_t SMID) 4667 { 4668 mptsas_slots_t *slots = mpt->m_active; 4669 mptsas_cmd_t *cmd = NULL; 4670 struct scsi_pkt *pkt; 4671 4672 /* 4673 * This is a success reply so just complete the IO. First, do a sanity 4674 * check on the SMID. The final slot is used for TM requests, which 4675 * would not come into this reply handler. 4676 */ 4677 if ((SMID == 0) || (SMID > slots->m_n_slots)) { 4678 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n", 4679 SMID); 4680 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 4681 return (TRUE); 4682 } 4683 4684 cmd = slots->m_slot[SMID]; 4685 4686 /* 4687 * print warning and return if the slot is empty 4688 */ 4689 if (cmd == NULL) { 4690 mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO " 4691 "in slot %d", SMID); 4692 return (TRUE); 4693 } 4694 4695 pkt = CMD2PKT(cmd); 4696 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD | 4697 STATE_GOT_STATUS); 4698 if (cmd->cmd_flags & CFLAG_DMAVALID) { 4699 pkt->pkt_state |= STATE_XFERRED_DATA; 4700 } 4701 pkt->pkt_resid = 0; 4702 4703 /* 4704 * If the cmd is a IOC, or a passthrough, then we don't process it in 4705 * fastpath, and later it would be handled by mptsas_process_intr() 4706 * with m_mutex protected. 4707 */ 4708 if (cmd->cmd_flags & (CFLAG_PASSTHRU | CFLAG_CMDIOC)) { 4709 return (FALSE); 4710 } else { 4711 mptsas_remove_cmd0(mpt, cmd); 4712 } 4713 4714 if (cmd->cmd_flags & CFLAG_RETRY) { 4715 /* 4716 * The target returned QFULL or busy, do not add tihs 4717 * pkt to the doneq since the hba will retry 4718 * this cmd. 4719 * 4720 * The pkt has already been resubmitted in 4721 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error(). 4722 * Remove this cmd_flag here. 4723 */ 4724 cmd->cmd_flags &= ~CFLAG_RETRY; 4725 } else { 4726 mptsas_doneq_add0(mpt, cmd); 4727 } 4728 4729 /* 4730 * In fastpath, the cmd should only be a context reply, so just check 4731 * the post queue of the reply descriptor and the dmahandle of the cmd 4732 * is enough. No sense data in this case and no need to check the dma 4733 * handle where sense data dma info is saved, the dma handle of the 4734 * reply frame, and the dma handle of the reply free queue. 4735 * For the dma handle of the request queue. Check fma here since we 4736 * are sure the request must have already been sent/DMAed correctly. 4737 * otherwise checking in mptsas_scsi_start() is not correct since 4738 * at that time the dma may not start. 4739 */ 4740 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 4741 DDI_SUCCESS) || 4742 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) != 4743 DDI_SUCCESS)) { 4744 ddi_fm_service_impact(mpt->m_dip, 4745 DDI_SERVICE_UNAFFECTED); 4746 pkt->pkt_reason = CMD_TRAN_ERR; 4747 pkt->pkt_statistics = 0; 4748 } 4749 if (cmd->cmd_dmahandle && 4750 (mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS)) { 4751 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 4752 pkt->pkt_reason = CMD_TRAN_ERR; 4753 pkt->pkt_statistics = 0; 4754 } 4755 if ((cmd->cmd_extra_frames && 4756 ((mptsas_check_dma_handle(cmd->cmd_extra_frames->m_dma_hdl) != 4757 DDI_SUCCESS) || 4758 (mptsas_check_acc_handle(cmd->cmd_extra_frames->m_acc_hdl) != 4759 DDI_SUCCESS)))) { 4760 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 4761 pkt->pkt_reason = CMD_TRAN_ERR; 4762 pkt->pkt_statistics = 0; 4763 } 4764 4765 return (TRUE); 4766 } 4767 4768 static void 4769 mptsas_handle_scsi_io_success(mptsas_t *mpt, 4770 pMpi2ReplyDescriptorsUnion_t reply_desc) 4771 { 4772 pMpi2SCSIIOSuccessReplyDescriptor_t scsi_io_success; 4773 uint16_t SMID; 4774 mptsas_slots_t *slots = mpt->m_active; 4775 mptsas_cmd_t *cmd = NULL; 4776 struct scsi_pkt *pkt; 4777 4778 scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc; 4779 SMID = scsi_io_success->SMID; 4780 4781 /* 4782 * This is a success reply so just complete the IO. First, do a sanity 4783 * check on the SMID. The final slot is used for TM requests, which 4784 * would not come into this reply handler. 4785 */ 4786 if ((SMID == 0) || (SMID > slots->m_n_slots)) { 4787 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n", 4788 SMID); 4789 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 4790 return; 4791 } 4792 4793 cmd = slots->m_slot[SMID]; 4794 4795 /* 4796 * print warning and return if the slot is empty 4797 */ 4798 if (cmd == NULL) { 4799 mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO " 4800 "in slot %d", SMID); 4801 return; 4802 } 4803 4804 pkt = CMD2PKT(cmd); 4805 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD | 4806 STATE_GOT_STATUS); 4807 if (cmd->cmd_flags & CFLAG_DMAVALID) { 4808 pkt->pkt_state |= STATE_XFERRED_DATA; 4809 } 4810 pkt->pkt_resid = 0; 4811 4812 if (cmd->cmd_flags & CFLAG_PASSTHRU) { 4813 cmd->cmd_flags |= CFLAG_FINISHED; 4814 cv_broadcast(&mpt->m_passthru_cv); 4815 return; 4816 } else { 4817 mptsas_remove_cmd(mpt, cmd); 4818 } 4819 4820 if (cmd->cmd_flags & CFLAG_RETRY) { 4821 /* 4822 * The target returned QFULL or busy, do not add tihs 4823 * pkt to the doneq since the hba will retry 4824 * this cmd. 4825 * 4826 * The pkt has already been resubmitted in 4827 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error(). 4828 * Remove this cmd_flag here. 4829 */ 4830 cmd->cmd_flags &= ~CFLAG_RETRY; 4831 } else { 4832 mptsas_doneq_add(mpt, cmd); 4833 } 4834 } 4835 4836 static void 4837 mptsas_handle_address_reply(mptsas_t *mpt, 4838 pMpi2ReplyDescriptorsUnion_t reply_desc) 4839 { 4840 pMpi2AddressReplyDescriptor_t address_reply; 4841 pMPI2DefaultReply_t reply; 4842 mptsas_fw_diagnostic_buffer_t *pBuffer; 4843 uint32_t reply_addr; 4844 uint16_t SMID, iocstatus; 4845 mptsas_slots_t *slots = mpt->m_active; 4846 mptsas_cmd_t *cmd = NULL; 4847 uint8_t function, buffer_type; 4848 m_replyh_arg_t *args; 4849 int reply_frame_no; 4850 4851 ASSERT(mutex_owned(&mpt->m_mutex)); 4852 4853 address_reply = (pMpi2AddressReplyDescriptor_t)reply_desc; 4854 4855 reply_addr = address_reply->ReplyFrameAddress; 4856 SMID = address_reply->SMID; 4857 /* 4858 * If reply frame is not in the proper range we should ignore this 4859 * message and exit the interrupt handler. 4860 */ 4861 if ((reply_addr < mpt->m_reply_frame_dma_addr) || 4862 (reply_addr >= (mpt->m_reply_frame_dma_addr + 4863 (mpt->m_reply_frame_size * mpt->m_max_replies))) || 4864 ((reply_addr - mpt->m_reply_frame_dma_addr) % 4865 mpt->m_reply_frame_size != 0)) { 4866 mptsas_log(mpt, CE_WARN, "?Received invalid reply frame " 4867 "address 0x%x\n", reply_addr); 4868 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 4869 return; 4870 } 4871 4872 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 4873 DDI_DMA_SYNC_FORCPU); 4874 reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame + (reply_addr - 4875 mpt->m_reply_frame_dma_addr)); 4876 function = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Function); 4877 4878 /* 4879 * don't get slot information and command for events since these values 4880 * don't exist 4881 */ 4882 if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) && 4883 (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) { 4884 /* 4885 * This could be a TM reply, which use the last allocated SMID, 4886 * so allow for that. 4887 */ 4888 if ((SMID == 0) || (SMID > (slots->m_n_slots + 1))) { 4889 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of " 4890 "%d\n", SMID); 4891 ddi_fm_service_impact(mpt->m_dip, 4892 DDI_SERVICE_UNAFFECTED); 4893 return; 4894 } 4895 4896 cmd = slots->m_slot[SMID]; 4897 4898 /* 4899 * print warning and return if the slot is empty 4900 */ 4901 if (cmd == NULL) { 4902 mptsas_log(mpt, CE_WARN, "?NULL command for address " 4903 "reply in slot %d", SMID); 4904 return; 4905 } 4906 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 4907 (cmd->cmd_flags & CFLAG_CONFIG) || 4908 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 4909 cmd->cmd_rfm = reply_addr; 4910 cmd->cmd_flags |= CFLAG_FINISHED; 4911 cv_broadcast(&mpt->m_passthru_cv); 4912 cv_broadcast(&mpt->m_config_cv); 4913 cv_broadcast(&mpt->m_fw_diag_cv); 4914 return; 4915 } else if (!(cmd->cmd_flags & CFLAG_FW_CMD)) { 4916 mptsas_remove_cmd(mpt, cmd); 4917 } 4918 NDBG31(("\t\tmptsas_process_intr: slot=%d", SMID)); 4919 } 4920 /* 4921 * Depending on the function, we need to handle 4922 * the reply frame (and cmd) differently. 4923 */ 4924 switch (function) { 4925 case MPI2_FUNCTION_SCSI_IO_REQUEST: 4926 mptsas_check_scsi_io_error(mpt, (pMpi2SCSIIOReply_t)reply, cmd); 4927 break; 4928 case MPI2_FUNCTION_SCSI_TASK_MGMT: 4929 cmd->cmd_rfm = reply_addr; 4930 mptsas_check_task_mgt(mpt, (pMpi2SCSIManagementReply_t)reply, 4931 cmd); 4932 break; 4933 case MPI2_FUNCTION_FW_DOWNLOAD: 4934 cmd->cmd_flags |= CFLAG_FINISHED; 4935 cv_signal(&mpt->m_fw_cv); 4936 break; 4937 case MPI2_FUNCTION_EVENT_NOTIFICATION: 4938 reply_frame_no = (reply_addr - mpt->m_reply_frame_dma_addr) / 4939 mpt->m_reply_frame_size; 4940 args = &mpt->m_replyh_args[reply_frame_no]; 4941 args->mpt = (void *)mpt; 4942 args->rfm = reply_addr; 4943 4944 /* 4945 * Record the event if its type is enabled in 4946 * this mpt instance by ioctl. 4947 */ 4948 mptsas_record_event(args); 4949 4950 /* 4951 * Handle time critical events 4952 * NOT_RESPONDING/ADDED only now 4953 */ 4954 if (mptsas_handle_event_sync(args) == DDI_SUCCESS) { 4955 /* 4956 * Would not return main process, 4957 * just let taskq resolve ack action 4958 * and ack would be sent in taskq thread 4959 */ 4960 NDBG20(("send mptsas_handle_event_sync success")); 4961 } 4962 if ((ddi_taskq_dispatch(mpt->m_event_taskq, mptsas_handle_event, 4963 (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) { 4964 mptsas_log(mpt, CE_WARN, "No memory available" 4965 "for dispatch taskq"); 4966 /* 4967 * Return the reply frame to the free queue. 4968 */ 4969 ddi_put32(mpt->m_acc_free_queue_hdl, 4970 &((uint32_t *)(void *) 4971 mpt->m_free_queue)[mpt->m_free_index], reply_addr); 4972 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 4973 DDI_DMA_SYNC_FORDEV); 4974 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 4975 mpt->m_free_index = 0; 4976 } 4977 4978 ddi_put32(mpt->m_datap, 4979 &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index); 4980 } 4981 return; 4982 case MPI2_FUNCTION_DIAG_BUFFER_POST: 4983 /* 4984 * If SMID is 0, this implies that the reply is due to a 4985 * release function with a status that the buffer has been 4986 * released. Set the buffer flags accordingly. 4987 */ 4988 if (SMID == 0) { 4989 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 4990 &reply->IOCStatus); 4991 buffer_type = ddi_get8(mpt->m_acc_reply_frame_hdl, 4992 &(((pMpi2DiagBufferPostReply_t)reply)->BufferType)); 4993 if (iocstatus == MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED) { 4994 pBuffer = 4995 &mpt->m_fw_diag_buffer_list[buffer_type]; 4996 pBuffer->valid_data = TRUE; 4997 pBuffer->owned_by_firmware = FALSE; 4998 pBuffer->immediate = FALSE; 4999 } 5000 } else { 5001 /* 5002 * Normal handling of diag post reply with SMID. 5003 */ 5004 cmd = slots->m_slot[SMID]; 5005 5006 /* 5007 * print warning and return if the slot is empty 5008 */ 5009 if (cmd == NULL) { 5010 mptsas_log(mpt, CE_WARN, "?NULL command for " 5011 "address reply in slot %d", SMID); 5012 return; 5013 } 5014 cmd->cmd_rfm = reply_addr; 5015 cmd->cmd_flags |= CFLAG_FINISHED; 5016 cv_broadcast(&mpt->m_fw_diag_cv); 5017 } 5018 return; 5019 default: 5020 mptsas_log(mpt, CE_WARN, "Unknown function 0x%x ", function); 5021 break; 5022 } 5023 5024 /* 5025 * Return the reply frame to the free queue. 5026 */ 5027 ddi_put32(mpt->m_acc_free_queue_hdl, 5028 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 5029 reply_addr); 5030 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 5031 DDI_DMA_SYNC_FORDEV); 5032 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 5033 mpt->m_free_index = 0; 5034 } 5035 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 5036 mpt->m_free_index); 5037 5038 if (cmd->cmd_flags & CFLAG_FW_CMD) 5039 return; 5040 5041 if (cmd->cmd_flags & CFLAG_RETRY) { 5042 /* 5043 * The target returned QFULL or busy, do not add tihs 5044 * pkt to the doneq since the hba will retry 5045 * this cmd. 5046 * 5047 * The pkt has already been resubmitted in 5048 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error(). 5049 * Remove this cmd_flag here. 5050 */ 5051 cmd->cmd_flags &= ~CFLAG_RETRY; 5052 } else { 5053 mptsas_doneq_add(mpt, cmd); 5054 } 5055 } 5056 5057 static void 5058 mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, 5059 mptsas_cmd_t *cmd) 5060 { 5061 uint8_t scsi_status, scsi_state; 5062 uint16_t ioc_status; 5063 uint32_t xferred, sensecount, responsedata, loginfo = 0; 5064 struct scsi_pkt *pkt; 5065 struct scsi_arq_status *arqstat; 5066 struct buf *bp; 5067 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 5068 uint8_t *sensedata = NULL; 5069 5070 if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) == 5071 (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) { 5072 bp = cmd->cmd_ext_arq_buf; 5073 } else { 5074 bp = cmd->cmd_arq_buf; 5075 } 5076 5077 scsi_status = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIStatus); 5078 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus); 5079 scsi_state = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIState); 5080 xferred = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->TransferCount); 5081 sensecount = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->SenseCount); 5082 responsedata = ddi_get32(mpt->m_acc_reply_frame_hdl, 5083 &reply->ResponseInfo); 5084 5085 if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 5086 loginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 5087 &reply->IOCLogInfo); 5088 mptsas_log(mpt, CE_NOTE, 5089 "?Log info 0x%x received for target %d.\n" 5090 "\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x", 5091 loginfo, Tgt(cmd), scsi_status, ioc_status, 5092 scsi_state); 5093 } 5094 5095 NDBG31(("\t\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x", 5096 scsi_status, ioc_status, scsi_state)); 5097 5098 pkt = CMD2PKT(cmd); 5099 *(pkt->pkt_scbp) = scsi_status; 5100 5101 if (loginfo == 0x31170000) { 5102 /* 5103 * if loginfo PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY 5104 * 0x31170000 comes, that means the device missing delay 5105 * is in progressing, the command need retry later. 5106 */ 5107 *(pkt->pkt_scbp) = STATUS_BUSY; 5108 return; 5109 } 5110 5111 if ((scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS) && 5112 ((ioc_status & MPI2_IOCSTATUS_MASK) == 5113 MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE)) { 5114 pkt->pkt_reason = CMD_INCOMPLETE; 5115 pkt->pkt_state |= STATE_GOT_BUS; 5116 mutex_enter(&ptgt->m_tgt_intr_mutex); 5117 if (ptgt->m_reset_delay == 0) { 5118 mptsas_set_throttle(mpt, ptgt, 5119 DRAIN_THROTTLE); 5120 } 5121 mutex_exit(&ptgt->m_tgt_intr_mutex); 5122 return; 5123 } 5124 5125 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) { 5126 responsedata &= 0x000000FF; 5127 if (responsedata & MPTSAS_SCSI_RESPONSE_CODE_TLR_OFF) { 5128 mptsas_log(mpt, CE_NOTE, "Do not support the TLR\n"); 5129 pkt->pkt_reason = CMD_TLR_OFF; 5130 return; 5131 } 5132 } 5133 5134 5135 switch (scsi_status) { 5136 case MPI2_SCSI_STATUS_CHECK_CONDITION: 5137 pkt->pkt_resid = (cmd->cmd_dmacount - xferred); 5138 arqstat = (void*)(pkt->pkt_scbp); 5139 arqstat->sts_rqpkt_status = *((struct scsi_status *) 5140 (pkt->pkt_scbp)); 5141 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 5142 STATE_SENT_CMD | STATE_GOT_STATUS | STATE_ARQ_DONE); 5143 if (cmd->cmd_flags & CFLAG_XARQ) { 5144 pkt->pkt_state |= STATE_XARQ_DONE; 5145 } 5146 if (pkt->pkt_resid != cmd->cmd_dmacount) { 5147 pkt->pkt_state |= STATE_XFERRED_DATA; 5148 } 5149 arqstat->sts_rqpkt_reason = pkt->pkt_reason; 5150 arqstat->sts_rqpkt_state = pkt->pkt_state; 5151 arqstat->sts_rqpkt_state |= STATE_XFERRED_DATA; 5152 arqstat->sts_rqpkt_statistics = pkt->pkt_statistics; 5153 sensedata = (uint8_t *)&arqstat->sts_sensedata; 5154 5155 bcopy((uchar_t *)bp->b_un.b_addr, sensedata, 5156 ((cmd->cmd_rqslen >= sensecount) ? sensecount : 5157 cmd->cmd_rqslen)); 5158 arqstat->sts_rqpkt_resid = (cmd->cmd_rqslen - sensecount); 5159 cmd->cmd_flags |= CFLAG_CMDARQ; 5160 /* 5161 * Set proper status for pkt if autosense was valid 5162 */ 5163 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) { 5164 struct scsi_status zero_status = { 0 }; 5165 arqstat->sts_rqpkt_status = zero_status; 5166 } 5167 5168 /* 5169 * ASC=0x47 is parity error 5170 * ASC=0x48 is initiator detected error received 5171 */ 5172 if ((scsi_sense_key(sensedata) == KEY_ABORTED_COMMAND) && 5173 ((scsi_sense_asc(sensedata) == 0x47) || 5174 (scsi_sense_asc(sensedata) == 0x48))) { 5175 mptsas_log(mpt, CE_NOTE, "Aborted_command!"); 5176 } 5177 5178 /* 5179 * ASC/ASCQ=0x3F/0x0E means report_luns data changed 5180 * ASC/ASCQ=0x25/0x00 means invalid lun 5181 */ 5182 if (((scsi_sense_key(sensedata) == KEY_UNIT_ATTENTION) && 5183 (scsi_sense_asc(sensedata) == 0x3F) && 5184 (scsi_sense_ascq(sensedata) == 0x0E)) || 5185 ((scsi_sense_key(sensedata) == KEY_ILLEGAL_REQUEST) && 5186 (scsi_sense_asc(sensedata) == 0x25) && 5187 (scsi_sense_ascq(sensedata) == 0x00))) { 5188 mptsas_topo_change_list_t *topo_node = NULL; 5189 5190 topo_node = kmem_zalloc( 5191 sizeof (mptsas_topo_change_list_t), 5192 KM_NOSLEEP); 5193 if (topo_node == NULL) { 5194 mptsas_log(mpt, CE_NOTE, "No memory" 5195 "resource for handle SAS dynamic" 5196 "reconfigure.\n"); 5197 break; 5198 } 5199 topo_node->mpt = mpt; 5200 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET; 5201 topo_node->un.phymask = ptgt->m_phymask; 5202 topo_node->devhdl = ptgt->m_devhdl; 5203 topo_node->object = (void *)ptgt; 5204 topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED; 5205 5206 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 5207 mptsas_handle_dr, 5208 (void *)topo_node, 5209 DDI_NOSLEEP)) != DDI_SUCCESS) { 5210 mptsas_log(mpt, CE_NOTE, "mptsas start taskq" 5211 "for handle SAS dynamic reconfigure" 5212 "failed. \n"); 5213 } 5214 } 5215 break; 5216 case MPI2_SCSI_STATUS_GOOD: 5217 switch (ioc_status & MPI2_IOCSTATUS_MASK) { 5218 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 5219 pkt->pkt_reason = CMD_DEV_GONE; 5220 pkt->pkt_state |= STATE_GOT_BUS; 5221 mutex_enter(&ptgt->m_tgt_intr_mutex); 5222 if (ptgt->m_reset_delay == 0) { 5223 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5224 } 5225 mutex_exit(&ptgt->m_tgt_intr_mutex); 5226 NDBG31(("lost disk for target%d, command:%x", 5227 Tgt(cmd), pkt->pkt_cdbp[0])); 5228 break; 5229 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN: 5230 NDBG31(("data overrun: xferred=%d", xferred)); 5231 NDBG31(("dmacount=%d", cmd->cmd_dmacount)); 5232 pkt->pkt_reason = CMD_DATA_OVR; 5233 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET 5234 | STATE_SENT_CMD | STATE_GOT_STATUS 5235 | STATE_XFERRED_DATA); 5236 pkt->pkt_resid = 0; 5237 break; 5238 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: 5239 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN: 5240 NDBG31(("data underrun: xferred=%d", xferred)); 5241 NDBG31(("dmacount=%d", cmd->cmd_dmacount)); 5242 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET 5243 | STATE_SENT_CMD | STATE_GOT_STATUS); 5244 pkt->pkt_resid = (cmd->cmd_dmacount - xferred); 5245 if (pkt->pkt_resid != cmd->cmd_dmacount) { 5246 pkt->pkt_state |= STATE_XFERRED_DATA; 5247 } 5248 break; 5249 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: 5250 mptsas_set_pkt_reason(mpt, 5251 cmd, CMD_RESET, STAT_BUS_RESET); 5252 break; 5253 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: 5254 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: 5255 mptsas_set_pkt_reason(mpt, 5256 cmd, CMD_RESET, STAT_DEV_RESET); 5257 break; 5258 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR: 5259 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR: 5260 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET); 5261 mptsas_set_pkt_reason(mpt, 5262 cmd, CMD_TERMINATED, STAT_TERMINATED); 5263 break; 5264 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: 5265 case MPI2_IOCSTATUS_BUSY: 5266 /* 5267 * set throttles to drain 5268 */ 5269 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 5270 &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST); 5271 while (ptgt != NULL) { 5272 mutex_enter(&ptgt->m_tgt_intr_mutex); 5273 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5274 mutex_exit(&ptgt->m_tgt_intr_mutex); 5275 5276 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 5277 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 5278 } 5279 5280 /* 5281 * retry command 5282 */ 5283 cmd->cmd_flags |= CFLAG_RETRY; 5284 cmd->cmd_pkt_flags |= FLAG_HEAD; 5285 5286 mutex_exit(&mpt->m_mutex); 5287 (void) mptsas_accept_pkt(mpt, cmd); 5288 mutex_enter(&mpt->m_mutex); 5289 break; 5290 default: 5291 mptsas_log(mpt, CE_WARN, 5292 "unknown ioc_status = %x\n", ioc_status); 5293 mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer " 5294 "count = %x, scsi_status = %x", scsi_state, 5295 xferred, scsi_status); 5296 break; 5297 } 5298 break; 5299 case MPI2_SCSI_STATUS_TASK_SET_FULL: 5300 mptsas_handle_qfull(mpt, cmd); 5301 break; 5302 case MPI2_SCSI_STATUS_BUSY: 5303 NDBG31(("scsi_status busy received")); 5304 break; 5305 case MPI2_SCSI_STATUS_RESERVATION_CONFLICT: 5306 NDBG31(("scsi_status reservation conflict received")); 5307 break; 5308 default: 5309 mptsas_log(mpt, CE_WARN, "scsi_status=%x, ioc_status=%x\n", 5310 scsi_status, ioc_status); 5311 mptsas_log(mpt, CE_WARN, 5312 "mptsas_process_intr: invalid scsi status\n"); 5313 break; 5314 } 5315 } 5316 5317 static void 5318 mptsas_check_task_mgt(mptsas_t *mpt, pMpi2SCSIManagementReply_t reply, 5319 mptsas_cmd_t *cmd) 5320 { 5321 uint8_t task_type; 5322 uint16_t ioc_status; 5323 uint32_t log_info; 5324 uint16_t dev_handle; 5325 struct scsi_pkt *pkt = CMD2PKT(cmd); 5326 5327 task_type = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->TaskType); 5328 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus); 5329 log_info = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo); 5330 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->DevHandle); 5331 5332 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 5333 mptsas_log(mpt, CE_WARN, "mptsas_check_task_mgt: Task 0x%x " 5334 "failed. IOCStatus=0x%x IOCLogInfo=0x%x target=%d\n", 5335 task_type, ioc_status, log_info, dev_handle); 5336 pkt->pkt_reason = CMD_INCOMPLETE; 5337 return; 5338 } 5339 5340 switch (task_type) { 5341 case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK: 5342 case MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET: 5343 case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK: 5344 case MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA: 5345 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET: 5346 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION: 5347 break; 5348 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 5349 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 5350 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 5351 /* 5352 * Check for invalid DevHandle of 0 in case application 5353 * sends bad command. DevHandle of 0 could cause problems. 5354 */ 5355 if (dev_handle == 0) { 5356 mptsas_log(mpt, CE_WARN, "!Can't flush target with" 5357 " DevHandle of 0."); 5358 } else { 5359 mptsas_flush_target(mpt, dev_handle, Lun(cmd), 5360 task_type); 5361 } 5362 break; 5363 default: 5364 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.", 5365 task_type); 5366 mptsas_log(mpt, CE_WARN, "ioc status = %x", ioc_status); 5367 break; 5368 } 5369 } 5370 5371 static void 5372 mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg) 5373 { 5374 mptsas_t *mpt = arg->mpt; 5375 uint64_t t = arg->t; 5376 mptsas_cmd_t *cmd; 5377 struct scsi_pkt *pkt; 5378 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 5379 5380 mutex_enter(&item->mutex); 5381 while (item->flag & MPTSAS_DONEQ_THREAD_ACTIVE) { 5382 if (!item->doneq) { 5383 cv_wait(&item->cv, &item->mutex); 5384 } 5385 pkt = NULL; 5386 if ((cmd = mptsas_doneq_thread_rm(mpt, t)) != NULL) { 5387 cmd->cmd_flags |= CFLAG_COMPLETED; 5388 pkt = CMD2PKT(cmd); 5389 } 5390 mutex_exit(&item->mutex); 5391 if (pkt) { 5392 mptsas_pkt_comp(pkt, cmd); 5393 } 5394 mutex_enter(&item->mutex); 5395 } 5396 mutex_exit(&item->mutex); 5397 mutex_enter(&mpt->m_doneq_mutex); 5398 mpt->m_doneq_thread_n--; 5399 cv_broadcast(&mpt->m_doneq_thread_cv); 5400 mutex_exit(&mpt->m_doneq_mutex); 5401 } 5402 5403 /* 5404 * mpt interrupt handler. 5405 */ 5406 static uint_t 5407 mptsas_intr(caddr_t arg1, caddr_t arg2) 5408 { 5409 mptsas_t *mpt = (void *)arg1; 5410 pMpi2ReplyDescriptorsUnion_t reply_desc_union; 5411 uchar_t did_reply = FALSE; 5412 int i = 0, j; 5413 uint8_t reply_type; 5414 uint16_t SMID; 5415 5416 NDBG1(("mptsas_intr: arg1 0x%p arg2 0x%p", (void *)arg1, (void *)arg2)); 5417 5418 /* 5419 * 1. 5420 * To avoid using m_mutex in the ISR(ISR referes not only mptsas_intr, 5421 * but all of the recursive called functions in it. the same below), 5422 * separate mutexs are introduced to protect the elements shown in ISR. 5423 * 3 type of mutex are involved here: 5424 * a)per instance mutex m_intr_mutex. 5425 * b)per target mutex m_tgt_intr_mutex. 5426 * c)mutex that protect the free slot. 5427 * 5428 * a)per instance mutex m_intr_mutex: 5429 * used to protect m_options, m_power, m_waitq, etc that would be 5430 * checked/modified in ISR; protect the getting and setting the reply 5431 * descriptor index; protect the m_slots[]; 5432 * 5433 * b)per target mutex m_tgt_intr_mutex: 5434 * used to protect per target element which has relationship to ISR. 5435 * contention for the new per target mutex is just as high as it in 5436 * sd(7d) driver. 5437 * 5438 * c)mutexs that protect the free slots: 5439 * those mutexs are introduced to minimize the mutex contentions 5440 * between the IO request threads where free slots are allocated 5441 * for sending cmds and ISR where slots holding outstanding cmds 5442 * are returned to the free pool. 5443 * the idea is like this: 5444 * 1) Partition all of the free slot into NCPU groups. For example, 5445 * In system where we have 15 slots, and 4 CPU, then slot s1,s5,s9,s13 5446 * are marked belonging to CPU1, s2,s6,s10,s14 to CPU2, s3,s7,s11,s15 5447 * to CPU3, and s4,s8,s12 to CPU4. 5448 * 2) In each of the group, an alloc/release queue pair is created, 5449 * and both the allocq and the releaseq have a dedicated mutex. 5450 * 3) When init, all of the slots in a CPU group are inserted into the 5451 * allocq of its CPU's pair. 5452 * 4) When doing IO, 5453 * mptsas_scsi_start() 5454 * { 5455 * cpuid = the cpu NO of the cpu where this thread is running on 5456 * retry: 5457 * mutex_enter(&allocq[cpuid]); 5458 * if (get free slot = success) { 5459 * remove the slot from the allocq 5460 * mutex_exit(&allocq[cpuid]); 5461 * return(success); 5462 * } else { // exchange allocq and releaseq and try again 5463 * mutex_enter(&releq[cpuid]); 5464 * exchange the allocq and releaseq of this pair; 5465 * mutex_exit(&releq[cpuid]); 5466 * if (try to get free slot again = success) { 5467 * remove the slot from the allocq 5468 * mutex_exit(&allocq[cpuid]); 5469 * return(success); 5470 * } else { 5471 * MOD(cpuid)++; 5472 * goto retry; 5473 * if (all CPU groups tried) 5474 * mutex_exit(&allocq[cpuid]); 5475 * return(failure); 5476 * } 5477 * } 5478 * } 5479 * ISR() 5480 * { 5481 * cpuid = the CPU group id where the slot sending the 5482 * cmd belongs; 5483 * mutex_enter(&releq[cpuid]); 5484 * remove the slot from the releaseq 5485 * mutex_exit(&releq[cpuid]); 5486 * } 5487 * This way, only when the queue pair doing exchange have mutex 5488 * contentions. 5489 * 5490 * For mutex m_intr_mutex and m_tgt_intr_mutex, there are 2 scenarios: 5491 * 5492 * a)If the elements are only checked but not modified in the ISR, then 5493 * only the places where those elements are modifed(outside of ISR) 5494 * need to be protected by the new introduced mutex. 5495 * For example, data A is only read/checked in ISR, then we need do 5496 * like this: 5497 * In ISR: 5498 * { 5499 * mutex_enter(&new_mutex); 5500 * read(A); 5501 * mutex_exit(&new_mutex); 5502 * //the new_mutex here is either the m_tgt_intr_mutex or 5503 * //the m_intr_mutex. 5504 * } 5505 * In non-ISR 5506 * { 5507 * mutex_enter(&m_mutex); //the stock driver already did this 5508 * mutex_enter(&new_mutex); 5509 * write(A); 5510 * mutex_exit(&new_mutex); 5511 * mutex_exit(&m_mutex); //the stock driver already did this 5512 * 5513 * read(A); 5514 * // read(A) in non-ISR is not required to be protected by new 5515 * // mutex since 'A' has already been protected by m_mutex 5516 * // outside of the ISR 5517 * } 5518 * 5519 * Those fields in mptsas_target_t/ptgt which are only read in ISR 5520 * fall into this catergory. So they, together with the fields which 5521 * are never read in ISR, are not necessary to be protected by 5522 * m_tgt_intr_mutex, don't bother. 5523 * checking of m_waitq also falls into this catergory. so all of the 5524 * place outside of ISR where the m_waitq is modified, such as in 5525 * mptsas_waitq_add(), mptsas_waitq_delete(), mptsas_waitq_rm(), 5526 * m_intr_mutex should be used. 5527 * 5528 * b)If the elements are modified in the ISR, then each place where 5529 * those elements are referred(outside of ISR) need to be protected 5530 * by the new introduced mutex. Of course, if those elements only 5531 * appear in the non-key code path, that is, they don't affect 5532 * performance, then the m_mutex can still be used as before. 5533 * For example, data B is modified in key code path in ISR, and data C 5534 * is modified in non-key code path in ISR, then we can do like this: 5535 * In ISR: 5536 * { 5537 * mutex_enter(&new_mutex); 5538 * wirte(B); 5539 * mutex_exit(&new_mutex); 5540 * if (seldom happen) { 5541 * mutex_enter(&m_mutex); 5542 * write(C); 5543 * mutex_exit(&m_mutex); 5544 * } 5545 * //the new_mutex here is either the m_tgt_intr_mutex or 5546 * //the m_intr_mutex. 5547 * } 5548 * In non-ISR 5549 * { 5550 * mutex_enter(&new_mutex); 5551 * write(B); 5552 * mutex_exit(&new_mutex); 5553 * 5554 * mutex_enter(&new_mutex); 5555 * read(B); 5556 * mutex_exit(&new_mutex); 5557 * // both write(B) and read(B) in non-ISR is required to be 5558 * // protected by new mutex outside of the ISR 5559 * 5560 * mutex_enter(&m_mutex); //the stock driver already did this 5561 * read(C); 5562 * write(C); 5563 * mutex_exit(&m_mutex); //the stock driver already did this 5564 * // both write(C) and read(C) in non-ISR have been already 5565 * // been protected by m_mutex outside of the ISR 5566 * } 5567 * 5568 * For example, ptgt->m_t_ncmds fall into 'B' of this catergory, and 5569 * elements shown in address reply, restart_hba, passthrough, IOC 5570 * fall into 'C' of this catergory. 5571 * 5572 * In any case where mutexs are nested, make sure in the following 5573 * order: 5574 * m_mutex -> m_intr_mutex -> m_tgt_intr_mutex 5575 * m_intr_mutex -> m_tgt_intr_mutex 5576 * m_mutex -> m_intr_mutex 5577 * m_mutex -> m_tgt_intr_mutex 5578 * 5579 * 2. 5580 * Make sure at any time, getting the ReplyDescriptor by m_post_index 5581 * and setting m_post_index to the ReplyDescriptorIndex register are 5582 * atomic. Since m_mutex is not used for this purpose in ISR, the new 5583 * mutex m_intr_mutex must play this role. So mptsas_poll(), where this 5584 * kind of getting/setting is also performed, must use m_intr_mutex. 5585 * Note, since context reply in ISR/process_intr is the only code path 5586 * which affect performance, a fast path is introduced to only handle 5587 * the read/write IO having context reply. For other IOs such as 5588 * passthrough and IOC with context reply and all address reply, we 5589 * use the as-is process_intr() to handle them. In order to keep the 5590 * same semantics in process_intr(), make sure any new mutex is not held 5591 * before enterring it. 5592 */ 5593 5594 mutex_enter(&mpt->m_intr_mutex); 5595 5596 /* 5597 * If interrupts are shared by two channels then check whether this 5598 * interrupt is genuinely for this channel by making sure first the 5599 * chip is in high power state. 5600 */ 5601 if ((mpt->m_options & MPTSAS_OPT_PM) && 5602 (mpt->m_power_level != PM_LEVEL_D0)) { 5603 mutex_exit(&mpt->m_intr_mutex); 5604 return (DDI_INTR_UNCLAIMED); 5605 } 5606 5607 /* 5608 * If polling, interrupt was triggered by some shared interrupt because 5609 * IOC interrupts are disabled during polling, so polling routine will 5610 * handle any replies. Considering this, if polling is happening, 5611 * return with interrupt unclaimed. 5612 */ 5613 if (mpt->m_polled_intr) { 5614 mutex_exit(&mpt->m_intr_mutex); 5615 mptsas_log(mpt, CE_WARN, "mpt_sas: Unclaimed interrupt"); 5616 return (DDI_INTR_UNCLAIMED); 5617 } 5618 5619 /* 5620 * Read the istat register. 5621 */ 5622 if ((INTPENDING(mpt)) != 0) { 5623 /* 5624 * read fifo until empty. 5625 */ 5626 #ifndef __lock_lint 5627 _NOTE(CONSTCOND) 5628 #endif 5629 while (TRUE) { 5630 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 5631 DDI_DMA_SYNC_FORCPU); 5632 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t) 5633 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index); 5634 5635 if (ddi_get32(mpt->m_acc_post_queue_hdl, 5636 &reply_desc_union->Words.Low) == 0xFFFFFFFF || 5637 ddi_get32(mpt->m_acc_post_queue_hdl, 5638 &reply_desc_union->Words.High) == 0xFFFFFFFF) { 5639 break; 5640 } 5641 5642 /* 5643 * The reply is valid, process it according to its 5644 * type. Also, set a flag for updating the reply index 5645 * after they've all been processed. 5646 */ 5647 did_reply = TRUE; 5648 5649 reply_type = ddi_get8(mpt->m_acc_post_queue_hdl, 5650 &reply_desc_union->Default.ReplyFlags); 5651 reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; 5652 mpt->m_reply[i].Default.ReplyFlags = reply_type; 5653 if (reply_type == 5654 MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) { 5655 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, 5656 &reply_desc_union->SCSIIOSuccess.SMID); 5657 if (mptsas_handle_io_fastpath(mpt, SMID) != 5658 TRUE) { 5659 mpt->m_reply[i].SCSIIOSuccess.SMID = 5660 SMID; 5661 i++; 5662 } 5663 } else if (reply_type == 5664 MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { 5665 mpt->m_reply[i].AddressReply.ReplyFrameAddress = 5666 ddi_get32(mpt->m_acc_post_queue_hdl, 5667 &reply_desc_union->AddressReply. 5668 ReplyFrameAddress); 5669 mpt->m_reply[i].AddressReply.SMID = 5670 ddi_get16(mpt->m_acc_post_queue_hdl, 5671 &reply_desc_union->AddressReply.SMID); 5672 i++; 5673 } 5674 /* 5675 * Clear the reply descriptor for re-use and increment 5676 * index. 5677 */ 5678 ddi_put64(mpt->m_acc_post_queue_hdl, 5679 &((uint64_t *)(void *)mpt->m_post_queue) 5680 [mpt->m_post_index], 0xFFFFFFFFFFFFFFFF); 5681 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 5682 DDI_DMA_SYNC_FORDEV); 5683 5684 /* 5685 * Increment post index and roll over if needed. 5686 */ 5687 if (++mpt->m_post_index == mpt->m_post_queue_depth) { 5688 mpt->m_post_index = 0; 5689 } 5690 if (i >= MPI_ADDRESS_COALSCE_MAX) 5691 break; 5692 } 5693 5694 /* 5695 * Update the global reply index if at least one reply was 5696 * processed. 5697 */ 5698 if (did_reply) { 5699 ddi_put32(mpt->m_datap, 5700 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); 5701 5702 /* 5703 * For fma, only check the PIO is required and enough 5704 * here. Those cases where fastpath is not hit, the 5705 * mptsas_fma_check() check all of the types of 5706 * fma. That is not necessary and sometimes not 5707 * correct. fma check should only be done after 5708 * the PIO and/or dma is performed. 5709 */ 5710 if ((mptsas_check_acc_handle(mpt->m_datap) != 5711 DDI_SUCCESS)) { 5712 ddi_fm_service_impact(mpt->m_dip, 5713 DDI_SERVICE_UNAFFECTED); 5714 } 5715 5716 } 5717 } else { 5718 mutex_exit(&mpt->m_intr_mutex); 5719 return (DDI_INTR_UNCLAIMED); 5720 } 5721 NDBG1(("mptsas_intr complete")); 5722 mutex_exit(&mpt->m_intr_mutex); 5723 5724 /* 5725 * Since most of the cmds(read and write IO with success return.) 5726 * have already been processed in fast path in which the m_mutex 5727 * is not held, handling here the address reply and other context reply 5728 * such as passthrough and IOC cmd with m_mutex held should be a big 5729 * issue for performance. 5730 * If holding m_mutex to process these cmds was still an obvious issue, 5731 * we can process them in a taskq. 5732 */ 5733 for (j = 0; j < i; j++) { 5734 mutex_enter(&mpt->m_mutex); 5735 mptsas_process_intr(mpt, &mpt->m_reply[j]); 5736 mutex_exit(&mpt->m_mutex); 5737 } 5738 5739 /* 5740 * If no helper threads are created, process the doneq in ISR. If 5741 * helpers are created, use the doneq length as a metric to measure the 5742 * load on the interrupt CPU. If it is long enough, which indicates the 5743 * load is heavy, then we deliver the IO completions to the helpers. 5744 * This measurement has some limitations, although it is simple and 5745 * straightforward and works well for most of the cases at present. 5746 */ 5747 if (!mpt->m_doneq_thread_n) { 5748 mptsas_doneq_empty(mpt); 5749 } else { 5750 int helper = 1; 5751 mutex_enter(&mpt->m_intr_mutex); 5752 if (mpt->m_doneq_len <= mpt->m_doneq_length_threshold) 5753 helper = 0; 5754 mutex_exit(&mpt->m_intr_mutex); 5755 if (helper) { 5756 mptsas_deliver_doneq_thread(mpt); 5757 } else { 5758 mptsas_doneq_empty(mpt); 5759 } 5760 } 5761 5762 /* 5763 * If there are queued cmd, start them now. 5764 */ 5765 mutex_enter(&mpt->m_intr_mutex); 5766 if (mpt->m_waitq != NULL) { 5767 mutex_exit(&mpt->m_intr_mutex); 5768 mutex_enter(&mpt->m_mutex); 5769 mptsas_restart_hba(mpt); 5770 mutex_exit(&mpt->m_mutex); 5771 return (DDI_INTR_CLAIMED); 5772 } 5773 mutex_exit(&mpt->m_intr_mutex); 5774 return (DDI_INTR_CLAIMED); 5775 } 5776 5777 /* 5778 * In ISR, the successfully completed read and write IO are processed in a 5779 * fast path. This function is only used to handle non-fastpath IO, including 5780 * all of the address reply, and the context reply for IOC cmd, passthrough, 5781 * etc. 5782 * This function is also used to process polled cmd. 5783 */ 5784 static void 5785 mptsas_process_intr(mptsas_t *mpt, 5786 pMpi2ReplyDescriptorsUnion_t reply_desc_union) 5787 { 5788 uint8_t reply_type; 5789 5790 /* 5791 * The reply is valid, process it according to its 5792 * type. Also, set a flag for updated the reply index 5793 * after they've all been processed. 5794 */ 5795 reply_type = reply_desc_union->Default.ReplyFlags; 5796 if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) { 5797 mptsas_handle_scsi_io_success(mpt, reply_desc_union); 5798 } else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { 5799 mptsas_handle_address_reply(mpt, reply_desc_union); 5800 } else { 5801 mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type); 5802 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 5803 } 5804 } 5805 5806 /* 5807 * handle qfull condition 5808 */ 5809 static void 5810 mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd) 5811 { 5812 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 5813 5814 if ((++cmd->cmd_qfull_retries > ptgt->m_qfull_retries) || 5815 (ptgt->m_qfull_retries == 0)) { 5816 /* 5817 * We have exhausted the retries on QFULL, or, 5818 * the target driver has indicated that it 5819 * wants to handle QFULL itself by setting 5820 * qfull-retries capability to 0. In either case 5821 * we want the target driver's QFULL handling 5822 * to kick in. We do this by having pkt_reason 5823 * as CMD_CMPLT and pkt_scbp as STATUS_QFULL. 5824 */ 5825 mutex_enter(&ptgt->m_tgt_intr_mutex); 5826 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5827 mutex_exit(&ptgt->m_tgt_intr_mutex); 5828 } else { 5829 mutex_enter(&ptgt->m_tgt_intr_mutex); 5830 if (ptgt->m_reset_delay == 0) { 5831 ptgt->m_t_throttle = 5832 max((ptgt->m_t_ncmds - 2), 0); 5833 } 5834 mutex_exit(&ptgt->m_tgt_intr_mutex); 5835 5836 cmd->cmd_pkt_flags |= FLAG_HEAD; 5837 cmd->cmd_flags &= ~(CFLAG_TRANFLAG); 5838 cmd->cmd_flags |= CFLAG_RETRY; 5839 5840 mutex_exit(&mpt->m_mutex); 5841 (void) mptsas_accept_pkt(mpt, cmd); 5842 mutex_enter(&mpt->m_mutex); 5843 5844 /* 5845 * when target gives queue full status with no commands 5846 * outstanding (m_t_ncmds == 0), throttle is set to 0 5847 * (HOLD_THROTTLE), and the queue full handling start 5848 * (see psarc/1994/313); if there are commands outstanding, 5849 * throttle is set to (m_t_ncmds - 2) 5850 */ 5851 mutex_enter(&ptgt->m_tgt_intr_mutex); 5852 if (ptgt->m_t_throttle == HOLD_THROTTLE) { 5853 /* 5854 * By setting throttle to QFULL_THROTTLE, we 5855 * avoid submitting new commands and in 5856 * mptsas_restart_cmd find out slots which need 5857 * their throttles to be cleared. 5858 */ 5859 mptsas_set_throttle(mpt, ptgt, QFULL_THROTTLE); 5860 if (mpt->m_restart_cmd_timeid == 0) { 5861 mpt->m_restart_cmd_timeid = 5862 timeout(mptsas_restart_cmd, mpt, 5863 ptgt->m_qfull_retry_interval); 5864 } 5865 } 5866 mutex_exit(&ptgt->m_tgt_intr_mutex); 5867 } 5868 } 5869 5870 mptsas_phymask_t 5871 mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport) 5872 { 5873 mptsas_phymask_t phy_mask = 0; 5874 uint8_t i = 0; 5875 5876 NDBG20(("mptsas%d physport_to_phymask enter", mpt->m_instance)); 5877 5878 ASSERT(mutex_owned(&mpt->m_mutex)); 5879 5880 /* 5881 * If physport is 0xFF, this is a RAID volume. Use phymask of 0. 5882 */ 5883 if (physport == 0xFF) { 5884 return (0); 5885 } 5886 5887 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 5888 if (mpt->m_phy_info[i].attached_devhdl && 5889 (mpt->m_phy_info[i].phy_mask != 0) && 5890 (mpt->m_phy_info[i].port_num == physport)) { 5891 phy_mask = mpt->m_phy_info[i].phy_mask; 5892 break; 5893 } 5894 } 5895 NDBG20(("mptsas%d physport_to_phymask:physport :%x phymask :%x, ", 5896 mpt->m_instance, physport, phy_mask)); 5897 return (phy_mask); 5898 } 5899 5900 /* 5901 * mpt free device handle after device gone, by use of passthrough 5902 */ 5903 static int 5904 mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl) 5905 { 5906 Mpi2SasIoUnitControlRequest_t req; 5907 Mpi2SasIoUnitControlReply_t rep; 5908 int ret; 5909 5910 ASSERT(mutex_owned(&mpt->m_mutex)); 5911 5912 /* 5913 * Need to compose a SAS IO Unit Control request message 5914 * and call mptsas_do_passthru() function 5915 */ 5916 bzero(&req, sizeof (req)); 5917 bzero(&rep, sizeof (rep)); 5918 5919 req.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 5920 req.Operation = MPI2_SAS_OP_REMOVE_DEVICE; 5921 req.DevHandle = LE_16(devhdl); 5922 5923 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL, 5924 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL); 5925 if (ret != 0) { 5926 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit " 5927 "Control error %d", ret); 5928 return (DDI_FAILURE); 5929 } 5930 5931 /* do passthrough success, check the ioc status */ 5932 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 5933 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit " 5934 "Control IOCStatus %d", LE_16(rep.IOCStatus)); 5935 return (DDI_FAILURE); 5936 } 5937 5938 return (DDI_SUCCESS); 5939 } 5940 5941 static void 5942 mptsas_update_phymask(mptsas_t *mpt) 5943 { 5944 mptsas_phymask_t mask = 0, phy_mask; 5945 char *phy_mask_name; 5946 uint8_t current_port; 5947 int i, j; 5948 5949 NDBG20(("mptsas%d update phymask ", mpt->m_instance)); 5950 5951 ASSERT(mutex_owned(&mpt->m_mutex)); 5952 5953 (void) mptsas_get_sas_io_unit_page(mpt); 5954 5955 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 5956 5957 for (i = 0; i < mpt->m_num_phys; i++) { 5958 phy_mask = 0x00; 5959 5960 if (mpt->m_phy_info[i].attached_devhdl == 0) 5961 continue; 5962 5963 bzero(phy_mask_name, sizeof (phy_mask_name)); 5964 5965 current_port = mpt->m_phy_info[i].port_num; 5966 5967 if ((mask & (1 << i)) != 0) 5968 continue; 5969 5970 for (j = 0; j < mpt->m_num_phys; j++) { 5971 if (mpt->m_phy_info[j].attached_devhdl && 5972 (mpt->m_phy_info[j].port_num == current_port)) { 5973 phy_mask |= (1 << j); 5974 } 5975 } 5976 mask = mask | phy_mask; 5977 5978 for (j = 0; j < mpt->m_num_phys; j++) { 5979 if ((phy_mask >> j) & 0x01) { 5980 mpt->m_phy_info[j].phy_mask = phy_mask; 5981 } 5982 } 5983 5984 (void) sprintf(phy_mask_name, "%x", phy_mask); 5985 5986 mutex_exit(&mpt->m_mutex); 5987 /* 5988 * register a iport, if the port has already been existed 5989 * SCSA will do nothing and just return. 5990 */ 5991 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name); 5992 mutex_enter(&mpt->m_mutex); 5993 } 5994 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 5995 NDBG20(("mptsas%d update phymask return", mpt->m_instance)); 5996 } 5997 5998 /* 5999 * mptsas_handle_dr is a task handler for DR, the DR action includes: 6000 * 1. Directly attched Device Added/Removed. 6001 * 2. Expander Device Added/Removed. 6002 * 3. Indirectly Attached Device Added/Expander. 6003 * 4. LUNs of a existing device status change. 6004 * 5. RAID volume created/deleted. 6005 * 6. Member of RAID volume is released because of RAID deletion. 6006 * 7. Physical disks are removed because of RAID creation. 6007 */ 6008 static void 6009 mptsas_handle_dr(void *args) { 6010 mptsas_topo_change_list_t *topo_node = NULL; 6011 mptsas_topo_change_list_t *save_node = NULL; 6012 mptsas_t *mpt; 6013 dev_info_t *parent = NULL; 6014 mptsas_phymask_t phymask = 0; 6015 char *phy_mask_name; 6016 uint8_t flags = 0, physport = 0xff; 6017 uint8_t port_update = 0; 6018 uint_t event; 6019 6020 topo_node = (mptsas_topo_change_list_t *)args; 6021 6022 mpt = topo_node->mpt; 6023 event = topo_node->event; 6024 flags = topo_node->flags; 6025 6026 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 6027 6028 NDBG20(("mptsas%d handle_dr enter", mpt->m_instance)); 6029 6030 switch (event) { 6031 case MPTSAS_DR_EVENT_RECONFIG_TARGET: 6032 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 6033 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE) || 6034 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) { 6035 /* 6036 * Direct attached or expander attached device added 6037 * into system or a Phys Disk that is being unhidden. 6038 */ 6039 port_update = 1; 6040 } 6041 break; 6042 case MPTSAS_DR_EVENT_RECONFIG_SMP: 6043 /* 6044 * New expander added into system, it must be the head 6045 * of topo_change_list_t 6046 */ 6047 port_update = 1; 6048 break; 6049 default: 6050 port_update = 0; 6051 break; 6052 } 6053 /* 6054 * All cases port_update == 1 may cause initiator port form change 6055 */ 6056 mutex_enter(&mpt->m_mutex); 6057 if (mpt->m_port_chng && port_update) { 6058 /* 6059 * mpt->m_port_chng flag indicates some PHYs of initiator 6060 * port have changed to online. So when expander added or 6061 * directly attached device online event come, we force to 6062 * update port information by issueing SAS IO Unit Page and 6063 * update PHYMASKs. 6064 */ 6065 (void) mptsas_update_phymask(mpt); 6066 mpt->m_port_chng = 0; 6067 6068 } 6069 mutex_exit(&mpt->m_mutex); 6070 while (topo_node) { 6071 phymask = 0; 6072 if (parent == NULL) { 6073 physport = topo_node->un.physport; 6074 event = topo_node->event; 6075 flags = topo_node->flags; 6076 if (event & (MPTSAS_DR_EVENT_OFFLINE_TARGET | 6077 MPTSAS_DR_EVENT_OFFLINE_SMP)) { 6078 /* 6079 * For all offline events, phymask is known 6080 */ 6081 phymask = topo_node->un.phymask; 6082 goto find_parent; 6083 } 6084 if (event & MPTSAS_TOPO_FLAG_REMOVE_HANDLE) { 6085 goto handle_topo_change; 6086 } 6087 if (flags & MPTSAS_TOPO_FLAG_LUN_ASSOCIATED) { 6088 phymask = topo_node->un.phymask; 6089 goto find_parent; 6090 } 6091 6092 if ((flags == 6093 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) && 6094 (event == MPTSAS_DR_EVENT_RECONFIG_TARGET)) { 6095 /* 6096 * There is no any field in IR_CONFIG_CHANGE 6097 * event indicate physport/phynum, let's get 6098 * parent after SAS Device Page0 request. 6099 */ 6100 goto handle_topo_change; 6101 } 6102 6103 mutex_enter(&mpt->m_mutex); 6104 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 6105 /* 6106 * If the direct attached device added or a 6107 * phys disk is being unhidden, argument 6108 * physport actually is PHY#, so we have to get 6109 * phymask according PHY#. 6110 */ 6111 physport = mpt->m_phy_info[physport].port_num; 6112 } 6113 6114 /* 6115 * Translate physport to phymask so that we can search 6116 * parent dip. 6117 */ 6118 phymask = mptsas_physport_to_phymask(mpt, 6119 physport); 6120 mutex_exit(&mpt->m_mutex); 6121 6122 find_parent: 6123 bzero(phy_mask_name, MPTSAS_MAX_PHYS); 6124 /* 6125 * For RAID topology change node, write the iport name 6126 * as v0. 6127 */ 6128 if (flags & MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 6129 (void) sprintf(phy_mask_name, "v0"); 6130 } else { 6131 /* 6132 * phymask can bo 0 if the drive has been 6133 * pulled by the time an add event is 6134 * processed. If phymask is 0, just skip this 6135 * event and continue. 6136 */ 6137 if (phymask == 0) { 6138 mutex_enter(&mpt->m_mutex); 6139 save_node = topo_node; 6140 topo_node = topo_node->next; 6141 ASSERT(save_node); 6142 kmem_free(save_node, 6143 sizeof (mptsas_topo_change_list_t)); 6144 mutex_exit(&mpt->m_mutex); 6145 6146 parent = NULL; 6147 continue; 6148 } 6149 (void) sprintf(phy_mask_name, "%x", phymask); 6150 } 6151 parent = scsi_hba_iport_find(mpt->m_dip, 6152 phy_mask_name); 6153 if (parent == NULL) { 6154 mptsas_log(mpt, CE_WARN, "Failed to find an " 6155 "iport, should not happen!"); 6156 goto out; 6157 } 6158 6159 } 6160 ASSERT(parent); 6161 handle_topo_change: 6162 6163 mutex_enter(&mpt->m_mutex); 6164 6165 mptsas_handle_topo_change(topo_node, parent); 6166 save_node = topo_node; 6167 topo_node = topo_node->next; 6168 ASSERT(save_node); 6169 kmem_free(save_node, sizeof (mptsas_topo_change_list_t)); 6170 mutex_exit(&mpt->m_mutex); 6171 6172 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 6173 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) || 6174 (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) { 6175 /* 6176 * If direct attached device associated, make sure 6177 * reset the parent before start the next one. But 6178 * all devices associated with expander shares the 6179 * parent. Also, reset parent if this is for RAID. 6180 */ 6181 parent = NULL; 6182 } 6183 } 6184 out: 6185 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 6186 } 6187 6188 static void 6189 mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node, 6190 dev_info_t *parent) 6191 { 6192 mptsas_target_t *ptgt = NULL; 6193 mptsas_smp_t *psmp = NULL; 6194 mptsas_t *mpt = (void *)topo_node->mpt; 6195 uint16_t devhdl; 6196 uint16_t attached_devhdl; 6197 uint64_t sas_wwn = 0; 6198 int rval = 0; 6199 uint32_t page_address; 6200 uint8_t phy, flags; 6201 char *addr = NULL; 6202 dev_info_t *lundip; 6203 int circ = 0, circ1 = 0; 6204 char attached_wwnstr[MPTSAS_WWN_STRLEN]; 6205 6206 NDBG20(("mptsas%d handle_topo_change enter", mpt->m_instance)); 6207 6208 ASSERT(mutex_owned(&mpt->m_mutex)); 6209 6210 switch (topo_node->event) { 6211 case MPTSAS_DR_EVENT_RECONFIG_TARGET: 6212 { 6213 char *phy_mask_name; 6214 mptsas_phymask_t phymask = 0; 6215 6216 if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 6217 /* 6218 * Get latest RAID info. 6219 */ 6220 (void) mptsas_get_raid_info(mpt); 6221 ptgt = mptsas_search_by_devhdl( 6222 &mpt->m_active->m_tgttbl, topo_node->devhdl); 6223 if (ptgt == NULL) 6224 break; 6225 } else { 6226 ptgt = (void *)topo_node->object; 6227 } 6228 6229 if (ptgt == NULL) { 6230 /* 6231 * If a Phys Disk was deleted, RAID info needs to be 6232 * updated to reflect the new topology. 6233 */ 6234 (void) mptsas_get_raid_info(mpt); 6235 6236 /* 6237 * Get sas device page 0 by DevHandle to make sure if 6238 * SSP/SATA end device exist. 6239 */ 6240 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 6241 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 6242 topo_node->devhdl; 6243 6244 rval = mptsas_get_target_device_info(mpt, page_address, 6245 &devhdl, &ptgt); 6246 if (rval == DEV_INFO_WRONG_DEVICE_TYPE) { 6247 mptsas_log(mpt, CE_NOTE, 6248 "mptsas_handle_topo_change: target %d is " 6249 "not a SAS/SATA device. \n", 6250 topo_node->devhdl); 6251 } else if (rval == DEV_INFO_FAIL_ALLOC) { 6252 mptsas_log(mpt, CE_NOTE, 6253 "mptsas_handle_topo_change: could not " 6254 "allocate memory. \n"); 6255 } 6256 /* 6257 * If rval is DEV_INFO_PHYS_DISK than there is nothing 6258 * else to do, just leave. 6259 */ 6260 if (rval != DEV_INFO_SUCCESS) { 6261 return; 6262 } 6263 } 6264 6265 ASSERT(ptgt->m_devhdl == topo_node->devhdl); 6266 6267 mutex_exit(&mpt->m_mutex); 6268 flags = topo_node->flags; 6269 6270 if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) { 6271 phymask = ptgt->m_phymask; 6272 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 6273 (void) sprintf(phy_mask_name, "%x", phymask); 6274 parent = scsi_hba_iport_find(mpt->m_dip, 6275 phy_mask_name); 6276 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 6277 if (parent == NULL) { 6278 mptsas_log(mpt, CE_WARN, "Failed to find a " 6279 "iport for PD, should not happen!"); 6280 mutex_enter(&mpt->m_mutex); 6281 break; 6282 } 6283 } 6284 6285 if (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 6286 ndi_devi_enter(parent, &circ1); 6287 (void) mptsas_config_raid(parent, topo_node->devhdl, 6288 &lundip); 6289 ndi_devi_exit(parent, circ1); 6290 } else { 6291 /* 6292 * hold nexus for bus configure 6293 */ 6294 ndi_devi_enter(scsi_vhci_dip, &circ); 6295 ndi_devi_enter(parent, &circ1); 6296 rval = mptsas_config_target(parent, ptgt); 6297 /* 6298 * release nexus for bus configure 6299 */ 6300 ndi_devi_exit(parent, circ1); 6301 ndi_devi_exit(scsi_vhci_dip, circ); 6302 6303 /* 6304 * Add parent's props for SMHBA support 6305 */ 6306 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 6307 bzero(attached_wwnstr, 6308 sizeof (attached_wwnstr)); 6309 (void) sprintf(attached_wwnstr, "w%016"PRIx64, 6310 ptgt->m_sas_wwn); 6311 if (ddi_prop_update_string(DDI_DEV_T_NONE, 6312 parent, 6313 SCSI_ADDR_PROP_ATTACHED_PORT, 6314 attached_wwnstr) 6315 != DDI_PROP_SUCCESS) { 6316 (void) ddi_prop_remove(DDI_DEV_T_NONE, 6317 parent, 6318 SCSI_ADDR_PROP_ATTACHED_PORT); 6319 mptsas_log(mpt, CE_WARN, "Failed to" 6320 "attached-port props"); 6321 return; 6322 } 6323 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6324 MPTSAS_NUM_PHYS, 1) != 6325 DDI_PROP_SUCCESS) { 6326 (void) ddi_prop_remove(DDI_DEV_T_NONE, 6327 parent, MPTSAS_NUM_PHYS); 6328 mptsas_log(mpt, CE_WARN, "Failed to" 6329 " create num-phys props"); 6330 return; 6331 } 6332 6333 /* 6334 * Update PHY info for smhba 6335 */ 6336 mutex_enter(&mpt->m_mutex); 6337 if (mptsas_smhba_phy_init(mpt)) { 6338 mutex_exit(&mpt->m_mutex); 6339 mptsas_log(mpt, CE_WARN, "mptsas phy" 6340 " update failed"); 6341 return; 6342 } 6343 mutex_exit(&mpt->m_mutex); 6344 mptsas_smhba_set_phy_props(mpt, 6345 ddi_get_name_addr(parent), parent, 6346 1, &attached_devhdl); 6347 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6348 MPTSAS_VIRTUAL_PORT, 0) != 6349 DDI_PROP_SUCCESS) { 6350 (void) ddi_prop_remove(DDI_DEV_T_NONE, 6351 parent, MPTSAS_VIRTUAL_PORT); 6352 mptsas_log(mpt, CE_WARN, 6353 "mptsas virtual-port" 6354 "port prop update failed"); 6355 return; 6356 } 6357 } 6358 } 6359 mutex_enter(&mpt->m_mutex); 6360 6361 NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, " 6362 "phymask:%x.", mpt->m_instance, ptgt->m_devhdl, 6363 ptgt->m_phymask)); 6364 break; 6365 } 6366 case MPTSAS_DR_EVENT_OFFLINE_TARGET: 6367 { 6368 mptsas_hash_table_t *tgttbl = &mpt->m_active->m_tgttbl; 6369 devhdl = topo_node->devhdl; 6370 ptgt = mptsas_search_by_devhdl(tgttbl, devhdl); 6371 if (ptgt == NULL) 6372 break; 6373 6374 sas_wwn = ptgt->m_sas_wwn; 6375 phy = ptgt->m_phynum; 6376 6377 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 6378 6379 if (sas_wwn) { 6380 (void) sprintf(addr, "w%016"PRIx64, sas_wwn); 6381 } else { 6382 (void) sprintf(addr, "p%x", phy); 6383 } 6384 ASSERT(ptgt->m_devhdl == devhdl); 6385 6386 if ((topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) || 6387 (topo_node->flags == 6388 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) { 6389 /* 6390 * Get latest RAID info if RAID volume status changes 6391 * or Phys Disk status changes 6392 */ 6393 (void) mptsas_get_raid_info(mpt); 6394 } 6395 /* 6396 * Abort all outstanding command on the device 6397 */ 6398 rval = mptsas_do_scsi_reset(mpt, devhdl); 6399 if (rval) { 6400 NDBG20(("mptsas%d handle_topo_change to reset target " 6401 "before offline devhdl:%x, phymask:%x, rval:%x", 6402 mpt->m_instance, ptgt->m_devhdl, ptgt->m_phymask, 6403 rval)); 6404 } 6405 6406 mutex_exit(&mpt->m_mutex); 6407 6408 ndi_devi_enter(scsi_vhci_dip, &circ); 6409 ndi_devi_enter(parent, &circ1); 6410 rval = mptsas_offline_target(parent, addr); 6411 ndi_devi_exit(parent, circ1); 6412 ndi_devi_exit(scsi_vhci_dip, circ); 6413 NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, " 6414 "phymask:%x, rval:%x", mpt->m_instance, 6415 ptgt->m_devhdl, ptgt->m_phymask, rval)); 6416 6417 kmem_free(addr, SCSI_MAXNAMELEN); 6418 6419 /* 6420 * Clear parent's props for SMHBA support 6421 */ 6422 flags = topo_node->flags; 6423 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 6424 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6425 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent, 6426 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 6427 DDI_PROP_SUCCESS) { 6428 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6429 SCSI_ADDR_PROP_ATTACHED_PORT); 6430 mptsas_log(mpt, CE_WARN, "mptsas attached port " 6431 "prop update failed"); 6432 break; 6433 } 6434 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6435 MPTSAS_NUM_PHYS, 0) != 6436 DDI_PROP_SUCCESS) { 6437 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6438 MPTSAS_NUM_PHYS); 6439 mptsas_log(mpt, CE_WARN, "mptsas num phys " 6440 "prop update failed"); 6441 break; 6442 } 6443 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6444 MPTSAS_VIRTUAL_PORT, 1) != 6445 DDI_PROP_SUCCESS) { 6446 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6447 MPTSAS_VIRTUAL_PORT); 6448 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 6449 "prop update failed"); 6450 break; 6451 } 6452 } 6453 6454 mutex_enter(&mpt->m_mutex); 6455 ptgt->m_led_status = 0; 6456 if (mptsas_flush_led_status(mpt, ptgt) != DDI_SUCCESS) { 6457 NDBG14(("mptsas: clear LED for tgt %x failed", 6458 ptgt->m_slot_num)); 6459 } 6460 if (rval == DDI_SUCCESS) { 6461 mptsas_tgt_free(&mpt->m_active->m_tgttbl, 6462 ptgt->m_sas_wwn, ptgt->m_phymask); 6463 ptgt = NULL; 6464 } else { 6465 /* 6466 * clean DR_INTRANSITION flag to allow I/O down to 6467 * PHCI driver since failover finished. 6468 * Invalidate the devhdl 6469 */ 6470 mutex_enter(&ptgt->m_tgt_intr_mutex); 6471 ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL; 6472 ptgt->m_tgt_unconfigured = 0; 6473 ptgt->m_dr_flag = MPTSAS_DR_INACTIVE; 6474 mutex_exit(&ptgt->m_tgt_intr_mutex); 6475 } 6476 6477 /* 6478 * Send SAS IO Unit Control to free the dev handle 6479 */ 6480 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 6481 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE)) { 6482 rval = mptsas_free_devhdl(mpt, devhdl); 6483 6484 NDBG20(("mptsas%d handle_topo_change to remove " 6485 "devhdl:%x, rval:%x", mpt->m_instance, devhdl, 6486 rval)); 6487 } 6488 6489 break; 6490 } 6491 case MPTSAS_TOPO_FLAG_REMOVE_HANDLE: 6492 { 6493 devhdl = topo_node->devhdl; 6494 /* 6495 * If this is the remove handle event, do a reset first. 6496 */ 6497 if (topo_node->event == MPTSAS_TOPO_FLAG_REMOVE_HANDLE) { 6498 rval = mptsas_do_scsi_reset(mpt, devhdl); 6499 if (rval) { 6500 NDBG20(("mpt%d reset target before remove " 6501 "devhdl:%x, rval:%x", mpt->m_instance, 6502 devhdl, rval)); 6503 } 6504 } 6505 6506 /* 6507 * Send SAS IO Unit Control to free the dev handle 6508 */ 6509 rval = mptsas_free_devhdl(mpt, devhdl); 6510 NDBG20(("mptsas%d handle_topo_change to remove " 6511 "devhdl:%x, rval:%x", mpt->m_instance, devhdl, 6512 rval)); 6513 break; 6514 } 6515 case MPTSAS_DR_EVENT_RECONFIG_SMP: 6516 { 6517 mptsas_smp_t smp; 6518 dev_info_t *smpdip; 6519 mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl; 6520 6521 devhdl = topo_node->devhdl; 6522 6523 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL & 6524 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl; 6525 rval = mptsas_get_sas_expander_page0(mpt, page_address, &smp); 6526 if (rval != DDI_SUCCESS) { 6527 mptsas_log(mpt, CE_WARN, "failed to online smp, " 6528 "handle %x", devhdl); 6529 return; 6530 } 6531 6532 psmp = mptsas_smp_alloc(smptbl, &smp); 6533 if (psmp == NULL) { 6534 return; 6535 } 6536 6537 mutex_exit(&mpt->m_mutex); 6538 ndi_devi_enter(parent, &circ1); 6539 (void) mptsas_online_smp(parent, psmp, &smpdip); 6540 ndi_devi_exit(parent, circ1); 6541 6542 mutex_enter(&mpt->m_mutex); 6543 break; 6544 } 6545 case MPTSAS_DR_EVENT_OFFLINE_SMP: 6546 { 6547 mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl; 6548 devhdl = topo_node->devhdl; 6549 uint32_t dev_info; 6550 6551 psmp = mptsas_search_by_devhdl(smptbl, devhdl); 6552 if (psmp == NULL) 6553 break; 6554 /* 6555 * The mptsas_smp_t data is released only if the dip is offlined 6556 * successfully. 6557 */ 6558 mutex_exit(&mpt->m_mutex); 6559 6560 ndi_devi_enter(parent, &circ1); 6561 rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE); 6562 ndi_devi_exit(parent, circ1); 6563 6564 dev_info = psmp->m_deviceinfo; 6565 if ((dev_info & DEVINFO_DIRECT_ATTACHED) == 6566 DEVINFO_DIRECT_ATTACHED) { 6567 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6568 MPTSAS_VIRTUAL_PORT, 1) != 6569 DDI_PROP_SUCCESS) { 6570 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6571 MPTSAS_VIRTUAL_PORT); 6572 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 6573 "prop update failed"); 6574 return; 6575 } 6576 /* 6577 * Check whether the smp connected to the iport, 6578 */ 6579 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6580 MPTSAS_NUM_PHYS, 0) != 6581 DDI_PROP_SUCCESS) { 6582 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6583 MPTSAS_NUM_PHYS); 6584 mptsas_log(mpt, CE_WARN, "mptsas num phys" 6585 "prop update failed"); 6586 return; 6587 } 6588 /* 6589 * Clear parent's attached-port props 6590 */ 6591 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6592 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent, 6593 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 6594 DDI_PROP_SUCCESS) { 6595 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6596 SCSI_ADDR_PROP_ATTACHED_PORT); 6597 mptsas_log(mpt, CE_WARN, "mptsas attached port " 6598 "prop update failed"); 6599 return; 6600 } 6601 } 6602 6603 mutex_enter(&mpt->m_mutex); 6604 NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, " 6605 "rval:%x", mpt->m_instance, psmp->m_devhdl, rval)); 6606 if (rval == DDI_SUCCESS) { 6607 mptsas_smp_free(smptbl, psmp->m_sasaddr, 6608 psmp->m_phymask); 6609 } else { 6610 psmp->m_devhdl = MPTSAS_INVALID_DEVHDL; 6611 } 6612 6613 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6614 6615 break; 6616 } 6617 default: 6618 return; 6619 } 6620 } 6621 6622 /* 6623 * Record the event if its type is enabled in mpt instance by ioctl. 6624 */ 6625 static void 6626 mptsas_record_event(void *args) 6627 { 6628 m_replyh_arg_t *replyh_arg; 6629 pMpi2EventNotificationReply_t eventreply; 6630 uint32_t event, rfm; 6631 mptsas_t *mpt; 6632 int i, j; 6633 uint16_t event_data_len; 6634 boolean_t sendAEN = FALSE; 6635 6636 replyh_arg = (m_replyh_arg_t *)args; 6637 rfm = replyh_arg->rfm; 6638 mpt = replyh_arg->mpt; 6639 6640 eventreply = (pMpi2EventNotificationReply_t) 6641 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr)); 6642 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 6643 6644 6645 /* 6646 * Generate a system event to let anyone who cares know that a 6647 * LOG_ENTRY_ADDED event has occurred. This is sent no matter what the 6648 * event mask is set to. 6649 */ 6650 if (event == MPI2_EVENT_LOG_ENTRY_ADDED) { 6651 sendAEN = TRUE; 6652 } 6653 6654 /* 6655 * Record the event only if it is not masked. Determine which dword 6656 * and bit of event mask to test. 6657 */ 6658 i = (uint8_t)(event / 32); 6659 j = (uint8_t)(event % 32); 6660 if ((i < 4) && ((1 << j) & mpt->m_event_mask[i])) { 6661 i = mpt->m_event_index; 6662 mpt->m_events[i].Type = event; 6663 mpt->m_events[i].Number = ++mpt->m_event_number; 6664 bzero(mpt->m_events[i].Data, MPTSAS_MAX_EVENT_DATA_LENGTH * 4); 6665 event_data_len = ddi_get16(mpt->m_acc_reply_frame_hdl, 6666 &eventreply->EventDataLength); 6667 6668 if (event_data_len > 0) { 6669 /* 6670 * Limit data to size in m_event entry 6671 */ 6672 if (event_data_len > MPTSAS_MAX_EVENT_DATA_LENGTH) { 6673 event_data_len = MPTSAS_MAX_EVENT_DATA_LENGTH; 6674 } 6675 for (j = 0; j < event_data_len; j++) { 6676 mpt->m_events[i].Data[j] = 6677 ddi_get32(mpt->m_acc_reply_frame_hdl, 6678 &(eventreply->EventData[j])); 6679 } 6680 6681 /* 6682 * check for index wrap-around 6683 */ 6684 if (++i == MPTSAS_EVENT_QUEUE_SIZE) { 6685 i = 0; 6686 } 6687 mpt->m_event_index = (uint8_t)i; 6688 6689 /* 6690 * Set flag to send the event. 6691 */ 6692 sendAEN = TRUE; 6693 } 6694 } 6695 6696 /* 6697 * Generate a system event if flag is set to let anyone who cares know 6698 * that an event has occurred. 6699 */ 6700 if (sendAEN) { 6701 (void) ddi_log_sysevent(mpt->m_dip, DDI_VENDOR_LSI, "MPT_SAS", 6702 "SAS", NULL, NULL, DDI_NOSLEEP); 6703 } 6704 } 6705 6706 #define SMP_RESET_IN_PROGRESS MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS 6707 /* 6708 * handle sync events from ioc in interrupt 6709 * return value: 6710 * DDI_SUCCESS: The event is handled by this func 6711 * DDI_FAILURE: Event is not handled 6712 */ 6713 static int 6714 mptsas_handle_event_sync(void *args) 6715 { 6716 m_replyh_arg_t *replyh_arg; 6717 pMpi2EventNotificationReply_t eventreply; 6718 uint32_t event, rfm; 6719 mptsas_t *mpt; 6720 uint_t iocstatus; 6721 6722 replyh_arg = (m_replyh_arg_t *)args; 6723 rfm = replyh_arg->rfm; 6724 mpt = replyh_arg->mpt; 6725 6726 ASSERT(mutex_owned(&mpt->m_mutex)); 6727 6728 eventreply = (pMpi2EventNotificationReply_t) 6729 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr)); 6730 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 6731 6732 if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 6733 &eventreply->IOCStatus)) { 6734 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 6735 mptsas_log(mpt, CE_WARN, 6736 "!mptsas_handle_event_sync: IOCStatus=0x%x, " 6737 "IOCLogInfo=0x%x", iocstatus, 6738 ddi_get32(mpt->m_acc_reply_frame_hdl, 6739 &eventreply->IOCLogInfo)); 6740 } else { 6741 mptsas_log(mpt, CE_WARN, 6742 "mptsas_handle_event_sync: IOCStatus=0x%x, " 6743 "IOCLogInfo=0x%x", iocstatus, 6744 ddi_get32(mpt->m_acc_reply_frame_hdl, 6745 &eventreply->IOCLogInfo)); 6746 } 6747 } 6748 6749 /* 6750 * figure out what kind of event we got and handle accordingly 6751 */ 6752 switch (event) { 6753 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 6754 { 6755 pMpi2EventDataSasTopologyChangeList_t sas_topo_change_list; 6756 uint8_t num_entries, expstatus, phy; 6757 uint8_t phystatus, physport, state, i; 6758 uint8_t start_phy_num, link_rate; 6759 uint16_t dev_handle, reason_code; 6760 uint16_t enc_handle, expd_handle; 6761 char string[80], curr[80], prev[80]; 6762 mptsas_topo_change_list_t *topo_head = NULL; 6763 mptsas_topo_change_list_t *topo_tail = NULL; 6764 mptsas_topo_change_list_t *topo_node = NULL; 6765 mptsas_target_t *ptgt; 6766 mptsas_smp_t *psmp; 6767 mptsas_hash_table_t *tgttbl, *smptbl; 6768 uint8_t flags = 0, exp_flag; 6769 smhba_info_t *pSmhba = NULL; 6770 6771 NDBG20(("mptsas_handle_event_sync: SAS topology change")); 6772 6773 tgttbl = &mpt->m_active->m_tgttbl; 6774 smptbl = &mpt->m_active->m_smptbl; 6775 6776 sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t) 6777 eventreply->EventData; 6778 6779 enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6780 &sas_topo_change_list->EnclosureHandle); 6781 expd_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6782 &sas_topo_change_list->ExpanderDevHandle); 6783 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl, 6784 &sas_topo_change_list->NumEntries); 6785 start_phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl, 6786 &sas_topo_change_list->StartPhyNum); 6787 expstatus = ddi_get8(mpt->m_acc_reply_frame_hdl, 6788 &sas_topo_change_list->ExpStatus); 6789 physport = ddi_get8(mpt->m_acc_reply_frame_hdl, 6790 &sas_topo_change_list->PhysicalPort); 6791 6792 string[0] = 0; 6793 if (expd_handle) { 6794 flags = MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED; 6795 switch (expstatus) { 6796 case MPI2_EVENT_SAS_TOPO_ES_ADDED: 6797 (void) sprintf(string, " added"); 6798 /* 6799 * New expander device added 6800 */ 6801 mpt->m_port_chng = 1; 6802 topo_node = kmem_zalloc( 6803 sizeof (mptsas_topo_change_list_t), 6804 KM_SLEEP); 6805 topo_node->mpt = mpt; 6806 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_SMP; 6807 topo_node->un.physport = physport; 6808 topo_node->devhdl = expd_handle; 6809 topo_node->flags = flags; 6810 topo_node->object = NULL; 6811 if (topo_head == NULL) { 6812 topo_head = topo_tail = topo_node; 6813 } else { 6814 topo_tail->next = topo_node; 6815 topo_tail = topo_node; 6816 } 6817 break; 6818 case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING: 6819 (void) sprintf(string, " not responding, " 6820 "removed"); 6821 psmp = mptsas_search_by_devhdl(smptbl, 6822 expd_handle); 6823 if (psmp == NULL) 6824 break; 6825 6826 topo_node = kmem_zalloc( 6827 sizeof (mptsas_topo_change_list_t), 6828 KM_SLEEP); 6829 topo_node->mpt = mpt; 6830 topo_node->un.phymask = psmp->m_phymask; 6831 topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP; 6832 topo_node->devhdl = expd_handle; 6833 topo_node->flags = flags; 6834 topo_node->object = NULL; 6835 if (topo_head == NULL) { 6836 topo_head = topo_tail = topo_node; 6837 } else { 6838 topo_tail->next = topo_node; 6839 topo_tail = topo_node; 6840 } 6841 break; 6842 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING: 6843 break; 6844 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING: 6845 (void) sprintf(string, " not responding, " 6846 "delaying removal"); 6847 break; 6848 default: 6849 break; 6850 } 6851 } else { 6852 flags = MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE; 6853 } 6854 6855 NDBG20(("SAS TOPOLOGY CHANGE for enclosure %x expander %x%s\n", 6856 enc_handle, expd_handle, string)); 6857 for (i = 0; i < num_entries; i++) { 6858 phy = i + start_phy_num; 6859 phystatus = ddi_get8(mpt->m_acc_reply_frame_hdl, 6860 &sas_topo_change_list->PHY[i].PhyStatus); 6861 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6862 &sas_topo_change_list->PHY[i].AttachedDevHandle); 6863 reason_code = phystatus & MPI2_EVENT_SAS_TOPO_RC_MASK; 6864 /* 6865 * Filter out processing of Phy Vacant Status unless 6866 * the reason code is "Not Responding". Process all 6867 * other combinations of Phy Status and Reason Codes. 6868 */ 6869 if ((phystatus & 6870 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) && 6871 (reason_code != 6872 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) { 6873 continue; 6874 } 6875 curr[0] = 0; 6876 prev[0] = 0; 6877 string[0] = 0; 6878 switch (reason_code) { 6879 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 6880 { 6881 NDBG20(("mptsas%d phy %d physical_port %d " 6882 "dev_handle %d added", mpt->m_instance, phy, 6883 physport, dev_handle)); 6884 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl, 6885 &sas_topo_change_list->PHY[i].LinkRate); 6886 state = (link_rate & 6887 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >> 6888 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT; 6889 switch (state) { 6890 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 6891 (void) sprintf(curr, "is disabled"); 6892 break; 6893 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 6894 (void) sprintf(curr, "is offline, " 6895 "failed speed negotiation"); 6896 break; 6897 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 6898 (void) sprintf(curr, "SATA OOB " 6899 "complete"); 6900 break; 6901 case SMP_RESET_IN_PROGRESS: 6902 (void) sprintf(curr, "SMP reset in " 6903 "progress"); 6904 break; 6905 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 6906 (void) sprintf(curr, "is online at " 6907 "1.5 Gbps"); 6908 break; 6909 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 6910 (void) sprintf(curr, "is online at 3.0 " 6911 "Gbps"); 6912 break; 6913 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 6914 (void) sprintf(curr, "is online at 6.0 " 6915 "Gbps"); 6916 break; 6917 default: 6918 (void) sprintf(curr, "state is " 6919 "unknown"); 6920 break; 6921 } 6922 /* 6923 * New target device added into the system. 6924 * Set association flag according to if an 6925 * expander is used or not. 6926 */ 6927 exp_flag = 6928 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE; 6929 if (flags == 6930 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) { 6931 flags = exp_flag; 6932 } 6933 topo_node = kmem_zalloc( 6934 sizeof (mptsas_topo_change_list_t), 6935 KM_SLEEP); 6936 topo_node->mpt = mpt; 6937 topo_node->event = 6938 MPTSAS_DR_EVENT_RECONFIG_TARGET; 6939 if (expd_handle == 0) { 6940 /* 6941 * Per MPI 2, if expander dev handle 6942 * is 0, it's a directly attached 6943 * device. So driver use PHY to decide 6944 * which iport is associated 6945 */ 6946 physport = phy; 6947 mpt->m_port_chng = 1; 6948 } 6949 topo_node->un.physport = physport; 6950 topo_node->devhdl = dev_handle; 6951 topo_node->flags = flags; 6952 topo_node->object = NULL; 6953 if (topo_head == NULL) { 6954 topo_head = topo_tail = topo_node; 6955 } else { 6956 topo_tail->next = topo_node; 6957 topo_tail = topo_node; 6958 } 6959 break; 6960 } 6961 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 6962 { 6963 NDBG20(("mptsas%d phy %d physical_port %d " 6964 "dev_handle %d removed", mpt->m_instance, 6965 phy, physport, dev_handle)); 6966 /* 6967 * Set association flag according to if an 6968 * expander is used or not. 6969 */ 6970 exp_flag = 6971 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE; 6972 if (flags == 6973 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) { 6974 flags = exp_flag; 6975 } 6976 /* 6977 * Target device is removed from the system 6978 * Before the device is really offline from 6979 * from system. 6980 */ 6981 ptgt = mptsas_search_by_devhdl(tgttbl, 6982 dev_handle); 6983 /* 6984 * If ptgt is NULL here, it means that the 6985 * DevHandle is not in the hash table. This is 6986 * reasonable sometimes. For example, if a 6987 * disk was pulled, then added, then pulled 6988 * again, the disk will not have been put into 6989 * the hash table because the add event will 6990 * have an invalid phymask. BUT, this does not 6991 * mean that the DevHandle is invalid. The 6992 * controller will still have a valid DevHandle 6993 * that must be removed. To do this, use the 6994 * MPTSAS_TOPO_FLAG_REMOVE_HANDLE event. 6995 */ 6996 if (ptgt == NULL) { 6997 topo_node = kmem_zalloc( 6998 sizeof (mptsas_topo_change_list_t), 6999 KM_SLEEP); 7000 topo_node->mpt = mpt; 7001 topo_node->un.phymask = 0; 7002 topo_node->event = 7003 MPTSAS_TOPO_FLAG_REMOVE_HANDLE; 7004 topo_node->devhdl = dev_handle; 7005 topo_node->flags = flags; 7006 topo_node->object = NULL; 7007 if (topo_head == NULL) { 7008 topo_head = topo_tail = 7009 topo_node; 7010 } else { 7011 topo_tail->next = topo_node; 7012 topo_tail = topo_node; 7013 } 7014 break; 7015 } 7016 7017 /* 7018 * Update DR flag immediately avoid I/O failure 7019 * before failover finish. Pay attention to the 7020 * mutex protect, we need grab the per target 7021 * mutex during set m_dr_flag because the 7022 * m_mutex would not be held all the time in 7023 * mptsas_scsi_start(). 7024 */ 7025 mutex_enter(&ptgt->m_tgt_intr_mutex); 7026 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 7027 mutex_exit(&ptgt->m_tgt_intr_mutex); 7028 7029 topo_node = kmem_zalloc( 7030 sizeof (mptsas_topo_change_list_t), 7031 KM_SLEEP); 7032 topo_node->mpt = mpt; 7033 topo_node->un.phymask = ptgt->m_phymask; 7034 topo_node->event = 7035 MPTSAS_DR_EVENT_OFFLINE_TARGET; 7036 topo_node->devhdl = dev_handle; 7037 topo_node->flags = flags; 7038 topo_node->object = NULL; 7039 if (topo_head == NULL) { 7040 topo_head = topo_tail = topo_node; 7041 } else { 7042 topo_tail->next = topo_node; 7043 topo_tail = topo_node; 7044 } 7045 break; 7046 } 7047 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 7048 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl, 7049 &sas_topo_change_list->PHY[i].LinkRate); 7050 state = (link_rate & 7051 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >> 7052 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT; 7053 pSmhba = &mpt->m_phy_info[i].smhba_info; 7054 pSmhba->negotiated_link_rate = state; 7055 switch (state) { 7056 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 7057 (void) sprintf(curr, "is disabled"); 7058 mptsas_smhba_log_sysevent(mpt, 7059 ESC_SAS_PHY_EVENT, 7060 SAS_PHY_REMOVE, 7061 &mpt->m_phy_info[i].smhba_info); 7062 mpt->m_phy_info[i].smhba_info. 7063 negotiated_link_rate 7064 = 0x1; 7065 break; 7066 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 7067 (void) sprintf(curr, "is offline, " 7068 "failed speed negotiation"); 7069 mptsas_smhba_log_sysevent(mpt, 7070 ESC_SAS_PHY_EVENT, 7071 SAS_PHY_OFFLINE, 7072 &mpt->m_phy_info[i].smhba_info); 7073 break; 7074 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 7075 (void) sprintf(curr, "SATA OOB " 7076 "complete"); 7077 break; 7078 case SMP_RESET_IN_PROGRESS: 7079 (void) sprintf(curr, "SMP reset in " 7080 "progress"); 7081 break; 7082 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 7083 (void) sprintf(curr, "is online at " 7084 "1.5 Gbps"); 7085 if ((expd_handle == 0) && 7086 (enc_handle == 1)) { 7087 mpt->m_port_chng = 1; 7088 } 7089 mptsas_smhba_log_sysevent(mpt, 7090 ESC_SAS_PHY_EVENT, 7091 SAS_PHY_ONLINE, 7092 &mpt->m_phy_info[i].smhba_info); 7093 break; 7094 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 7095 (void) sprintf(curr, "is online at 3.0 " 7096 "Gbps"); 7097 if ((expd_handle == 0) && 7098 (enc_handle == 1)) { 7099 mpt->m_port_chng = 1; 7100 } 7101 mptsas_smhba_log_sysevent(mpt, 7102 ESC_SAS_PHY_EVENT, 7103 SAS_PHY_ONLINE, 7104 &mpt->m_phy_info[i].smhba_info); 7105 break; 7106 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 7107 (void) sprintf(curr, "is online at " 7108 "6.0 Gbps"); 7109 if ((expd_handle == 0) && 7110 (enc_handle == 1)) { 7111 mpt->m_port_chng = 1; 7112 } 7113 mptsas_smhba_log_sysevent(mpt, 7114 ESC_SAS_PHY_EVENT, 7115 SAS_PHY_ONLINE, 7116 &mpt->m_phy_info[i].smhba_info); 7117 break; 7118 default: 7119 (void) sprintf(curr, "state is " 7120 "unknown"); 7121 break; 7122 } 7123 7124 state = (link_rate & 7125 MPI2_EVENT_SAS_TOPO_LR_PREV_MASK) >> 7126 MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT; 7127 switch (state) { 7128 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 7129 (void) sprintf(prev, ", was disabled"); 7130 break; 7131 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 7132 (void) sprintf(prev, ", was offline, " 7133 "failed speed negotiation"); 7134 break; 7135 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 7136 (void) sprintf(prev, ", was SATA OOB " 7137 "complete"); 7138 break; 7139 case SMP_RESET_IN_PROGRESS: 7140 (void) sprintf(prev, ", was SMP reset " 7141 "in progress"); 7142 break; 7143 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 7144 (void) sprintf(prev, ", was online at " 7145 "1.5 Gbps"); 7146 break; 7147 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 7148 (void) sprintf(prev, ", was online at " 7149 "3.0 Gbps"); 7150 break; 7151 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 7152 (void) sprintf(prev, ", was online at " 7153 "6.0 Gbps"); 7154 break; 7155 default: 7156 break; 7157 } 7158 (void) sprintf(&string[strlen(string)], "link " 7159 "changed, "); 7160 break; 7161 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE: 7162 continue; 7163 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING: 7164 (void) sprintf(&string[strlen(string)], 7165 "target not responding, delaying " 7166 "removal"); 7167 break; 7168 } 7169 NDBG20(("mptsas%d phy %d DevHandle %x, %s%s%s\n", 7170 mpt->m_instance, phy, dev_handle, string, curr, 7171 prev)); 7172 } 7173 if (topo_head != NULL) { 7174 /* 7175 * Launch DR taskq to handle topology change 7176 */ 7177 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 7178 mptsas_handle_dr, (void *)topo_head, 7179 DDI_NOSLEEP)) != DDI_SUCCESS) { 7180 mptsas_log(mpt, CE_NOTE, "mptsas start taskq " 7181 "for handle SAS DR event failed. \n"); 7182 } 7183 } 7184 break; 7185 } 7186 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 7187 { 7188 Mpi2EventDataIrConfigChangeList_t *irChangeList; 7189 mptsas_topo_change_list_t *topo_head = NULL; 7190 mptsas_topo_change_list_t *topo_tail = NULL; 7191 mptsas_topo_change_list_t *topo_node = NULL; 7192 mptsas_target_t *ptgt; 7193 mptsas_hash_table_t *tgttbl; 7194 uint8_t num_entries, i, reason; 7195 uint16_t volhandle, diskhandle; 7196 7197 irChangeList = (pMpi2EventDataIrConfigChangeList_t) 7198 eventreply->EventData; 7199 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl, 7200 &irChangeList->NumElements); 7201 7202 tgttbl = &mpt->m_active->m_tgttbl; 7203 7204 NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received", 7205 mpt->m_instance)); 7206 7207 for (i = 0; i < num_entries; i++) { 7208 reason = ddi_get8(mpt->m_acc_reply_frame_hdl, 7209 &irChangeList->ConfigElement[i].ReasonCode); 7210 volhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7211 &irChangeList->ConfigElement[i].VolDevHandle); 7212 diskhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7213 &irChangeList->ConfigElement[i].PhysDiskDevHandle); 7214 7215 switch (reason) { 7216 case MPI2_EVENT_IR_CHANGE_RC_ADDED: 7217 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: 7218 { 7219 NDBG20(("mptsas %d volume added\n", 7220 mpt->m_instance)); 7221 7222 topo_node = kmem_zalloc( 7223 sizeof (mptsas_topo_change_list_t), 7224 KM_SLEEP); 7225 7226 topo_node->mpt = mpt; 7227 topo_node->event = 7228 MPTSAS_DR_EVENT_RECONFIG_TARGET; 7229 topo_node->un.physport = 0xff; 7230 topo_node->devhdl = volhandle; 7231 topo_node->flags = 7232 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED; 7233 topo_node->object = NULL; 7234 if (topo_head == NULL) { 7235 topo_head = topo_tail = topo_node; 7236 } else { 7237 topo_tail->next = topo_node; 7238 topo_tail = topo_node; 7239 } 7240 break; 7241 } 7242 case MPI2_EVENT_IR_CHANGE_RC_REMOVED: 7243 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: 7244 { 7245 NDBG20(("mptsas %d volume deleted\n", 7246 mpt->m_instance)); 7247 ptgt = mptsas_search_by_devhdl(tgttbl, 7248 volhandle); 7249 if (ptgt == NULL) 7250 break; 7251 7252 /* 7253 * Clear any flags related to volume 7254 */ 7255 (void) mptsas_delete_volume(mpt, volhandle); 7256 7257 /* 7258 * Update DR flag immediately avoid I/O failure 7259 */ 7260 mutex_enter(&ptgt->m_tgt_intr_mutex); 7261 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 7262 mutex_exit(&ptgt->m_tgt_intr_mutex); 7263 7264 topo_node = kmem_zalloc( 7265 sizeof (mptsas_topo_change_list_t), 7266 KM_SLEEP); 7267 topo_node->mpt = mpt; 7268 topo_node->un.phymask = ptgt->m_phymask; 7269 topo_node->event = 7270 MPTSAS_DR_EVENT_OFFLINE_TARGET; 7271 topo_node->devhdl = volhandle; 7272 topo_node->flags = 7273 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED; 7274 topo_node->object = (void *)ptgt; 7275 if (topo_head == NULL) { 7276 topo_head = topo_tail = topo_node; 7277 } else { 7278 topo_tail->next = topo_node; 7279 topo_tail = topo_node; 7280 } 7281 break; 7282 } 7283 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: 7284 case MPI2_EVENT_IR_CHANGE_RC_HIDE: 7285 { 7286 ptgt = mptsas_search_by_devhdl(tgttbl, 7287 diskhandle); 7288 if (ptgt == NULL) 7289 break; 7290 7291 /* 7292 * Update DR flag immediately avoid I/O failure 7293 */ 7294 mutex_enter(&ptgt->m_tgt_intr_mutex); 7295 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 7296 mutex_exit(&ptgt->m_tgt_intr_mutex); 7297 7298 topo_node = kmem_zalloc( 7299 sizeof (mptsas_topo_change_list_t), 7300 KM_SLEEP); 7301 topo_node->mpt = mpt; 7302 topo_node->un.phymask = ptgt->m_phymask; 7303 topo_node->event = 7304 MPTSAS_DR_EVENT_OFFLINE_TARGET; 7305 topo_node->devhdl = diskhandle; 7306 topo_node->flags = 7307 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED; 7308 topo_node->object = (void *)ptgt; 7309 if (topo_head == NULL) { 7310 topo_head = topo_tail = topo_node; 7311 } else { 7312 topo_tail->next = topo_node; 7313 topo_tail = topo_node; 7314 } 7315 break; 7316 } 7317 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: 7318 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: 7319 { 7320 /* 7321 * The physical drive is released by a IR 7322 * volume. But we cannot get the the physport 7323 * or phynum from the event data, so we only 7324 * can get the physport/phynum after SAS 7325 * Device Page0 request for the devhdl. 7326 */ 7327 topo_node = kmem_zalloc( 7328 sizeof (mptsas_topo_change_list_t), 7329 KM_SLEEP); 7330 topo_node->mpt = mpt; 7331 topo_node->un.phymask = 0; 7332 topo_node->event = 7333 MPTSAS_DR_EVENT_RECONFIG_TARGET; 7334 topo_node->devhdl = diskhandle; 7335 topo_node->flags = 7336 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED; 7337 topo_node->object = NULL; 7338 mpt->m_port_chng = 1; 7339 if (topo_head == NULL) { 7340 topo_head = topo_tail = topo_node; 7341 } else { 7342 topo_tail->next = topo_node; 7343 topo_tail = topo_node; 7344 } 7345 break; 7346 } 7347 default: 7348 break; 7349 } 7350 } 7351 7352 if (topo_head != NULL) { 7353 /* 7354 * Launch DR taskq to handle topology change 7355 */ 7356 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 7357 mptsas_handle_dr, (void *)topo_head, 7358 DDI_NOSLEEP)) != DDI_SUCCESS) { 7359 mptsas_log(mpt, CE_NOTE, "mptsas start taskq " 7360 "for handle SAS DR event failed. \n"); 7361 } 7362 } 7363 break; 7364 } 7365 default: 7366 return (DDI_FAILURE); 7367 } 7368 7369 return (DDI_SUCCESS); 7370 } 7371 7372 /* 7373 * handle events from ioc 7374 */ 7375 static void 7376 mptsas_handle_event(void *args) 7377 { 7378 m_replyh_arg_t *replyh_arg; 7379 pMpi2EventNotificationReply_t eventreply; 7380 uint32_t event, iocloginfo, rfm; 7381 uint32_t status; 7382 uint8_t port; 7383 mptsas_t *mpt; 7384 uint_t iocstatus; 7385 7386 replyh_arg = (m_replyh_arg_t *)args; 7387 rfm = replyh_arg->rfm; 7388 mpt = replyh_arg->mpt; 7389 7390 mutex_enter(&mpt->m_mutex); 7391 7392 eventreply = (pMpi2EventNotificationReply_t) 7393 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr)); 7394 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 7395 7396 if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 7397 &eventreply->IOCStatus)) { 7398 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 7399 mptsas_log(mpt, CE_WARN, 7400 "!mptsas_handle_event: IOCStatus=0x%x, " 7401 "IOCLogInfo=0x%x", iocstatus, 7402 ddi_get32(mpt->m_acc_reply_frame_hdl, 7403 &eventreply->IOCLogInfo)); 7404 } else { 7405 mptsas_log(mpt, CE_WARN, 7406 "mptsas_handle_event: IOCStatus=0x%x, " 7407 "IOCLogInfo=0x%x", iocstatus, 7408 ddi_get32(mpt->m_acc_reply_frame_hdl, 7409 &eventreply->IOCLogInfo)); 7410 } 7411 } 7412 7413 /* 7414 * figure out what kind of event we got and handle accordingly 7415 */ 7416 switch (event) { 7417 case MPI2_EVENT_LOG_ENTRY_ADDED: 7418 break; 7419 case MPI2_EVENT_LOG_DATA: 7420 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 7421 &eventreply->IOCLogInfo); 7422 NDBG20(("mptsas %d log info %x received.\n", mpt->m_instance, 7423 iocloginfo)); 7424 break; 7425 case MPI2_EVENT_STATE_CHANGE: 7426 NDBG20(("mptsas%d state change.", mpt->m_instance)); 7427 break; 7428 case MPI2_EVENT_HARD_RESET_RECEIVED: 7429 NDBG20(("mptsas%d event change.", mpt->m_instance)); 7430 break; 7431 case MPI2_EVENT_SAS_DISCOVERY: 7432 { 7433 MPI2_EVENT_DATA_SAS_DISCOVERY *sasdiscovery; 7434 char string[80]; 7435 uint8_t rc; 7436 7437 sasdiscovery = 7438 (pMpi2EventDataSasDiscovery_t)eventreply->EventData; 7439 7440 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7441 &sasdiscovery->ReasonCode); 7442 port = ddi_get8(mpt->m_acc_reply_frame_hdl, 7443 &sasdiscovery->PhysicalPort); 7444 status = ddi_get32(mpt->m_acc_reply_frame_hdl, 7445 &sasdiscovery->DiscoveryStatus); 7446 7447 string[0] = 0; 7448 switch (rc) { 7449 case MPI2_EVENT_SAS_DISC_RC_STARTED: 7450 (void) sprintf(string, "STARTING"); 7451 break; 7452 case MPI2_EVENT_SAS_DISC_RC_COMPLETED: 7453 (void) sprintf(string, "COMPLETED"); 7454 break; 7455 default: 7456 (void) sprintf(string, "UNKNOWN"); 7457 break; 7458 } 7459 7460 NDBG20(("SAS DISCOVERY is %s for port %d, status %x", string, 7461 port, status)); 7462 7463 break; 7464 } 7465 case MPI2_EVENT_EVENT_CHANGE: 7466 NDBG20(("mptsas%d event change.", mpt->m_instance)); 7467 break; 7468 case MPI2_EVENT_TASK_SET_FULL: 7469 { 7470 pMpi2EventDataTaskSetFull_t taskfull; 7471 7472 taskfull = (pMpi2EventDataTaskSetFull_t)eventreply->EventData; 7473 7474 NDBG20(("TASK_SET_FULL received for mptsas%d, depth %d\n", 7475 mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl, 7476 &taskfull->CurrentDepth))); 7477 break; 7478 } 7479 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 7480 { 7481 /* 7482 * SAS TOPOLOGY CHANGE LIST Event has already been handled 7483 * in mptsas_handle_event_sync() of interrupt context 7484 */ 7485 break; 7486 } 7487 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: 7488 { 7489 pMpi2EventDataSasEnclDevStatusChange_t encstatus; 7490 uint8_t rc; 7491 char string[80]; 7492 7493 encstatus = (pMpi2EventDataSasEnclDevStatusChange_t) 7494 eventreply->EventData; 7495 7496 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7497 &encstatus->ReasonCode); 7498 switch (rc) { 7499 case MPI2_EVENT_SAS_ENCL_RC_ADDED: 7500 (void) sprintf(string, "added"); 7501 break; 7502 case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING: 7503 (void) sprintf(string, ", not responding"); 7504 break; 7505 default: 7506 break; 7507 } 7508 NDBG20(("mptsas%d ENCLOSURE STATUS CHANGE for enclosure %x%s\n", 7509 mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl, 7510 &encstatus->EnclosureHandle), string)); 7511 break; 7512 } 7513 7514 /* 7515 * MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE is handled by 7516 * mptsas_handle_event_sync,in here just send ack message. 7517 */ 7518 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: 7519 { 7520 pMpi2EventDataSasDeviceStatusChange_t statuschange; 7521 uint8_t rc; 7522 uint16_t devhdl; 7523 uint64_t wwn = 0; 7524 uint32_t wwn_lo, wwn_hi; 7525 7526 statuschange = (pMpi2EventDataSasDeviceStatusChange_t) 7527 eventreply->EventData; 7528 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7529 &statuschange->ReasonCode); 7530 wwn_lo = ddi_get32(mpt->m_acc_reply_frame_hdl, 7531 (uint32_t *)(void *)&statuschange->SASAddress); 7532 wwn_hi = ddi_get32(mpt->m_acc_reply_frame_hdl, 7533 (uint32_t *)(void *)&statuschange->SASAddress + 1); 7534 wwn = ((uint64_t)wwn_hi << 32) | wwn_lo; 7535 devhdl = ddi_get16(mpt->m_acc_reply_frame_hdl, 7536 &statuschange->DevHandle); 7537 7538 NDBG13(("MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE wwn is %"PRIx64, 7539 wwn)); 7540 7541 switch (rc) { 7542 case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA: 7543 NDBG20(("SMART data received, ASC/ASCQ = %02x/%02x", 7544 ddi_get8(mpt->m_acc_reply_frame_hdl, 7545 &statuschange->ASC), 7546 ddi_get8(mpt->m_acc_reply_frame_hdl, 7547 &statuschange->ASCQ))); 7548 break; 7549 7550 case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED: 7551 NDBG20(("Device not supported")); 7552 break; 7553 7554 case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: 7555 NDBG20(("IOC internally generated the Target Reset " 7556 "for devhdl:%x", devhdl)); 7557 break; 7558 7559 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET: 7560 NDBG20(("IOC's internally generated Target Reset " 7561 "completed for devhdl:%x", devhdl)); 7562 break; 7563 7564 case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: 7565 NDBG20(("IOC internally generated Abort Task")); 7566 break; 7567 7568 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL: 7569 NDBG20(("IOC's internally generated Abort Task " 7570 "completed")); 7571 break; 7572 7573 case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: 7574 NDBG20(("IOC internally generated Abort Task Set")); 7575 break; 7576 7577 case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: 7578 NDBG20(("IOC internally generated Clear Task Set")); 7579 break; 7580 7581 case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: 7582 NDBG20(("IOC internally generated Query Task")); 7583 break; 7584 7585 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION: 7586 NDBG20(("Device sent an Asynchronous Notification")); 7587 break; 7588 7589 default: 7590 break; 7591 } 7592 break; 7593 } 7594 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 7595 { 7596 /* 7597 * IR TOPOLOGY CHANGE LIST Event has already been handled 7598 * in mpt_handle_event_sync() of interrupt context 7599 */ 7600 break; 7601 } 7602 case MPI2_EVENT_IR_OPERATION_STATUS: 7603 { 7604 Mpi2EventDataIrOperationStatus_t *irOpStatus; 7605 char reason_str[80]; 7606 uint8_t rc, percent; 7607 uint16_t handle; 7608 7609 irOpStatus = (pMpi2EventDataIrOperationStatus_t) 7610 eventreply->EventData; 7611 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7612 &irOpStatus->RAIDOperation); 7613 percent = ddi_get8(mpt->m_acc_reply_frame_hdl, 7614 &irOpStatus->PercentComplete); 7615 handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7616 &irOpStatus->VolDevHandle); 7617 7618 switch (rc) { 7619 case MPI2_EVENT_IR_RAIDOP_RESYNC: 7620 (void) sprintf(reason_str, "resync"); 7621 break; 7622 case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION: 7623 (void) sprintf(reason_str, "online capacity " 7624 "expansion"); 7625 break; 7626 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK: 7627 (void) sprintf(reason_str, "consistency check"); 7628 break; 7629 default: 7630 (void) sprintf(reason_str, "unknown reason %x", 7631 rc); 7632 } 7633 7634 NDBG20(("mptsas%d raid operational status: (%s)" 7635 "\thandle(0x%04x), percent complete(%d)\n", 7636 mpt->m_instance, reason_str, handle, percent)); 7637 break; 7638 } 7639 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: 7640 { 7641 pMpi2EventDataSasBroadcastPrimitive_t sas_broadcast; 7642 uint8_t phy_num; 7643 uint8_t primitive; 7644 7645 sas_broadcast = (pMpi2EventDataSasBroadcastPrimitive_t) 7646 eventreply->EventData; 7647 7648 phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl, 7649 &sas_broadcast->PhyNum); 7650 primitive = ddi_get8(mpt->m_acc_reply_frame_hdl, 7651 &sas_broadcast->Primitive); 7652 7653 switch (primitive) { 7654 case MPI2_EVENT_PRIMITIVE_CHANGE: 7655 mptsas_smhba_log_sysevent(mpt, 7656 ESC_SAS_HBA_PORT_BROADCAST, 7657 SAS_PORT_BROADCAST_CHANGE, 7658 &mpt->m_phy_info[phy_num].smhba_info); 7659 break; 7660 case MPI2_EVENT_PRIMITIVE_SES: 7661 mptsas_smhba_log_sysevent(mpt, 7662 ESC_SAS_HBA_PORT_BROADCAST, 7663 SAS_PORT_BROADCAST_SES, 7664 &mpt->m_phy_info[phy_num].smhba_info); 7665 break; 7666 case MPI2_EVENT_PRIMITIVE_EXPANDER: 7667 mptsas_smhba_log_sysevent(mpt, 7668 ESC_SAS_HBA_PORT_BROADCAST, 7669 SAS_PORT_BROADCAST_D01_4, 7670 &mpt->m_phy_info[phy_num].smhba_info); 7671 break; 7672 case MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT: 7673 mptsas_smhba_log_sysevent(mpt, 7674 ESC_SAS_HBA_PORT_BROADCAST, 7675 SAS_PORT_BROADCAST_D04_7, 7676 &mpt->m_phy_info[phy_num].smhba_info); 7677 break; 7678 case MPI2_EVENT_PRIMITIVE_RESERVED3: 7679 mptsas_smhba_log_sysevent(mpt, 7680 ESC_SAS_HBA_PORT_BROADCAST, 7681 SAS_PORT_BROADCAST_D16_7, 7682 &mpt->m_phy_info[phy_num].smhba_info); 7683 break; 7684 case MPI2_EVENT_PRIMITIVE_RESERVED4: 7685 mptsas_smhba_log_sysevent(mpt, 7686 ESC_SAS_HBA_PORT_BROADCAST, 7687 SAS_PORT_BROADCAST_D29_7, 7688 &mpt->m_phy_info[phy_num].smhba_info); 7689 break; 7690 case MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED: 7691 mptsas_smhba_log_sysevent(mpt, 7692 ESC_SAS_HBA_PORT_BROADCAST, 7693 SAS_PORT_BROADCAST_D24_0, 7694 &mpt->m_phy_info[phy_num].smhba_info); 7695 break; 7696 case MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED: 7697 mptsas_smhba_log_sysevent(mpt, 7698 ESC_SAS_HBA_PORT_BROADCAST, 7699 SAS_PORT_BROADCAST_D27_4, 7700 &mpt->m_phy_info[phy_num].smhba_info); 7701 break; 7702 default: 7703 NDBG20(("mptsas%d: unknown BROADCAST PRIMITIVE" 7704 " %x received", 7705 mpt->m_instance, primitive)); 7706 break; 7707 } 7708 NDBG20(("mptsas%d sas broadcast primitive: " 7709 "\tprimitive(0x%04x), phy(%d) complete\n", 7710 mpt->m_instance, primitive, phy_num)); 7711 break; 7712 } 7713 case MPI2_EVENT_IR_VOLUME: 7714 { 7715 Mpi2EventDataIrVolume_t *irVolume; 7716 uint16_t devhandle; 7717 uint32_t state; 7718 int config, vol; 7719 mptsas_slots_t *slots = mpt->m_active; 7720 uint8_t found = FALSE; 7721 7722 irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData; 7723 state = ddi_get32(mpt->m_acc_reply_frame_hdl, 7724 &irVolume->NewValue); 7725 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7726 &irVolume->VolDevHandle); 7727 7728 NDBG20(("EVENT_IR_VOLUME event is received")); 7729 7730 /* 7731 * Get latest RAID info and then find the DevHandle for this 7732 * event in the configuration. If the DevHandle is not found 7733 * just exit the event. 7734 */ 7735 (void) mptsas_get_raid_info(mpt); 7736 for (config = 0; (config < slots->m_num_raid_configs) && 7737 (!found); config++) { 7738 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) { 7739 if (slots->m_raidconfig[config].m_raidvol[vol]. 7740 m_raidhandle == devhandle) { 7741 found = TRUE; 7742 break; 7743 } 7744 } 7745 } 7746 if (!found) { 7747 break; 7748 } 7749 7750 switch (irVolume->ReasonCode) { 7751 case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED: 7752 { 7753 uint32_t i; 7754 slots->m_raidconfig[config].m_raidvol[vol].m_settings = 7755 state; 7756 7757 i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING; 7758 mptsas_log(mpt, CE_NOTE, " Volume %d settings changed" 7759 ", auto-config of hot-swap drives is %s" 7760 ", write caching is %s" 7761 ", hot-spare pool mask is %02x\n", 7762 vol, state & 7763 MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE 7764 ? "disabled" : "enabled", 7765 i == MPI2_RAIDVOL0_SETTING_UNCHANGED 7766 ? "controlled by member disks" : 7767 i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING 7768 ? "disabled" : 7769 i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING 7770 ? "enabled" : 7771 "incorrectly set", 7772 (state >> 16) & 0xff); 7773 break; 7774 } 7775 case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED: 7776 { 7777 slots->m_raidconfig[config].m_raidvol[vol].m_state = 7778 (uint8_t)state; 7779 7780 mptsas_log(mpt, CE_NOTE, 7781 "Volume %d is now %s\n", vol, 7782 state == MPI2_RAID_VOL_STATE_OPTIMAL 7783 ? "optimal" : 7784 state == MPI2_RAID_VOL_STATE_DEGRADED 7785 ? "degraded" : 7786 state == MPI2_RAID_VOL_STATE_ONLINE 7787 ? "online" : 7788 state == MPI2_RAID_VOL_STATE_INITIALIZING 7789 ? "initializing" : 7790 state == MPI2_RAID_VOL_STATE_FAILED 7791 ? "failed" : 7792 state == MPI2_RAID_VOL_STATE_MISSING 7793 ? "missing" : 7794 "state unknown"); 7795 break; 7796 } 7797 case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED: 7798 { 7799 slots->m_raidconfig[config].m_raidvol[vol]. 7800 m_statusflags = state; 7801 7802 mptsas_log(mpt, CE_NOTE, 7803 " Volume %d is now %s%s%s%s%s%s%s%s%s\n", 7804 vol, 7805 state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED 7806 ? ", enabled" : ", disabled", 7807 state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED 7808 ? ", quiesced" : "", 7809 state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE 7810 ? ", inactive" : ", active", 7811 state & 7812 MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL 7813 ? ", bad block table is full" : "", 7814 state & 7815 MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS 7816 ? ", resync in progress" : "", 7817 state & MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT 7818 ? ", background initialization in progress" : "", 7819 state & 7820 MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION 7821 ? ", capacity expansion in progress" : "", 7822 state & 7823 MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK 7824 ? ", consistency check in progress" : "", 7825 state & MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB 7826 ? ", data scrub in progress" : ""); 7827 break; 7828 } 7829 default: 7830 break; 7831 } 7832 break; 7833 } 7834 case MPI2_EVENT_IR_PHYSICAL_DISK: 7835 { 7836 Mpi2EventDataIrPhysicalDisk_t *irPhysDisk; 7837 uint16_t devhandle, enchandle, slot; 7838 uint32_t status, state; 7839 uint8_t physdisknum, reason; 7840 7841 irPhysDisk = (Mpi2EventDataIrPhysicalDisk_t *) 7842 eventreply->EventData; 7843 physdisknum = ddi_get8(mpt->m_acc_reply_frame_hdl, 7844 &irPhysDisk->PhysDiskNum); 7845 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7846 &irPhysDisk->PhysDiskDevHandle); 7847 enchandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7848 &irPhysDisk->EnclosureHandle); 7849 slot = ddi_get16(mpt->m_acc_reply_frame_hdl, 7850 &irPhysDisk->Slot); 7851 state = ddi_get32(mpt->m_acc_reply_frame_hdl, 7852 &irPhysDisk->NewValue); 7853 reason = ddi_get8(mpt->m_acc_reply_frame_hdl, 7854 &irPhysDisk->ReasonCode); 7855 7856 NDBG20(("EVENT_IR_PHYSICAL_DISK event is received")); 7857 7858 switch (reason) { 7859 case MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED: 7860 mptsas_log(mpt, CE_NOTE, 7861 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 7862 "for enclosure with handle 0x%x is now in hot " 7863 "spare pool %d", 7864 physdisknum, devhandle, slot, enchandle, 7865 (state >> 16) & 0xff); 7866 break; 7867 7868 case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED: 7869 status = state; 7870 mptsas_log(mpt, CE_NOTE, 7871 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 7872 "for enclosure with handle 0x%x is now " 7873 "%s%s%s%s%s\n", physdisknum, devhandle, slot, 7874 enchandle, 7875 status & MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME 7876 ? ", inactive" : ", active", 7877 status & MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC 7878 ? ", out of sync" : "", 7879 status & MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED 7880 ? ", quiesced" : "", 7881 status & 7882 MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED 7883 ? ", write cache enabled" : "", 7884 status & MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET 7885 ? ", capacity expansion target" : ""); 7886 break; 7887 7888 case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED: 7889 mptsas_log(mpt, CE_NOTE, 7890 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 7891 "for enclosure with handle 0x%x is now %s\n", 7892 physdisknum, devhandle, slot, enchandle, 7893 state == MPI2_RAID_PD_STATE_OPTIMAL 7894 ? "optimal" : 7895 state == MPI2_RAID_PD_STATE_REBUILDING 7896 ? "rebuilding" : 7897 state == MPI2_RAID_PD_STATE_DEGRADED 7898 ? "degraded" : 7899 state == MPI2_RAID_PD_STATE_HOT_SPARE 7900 ? "a hot spare" : 7901 state == MPI2_RAID_PD_STATE_ONLINE 7902 ? "online" : 7903 state == MPI2_RAID_PD_STATE_OFFLINE 7904 ? "offline" : 7905 state == MPI2_RAID_PD_STATE_NOT_COMPATIBLE 7906 ? "not compatible" : 7907 state == MPI2_RAID_PD_STATE_NOT_CONFIGURED 7908 ? "not configured" : 7909 "state unknown"); 7910 break; 7911 } 7912 break; 7913 } 7914 default: 7915 NDBG20(("mptsas%d: unknown event %x received", 7916 mpt->m_instance, event)); 7917 break; 7918 } 7919 7920 /* 7921 * Return the reply frame to the free queue. 7922 */ 7923 ddi_put32(mpt->m_acc_free_queue_hdl, 7924 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], rfm); 7925 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 7926 DDI_DMA_SYNC_FORDEV); 7927 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 7928 mpt->m_free_index = 0; 7929 } 7930 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 7931 mpt->m_free_index); 7932 mutex_exit(&mpt->m_mutex); 7933 } 7934 7935 /* 7936 * invoked from timeout() to restart qfull cmds with throttle == 0 7937 */ 7938 static void 7939 mptsas_restart_cmd(void *arg) 7940 { 7941 mptsas_t *mpt = arg; 7942 mptsas_target_t *ptgt = NULL; 7943 7944 mutex_enter(&mpt->m_mutex); 7945 7946 mpt->m_restart_cmd_timeid = 0; 7947 7948 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 7949 MPTSAS_HASH_FIRST); 7950 while (ptgt != NULL) { 7951 mutex_enter(&ptgt->m_tgt_intr_mutex); 7952 if (ptgt->m_reset_delay == 0) { 7953 if (ptgt->m_t_throttle == QFULL_THROTTLE) { 7954 mptsas_set_throttle(mpt, ptgt, 7955 MAX_THROTTLE); 7956 } 7957 } 7958 mutex_exit(&ptgt->m_tgt_intr_mutex); 7959 7960 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 7961 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 7962 } 7963 mptsas_restart_hba(mpt); 7964 mutex_exit(&mpt->m_mutex); 7965 } 7966 7967 /* 7968 * mptsas_remove_cmd0 is similar to mptsas_remove_cmd except that it is called 7969 * where m_intr_mutex has already been held. 7970 */ 7971 void 7972 mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 7973 { 7974 ASSERT(mutex_owned(&mpt->m_mutex)); 7975 7976 /* 7977 * With new fine-grained lock mechanism, the outstanding cmd is only 7978 * linked to m_active before the dma is triggerred(MPTSAS_START_CMD) 7979 * to send it. that is, mptsas_save_cmd() doesn't link the outstanding 7980 * cmd now. So when mptsas_remove_cmd is called, a mptsas_save_cmd must 7981 * have been called, but the cmd may have not been linked. 7982 * For mptsas_remove_cmd0, the cmd must have been linked. 7983 * In order to keep the same semantic, we link the cmd to the 7984 * outstanding cmd list. 7985 */ 7986 mpt->m_active->m_slot[cmd->cmd_slot] = cmd; 7987 7988 mutex_enter(&mpt->m_intr_mutex); 7989 mptsas_remove_cmd0(mpt, cmd); 7990 mutex_exit(&mpt->m_intr_mutex); 7991 } 7992 7993 static inline void 7994 mptsas_remove_cmd0(mptsas_t *mpt, mptsas_cmd_t *cmd) 7995 { 7996 int slot; 7997 mptsas_slots_t *slots = mpt->m_active; 7998 int t; 7999 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8000 mptsas_slot_free_e_t *pe; 8001 8002 ASSERT(cmd != NULL); 8003 ASSERT(cmd->cmd_queued == FALSE); 8004 8005 /* 8006 * Task Management cmds are removed in their own routines. Also, 8007 * we don't want to modify timeout based on TM cmds. 8008 */ 8009 if (cmd->cmd_flags & CFLAG_TM_CMD) { 8010 return; 8011 } 8012 8013 t = Tgt(cmd); 8014 slot = cmd->cmd_slot; 8015 pe = mpt->m_slot_free_ae + slot - 1; 8016 ASSERT(cmd == slots->m_slot[slot]); 8017 ASSERT((slot > 0) && slot < (mpt->m_max_requests - 1)); 8018 8019 /* 8020 * remove the cmd. 8021 */ 8022 mutex_enter(&mpt->m_slot_freeq_pairp[pe->cpuid]. 8023 m_slot_releq.s.m_fq_mutex); 8024 NDBG31(("mptsas_remove_cmd0: removing cmd=0x%p", (void *)cmd)); 8025 slots->m_slot[slot] = NULL; 8026 ASSERT(pe->slot == slot); 8027 list_insert_tail(&mpt->m_slot_freeq_pairp[pe->cpuid]. 8028 m_slot_releq.s.m_fq_list, pe); 8029 mpt->m_slot_freeq_pairp[pe->cpuid].m_slot_releq.s.m_fq_n++; 8030 ASSERT(mpt->m_slot_freeq_pairp[pe->cpuid]. 8031 m_slot_releq.s.m_fq_n <= mpt->m_max_requests - 2); 8032 mutex_exit(&mpt->m_slot_freeq_pairp[pe->cpuid]. 8033 m_slot_releq.s.m_fq_mutex); 8034 8035 /* 8036 * only decrement per target ncmds if command 8037 * has a target associated with it. 8038 */ 8039 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 8040 mutex_enter(&ptgt->m_tgt_intr_mutex); 8041 ptgt->m_t_ncmds--; 8042 /* 8043 * reset throttle if we just ran an untagged command 8044 * to a tagged target 8045 */ 8046 if ((ptgt->m_t_ncmds == 0) && 8047 ((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0)) { 8048 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 8049 } 8050 mutex_exit(&ptgt->m_tgt_intr_mutex); 8051 } 8052 8053 /* 8054 * This is all we need to do for ioc commands. 8055 * The ioc cmds would never be handled in fastpath in ISR, so we make 8056 * sure the mptsas_return_to_pool() would always be called with 8057 * m_mutex protected. 8058 */ 8059 if (cmd->cmd_flags & CFLAG_CMDIOC) { 8060 ASSERT(mutex_owned(&mpt->m_mutex)); 8061 mptsas_return_to_pool(mpt, cmd); 8062 return; 8063 } 8064 8065 /* 8066 * Figure out what to set tag Q timeout for... 8067 * 8068 * Optimize: If we have duplicate's of same timeout 8069 * we're using, then we'll use it again until we run 8070 * out of duplicates. This should be the normal case 8071 * for block and raw I/O. 8072 * If no duplicates, we have to scan through tag que and 8073 * find the longest timeout value and use it. This is 8074 * going to take a while... 8075 * Add 1 to m_n_slots to account for TM request. 8076 */ 8077 mutex_enter(&ptgt->m_tgt_intr_mutex); 8078 if (cmd->cmd_pkt->pkt_time == ptgt->m_timebase) { 8079 if (--(ptgt->m_dups) == 0) { 8080 if (ptgt->m_t_ncmds) { 8081 mptsas_cmd_t *ssp; 8082 uint_t n = 0; 8083 ushort_t nslots = (slots->m_n_slots + 1); 8084 ushort_t i; 8085 /* 8086 * This crude check assumes we don't do 8087 * this too often which seems reasonable 8088 * for block and raw I/O. 8089 */ 8090 for (i = 0; i < nslots; i++) { 8091 ssp = slots->m_slot[i]; 8092 if (ssp && (Tgt(ssp) == t) && 8093 (ssp->cmd_pkt->pkt_time > n)) { 8094 n = ssp->cmd_pkt->pkt_time; 8095 ptgt->m_dups = 1; 8096 } else if (ssp && (Tgt(ssp) == t) && 8097 (ssp->cmd_pkt->pkt_time == n)) { 8098 ptgt->m_dups++; 8099 } 8100 } 8101 ptgt->m_timebase = n; 8102 } else { 8103 ptgt->m_dups = 0; 8104 ptgt->m_timebase = 0; 8105 } 8106 } 8107 } 8108 ptgt->m_timeout = ptgt->m_timebase; 8109 8110 ASSERT(cmd != slots->m_slot[cmd->cmd_slot]); 8111 mutex_exit(&ptgt->m_tgt_intr_mutex); 8112 } 8113 8114 /* 8115 * start a fresh request from the top of the device queue. 8116 */ 8117 static void 8118 mptsas_restart_hba(mptsas_t *mpt) 8119 { 8120 mptsas_cmd_t *cmd, *next_cmd; 8121 mptsas_target_t *ptgt = NULL; 8122 8123 NDBG1(("mptsas_restart_hba: mpt=0x%p", (void *)mpt)); 8124 8125 ASSERT(mutex_owned(&mpt->m_mutex)); 8126 8127 /* 8128 * If there is a reset delay, don't start any cmds. Otherwise, start 8129 * as many cmds as possible. 8130 * Since SMID 0 is reserved and the TM slot is reserved, the actual max 8131 * commands is m_max_requests - 2. 8132 */ 8133 cmd = mpt->m_waitq; 8134 8135 while (cmd != NULL) { 8136 next_cmd = cmd->cmd_linkp; 8137 if (cmd->cmd_flags & CFLAG_PASSTHRU) { 8138 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 8139 /* 8140 * passthru command get slot need 8141 * set CFLAG_PREPARED. 8142 */ 8143 cmd->cmd_flags |= CFLAG_PREPARED; 8144 mptsas_waitq_delete(mpt, cmd); 8145 mptsas_start_passthru(mpt, cmd); 8146 } 8147 cmd = next_cmd; 8148 continue; 8149 } 8150 if (cmd->cmd_flags & CFLAG_CONFIG) { 8151 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 8152 /* 8153 * Send the config page request and delete it 8154 * from the waitq. 8155 */ 8156 cmd->cmd_flags |= CFLAG_PREPARED; 8157 mptsas_waitq_delete(mpt, cmd); 8158 mptsas_start_config_page_access(mpt, cmd); 8159 } 8160 cmd = next_cmd; 8161 continue; 8162 } 8163 if (cmd->cmd_flags & CFLAG_FW_DIAG) { 8164 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 8165 /* 8166 * Send the FW Diag request and delete if from 8167 * the waitq. 8168 */ 8169 cmd->cmd_flags |= CFLAG_PREPARED; 8170 mptsas_waitq_delete(mpt, cmd); 8171 mptsas_start_diag(mpt, cmd); 8172 } 8173 cmd = next_cmd; 8174 continue; 8175 } 8176 8177 ptgt = cmd->cmd_tgt_addr; 8178 if (ptgt) { 8179 mutex_enter(&mpt->m_intr_mutex); 8180 mutex_enter(&ptgt->m_tgt_intr_mutex); 8181 if ((ptgt->m_t_throttle == DRAIN_THROTTLE) && 8182 (ptgt->m_t_ncmds == 0)) { 8183 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 8184 } 8185 if ((ptgt->m_reset_delay == 0) && 8186 (ptgt->m_t_ncmds < ptgt->m_t_throttle)) { 8187 mutex_exit(&ptgt->m_tgt_intr_mutex); 8188 mutex_exit(&mpt->m_intr_mutex); 8189 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 8190 mptsas_waitq_delete(mpt, cmd); 8191 (void) mptsas_start_cmd(mpt, cmd); 8192 } 8193 goto out; 8194 } 8195 mutex_exit(&ptgt->m_tgt_intr_mutex); 8196 mutex_exit(&mpt->m_intr_mutex); 8197 } 8198 out: 8199 cmd = next_cmd; 8200 } 8201 } 8202 8203 /* 8204 * mpt tag type lookup 8205 */ 8206 static char mptsas_tag_lookup[] = 8207 {0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG}; 8208 8209 /* 8210 * mptsas_start_cmd0 is similar to mptsas_start_cmd, except that, it is called 8211 * without ANY mutex protected, while, mptsas_start_cmd is called with m_mutex 8212 * protected. 8213 * 8214 * the relevant field in ptgt should be protected by m_tgt_intr_mutex in both 8215 * functions. 8216 * 8217 * before the cmds are linked on the slot for monitor as outstanding cmds, they 8218 * are accessed as slab objects, so slab framework ensures the exclusive access, 8219 * and no other mutex is requireed. Linking for monitor and the trigger of dma 8220 * must be done exclusively. 8221 */ 8222 static int 8223 mptsas_start_cmd0(mptsas_t *mpt, mptsas_cmd_t *cmd) 8224 { 8225 struct scsi_pkt *pkt = CMD2PKT(cmd); 8226 uint32_t control = 0; 8227 int n; 8228 caddr_t mem; 8229 pMpi2SCSIIORequest_t io_request; 8230 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; 8231 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl; 8232 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8233 uint16_t SMID, io_flags = 0; 8234 uint32_t request_desc_low, request_desc_high; 8235 8236 NDBG1(("mptsas_start_cmd0: cmd=0x%p", (void *)cmd)); 8237 8238 /* 8239 * Set SMID and increment index. Rollover to 1 instead of 0 if index 8240 * is at the max. 0 is an invalid SMID, so we call the first index 1. 8241 */ 8242 SMID = cmd->cmd_slot; 8243 8244 /* 8245 * It is possible for back to back device reset to 8246 * happen before the reset delay has expired. That's 8247 * ok, just let the device reset go out on the bus. 8248 */ 8249 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 8250 ASSERT(ptgt->m_reset_delay == 0); 8251 } 8252 8253 /* 8254 * if a non-tagged cmd is submitted to an active tagged target 8255 * then drain before submitting this cmd; SCSI-2 allows RQSENSE 8256 * to be untagged 8257 */ 8258 mutex_enter(&ptgt->m_tgt_intr_mutex); 8259 if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) && 8260 (ptgt->m_t_ncmds > 1) && 8261 ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) && 8262 (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) { 8263 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 8264 NDBG23(("target=%d, untagged cmd, start draining\n", 8265 ptgt->m_devhdl)); 8266 8267 if (ptgt->m_reset_delay == 0) { 8268 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 8269 } 8270 mutex_exit(&ptgt->m_tgt_intr_mutex); 8271 8272 mutex_enter(&mpt->m_mutex); 8273 mptsas_remove_cmd(mpt, cmd); 8274 cmd->cmd_pkt_flags |= FLAG_HEAD; 8275 mptsas_waitq_add(mpt, cmd); 8276 mutex_exit(&mpt->m_mutex); 8277 return (DDI_FAILURE); 8278 } 8279 mutex_exit(&ptgt->m_tgt_intr_mutex); 8280 return (DDI_FAILURE); 8281 } 8282 mutex_exit(&ptgt->m_tgt_intr_mutex); 8283 8284 /* 8285 * Set correct tag bits. 8286 */ 8287 if (cmd->cmd_pkt_flags & FLAG_TAGMASK) { 8288 switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags & 8289 FLAG_TAGMASK) >> 12)]) { 8290 case MSG_SIMPLE_QTAG: 8291 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 8292 break; 8293 case MSG_HEAD_QTAG: 8294 control |= MPI2_SCSIIO_CONTROL_HEADOFQ; 8295 break; 8296 case MSG_ORDERED_QTAG: 8297 control |= MPI2_SCSIIO_CONTROL_ORDEREDQ; 8298 break; 8299 default: 8300 mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n"); 8301 break; 8302 } 8303 } else { 8304 if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) { 8305 ptgt->m_t_throttle = 1; 8306 } 8307 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 8308 } 8309 8310 if (cmd->cmd_pkt_flags & FLAG_TLR) { 8311 control |= MPI2_SCSIIO_CONTROL_TLR_ON; 8312 } 8313 8314 mem = mpt->m_req_frame + (mpt->m_req_frame_size * SMID); 8315 io_request = (pMpi2SCSIIORequest_t)mem; 8316 8317 bzero(io_request, sizeof (Mpi2SCSIIORequest_t)); 8318 ddi_put8(acc_hdl, &io_request->SGLOffset0, offsetof 8319 (MPI2_SCSI_IO_REQUEST, SGL) / 4); 8320 mptsas_init_std_hdr(acc_hdl, io_request, ptgt->m_devhdl, Lun(cmd), 0, 8321 MPI2_FUNCTION_SCSI_IO_REQUEST); 8322 8323 (void) ddi_rep_put8(acc_hdl, (uint8_t *)pkt->pkt_cdbp, 8324 io_request->CDB.CDB32, cmd->cmd_cdblen, DDI_DEV_AUTOINCR); 8325 8326 io_flags = cmd->cmd_cdblen; 8327 ddi_put16(acc_hdl, &io_request->IoFlags, io_flags); 8328 /* 8329 * setup the Scatter/Gather DMA list for this request 8330 */ 8331 if (cmd->cmd_cookiec > 0) { 8332 mptsas_sge_setup(mpt, cmd, &control, io_request, acc_hdl); 8333 } else { 8334 ddi_put32(acc_hdl, &io_request->SGL.MpiSimple.FlagsLength, 8335 ((uint32_t)MPI2_SGE_FLAGS_LAST_ELEMENT | 8336 MPI2_SGE_FLAGS_END_OF_BUFFER | 8337 MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 8338 MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); 8339 } 8340 8341 /* 8342 * save ARQ information 8343 */ 8344 ddi_put8(acc_hdl, &io_request->SenseBufferLength, cmd->cmd_rqslen); 8345 if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) == 8346 (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) { 8347 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, 8348 cmd->cmd_ext_arqcookie.dmac_address); 8349 } else { 8350 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, 8351 cmd->cmd_arqcookie.dmac_address); 8352 } 8353 8354 ddi_put32(acc_hdl, &io_request->Control, control); 8355 8356 NDBG31(("starting message=0x%p, with cmd=0x%p", 8357 (void *)(uintptr_t)mpt->m_req_frame_dma_addr, (void *)cmd)); 8358 8359 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 8360 8361 /* 8362 * Build request descriptor and write it to the request desc post reg. 8363 */ 8364 request_desc_low = (SMID << 16) + MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 8365 request_desc_high = ptgt->m_devhdl << 16; 8366 8367 mutex_enter(&mpt->m_mutex); 8368 mpt->m_active->m_slot[cmd->cmd_slot] = cmd; 8369 MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high); 8370 mutex_exit(&mpt->m_mutex); 8371 8372 /* 8373 * Start timeout. 8374 */ 8375 mutex_enter(&ptgt->m_tgt_intr_mutex); 8376 #ifdef MPTSAS_TEST 8377 /* 8378 * Temporarily set timebase = 0; needed for 8379 * timeout torture test. 8380 */ 8381 if (mptsas_test_timeouts) { 8382 ptgt->m_timebase = 0; 8383 } 8384 #endif 8385 n = pkt->pkt_time - ptgt->m_timebase; 8386 8387 if (n == 0) { 8388 (ptgt->m_dups)++; 8389 ptgt->m_timeout = ptgt->m_timebase; 8390 } else if (n > 0) { 8391 ptgt->m_timeout = 8392 ptgt->m_timebase = pkt->pkt_time; 8393 ptgt->m_dups = 1; 8394 } else if (n < 0) { 8395 ptgt->m_timeout = ptgt->m_timebase; 8396 } 8397 #ifdef MPTSAS_TEST 8398 /* 8399 * Set back to a number higher than 8400 * mptsas_scsi_watchdog_tick 8401 * so timeouts will happen in mptsas_watchsubr 8402 */ 8403 if (mptsas_test_timeouts) { 8404 ptgt->m_timebase = 60; 8405 } 8406 #endif 8407 mutex_exit(&ptgt->m_tgt_intr_mutex); 8408 8409 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || 8410 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { 8411 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8412 return (DDI_FAILURE); 8413 } 8414 return (DDI_SUCCESS); 8415 } 8416 8417 static int 8418 mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 8419 { 8420 struct scsi_pkt *pkt = CMD2PKT(cmd); 8421 uint32_t control = 0; 8422 int n; 8423 caddr_t mem; 8424 pMpi2SCSIIORequest_t io_request; 8425 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; 8426 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl; 8427 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8428 uint16_t SMID, io_flags = 0; 8429 uint32_t request_desc_low, request_desc_high; 8430 8431 NDBG1(("mptsas_start_cmd: cmd=0x%p", (void *)cmd)); 8432 8433 /* 8434 * Set SMID and increment index. Rollover to 1 instead of 0 if index 8435 * is at the max. 0 is an invalid SMID, so we call the first index 1. 8436 */ 8437 SMID = cmd->cmd_slot; 8438 8439 /* 8440 * It is possible for back to back device reset to 8441 * happen before the reset delay has expired. That's 8442 * ok, just let the device reset go out on the bus. 8443 */ 8444 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 8445 ASSERT(ptgt->m_reset_delay == 0); 8446 } 8447 8448 /* 8449 * if a non-tagged cmd is submitted to an active tagged target 8450 * then drain before submitting this cmd; SCSI-2 allows RQSENSE 8451 * to be untagged 8452 */ 8453 mutex_enter(&ptgt->m_tgt_intr_mutex); 8454 if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) && 8455 (ptgt->m_t_ncmds > 1) && 8456 ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) && 8457 (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) { 8458 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 8459 NDBG23(("target=%d, untagged cmd, start draining\n", 8460 ptgt->m_devhdl)); 8461 8462 if (ptgt->m_reset_delay == 0) { 8463 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 8464 } 8465 mutex_exit(&ptgt->m_tgt_intr_mutex); 8466 8467 mptsas_remove_cmd(mpt, cmd); 8468 cmd->cmd_pkt_flags |= FLAG_HEAD; 8469 mptsas_waitq_add(mpt, cmd); 8470 return (DDI_FAILURE); 8471 } 8472 mutex_exit(&ptgt->m_tgt_intr_mutex); 8473 return (DDI_FAILURE); 8474 } 8475 mutex_exit(&ptgt->m_tgt_intr_mutex); 8476 8477 /* 8478 * Set correct tag bits. 8479 */ 8480 if (cmd->cmd_pkt_flags & FLAG_TAGMASK) { 8481 switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags & 8482 FLAG_TAGMASK) >> 12)]) { 8483 case MSG_SIMPLE_QTAG: 8484 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 8485 break; 8486 case MSG_HEAD_QTAG: 8487 control |= MPI2_SCSIIO_CONTROL_HEADOFQ; 8488 break; 8489 case MSG_ORDERED_QTAG: 8490 control |= MPI2_SCSIIO_CONTROL_ORDEREDQ; 8491 break; 8492 default: 8493 mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n"); 8494 break; 8495 } 8496 } else { 8497 if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) { 8498 ptgt->m_t_throttle = 1; 8499 } 8500 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 8501 } 8502 8503 if (cmd->cmd_pkt_flags & FLAG_TLR) { 8504 control |= MPI2_SCSIIO_CONTROL_TLR_ON; 8505 } 8506 8507 mem = mpt->m_req_frame + (mpt->m_req_frame_size * SMID); 8508 io_request = (pMpi2SCSIIORequest_t)mem; 8509 8510 bzero(io_request, sizeof (Mpi2SCSIIORequest_t)); 8511 ddi_put8(acc_hdl, &io_request->SGLOffset0, offsetof 8512 (MPI2_SCSI_IO_REQUEST, SGL) / 4); 8513 mptsas_init_std_hdr(acc_hdl, io_request, ptgt->m_devhdl, Lun(cmd), 0, 8514 MPI2_FUNCTION_SCSI_IO_REQUEST); 8515 8516 (void) ddi_rep_put8(acc_hdl, (uint8_t *)pkt->pkt_cdbp, 8517 io_request->CDB.CDB32, cmd->cmd_cdblen, DDI_DEV_AUTOINCR); 8518 8519 io_flags = cmd->cmd_cdblen; 8520 ddi_put16(acc_hdl, &io_request->IoFlags, io_flags); 8521 /* 8522 * setup the Scatter/Gather DMA list for this request 8523 */ 8524 if (cmd->cmd_cookiec > 0) { 8525 mptsas_sge_setup(mpt, cmd, &control, io_request, acc_hdl); 8526 } else { 8527 ddi_put32(acc_hdl, &io_request->SGL.MpiSimple.FlagsLength, 8528 ((uint32_t)MPI2_SGE_FLAGS_LAST_ELEMENT | 8529 MPI2_SGE_FLAGS_END_OF_BUFFER | 8530 MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 8531 MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); 8532 } 8533 8534 /* 8535 * save ARQ information 8536 */ 8537 ddi_put8(acc_hdl, &io_request->SenseBufferLength, cmd->cmd_rqslen); 8538 if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) == 8539 (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) { 8540 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, 8541 cmd->cmd_ext_arqcookie.dmac_address); 8542 } else { 8543 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, 8544 cmd->cmd_arqcookie.dmac_address); 8545 } 8546 8547 ddi_put32(acc_hdl, &io_request->Control, control); 8548 8549 NDBG31(("starting message=0x%p, with cmd=0x%p", 8550 (void *)(uintptr_t)mpt->m_req_frame_dma_addr, (void *)cmd)); 8551 8552 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 8553 8554 /* 8555 * Build request descriptor and write it to the request desc post reg. 8556 */ 8557 request_desc_low = (SMID << 16) + MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 8558 request_desc_high = ptgt->m_devhdl << 16; 8559 8560 mpt->m_active->m_slot[cmd->cmd_slot] = cmd; 8561 MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high); 8562 8563 /* 8564 * Start timeout. 8565 */ 8566 mutex_enter(&ptgt->m_tgt_intr_mutex); 8567 #ifdef MPTSAS_TEST 8568 /* 8569 * Temporarily set timebase = 0; needed for 8570 * timeout torture test. 8571 */ 8572 if (mptsas_test_timeouts) { 8573 ptgt->m_timebase = 0; 8574 } 8575 #endif 8576 n = pkt->pkt_time - ptgt->m_timebase; 8577 8578 if (n == 0) { 8579 (ptgt->m_dups)++; 8580 ptgt->m_timeout = ptgt->m_timebase; 8581 } else if (n > 0) { 8582 ptgt->m_timeout = 8583 ptgt->m_timebase = pkt->pkt_time; 8584 ptgt->m_dups = 1; 8585 } else if (n < 0) { 8586 ptgt->m_timeout = ptgt->m_timebase; 8587 } 8588 #ifdef MPTSAS_TEST 8589 /* 8590 * Set back to a number higher than 8591 * mptsas_scsi_watchdog_tick 8592 * so timeouts will happen in mptsas_watchsubr 8593 */ 8594 if (mptsas_test_timeouts) { 8595 ptgt->m_timebase = 60; 8596 } 8597 #endif 8598 mutex_exit(&ptgt->m_tgt_intr_mutex); 8599 8600 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || 8601 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { 8602 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8603 return (DDI_FAILURE); 8604 } 8605 return (DDI_SUCCESS); 8606 } 8607 8608 /* 8609 * Select a helper thread to handle current doneq 8610 */ 8611 static void 8612 mptsas_deliver_doneq_thread(mptsas_t *mpt) 8613 { 8614 uint64_t t, i; 8615 uint32_t min = 0xffffffff; 8616 mptsas_doneq_thread_list_t *item; 8617 8618 for (i = 0; i < mpt->m_doneq_thread_n; i++) { 8619 item = &mpt->m_doneq_thread_id[i]; 8620 /* 8621 * If the completed command on help thread[i] less than 8622 * doneq_thread_threshold, then pick the thread[i]. Otherwise 8623 * pick a thread which has least completed command. 8624 */ 8625 8626 mutex_enter(&item->mutex); 8627 if (item->len < mpt->m_doneq_thread_threshold) { 8628 t = i; 8629 mutex_exit(&item->mutex); 8630 break; 8631 } 8632 if (item->len < min) { 8633 min = item->len; 8634 t = i; 8635 } 8636 mutex_exit(&item->mutex); 8637 } 8638 mutex_enter(&mpt->m_doneq_thread_id[t].mutex); 8639 mptsas_doneq_mv(mpt, t); 8640 cv_signal(&mpt->m_doneq_thread_id[t].cv); 8641 mutex_exit(&mpt->m_doneq_thread_id[t].mutex); 8642 } 8643 8644 /* 8645 * move the current global doneq to the doneq of thread[t] 8646 */ 8647 static void 8648 mptsas_doneq_mv(mptsas_t *mpt, uint64_t t) 8649 { 8650 mptsas_cmd_t *cmd; 8651 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 8652 8653 ASSERT(mutex_owned(&item->mutex)); 8654 mutex_enter(&mpt->m_intr_mutex); 8655 while ((cmd = mpt->m_doneq) != NULL) { 8656 if ((mpt->m_doneq = cmd->cmd_linkp) == NULL) { 8657 mpt->m_donetail = &mpt->m_doneq; 8658 } 8659 cmd->cmd_linkp = NULL; 8660 *item->donetail = cmd; 8661 item->donetail = &cmd->cmd_linkp; 8662 mpt->m_doneq_len--; 8663 item->len++; 8664 } 8665 mutex_exit(&mpt->m_intr_mutex); 8666 } 8667 8668 void 8669 mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd) 8670 { 8671 struct scsi_pkt *pkt = CMD2PKT(cmd); 8672 8673 /* Check all acc and dma handles */ 8674 if ((mptsas_check_acc_handle(mpt->m_datap) != 8675 DDI_SUCCESS) || 8676 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 8677 DDI_SUCCESS) || 8678 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) != 8679 DDI_SUCCESS) || 8680 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) != 8681 DDI_SUCCESS) || 8682 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) != 8683 DDI_SUCCESS) || 8684 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) != 8685 DDI_SUCCESS) || 8686 (mptsas_check_acc_handle(mpt->m_config_handle) != 8687 DDI_SUCCESS)) { 8688 ddi_fm_service_impact(mpt->m_dip, 8689 DDI_SERVICE_UNAFFECTED); 8690 ddi_fm_acc_err_clear(mpt->m_config_handle, 8691 DDI_FME_VER0); 8692 pkt->pkt_reason = CMD_TRAN_ERR; 8693 pkt->pkt_statistics = 0; 8694 } 8695 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 8696 DDI_SUCCESS) || 8697 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) != 8698 DDI_SUCCESS) || 8699 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) != 8700 DDI_SUCCESS) || 8701 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) != 8702 DDI_SUCCESS) || 8703 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) != 8704 DDI_SUCCESS)) { 8705 ddi_fm_service_impact(mpt->m_dip, 8706 DDI_SERVICE_UNAFFECTED); 8707 pkt->pkt_reason = CMD_TRAN_ERR; 8708 pkt->pkt_statistics = 0; 8709 } 8710 if (cmd->cmd_dmahandle && 8711 (mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS)) { 8712 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8713 pkt->pkt_reason = CMD_TRAN_ERR; 8714 pkt->pkt_statistics = 0; 8715 } 8716 if ((cmd->cmd_extra_frames && 8717 ((mptsas_check_dma_handle(cmd->cmd_extra_frames->m_dma_hdl) != 8718 DDI_SUCCESS) || 8719 (mptsas_check_acc_handle(cmd->cmd_extra_frames->m_acc_hdl) != 8720 DDI_SUCCESS)))) { 8721 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8722 pkt->pkt_reason = CMD_TRAN_ERR; 8723 pkt->pkt_statistics = 0; 8724 } 8725 if (cmd->cmd_arqhandle && 8726 (mptsas_check_dma_handle(cmd->cmd_arqhandle) != DDI_SUCCESS)) { 8727 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8728 pkt->pkt_reason = CMD_TRAN_ERR; 8729 pkt->pkt_statistics = 0; 8730 } 8731 if (cmd->cmd_ext_arqhandle && 8732 (mptsas_check_dma_handle(cmd->cmd_ext_arqhandle) != DDI_SUCCESS)) { 8733 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8734 pkt->pkt_reason = CMD_TRAN_ERR; 8735 pkt->pkt_statistics = 0; 8736 } 8737 } 8738 8739 /* 8740 * mptsas_doneq_add0 is similar to mptsas_doneq_add except that it is called 8741 * where m_intr_mutex has already been held. 8742 */ 8743 static inline void 8744 mptsas_doneq_add0(mptsas_t *mpt, mptsas_cmd_t *cmd) 8745 { 8746 struct scsi_pkt *pkt = CMD2PKT(cmd); 8747 8748 NDBG31(("mptsas_doneq_add0: cmd=0x%p", (void *)cmd)); 8749 8750 ASSERT((cmd->cmd_flags & CFLAG_COMPLETED) == 0); 8751 cmd->cmd_linkp = NULL; 8752 cmd->cmd_flags |= CFLAG_FINISHED; 8753 cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT; 8754 8755 /* 8756 * only add scsi pkts that have completion routines to 8757 * the doneq. no intr cmds do not have callbacks. 8758 */ 8759 if (pkt && (pkt->pkt_comp)) { 8760 *mpt->m_donetail = cmd; 8761 mpt->m_donetail = &cmd->cmd_linkp; 8762 mpt->m_doneq_len++; 8763 } 8764 } 8765 8766 /* 8767 * These routines manipulate the queue of commands that 8768 * are waiting for their completion routines to be called. 8769 * The queue is usually in FIFO order but on an MP system 8770 * it's possible for the completion routines to get out 8771 * of order. If that's a problem you need to add a global 8772 * mutex around the code that calls the completion routine 8773 * in the interrupt handler. 8774 */ 8775 static void 8776 mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd) 8777 { 8778 ASSERT(mutex_owned(&mpt->m_mutex)); 8779 8780 mptsas_fma_check(mpt, cmd); 8781 8782 mutex_enter(&mpt->m_intr_mutex); 8783 mptsas_doneq_add0(mpt, cmd); 8784 mutex_exit(&mpt->m_intr_mutex); 8785 } 8786 8787 static mptsas_cmd_t * 8788 mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t) 8789 { 8790 mptsas_cmd_t *cmd; 8791 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 8792 8793 /* pop one off the done queue */ 8794 if ((cmd = item->doneq) != NULL) { 8795 /* if the queue is now empty fix the tail pointer */ 8796 NDBG31(("mptsas_doneq_thread_rm: cmd=0x%p", (void *)cmd)); 8797 if ((item->doneq = cmd->cmd_linkp) == NULL) { 8798 item->donetail = &item->doneq; 8799 } 8800 cmd->cmd_linkp = NULL; 8801 item->len--; 8802 } 8803 return (cmd); 8804 } 8805 8806 static void 8807 mptsas_doneq_empty(mptsas_t *mpt) 8808 { 8809 mutex_enter(&mpt->m_intr_mutex); 8810 if (mpt->m_doneq && !mpt->m_in_callback) { 8811 mptsas_cmd_t *cmd, *next; 8812 struct scsi_pkt *pkt; 8813 8814 mpt->m_in_callback = 1; 8815 cmd = mpt->m_doneq; 8816 mpt->m_doneq = NULL; 8817 mpt->m_donetail = &mpt->m_doneq; 8818 mpt->m_doneq_len = 0; 8819 8820 mutex_exit(&mpt->m_intr_mutex); 8821 8822 /* 8823 * ONLY in ISR, is it called without m_mutex held, otherwise, 8824 * it is always called with m_mutex held. 8825 */ 8826 if ((curthread->t_flag & T_INTR_THREAD) == 0) 8827 mutex_exit(&mpt->m_mutex); 8828 /* 8829 * run the completion routines of all the 8830 * completed commands 8831 */ 8832 while (cmd != NULL) { 8833 next = cmd->cmd_linkp; 8834 cmd->cmd_linkp = NULL; 8835 /* run this command's completion routine */ 8836 cmd->cmd_flags |= CFLAG_COMPLETED; 8837 pkt = CMD2PKT(cmd); 8838 mptsas_pkt_comp(pkt, cmd); 8839 cmd = next; 8840 } 8841 if ((curthread->t_flag & T_INTR_THREAD) == 0) 8842 mutex_enter(&mpt->m_mutex); 8843 mpt->m_in_callback = 0; 8844 return; 8845 } 8846 mutex_exit(&mpt->m_intr_mutex); 8847 } 8848 8849 /* 8850 * These routines manipulate the target's queue of pending requests 8851 */ 8852 void 8853 mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd) 8854 { 8855 NDBG7(("mptsas_waitq_add: cmd=0x%p", (void *)cmd)); 8856 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8857 cmd->cmd_queued = TRUE; 8858 if (ptgt) 8859 ptgt->m_t_nwait++; 8860 if (cmd->cmd_pkt_flags & FLAG_HEAD) { 8861 mutex_enter(&mpt->m_intr_mutex); 8862 if ((cmd->cmd_linkp = mpt->m_waitq) == NULL) { 8863 mpt->m_waitqtail = &cmd->cmd_linkp; 8864 } 8865 mpt->m_waitq = cmd; 8866 mutex_exit(&mpt->m_intr_mutex); 8867 } else { 8868 cmd->cmd_linkp = NULL; 8869 *(mpt->m_waitqtail) = cmd; 8870 mpt->m_waitqtail = &cmd->cmd_linkp; 8871 } 8872 } 8873 8874 static mptsas_cmd_t * 8875 mptsas_waitq_rm(mptsas_t *mpt) 8876 { 8877 mptsas_cmd_t *cmd; 8878 mptsas_target_t *ptgt; 8879 NDBG7(("mptsas_waitq_rm")); 8880 8881 mutex_enter(&mpt->m_intr_mutex); 8882 MPTSAS_WAITQ_RM(mpt, cmd); 8883 mutex_exit(&mpt->m_intr_mutex); 8884 8885 NDBG7(("mptsas_waitq_rm: cmd=0x%p", (void *)cmd)); 8886 if (cmd) { 8887 ptgt = cmd->cmd_tgt_addr; 8888 if (ptgt) { 8889 ptgt->m_t_nwait--; 8890 ASSERT(ptgt->m_t_nwait >= 0); 8891 } 8892 } 8893 return (cmd); 8894 } 8895 8896 /* 8897 * remove specified cmd from the middle of the wait queue. 8898 */ 8899 static void 8900 mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd) 8901 { 8902 mptsas_cmd_t *prevp = mpt->m_waitq; 8903 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8904 8905 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8906 (void *)mpt, (void *)cmd)); 8907 if (ptgt) { 8908 ptgt->m_t_nwait--; 8909 ASSERT(ptgt->m_t_nwait >= 0); 8910 } 8911 8912 if (prevp == cmd) { 8913 mutex_enter(&mpt->m_intr_mutex); 8914 if ((mpt->m_waitq = cmd->cmd_linkp) == NULL) 8915 mpt->m_waitqtail = &mpt->m_waitq; 8916 mutex_exit(&mpt->m_intr_mutex); 8917 8918 cmd->cmd_linkp = NULL; 8919 cmd->cmd_queued = FALSE; 8920 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8921 (void *)mpt, (void *)cmd)); 8922 return; 8923 } 8924 8925 while (prevp != NULL) { 8926 if (prevp->cmd_linkp == cmd) { 8927 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL) 8928 mpt->m_waitqtail = &prevp->cmd_linkp; 8929 8930 cmd->cmd_linkp = NULL; 8931 cmd->cmd_queued = FALSE; 8932 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8933 (void *)mpt, (void *)cmd)); 8934 return; 8935 } 8936 prevp = prevp->cmd_linkp; 8937 } 8938 cmn_err(CE_PANIC, "mpt: mptsas_waitq_delete: queue botch"); 8939 } 8940 8941 /* 8942 * device and bus reset handling 8943 * 8944 * Notes: 8945 * - RESET_ALL: reset the controller 8946 * - RESET_TARGET: reset the target specified in scsi_address 8947 */ 8948 static int 8949 mptsas_scsi_reset(struct scsi_address *ap, int level) 8950 { 8951 mptsas_t *mpt = ADDR2MPT(ap); 8952 int rval; 8953 mptsas_tgt_private_t *tgt_private; 8954 mptsas_target_t *ptgt = NULL; 8955 8956 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->tran_tgt_private; 8957 ptgt = tgt_private->t_private; 8958 if (ptgt == NULL) { 8959 return (FALSE); 8960 } 8961 NDBG22(("mptsas_scsi_reset: target=%d level=%d", ptgt->m_devhdl, 8962 level)); 8963 8964 mutex_enter(&mpt->m_mutex); 8965 /* 8966 * if we are not in panic set up a reset delay for this target 8967 */ 8968 if (!ddi_in_panic()) { 8969 mptsas_setup_bus_reset_delay(mpt); 8970 } else { 8971 drv_usecwait(mpt->m_scsi_reset_delay * 1000); 8972 } 8973 rval = mptsas_do_scsi_reset(mpt, ptgt->m_devhdl); 8974 mutex_exit(&mpt->m_mutex); 8975 8976 /* 8977 * The transport layer expect to only see TRUE and 8978 * FALSE. Therefore, we will adjust the return value 8979 * if mptsas_do_scsi_reset returns FAILED. 8980 */ 8981 if (rval == FAILED) 8982 rval = FALSE; 8983 return (rval); 8984 } 8985 8986 static int 8987 mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl) 8988 { 8989 int rval = FALSE; 8990 uint8_t config, disk; 8991 mptsas_slots_t *slots = mpt->m_active; 8992 8993 ASSERT(mutex_owned(&mpt->m_mutex)); 8994 8995 if (mptsas_debug_resets) { 8996 mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d", 8997 devhdl); 8998 } 8999 9000 /* 9001 * Issue a Target Reset message to the target specified but not to a 9002 * disk making up a raid volume. Just look through the RAID config 9003 * Phys Disk list of DevHandles. If the target's DevHandle is in this 9004 * list, then don't reset this target. 9005 */ 9006 for (config = 0; config < slots->m_num_raid_configs; config++) { 9007 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) { 9008 if (devhdl == slots->m_raidconfig[config]. 9009 m_physdisk_devhdl[disk]) { 9010 return (TRUE); 9011 } 9012 } 9013 } 9014 9015 rval = mptsas_ioc_task_management(mpt, 9016 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, devhdl, 0, NULL, 0, 0); 9017 9018 mptsas_doneq_empty(mpt); 9019 return (rval); 9020 } 9021 9022 static int 9023 mptsas_scsi_reset_notify(struct scsi_address *ap, int flag, 9024 void (*callback)(caddr_t), caddr_t arg) 9025 { 9026 mptsas_t *mpt = ADDR2MPT(ap); 9027 9028 NDBG22(("mptsas_scsi_reset_notify: tgt=%d", ap->a_target)); 9029 9030 return (scsi_hba_reset_notify_setup(ap, flag, callback, arg, 9031 &mpt->m_mutex, &mpt->m_reset_notify_listf)); 9032 } 9033 9034 static int 9035 mptsas_get_name(struct scsi_device *sd, char *name, int len) 9036 { 9037 dev_info_t *lun_dip = NULL; 9038 9039 ASSERT(sd != NULL); 9040 ASSERT(name != NULL); 9041 lun_dip = sd->sd_dev; 9042 ASSERT(lun_dip != NULL); 9043 9044 if (mptsas_name_child(lun_dip, name, len) == DDI_SUCCESS) { 9045 return (1); 9046 } else { 9047 return (0); 9048 } 9049 } 9050 9051 static int 9052 mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len) 9053 { 9054 return (mptsas_get_name(sd, name, len)); 9055 } 9056 9057 void 9058 mptsas_set_throttle(mptsas_t *mpt, mptsas_target_t *ptgt, int what) 9059 { 9060 9061 NDBG25(("mptsas_set_throttle: throttle=%x", what)); 9062 9063 /* 9064 * if the bus is draining/quiesced, no changes to the throttles 9065 * are allowed. Not allowing change of throttles during draining 9066 * limits error recovery but will reduce draining time 9067 * 9068 * all throttles should have been set to HOLD_THROTTLE 9069 */ 9070 if (mpt->m_softstate & (MPTSAS_SS_QUIESCED | MPTSAS_SS_DRAINING)) { 9071 return; 9072 } 9073 9074 if (what == HOLD_THROTTLE) { 9075 ptgt->m_t_throttle = HOLD_THROTTLE; 9076 } else if (ptgt->m_reset_delay == 0) { 9077 ptgt->m_t_throttle = what; 9078 } 9079 } 9080 9081 /* 9082 * Clean up from a device reset. 9083 * For the case of target reset, this function clears the waitq of all 9084 * commands for a particular target. For the case of abort task set, this 9085 * function clears the waitq of all commonds for a particular target/lun. 9086 */ 9087 static void 9088 mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype) 9089 { 9090 mptsas_slots_t *slots = mpt->m_active; 9091 mptsas_cmd_t *cmd, *next_cmd; 9092 int slot; 9093 uchar_t reason; 9094 uint_t stat; 9095 9096 NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun)); 9097 9098 /* 9099 * Make sure the I/O Controller has flushed all cmds 9100 * that are associated with this target for a target reset 9101 * and target/lun for abort task set. 9102 * Account for TM requests, which use the last SMID. 9103 */ 9104 mutex_enter(&mpt->m_intr_mutex); 9105 for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) { 9106 if ((cmd = slots->m_slot[slot]) == NULL) { 9107 continue; 9108 } 9109 reason = CMD_RESET; 9110 stat = STAT_DEV_RESET; 9111 switch (tasktype) { 9112 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 9113 if (Tgt(cmd) == target) { 9114 NDBG25(("mptsas_flush_target discovered non-" 9115 "NULL cmd in slot %d, tasktype 0x%x", slot, 9116 tasktype)); 9117 mptsas_dump_cmd(mpt, cmd); 9118 mptsas_remove_cmd0(mpt, cmd); 9119 mptsas_set_pkt_reason(mpt, cmd, reason, stat); 9120 mptsas_doneq_add0(mpt, cmd); 9121 } 9122 break; 9123 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 9124 reason = CMD_ABORTED; 9125 stat = STAT_ABORTED; 9126 /*FALLTHROUGH*/ 9127 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 9128 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 9129 9130 NDBG25(("mptsas_flush_target discovered non-" 9131 "NULL cmd in slot %d, tasktype 0x%x", slot, 9132 tasktype)); 9133 mptsas_dump_cmd(mpt, cmd); 9134 mptsas_remove_cmd0(mpt, cmd); 9135 mptsas_set_pkt_reason(mpt, cmd, reason, 9136 stat); 9137 mptsas_doneq_add0(mpt, cmd); 9138 } 9139 break; 9140 default: 9141 break; 9142 } 9143 } 9144 mutex_exit(&mpt->m_intr_mutex); 9145 9146 /* 9147 * Flush the waitq of this target's cmds 9148 */ 9149 cmd = mpt->m_waitq; 9150 9151 reason = CMD_RESET; 9152 stat = STAT_DEV_RESET; 9153 9154 switch (tasktype) { 9155 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 9156 while (cmd != NULL) { 9157 next_cmd = cmd->cmd_linkp; 9158 if (Tgt(cmd) == target) { 9159 mptsas_waitq_delete(mpt, cmd); 9160 mptsas_set_pkt_reason(mpt, cmd, 9161 reason, stat); 9162 mptsas_doneq_add(mpt, cmd); 9163 } 9164 cmd = next_cmd; 9165 } 9166 break; 9167 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 9168 reason = CMD_ABORTED; 9169 stat = STAT_ABORTED; 9170 /*FALLTHROUGH*/ 9171 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 9172 while (cmd != NULL) { 9173 next_cmd = cmd->cmd_linkp; 9174 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 9175 mptsas_waitq_delete(mpt, cmd); 9176 mptsas_set_pkt_reason(mpt, cmd, 9177 reason, stat); 9178 mptsas_doneq_add(mpt, cmd); 9179 } 9180 cmd = next_cmd; 9181 } 9182 break; 9183 default: 9184 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.", 9185 tasktype); 9186 break; 9187 } 9188 } 9189 9190 /* 9191 * Clean up hba state, abort all outstanding command and commands in waitq 9192 * reset timeout of all targets. 9193 */ 9194 static void 9195 mptsas_flush_hba(mptsas_t *mpt) 9196 { 9197 mptsas_slots_t *slots = mpt->m_active; 9198 mptsas_cmd_t *cmd; 9199 int slot; 9200 9201 NDBG25(("mptsas_flush_hba")); 9202 9203 /* 9204 * The I/O Controller should have already sent back 9205 * all commands via the scsi I/O reply frame. Make 9206 * sure all commands have been flushed. 9207 * Account for TM request, which use the last SMID. 9208 */ 9209 mutex_enter(&mpt->m_intr_mutex); 9210 for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) { 9211 if ((cmd = slots->m_slot[slot]) == NULL) { 9212 continue; 9213 } 9214 9215 if (cmd->cmd_flags & CFLAG_CMDIOC) { 9216 /* 9217 * Need to make sure to tell everyone that might be 9218 * waiting on this command that it's going to fail. If 9219 * we get here, this command will never timeout because 9220 * the active command table is going to be re-allocated, 9221 * so there will be nothing to check against a time out. 9222 * Instead, mark the command as failed due to reset. 9223 */ 9224 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, 9225 STAT_BUS_RESET); 9226 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 9227 (cmd->cmd_flags & CFLAG_CONFIG) || 9228 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 9229 cmd->cmd_flags |= CFLAG_FINISHED; 9230 cv_broadcast(&mpt->m_passthru_cv); 9231 cv_broadcast(&mpt->m_config_cv); 9232 cv_broadcast(&mpt->m_fw_diag_cv); 9233 } 9234 continue; 9235 } 9236 9237 NDBG25(("mptsas_flush_hba discovered non-NULL cmd in slot %d", 9238 slot)); 9239 mptsas_dump_cmd(mpt, cmd); 9240 9241 mptsas_remove_cmd0(mpt, cmd); 9242 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 9243 mptsas_doneq_add0(mpt, cmd); 9244 } 9245 mutex_exit(&mpt->m_intr_mutex); 9246 9247 /* 9248 * Flush the waitq. 9249 */ 9250 while ((cmd = mptsas_waitq_rm(mpt)) != NULL) { 9251 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 9252 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 9253 (cmd->cmd_flags & CFLAG_CONFIG) || 9254 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 9255 cmd->cmd_flags |= CFLAG_FINISHED; 9256 cv_broadcast(&mpt->m_passthru_cv); 9257 cv_broadcast(&mpt->m_config_cv); 9258 cv_broadcast(&mpt->m_fw_diag_cv); 9259 } else { 9260 mptsas_doneq_add(mpt, cmd); 9261 } 9262 } 9263 } 9264 9265 /* 9266 * set pkt_reason and OR in pkt_statistics flag 9267 */ 9268 static void 9269 mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, uchar_t reason, 9270 uint_t stat) 9271 { 9272 #ifndef __lock_lint 9273 _NOTE(ARGUNUSED(mpt)) 9274 #endif 9275 9276 NDBG25(("mptsas_set_pkt_reason: cmd=0x%p reason=%x stat=%x", 9277 (void *)cmd, reason, stat)); 9278 9279 if (cmd) { 9280 if (cmd->cmd_pkt->pkt_reason == CMD_CMPLT) { 9281 cmd->cmd_pkt->pkt_reason = reason; 9282 } 9283 cmd->cmd_pkt->pkt_statistics |= stat; 9284 } 9285 } 9286 9287 static void 9288 mptsas_start_watch_reset_delay() 9289 { 9290 NDBG22(("mptsas_start_watch_reset_delay")); 9291 9292 mutex_enter(&mptsas_global_mutex); 9293 if (mptsas_reset_watch == NULL && mptsas_timeouts_enabled) { 9294 mptsas_reset_watch = timeout(mptsas_watch_reset_delay, NULL, 9295 drv_usectohz((clock_t) 9296 MPTSAS_WATCH_RESET_DELAY_TICK * 1000)); 9297 ASSERT(mptsas_reset_watch != NULL); 9298 } 9299 mutex_exit(&mptsas_global_mutex); 9300 } 9301 9302 static void 9303 mptsas_setup_bus_reset_delay(mptsas_t *mpt) 9304 { 9305 mptsas_target_t *ptgt = NULL; 9306 9307 NDBG22(("mptsas_setup_bus_reset_delay")); 9308 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 9309 MPTSAS_HASH_FIRST); 9310 while (ptgt != NULL) { 9311 mutex_enter(&ptgt->m_tgt_intr_mutex); 9312 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 9313 ptgt->m_reset_delay = mpt->m_scsi_reset_delay; 9314 mutex_exit(&ptgt->m_tgt_intr_mutex); 9315 9316 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9317 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9318 } 9319 9320 mptsas_start_watch_reset_delay(); 9321 } 9322 9323 /* 9324 * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every 9325 * mpt instance for active reset delays 9326 */ 9327 static void 9328 mptsas_watch_reset_delay(void *arg) 9329 { 9330 #ifndef __lock_lint 9331 _NOTE(ARGUNUSED(arg)) 9332 #endif 9333 9334 mptsas_t *mpt; 9335 int not_done = 0; 9336 9337 NDBG22(("mptsas_watch_reset_delay")); 9338 9339 mutex_enter(&mptsas_global_mutex); 9340 mptsas_reset_watch = 0; 9341 mutex_exit(&mptsas_global_mutex); 9342 rw_enter(&mptsas_global_rwlock, RW_READER); 9343 for (mpt = mptsas_head; mpt != NULL; mpt = mpt->m_next) { 9344 if (mpt->m_tran == 0) { 9345 continue; 9346 } 9347 mutex_enter(&mpt->m_mutex); 9348 not_done += mptsas_watch_reset_delay_subr(mpt); 9349 mutex_exit(&mpt->m_mutex); 9350 } 9351 rw_exit(&mptsas_global_rwlock); 9352 9353 if (not_done) { 9354 mptsas_start_watch_reset_delay(); 9355 } 9356 } 9357 9358 static int 9359 mptsas_watch_reset_delay_subr(mptsas_t *mpt) 9360 { 9361 int done = 0; 9362 int restart = 0; 9363 mptsas_target_t *ptgt = NULL; 9364 9365 NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt)); 9366 9367 ASSERT(mutex_owned(&mpt->m_mutex)); 9368 9369 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 9370 MPTSAS_HASH_FIRST); 9371 while (ptgt != NULL) { 9372 mutex_enter(&ptgt->m_tgt_intr_mutex); 9373 if (ptgt->m_reset_delay != 0) { 9374 ptgt->m_reset_delay -= 9375 MPTSAS_WATCH_RESET_DELAY_TICK; 9376 if (ptgt->m_reset_delay <= 0) { 9377 ptgt->m_reset_delay = 0; 9378 mptsas_set_throttle(mpt, ptgt, 9379 MAX_THROTTLE); 9380 restart++; 9381 } else { 9382 done = -1; 9383 } 9384 } 9385 mutex_exit(&ptgt->m_tgt_intr_mutex); 9386 9387 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9388 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9389 } 9390 9391 if (restart > 0) { 9392 mptsas_restart_hba(mpt); 9393 } 9394 return (done); 9395 } 9396 9397 #ifdef MPTSAS_TEST 9398 static void 9399 mptsas_test_reset(mptsas_t *mpt, int target) 9400 { 9401 mptsas_target_t *ptgt = NULL; 9402 9403 if (mptsas_rtest == target) { 9404 if (mptsas_do_scsi_reset(mpt, target) == TRUE) { 9405 mptsas_rtest = -1; 9406 } 9407 if (mptsas_rtest == -1) { 9408 NDBG22(("mptsas_test_reset success")); 9409 } 9410 } 9411 } 9412 #endif 9413 9414 /* 9415 * abort handling: 9416 * 9417 * Notes: 9418 * - if pkt is not NULL, abort just that command 9419 * - if pkt is NULL, abort all outstanding commands for target 9420 */ 9421 static int 9422 mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt) 9423 { 9424 mptsas_t *mpt = ADDR2MPT(ap); 9425 int rval; 9426 mptsas_tgt_private_t *tgt_private; 9427 int target, lun; 9428 9429 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran-> 9430 tran_tgt_private; 9431 ASSERT(tgt_private != NULL); 9432 target = tgt_private->t_private->m_devhdl; 9433 lun = tgt_private->t_lun; 9434 9435 NDBG23(("mptsas_scsi_abort: target=%d.%d", target, lun)); 9436 9437 mutex_enter(&mpt->m_mutex); 9438 rval = mptsas_do_scsi_abort(mpt, target, lun, pkt); 9439 mutex_exit(&mpt->m_mutex); 9440 return (rval); 9441 } 9442 9443 static int 9444 mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, struct scsi_pkt *pkt) 9445 { 9446 mptsas_cmd_t *sp = NULL; 9447 mptsas_slots_t *slots = mpt->m_active; 9448 int rval = FALSE; 9449 9450 ASSERT(mutex_owned(&mpt->m_mutex)); 9451 9452 /* 9453 * Abort the command pkt on the target/lun in ap. If pkt is 9454 * NULL, abort all outstanding commands on that target/lun. 9455 * If you can abort them, return 1, else return 0. 9456 * Each packet that's aborted should be sent back to the target 9457 * driver through the callback routine, with pkt_reason set to 9458 * CMD_ABORTED. 9459 * 9460 * abort cmd pkt on HBA hardware; clean out of outstanding 9461 * command lists, etc. 9462 */ 9463 if (pkt != NULL) { 9464 /* abort the specified packet */ 9465 sp = PKT2CMD(pkt); 9466 9467 if (sp->cmd_queued) { 9468 NDBG23(("mptsas_do_scsi_abort: queued sp=0x%p aborted", 9469 (void *)sp)); 9470 mptsas_waitq_delete(mpt, sp); 9471 mptsas_set_pkt_reason(mpt, sp, CMD_ABORTED, 9472 STAT_ABORTED); 9473 mptsas_doneq_add(mpt, sp); 9474 rval = TRUE; 9475 goto done; 9476 } 9477 9478 /* 9479 * Have mpt firmware abort this command 9480 */ 9481 mutex_enter(&mpt->m_intr_mutex); 9482 if (slots->m_slot[sp->cmd_slot] != NULL) { 9483 mutex_exit(&mpt->m_intr_mutex); 9484 rval = mptsas_ioc_task_management(mpt, 9485 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, target, 9486 lun, NULL, 0, 0); 9487 9488 /* 9489 * The transport layer expects only TRUE and FALSE. 9490 * Therefore, if mptsas_ioc_task_management returns 9491 * FAILED we will return FALSE. 9492 */ 9493 if (rval == FAILED) 9494 rval = FALSE; 9495 goto done; 9496 } 9497 mutex_exit(&mpt->m_intr_mutex); 9498 } 9499 9500 /* 9501 * If pkt is NULL then abort task set 9502 */ 9503 rval = mptsas_ioc_task_management(mpt, 9504 MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, target, lun, NULL, 0, 0); 9505 9506 /* 9507 * The transport layer expects only TRUE and FALSE. 9508 * Therefore, if mptsas_ioc_task_management returns 9509 * FAILED we will return FALSE. 9510 */ 9511 if (rval == FAILED) 9512 rval = FALSE; 9513 9514 #ifdef MPTSAS_TEST 9515 if (rval && mptsas_test_stop) { 9516 debug_enter("mptsas_do_scsi_abort"); 9517 } 9518 #endif 9519 9520 done: 9521 mptsas_doneq_empty(mpt); 9522 return (rval); 9523 } 9524 9525 /* 9526 * capability handling: 9527 * (*tran_getcap). Get the capability named, and return its value. 9528 */ 9529 static int 9530 mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly) 9531 { 9532 mptsas_t *mpt = ADDR2MPT(ap); 9533 int ckey; 9534 int rval = FALSE; 9535 9536 NDBG24(("mptsas_scsi_getcap: target=%d, cap=%s tgtonly=%x", 9537 ap->a_target, cap, tgtonly)); 9538 9539 mutex_enter(&mpt->m_mutex); 9540 9541 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) { 9542 mutex_exit(&mpt->m_mutex); 9543 return (UNDEFINED); 9544 } 9545 9546 switch (ckey) { 9547 case SCSI_CAP_DMA_MAX: 9548 rval = (int)mpt->m_msg_dma_attr.dma_attr_maxxfer; 9549 break; 9550 case SCSI_CAP_ARQ: 9551 rval = TRUE; 9552 break; 9553 case SCSI_CAP_MSG_OUT: 9554 case SCSI_CAP_PARITY: 9555 case SCSI_CAP_UNTAGGED_QING: 9556 rval = TRUE; 9557 break; 9558 case SCSI_CAP_TAGGED_QING: 9559 rval = TRUE; 9560 break; 9561 case SCSI_CAP_RESET_NOTIFICATION: 9562 rval = TRUE; 9563 break; 9564 case SCSI_CAP_LINKED_CMDS: 9565 rval = FALSE; 9566 break; 9567 case SCSI_CAP_QFULL_RETRIES: 9568 rval = ((mptsas_tgt_private_t *)(ap->a_hba_tran-> 9569 tran_tgt_private))->t_private->m_qfull_retries; 9570 break; 9571 case SCSI_CAP_QFULL_RETRY_INTERVAL: 9572 rval = drv_hztousec(((mptsas_tgt_private_t *) 9573 (ap->a_hba_tran->tran_tgt_private))-> 9574 t_private->m_qfull_retry_interval) / 1000; 9575 break; 9576 case SCSI_CAP_CDB_LEN: 9577 rval = CDB_GROUP4; 9578 break; 9579 case SCSI_CAP_INTERCONNECT_TYPE: 9580 rval = INTERCONNECT_SAS; 9581 break; 9582 case SCSI_CAP_TRAN_LAYER_RETRIES: 9583 if (mpt->m_ioc_capabilities & 9584 MPI2_IOCFACTS_CAPABILITY_TLR) 9585 rval = TRUE; 9586 else 9587 rval = FALSE; 9588 break; 9589 default: 9590 rval = UNDEFINED; 9591 break; 9592 } 9593 9594 NDBG24(("mptsas_scsi_getcap: %s, rval=%x", cap, rval)); 9595 9596 mutex_exit(&mpt->m_mutex); 9597 return (rval); 9598 } 9599 9600 /* 9601 * (*tran_setcap). Set the capability named to the value given. 9602 */ 9603 static int 9604 mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, int tgtonly) 9605 { 9606 mptsas_t *mpt = ADDR2MPT(ap); 9607 int ckey; 9608 int rval = FALSE; 9609 mptsas_target_t *ptgt; 9610 9611 NDBG24(("mptsas_scsi_setcap: target=%d, cap=%s value=%x tgtonly=%x", 9612 ap->a_target, cap, value, tgtonly)); 9613 9614 if (!tgtonly) { 9615 return (rval); 9616 } 9617 9618 mutex_enter(&mpt->m_mutex); 9619 9620 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) { 9621 mutex_exit(&mpt->m_mutex); 9622 return (UNDEFINED); 9623 } 9624 9625 switch (ckey) { 9626 case SCSI_CAP_DMA_MAX: 9627 case SCSI_CAP_MSG_OUT: 9628 case SCSI_CAP_PARITY: 9629 case SCSI_CAP_INITIATOR_ID: 9630 case SCSI_CAP_LINKED_CMDS: 9631 case SCSI_CAP_UNTAGGED_QING: 9632 case SCSI_CAP_RESET_NOTIFICATION: 9633 /* 9634 * None of these are settable via 9635 * the capability interface. 9636 */ 9637 break; 9638 case SCSI_CAP_ARQ: 9639 /* 9640 * We cannot turn off arq so return false if asked to 9641 */ 9642 if (value) { 9643 rval = TRUE; 9644 } else { 9645 rval = FALSE; 9646 } 9647 break; 9648 case SCSI_CAP_TAGGED_QING: 9649 ptgt = ((mptsas_tgt_private_t *) 9650 (ap->a_hba_tran->tran_tgt_private))->t_private; 9651 mutex_enter(&ptgt->m_tgt_intr_mutex); 9652 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 9653 mutex_exit(&ptgt->m_tgt_intr_mutex); 9654 rval = TRUE; 9655 break; 9656 case SCSI_CAP_QFULL_RETRIES: 9657 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))-> 9658 t_private->m_qfull_retries = (uchar_t)value; 9659 rval = TRUE; 9660 break; 9661 case SCSI_CAP_QFULL_RETRY_INTERVAL: 9662 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))-> 9663 t_private->m_qfull_retry_interval = 9664 drv_usectohz(value * 1000); 9665 rval = TRUE; 9666 break; 9667 default: 9668 rval = UNDEFINED; 9669 break; 9670 } 9671 mutex_exit(&mpt->m_mutex); 9672 return (rval); 9673 } 9674 9675 /* 9676 * Utility routine for mptsas_ifsetcap/ifgetcap 9677 */ 9678 /*ARGSUSED*/ 9679 static int 9680 mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp) 9681 { 9682 NDBG24(("mptsas_scsi_capchk: cap=%s", cap)); 9683 9684 if (!cap) 9685 return (FALSE); 9686 9687 *cidxp = scsi_hba_lookup_capstr(cap); 9688 return (TRUE); 9689 } 9690 9691 static int 9692 mptsas_alloc_active_slots(mptsas_t *mpt, int flag) 9693 { 9694 mptsas_slots_t *old_active = mpt->m_active; 9695 mptsas_slots_t *new_active; 9696 size_t size; 9697 int rval = -1, nslot, i; 9698 mptsas_slot_free_e_t *pe; 9699 9700 if (mptsas_outstanding_cmds_n(mpt)) { 9701 NDBG9(("cannot change size of active slots array")); 9702 return (rval); 9703 } 9704 9705 size = MPTSAS_SLOTS_SIZE(mpt); 9706 new_active = kmem_zalloc(size, flag); 9707 if (new_active == NULL) { 9708 NDBG1(("new active alloc failed")); 9709 return (rval); 9710 } 9711 /* 9712 * Since SMID 0 is reserved and the TM slot is reserved, the 9713 * number of slots that can be used at any one time is 9714 * m_max_requests - 2. 9715 */ 9716 new_active->m_n_slots = nslot = (mpt->m_max_requests - 2); 9717 new_active->m_size = size; 9718 new_active->m_tags = 1; 9719 9720 if (old_active) { 9721 new_active->m_tgttbl = old_active->m_tgttbl; 9722 new_active->m_smptbl = old_active->m_smptbl; 9723 new_active->m_num_raid_configs = 9724 old_active->m_num_raid_configs; 9725 for (i = 0; i < new_active->m_num_raid_configs; i++) { 9726 new_active->m_raidconfig[i] = 9727 old_active->m_raidconfig[i]; 9728 } 9729 mptsas_free_active_slots(mpt); 9730 } 9731 9732 if (max_ncpus & (max_ncpus - 1)) { 9733 mpt->m_slot_freeq_pair_n = (1 << highbit(max_ncpus)); 9734 } else { 9735 mpt->m_slot_freeq_pair_n = max_ncpus; 9736 } 9737 mpt->m_slot_freeq_pairp = kmem_zalloc( 9738 mpt->m_slot_freeq_pair_n * 9739 sizeof (mptsas_slot_freeq_pair_t), KM_SLEEP); 9740 for (i = 0; i < mpt->m_slot_freeq_pair_n; i++) { 9741 list_create(&mpt->m_slot_freeq_pairp[i]. 9742 m_slot_allocq.s.m_fq_list, 9743 sizeof (mptsas_slot_free_e_t), 9744 offsetof(mptsas_slot_free_e_t, node)); 9745 list_create(&mpt->m_slot_freeq_pairp[i]. 9746 m_slot_releq.s.m_fq_list, 9747 sizeof (mptsas_slot_free_e_t), 9748 offsetof(mptsas_slot_free_e_t, node)); 9749 mpt->m_slot_freeq_pairp[i].m_slot_allocq.s.m_fq_n = 0; 9750 mpt->m_slot_freeq_pairp[i].m_slot_releq.s.m_fq_n = 0; 9751 mutex_init(&mpt->m_slot_freeq_pairp[i]. 9752 m_slot_allocq.s.m_fq_mutex, NULL, MUTEX_DRIVER, 9753 DDI_INTR_PRI(mpt->m_intr_pri)); 9754 mutex_init(&mpt->m_slot_freeq_pairp[i]. 9755 m_slot_releq.s.m_fq_mutex, NULL, MUTEX_DRIVER, 9756 DDI_INTR_PRI(mpt->m_intr_pri)); 9757 } 9758 pe = mpt->m_slot_free_ae = kmem_zalloc(nslot * 9759 sizeof (mptsas_slot_free_e_t), KM_SLEEP); 9760 /* 9761 * An array of Mpi2ReplyDescriptorsUnion_t is defined here. 9762 * We are trying to eliminate the m_mutex in the context 9763 * reply code path in the ISR. Since the read of the 9764 * ReplyDescriptor and update/write of the ReplyIndex must 9765 * be atomic (since the poll thread may also update them at 9766 * the same time) so we first read out of the ReplyDescriptor 9767 * into this array and update the ReplyIndex register with a 9768 * separate mutex m_intr_mutex protected, and then release the 9769 * mutex and process all of them. the length of the array is 9770 * defined as max as 128(128*64=8k), which is 9771 * assumed as the maxmium depth of the interrupt coalese. 9772 */ 9773 mpt->m_reply = kmem_zalloc(MPI_ADDRESS_COALSCE_MAX * 9774 sizeof (Mpi2ReplyDescriptorsUnion_t), KM_SLEEP); 9775 for (i = 0; i < nslot; i++, pe++) { 9776 pe->slot = i + 1; /* SMID 0 is reserved */ 9777 pe->cpuid = i % mpt->m_slot_freeq_pair_n; 9778 list_insert_tail(&mpt->m_slot_freeq_pairp 9779 [i % mpt->m_slot_freeq_pair_n] 9780 .m_slot_allocq.s.m_fq_list, pe); 9781 mpt->m_slot_freeq_pairp[i % mpt->m_slot_freeq_pair_n] 9782 .m_slot_allocq.s.m_fq_n++; 9783 mpt->m_slot_freeq_pairp[i % mpt->m_slot_freeq_pair_n] 9784 .m_slot_allocq.s.m_fq_n_init++; 9785 } 9786 9787 mpt->m_active = new_active; 9788 rval = 0; 9789 9790 return (rval); 9791 } 9792 9793 static void 9794 mptsas_free_active_slots(mptsas_t *mpt) 9795 { 9796 mptsas_slots_t *active = mpt->m_active; 9797 size_t size; 9798 mptsas_slot_free_e_t *pe; 9799 int i; 9800 9801 if (active == NULL) 9802 return; 9803 9804 if (mpt->m_slot_freeq_pairp) { 9805 for (i = 0; i < mpt->m_slot_freeq_pair_n; i++) { 9806 while ((pe = list_head(&mpt->m_slot_freeq_pairp 9807 [i].m_slot_allocq.s.m_fq_list)) != NULL) { 9808 list_remove(&mpt->m_slot_freeq_pairp[i] 9809 .m_slot_allocq.s.m_fq_list, pe); 9810 } 9811 list_destroy(&mpt->m_slot_freeq_pairp 9812 [i].m_slot_allocq.s.m_fq_list); 9813 while ((pe = list_head(&mpt->m_slot_freeq_pairp 9814 [i].m_slot_releq.s.m_fq_list)) != NULL) { 9815 list_remove(&mpt->m_slot_freeq_pairp[i] 9816 .m_slot_releq.s.m_fq_list, pe); 9817 } 9818 list_destroy(&mpt->m_slot_freeq_pairp 9819 [i].m_slot_releq.s.m_fq_list); 9820 mutex_destroy(&mpt->m_slot_freeq_pairp 9821 [i].m_slot_allocq.s.m_fq_mutex); 9822 mutex_destroy(&mpt->m_slot_freeq_pairp 9823 [i].m_slot_releq.s.m_fq_mutex); 9824 } 9825 kmem_free(mpt->m_slot_freeq_pairp, mpt->m_slot_freeq_pair_n * 9826 sizeof (mptsas_slot_freeq_pair_t)); 9827 } 9828 if (mpt->m_slot_free_ae) 9829 kmem_free(mpt->m_slot_free_ae, mpt->m_active->m_n_slots * 9830 sizeof (mptsas_slot_free_e_t)); 9831 9832 if (mpt->m_reply) 9833 kmem_free(mpt->m_reply, MPI_ADDRESS_COALSCE_MAX * 9834 sizeof (Mpi2ReplyDescriptorsUnion_t)); 9835 9836 size = active->m_size; 9837 kmem_free(active, size); 9838 mpt->m_active = NULL; 9839 } 9840 9841 /* 9842 * Error logging, printing, and debug print routines. 9843 */ 9844 static char *mptsas_label = "mpt_sas"; 9845 9846 /*PRINTFLIKE3*/ 9847 void 9848 mptsas_log(mptsas_t *mpt, int level, char *fmt, ...) 9849 { 9850 dev_info_t *dev; 9851 va_list ap; 9852 9853 if (mpt) { 9854 dev = mpt->m_dip; 9855 } else { 9856 dev = 0; 9857 } 9858 9859 mutex_enter(&mptsas_log_mutex); 9860 9861 va_start(ap, fmt); 9862 (void) vsprintf(mptsas_log_buf, fmt, ap); 9863 va_end(ap); 9864 9865 if (level == CE_CONT) { 9866 scsi_log(dev, mptsas_label, level, "%s\n", mptsas_log_buf); 9867 } else { 9868 scsi_log(dev, mptsas_label, level, "%s", mptsas_log_buf); 9869 } 9870 9871 mutex_exit(&mptsas_log_mutex); 9872 } 9873 9874 #ifdef MPTSAS_DEBUG 9875 /*PRINTFLIKE1*/ 9876 void 9877 mptsas_printf(char *fmt, ...) 9878 { 9879 dev_info_t *dev = 0; 9880 va_list ap; 9881 9882 mutex_enter(&mptsas_log_mutex); 9883 9884 va_start(ap, fmt); 9885 (void) vsprintf(mptsas_log_buf, fmt, ap); 9886 va_end(ap); 9887 9888 #ifdef PROM_PRINTF 9889 prom_printf("%s:\t%s\n", mptsas_label, mptsas_log_buf); 9890 #else 9891 scsi_log(dev, mptsas_label, SCSI_DEBUG, "%s\n", mptsas_log_buf); 9892 #endif 9893 mutex_exit(&mptsas_log_mutex); 9894 } 9895 #endif 9896 9897 /* 9898 * timeout handling 9899 */ 9900 static void 9901 mptsas_watch(void *arg) 9902 { 9903 #ifndef __lock_lint 9904 _NOTE(ARGUNUSED(arg)) 9905 #endif 9906 9907 mptsas_t *mpt; 9908 uint32_t doorbell; 9909 9910 NDBG30(("mptsas_watch")); 9911 9912 rw_enter(&mptsas_global_rwlock, RW_READER); 9913 for (mpt = mptsas_head; mpt != (mptsas_t *)NULL; mpt = mpt->m_next) { 9914 9915 mutex_enter(&mpt->m_mutex); 9916 9917 /* Skip device if not powered on */ 9918 if (mpt->m_options & MPTSAS_OPT_PM) { 9919 if (mpt->m_power_level == PM_LEVEL_D0) { 9920 (void) pm_busy_component(mpt->m_dip, 0); 9921 mpt->m_busy = 1; 9922 } else { 9923 mutex_exit(&mpt->m_mutex); 9924 continue; 9925 } 9926 } 9927 9928 /* 9929 * Check if controller is in a FAULT state. If so, reset it. 9930 */ 9931 doorbell = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell); 9932 if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { 9933 doorbell &= MPI2_DOORBELL_DATA_MASK; 9934 mptsas_log(mpt, CE_WARN, "MPT Firmware Fault, " 9935 "code: %04x", doorbell); 9936 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 9937 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 9938 mptsas_log(mpt, CE_WARN, "Reset failed" 9939 "after fault was detected"); 9940 } 9941 } 9942 9943 /* 9944 * For now, always call mptsas_watchsubr. 9945 */ 9946 mptsas_watchsubr(mpt); 9947 9948 if (mpt->m_options & MPTSAS_OPT_PM) { 9949 mpt->m_busy = 0; 9950 (void) pm_idle_component(mpt->m_dip, 0); 9951 } 9952 9953 mutex_exit(&mpt->m_mutex); 9954 } 9955 rw_exit(&mptsas_global_rwlock); 9956 9957 mutex_enter(&mptsas_global_mutex); 9958 if (mptsas_timeouts_enabled) 9959 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick); 9960 mutex_exit(&mptsas_global_mutex); 9961 } 9962 9963 static void 9964 mptsas_watchsubr(mptsas_t *mpt) 9965 { 9966 int i; 9967 mptsas_cmd_t *cmd; 9968 mptsas_target_t *ptgt = NULL; 9969 9970 NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt)); 9971 9972 #ifdef MPTSAS_TEST 9973 if (mptsas_enable_untagged) { 9974 mptsas_test_untagged++; 9975 } 9976 #endif 9977 9978 /* 9979 * Check for commands stuck in active slot 9980 * Account for TM requests, which use the last SMID. 9981 */ 9982 mutex_enter(&mpt->m_intr_mutex); 9983 for (i = 0; i <= mpt->m_active->m_n_slots; i++) { 9984 if ((cmd = mpt->m_active->m_slot[i]) != NULL) { 9985 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 9986 cmd->cmd_active_timeout -= 9987 mptsas_scsi_watchdog_tick; 9988 if (cmd->cmd_active_timeout <= 0) { 9989 /* 9990 * There seems to be a command stuck 9991 * in the active slot. Drain throttle. 9992 */ 9993 ptgt = cmd->cmd_tgt_addr; 9994 mutex_enter(&ptgt->m_tgt_intr_mutex); 9995 mptsas_set_throttle(mpt, ptgt, 9996 DRAIN_THROTTLE); 9997 mutex_exit(&ptgt->m_tgt_intr_mutex); 9998 } 9999 } 10000 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 10001 (cmd->cmd_flags & CFLAG_CONFIG) || 10002 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 10003 cmd->cmd_active_timeout -= 10004 mptsas_scsi_watchdog_tick; 10005 if (cmd->cmd_active_timeout <= 0) { 10006 /* 10007 * passthrough command timeout 10008 */ 10009 cmd->cmd_flags |= (CFLAG_FINISHED | 10010 CFLAG_TIMEOUT); 10011 cv_broadcast(&mpt->m_passthru_cv); 10012 cv_broadcast(&mpt->m_config_cv); 10013 cv_broadcast(&mpt->m_fw_diag_cv); 10014 } 10015 } 10016 } 10017 } 10018 mutex_exit(&mpt->m_intr_mutex); 10019 10020 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 10021 MPTSAS_HASH_FIRST); 10022 while (ptgt != NULL) { 10023 /* 10024 * In order to avoid using m_mutex in the key code path in ISR, 10025 * separate mutexs are introduced to protect those elements 10026 * shown in ISR. 10027 */ 10028 mutex_enter(&ptgt->m_tgt_intr_mutex); 10029 10030 /* 10031 * If we were draining due to a qfull condition, 10032 * go back to full throttle. 10033 */ 10034 if ((ptgt->m_t_throttle < MAX_THROTTLE) && 10035 (ptgt->m_t_throttle > HOLD_THROTTLE) && 10036 (ptgt->m_t_ncmds < ptgt->m_t_throttle)) { 10037 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 10038 mptsas_restart_hba(mpt); 10039 } 10040 10041 if ((ptgt->m_t_ncmds > 0) && 10042 (ptgt->m_timebase)) { 10043 10044 if (ptgt->m_timebase <= 10045 mptsas_scsi_watchdog_tick) { 10046 ptgt->m_timebase += 10047 mptsas_scsi_watchdog_tick; 10048 mutex_exit(&ptgt->m_tgt_intr_mutex); 10049 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10050 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 10051 continue; 10052 } 10053 10054 ptgt->m_timeout -= mptsas_scsi_watchdog_tick; 10055 10056 if (ptgt->m_timeout < 0) { 10057 mutex_exit(&ptgt->m_tgt_intr_mutex); 10058 mptsas_cmd_timeout(mpt, ptgt->m_devhdl); 10059 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10060 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 10061 continue; 10062 } 10063 10064 if ((ptgt->m_timeout) <= 10065 mptsas_scsi_watchdog_tick) { 10066 NDBG23(("pending timeout")); 10067 mptsas_set_throttle(mpt, ptgt, 10068 DRAIN_THROTTLE); 10069 } 10070 } 10071 mutex_exit(&ptgt->m_tgt_intr_mutex); 10072 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10073 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 10074 } 10075 } 10076 10077 /* 10078 * timeout recovery 10079 */ 10080 static void 10081 mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl) 10082 { 10083 10084 NDBG29(("mptsas_cmd_timeout: target=%d", devhdl)); 10085 mptsas_log(mpt, CE_WARN, "Disconnected command timeout for " 10086 "Target %d", devhdl); 10087 10088 /* 10089 * If the current target is not the target passed in, 10090 * try to reset that target. 10091 */ 10092 NDBG29(("mptsas_cmd_timeout: device reset")); 10093 if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) { 10094 mptsas_log(mpt, CE_WARN, "Target %d reset for command timeout " 10095 "recovery failed!", devhdl); 10096 } 10097 } 10098 10099 /* 10100 * Device / Hotplug control 10101 */ 10102 static int 10103 mptsas_scsi_quiesce(dev_info_t *dip) 10104 { 10105 mptsas_t *mpt; 10106 scsi_hba_tran_t *tran; 10107 10108 tran = ddi_get_driver_private(dip); 10109 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL) 10110 return (-1); 10111 10112 return (mptsas_quiesce_bus(mpt)); 10113 } 10114 10115 static int 10116 mptsas_scsi_unquiesce(dev_info_t *dip) 10117 { 10118 mptsas_t *mpt; 10119 scsi_hba_tran_t *tran; 10120 10121 tran = ddi_get_driver_private(dip); 10122 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL) 10123 return (-1); 10124 10125 return (mptsas_unquiesce_bus(mpt)); 10126 } 10127 10128 static int 10129 mptsas_quiesce_bus(mptsas_t *mpt) 10130 { 10131 mptsas_target_t *ptgt = NULL; 10132 10133 NDBG28(("mptsas_quiesce_bus")); 10134 mutex_enter(&mpt->m_mutex); 10135 10136 /* Set all the throttles to zero */ 10137 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 10138 MPTSAS_HASH_FIRST); 10139 while (ptgt != NULL) { 10140 mutex_enter(&ptgt->m_tgt_intr_mutex); 10141 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 10142 mutex_exit(&ptgt->m_tgt_intr_mutex); 10143 10144 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10145 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 10146 } 10147 10148 /* If there are any outstanding commands in the queue */ 10149 mutex_enter(&mpt->m_intr_mutex); 10150 if (mptsas_outstanding_cmds_n(mpt)) { 10151 mutex_exit(&mpt->m_intr_mutex); 10152 mpt->m_softstate |= MPTSAS_SS_DRAINING; 10153 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain, 10154 mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000))); 10155 if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) { 10156 /* 10157 * Quiesce has been interrupted 10158 */ 10159 mpt->m_softstate &= ~MPTSAS_SS_DRAINING; 10160 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10161 &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST); 10162 while (ptgt != NULL) { 10163 mutex_enter(&ptgt->m_tgt_intr_mutex); 10164 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 10165 mutex_exit(&ptgt->m_tgt_intr_mutex); 10166 10167 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10168 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 10169 } 10170 mptsas_restart_hba(mpt); 10171 if (mpt->m_quiesce_timeid != 0) { 10172 timeout_id_t tid = mpt->m_quiesce_timeid; 10173 mpt->m_quiesce_timeid = 0; 10174 mutex_exit(&mpt->m_mutex); 10175 (void) untimeout(tid); 10176 return (-1); 10177 } 10178 mutex_exit(&mpt->m_mutex); 10179 return (-1); 10180 } else { 10181 /* Bus has been quiesced */ 10182 ASSERT(mpt->m_quiesce_timeid == 0); 10183 mpt->m_softstate &= ~MPTSAS_SS_DRAINING; 10184 mpt->m_softstate |= MPTSAS_SS_QUIESCED; 10185 mutex_exit(&mpt->m_mutex); 10186 return (0); 10187 } 10188 } 10189 mutex_exit(&mpt->m_intr_mutex); 10190 /* Bus was not busy - QUIESCED */ 10191 mutex_exit(&mpt->m_mutex); 10192 10193 return (0); 10194 } 10195 10196 static int 10197 mptsas_unquiesce_bus(mptsas_t *mpt) 10198 { 10199 mptsas_target_t *ptgt = NULL; 10200 10201 NDBG28(("mptsas_unquiesce_bus")); 10202 mutex_enter(&mpt->m_mutex); 10203 mpt->m_softstate &= ~MPTSAS_SS_QUIESCED; 10204 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 10205 MPTSAS_HASH_FIRST); 10206 while (ptgt != NULL) { 10207 mutex_enter(&ptgt->m_tgt_intr_mutex); 10208 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 10209 mutex_exit(&ptgt->m_tgt_intr_mutex); 10210 10211 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10212 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 10213 } 10214 mptsas_restart_hba(mpt); 10215 mutex_exit(&mpt->m_mutex); 10216 return (0); 10217 } 10218 10219 static void 10220 mptsas_ncmds_checkdrain(void *arg) 10221 { 10222 mptsas_t *mpt = arg; 10223 mptsas_target_t *ptgt = NULL; 10224 10225 mutex_enter(&mpt->m_mutex); 10226 if (mpt->m_softstate & MPTSAS_SS_DRAINING) { 10227 mpt->m_quiesce_timeid = 0; 10228 mutex_enter(&mpt->m_intr_mutex); 10229 if (mptsas_outstanding_cmds_n(mpt)) { 10230 mutex_exit(&mpt->m_intr_mutex); 10231 /* 10232 * The throttle may have been reset because 10233 * of a SCSI bus reset 10234 */ 10235 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10236 &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST); 10237 while (ptgt != NULL) { 10238 mutex_enter(&ptgt->m_tgt_intr_mutex); 10239 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 10240 mutex_exit(&ptgt->m_tgt_intr_mutex); 10241 10242 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10243 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 10244 } 10245 10246 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain, 10247 mpt, (MPTSAS_QUIESCE_TIMEOUT * 10248 drv_usectohz(1000000))); 10249 } else { 10250 mutex_exit(&mpt->m_intr_mutex); 10251 /* Command queue has been drained */ 10252 cv_signal(&mpt->m_cv); 10253 } 10254 } 10255 mutex_exit(&mpt->m_mutex); 10256 } 10257 10258 /*ARGSUSED*/ 10259 static void 10260 mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 10261 { 10262 int i; 10263 uint8_t *cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp; 10264 char buf[128]; 10265 10266 buf[0] = '\0'; 10267 NDBG25(("?Cmd (0x%p) dump for Target %d Lun %d:\n", (void *)cmd, 10268 Tgt(cmd), Lun(cmd))); 10269 (void) sprintf(&buf[0], "\tcdb=["); 10270 for (i = 0; i < (int)cmd->cmd_cdblen; i++) { 10271 (void) sprintf(&buf[strlen(buf)], " 0x%x", *cp++); 10272 } 10273 (void) sprintf(&buf[strlen(buf)], " ]"); 10274 NDBG25(("?%s\n", buf)); 10275 NDBG25(("?pkt_flags=0x%x pkt_statistics=0x%x pkt_state=0x%x\n", 10276 cmd->cmd_pkt->pkt_flags, cmd->cmd_pkt->pkt_statistics, 10277 cmd->cmd_pkt->pkt_state)); 10278 NDBG25(("?pkt_scbp=0x%x cmd_flags=0x%x\n", cmd->cmd_pkt->pkt_scbp ? 10279 *(cmd->cmd_pkt->pkt_scbp) : 0, cmd->cmd_flags)); 10280 } 10281 10282 static void 10283 mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd) 10284 { 10285 caddr_t memp; 10286 pMPI2RequestHeader_t request_hdrp; 10287 struct scsi_pkt *pkt = cmd->cmd_pkt; 10288 mptsas_pt_request_t *pt = pkt->pkt_ha_private; 10289 uint32_t request_size, data_size, dataout_size; 10290 uint32_t direction; 10291 ddi_dma_cookie_t data_cookie; 10292 ddi_dma_cookie_t dataout_cookie; 10293 uint32_t request_desc_low, request_desc_high = 0; 10294 uint32_t i, sense_bufp; 10295 uint8_t desc_type; 10296 uint8_t *request, function; 10297 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; 10298 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl; 10299 10300 desc_type = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 10301 10302 request = pt->request; 10303 direction = pt->direction; 10304 request_size = pt->request_size; 10305 data_size = pt->data_size; 10306 dataout_size = pt->dataout_size; 10307 data_cookie = pt->data_cookie; 10308 dataout_cookie = pt->dataout_cookie; 10309 10310 /* 10311 * Store the passthrough message in memory location 10312 * corresponding to our slot number 10313 */ 10314 memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot); 10315 request_hdrp = (pMPI2RequestHeader_t)memp; 10316 bzero(memp, mpt->m_req_frame_size); 10317 10318 for (i = 0; i < request_size; i++) { 10319 bcopy(request + i, memp + i, 1); 10320 } 10321 10322 if (data_size || dataout_size) { 10323 pMpi2SGESimple64_t sgep; 10324 uint32_t sge_flags; 10325 10326 sgep = (pMpi2SGESimple64_t)((uint8_t *)request_hdrp + 10327 request_size); 10328 if (dataout_size) { 10329 10330 sge_flags = dataout_size | 10331 ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 10332 MPI2_SGE_FLAGS_END_OF_BUFFER | 10333 MPI2_SGE_FLAGS_HOST_TO_IOC | 10334 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 10335 MPI2_SGE_FLAGS_SHIFT); 10336 ddi_put32(acc_hdl, &sgep->FlagsLength, sge_flags); 10337 ddi_put32(acc_hdl, &sgep->Address.Low, 10338 (uint32_t)(dataout_cookie.dmac_laddress & 10339 0xffffffffull)); 10340 ddi_put32(acc_hdl, &sgep->Address.High, 10341 (uint32_t)(dataout_cookie.dmac_laddress 10342 >> 32)); 10343 sgep++; 10344 } 10345 sge_flags = data_size; 10346 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 10347 MPI2_SGE_FLAGS_LAST_ELEMENT | 10348 MPI2_SGE_FLAGS_END_OF_BUFFER | 10349 MPI2_SGE_FLAGS_END_OF_LIST | 10350 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 10351 MPI2_SGE_FLAGS_SHIFT); 10352 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) { 10353 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_HOST_TO_IOC) << 10354 MPI2_SGE_FLAGS_SHIFT); 10355 } else { 10356 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_IOC_TO_HOST) << 10357 MPI2_SGE_FLAGS_SHIFT); 10358 } 10359 ddi_put32(acc_hdl, &sgep->FlagsLength, 10360 sge_flags); 10361 ddi_put32(acc_hdl, &sgep->Address.Low, 10362 (uint32_t)(data_cookie.dmac_laddress & 10363 0xffffffffull)); 10364 ddi_put32(acc_hdl, &sgep->Address.High, 10365 (uint32_t)(data_cookie.dmac_laddress >> 32)); 10366 } 10367 10368 function = request_hdrp->Function; 10369 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) || 10370 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 10371 pMpi2SCSIIORequest_t scsi_io_req; 10372 10373 scsi_io_req = (pMpi2SCSIIORequest_t)request_hdrp; 10374 /* 10375 * Put SGE for data and data_out buffer at the end of 10376 * scsi_io_request message header.(64 bytes in total) 10377 * Following above SGEs, the residual space will be 10378 * used by sense data. 10379 */ 10380 ddi_put8(acc_hdl, 10381 &scsi_io_req->SenseBufferLength, 10382 (uint8_t)(request_size - 64)); 10383 10384 sense_bufp = mpt->m_req_frame_dma_addr + 10385 (mpt->m_req_frame_size * cmd->cmd_slot); 10386 sense_bufp += 64; 10387 ddi_put32(acc_hdl, 10388 &scsi_io_req->SenseBufferLowAddress, sense_bufp); 10389 10390 /* 10391 * Set SGLOffset0 value 10392 */ 10393 ddi_put8(acc_hdl, &scsi_io_req->SGLOffset0, 10394 offsetof(MPI2_SCSI_IO_REQUEST, SGL) / 4); 10395 10396 /* 10397 * Setup descriptor info. RAID passthrough must use the 10398 * default request descriptor which is already set, so if this 10399 * is a SCSI IO request, change the descriptor to SCSI IO. 10400 */ 10401 if (function == MPI2_FUNCTION_SCSI_IO_REQUEST) { 10402 desc_type = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 10403 request_desc_high = (ddi_get16(acc_hdl, 10404 &scsi_io_req->DevHandle) << 16); 10405 } 10406 } 10407 10408 /* 10409 * We must wait till the message has been completed before 10410 * beginning the next message so we wait for this one to 10411 * finish. 10412 */ 10413 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 10414 request_desc_low = (cmd->cmd_slot << 16) + desc_type; 10415 cmd->cmd_rfm = NULL; 10416 mpt->m_active->m_slot[cmd->cmd_slot] = cmd; 10417 MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high); 10418 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || 10419 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { 10420 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 10421 } 10422 } 10423 10424 10425 10426 static int 10427 mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply, 10428 uint8_t *data, uint32_t request_size, uint32_t reply_size, 10429 uint32_t data_size, uint32_t direction, uint8_t *dataout, 10430 uint32_t dataout_size, short timeout, int mode) 10431 { 10432 mptsas_pt_request_t pt; 10433 mptsas_dma_alloc_state_t data_dma_state; 10434 mptsas_dma_alloc_state_t dataout_dma_state; 10435 caddr_t memp; 10436 mptsas_cmd_t *cmd = NULL; 10437 struct scsi_pkt *pkt; 10438 uint32_t reply_len = 0, sense_len = 0; 10439 pMPI2RequestHeader_t request_hdrp; 10440 pMPI2RequestHeader_t request_msg; 10441 pMPI2DefaultReply_t reply_msg; 10442 Mpi2SCSIIOReply_t rep_msg; 10443 int i, status = 0, pt_flags = 0, rv = 0; 10444 int rvalue; 10445 uint8_t function; 10446 10447 ASSERT(mutex_owned(&mpt->m_mutex)); 10448 10449 reply_msg = (pMPI2DefaultReply_t)(&rep_msg); 10450 bzero(reply_msg, sizeof (MPI2_DEFAULT_REPLY)); 10451 request_msg = kmem_zalloc(request_size, KM_SLEEP); 10452 10453 mutex_exit(&mpt->m_mutex); 10454 /* 10455 * copy in the request buffer since it could be used by 10456 * another thread when the pt request into waitq 10457 */ 10458 if (ddi_copyin(request, request_msg, request_size, mode)) { 10459 mutex_enter(&mpt->m_mutex); 10460 status = EFAULT; 10461 mptsas_log(mpt, CE_WARN, "failed to copy request data"); 10462 goto out; 10463 } 10464 mutex_enter(&mpt->m_mutex); 10465 10466 function = request_msg->Function; 10467 if (function == MPI2_FUNCTION_SCSI_TASK_MGMT) { 10468 pMpi2SCSITaskManagementRequest_t task; 10469 task = (pMpi2SCSITaskManagementRequest_t)request_msg; 10470 mptsas_setup_bus_reset_delay(mpt); 10471 rv = mptsas_ioc_task_management(mpt, task->TaskType, 10472 task->DevHandle, (int)task->LUN[1], reply, reply_size, 10473 mode); 10474 10475 if (rv != TRUE) { 10476 status = EIO; 10477 mptsas_log(mpt, CE_WARN, "task management failed"); 10478 } 10479 goto out; 10480 } 10481 10482 if (data_size != 0) { 10483 data_dma_state.size = data_size; 10484 if (mptsas_dma_alloc(mpt, &data_dma_state) != DDI_SUCCESS) { 10485 status = ENOMEM; 10486 mptsas_log(mpt, CE_WARN, "failed to alloc DMA " 10487 "resource"); 10488 goto out; 10489 } 10490 pt_flags |= MPTSAS_DATA_ALLOCATED; 10491 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) { 10492 mutex_exit(&mpt->m_mutex); 10493 for (i = 0; i < data_size; i++) { 10494 if (ddi_copyin(data + i, (uint8_t *) 10495 data_dma_state.memp + i, 1, mode)) { 10496 mutex_enter(&mpt->m_mutex); 10497 status = EFAULT; 10498 mptsas_log(mpt, CE_WARN, "failed to " 10499 "copy read data"); 10500 goto out; 10501 } 10502 } 10503 mutex_enter(&mpt->m_mutex); 10504 } 10505 } 10506 10507 if (dataout_size != 0) { 10508 dataout_dma_state.size = dataout_size; 10509 if (mptsas_dma_alloc(mpt, &dataout_dma_state) != DDI_SUCCESS) { 10510 status = ENOMEM; 10511 mptsas_log(mpt, CE_WARN, "failed to alloc DMA " 10512 "resource"); 10513 goto out; 10514 } 10515 pt_flags |= MPTSAS_DATAOUT_ALLOCATED; 10516 mutex_exit(&mpt->m_mutex); 10517 for (i = 0; i < dataout_size; i++) { 10518 if (ddi_copyin(dataout + i, (uint8_t *) 10519 dataout_dma_state.memp + i, 1, mode)) { 10520 mutex_enter(&mpt->m_mutex); 10521 mptsas_log(mpt, CE_WARN, "failed to copy out" 10522 " data"); 10523 status = EFAULT; 10524 goto out; 10525 } 10526 } 10527 mutex_enter(&mpt->m_mutex); 10528 } 10529 10530 if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 10531 status = EAGAIN; 10532 mptsas_log(mpt, CE_NOTE, "event ack command pool is full"); 10533 goto out; 10534 } 10535 pt_flags |= MPTSAS_REQUEST_POOL_CMD; 10536 10537 bzero((caddr_t)cmd, sizeof (*cmd)); 10538 bzero((caddr_t)pkt, scsi_pkt_size()); 10539 bzero((caddr_t)&pt, sizeof (pt)); 10540 10541 cmd->ioc_cmd_slot = (uint32_t)(rvalue); 10542 10543 pt.request = (uint8_t *)request_msg; 10544 pt.direction = direction; 10545 pt.request_size = request_size; 10546 pt.data_size = data_size; 10547 pt.dataout_size = dataout_size; 10548 pt.data_cookie = data_dma_state.cookie; 10549 pt.dataout_cookie = dataout_dma_state.cookie; 10550 10551 /* 10552 * Form a blank cmd/pkt to store the acknowledgement message 10553 */ 10554 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb[0]; 10555 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; 10556 pkt->pkt_ha_private = (opaque_t)&pt; 10557 pkt->pkt_flags = FLAG_HEAD; 10558 pkt->pkt_time = timeout; 10559 cmd->cmd_pkt = pkt; 10560 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_PASSTHRU; 10561 10562 /* 10563 * Save the command in a slot 10564 */ 10565 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 10566 /* 10567 * Once passthru command get slot, set cmd_flags 10568 * CFLAG_PREPARED. 10569 */ 10570 cmd->cmd_flags |= CFLAG_PREPARED; 10571 mptsas_start_passthru(mpt, cmd); 10572 } else { 10573 mptsas_waitq_add(mpt, cmd); 10574 } 10575 10576 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 10577 cv_wait(&mpt->m_passthru_cv, &mpt->m_mutex); 10578 } 10579 10580 if (cmd->cmd_flags & CFLAG_PREPARED) { 10581 memp = mpt->m_req_frame + (mpt->m_req_frame_size * 10582 cmd->cmd_slot); 10583 request_hdrp = (pMPI2RequestHeader_t)memp; 10584 } 10585 10586 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 10587 status = ETIMEDOUT; 10588 mptsas_log(mpt, CE_WARN, "passthrough command timeout"); 10589 pt_flags |= MPTSAS_CMD_TIMEOUT; 10590 goto out; 10591 } 10592 10593 if (cmd->cmd_rfm) { 10594 /* 10595 * cmd_rfm is zero means the command reply is a CONTEXT 10596 * reply and no PCI Write to post the free reply SMFA 10597 * because no reply message frame is used. 10598 * cmd_rfm is non-zero means the reply is a ADDRESS 10599 * reply and reply message frame is used. 10600 */ 10601 pt_flags |= MPTSAS_ADDRESS_REPLY; 10602 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 10603 DDI_DMA_SYNC_FORCPU); 10604 reply_msg = (pMPI2DefaultReply_t) 10605 (mpt->m_reply_frame + (cmd->cmd_rfm - 10606 mpt->m_reply_frame_dma_addr)); 10607 } 10608 10609 mptsas_fma_check(mpt, cmd); 10610 if (pkt->pkt_reason == CMD_TRAN_ERR) { 10611 status = EAGAIN; 10612 mptsas_log(mpt, CE_WARN, "passthru fma error"); 10613 goto out; 10614 } 10615 if (pkt->pkt_reason == CMD_RESET) { 10616 status = EAGAIN; 10617 mptsas_log(mpt, CE_WARN, "ioc reset abort passthru"); 10618 goto out; 10619 } 10620 10621 if (pkt->pkt_reason == CMD_INCOMPLETE) { 10622 status = EIO; 10623 mptsas_log(mpt, CE_WARN, "passthrough command incomplete"); 10624 goto out; 10625 } 10626 10627 mutex_exit(&mpt->m_mutex); 10628 if (cmd->cmd_flags & CFLAG_PREPARED) { 10629 function = request_hdrp->Function; 10630 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) || 10631 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 10632 reply_len = sizeof (MPI2_SCSI_IO_REPLY); 10633 sense_len = reply_size - reply_len; 10634 } else { 10635 reply_len = reply_size; 10636 sense_len = 0; 10637 } 10638 10639 for (i = 0; i < reply_len; i++) { 10640 if (ddi_copyout((uint8_t *)reply_msg + i, reply + i, 1, 10641 mode)) { 10642 mutex_enter(&mpt->m_mutex); 10643 status = EFAULT; 10644 mptsas_log(mpt, CE_WARN, "failed to copy out " 10645 "reply data"); 10646 goto out; 10647 } 10648 } 10649 for (i = 0; i < sense_len; i++) { 10650 if (ddi_copyout((uint8_t *)request_hdrp + 64 + i, 10651 reply + reply_len + i, 1, mode)) { 10652 mutex_enter(&mpt->m_mutex); 10653 status = EFAULT; 10654 mptsas_log(mpt, CE_WARN, "failed to copy out " 10655 "sense data"); 10656 goto out; 10657 } 10658 } 10659 } 10660 10661 if (data_size) { 10662 if (direction != MPTSAS_PASS_THRU_DIRECTION_WRITE) { 10663 (void) ddi_dma_sync(data_dma_state.handle, 0, 0, 10664 DDI_DMA_SYNC_FORCPU); 10665 for (i = 0; i < data_size; i++) { 10666 if (ddi_copyout((uint8_t *)( 10667 data_dma_state.memp + i), data + i, 1, 10668 mode)) { 10669 mutex_enter(&mpt->m_mutex); 10670 status = EFAULT; 10671 mptsas_log(mpt, CE_WARN, "failed to " 10672 "copy out the reply data"); 10673 goto out; 10674 } 10675 } 10676 } 10677 } 10678 mutex_enter(&mpt->m_mutex); 10679 out: 10680 /* 10681 * Put the reply frame back on the free queue, increment the free 10682 * index, and write the new index to the free index register. But only 10683 * if this reply is an ADDRESS reply. 10684 */ 10685 if (pt_flags & MPTSAS_ADDRESS_REPLY) { 10686 ddi_put32(mpt->m_acc_free_queue_hdl, 10687 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 10688 cmd->cmd_rfm); 10689 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 10690 DDI_DMA_SYNC_FORDEV); 10691 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 10692 mpt->m_free_index = 0; 10693 } 10694 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 10695 mpt->m_free_index); 10696 } 10697 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 10698 mptsas_remove_cmd(mpt, cmd); 10699 pt_flags &= (~MPTSAS_REQUEST_POOL_CMD); 10700 } 10701 if (pt_flags & MPTSAS_REQUEST_POOL_CMD) 10702 mptsas_return_to_pool(mpt, cmd); 10703 if (pt_flags & MPTSAS_DATA_ALLOCATED) { 10704 if (mptsas_check_dma_handle(data_dma_state.handle) != 10705 DDI_SUCCESS) { 10706 ddi_fm_service_impact(mpt->m_dip, 10707 DDI_SERVICE_UNAFFECTED); 10708 status = EFAULT; 10709 } 10710 mptsas_dma_free(&data_dma_state); 10711 } 10712 if (pt_flags & MPTSAS_DATAOUT_ALLOCATED) { 10713 if (mptsas_check_dma_handle(dataout_dma_state.handle) != 10714 DDI_SUCCESS) { 10715 ddi_fm_service_impact(mpt->m_dip, 10716 DDI_SERVICE_UNAFFECTED); 10717 status = EFAULT; 10718 } 10719 mptsas_dma_free(&dataout_dma_state); 10720 } 10721 if (pt_flags & MPTSAS_CMD_TIMEOUT) { 10722 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 10723 mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed"); 10724 } 10725 } 10726 if (request_msg) 10727 kmem_free(request_msg, request_size); 10728 10729 return (status); 10730 } 10731 10732 static int 10733 mptsas_pass_thru(mptsas_t *mpt, mptsas_pass_thru_t *data, int mode) 10734 { 10735 /* 10736 * If timeout is 0, set timeout to default of 60 seconds. 10737 */ 10738 if (data->Timeout == 0) { 10739 data->Timeout = MPTSAS_PASS_THRU_TIME_DEFAULT; 10740 } 10741 10742 if (((data->DataSize == 0) && 10743 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_NONE)) || 10744 ((data->DataSize != 0) && 10745 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_READ) || 10746 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_WRITE) || 10747 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) && 10748 (data->DataOutSize != 0))))) { 10749 if (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) { 10750 data->DataDirection = MPTSAS_PASS_THRU_DIRECTION_READ; 10751 } else { 10752 data->DataOutSize = 0; 10753 } 10754 /* 10755 * Send passthru request messages 10756 */ 10757 return (mptsas_do_passthru(mpt, 10758 (uint8_t *)((uintptr_t)data->PtrRequest), 10759 (uint8_t *)((uintptr_t)data->PtrReply), 10760 (uint8_t *)((uintptr_t)data->PtrData), 10761 data->RequestSize, data->ReplySize, 10762 data->DataSize, data->DataDirection, 10763 (uint8_t *)((uintptr_t)data->PtrDataOut), 10764 data->DataOutSize, data->Timeout, mode)); 10765 } else { 10766 return (EINVAL); 10767 } 10768 } 10769 10770 static uint8_t 10771 mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, uint32_t unique_id) 10772 { 10773 uint8_t index; 10774 10775 for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) { 10776 if (mpt->m_fw_diag_buffer_list[index].unique_id == unique_id) { 10777 return (index); 10778 } 10779 } 10780 10781 return (MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND); 10782 } 10783 10784 static void 10785 mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd) 10786 { 10787 pMpi2DiagBufferPostRequest_t pDiag_post_msg; 10788 pMpi2DiagReleaseRequest_t pDiag_release_msg; 10789 struct scsi_pkt *pkt = cmd->cmd_pkt; 10790 mptsas_diag_request_t *diag = pkt->pkt_ha_private; 10791 uint32_t request_desc_low, i; 10792 10793 ASSERT(mutex_owned(&mpt->m_mutex)); 10794 10795 /* 10796 * Form the diag message depending on the post or release function. 10797 */ 10798 if (diag->function == MPI2_FUNCTION_DIAG_BUFFER_POST) { 10799 pDiag_post_msg = (pMpi2DiagBufferPostRequest_t) 10800 (mpt->m_req_frame + (mpt->m_req_frame_size * 10801 cmd->cmd_slot)); 10802 bzero(pDiag_post_msg, mpt->m_req_frame_size); 10803 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->Function, 10804 diag->function); 10805 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->BufferType, 10806 diag->pBuffer->buffer_type); 10807 ddi_put8(mpt->m_acc_req_frame_hdl, 10808 &pDiag_post_msg->ExtendedType, 10809 diag->pBuffer->extended_type); 10810 ddi_put32(mpt->m_acc_req_frame_hdl, 10811 &pDiag_post_msg->BufferLength, 10812 diag->pBuffer->buffer_data.size); 10813 for (i = 0; i < (sizeof (pDiag_post_msg->ProductSpecific) / 4); 10814 i++) { 10815 ddi_put32(mpt->m_acc_req_frame_hdl, 10816 &pDiag_post_msg->ProductSpecific[i], 10817 diag->pBuffer->product_specific[i]); 10818 } 10819 ddi_put32(mpt->m_acc_req_frame_hdl, 10820 &pDiag_post_msg->BufferAddress.Low, 10821 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress 10822 & 0xffffffffull)); 10823 ddi_put32(mpt->m_acc_req_frame_hdl, 10824 &pDiag_post_msg->BufferAddress.High, 10825 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress 10826 >> 32)); 10827 } else { 10828 pDiag_release_msg = (pMpi2DiagReleaseRequest_t) 10829 (mpt->m_req_frame + (mpt->m_req_frame_size * 10830 cmd->cmd_slot)); 10831 bzero(pDiag_release_msg, mpt->m_req_frame_size); 10832 ddi_put8(mpt->m_acc_req_frame_hdl, 10833 &pDiag_release_msg->Function, diag->function); 10834 ddi_put8(mpt->m_acc_req_frame_hdl, 10835 &pDiag_release_msg->BufferType, 10836 diag->pBuffer->buffer_type); 10837 } 10838 10839 /* 10840 * Send the message 10841 */ 10842 (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0, 10843 DDI_DMA_SYNC_FORDEV); 10844 request_desc_low = (cmd->cmd_slot << 16) + 10845 MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 10846 cmd->cmd_rfm = NULL; 10847 mpt->m_active->m_slot[cmd->cmd_slot] = cmd; 10848 MPTSAS_START_CMD(mpt, request_desc_low, 0); 10849 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 10850 DDI_SUCCESS) || 10851 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 10852 DDI_SUCCESS)) { 10853 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 10854 } 10855 } 10856 10857 static int 10858 mptsas_post_fw_diag_buffer(mptsas_t *mpt, 10859 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code) 10860 { 10861 mptsas_diag_request_t diag; 10862 int status, slot_num, post_flags = 0; 10863 mptsas_cmd_t *cmd = NULL; 10864 struct scsi_pkt *pkt; 10865 pMpi2DiagBufferPostReply_t reply; 10866 uint16_t iocstatus; 10867 uint32_t iocloginfo, transfer_length; 10868 10869 /* 10870 * If buffer is not enabled, just leave. 10871 */ 10872 *return_code = MPTSAS_FW_DIAG_ERROR_POST_FAILED; 10873 if (!pBuffer->enabled) { 10874 status = DDI_FAILURE; 10875 goto out; 10876 } 10877 10878 /* 10879 * Clear some flags initially. 10880 */ 10881 pBuffer->force_release = FALSE; 10882 pBuffer->valid_data = FALSE; 10883 pBuffer->owned_by_firmware = FALSE; 10884 10885 /* 10886 * Get a cmd buffer from the cmd buffer pool 10887 */ 10888 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 10889 status = DDI_FAILURE; 10890 mptsas_log(mpt, CE_NOTE, "command pool is full: Post FW Diag"); 10891 goto out; 10892 } 10893 post_flags |= MPTSAS_REQUEST_POOL_CMD; 10894 10895 bzero((caddr_t)cmd, sizeof (*cmd)); 10896 bzero((caddr_t)pkt, scsi_pkt_size()); 10897 10898 cmd->ioc_cmd_slot = (uint32_t)(slot_num); 10899 10900 diag.pBuffer = pBuffer; 10901 diag.function = MPI2_FUNCTION_DIAG_BUFFER_POST; 10902 10903 /* 10904 * Form a blank cmd/pkt to store the acknowledgement message 10905 */ 10906 pkt->pkt_ha_private = (opaque_t)&diag; 10907 pkt->pkt_flags = FLAG_HEAD; 10908 pkt->pkt_time = 60; 10909 cmd->cmd_pkt = pkt; 10910 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG; 10911 10912 /* 10913 * Save the command in a slot 10914 */ 10915 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 10916 /* 10917 * Once passthru command get slot, set cmd_flags 10918 * CFLAG_PREPARED. 10919 */ 10920 cmd->cmd_flags |= CFLAG_PREPARED; 10921 mptsas_start_diag(mpt, cmd); 10922 } else { 10923 mptsas_waitq_add(mpt, cmd); 10924 } 10925 10926 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 10927 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex); 10928 } 10929 10930 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 10931 status = DDI_FAILURE; 10932 mptsas_log(mpt, CE_WARN, "Post FW Diag command timeout"); 10933 goto out; 10934 } 10935 10936 /* 10937 * cmd_rfm points to the reply message if a reply was given. Check the 10938 * IOCStatus to make sure everything went OK with the FW diag request 10939 * and set buffer flags. 10940 */ 10941 if (cmd->cmd_rfm) { 10942 post_flags |= MPTSAS_ADDRESS_REPLY; 10943 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 10944 DDI_DMA_SYNC_FORCPU); 10945 reply = (pMpi2DiagBufferPostReply_t)(mpt->m_reply_frame + 10946 (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr)); 10947 10948 /* 10949 * Get the reply message data 10950 */ 10951 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 10952 &reply->IOCStatus); 10953 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 10954 &reply->IOCLogInfo); 10955 transfer_length = ddi_get32(mpt->m_acc_reply_frame_hdl, 10956 &reply->TransferLength); 10957 10958 /* 10959 * If post failed quit. 10960 */ 10961 if (iocstatus != MPI2_IOCSTATUS_SUCCESS) { 10962 status = DDI_FAILURE; 10963 NDBG13(("post FW Diag Buffer failed: IOCStatus=0x%x, " 10964 "IOCLogInfo=0x%x, TransferLength=0x%x", iocstatus, 10965 iocloginfo, transfer_length)); 10966 goto out; 10967 } 10968 10969 /* 10970 * Post was successful. 10971 */ 10972 pBuffer->valid_data = TRUE; 10973 pBuffer->owned_by_firmware = TRUE; 10974 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 10975 status = DDI_SUCCESS; 10976 } 10977 10978 out: 10979 /* 10980 * Put the reply frame back on the free queue, increment the free 10981 * index, and write the new index to the free index register. But only 10982 * if this reply is an ADDRESS reply. 10983 */ 10984 if (post_flags & MPTSAS_ADDRESS_REPLY) { 10985 ddi_put32(mpt->m_acc_free_queue_hdl, 10986 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 10987 cmd->cmd_rfm); 10988 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 10989 DDI_DMA_SYNC_FORDEV); 10990 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 10991 mpt->m_free_index = 0; 10992 } 10993 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 10994 mpt->m_free_index); 10995 } 10996 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 10997 mptsas_remove_cmd(mpt, cmd); 10998 post_flags &= (~MPTSAS_REQUEST_POOL_CMD); 10999 } 11000 if (post_flags & MPTSAS_REQUEST_POOL_CMD) { 11001 mptsas_return_to_pool(mpt, cmd); 11002 } 11003 11004 return (status); 11005 } 11006 11007 static int 11008 mptsas_release_fw_diag_buffer(mptsas_t *mpt, 11009 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code, 11010 uint32_t diag_type) 11011 { 11012 mptsas_diag_request_t diag; 11013 int status, slot_num, rel_flags = 0; 11014 mptsas_cmd_t *cmd = NULL; 11015 struct scsi_pkt *pkt; 11016 pMpi2DiagReleaseReply_t reply; 11017 uint16_t iocstatus; 11018 uint32_t iocloginfo; 11019 11020 /* 11021 * If buffer is not enabled, just leave. 11022 */ 11023 *return_code = MPTSAS_FW_DIAG_ERROR_RELEASE_FAILED; 11024 if (!pBuffer->enabled) { 11025 mptsas_log(mpt, CE_NOTE, "This buffer type is not supported " 11026 "by the IOC"); 11027 status = DDI_FAILURE; 11028 goto out; 11029 } 11030 11031 /* 11032 * Clear some flags initially. 11033 */ 11034 pBuffer->force_release = FALSE; 11035 pBuffer->valid_data = FALSE; 11036 pBuffer->owned_by_firmware = FALSE; 11037 11038 /* 11039 * Get a cmd buffer from the cmd buffer pool 11040 */ 11041 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 11042 status = DDI_FAILURE; 11043 mptsas_log(mpt, CE_NOTE, "command pool is full: Release FW " 11044 "Diag"); 11045 goto out; 11046 } 11047 rel_flags |= MPTSAS_REQUEST_POOL_CMD; 11048 11049 bzero((caddr_t)cmd, sizeof (*cmd)); 11050 bzero((caddr_t)pkt, scsi_pkt_size()); 11051 11052 cmd->ioc_cmd_slot = (uint32_t)(slot_num); 11053 11054 diag.pBuffer = pBuffer; 11055 diag.function = MPI2_FUNCTION_DIAG_RELEASE; 11056 11057 /* 11058 * Form a blank cmd/pkt to store the acknowledgement message 11059 */ 11060 pkt->pkt_ha_private = (opaque_t)&diag; 11061 pkt->pkt_flags = FLAG_HEAD; 11062 pkt->pkt_time = 60; 11063 cmd->cmd_pkt = pkt; 11064 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG; 11065 11066 /* 11067 * Save the command in a slot 11068 */ 11069 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 11070 /* 11071 * Once passthru command get slot, set cmd_flags 11072 * CFLAG_PREPARED. 11073 */ 11074 cmd->cmd_flags |= CFLAG_PREPARED; 11075 mptsas_start_diag(mpt, cmd); 11076 } else { 11077 mptsas_waitq_add(mpt, cmd); 11078 } 11079 11080 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 11081 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex); 11082 } 11083 11084 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 11085 status = DDI_FAILURE; 11086 mptsas_log(mpt, CE_WARN, "Release FW Diag command timeout"); 11087 goto out; 11088 } 11089 11090 /* 11091 * cmd_rfm points to the reply message if a reply was given. Check the 11092 * IOCStatus to make sure everything went OK with the FW diag request 11093 * and set buffer flags. 11094 */ 11095 if (cmd->cmd_rfm) { 11096 rel_flags |= MPTSAS_ADDRESS_REPLY; 11097 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 11098 DDI_DMA_SYNC_FORCPU); 11099 reply = (pMpi2DiagReleaseReply_t)(mpt->m_reply_frame + 11100 (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr)); 11101 11102 /* 11103 * Get the reply message data 11104 */ 11105 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 11106 &reply->IOCStatus); 11107 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 11108 &reply->IOCLogInfo); 11109 11110 /* 11111 * If release failed quit. 11112 */ 11113 if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) || 11114 pBuffer->owned_by_firmware) { 11115 status = DDI_FAILURE; 11116 NDBG13(("release FW Diag Buffer failed: " 11117 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus, 11118 iocloginfo)); 11119 goto out; 11120 } 11121 11122 /* 11123 * Release was successful. 11124 */ 11125 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 11126 status = DDI_SUCCESS; 11127 11128 /* 11129 * If this was for an UNREGISTER diag type command, clear the 11130 * unique ID. 11131 */ 11132 if (diag_type == MPTSAS_FW_DIAG_TYPE_UNREGISTER) { 11133 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID; 11134 } 11135 } 11136 11137 out: 11138 /* 11139 * Put the reply frame back on the free queue, increment the free 11140 * index, and write the new index to the free index register. But only 11141 * if this reply is an ADDRESS reply. 11142 */ 11143 if (rel_flags & MPTSAS_ADDRESS_REPLY) { 11144 ddi_put32(mpt->m_acc_free_queue_hdl, 11145 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 11146 cmd->cmd_rfm); 11147 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 11148 DDI_DMA_SYNC_FORDEV); 11149 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 11150 mpt->m_free_index = 0; 11151 } 11152 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 11153 mpt->m_free_index); 11154 } 11155 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 11156 mptsas_remove_cmd(mpt, cmd); 11157 rel_flags &= (~MPTSAS_REQUEST_POOL_CMD); 11158 } 11159 if (rel_flags & MPTSAS_REQUEST_POOL_CMD) { 11160 mptsas_return_to_pool(mpt, cmd); 11161 } 11162 11163 return (status); 11164 } 11165 11166 static int 11167 mptsas_diag_register(mptsas_t *mpt, mptsas_fw_diag_register_t *diag_register, 11168 uint32_t *return_code) 11169 { 11170 mptsas_fw_diagnostic_buffer_t *pBuffer; 11171 uint8_t extended_type, buffer_type, i; 11172 uint32_t buffer_size; 11173 uint32_t unique_id; 11174 int status; 11175 11176 ASSERT(mutex_owned(&mpt->m_mutex)); 11177 11178 extended_type = diag_register->ExtendedType; 11179 buffer_type = diag_register->BufferType; 11180 buffer_size = diag_register->RequestedBufferSize; 11181 unique_id = diag_register->UniqueId; 11182 11183 /* 11184 * Check for valid buffer type 11185 */ 11186 if (buffer_type >= MPI2_DIAG_BUF_TYPE_COUNT) { 11187 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11188 return (DDI_FAILURE); 11189 } 11190 11191 /* 11192 * Get the current buffer and look up the unique ID. The unique ID 11193 * should not be found. If it is, the ID is already in use. 11194 */ 11195 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 11196 pBuffer = &mpt->m_fw_diag_buffer_list[buffer_type]; 11197 if (i != MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 11198 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11199 return (DDI_FAILURE); 11200 } 11201 11202 /* 11203 * The buffer's unique ID should not be registered yet, and the given 11204 * unique ID cannot be 0. 11205 */ 11206 if ((pBuffer->unique_id != MPTSAS_FW_DIAG_INVALID_UID) || 11207 (unique_id == MPTSAS_FW_DIAG_INVALID_UID)) { 11208 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11209 return (DDI_FAILURE); 11210 } 11211 11212 /* 11213 * If this buffer is already posted as immediate, just change owner. 11214 */ 11215 if (pBuffer->immediate && pBuffer->owned_by_firmware && 11216 (pBuffer->unique_id == MPTSAS_FW_DIAG_INVALID_UID)) { 11217 pBuffer->immediate = FALSE; 11218 pBuffer->unique_id = unique_id; 11219 return (DDI_SUCCESS); 11220 } 11221 11222 /* 11223 * Post a new buffer after checking if it's enabled. The DMA buffer 11224 * that is allocated will be contiguous (sgl_len = 1). 11225 */ 11226 if (!pBuffer->enabled) { 11227 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER; 11228 return (DDI_FAILURE); 11229 } 11230 bzero(&pBuffer->buffer_data, sizeof (mptsas_dma_alloc_state_t)); 11231 pBuffer->buffer_data.size = buffer_size; 11232 if (mptsas_dma_alloc(mpt, &pBuffer->buffer_data) != DDI_SUCCESS) { 11233 mptsas_log(mpt, CE_WARN, "failed to alloc DMA resource for " 11234 "diag buffer: size = %d bytes", buffer_size); 11235 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER; 11236 return (DDI_FAILURE); 11237 } 11238 11239 /* 11240 * Copy the given info to the diag buffer and post the buffer. 11241 */ 11242 pBuffer->buffer_type = buffer_type; 11243 pBuffer->immediate = FALSE; 11244 if (buffer_type == MPI2_DIAG_BUF_TYPE_TRACE) { 11245 for (i = 0; i < (sizeof (pBuffer->product_specific) / 4); 11246 i++) { 11247 pBuffer->product_specific[i] = 11248 diag_register->ProductSpecific[i]; 11249 } 11250 } 11251 pBuffer->extended_type = extended_type; 11252 pBuffer->unique_id = unique_id; 11253 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, return_code); 11254 11255 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) != 11256 DDI_SUCCESS) { 11257 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed in " 11258 "mptsas_diag_register."); 11259 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 11260 status = DDI_FAILURE; 11261 } 11262 11263 /* 11264 * In case there was a failure, free the DMA buffer. 11265 */ 11266 if (status == DDI_FAILURE) { 11267 mptsas_dma_free(&pBuffer->buffer_data); 11268 } 11269 11270 return (status); 11271 } 11272 11273 static int 11274 mptsas_diag_unregister(mptsas_t *mpt, 11275 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code) 11276 { 11277 mptsas_fw_diagnostic_buffer_t *pBuffer; 11278 uint8_t i; 11279 uint32_t unique_id; 11280 int status; 11281 11282 ASSERT(mutex_owned(&mpt->m_mutex)); 11283 11284 unique_id = diag_unregister->UniqueId; 11285 11286 /* 11287 * Get the current buffer and look up the unique ID. The unique ID 11288 * should be there. 11289 */ 11290 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 11291 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 11292 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11293 return (DDI_FAILURE); 11294 } 11295 11296 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 11297 11298 /* 11299 * Try to release the buffer from FW before freeing it. If release 11300 * fails, don't free the DMA buffer in case FW tries to access it 11301 * later. If buffer is not owned by firmware, can't release it. 11302 */ 11303 if (!pBuffer->owned_by_firmware) { 11304 status = DDI_SUCCESS; 11305 } else { 11306 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, 11307 return_code, MPTSAS_FW_DIAG_TYPE_UNREGISTER); 11308 } 11309 11310 /* 11311 * At this point, return the current status no matter what happens with 11312 * the DMA buffer. 11313 */ 11314 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID; 11315 if (status == DDI_SUCCESS) { 11316 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) != 11317 DDI_SUCCESS) { 11318 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed " 11319 "in mptsas_diag_unregister."); 11320 ddi_fm_service_impact(mpt->m_dip, 11321 DDI_SERVICE_UNAFFECTED); 11322 } 11323 mptsas_dma_free(&pBuffer->buffer_data); 11324 } 11325 11326 return (status); 11327 } 11328 11329 static int 11330 mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query, 11331 uint32_t *return_code) 11332 { 11333 mptsas_fw_diagnostic_buffer_t *pBuffer; 11334 uint8_t i; 11335 uint32_t unique_id; 11336 11337 ASSERT(mutex_owned(&mpt->m_mutex)); 11338 11339 unique_id = diag_query->UniqueId; 11340 11341 /* 11342 * If ID is valid, query on ID. 11343 * If ID is invalid, query on buffer type. 11344 */ 11345 if (unique_id == MPTSAS_FW_DIAG_INVALID_UID) { 11346 i = diag_query->BufferType; 11347 if (i >= MPI2_DIAG_BUF_TYPE_COUNT) { 11348 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11349 return (DDI_FAILURE); 11350 } 11351 } else { 11352 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 11353 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 11354 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11355 return (DDI_FAILURE); 11356 } 11357 } 11358 11359 /* 11360 * Fill query structure with the diag buffer info. 11361 */ 11362 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 11363 diag_query->BufferType = pBuffer->buffer_type; 11364 diag_query->ExtendedType = pBuffer->extended_type; 11365 if (diag_query->BufferType == MPI2_DIAG_BUF_TYPE_TRACE) { 11366 for (i = 0; i < (sizeof (diag_query->ProductSpecific) / 4); 11367 i++) { 11368 diag_query->ProductSpecific[i] = 11369 pBuffer->product_specific[i]; 11370 } 11371 } 11372 diag_query->TotalBufferSize = pBuffer->buffer_data.size; 11373 diag_query->DriverAddedBufferSize = 0; 11374 diag_query->UniqueId = pBuffer->unique_id; 11375 diag_query->ApplicationFlags = 0; 11376 diag_query->DiagnosticFlags = 0; 11377 11378 /* 11379 * Set/Clear application flags 11380 */ 11381 if (pBuffer->immediate) { 11382 diag_query->ApplicationFlags &= ~MPTSAS_FW_DIAG_FLAG_APP_OWNED; 11383 } else { 11384 diag_query->ApplicationFlags |= MPTSAS_FW_DIAG_FLAG_APP_OWNED; 11385 } 11386 if (pBuffer->valid_data || pBuffer->owned_by_firmware) { 11387 diag_query->ApplicationFlags |= 11388 MPTSAS_FW_DIAG_FLAG_BUFFER_VALID; 11389 } else { 11390 diag_query->ApplicationFlags &= 11391 ~MPTSAS_FW_DIAG_FLAG_BUFFER_VALID; 11392 } 11393 if (pBuffer->owned_by_firmware) { 11394 diag_query->ApplicationFlags |= 11395 MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS; 11396 } else { 11397 diag_query->ApplicationFlags &= 11398 ~MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS; 11399 } 11400 11401 return (DDI_SUCCESS); 11402 } 11403 11404 static int 11405 mptsas_diag_read_buffer(mptsas_t *mpt, 11406 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf, 11407 uint32_t *return_code, int ioctl_mode) 11408 { 11409 mptsas_fw_diagnostic_buffer_t *pBuffer; 11410 uint8_t i, *pData; 11411 uint32_t unique_id, byte; 11412 int status; 11413 11414 ASSERT(mutex_owned(&mpt->m_mutex)); 11415 11416 unique_id = diag_read_buffer->UniqueId; 11417 11418 /* 11419 * Get the current buffer and look up the unique ID. The unique ID 11420 * should be there. 11421 */ 11422 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 11423 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 11424 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11425 return (DDI_FAILURE); 11426 } 11427 11428 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 11429 11430 /* 11431 * Make sure requested read is within limits 11432 */ 11433 if (diag_read_buffer->StartingOffset + diag_read_buffer->BytesToRead > 11434 pBuffer->buffer_data.size) { 11435 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11436 return (DDI_FAILURE); 11437 } 11438 11439 /* 11440 * Copy the requested data from DMA to the diag_read_buffer. The DMA 11441 * buffer that was allocated is one contiguous buffer. 11442 */ 11443 pData = (uint8_t *)(pBuffer->buffer_data.memp + 11444 diag_read_buffer->StartingOffset); 11445 (void) ddi_dma_sync(pBuffer->buffer_data.handle, 0, 0, 11446 DDI_DMA_SYNC_FORCPU); 11447 for (byte = 0; byte < diag_read_buffer->BytesToRead; byte++) { 11448 if (ddi_copyout(pData + byte, ioctl_buf + byte, 1, ioctl_mode) 11449 != 0) { 11450 return (DDI_FAILURE); 11451 } 11452 } 11453 diag_read_buffer->Status = 0; 11454 11455 /* 11456 * Set or clear the Force Release flag. 11457 */ 11458 if (pBuffer->force_release) { 11459 diag_read_buffer->Flags |= MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE; 11460 } else { 11461 diag_read_buffer->Flags &= ~MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE; 11462 } 11463 11464 /* 11465 * If buffer is to be reregistered, make sure it's not already owned by 11466 * firmware first. 11467 */ 11468 status = DDI_SUCCESS; 11469 if (!pBuffer->owned_by_firmware) { 11470 if (diag_read_buffer->Flags & MPTSAS_FW_DIAG_FLAG_REREGISTER) { 11471 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, 11472 return_code); 11473 } 11474 } 11475 11476 return (status); 11477 } 11478 11479 static int 11480 mptsas_diag_release(mptsas_t *mpt, mptsas_fw_diag_release_t *diag_release, 11481 uint32_t *return_code) 11482 { 11483 mptsas_fw_diagnostic_buffer_t *pBuffer; 11484 uint8_t i; 11485 uint32_t unique_id; 11486 int status; 11487 11488 ASSERT(mutex_owned(&mpt->m_mutex)); 11489 11490 unique_id = diag_release->UniqueId; 11491 11492 /* 11493 * Get the current buffer and look up the unique ID. The unique ID 11494 * should be there. 11495 */ 11496 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 11497 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 11498 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11499 return (DDI_FAILURE); 11500 } 11501 11502 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 11503 11504 /* 11505 * If buffer is not owned by firmware, it's already been released. 11506 */ 11507 if (!pBuffer->owned_by_firmware) { 11508 *return_code = MPTSAS_FW_DIAG_ERROR_ALREADY_RELEASED; 11509 return (DDI_FAILURE); 11510 } 11511 11512 /* 11513 * Release the buffer. 11514 */ 11515 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, return_code, 11516 MPTSAS_FW_DIAG_TYPE_RELEASE); 11517 return (status); 11518 } 11519 11520 static int 11521 mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, uint8_t *diag_action, 11522 uint32_t length, uint32_t *return_code, int ioctl_mode) 11523 { 11524 mptsas_fw_diag_register_t diag_register; 11525 mptsas_fw_diag_unregister_t diag_unregister; 11526 mptsas_fw_diag_query_t diag_query; 11527 mptsas_diag_read_buffer_t diag_read_buffer; 11528 mptsas_fw_diag_release_t diag_release; 11529 int status = DDI_SUCCESS; 11530 uint32_t original_return_code, read_buf_len; 11531 11532 ASSERT(mutex_owned(&mpt->m_mutex)); 11533 11534 original_return_code = *return_code; 11535 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 11536 11537 switch (action) { 11538 case MPTSAS_FW_DIAG_TYPE_REGISTER: 11539 if (!length) { 11540 *return_code = 11541 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11542 status = DDI_FAILURE; 11543 break; 11544 } 11545 if (ddi_copyin(diag_action, &diag_register, 11546 sizeof (diag_register), ioctl_mode) != 0) { 11547 return (DDI_FAILURE); 11548 } 11549 status = mptsas_diag_register(mpt, &diag_register, 11550 return_code); 11551 break; 11552 11553 case MPTSAS_FW_DIAG_TYPE_UNREGISTER: 11554 if (length < sizeof (diag_unregister)) { 11555 *return_code = 11556 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11557 status = DDI_FAILURE; 11558 break; 11559 } 11560 if (ddi_copyin(diag_action, &diag_unregister, 11561 sizeof (diag_unregister), ioctl_mode) != 0) { 11562 return (DDI_FAILURE); 11563 } 11564 status = mptsas_diag_unregister(mpt, &diag_unregister, 11565 return_code); 11566 break; 11567 11568 case MPTSAS_FW_DIAG_TYPE_QUERY: 11569 if (length < sizeof (diag_query)) { 11570 *return_code = 11571 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11572 status = DDI_FAILURE; 11573 break; 11574 } 11575 if (ddi_copyin(diag_action, &diag_query, 11576 sizeof (diag_query), ioctl_mode) != 0) { 11577 return (DDI_FAILURE); 11578 } 11579 status = mptsas_diag_query(mpt, &diag_query, 11580 return_code); 11581 if (status == DDI_SUCCESS) { 11582 if (ddi_copyout(&diag_query, diag_action, 11583 sizeof (diag_query), ioctl_mode) != 0) { 11584 return (DDI_FAILURE); 11585 } 11586 } 11587 break; 11588 11589 case MPTSAS_FW_DIAG_TYPE_READ_BUFFER: 11590 if (ddi_copyin(diag_action, &diag_read_buffer, 11591 sizeof (diag_read_buffer) - 4, ioctl_mode) != 0) { 11592 return (DDI_FAILURE); 11593 } 11594 read_buf_len = sizeof (diag_read_buffer) - 11595 sizeof (diag_read_buffer.DataBuffer) + 11596 diag_read_buffer.BytesToRead; 11597 if (length < read_buf_len) { 11598 *return_code = 11599 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11600 status = DDI_FAILURE; 11601 break; 11602 } 11603 status = mptsas_diag_read_buffer(mpt, 11604 &diag_read_buffer, diag_action + 11605 sizeof (diag_read_buffer) - 4, return_code, 11606 ioctl_mode); 11607 if (status == DDI_SUCCESS) { 11608 if (ddi_copyout(&diag_read_buffer, diag_action, 11609 sizeof (diag_read_buffer) - 4, ioctl_mode) 11610 != 0) { 11611 return (DDI_FAILURE); 11612 } 11613 } 11614 break; 11615 11616 case MPTSAS_FW_DIAG_TYPE_RELEASE: 11617 if (length < sizeof (diag_release)) { 11618 *return_code = 11619 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11620 status = DDI_FAILURE; 11621 break; 11622 } 11623 if (ddi_copyin(diag_action, &diag_release, 11624 sizeof (diag_release), ioctl_mode) != 0) { 11625 return (DDI_FAILURE); 11626 } 11627 status = mptsas_diag_release(mpt, &diag_release, 11628 return_code); 11629 break; 11630 11631 default: 11632 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11633 status = DDI_FAILURE; 11634 break; 11635 } 11636 11637 if ((status == DDI_FAILURE) && 11638 (original_return_code == MPTSAS_FW_DIAG_NEW) && 11639 (*return_code != MPTSAS_FW_DIAG_ERROR_SUCCESS)) { 11640 status = DDI_SUCCESS; 11641 } 11642 11643 return (status); 11644 } 11645 11646 static int 11647 mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *user_data, int mode) 11648 { 11649 int status; 11650 mptsas_diag_action_t driver_data; 11651 11652 ASSERT(mutex_owned(&mpt->m_mutex)); 11653 11654 /* 11655 * Copy the user data to a driver data buffer. 11656 */ 11657 if (ddi_copyin(user_data, &driver_data, sizeof (mptsas_diag_action_t), 11658 mode) == 0) { 11659 /* 11660 * Send diag action request if Action is valid 11661 */ 11662 if (driver_data.Action == MPTSAS_FW_DIAG_TYPE_REGISTER || 11663 driver_data.Action == MPTSAS_FW_DIAG_TYPE_UNREGISTER || 11664 driver_data.Action == MPTSAS_FW_DIAG_TYPE_QUERY || 11665 driver_data.Action == MPTSAS_FW_DIAG_TYPE_READ_BUFFER || 11666 driver_data.Action == MPTSAS_FW_DIAG_TYPE_RELEASE) { 11667 status = mptsas_do_diag_action(mpt, driver_data.Action, 11668 (void *)(uintptr_t)driver_data.PtrDiagAction, 11669 driver_data.Length, &driver_data.ReturnCode, 11670 mode); 11671 if (status == DDI_SUCCESS) { 11672 if (ddi_copyout(&driver_data.ReturnCode, 11673 &user_data->ReturnCode, 11674 sizeof (user_data->ReturnCode), mode) 11675 != 0) { 11676 status = EFAULT; 11677 } else { 11678 status = 0; 11679 } 11680 } else { 11681 status = EIO; 11682 } 11683 } else { 11684 status = EINVAL; 11685 } 11686 } else { 11687 status = EFAULT; 11688 } 11689 11690 return (status); 11691 } 11692 11693 /* 11694 * This routine handles the "event query" ioctl. 11695 */ 11696 static int 11697 mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, int mode, 11698 int *rval) 11699 { 11700 int status; 11701 mptsas_event_query_t driverdata; 11702 uint8_t i; 11703 11704 driverdata.Entries = MPTSAS_EVENT_QUEUE_SIZE; 11705 11706 mutex_enter(&mpt->m_mutex); 11707 for (i = 0; i < 4; i++) { 11708 driverdata.Types[i] = mpt->m_event_mask[i]; 11709 } 11710 mutex_exit(&mpt->m_mutex); 11711 11712 if (ddi_copyout(&driverdata, data, sizeof (driverdata), mode) != 0) { 11713 status = EFAULT; 11714 } else { 11715 *rval = MPTIOCTL_STATUS_GOOD; 11716 status = 0; 11717 } 11718 11719 return (status); 11720 } 11721 11722 /* 11723 * This routine handles the "event enable" ioctl. 11724 */ 11725 static int 11726 mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, int mode, 11727 int *rval) 11728 { 11729 int status; 11730 mptsas_event_enable_t driverdata; 11731 uint8_t i; 11732 11733 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) { 11734 mutex_enter(&mpt->m_mutex); 11735 for (i = 0; i < 4; i++) { 11736 mpt->m_event_mask[i] = driverdata.Types[i]; 11737 } 11738 mutex_exit(&mpt->m_mutex); 11739 11740 *rval = MPTIOCTL_STATUS_GOOD; 11741 status = 0; 11742 } else { 11743 status = EFAULT; 11744 } 11745 return (status); 11746 } 11747 11748 /* 11749 * This routine handles the "event report" ioctl. 11750 */ 11751 static int 11752 mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, int mode, 11753 int *rval) 11754 { 11755 int status; 11756 mptsas_event_report_t driverdata; 11757 11758 mutex_enter(&mpt->m_mutex); 11759 11760 if (ddi_copyin(&data->Size, &driverdata.Size, sizeof (driverdata.Size), 11761 mode) == 0) { 11762 if (driverdata.Size >= sizeof (mpt->m_events)) { 11763 if (ddi_copyout(mpt->m_events, data->Events, 11764 sizeof (mpt->m_events), mode) != 0) { 11765 status = EFAULT; 11766 } else { 11767 if (driverdata.Size > sizeof (mpt->m_events)) { 11768 driverdata.Size = 11769 sizeof (mpt->m_events); 11770 if (ddi_copyout(&driverdata.Size, 11771 &data->Size, 11772 sizeof (driverdata.Size), 11773 mode) != 0) { 11774 status = EFAULT; 11775 } else { 11776 *rval = MPTIOCTL_STATUS_GOOD; 11777 status = 0; 11778 } 11779 } else { 11780 *rval = MPTIOCTL_STATUS_GOOD; 11781 status = 0; 11782 } 11783 } 11784 } else { 11785 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT; 11786 status = 0; 11787 } 11788 } else { 11789 status = EFAULT; 11790 } 11791 11792 mutex_exit(&mpt->m_mutex); 11793 return (status); 11794 } 11795 11796 static void 11797 mptsas_lookup_pci_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data) 11798 { 11799 int *reg_data; 11800 uint_t reglen; 11801 11802 /* 11803 * Lookup the 'reg' property and extract the other data 11804 */ 11805 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip, 11806 DDI_PROP_DONTPASS, "reg", ®_data, ®len) == 11807 DDI_PROP_SUCCESS) { 11808 /* 11809 * Extract the PCI data from the 'reg' property first DWORD. 11810 * The entry looks like the following: 11811 * First DWORD: 11812 * Bits 0 - 7 8-bit Register number 11813 * Bits 8 - 10 3-bit Function number 11814 * Bits 11 - 15 5-bit Device number 11815 * Bits 16 - 23 8-bit Bus number 11816 * Bits 24 - 25 2-bit Address Space type identifier 11817 * 11818 */ 11819 adapter_data->PciInformation.u.bits.BusNumber = 11820 (reg_data[0] & 0x00FF0000) >> 16; 11821 adapter_data->PciInformation.u.bits.DeviceNumber = 11822 (reg_data[0] & 0x0000F800) >> 11; 11823 adapter_data->PciInformation.u.bits.FunctionNumber = 11824 (reg_data[0] & 0x00000700) >> 8; 11825 ddi_prop_free((void *)reg_data); 11826 } else { 11827 /* 11828 * If we can't determine the PCI data then we fill in FF's for 11829 * the data to indicate this. 11830 */ 11831 adapter_data->PCIDeviceHwId = 0xFFFFFFFF; 11832 adapter_data->MpiPortNumber = 0xFFFFFFFF; 11833 adapter_data->PciInformation.u.AsDWORD = 0xFFFFFFFF; 11834 } 11835 11836 /* 11837 * Saved in the mpt->m_fwversion 11838 */ 11839 adapter_data->MpiFirmwareVersion = mpt->m_fwversion; 11840 } 11841 11842 static void 11843 mptsas_read_adapter_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data) 11844 { 11845 char *driver_verstr = MPTSAS_MOD_STRING; 11846 11847 mptsas_lookup_pci_data(mpt, adapter_data); 11848 adapter_data->AdapterType = MPTIOCTL_ADAPTER_TYPE_SAS2; 11849 adapter_data->PCIDeviceHwId = (uint32_t)mpt->m_devid; 11850 adapter_data->PCIDeviceHwRev = (uint32_t)mpt->m_revid; 11851 adapter_data->SubSystemId = (uint32_t)mpt->m_ssid; 11852 adapter_data->SubsystemVendorId = (uint32_t)mpt->m_svid; 11853 (void) strcpy((char *)&adapter_data->DriverVersion[0], driver_verstr); 11854 adapter_data->BiosVersion = 0; 11855 (void) mptsas_get_bios_page3(mpt, &adapter_data->BiosVersion); 11856 } 11857 11858 static void 11859 mptsas_read_pci_info(mptsas_t *mpt, mptsas_pci_info_t *pci_info) 11860 { 11861 int *reg_data, i; 11862 uint_t reglen; 11863 11864 /* 11865 * Lookup the 'reg' property and extract the other data 11866 */ 11867 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip, 11868 DDI_PROP_DONTPASS, "reg", ®_data, ®len) == 11869 DDI_PROP_SUCCESS) { 11870 /* 11871 * Extract the PCI data from the 'reg' property first DWORD. 11872 * The entry looks like the following: 11873 * First DWORD: 11874 * Bits 8 - 10 3-bit Function number 11875 * Bits 11 - 15 5-bit Device number 11876 * Bits 16 - 23 8-bit Bus number 11877 */ 11878 pci_info->BusNumber = (reg_data[0] & 0x00FF0000) >> 16; 11879 pci_info->DeviceNumber = (reg_data[0] & 0x0000F800) >> 11; 11880 pci_info->FunctionNumber = (reg_data[0] & 0x00000700) >> 8; 11881 ddi_prop_free((void *)reg_data); 11882 } else { 11883 /* 11884 * If we can't determine the PCI info then we fill in FF's for 11885 * the data to indicate this. 11886 */ 11887 pci_info->BusNumber = 0xFFFFFFFF; 11888 pci_info->DeviceNumber = 0xFF; 11889 pci_info->FunctionNumber = 0xFF; 11890 } 11891 11892 /* 11893 * Now get the interrupt vector and the pci header. The vector can 11894 * only be 0 right now. The header is the first 256 bytes of config 11895 * space. 11896 */ 11897 pci_info->InterruptVector = 0; 11898 for (i = 0; i < sizeof (pci_info->PciHeader); i++) { 11899 pci_info->PciHeader[i] = pci_config_get8(mpt->m_config_handle, 11900 i); 11901 } 11902 } 11903 11904 static int 11905 mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, int mode) 11906 { 11907 int status = 0; 11908 mptsas_reg_access_t driverdata; 11909 11910 mutex_enter(&mpt->m_mutex); 11911 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) { 11912 switch (driverdata.Command) { 11913 /* 11914 * IO access is not supported. 11915 */ 11916 case REG_IO_READ: 11917 case REG_IO_WRITE: 11918 mptsas_log(mpt, CE_WARN, "IO access is not " 11919 "supported. Use memory access."); 11920 status = EINVAL; 11921 break; 11922 11923 case REG_MEM_READ: 11924 driverdata.RegData = ddi_get32(mpt->m_datap, 11925 (uint32_t *)(void *)mpt->m_reg + 11926 driverdata.RegOffset); 11927 if (ddi_copyout(&driverdata.RegData, 11928 &data->RegData, 11929 sizeof (driverdata.RegData), mode) != 0) { 11930 mptsas_log(mpt, CE_WARN, "Register " 11931 "Read Failed"); 11932 status = EFAULT; 11933 } 11934 break; 11935 11936 case REG_MEM_WRITE: 11937 ddi_put32(mpt->m_datap, 11938 (uint32_t *)(void *)mpt->m_reg + 11939 driverdata.RegOffset, 11940 driverdata.RegData); 11941 break; 11942 11943 default: 11944 status = EINVAL; 11945 break; 11946 } 11947 } else { 11948 status = EFAULT; 11949 } 11950 11951 mutex_exit(&mpt->m_mutex); 11952 return (status); 11953 } 11954 11955 static int 11956 led_control(mptsas_t *mpt, intptr_t data, int mode) 11957 { 11958 int ret = 0; 11959 mptsas_led_control_t lc; 11960 mptsas_target_t *ptgt; 11961 11962 if (ddi_copyin((void *)data, &lc, sizeof (lc), mode) != 0) { 11963 return (EFAULT); 11964 } 11965 11966 if ((lc.Command != MPTSAS_LEDCTL_FLAG_SET && 11967 lc.Command != MPTSAS_LEDCTL_FLAG_GET) || 11968 lc.Led < MPTSAS_LEDCTL_LED_IDENT || 11969 lc.Led > MPTSAS_LEDCTL_LED_OK2RM || 11970 (lc.Command == MPTSAS_LEDCTL_FLAG_SET && lc.LedStatus != 0 && 11971 lc.LedStatus != 1)) { 11972 return (EINVAL); 11973 } 11974 11975 /* Locate the target we're interrogating... */ 11976 mutex_enter(&mpt->m_mutex); 11977 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 11978 MPTSAS_HASH_FIRST); 11979 while (ptgt != NULL) { 11980 if (ptgt->m_enclosure == lc.Enclosure && 11981 ptgt->m_slot_num == lc.Slot) { 11982 break; 11983 } 11984 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 11985 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 11986 } 11987 if (ptgt == NULL) { 11988 /* We could not find a target for that enclosure/slot. */ 11989 mutex_exit(&mpt->m_mutex); 11990 return (ENOENT); 11991 } 11992 11993 if (lc.Command == MPTSAS_LEDCTL_FLAG_SET) { 11994 /* Update our internal LED state. */ 11995 ptgt->m_led_status &= ~(1 << (lc.Led - 1)); 11996 ptgt->m_led_status |= lc.LedStatus << (lc.Led - 1); 11997 11998 /* Flush it to the controller. */ 11999 ret = mptsas_flush_led_status(mpt, ptgt); 12000 mutex_exit(&mpt->m_mutex); 12001 return (ret); 12002 } 12003 12004 /* Return our internal LED state. */ 12005 lc.LedStatus = (ptgt->m_led_status >> (lc.Led - 1)) & 1; 12006 mutex_exit(&mpt->m_mutex); 12007 12008 if (ddi_copyout(&lc, (void *)data, sizeof (lc), mode) != 0) { 12009 return (EFAULT); 12010 } 12011 12012 return (0); 12013 } 12014 12015 static int 12016 get_disk_info(mptsas_t *mpt, intptr_t data, int mode) 12017 { 12018 int i = 0; 12019 int count = 0; 12020 int ret = 0; 12021 mptsas_target_t *ptgt; 12022 mptsas_disk_info_t *di; 12023 STRUCT_DECL(mptsas_get_disk_info, gdi); 12024 12025 STRUCT_INIT(gdi, get_udatamodel()); 12026 12027 if (ddi_copyin((void *)data, STRUCT_BUF(gdi), STRUCT_SIZE(gdi), 12028 mode) != 0) { 12029 return (EFAULT); 12030 } 12031 12032 /* Find out how many targets there are. */ 12033 mutex_enter(&mpt->m_mutex); 12034 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 12035 MPTSAS_HASH_FIRST); 12036 while (ptgt != NULL) { 12037 count++; 12038 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 12039 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 12040 } 12041 mutex_exit(&mpt->m_mutex); 12042 12043 /* 12044 * If we haven't been asked to copy out information on each target, 12045 * then just return the count. 12046 */ 12047 STRUCT_FSET(gdi, DiskCount, count); 12048 if (STRUCT_FGETP(gdi, PtrDiskInfoArray) == NULL) 12049 goto copy_out; 12050 12051 /* 12052 * If we haven't been given a large enough buffer to copy out into, 12053 * let the caller know. 12054 */ 12055 if (STRUCT_FGET(gdi, DiskInfoArraySize) < 12056 count * sizeof (mptsas_disk_info_t)) { 12057 ret = ENOSPC; 12058 goto copy_out; 12059 } 12060 12061 di = kmem_zalloc(count * sizeof (mptsas_disk_info_t), KM_SLEEP); 12062 12063 mutex_enter(&mpt->m_mutex); 12064 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 12065 MPTSAS_HASH_FIRST); 12066 while (ptgt != NULL) { 12067 if (i >= count) { 12068 /* 12069 * The number of targets changed while we weren't 12070 * looking, so give up. 12071 */ 12072 mutex_exit(&mpt->m_mutex); 12073 kmem_free(di, count * sizeof (mptsas_disk_info_t)); 12074 return (EAGAIN); 12075 } 12076 di[i].Instance = mpt->m_instance; 12077 di[i].Enclosure = ptgt->m_enclosure; 12078 di[i].Slot = ptgt->m_slot_num; 12079 di[i].SasAddress = ptgt->m_sas_wwn; 12080 12081 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 12082 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 12083 i++; 12084 } 12085 mutex_exit(&mpt->m_mutex); 12086 STRUCT_FSET(gdi, DiskCount, i); 12087 12088 /* Copy out the disk information to the caller. */ 12089 if (ddi_copyout((void *)di, STRUCT_FGETP(gdi, PtrDiskInfoArray), 12090 i * sizeof (mptsas_disk_info_t), mode) != 0) { 12091 ret = EFAULT; 12092 } 12093 12094 kmem_free(di, count * sizeof (mptsas_disk_info_t)); 12095 12096 copy_out: 12097 if (ddi_copyout(STRUCT_BUF(gdi), (void *)data, STRUCT_SIZE(gdi), 12098 mode) != 0) { 12099 ret = EFAULT; 12100 } 12101 12102 return (ret); 12103 } 12104 12105 static int 12106 mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp, 12107 int *rval) 12108 { 12109 int status = 0; 12110 mptsas_t *mpt; 12111 mptsas_update_flash_t flashdata; 12112 mptsas_pass_thru_t passthru_data; 12113 mptsas_adapter_data_t adapter_data; 12114 mptsas_pci_info_t pci_info; 12115 int copylen; 12116 12117 int iport_flag = 0; 12118 dev_info_t *dip = NULL; 12119 mptsas_phymask_t phymask = 0; 12120 struct devctl_iocdata *dcp = NULL; 12121 uint32_t slotstatus = 0; 12122 char *addr = NULL; 12123 mptsas_target_t *ptgt = NULL; 12124 12125 *rval = MPTIOCTL_STATUS_GOOD; 12126 if (secpolicy_sys_config(credp, B_FALSE) != 0) { 12127 return (EPERM); 12128 } 12129 12130 mpt = ddi_get_soft_state(mptsas_state, MINOR2INST(getminor(dev))); 12131 if (mpt == NULL) { 12132 /* 12133 * Called from iport node, get the states 12134 */ 12135 iport_flag = 1; 12136 dip = mptsas_get_dip_from_dev(dev, &phymask); 12137 if (dip == NULL) { 12138 return (ENXIO); 12139 } 12140 mpt = DIP2MPT(dip); 12141 } 12142 /* Make sure power level is D0 before accessing registers */ 12143 mutex_enter(&mpt->m_mutex); 12144 if (mpt->m_options & MPTSAS_OPT_PM) { 12145 (void) pm_busy_component(mpt->m_dip, 0); 12146 if (mpt->m_power_level != PM_LEVEL_D0) { 12147 mutex_exit(&mpt->m_mutex); 12148 if (pm_raise_power(mpt->m_dip, 0, PM_LEVEL_D0) != 12149 DDI_SUCCESS) { 12150 mptsas_log(mpt, CE_WARN, 12151 "mptsas%d: mptsas_ioctl: Raise power " 12152 "request failed.", mpt->m_instance); 12153 (void) pm_idle_component(mpt->m_dip, 0); 12154 return (ENXIO); 12155 } 12156 } else { 12157 mutex_exit(&mpt->m_mutex); 12158 } 12159 } else { 12160 mutex_exit(&mpt->m_mutex); 12161 } 12162 12163 if (iport_flag) { 12164 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, rval); 12165 if (status != 0) { 12166 goto out; 12167 } 12168 /* 12169 * The following code control the OK2RM LED, it doesn't affect 12170 * the ioctl return status. 12171 */ 12172 if ((cmd == DEVCTL_DEVICE_ONLINE) || 12173 (cmd == DEVCTL_DEVICE_OFFLINE)) { 12174 if (ndi_dc_allochdl((void *)data, &dcp) != 12175 NDI_SUCCESS) { 12176 goto out; 12177 } 12178 addr = ndi_dc_getaddr(dcp); 12179 ptgt = mptsas_addr_to_ptgt(mpt, addr, phymask); 12180 if (ptgt == NULL) { 12181 NDBG14(("mptsas_ioctl led control: tgt %s not " 12182 "found", addr)); 12183 ndi_dc_freehdl(dcp); 12184 goto out; 12185 } 12186 mutex_enter(&mpt->m_mutex); 12187 if (cmd == DEVCTL_DEVICE_ONLINE) { 12188 ptgt->m_tgt_unconfigured = 0; 12189 } else if (cmd == DEVCTL_DEVICE_OFFLINE) { 12190 ptgt->m_tgt_unconfigured = 1; 12191 } 12192 if (cmd == DEVCTL_DEVICE_OFFLINE) { 12193 ptgt->m_led_status |= 12194 (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1)); 12195 } else { 12196 ptgt->m_led_status &= 12197 ~(1 << (MPTSAS_LEDCTL_LED_OK2RM - 1)); 12198 } 12199 if (mptsas_flush_led_status(mpt, ptgt) != DDI_SUCCESS) { 12200 NDBG14(("mptsas_ioctl: set LED for tgt %s " 12201 "failed %x", addr, slotstatus)); 12202 } 12203 mutex_exit(&mpt->m_mutex); 12204 ndi_dc_freehdl(dcp); 12205 } 12206 goto out; 12207 } 12208 switch (cmd) { 12209 case MPTIOCTL_GET_DISK_INFO: 12210 status = get_disk_info(mpt, data, mode); 12211 break; 12212 case MPTIOCTL_LED_CONTROL: 12213 status = led_control(mpt, data, mode); 12214 break; 12215 case MPTIOCTL_UPDATE_FLASH: 12216 if (ddi_copyin((void *)data, &flashdata, 12217 sizeof (struct mptsas_update_flash), mode)) { 12218 status = EFAULT; 12219 break; 12220 } 12221 12222 mutex_enter(&mpt->m_mutex); 12223 if (mptsas_update_flash(mpt, 12224 (caddr_t)(long)flashdata.PtrBuffer, 12225 flashdata.ImageSize, flashdata.ImageType, mode)) { 12226 status = EFAULT; 12227 } 12228 12229 /* 12230 * Reset the chip to start using the new 12231 * firmware. Reset if failed also. 12232 */ 12233 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 12234 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) { 12235 status = EFAULT; 12236 } 12237 mutex_exit(&mpt->m_mutex); 12238 break; 12239 case MPTIOCTL_PASS_THRU: 12240 /* 12241 * The user has requested to pass through a command to 12242 * be executed by the MPT firmware. Call our routine 12243 * which does this. Only allow one passthru IOCTL at 12244 * one time. Other threads will block on 12245 * m_passthru_mutex, which is of adaptive variant. 12246 */ 12247 if (ddi_copyin((void *)data, &passthru_data, 12248 sizeof (mptsas_pass_thru_t), mode)) { 12249 status = EFAULT; 12250 break; 12251 } 12252 mutex_enter(&mpt->m_passthru_mutex); 12253 mutex_enter(&mpt->m_mutex); 12254 status = mptsas_pass_thru(mpt, &passthru_data, mode); 12255 mutex_exit(&mpt->m_mutex); 12256 mutex_exit(&mpt->m_passthru_mutex); 12257 12258 break; 12259 case MPTIOCTL_GET_ADAPTER_DATA: 12260 /* 12261 * The user has requested to read adapter data. Call 12262 * our routine which does this. 12263 */ 12264 bzero(&adapter_data, sizeof (mptsas_adapter_data_t)); 12265 if (ddi_copyin((void *)data, (void *)&adapter_data, 12266 sizeof (mptsas_adapter_data_t), mode)) { 12267 status = EFAULT; 12268 break; 12269 } 12270 if (adapter_data.StructureLength >= 12271 sizeof (mptsas_adapter_data_t)) { 12272 adapter_data.StructureLength = (uint32_t) 12273 sizeof (mptsas_adapter_data_t); 12274 copylen = sizeof (mptsas_adapter_data_t); 12275 mutex_enter(&mpt->m_mutex); 12276 mptsas_read_adapter_data(mpt, &adapter_data); 12277 mutex_exit(&mpt->m_mutex); 12278 } else { 12279 adapter_data.StructureLength = (uint32_t) 12280 sizeof (mptsas_adapter_data_t); 12281 copylen = sizeof (adapter_data.StructureLength); 12282 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT; 12283 } 12284 if (ddi_copyout((void *)(&adapter_data), (void *)data, 12285 copylen, mode) != 0) { 12286 status = EFAULT; 12287 } 12288 break; 12289 case MPTIOCTL_GET_PCI_INFO: 12290 /* 12291 * The user has requested to read pci info. Call 12292 * our routine which does this. 12293 */ 12294 bzero(&pci_info, sizeof (mptsas_pci_info_t)); 12295 mutex_enter(&mpt->m_mutex); 12296 mptsas_read_pci_info(mpt, &pci_info); 12297 mutex_exit(&mpt->m_mutex); 12298 if (ddi_copyout((void *)(&pci_info), (void *)data, 12299 sizeof (mptsas_pci_info_t), mode) != 0) { 12300 status = EFAULT; 12301 } 12302 break; 12303 case MPTIOCTL_RESET_ADAPTER: 12304 mutex_enter(&mpt->m_mutex); 12305 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 12306 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 12307 mptsas_log(mpt, CE_WARN, "reset adapter IOCTL " 12308 "failed"); 12309 status = EFAULT; 12310 } 12311 mutex_exit(&mpt->m_mutex); 12312 break; 12313 case MPTIOCTL_DIAG_ACTION: 12314 /* 12315 * The user has done a diag buffer action. Call our 12316 * routine which does this. Only allow one diag action 12317 * at one time. 12318 */ 12319 mutex_enter(&mpt->m_mutex); 12320 if (mpt->m_diag_action_in_progress) { 12321 mutex_exit(&mpt->m_mutex); 12322 return (EBUSY); 12323 } 12324 mpt->m_diag_action_in_progress = 1; 12325 status = mptsas_diag_action(mpt, 12326 (mptsas_diag_action_t *)data, mode); 12327 mpt->m_diag_action_in_progress = 0; 12328 mutex_exit(&mpt->m_mutex); 12329 break; 12330 case MPTIOCTL_EVENT_QUERY: 12331 /* 12332 * The user has done an event query. Call our routine 12333 * which does this. 12334 */ 12335 status = mptsas_event_query(mpt, 12336 (mptsas_event_query_t *)data, mode, rval); 12337 break; 12338 case MPTIOCTL_EVENT_ENABLE: 12339 /* 12340 * The user has done an event enable. Call our routine 12341 * which does this. 12342 */ 12343 status = mptsas_event_enable(mpt, 12344 (mptsas_event_enable_t *)data, mode, rval); 12345 break; 12346 case MPTIOCTL_EVENT_REPORT: 12347 /* 12348 * The user has done an event report. Call our routine 12349 * which does this. 12350 */ 12351 status = mptsas_event_report(mpt, 12352 (mptsas_event_report_t *)data, mode, rval); 12353 break; 12354 case MPTIOCTL_REG_ACCESS: 12355 /* 12356 * The user has requested register access. Call our 12357 * routine which does this. 12358 */ 12359 status = mptsas_reg_access(mpt, 12360 (mptsas_reg_access_t *)data, mode); 12361 break; 12362 default: 12363 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, 12364 rval); 12365 break; 12366 } 12367 12368 out: 12369 if (mpt->m_options & MPTSAS_OPT_PM) 12370 (void) pm_idle_component(mpt->m_dip, 0); 12371 return (status); 12372 } 12373 12374 int 12375 mptsas_restart_ioc(mptsas_t *mpt) 12376 { 12377 int rval = DDI_SUCCESS; 12378 mptsas_target_t *ptgt = NULL; 12379 12380 ASSERT(mutex_owned(&mpt->m_mutex)); 12381 12382 /* 12383 * Set a flag telling I/O path that we're processing a reset. This is 12384 * needed because after the reset is complete, the hash table still 12385 * needs to be rebuilt. If I/Os are started before the hash table is 12386 * rebuilt, I/O errors will occur. This flag allows I/Os to be marked 12387 * so that they can be retried. 12388 */ 12389 mpt->m_in_reset = TRUE; 12390 12391 /* 12392 * Set all throttles to HOLD 12393 */ 12394 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 12395 MPTSAS_HASH_FIRST); 12396 while (ptgt != NULL) { 12397 mutex_enter(&ptgt->m_tgt_intr_mutex); 12398 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 12399 mutex_exit(&ptgt->m_tgt_intr_mutex); 12400 12401 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 12402 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 12403 } 12404 12405 /* 12406 * Disable interrupts 12407 */ 12408 MPTSAS_DISABLE_INTR(mpt); 12409 12410 /* 12411 * Abort all commands: outstanding commands, commands in waitq 12412 */ 12413 mptsas_flush_hba(mpt); 12414 12415 /* 12416 * Reinitialize the chip. 12417 */ 12418 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) { 12419 rval = DDI_FAILURE; 12420 } 12421 12422 /* 12423 * Enable interrupts again 12424 */ 12425 MPTSAS_ENABLE_INTR(mpt); 12426 12427 /* 12428 * If mptsas_init_chip was successful, update the driver data. 12429 */ 12430 if (rval == DDI_SUCCESS) { 12431 mptsas_update_driver_data(mpt); 12432 } 12433 12434 /* 12435 * Reset the throttles 12436 */ 12437 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 12438 MPTSAS_HASH_FIRST); 12439 while (ptgt != NULL) { 12440 mutex_enter(&ptgt->m_tgt_intr_mutex); 12441 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 12442 mutex_exit(&ptgt->m_tgt_intr_mutex); 12443 12444 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 12445 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 12446 } 12447 12448 mptsas_doneq_empty(mpt); 12449 mptsas_restart_hba(mpt); 12450 12451 if (rval != DDI_SUCCESS) { 12452 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 12453 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 12454 } 12455 12456 /* 12457 * Clear the reset flag so that I/Os can continue. 12458 */ 12459 mpt->m_in_reset = FALSE; 12460 12461 return (rval); 12462 } 12463 12464 static int 12465 mptsas_init_chip(mptsas_t *mpt, int first_time) 12466 { 12467 ddi_dma_cookie_t cookie; 12468 uint32_t i; 12469 int rval; 12470 12471 /* 12472 * Check to see if the firmware image is valid 12473 */ 12474 if (ddi_get32(mpt->m_datap, &mpt->m_reg->HostDiagnostic) & 12475 MPI2_DIAG_FLASH_BAD_SIG) { 12476 mptsas_log(mpt, CE_WARN, "mptsas bad flash signature!"); 12477 goto fail; 12478 } 12479 12480 /* 12481 * Reset the chip 12482 */ 12483 rval = mptsas_ioc_reset(mpt, first_time); 12484 if (rval == MPTSAS_RESET_FAIL) { 12485 mptsas_log(mpt, CE_WARN, "hard reset failed!"); 12486 goto fail; 12487 } 12488 12489 if ((rval == MPTSAS_SUCCESS_MUR) && (!first_time)) { 12490 goto mur; 12491 } 12492 /* 12493 * Setup configuration space 12494 */ 12495 if (mptsas_config_space_init(mpt) == FALSE) { 12496 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init " 12497 "failed!"); 12498 goto fail; 12499 } 12500 12501 /* 12502 * IOC facts can change after a diag reset so all buffers that are 12503 * based on these numbers must be de-allocated and re-allocated. Get 12504 * new IOC facts each time chip is initialized. 12505 */ 12506 if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) { 12507 mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed"); 12508 goto fail; 12509 } 12510 12511 if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) { 12512 goto fail; 12513 } 12514 /* 12515 * Allocate request message frames, reply free queue, reply descriptor 12516 * post queue, and reply message frames using latest IOC facts. 12517 */ 12518 if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) { 12519 mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed"); 12520 goto fail; 12521 } 12522 if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) { 12523 mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue failed!"); 12524 goto fail; 12525 } 12526 if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) { 12527 mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue failed!"); 12528 goto fail; 12529 } 12530 if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) { 12531 mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames failed!"); 12532 goto fail; 12533 } 12534 12535 mur: 12536 /* 12537 * Re-Initialize ioc to operational state 12538 */ 12539 if (mptsas_ioc_init(mpt) == DDI_FAILURE) { 12540 mptsas_log(mpt, CE_WARN, "mptsas_ioc_init failed"); 12541 goto fail; 12542 } 12543 12544 mptsas_alloc_reply_args(mpt); 12545 12546 /* 12547 * Initialize reply post index. Reply free index is initialized after 12548 * the next loop. 12549 */ 12550 mpt->m_post_index = 0; 12551 12552 /* 12553 * Initialize the Reply Free Queue with the physical addresses of our 12554 * reply frames. 12555 */ 12556 cookie.dmac_address = mpt->m_reply_frame_dma_addr; 12557 for (i = 0; i < mpt->m_max_replies; i++) { 12558 ddi_put32(mpt->m_acc_free_queue_hdl, 12559 &((uint32_t *)(void *)mpt->m_free_queue)[i], 12560 cookie.dmac_address); 12561 cookie.dmac_address += mpt->m_reply_frame_size; 12562 } 12563 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 12564 DDI_DMA_SYNC_FORDEV); 12565 12566 /* 12567 * Initialize the reply free index to one past the last frame on the 12568 * queue. This will signify that the queue is empty to start with. 12569 */ 12570 mpt->m_free_index = i; 12571 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, i); 12572 12573 /* 12574 * Initialize the reply post queue to 0xFFFFFFFF,0xFFFFFFFF's. 12575 */ 12576 for (i = 0; i < mpt->m_post_queue_depth; i++) { 12577 ddi_put64(mpt->m_acc_post_queue_hdl, 12578 &((uint64_t *)(void *)mpt->m_post_queue)[i], 12579 0xFFFFFFFFFFFFFFFF); 12580 } 12581 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 12582 DDI_DMA_SYNC_FORDEV); 12583 12584 /* 12585 * Enable ports 12586 */ 12587 if (mptsas_ioc_enable_port(mpt) == DDI_FAILURE) { 12588 mptsas_log(mpt, CE_WARN, "mptsas_ioc_enable_port failed"); 12589 goto fail; 12590 } 12591 12592 /* 12593 * enable events 12594 */ 12595 if (mptsas_ioc_enable_event_notification(mpt)) { 12596 goto fail; 12597 } 12598 12599 /* 12600 * We need checks in attach and these. 12601 * chip_init is called in mult. places 12602 */ 12603 12604 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 12605 DDI_SUCCESS) || 12606 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) != 12607 DDI_SUCCESS) || 12608 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) != 12609 DDI_SUCCESS) || 12610 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) != 12611 DDI_SUCCESS) || 12612 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) != 12613 DDI_SUCCESS)) { 12614 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 12615 goto fail; 12616 } 12617 12618 /* Check all acc handles */ 12619 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) || 12620 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 12621 DDI_SUCCESS) || 12622 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) != 12623 DDI_SUCCESS) || 12624 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) != 12625 DDI_SUCCESS) || 12626 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) != 12627 DDI_SUCCESS) || 12628 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) != 12629 DDI_SUCCESS) || 12630 (mptsas_check_acc_handle(mpt->m_config_handle) != 12631 DDI_SUCCESS)) { 12632 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 12633 goto fail; 12634 } 12635 12636 return (DDI_SUCCESS); 12637 12638 fail: 12639 return (DDI_FAILURE); 12640 } 12641 12642 static int 12643 mptsas_get_pci_cap(mptsas_t *mpt) 12644 { 12645 ushort_t caps_ptr, cap, cap_count; 12646 12647 if (mpt->m_config_handle == NULL) 12648 return (FALSE); 12649 /* 12650 * Check if capabilities list is supported and if so, 12651 * get initial capabilities pointer and clear bits 0,1. 12652 */ 12653 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) 12654 & PCI_STAT_CAP) { 12655 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle, 12656 PCI_CONF_CAP_PTR), 4); 12657 } else { 12658 caps_ptr = PCI_CAP_NEXT_PTR_NULL; 12659 } 12660 12661 /* 12662 * Walk capabilities if supported. 12663 */ 12664 for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) { 12665 12666 /* 12667 * Check that we haven't exceeded the maximum number of 12668 * capabilities and that the pointer is in a valid range. 12669 */ 12670 if (++cap_count > 48) { 12671 mptsas_log(mpt, CE_WARN, 12672 "too many device capabilities.\n"); 12673 break; 12674 } 12675 if (caps_ptr < 64) { 12676 mptsas_log(mpt, CE_WARN, 12677 "capabilities pointer 0x%x out of range.\n", 12678 caps_ptr); 12679 break; 12680 } 12681 12682 /* 12683 * Get next capability and check that it is valid. 12684 * For now, we only support power management. 12685 */ 12686 cap = pci_config_get8(mpt->m_config_handle, caps_ptr); 12687 switch (cap) { 12688 case PCI_CAP_ID_PM: 12689 mptsas_log(mpt, CE_NOTE, 12690 "?mptsas%d supports power management.\n", 12691 mpt->m_instance); 12692 mpt->m_options |= MPTSAS_OPT_PM; 12693 12694 /* Save PMCSR offset */ 12695 mpt->m_pmcsr_offset = caps_ptr + PCI_PMCSR; 12696 break; 12697 /* 12698 * The following capabilities are valid. Any others 12699 * will cause a message to be logged. 12700 */ 12701 case PCI_CAP_ID_VPD: 12702 case PCI_CAP_ID_MSI: 12703 case PCI_CAP_ID_PCIX: 12704 case PCI_CAP_ID_PCI_E: 12705 case PCI_CAP_ID_MSI_X: 12706 break; 12707 default: 12708 mptsas_log(mpt, CE_NOTE, 12709 "?mptsas%d unrecognized capability " 12710 "0x%x.\n", mpt->m_instance, cap); 12711 break; 12712 } 12713 12714 /* 12715 * Get next capabilities pointer and clear bits 0,1. 12716 */ 12717 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle, 12718 (caps_ptr + PCI_CAP_NEXT_PTR)), 4); 12719 } 12720 return (TRUE); 12721 } 12722 12723 static int 12724 mptsas_init_pm(mptsas_t *mpt) 12725 { 12726 char pmc_name[16]; 12727 char *pmc[] = { 12728 NULL, 12729 "0=Off (PCI D3 State)", 12730 "3=On (PCI D0 State)", 12731 NULL 12732 }; 12733 uint16_t pmcsr_stat; 12734 12735 if (mptsas_get_pci_cap(mpt) == FALSE) { 12736 return (DDI_FAILURE); 12737 } 12738 /* 12739 * If PCI's capability does not support PM, then don't need 12740 * to registe the pm-components 12741 */ 12742 if (!(mpt->m_options & MPTSAS_OPT_PM)) 12743 return (DDI_SUCCESS); 12744 /* 12745 * If power management is supported by this chip, create 12746 * pm-components property for the power management framework 12747 */ 12748 (void) sprintf(pmc_name, "NAME=mptsas%d", mpt->m_instance); 12749 pmc[0] = pmc_name; 12750 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, mpt->m_dip, 12751 "pm-components", pmc, 3) != DDI_PROP_SUCCESS) { 12752 mutex_enter(&mpt->m_intr_mutex); 12753 mpt->m_options &= ~MPTSAS_OPT_PM; 12754 mutex_exit(&mpt->m_intr_mutex); 12755 mptsas_log(mpt, CE_WARN, 12756 "mptsas%d: pm-component property creation failed.", 12757 mpt->m_instance); 12758 return (DDI_FAILURE); 12759 } 12760 12761 /* 12762 * Power on device. 12763 */ 12764 (void) pm_busy_component(mpt->m_dip, 0); 12765 pmcsr_stat = pci_config_get16(mpt->m_config_handle, 12766 mpt->m_pmcsr_offset); 12767 if ((pmcsr_stat & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_D0) { 12768 mptsas_log(mpt, CE_WARN, "mptsas%d: Power up the device", 12769 mpt->m_instance); 12770 pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset, 12771 PCI_PMCSR_D0); 12772 } 12773 if (pm_power_has_changed(mpt->m_dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) { 12774 mptsas_log(mpt, CE_WARN, "pm_power_has_changed failed"); 12775 return (DDI_FAILURE); 12776 } 12777 mutex_enter(&mpt->m_intr_mutex); 12778 mpt->m_power_level = PM_LEVEL_D0; 12779 mutex_exit(&mpt->m_intr_mutex); 12780 /* 12781 * Set pm idle delay. 12782 */ 12783 mpt->m_pm_idle_delay = ddi_prop_get_int(DDI_DEV_T_ANY, 12784 mpt->m_dip, 0, "mptsas-pm-idle-delay", MPTSAS_PM_IDLE_TIMEOUT); 12785 12786 return (DDI_SUCCESS); 12787 } 12788 12789 static int 12790 mptsas_register_intrs(mptsas_t *mpt) 12791 { 12792 dev_info_t *dip; 12793 int intr_types; 12794 12795 dip = mpt->m_dip; 12796 12797 /* Get supported interrupt types */ 12798 if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) { 12799 mptsas_log(mpt, CE_WARN, "ddi_intr_get_supported_types " 12800 "failed\n"); 12801 return (FALSE); 12802 } 12803 12804 NDBG6(("ddi_intr_get_supported_types() returned: 0x%x", intr_types)); 12805 12806 /* 12807 * Try MSI, but fall back to FIXED 12808 */ 12809 if (mptsas_enable_msi && (intr_types & DDI_INTR_TYPE_MSI)) { 12810 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_MSI) == DDI_SUCCESS) { 12811 NDBG0(("Using MSI interrupt type")); 12812 mpt->m_intr_type = DDI_INTR_TYPE_MSI; 12813 return (TRUE); 12814 } 12815 } 12816 if (intr_types & DDI_INTR_TYPE_FIXED) { 12817 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_FIXED) == DDI_SUCCESS) { 12818 NDBG0(("Using FIXED interrupt type")); 12819 mpt->m_intr_type = DDI_INTR_TYPE_FIXED; 12820 return (TRUE); 12821 } else { 12822 NDBG0(("FIXED interrupt registration failed")); 12823 return (FALSE); 12824 } 12825 } 12826 12827 return (FALSE); 12828 } 12829 12830 static void 12831 mptsas_unregister_intrs(mptsas_t *mpt) 12832 { 12833 mptsas_rem_intrs(mpt); 12834 } 12835 12836 /* 12837 * mptsas_add_intrs: 12838 * 12839 * Register FIXED or MSI interrupts. 12840 */ 12841 static int 12842 mptsas_add_intrs(mptsas_t *mpt, int intr_type) 12843 { 12844 dev_info_t *dip = mpt->m_dip; 12845 int avail, actual, count = 0; 12846 int i, flag, ret; 12847 12848 NDBG6(("mptsas_add_intrs:interrupt type 0x%x", intr_type)); 12849 12850 /* Get number of interrupts */ 12851 ret = ddi_intr_get_nintrs(dip, intr_type, &count); 12852 if ((ret != DDI_SUCCESS) || (count <= 0)) { 12853 mptsas_log(mpt, CE_WARN, "ddi_intr_get_nintrs() failed, " 12854 "ret %d count %d\n", ret, count); 12855 12856 return (DDI_FAILURE); 12857 } 12858 12859 /* Get number of available interrupts */ 12860 ret = ddi_intr_get_navail(dip, intr_type, &avail); 12861 if ((ret != DDI_SUCCESS) || (avail == 0)) { 12862 mptsas_log(mpt, CE_WARN, "ddi_intr_get_navail() failed, " 12863 "ret %d avail %d\n", ret, avail); 12864 12865 return (DDI_FAILURE); 12866 } 12867 12868 if (avail < count) { 12869 mptsas_log(mpt, CE_NOTE, "ddi_intr_get_nvail returned %d, " 12870 "navail() returned %d", count, avail); 12871 } 12872 12873 /* Mpt only have one interrupt routine */ 12874 if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) { 12875 count = 1; 12876 } 12877 12878 /* Allocate an array of interrupt handles */ 12879 mpt->m_intr_size = count * sizeof (ddi_intr_handle_t); 12880 mpt->m_htable = kmem_alloc(mpt->m_intr_size, KM_SLEEP); 12881 12882 flag = DDI_INTR_ALLOC_NORMAL; 12883 12884 /* call ddi_intr_alloc() */ 12885 ret = ddi_intr_alloc(dip, mpt->m_htable, intr_type, 0, 12886 count, &actual, flag); 12887 12888 if ((ret != DDI_SUCCESS) || (actual == 0)) { 12889 mptsas_log(mpt, CE_WARN, "ddi_intr_alloc() failed, ret %d\n", 12890 ret); 12891 kmem_free(mpt->m_htable, mpt->m_intr_size); 12892 return (DDI_FAILURE); 12893 } 12894 12895 /* use interrupt count returned or abort? */ 12896 if (actual < count) { 12897 mptsas_log(mpt, CE_NOTE, "Requested: %d, Received: %d\n", 12898 count, actual); 12899 } 12900 12901 mpt->m_intr_cnt = actual; 12902 12903 /* 12904 * Get priority for first msi, assume remaining are all the same 12905 */ 12906 if ((ret = ddi_intr_get_pri(mpt->m_htable[0], 12907 &mpt->m_intr_pri)) != DDI_SUCCESS) { 12908 mptsas_log(mpt, CE_WARN, "ddi_intr_get_pri() failed %d\n", ret); 12909 12910 /* Free already allocated intr */ 12911 for (i = 0; i < actual; i++) { 12912 (void) ddi_intr_free(mpt->m_htable[i]); 12913 } 12914 12915 kmem_free(mpt->m_htable, mpt->m_intr_size); 12916 return (DDI_FAILURE); 12917 } 12918 12919 /* Test for high level mutex */ 12920 if (mpt->m_intr_pri >= ddi_intr_get_hilevel_pri()) { 12921 mptsas_log(mpt, CE_WARN, "mptsas_add_intrs: " 12922 "Hi level interrupt not supported\n"); 12923 12924 /* Free already allocated intr */ 12925 for (i = 0; i < actual; i++) { 12926 (void) ddi_intr_free(mpt->m_htable[i]); 12927 } 12928 12929 kmem_free(mpt->m_htable, mpt->m_intr_size); 12930 return (DDI_FAILURE); 12931 } 12932 12933 /* Call ddi_intr_add_handler() */ 12934 for (i = 0; i < actual; i++) { 12935 if ((ret = ddi_intr_add_handler(mpt->m_htable[i], mptsas_intr, 12936 (caddr_t)mpt, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) { 12937 mptsas_log(mpt, CE_WARN, "ddi_intr_add_handler() " 12938 "failed %d\n", ret); 12939 12940 /* Free already allocated intr */ 12941 for (i = 0; i < actual; i++) { 12942 (void) ddi_intr_free(mpt->m_htable[i]); 12943 } 12944 12945 kmem_free(mpt->m_htable, mpt->m_intr_size); 12946 return (DDI_FAILURE); 12947 } 12948 } 12949 12950 if ((ret = ddi_intr_get_cap(mpt->m_htable[0], &mpt->m_intr_cap)) 12951 != DDI_SUCCESS) { 12952 mptsas_log(mpt, CE_WARN, "ddi_intr_get_cap() failed %d\n", ret); 12953 12954 /* Free already allocated intr */ 12955 for (i = 0; i < actual; i++) { 12956 (void) ddi_intr_free(mpt->m_htable[i]); 12957 } 12958 12959 kmem_free(mpt->m_htable, mpt->m_intr_size); 12960 return (DDI_FAILURE); 12961 } 12962 12963 /* 12964 * Enable interrupts 12965 */ 12966 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) { 12967 /* Call ddi_intr_block_enable() for MSI interrupts */ 12968 (void) ddi_intr_block_enable(mpt->m_htable, mpt->m_intr_cnt); 12969 } else { 12970 /* Call ddi_intr_enable for MSI or FIXED interrupts */ 12971 for (i = 0; i < mpt->m_intr_cnt; i++) { 12972 (void) ddi_intr_enable(mpt->m_htable[i]); 12973 } 12974 } 12975 return (DDI_SUCCESS); 12976 } 12977 12978 /* 12979 * mptsas_rem_intrs: 12980 * 12981 * Unregister FIXED or MSI interrupts 12982 */ 12983 static void 12984 mptsas_rem_intrs(mptsas_t *mpt) 12985 { 12986 int i; 12987 12988 NDBG6(("mptsas_rem_intrs")); 12989 12990 /* Disable all interrupts */ 12991 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) { 12992 /* Call ddi_intr_block_disable() */ 12993 (void) ddi_intr_block_disable(mpt->m_htable, mpt->m_intr_cnt); 12994 } else { 12995 for (i = 0; i < mpt->m_intr_cnt; i++) { 12996 (void) ddi_intr_disable(mpt->m_htable[i]); 12997 } 12998 } 12999 13000 /* Call ddi_intr_remove_handler() */ 13001 for (i = 0; i < mpt->m_intr_cnt; i++) { 13002 (void) ddi_intr_remove_handler(mpt->m_htable[i]); 13003 (void) ddi_intr_free(mpt->m_htable[i]); 13004 } 13005 13006 kmem_free(mpt->m_htable, mpt->m_intr_size); 13007 } 13008 13009 /* 13010 * The IO fault service error handling callback function 13011 */ 13012 /*ARGSUSED*/ 13013 static int 13014 mptsas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data) 13015 { 13016 /* 13017 * as the driver can always deal with an error in any dma or 13018 * access handle, we can just return the fme_status value. 13019 */ 13020 pci_ereport_post(dip, err, NULL); 13021 return (err->fme_status); 13022 } 13023 13024 /* 13025 * mptsas_fm_init - initialize fma capabilities and register with IO 13026 * fault services. 13027 */ 13028 static void 13029 mptsas_fm_init(mptsas_t *mpt) 13030 { 13031 /* 13032 * Need to change iblock to priority for new MSI intr 13033 */ 13034 ddi_iblock_cookie_t fm_ibc; 13035 13036 /* Only register with IO Fault Services if we have some capability */ 13037 if (mpt->m_fm_capabilities) { 13038 /* Adjust access and dma attributes for FMA */ 13039 mpt->m_reg_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC; 13040 mpt->m_msg_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 13041 mpt->m_io_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 13042 13043 /* 13044 * Register capabilities with IO Fault Services. 13045 * mpt->m_fm_capabilities will be updated to indicate 13046 * capabilities actually supported (not requested.) 13047 */ 13048 ddi_fm_init(mpt->m_dip, &mpt->m_fm_capabilities, &fm_ibc); 13049 13050 /* 13051 * Initialize pci ereport capabilities if ereport 13052 * capable (should always be.) 13053 */ 13054 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) || 13055 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 13056 pci_ereport_setup(mpt->m_dip); 13057 } 13058 13059 /* 13060 * Register error callback if error callback capable. 13061 */ 13062 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 13063 ddi_fm_handler_register(mpt->m_dip, 13064 mptsas_fm_error_cb, (void *) mpt); 13065 } 13066 } 13067 } 13068 13069 /* 13070 * mptsas_fm_fini - Releases fma capabilities and un-registers with IO 13071 * fault services. 13072 * 13073 */ 13074 static void 13075 mptsas_fm_fini(mptsas_t *mpt) 13076 { 13077 /* Only unregister FMA capabilities if registered */ 13078 if (mpt->m_fm_capabilities) { 13079 13080 /* 13081 * Un-register error callback if error callback capable. 13082 */ 13083 13084 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 13085 ddi_fm_handler_unregister(mpt->m_dip); 13086 } 13087 13088 /* 13089 * Release any resources allocated by pci_ereport_setup() 13090 */ 13091 13092 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) || 13093 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 13094 pci_ereport_teardown(mpt->m_dip); 13095 } 13096 13097 /* Unregister from IO Fault Services */ 13098 ddi_fm_fini(mpt->m_dip); 13099 13100 /* Adjust access and dma attributes for FMA */ 13101 mpt->m_reg_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC; 13102 mpt->m_msg_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 13103 mpt->m_io_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 13104 13105 } 13106 } 13107 13108 int 13109 mptsas_check_acc_handle(ddi_acc_handle_t handle) 13110 { 13111 ddi_fm_error_t de; 13112 13113 if (handle == NULL) 13114 return (DDI_FAILURE); 13115 ddi_fm_acc_err_get(handle, &de, DDI_FME_VER0); 13116 return (de.fme_status); 13117 } 13118 13119 int 13120 mptsas_check_dma_handle(ddi_dma_handle_t handle) 13121 { 13122 ddi_fm_error_t de; 13123 13124 if (handle == NULL) 13125 return (DDI_FAILURE); 13126 ddi_fm_dma_err_get(handle, &de, DDI_FME_VER0); 13127 return (de.fme_status); 13128 } 13129 13130 void 13131 mptsas_fm_ereport(mptsas_t *mpt, char *detail) 13132 { 13133 uint64_t ena; 13134 char buf[FM_MAX_CLASS]; 13135 13136 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail); 13137 ena = fm_ena_generate(0, FM_ENA_FMT1); 13138 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities)) { 13139 ddi_fm_ereport_post(mpt->m_dip, buf, ena, DDI_NOSLEEP, 13140 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL); 13141 } 13142 } 13143 13144 static int 13145 mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address, 13146 uint16_t *dev_handle, mptsas_target_t **pptgt) 13147 { 13148 int rval; 13149 uint32_t dev_info; 13150 uint64_t sas_wwn; 13151 mptsas_phymask_t phymask; 13152 uint8_t physport, phynum, config, disk; 13153 mptsas_slots_t *slots = mpt->m_active; 13154 uint64_t devicename; 13155 uint16_t pdev_hdl; 13156 mptsas_target_t *tmp_tgt = NULL; 13157 uint16_t bay_num, enclosure; 13158 13159 ASSERT(*pptgt == NULL); 13160 13161 rval = mptsas_get_sas_device_page0(mpt, page_address, dev_handle, 13162 &sas_wwn, &dev_info, &physport, &phynum, &pdev_hdl, 13163 &bay_num, &enclosure); 13164 if (rval != DDI_SUCCESS) { 13165 rval = DEV_INFO_FAIL_PAGE0; 13166 return (rval); 13167 } 13168 13169 if ((dev_info & (MPI2_SAS_DEVICE_INFO_SSP_TARGET | 13170 MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 13171 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) == NULL) { 13172 rval = DEV_INFO_WRONG_DEVICE_TYPE; 13173 return (rval); 13174 } 13175 13176 /* 13177 * Check if the dev handle is for a Phys Disk. If so, set return value 13178 * and exit. Don't add Phys Disks to hash. 13179 */ 13180 for (config = 0; config < slots->m_num_raid_configs; config++) { 13181 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) { 13182 if (*dev_handle == slots->m_raidconfig[config]. 13183 m_physdisk_devhdl[disk]) { 13184 rval = DEV_INFO_PHYS_DISK; 13185 return (rval); 13186 } 13187 } 13188 } 13189 13190 /* 13191 * Get SATA Device Name from SAS device page0 for 13192 * sata device, if device name doesn't exist, set m_sas_wwn to 13193 * 0 for direct attached SATA. For the device behind the expander 13194 * we still can use STP address assigned by expander. 13195 */ 13196 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 13197 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 13198 mutex_exit(&mpt->m_mutex); 13199 /* alloc a tmp_tgt to send the cmd */ 13200 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), 13201 KM_SLEEP); 13202 tmp_tgt->m_devhdl = *dev_handle; 13203 tmp_tgt->m_deviceinfo = dev_info; 13204 tmp_tgt->m_qfull_retries = QFULL_RETRIES; 13205 tmp_tgt->m_qfull_retry_interval = 13206 drv_usectohz(QFULL_RETRY_INTERVAL * 1000); 13207 tmp_tgt->m_t_throttle = MAX_THROTTLE; 13208 devicename = mptsas_get_sata_guid(mpt, tmp_tgt, 0); 13209 kmem_free(tmp_tgt, sizeof (struct mptsas_target)); 13210 mutex_enter(&mpt->m_mutex); 13211 if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) { 13212 sas_wwn = devicename; 13213 } else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) { 13214 sas_wwn = 0; 13215 } 13216 } 13217 13218 phymask = mptsas_physport_to_phymask(mpt, physport); 13219 *pptgt = mptsas_tgt_alloc(&slots->m_tgttbl, *dev_handle, sas_wwn, 13220 dev_info, phymask, phynum, mpt); 13221 if (*pptgt == NULL) { 13222 mptsas_log(mpt, CE_WARN, "Failed to allocated target" 13223 "structure!"); 13224 rval = DEV_INFO_FAIL_ALLOC; 13225 return (rval); 13226 } 13227 (*pptgt)->m_enclosure = enclosure; 13228 (*pptgt)->m_slot_num = bay_num; 13229 return (DEV_INFO_SUCCESS); 13230 } 13231 13232 uint64_t 13233 mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun) 13234 { 13235 uint64_t sata_guid = 0, *pwwn = NULL; 13236 int target = ptgt->m_devhdl; 13237 uchar_t *inq83 = NULL; 13238 int inq83_len = 0xFF; 13239 uchar_t *dblk = NULL; 13240 int inq83_retry = 3; 13241 int rval = DDI_FAILURE; 13242 13243 inq83 = kmem_zalloc(inq83_len, KM_SLEEP); 13244 13245 inq83_retry: 13246 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83, 13247 inq83_len, NULL, 1); 13248 if (rval != DDI_SUCCESS) { 13249 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 13250 "0x83 for target:%x, lun:%x failed!", target, lun); 13251 goto out; 13252 } 13253 /* According to SAT2, the first descriptor is logic unit name */ 13254 dblk = &inq83[4]; 13255 if ((dblk[1] & 0x30) != 0) { 13256 mptsas_log(mpt, CE_WARN, "!Descriptor is not lun associated."); 13257 goto out; 13258 } 13259 pwwn = (uint64_t *)(void *)(&dblk[4]); 13260 if ((dblk[4] & 0xf0) == 0x50) { 13261 sata_guid = BE_64(*pwwn); 13262 goto out; 13263 } else if (dblk[4] == 'A') { 13264 NDBG20(("SATA drive has no NAA format GUID.")); 13265 goto out; 13266 } else { 13267 /* The data is not ready, wait and retry */ 13268 inq83_retry--; 13269 if (inq83_retry <= 0) { 13270 goto out; 13271 } 13272 NDBG20(("The GUID is not ready, retry...")); 13273 delay(1 * drv_usectohz(1000000)); 13274 goto inq83_retry; 13275 } 13276 out: 13277 kmem_free(inq83, inq83_len); 13278 return (sata_guid); 13279 } 13280 13281 static int 13282 mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, uchar_t page, 13283 unsigned char *buf, int len, int *reallen, uchar_t evpd) 13284 { 13285 uchar_t cdb[CDB_GROUP0]; 13286 struct scsi_address ap; 13287 struct buf *data_bp = NULL; 13288 int resid = 0; 13289 int ret = DDI_FAILURE; 13290 13291 ASSERT(len <= 0xffff); 13292 13293 ap.a_target = MPTSAS_INVALID_DEVHDL; 13294 ap.a_lun = (uchar_t)(lun); 13295 ap.a_hba_tran = mpt->m_tran; 13296 13297 data_bp = scsi_alloc_consistent_buf(&ap, 13298 (struct buf *)NULL, len, B_READ, NULL_FUNC, NULL); 13299 if (data_bp == NULL) { 13300 return (ret); 13301 } 13302 bzero(cdb, CDB_GROUP0); 13303 cdb[0] = SCMD_INQUIRY; 13304 cdb[1] = evpd; 13305 cdb[2] = page; 13306 cdb[3] = (len & 0xff00) >> 8; 13307 cdb[4] = (len & 0x00ff); 13308 cdb[5] = 0; 13309 13310 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP0, data_bp, 13311 &resid); 13312 if (ret == DDI_SUCCESS) { 13313 if (reallen) { 13314 *reallen = len - resid; 13315 } 13316 bcopy((caddr_t)data_bp->b_un.b_addr, buf, len); 13317 } 13318 if (data_bp) { 13319 scsi_free_consistent_buf(data_bp); 13320 } 13321 return (ret); 13322 } 13323 13324 static int 13325 mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap, 13326 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp, 13327 int *resid) 13328 { 13329 struct scsi_pkt *pktp = NULL; 13330 scsi_hba_tran_t *tran_clone = NULL; 13331 mptsas_tgt_private_t *tgt_private = NULL; 13332 int ret = DDI_FAILURE; 13333 13334 /* 13335 * scsi_hba_tran_t->tran_tgt_private is used to pass the address 13336 * information to scsi_init_pkt, allocate a scsi_hba_tran structure 13337 * to simulate the cmds from sd 13338 */ 13339 tran_clone = kmem_alloc( 13340 sizeof (scsi_hba_tran_t), KM_SLEEP); 13341 if (tran_clone == NULL) { 13342 goto out; 13343 } 13344 bcopy((caddr_t)mpt->m_tran, 13345 (caddr_t)tran_clone, sizeof (scsi_hba_tran_t)); 13346 tgt_private = kmem_alloc( 13347 sizeof (mptsas_tgt_private_t), KM_SLEEP); 13348 if (tgt_private == NULL) { 13349 goto out; 13350 } 13351 tgt_private->t_lun = ap->a_lun; 13352 tgt_private->t_private = ptgt; 13353 tran_clone->tran_tgt_private = tgt_private; 13354 ap->a_hba_tran = tran_clone; 13355 13356 pktp = scsi_init_pkt(ap, (struct scsi_pkt *)NULL, 13357 data_bp, cdblen, sizeof (struct scsi_arq_status), 13358 0, PKT_CONSISTENT, NULL, NULL); 13359 if (pktp == NULL) { 13360 goto out; 13361 } 13362 bcopy(cdb, pktp->pkt_cdbp, cdblen); 13363 pktp->pkt_flags = FLAG_NOPARITY; 13364 if (scsi_poll(pktp) < 0) { 13365 goto out; 13366 } 13367 if (((struct scsi_status *)pktp->pkt_scbp)->sts_chk) { 13368 goto out; 13369 } 13370 if (resid != NULL) { 13371 *resid = pktp->pkt_resid; 13372 } 13373 13374 ret = DDI_SUCCESS; 13375 out: 13376 if (pktp) { 13377 scsi_destroy_pkt(pktp); 13378 } 13379 if (tran_clone) { 13380 kmem_free(tran_clone, sizeof (scsi_hba_tran_t)); 13381 } 13382 if (tgt_private) { 13383 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t)); 13384 } 13385 return (ret); 13386 } 13387 static int 13388 mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, int *lun) 13389 { 13390 char *cp = NULL; 13391 char *ptr = NULL; 13392 size_t s = 0; 13393 char *wwid_str = NULL; 13394 char *lun_str = NULL; 13395 long lunnum; 13396 long phyid = -1; 13397 int rc = DDI_FAILURE; 13398 13399 ptr = name; 13400 ASSERT(ptr[0] == 'w' || ptr[0] == 'p'); 13401 ptr++; 13402 if ((cp = strchr(ptr, ',')) == NULL) { 13403 return (DDI_FAILURE); 13404 } 13405 13406 wwid_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13407 s = (uintptr_t)cp - (uintptr_t)ptr; 13408 13409 bcopy(ptr, wwid_str, s); 13410 wwid_str[s] = '\0'; 13411 13412 ptr = ++cp; 13413 13414 if ((cp = strchr(ptr, '\0')) == NULL) { 13415 goto out; 13416 } 13417 lun_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13418 s = (uintptr_t)cp - (uintptr_t)ptr; 13419 13420 bcopy(ptr, lun_str, s); 13421 lun_str[s] = '\0'; 13422 13423 if (name[0] == 'p') { 13424 rc = ddi_strtol(wwid_str, NULL, 0x10, &phyid); 13425 } else { 13426 rc = scsi_wwnstr_to_wwn(wwid_str, wwid); 13427 } 13428 if (rc != DDI_SUCCESS) 13429 goto out; 13430 13431 if (phyid != -1) { 13432 ASSERT(phyid < MPTSAS_MAX_PHYS); 13433 *phy = (uint8_t)phyid; 13434 } 13435 rc = ddi_strtol(lun_str, NULL, 0x10, &lunnum); 13436 if (rc != 0) 13437 goto out; 13438 13439 *lun = (int)lunnum; 13440 rc = DDI_SUCCESS; 13441 out: 13442 if (wwid_str) 13443 kmem_free(wwid_str, SCSI_MAXNAMELEN); 13444 if (lun_str) 13445 kmem_free(lun_str, SCSI_MAXNAMELEN); 13446 13447 return (rc); 13448 } 13449 13450 /* 13451 * mptsas_parse_smp_name() is to parse sas wwn string 13452 * which format is "wWWN" 13453 */ 13454 static int 13455 mptsas_parse_smp_name(char *name, uint64_t *wwn) 13456 { 13457 char *ptr = name; 13458 13459 if (*ptr != 'w') { 13460 return (DDI_FAILURE); 13461 } 13462 13463 ptr++; 13464 if (scsi_wwnstr_to_wwn(ptr, wwn)) { 13465 return (DDI_FAILURE); 13466 } 13467 return (DDI_SUCCESS); 13468 } 13469 13470 static int 13471 mptsas_bus_config(dev_info_t *pdip, uint_t flag, 13472 ddi_bus_config_op_t op, void *arg, dev_info_t **childp) 13473 { 13474 int ret = NDI_FAILURE; 13475 int circ = 0; 13476 int circ1 = 0; 13477 mptsas_t *mpt; 13478 char *ptr = NULL; 13479 char *devnm = NULL; 13480 uint64_t wwid = 0; 13481 uint8_t phy = 0xFF; 13482 int lun = 0; 13483 uint_t mflags = flag; 13484 int bconfig = TRUE; 13485 13486 if (scsi_hba_iport_unit_address(pdip) == 0) { 13487 return (DDI_FAILURE); 13488 } 13489 13490 mpt = DIP2MPT(pdip); 13491 if (!mpt) { 13492 return (DDI_FAILURE); 13493 } 13494 /* 13495 * Hold the nexus across the bus_config 13496 */ 13497 ndi_devi_enter(scsi_vhci_dip, &circ); 13498 ndi_devi_enter(pdip, &circ1); 13499 switch (op) { 13500 case BUS_CONFIG_ONE: 13501 /* parse wwid/target name out of name given */ 13502 if ((ptr = strchr((char *)arg, '@')) == NULL) { 13503 ret = NDI_FAILURE; 13504 break; 13505 } 13506 ptr++; 13507 if (strncmp((char *)arg, "smp", 3) == 0) { 13508 /* 13509 * This is a SMP target device 13510 */ 13511 ret = mptsas_parse_smp_name(ptr, &wwid); 13512 if (ret != DDI_SUCCESS) { 13513 ret = NDI_FAILURE; 13514 break; 13515 } 13516 ret = mptsas_config_smp(pdip, wwid, childp); 13517 } else if ((ptr[0] == 'w') || (ptr[0] == 'p')) { 13518 /* 13519 * OBP could pass down a non-canonical form 13520 * bootpath without LUN part when LUN is 0. 13521 * So driver need adjust the string. 13522 */ 13523 if (strchr(ptr, ',') == NULL) { 13524 devnm = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13525 (void) sprintf(devnm, "%s,0", (char *)arg); 13526 ptr = strchr(devnm, '@'); 13527 ptr++; 13528 } 13529 13530 /* 13531 * The device path is wWWID format and the device 13532 * is not SMP target device. 13533 */ 13534 ret = mptsas_parse_address(ptr, &wwid, &phy, &lun); 13535 if (ret != DDI_SUCCESS) { 13536 ret = NDI_FAILURE; 13537 break; 13538 } 13539 *childp = NULL; 13540 if (ptr[0] == 'w') { 13541 ret = mptsas_config_one_addr(pdip, wwid, 13542 lun, childp); 13543 } else if (ptr[0] == 'p') { 13544 ret = mptsas_config_one_phy(pdip, phy, lun, 13545 childp); 13546 } 13547 13548 /* 13549 * If this is CD/DVD device in OBP path, the 13550 * ndi_busop_bus_config can be skipped as config one 13551 * operation is done above. 13552 */ 13553 if ((ret == NDI_SUCCESS) && (*childp != NULL) && 13554 (strcmp(ddi_node_name(*childp), "cdrom") == 0) && 13555 (strncmp((char *)arg, "disk", 4) == 0)) { 13556 bconfig = FALSE; 13557 ndi_hold_devi(*childp); 13558 } 13559 } else { 13560 ret = NDI_FAILURE; 13561 break; 13562 } 13563 13564 /* 13565 * DDI group instructed us to use this flag. 13566 */ 13567 mflags |= NDI_MDI_FALLBACK; 13568 break; 13569 case BUS_CONFIG_DRIVER: 13570 case BUS_CONFIG_ALL: 13571 mptsas_config_all(pdip); 13572 ret = NDI_SUCCESS; 13573 break; 13574 } 13575 13576 if ((ret == NDI_SUCCESS) && bconfig) { 13577 ret = ndi_busop_bus_config(pdip, mflags, op, 13578 (devnm == NULL) ? arg : devnm, childp, 0); 13579 } 13580 13581 ndi_devi_exit(pdip, circ1); 13582 ndi_devi_exit(scsi_vhci_dip, circ); 13583 if (devnm != NULL) 13584 kmem_free(devnm, SCSI_MAXNAMELEN); 13585 return (ret); 13586 } 13587 13588 static int 13589 mptsas_probe_lun(dev_info_t *pdip, int lun, dev_info_t **dip, 13590 mptsas_target_t *ptgt) 13591 { 13592 int rval = DDI_FAILURE; 13593 struct scsi_inquiry *sd_inq = NULL; 13594 mptsas_t *mpt = DIP2MPT(pdip); 13595 13596 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP); 13597 13598 rval = mptsas_inquiry(mpt, ptgt, lun, 0, (uchar_t *)sd_inq, 13599 SUN_INQSIZE, 0, (uchar_t)0); 13600 13601 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) { 13602 rval = mptsas_create_lun(pdip, sd_inq, dip, ptgt, lun); 13603 } else { 13604 rval = DDI_FAILURE; 13605 } 13606 13607 kmem_free(sd_inq, SUN_INQSIZE); 13608 return (rval); 13609 } 13610 13611 static int 13612 mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun, 13613 dev_info_t **lundip) 13614 { 13615 int rval; 13616 mptsas_t *mpt = DIP2MPT(pdip); 13617 int phymask; 13618 mptsas_target_t *ptgt = NULL; 13619 13620 /* 13621 * Get the physical port associated to the iport 13622 */ 13623 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 13624 "phymask", 0); 13625 13626 ptgt = mptsas_wwid_to_ptgt(mpt, phymask, sasaddr); 13627 if (ptgt == NULL) { 13628 /* 13629 * didn't match any device by searching 13630 */ 13631 return (DDI_FAILURE); 13632 } 13633 /* 13634 * If the LUN already exists and the status is online, 13635 * we just return the pointer to dev_info_t directly. 13636 * For the mdi_pathinfo node, we'll handle it in 13637 * mptsas_create_virt_lun() 13638 * TODO should be also in mptsas_handle_dr 13639 */ 13640 13641 *lundip = mptsas_find_child_addr(pdip, sasaddr, lun); 13642 if (*lundip != NULL) { 13643 /* 13644 * TODO Another senario is, we hotplug the same disk 13645 * on the same slot, the devhdl changed, is this 13646 * possible? 13647 * tgt_private->t_private != ptgt 13648 */ 13649 if (sasaddr != ptgt->m_sas_wwn) { 13650 /* 13651 * The device has changed although the devhdl is the 13652 * same (Enclosure mapping mode, change drive on the 13653 * same slot) 13654 */ 13655 return (DDI_FAILURE); 13656 } 13657 return (DDI_SUCCESS); 13658 } 13659 13660 if (phymask == 0) { 13661 /* 13662 * Configure IR volume 13663 */ 13664 rval = mptsas_config_raid(pdip, ptgt->m_devhdl, lundip); 13665 return (rval); 13666 } 13667 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt); 13668 13669 return (rval); 13670 } 13671 13672 static int 13673 mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun, 13674 dev_info_t **lundip) 13675 { 13676 int rval; 13677 mptsas_t *mpt = DIP2MPT(pdip); 13678 int phymask; 13679 mptsas_target_t *ptgt = NULL; 13680 13681 /* 13682 * Get the physical port associated to the iport 13683 */ 13684 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 13685 "phymask", 0); 13686 13687 ptgt = mptsas_phy_to_tgt(mpt, phymask, phy); 13688 if (ptgt == NULL) { 13689 /* 13690 * didn't match any device by searching 13691 */ 13692 return (DDI_FAILURE); 13693 } 13694 13695 /* 13696 * If the LUN already exists and the status is online, 13697 * we just return the pointer to dev_info_t directly. 13698 * For the mdi_pathinfo node, we'll handle it in 13699 * mptsas_create_virt_lun(). 13700 */ 13701 13702 *lundip = mptsas_find_child_phy(pdip, phy); 13703 if (*lundip != NULL) { 13704 return (DDI_SUCCESS); 13705 } 13706 13707 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt); 13708 13709 return (rval); 13710 } 13711 13712 static int 13713 mptsas_retrieve_lundata(int lun_cnt, uint8_t *buf, uint16_t *lun_num, 13714 uint8_t *lun_addr_type) 13715 { 13716 uint32_t lun_idx = 0; 13717 13718 ASSERT(lun_num != NULL); 13719 ASSERT(lun_addr_type != NULL); 13720 13721 lun_idx = (lun_cnt + 1) * MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE; 13722 /* determine report luns addressing type */ 13723 switch (buf[lun_idx] & MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) { 13724 /* 13725 * Vendors in the field have been found to be concatenating 13726 * bus/target/lun to equal the complete lun value instead 13727 * of switching to flat space addressing 13728 */ 13729 /* 00b - peripheral device addressing method */ 13730 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_PERIPHERAL: 13731 /* FALLTHRU */ 13732 /* 10b - logical unit addressing method */ 13733 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT: 13734 /* FALLTHRU */ 13735 /* 01b - flat space addressing method */ 13736 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE: 13737 /* byte0 bit0-5=msb lun byte1 bit0-7=lsb lun */ 13738 *lun_addr_type = (buf[lun_idx] & 13739 MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) >> 6; 13740 *lun_num = (buf[lun_idx] & 0x3F) << 8; 13741 *lun_num |= buf[lun_idx + 1]; 13742 return (DDI_SUCCESS); 13743 default: 13744 return (DDI_FAILURE); 13745 } 13746 } 13747 13748 static int 13749 mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt) 13750 { 13751 struct buf *repluns_bp = NULL; 13752 struct scsi_address ap; 13753 uchar_t cdb[CDB_GROUP5]; 13754 int ret = DDI_FAILURE; 13755 int retry = 0; 13756 int lun_list_len = 0; 13757 uint16_t lun_num = 0; 13758 uint8_t lun_addr_type = 0; 13759 uint32_t lun_cnt = 0; 13760 uint32_t lun_total = 0; 13761 dev_info_t *cdip = NULL; 13762 uint16_t *saved_repluns = NULL; 13763 char *buffer = NULL; 13764 int buf_len = 128; 13765 mptsas_t *mpt = DIP2MPT(pdip); 13766 uint64_t sas_wwn = 0; 13767 uint8_t phy = 0xFF; 13768 uint32_t dev_info = 0; 13769 13770 mutex_enter(&mpt->m_mutex); 13771 sas_wwn = ptgt->m_sas_wwn; 13772 phy = ptgt->m_phynum; 13773 dev_info = ptgt->m_deviceinfo; 13774 mutex_exit(&mpt->m_mutex); 13775 13776 if (sas_wwn == 0) { 13777 /* 13778 * It's a SATA without Device Name 13779 * So don't try multi-LUNs 13780 */ 13781 if (mptsas_find_child_phy(pdip, phy)) { 13782 return (DDI_SUCCESS); 13783 } else { 13784 /* 13785 * need configure and create node 13786 */ 13787 return (DDI_FAILURE); 13788 } 13789 } 13790 13791 /* 13792 * WWN (SAS address or Device Name exist) 13793 */ 13794 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 13795 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 13796 /* 13797 * SATA device with Device Name 13798 * So don't try multi-LUNs 13799 */ 13800 if (mptsas_find_child_addr(pdip, sas_wwn, 0)) { 13801 return (DDI_SUCCESS); 13802 } else { 13803 return (DDI_FAILURE); 13804 } 13805 } 13806 13807 do { 13808 ap.a_target = MPTSAS_INVALID_DEVHDL; 13809 ap.a_lun = 0; 13810 ap.a_hba_tran = mpt->m_tran; 13811 repluns_bp = scsi_alloc_consistent_buf(&ap, 13812 (struct buf *)NULL, buf_len, B_READ, NULL_FUNC, NULL); 13813 if (repluns_bp == NULL) { 13814 retry++; 13815 continue; 13816 } 13817 bzero(cdb, CDB_GROUP5); 13818 cdb[0] = SCMD_REPORT_LUNS; 13819 cdb[6] = (buf_len & 0xff000000) >> 24; 13820 cdb[7] = (buf_len & 0x00ff0000) >> 16; 13821 cdb[8] = (buf_len & 0x0000ff00) >> 8; 13822 cdb[9] = (buf_len & 0x000000ff); 13823 13824 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP5, 13825 repluns_bp, NULL); 13826 if (ret != DDI_SUCCESS) { 13827 scsi_free_consistent_buf(repluns_bp); 13828 retry++; 13829 continue; 13830 } 13831 lun_list_len = BE_32(*(int *)((void *)( 13832 repluns_bp->b_un.b_addr))); 13833 if (buf_len >= lun_list_len + 8) { 13834 ret = DDI_SUCCESS; 13835 break; 13836 } 13837 scsi_free_consistent_buf(repluns_bp); 13838 buf_len = lun_list_len + 8; 13839 13840 } while (retry < 3); 13841 13842 if (ret != DDI_SUCCESS) 13843 return (ret); 13844 buffer = (char *)repluns_bp->b_un.b_addr; 13845 /* 13846 * find out the number of luns returned by the SCSI ReportLun call 13847 * and allocate buffer space 13848 */ 13849 lun_total = lun_list_len / MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE; 13850 saved_repluns = kmem_zalloc(sizeof (uint16_t) * lun_total, KM_SLEEP); 13851 if (saved_repluns == NULL) { 13852 scsi_free_consistent_buf(repluns_bp); 13853 return (DDI_FAILURE); 13854 } 13855 for (lun_cnt = 0; lun_cnt < lun_total; lun_cnt++) { 13856 if (mptsas_retrieve_lundata(lun_cnt, (uint8_t *)(buffer), 13857 &lun_num, &lun_addr_type) != DDI_SUCCESS) { 13858 continue; 13859 } 13860 saved_repluns[lun_cnt] = lun_num; 13861 if (cdip = mptsas_find_child_addr(pdip, sas_wwn, lun_num)) 13862 ret = DDI_SUCCESS; 13863 else 13864 ret = mptsas_probe_lun(pdip, lun_num, &cdip, 13865 ptgt); 13866 if ((ret == DDI_SUCCESS) && (cdip != NULL)) { 13867 (void) ndi_prop_remove(DDI_DEV_T_NONE, cdip, 13868 MPTSAS_DEV_GONE); 13869 } 13870 } 13871 mptsas_offline_missed_luns(pdip, saved_repluns, lun_total, ptgt); 13872 kmem_free(saved_repluns, sizeof (uint16_t) * lun_total); 13873 scsi_free_consistent_buf(repluns_bp); 13874 return (DDI_SUCCESS); 13875 } 13876 13877 static int 13878 mptsas_config_raid(dev_info_t *pdip, uint16_t target, dev_info_t **dip) 13879 { 13880 int rval = DDI_FAILURE; 13881 struct scsi_inquiry *sd_inq = NULL; 13882 mptsas_t *mpt = DIP2MPT(pdip); 13883 mptsas_target_t *ptgt = NULL; 13884 13885 mutex_enter(&mpt->m_mutex); 13886 ptgt = mptsas_search_by_devhdl(&mpt->m_active->m_tgttbl, target); 13887 mutex_exit(&mpt->m_mutex); 13888 if (ptgt == NULL) { 13889 mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x " 13890 "not found.", target); 13891 return (rval); 13892 } 13893 13894 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP); 13895 rval = mptsas_inquiry(mpt, ptgt, 0, 0, (uchar_t *)sd_inq, 13896 SUN_INQSIZE, 0, (uchar_t)0); 13897 13898 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) { 13899 rval = mptsas_create_phys_lun(pdip, sd_inq, NULL, dip, ptgt, 13900 0); 13901 } else { 13902 rval = DDI_FAILURE; 13903 } 13904 13905 kmem_free(sd_inq, SUN_INQSIZE); 13906 return (rval); 13907 } 13908 13909 /* 13910 * configure all RAID volumes for virtual iport 13911 */ 13912 static void 13913 mptsas_config_all_viport(dev_info_t *pdip) 13914 { 13915 mptsas_t *mpt = DIP2MPT(pdip); 13916 int config, vol; 13917 int target; 13918 dev_info_t *lundip = NULL; 13919 mptsas_slots_t *slots = mpt->m_active; 13920 13921 /* 13922 * Get latest RAID info and search for any Volume DevHandles. If any 13923 * are found, configure the volume. 13924 */ 13925 mutex_enter(&mpt->m_mutex); 13926 for (config = 0; config < slots->m_num_raid_configs; config++) { 13927 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) { 13928 if (slots->m_raidconfig[config].m_raidvol[vol].m_israid 13929 == 1) { 13930 target = slots->m_raidconfig[config]. 13931 m_raidvol[vol].m_raidhandle; 13932 mutex_exit(&mpt->m_mutex); 13933 (void) mptsas_config_raid(pdip, target, 13934 &lundip); 13935 mutex_enter(&mpt->m_mutex); 13936 } 13937 } 13938 } 13939 mutex_exit(&mpt->m_mutex); 13940 } 13941 13942 static void 13943 mptsas_offline_missed_luns(dev_info_t *pdip, uint16_t *repluns, 13944 int lun_cnt, mptsas_target_t *ptgt) 13945 { 13946 dev_info_t *child = NULL, *savechild = NULL; 13947 mdi_pathinfo_t *pip = NULL, *savepip = NULL; 13948 uint64_t sas_wwn, wwid; 13949 uint8_t phy; 13950 int lun; 13951 int i; 13952 int find; 13953 char *addr; 13954 char *nodename; 13955 mptsas_t *mpt = DIP2MPT(pdip); 13956 13957 mutex_enter(&mpt->m_mutex); 13958 wwid = ptgt->m_sas_wwn; 13959 mutex_exit(&mpt->m_mutex); 13960 13961 child = ddi_get_child(pdip); 13962 while (child) { 13963 find = 0; 13964 savechild = child; 13965 child = ddi_get_next_sibling(child); 13966 13967 nodename = ddi_node_name(savechild); 13968 if (strcmp(nodename, "smp") == 0) { 13969 continue; 13970 } 13971 13972 addr = ddi_get_name_addr(savechild); 13973 if (addr == NULL) { 13974 continue; 13975 } 13976 13977 if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) != 13978 DDI_SUCCESS) { 13979 continue; 13980 } 13981 13982 if (wwid == sas_wwn) { 13983 for (i = 0; i < lun_cnt; i++) { 13984 if (repluns[i] == lun) { 13985 find = 1; 13986 break; 13987 } 13988 } 13989 } else { 13990 continue; 13991 } 13992 if (find == 0) { 13993 /* 13994 * The lun has not been there already 13995 */ 13996 (void) mptsas_offline_lun(pdip, savechild, NULL, 13997 NDI_DEVI_REMOVE); 13998 } 13999 } 14000 14001 pip = mdi_get_next_client_path(pdip, NULL); 14002 while (pip) { 14003 find = 0; 14004 savepip = pip; 14005 addr = MDI_PI(pip)->pi_addr; 14006 14007 pip = mdi_get_next_client_path(pdip, pip); 14008 14009 if (addr == NULL) { 14010 continue; 14011 } 14012 14013 if (mptsas_parse_address(addr, &sas_wwn, &phy, 14014 &lun) != DDI_SUCCESS) { 14015 continue; 14016 } 14017 14018 if (sas_wwn == wwid) { 14019 for (i = 0; i < lun_cnt; i++) { 14020 if (repluns[i] == lun) { 14021 find = 1; 14022 break; 14023 } 14024 } 14025 } else { 14026 continue; 14027 } 14028 14029 if (find == 0) { 14030 /* 14031 * The lun has not been there already 14032 */ 14033 (void) mptsas_offline_lun(pdip, NULL, savepip, 14034 NDI_DEVI_REMOVE); 14035 } 14036 } 14037 } 14038 14039 void 14040 mptsas_update_hashtab(struct mptsas *mpt) 14041 { 14042 uint32_t page_address; 14043 int rval = 0; 14044 uint16_t dev_handle; 14045 mptsas_target_t *ptgt = NULL; 14046 mptsas_smp_t smp_node; 14047 14048 /* 14049 * Get latest RAID info. 14050 */ 14051 (void) mptsas_get_raid_info(mpt); 14052 14053 dev_handle = mpt->m_smp_devhdl; 14054 for (; mpt->m_done_traverse_smp == 0; ) { 14055 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL & 14056 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)dev_handle; 14057 if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node) 14058 != DDI_SUCCESS) { 14059 break; 14060 } 14061 mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl; 14062 (void) mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node); 14063 } 14064 14065 /* 14066 * Config target devices 14067 */ 14068 dev_handle = mpt->m_dev_handle; 14069 14070 /* 14071 * Do loop to get sas device page 0 by GetNextHandle till the 14072 * the last handle. If the sas device is a SATA/SSP target, 14073 * we try to config it. 14074 */ 14075 for (; mpt->m_done_traverse_dev == 0; ) { 14076 ptgt = NULL; 14077 page_address = 14078 (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 14079 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14080 (uint32_t)dev_handle; 14081 rval = mptsas_get_target_device_info(mpt, page_address, 14082 &dev_handle, &ptgt); 14083 if ((rval == DEV_INFO_FAIL_PAGE0) || 14084 (rval == DEV_INFO_FAIL_ALLOC)) { 14085 break; 14086 } 14087 14088 mpt->m_dev_handle = dev_handle; 14089 } 14090 14091 } 14092 14093 void 14094 mptsas_invalid_hashtab(mptsas_hash_table_t *hashtab) 14095 { 14096 mptsas_hash_data_t *data; 14097 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST); 14098 while (data != NULL) { 14099 data->devhdl = MPTSAS_INVALID_DEVHDL; 14100 data->device_info = 0; 14101 /* 14102 * For tgttbl, clear dr_flag. 14103 */ 14104 data->dr_flag = MPTSAS_DR_INACTIVE; 14105 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT); 14106 } 14107 } 14108 14109 void 14110 mptsas_update_driver_data(struct mptsas *mpt) 14111 { 14112 /* 14113 * TODO after hard reset, update the driver data structures 14114 * 1. update port/phymask mapping table mpt->m_phy_info 14115 * 2. invalid all the entries in hash table 14116 * m_devhdl = 0xffff and m_deviceinfo = 0 14117 * 3. call sas_device_page/expander_page to update hash table 14118 */ 14119 mptsas_update_phymask(mpt); 14120 /* 14121 * Invalid the existing entries 14122 */ 14123 mptsas_invalid_hashtab(&mpt->m_active->m_tgttbl); 14124 mptsas_invalid_hashtab(&mpt->m_active->m_smptbl); 14125 mpt->m_done_traverse_dev = 0; 14126 mpt->m_done_traverse_smp = 0; 14127 mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL; 14128 mptsas_update_hashtab(mpt); 14129 } 14130 14131 static void 14132 mptsas_config_all(dev_info_t *pdip) 14133 { 14134 dev_info_t *smpdip = NULL; 14135 mptsas_t *mpt = DIP2MPT(pdip); 14136 int phymask = 0; 14137 mptsas_phymask_t phy_mask; 14138 mptsas_target_t *ptgt = NULL; 14139 mptsas_smp_t *psmp; 14140 14141 /* 14142 * Get the phymask associated to the iport 14143 */ 14144 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 14145 "phymask", 0); 14146 14147 /* 14148 * Enumerate RAID volumes here (phymask == 0). 14149 */ 14150 if (phymask == 0) { 14151 mptsas_config_all_viport(pdip); 14152 return; 14153 } 14154 14155 mutex_enter(&mpt->m_mutex); 14156 14157 if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp) { 14158 mptsas_update_hashtab(mpt); 14159 } 14160 14161 psmp = (mptsas_smp_t *)mptsas_hash_traverse(&mpt->m_active->m_smptbl, 14162 MPTSAS_HASH_FIRST); 14163 while (psmp != NULL) { 14164 phy_mask = psmp->m_phymask; 14165 if (phy_mask == phymask) { 14166 smpdip = NULL; 14167 mutex_exit(&mpt->m_mutex); 14168 (void) mptsas_online_smp(pdip, psmp, &smpdip); 14169 mutex_enter(&mpt->m_mutex); 14170 } 14171 psmp = (mptsas_smp_t *)mptsas_hash_traverse( 14172 &mpt->m_active->m_smptbl, MPTSAS_HASH_NEXT); 14173 } 14174 14175 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 14176 MPTSAS_HASH_FIRST); 14177 while (ptgt != NULL) { 14178 phy_mask = ptgt->m_phymask; 14179 if (phy_mask == phymask) { 14180 mutex_exit(&mpt->m_mutex); 14181 (void) mptsas_config_target(pdip, ptgt); 14182 mutex_enter(&mpt->m_mutex); 14183 } 14184 14185 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 14186 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 14187 } 14188 mutex_exit(&mpt->m_mutex); 14189 } 14190 14191 static int 14192 mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt) 14193 { 14194 int rval = DDI_FAILURE; 14195 dev_info_t *tdip; 14196 14197 rval = mptsas_config_luns(pdip, ptgt); 14198 if (rval != DDI_SUCCESS) { 14199 /* 14200 * The return value means the SCMD_REPORT_LUNS 14201 * did not execute successfully. The target maybe 14202 * doesn't support such command. 14203 */ 14204 rval = mptsas_probe_lun(pdip, 0, &tdip, ptgt); 14205 } 14206 return (rval); 14207 } 14208 14209 /* 14210 * Return fail if not all the childs/paths are freed. 14211 * if there is any path under the HBA, the return value will be always fail 14212 * because we didn't call mdi_pi_free for path 14213 */ 14214 static int 14215 mptsas_offline_target(dev_info_t *pdip, char *name) 14216 { 14217 dev_info_t *child = NULL, *prechild = NULL; 14218 mdi_pathinfo_t *pip = NULL, *savepip = NULL; 14219 int tmp_rval, rval = DDI_SUCCESS; 14220 char *addr, *cp; 14221 size_t s; 14222 mptsas_t *mpt = DIP2MPT(pdip); 14223 14224 child = ddi_get_child(pdip); 14225 while (child) { 14226 addr = ddi_get_name_addr(child); 14227 prechild = child; 14228 child = ddi_get_next_sibling(child); 14229 14230 if (addr == NULL) { 14231 continue; 14232 } 14233 if ((cp = strchr(addr, ',')) == NULL) { 14234 continue; 14235 } 14236 14237 s = (uintptr_t)cp - (uintptr_t)addr; 14238 14239 if (strncmp(addr, name, s) != 0) { 14240 continue; 14241 } 14242 14243 tmp_rval = mptsas_offline_lun(pdip, prechild, NULL, 14244 NDI_DEVI_REMOVE); 14245 if (tmp_rval != DDI_SUCCESS) { 14246 rval = DDI_FAILURE; 14247 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 14248 prechild, MPTSAS_DEV_GONE) != 14249 DDI_PROP_SUCCESS) { 14250 mptsas_log(mpt, CE_WARN, "mptsas driver " 14251 "unable to create property for " 14252 "SAS %s (MPTSAS_DEV_GONE)", addr); 14253 } 14254 } 14255 } 14256 14257 pip = mdi_get_next_client_path(pdip, NULL); 14258 while (pip) { 14259 addr = MDI_PI(pip)->pi_addr; 14260 savepip = pip; 14261 pip = mdi_get_next_client_path(pdip, pip); 14262 if (addr == NULL) { 14263 continue; 14264 } 14265 14266 if ((cp = strchr(addr, ',')) == NULL) { 14267 continue; 14268 } 14269 14270 s = (uintptr_t)cp - (uintptr_t)addr; 14271 14272 if (strncmp(addr, name, s) != 0) { 14273 continue; 14274 } 14275 14276 (void) mptsas_offline_lun(pdip, NULL, savepip, 14277 NDI_DEVI_REMOVE); 14278 /* 14279 * driver will not invoke mdi_pi_free, so path will not 14280 * be freed forever, return DDI_FAILURE. 14281 */ 14282 rval = DDI_FAILURE; 14283 } 14284 return (rval); 14285 } 14286 14287 static int 14288 mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip, 14289 mdi_pathinfo_t *rpip, uint_t flags) 14290 { 14291 int rval = DDI_FAILURE; 14292 char *devname; 14293 dev_info_t *cdip, *parent; 14294 14295 if (rpip != NULL) { 14296 parent = scsi_vhci_dip; 14297 cdip = mdi_pi_get_client(rpip); 14298 } else if (rdip != NULL) { 14299 parent = pdip; 14300 cdip = rdip; 14301 } else { 14302 return (DDI_FAILURE); 14303 } 14304 14305 /* 14306 * Make sure node is attached otherwise 14307 * it won't have related cache nodes to 14308 * clean up. i_ddi_devi_attached is 14309 * similiar to i_ddi_node_state(cdip) >= 14310 * DS_ATTACHED. 14311 */ 14312 if (i_ddi_devi_attached(cdip)) { 14313 14314 /* Get full devname */ 14315 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 14316 (void) ddi_deviname(cdip, devname); 14317 /* Clean cache */ 14318 (void) devfs_clean(parent, devname + 1, 14319 DV_CLEAN_FORCE); 14320 kmem_free(devname, MAXNAMELEN + 1); 14321 } 14322 if (rpip != NULL) { 14323 if (MDI_PI_IS_OFFLINE(rpip)) { 14324 rval = DDI_SUCCESS; 14325 } else { 14326 rval = mdi_pi_offline(rpip, 0); 14327 } 14328 } else { 14329 rval = ndi_devi_offline(cdip, flags); 14330 } 14331 14332 return (rval); 14333 } 14334 14335 static dev_info_t * 14336 mptsas_find_smp_child(dev_info_t *parent, char *str_wwn) 14337 { 14338 dev_info_t *child = NULL; 14339 char *smp_wwn = NULL; 14340 14341 child = ddi_get_child(parent); 14342 while (child) { 14343 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child, 14344 DDI_PROP_DONTPASS, SMP_WWN, &smp_wwn) 14345 != DDI_SUCCESS) { 14346 child = ddi_get_next_sibling(child); 14347 continue; 14348 } 14349 14350 if (strcmp(smp_wwn, str_wwn) == 0) { 14351 ddi_prop_free(smp_wwn); 14352 break; 14353 } 14354 child = ddi_get_next_sibling(child); 14355 ddi_prop_free(smp_wwn); 14356 } 14357 return (child); 14358 } 14359 14360 static int 14361 mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags) 14362 { 14363 int rval = DDI_FAILURE; 14364 char *devname; 14365 char wwn_str[MPTSAS_WWN_STRLEN]; 14366 dev_info_t *cdip; 14367 14368 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr); 14369 14370 cdip = mptsas_find_smp_child(pdip, wwn_str); 14371 14372 if (cdip == NULL) 14373 return (DDI_SUCCESS); 14374 14375 /* 14376 * Make sure node is attached otherwise 14377 * it won't have related cache nodes to 14378 * clean up. i_ddi_devi_attached is 14379 * similiar to i_ddi_node_state(cdip) >= 14380 * DS_ATTACHED. 14381 */ 14382 if (i_ddi_devi_attached(cdip)) { 14383 14384 /* Get full devname */ 14385 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 14386 (void) ddi_deviname(cdip, devname); 14387 /* Clean cache */ 14388 (void) devfs_clean(pdip, devname + 1, 14389 DV_CLEAN_FORCE); 14390 kmem_free(devname, MAXNAMELEN + 1); 14391 } 14392 14393 rval = ndi_devi_offline(cdip, flags); 14394 14395 return (rval); 14396 } 14397 14398 static dev_info_t * 14399 mptsas_find_child(dev_info_t *pdip, char *name) 14400 { 14401 dev_info_t *child = NULL; 14402 char *rname = NULL; 14403 int rval = DDI_FAILURE; 14404 14405 rname = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14406 14407 child = ddi_get_child(pdip); 14408 while (child) { 14409 rval = mptsas_name_child(child, rname, SCSI_MAXNAMELEN); 14410 if (rval != DDI_SUCCESS) { 14411 child = ddi_get_next_sibling(child); 14412 bzero(rname, SCSI_MAXNAMELEN); 14413 continue; 14414 } 14415 14416 if (strcmp(rname, name) == 0) { 14417 break; 14418 } 14419 child = ddi_get_next_sibling(child); 14420 bzero(rname, SCSI_MAXNAMELEN); 14421 } 14422 14423 kmem_free(rname, SCSI_MAXNAMELEN); 14424 14425 return (child); 14426 } 14427 14428 14429 static dev_info_t * 14430 mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, int lun) 14431 { 14432 dev_info_t *child = NULL; 14433 char *name = NULL; 14434 char *addr = NULL; 14435 14436 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14437 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14438 (void) sprintf(name, "%016"PRIx64, sasaddr); 14439 (void) sprintf(addr, "w%s,%x", name, lun); 14440 child = mptsas_find_child(pdip, addr); 14441 kmem_free(name, SCSI_MAXNAMELEN); 14442 kmem_free(addr, SCSI_MAXNAMELEN); 14443 return (child); 14444 } 14445 14446 static dev_info_t * 14447 mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy) 14448 { 14449 dev_info_t *child; 14450 char *addr; 14451 14452 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14453 (void) sprintf(addr, "p%x,0", phy); 14454 child = mptsas_find_child(pdip, addr); 14455 kmem_free(addr, SCSI_MAXNAMELEN); 14456 return (child); 14457 } 14458 14459 static mdi_pathinfo_t * 14460 mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy) 14461 { 14462 mdi_pathinfo_t *path; 14463 char *addr = NULL; 14464 14465 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14466 (void) sprintf(addr, "p%x,0", phy); 14467 path = mdi_pi_find(pdip, NULL, addr); 14468 kmem_free(addr, SCSI_MAXNAMELEN); 14469 return (path); 14470 } 14471 14472 static mdi_pathinfo_t * 14473 mptsas_find_path_addr(dev_info_t *parent, uint64_t sasaddr, int lun) 14474 { 14475 mdi_pathinfo_t *path; 14476 char *name = NULL; 14477 char *addr = NULL; 14478 14479 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14480 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14481 (void) sprintf(name, "%016"PRIx64, sasaddr); 14482 (void) sprintf(addr, "w%s,%x", name, lun); 14483 path = mdi_pi_find(parent, NULL, addr); 14484 kmem_free(name, SCSI_MAXNAMELEN); 14485 kmem_free(addr, SCSI_MAXNAMELEN); 14486 14487 return (path); 14488 } 14489 14490 static int 14491 mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq, 14492 dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun) 14493 { 14494 int i = 0; 14495 uchar_t *inq83 = NULL; 14496 int inq83_len1 = 0xFF; 14497 int inq83_len = 0; 14498 int rval = DDI_FAILURE; 14499 ddi_devid_t devid; 14500 char *guid = NULL; 14501 int target = ptgt->m_devhdl; 14502 mdi_pathinfo_t *pip = NULL; 14503 mptsas_t *mpt = DIP2MPT(pdip); 14504 14505 /* 14506 * For DVD/CD ROM and tape devices and optical 14507 * devices, we won't try to enumerate them under 14508 * scsi_vhci, so no need to try page83 14509 */ 14510 if (sd_inq && (sd_inq->inq_dtype == DTYPE_RODIRECT || 14511 sd_inq->inq_dtype == DTYPE_OPTICAL || 14512 sd_inq->inq_dtype == DTYPE_ESI)) 14513 goto create_lun; 14514 14515 /* 14516 * The LCA returns good SCSI status, but corrupt page 83 data the first 14517 * time it is queried. The solution is to keep trying to request page83 14518 * and verify the GUID is not (DDI_NOT_WELL_FORMED) in 14519 * mptsas_inq83_retry_timeout seconds. If the timeout expires, driver 14520 * give up to get VPD page at this stage and fail the enumeration. 14521 */ 14522 14523 inq83 = kmem_zalloc(inq83_len1, KM_SLEEP); 14524 14525 for (i = 0; i < mptsas_inq83_retry_timeout; i++) { 14526 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83, 14527 inq83_len1, &inq83_len, 1); 14528 if (rval != 0) { 14529 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 14530 "0x83 for target:%x, lun:%x failed!", target, lun); 14531 if (mptsas_physical_bind_failed_page_83 != B_FALSE) 14532 goto create_lun; 14533 goto out; 14534 } 14535 /* 14536 * create DEVID from inquiry data 14537 */ 14538 if ((rval = ddi_devid_scsi_encode( 14539 DEVID_SCSI_ENCODE_VERSION_LATEST, NULL, (uchar_t *)sd_inq, 14540 sizeof (struct scsi_inquiry), NULL, 0, inq83, 14541 (size_t)inq83_len, &devid)) == DDI_SUCCESS) { 14542 /* 14543 * extract GUID from DEVID 14544 */ 14545 guid = ddi_devid_to_guid(devid); 14546 14547 /* 14548 * Do not enable MPXIO if the strlen(guid) is greater 14549 * than MPTSAS_MAX_GUID_LEN, this constrain would be 14550 * handled by framework later. 14551 */ 14552 if (guid && (strlen(guid) > MPTSAS_MAX_GUID_LEN)) { 14553 ddi_devid_free_guid(guid); 14554 guid = NULL; 14555 if (mpt->m_mpxio_enable == TRUE) { 14556 mptsas_log(mpt, CE_NOTE, "!Target:%x, " 14557 "lun:%x doesn't have a valid GUID, " 14558 "multipathing for this drive is " 14559 "not enabled", target, lun); 14560 } 14561 } 14562 14563 /* 14564 * devid no longer needed 14565 */ 14566 ddi_devid_free(devid); 14567 break; 14568 } else if (rval == DDI_NOT_WELL_FORMED) { 14569 /* 14570 * return value of ddi_devid_scsi_encode equal to 14571 * DDI_NOT_WELL_FORMED means DEVID_RETRY, it worth 14572 * to retry inquiry page 0x83 and get GUID. 14573 */ 14574 NDBG20(("Not well formed devid, retry...")); 14575 delay(1 * drv_usectohz(1000000)); 14576 continue; 14577 } else { 14578 mptsas_log(mpt, CE_WARN, "!Encode devid failed for " 14579 "path target:%x, lun:%x", target, lun); 14580 rval = DDI_FAILURE; 14581 goto create_lun; 14582 } 14583 } 14584 14585 if (i == mptsas_inq83_retry_timeout) { 14586 mptsas_log(mpt, CE_WARN, "!Repeated page83 requests timeout " 14587 "for path target:%x, lun:%x", target, lun); 14588 } 14589 14590 rval = DDI_FAILURE; 14591 14592 create_lun: 14593 if ((guid != NULL) && (mpt->m_mpxio_enable == TRUE)) { 14594 rval = mptsas_create_virt_lun(pdip, sd_inq, guid, lun_dip, &pip, 14595 ptgt, lun); 14596 } 14597 if (rval != DDI_SUCCESS) { 14598 rval = mptsas_create_phys_lun(pdip, sd_inq, guid, lun_dip, 14599 ptgt, lun); 14600 14601 } 14602 out: 14603 if (guid != NULL) { 14604 /* 14605 * guid no longer needed 14606 */ 14607 ddi_devid_free_guid(guid); 14608 } 14609 if (inq83 != NULL) 14610 kmem_free(inq83, inq83_len1); 14611 return (rval); 14612 } 14613 14614 static int 14615 mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *inq, char *guid, 14616 dev_info_t **lun_dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, int lun) 14617 { 14618 int target; 14619 char *nodename = NULL; 14620 char **compatible = NULL; 14621 int ncompatible = 0; 14622 int mdi_rtn = MDI_FAILURE; 14623 int rval = DDI_FAILURE; 14624 char *old_guid = NULL; 14625 mptsas_t *mpt = DIP2MPT(pdip); 14626 char *lun_addr = NULL; 14627 char *wwn_str = NULL; 14628 char *attached_wwn_str = NULL; 14629 char *component = NULL; 14630 uint8_t phy = 0xFF; 14631 uint64_t sas_wwn; 14632 int64_t lun64 = 0; 14633 uint32_t devinfo; 14634 uint16_t dev_hdl; 14635 uint16_t pdev_hdl; 14636 uint64_t dev_sas_wwn; 14637 uint64_t pdev_sas_wwn; 14638 uint32_t pdev_info; 14639 uint8_t physport; 14640 uint8_t phy_id; 14641 uint32_t page_address; 14642 uint16_t bay_num, enclosure; 14643 char pdev_wwn_str[MPTSAS_WWN_STRLEN]; 14644 uint32_t dev_info; 14645 14646 mutex_enter(&mpt->m_mutex); 14647 target = ptgt->m_devhdl; 14648 sas_wwn = ptgt->m_sas_wwn; 14649 devinfo = ptgt->m_deviceinfo; 14650 phy = ptgt->m_phynum; 14651 mutex_exit(&mpt->m_mutex); 14652 14653 if (sas_wwn) { 14654 *pip = mptsas_find_path_addr(pdip, sas_wwn, lun); 14655 } else { 14656 *pip = mptsas_find_path_phy(pdip, phy); 14657 } 14658 14659 if (*pip != NULL) { 14660 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip; 14661 ASSERT(*lun_dip != NULL); 14662 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip, 14663 (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM), 14664 MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) { 14665 if (strncmp(guid, old_guid, strlen(guid)) == 0) { 14666 /* 14667 * Same path back online again. 14668 */ 14669 (void) ddi_prop_free(old_guid); 14670 if ((!MDI_PI_IS_ONLINE(*pip)) && 14671 (!MDI_PI_IS_STANDBY(*pip)) && 14672 (ptgt->m_tgt_unconfigured == 0)) { 14673 rval = mdi_pi_online(*pip, 0); 14674 mutex_enter(&mpt->m_mutex); 14675 ptgt->m_led_status = 0; 14676 (void) mptsas_flush_led_status(mpt, 14677 ptgt); 14678 mutex_exit(&mpt->m_mutex); 14679 } else { 14680 rval = DDI_SUCCESS; 14681 } 14682 if (rval != DDI_SUCCESS) { 14683 mptsas_log(mpt, CE_WARN, "path:target: " 14684 "%x, lun:%x online failed!", target, 14685 lun); 14686 *pip = NULL; 14687 *lun_dip = NULL; 14688 } 14689 return (rval); 14690 } else { 14691 /* 14692 * The GUID of the LUN has changed which maybe 14693 * because customer mapped another volume to the 14694 * same LUN. 14695 */ 14696 mptsas_log(mpt, CE_WARN, "The GUID of the " 14697 "target:%x, lun:%x was changed, maybe " 14698 "because someone mapped another volume " 14699 "to the same LUN", target, lun); 14700 (void) ddi_prop_free(old_guid); 14701 if (!MDI_PI_IS_OFFLINE(*pip)) { 14702 rval = mdi_pi_offline(*pip, 0); 14703 if (rval != MDI_SUCCESS) { 14704 mptsas_log(mpt, CE_WARN, "path:" 14705 "target:%x, lun:%x offline " 14706 "failed!", target, lun); 14707 *pip = NULL; 14708 *lun_dip = NULL; 14709 return (DDI_FAILURE); 14710 } 14711 } 14712 if (mdi_pi_free(*pip, 0) != MDI_SUCCESS) { 14713 mptsas_log(mpt, CE_WARN, "path:target:" 14714 "%x, lun:%x free failed!", target, 14715 lun); 14716 *pip = NULL; 14717 *lun_dip = NULL; 14718 return (DDI_FAILURE); 14719 } 14720 } 14721 } else { 14722 mptsas_log(mpt, CE_WARN, "Can't get client-guid " 14723 "property for path:target:%x, lun:%x", target, lun); 14724 *pip = NULL; 14725 *lun_dip = NULL; 14726 return (DDI_FAILURE); 14727 } 14728 } 14729 scsi_hba_nodename_compatible_get(inq, NULL, 14730 inq->inq_dtype, NULL, &nodename, &compatible, &ncompatible); 14731 14732 /* 14733 * if nodename can't be determined then print a message and skip it 14734 */ 14735 if (nodename == NULL) { 14736 mptsas_log(mpt, CE_WARN, "mptsas driver found no compatible " 14737 "driver for target%d lun %d dtype:0x%02x", target, lun, 14738 inq->inq_dtype); 14739 return (DDI_FAILURE); 14740 } 14741 14742 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP); 14743 /* The property is needed by MPAPI */ 14744 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn); 14745 14746 lun_addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14747 if (guid) { 14748 (void) sprintf(lun_addr, "w%s,%x", wwn_str, lun); 14749 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 14750 } else { 14751 (void) sprintf(lun_addr, "p%x,%x", phy, lun); 14752 (void) sprintf(wwn_str, "p%x", phy); 14753 } 14754 14755 mdi_rtn = mdi_pi_alloc_compatible(pdip, nodename, 14756 guid, lun_addr, compatible, ncompatible, 14757 0, pip); 14758 if (mdi_rtn == MDI_SUCCESS) { 14759 14760 if (mdi_prop_update_string(*pip, MDI_GUID, 14761 guid) != DDI_SUCCESS) { 14762 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14763 "create prop for target %d lun %d (MDI_GUID)", 14764 target, lun); 14765 mdi_rtn = MDI_FAILURE; 14766 goto virt_create_done; 14767 } 14768 14769 if (mdi_prop_update_int(*pip, LUN_PROP, 14770 lun) != DDI_SUCCESS) { 14771 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14772 "create prop for target %d lun %d (LUN_PROP)", 14773 target, lun); 14774 mdi_rtn = MDI_FAILURE; 14775 goto virt_create_done; 14776 } 14777 lun64 = (int64_t)lun; 14778 if (mdi_prop_update_int64(*pip, LUN64_PROP, 14779 lun64) != DDI_SUCCESS) { 14780 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14781 "create prop for target %d (LUN64_PROP)", 14782 target); 14783 mdi_rtn = MDI_FAILURE; 14784 goto virt_create_done; 14785 } 14786 if (mdi_prop_update_string_array(*pip, "compatible", 14787 compatible, ncompatible) != 14788 DDI_PROP_SUCCESS) { 14789 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14790 "create prop for target %d lun %d (COMPATIBLE)", 14791 target, lun); 14792 mdi_rtn = MDI_FAILURE; 14793 goto virt_create_done; 14794 } 14795 if (sas_wwn && (mdi_prop_update_string(*pip, 14796 SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != DDI_PROP_SUCCESS)) { 14797 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14798 "create prop for target %d lun %d " 14799 "(target-port)", target, lun); 14800 mdi_rtn = MDI_FAILURE; 14801 goto virt_create_done; 14802 } else if ((sas_wwn == 0) && (mdi_prop_update_int(*pip, 14803 "sata-phy", phy) != DDI_PROP_SUCCESS)) { 14804 /* 14805 * Direct attached SATA device without DeviceName 14806 */ 14807 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14808 "create prop for SAS target %d lun %d " 14809 "(sata-phy)", target, lun); 14810 mdi_rtn = MDI_FAILURE; 14811 goto virt_create_done; 14812 } 14813 mutex_enter(&mpt->m_mutex); 14814 14815 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14816 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14817 (uint32_t)ptgt->m_devhdl; 14818 rval = mptsas_get_sas_device_page0(mpt, page_address, 14819 &dev_hdl, &dev_sas_wwn, &dev_info, &physport, 14820 &phy_id, &pdev_hdl, &bay_num, &enclosure); 14821 if (rval != DDI_SUCCESS) { 14822 mutex_exit(&mpt->m_mutex); 14823 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 14824 "parent device for handle %d", page_address); 14825 mdi_rtn = MDI_FAILURE; 14826 goto virt_create_done; 14827 } 14828 14829 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14830 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl; 14831 rval = mptsas_get_sas_device_page0(mpt, page_address, 14832 &dev_hdl, &pdev_sas_wwn, &pdev_info, &physport, 14833 &phy_id, &pdev_hdl, &bay_num, &enclosure); 14834 if (rval != DDI_SUCCESS) { 14835 mutex_exit(&mpt->m_mutex); 14836 mptsas_log(mpt, CE_WARN, "mptsas unable to get" 14837 "device info for handle %d", page_address); 14838 mdi_rtn = MDI_FAILURE; 14839 goto virt_create_done; 14840 } 14841 14842 mutex_exit(&mpt->m_mutex); 14843 14844 /* 14845 * If this device direct attached to the controller 14846 * set the attached-port to the base wwid 14847 */ 14848 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 14849 != DEVINFO_DIRECT_ATTACHED) { 14850 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 14851 pdev_sas_wwn); 14852 } else { 14853 /* 14854 * Update the iport's attached-port to guid 14855 */ 14856 if (sas_wwn == 0) { 14857 (void) sprintf(wwn_str, "p%x", phy); 14858 } else { 14859 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 14860 } 14861 if (ddi_prop_update_string(DDI_DEV_T_NONE, 14862 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 14863 DDI_PROP_SUCCESS) { 14864 mptsas_log(mpt, CE_WARN, 14865 "mptsas unable to create " 14866 "property for iport target-port" 14867 " %s (sas_wwn)", 14868 wwn_str); 14869 mdi_rtn = MDI_FAILURE; 14870 goto virt_create_done; 14871 } 14872 14873 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 14874 mpt->un.m_base_wwid); 14875 } 14876 14877 if (mdi_prop_update_string(*pip, 14878 SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) != 14879 DDI_PROP_SUCCESS) { 14880 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14881 "property for iport attached-port %s (sas_wwn)", 14882 attached_wwn_str); 14883 mdi_rtn = MDI_FAILURE; 14884 goto virt_create_done; 14885 } 14886 14887 14888 if (inq->inq_dtype == 0) { 14889 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 14890 /* 14891 * set obp path for pathinfo 14892 */ 14893 (void) snprintf(component, MAXPATHLEN, 14894 "disk@%s", lun_addr); 14895 14896 if (mdi_pi_pathname_obp_set(*pip, component) != 14897 DDI_SUCCESS) { 14898 mptsas_log(mpt, CE_WARN, "mpt_sas driver " 14899 "unable to set obp-path for object %s", 14900 component); 14901 mdi_rtn = MDI_FAILURE; 14902 goto virt_create_done; 14903 } 14904 } 14905 14906 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip; 14907 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 14908 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 14909 if ((ndi_prop_update_int(DDI_DEV_T_NONE, *lun_dip, 14910 "pm-capable", 1)) != 14911 DDI_PROP_SUCCESS) { 14912 mptsas_log(mpt, CE_WARN, "mptsas driver" 14913 "failed to create pm-capable " 14914 "property, target %d", target); 14915 mdi_rtn = MDI_FAILURE; 14916 goto virt_create_done; 14917 } 14918 } 14919 /* 14920 * Create the phy-num property 14921 */ 14922 if (mdi_prop_update_int(*pip, "phy-num", 14923 ptgt->m_phynum) != DDI_SUCCESS) { 14924 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14925 "create phy-num property for target %d lun %d", 14926 target, lun); 14927 mdi_rtn = MDI_FAILURE; 14928 goto virt_create_done; 14929 } 14930 NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr)); 14931 mdi_rtn = mdi_pi_online(*pip, 0); 14932 if (mdi_rtn == MDI_SUCCESS) { 14933 mutex_enter(&mpt->m_mutex); 14934 ptgt->m_led_status = 0; 14935 if (mptsas_flush_led_status(mpt, ptgt) != DDI_SUCCESS) { 14936 NDBG14(("mptsas: clear LED for slot %x " 14937 "failed", ptgt->m_slot_num)); 14938 } 14939 mutex_exit(&mpt->m_mutex); 14940 } 14941 if (mdi_rtn == MDI_NOT_SUPPORTED) { 14942 mdi_rtn = MDI_FAILURE; 14943 } 14944 virt_create_done: 14945 if (*pip && mdi_rtn != MDI_SUCCESS) { 14946 (void) mdi_pi_free(*pip, 0); 14947 *pip = NULL; 14948 *lun_dip = NULL; 14949 } 14950 } 14951 14952 scsi_hba_nodename_compatible_free(nodename, compatible); 14953 if (lun_addr != NULL) { 14954 kmem_free(lun_addr, SCSI_MAXNAMELEN); 14955 } 14956 if (wwn_str != NULL) { 14957 kmem_free(wwn_str, MPTSAS_WWN_STRLEN); 14958 } 14959 if (component != NULL) { 14960 kmem_free(component, MAXPATHLEN); 14961 } 14962 14963 return ((mdi_rtn == MDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 14964 } 14965 14966 static int 14967 mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *inq, 14968 char *guid, dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun) 14969 { 14970 int target; 14971 int rval; 14972 int ndi_rtn = NDI_FAILURE; 14973 uint64_t be_sas_wwn; 14974 char *nodename = NULL; 14975 char **compatible = NULL; 14976 int ncompatible = 0; 14977 int instance = 0; 14978 mptsas_t *mpt = DIP2MPT(pdip); 14979 char *wwn_str = NULL; 14980 char *component = NULL; 14981 char *attached_wwn_str = NULL; 14982 uint8_t phy = 0xFF; 14983 uint64_t sas_wwn; 14984 uint32_t devinfo; 14985 uint16_t dev_hdl; 14986 uint16_t pdev_hdl; 14987 uint64_t pdev_sas_wwn; 14988 uint64_t dev_sas_wwn; 14989 uint32_t pdev_info; 14990 uint8_t physport; 14991 uint8_t phy_id; 14992 uint32_t page_address; 14993 uint16_t bay_num, enclosure; 14994 char pdev_wwn_str[MPTSAS_WWN_STRLEN]; 14995 uint32_t dev_info; 14996 int64_t lun64 = 0; 14997 14998 mutex_enter(&mpt->m_mutex); 14999 target = ptgt->m_devhdl; 15000 sas_wwn = ptgt->m_sas_wwn; 15001 devinfo = ptgt->m_deviceinfo; 15002 phy = ptgt->m_phynum; 15003 mutex_exit(&mpt->m_mutex); 15004 15005 /* 15006 * generate compatible property with binding-set "mpt" 15007 */ 15008 scsi_hba_nodename_compatible_get(inq, NULL, inq->inq_dtype, NULL, 15009 &nodename, &compatible, &ncompatible); 15010 15011 /* 15012 * if nodename can't be determined then print a message and skip it 15013 */ 15014 if (nodename == NULL) { 15015 mptsas_log(mpt, CE_WARN, "mptsas found no compatible driver " 15016 "for target %d lun %d", target, lun); 15017 return (DDI_FAILURE); 15018 } 15019 15020 ndi_rtn = ndi_devi_alloc(pdip, nodename, 15021 DEVI_SID_NODEID, lun_dip); 15022 15023 /* 15024 * if lun alloc success, set props 15025 */ 15026 if (ndi_rtn == NDI_SUCCESS) { 15027 15028 if (ndi_prop_update_int(DDI_DEV_T_NONE, 15029 *lun_dip, LUN_PROP, lun) != 15030 DDI_PROP_SUCCESS) { 15031 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15032 "property for target %d lun %d (LUN_PROP)", 15033 target, lun); 15034 ndi_rtn = NDI_FAILURE; 15035 goto phys_create_done; 15036 } 15037 15038 lun64 = (int64_t)lun; 15039 if (ndi_prop_update_int64(DDI_DEV_T_NONE, 15040 *lun_dip, LUN64_PROP, lun64) != 15041 DDI_PROP_SUCCESS) { 15042 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15043 "property for target %d lun64 %d (LUN64_PROP)", 15044 target, lun); 15045 ndi_rtn = NDI_FAILURE; 15046 goto phys_create_done; 15047 } 15048 if (ndi_prop_update_string_array(DDI_DEV_T_NONE, 15049 *lun_dip, "compatible", compatible, ncompatible) 15050 != DDI_PROP_SUCCESS) { 15051 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15052 "property for target %d lun %d (COMPATIBLE)", 15053 target, lun); 15054 ndi_rtn = NDI_FAILURE; 15055 goto phys_create_done; 15056 } 15057 15058 /* 15059 * We need the SAS WWN for non-multipath devices, so 15060 * we'll use the same property as that multipathing 15061 * devices need to present for MPAPI. If we don't have 15062 * a WWN (e.g. parallel SCSI), don't create the prop. 15063 */ 15064 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP); 15065 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 15066 if (sas_wwn && ndi_prop_update_string(DDI_DEV_T_NONE, 15067 *lun_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) 15068 != DDI_PROP_SUCCESS) { 15069 mptsas_log(mpt, CE_WARN, "mptsas unable to " 15070 "create property for SAS target %d lun %d " 15071 "(target-port)", target, lun); 15072 ndi_rtn = NDI_FAILURE; 15073 goto phys_create_done; 15074 } 15075 15076 be_sas_wwn = BE_64(sas_wwn); 15077 if (sas_wwn && ndi_prop_update_byte_array( 15078 DDI_DEV_T_NONE, *lun_dip, "port-wwn", 15079 (uchar_t *)&be_sas_wwn, 8) != DDI_PROP_SUCCESS) { 15080 mptsas_log(mpt, CE_WARN, "mptsas unable to " 15081 "create property for SAS target %d lun %d " 15082 "(port-wwn)", target, lun); 15083 ndi_rtn = NDI_FAILURE; 15084 goto phys_create_done; 15085 } else if ((sas_wwn == 0) && (ndi_prop_update_int( 15086 DDI_DEV_T_NONE, *lun_dip, "sata-phy", phy) != 15087 DDI_PROP_SUCCESS)) { 15088 /* 15089 * Direct attached SATA device without DeviceName 15090 */ 15091 mptsas_log(mpt, CE_WARN, "mptsas unable to " 15092 "create property for SAS target %d lun %d " 15093 "(sata-phy)", target, lun); 15094 ndi_rtn = NDI_FAILURE; 15095 goto phys_create_done; 15096 } 15097 15098 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 15099 *lun_dip, SAS_PROP) != DDI_PROP_SUCCESS) { 15100 mptsas_log(mpt, CE_WARN, "mptsas unable to" 15101 "create property for SAS target %d lun %d" 15102 " (SAS_PROP)", target, lun); 15103 ndi_rtn = NDI_FAILURE; 15104 goto phys_create_done; 15105 } 15106 if (guid && (ndi_prop_update_string(DDI_DEV_T_NONE, 15107 *lun_dip, NDI_GUID, guid) != DDI_SUCCESS)) { 15108 mptsas_log(mpt, CE_WARN, "mptsas unable " 15109 "to create guid property for target %d " 15110 "lun %d", target, lun); 15111 ndi_rtn = NDI_FAILURE; 15112 goto phys_create_done; 15113 } 15114 15115 /* 15116 * The following code is to set properties for SM-HBA support, 15117 * it doesn't apply to RAID volumes 15118 */ 15119 if (ptgt->m_phymask == 0) 15120 goto phys_raid_lun; 15121 15122 mutex_enter(&mpt->m_mutex); 15123 15124 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 15125 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 15126 (uint32_t)ptgt->m_devhdl; 15127 rval = mptsas_get_sas_device_page0(mpt, page_address, 15128 &dev_hdl, &dev_sas_wwn, &dev_info, 15129 &physport, &phy_id, &pdev_hdl, 15130 &bay_num, &enclosure); 15131 if (rval != DDI_SUCCESS) { 15132 mutex_exit(&mpt->m_mutex); 15133 mptsas_log(mpt, CE_WARN, "mptsas unable to get" 15134 "parent device for handle %d.", page_address); 15135 ndi_rtn = NDI_FAILURE; 15136 goto phys_create_done; 15137 } 15138 15139 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 15140 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl; 15141 rval = mptsas_get_sas_device_page0(mpt, page_address, 15142 &dev_hdl, &pdev_sas_wwn, &pdev_info, 15143 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure); 15144 if (rval != DDI_SUCCESS) { 15145 mutex_exit(&mpt->m_mutex); 15146 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15147 "device for handle %d.", page_address); 15148 ndi_rtn = NDI_FAILURE; 15149 goto phys_create_done; 15150 } 15151 15152 mutex_exit(&mpt->m_mutex); 15153 15154 /* 15155 * If this device direct attached to the controller 15156 * set the attached-port to the base wwid 15157 */ 15158 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 15159 != DEVINFO_DIRECT_ATTACHED) { 15160 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 15161 pdev_sas_wwn); 15162 } else { 15163 /* 15164 * Update the iport's attached-port to guid 15165 */ 15166 if (sas_wwn == 0) { 15167 (void) sprintf(wwn_str, "p%x", phy); 15168 } else { 15169 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 15170 } 15171 if (ddi_prop_update_string(DDI_DEV_T_NONE, 15172 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 15173 DDI_PROP_SUCCESS) { 15174 mptsas_log(mpt, CE_WARN, 15175 "mptsas unable to create " 15176 "property for iport target-port" 15177 " %s (sas_wwn)", 15178 wwn_str); 15179 ndi_rtn = NDI_FAILURE; 15180 goto phys_create_done; 15181 } 15182 15183 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 15184 mpt->un.m_base_wwid); 15185 } 15186 15187 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15188 *lun_dip, SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) != 15189 DDI_PROP_SUCCESS) { 15190 mptsas_log(mpt, CE_WARN, 15191 "mptsas unable to create " 15192 "property for iport attached-port %s (sas_wwn)", 15193 attached_wwn_str); 15194 ndi_rtn = NDI_FAILURE; 15195 goto phys_create_done; 15196 } 15197 15198 if (IS_SATA_DEVICE(dev_info)) { 15199 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15200 *lun_dip, MPTSAS_VARIANT, "sata") != 15201 DDI_PROP_SUCCESS) { 15202 mptsas_log(mpt, CE_WARN, 15203 "mptsas unable to create " 15204 "property for device variant "); 15205 ndi_rtn = NDI_FAILURE; 15206 goto phys_create_done; 15207 } 15208 } 15209 15210 if (IS_ATAPI_DEVICE(dev_info)) { 15211 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15212 *lun_dip, MPTSAS_VARIANT, "atapi") != 15213 DDI_PROP_SUCCESS) { 15214 mptsas_log(mpt, CE_WARN, 15215 "mptsas unable to create " 15216 "property for device variant "); 15217 ndi_rtn = NDI_FAILURE; 15218 goto phys_create_done; 15219 } 15220 } 15221 15222 phys_raid_lun: 15223 /* 15224 * if this is a SAS controller, and the target is a SATA 15225 * drive, set the 'pm-capable' property for sd and if on 15226 * an OPL platform, also check if this is an ATAPI 15227 * device. 15228 */ 15229 instance = ddi_get_instance(mpt->m_dip); 15230 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 15231 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 15232 NDBG2(("mptsas%d: creating pm-capable property, " 15233 "target %d", instance, target)); 15234 15235 if ((ndi_prop_update_int(DDI_DEV_T_NONE, 15236 *lun_dip, "pm-capable", 1)) != 15237 DDI_PROP_SUCCESS) { 15238 mptsas_log(mpt, CE_WARN, "mptsas " 15239 "failed to create pm-capable " 15240 "property, target %d", target); 15241 ndi_rtn = NDI_FAILURE; 15242 goto phys_create_done; 15243 } 15244 15245 } 15246 15247 if ((inq->inq_dtype == 0) || (inq->inq_dtype == 5)) { 15248 /* 15249 * add 'obp-path' properties for devinfo 15250 */ 15251 bzero(wwn_str, sizeof (wwn_str)); 15252 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn); 15253 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 15254 if (guid) { 15255 (void) snprintf(component, MAXPATHLEN, 15256 "disk@w%s,%x", wwn_str, lun); 15257 } else { 15258 (void) snprintf(component, MAXPATHLEN, 15259 "disk@p%x,%x", phy, lun); 15260 } 15261 if (ddi_pathname_obp_set(*lun_dip, component) 15262 != DDI_SUCCESS) { 15263 mptsas_log(mpt, CE_WARN, "mpt_sas driver " 15264 "unable to set obp-path for SAS " 15265 "object %s", component); 15266 ndi_rtn = NDI_FAILURE; 15267 goto phys_create_done; 15268 } 15269 } 15270 /* 15271 * Create the phy-num property for non-raid disk 15272 */ 15273 if (ptgt->m_phymask != 0) { 15274 if (ndi_prop_update_int(DDI_DEV_T_NONE, 15275 *lun_dip, "phy-num", ptgt->m_phynum) != 15276 DDI_PROP_SUCCESS) { 15277 mptsas_log(mpt, CE_WARN, "mptsas driver " 15278 "failed to create phy-num property for " 15279 "target %d", target); 15280 ndi_rtn = NDI_FAILURE; 15281 goto phys_create_done; 15282 } 15283 } 15284 phys_create_done: 15285 /* 15286 * If props were setup ok, online the lun 15287 */ 15288 if (ndi_rtn == NDI_SUCCESS) { 15289 /* 15290 * Try to online the new node 15291 */ 15292 ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH); 15293 } 15294 if (ndi_rtn == NDI_SUCCESS) { 15295 mutex_enter(&mpt->m_mutex); 15296 ptgt->m_led_status = 0; 15297 if (mptsas_flush_led_status(mpt, ptgt) != DDI_SUCCESS) { 15298 NDBG14(("mptsas: clear LED for tgt %x " 15299 "failed", ptgt->m_slot_num)); 15300 } 15301 mutex_exit(&mpt->m_mutex); 15302 } 15303 15304 /* 15305 * If success set rtn flag, else unwire alloc'd lun 15306 */ 15307 if (ndi_rtn != NDI_SUCCESS) { 15308 NDBG12(("mptsas driver unable to online " 15309 "target %d lun %d", target, lun)); 15310 ndi_prop_remove_all(*lun_dip); 15311 (void) ndi_devi_free(*lun_dip); 15312 *lun_dip = NULL; 15313 } 15314 } 15315 15316 scsi_hba_nodename_compatible_free(nodename, compatible); 15317 15318 if (wwn_str != NULL) { 15319 kmem_free(wwn_str, MPTSAS_WWN_STRLEN); 15320 } 15321 if (component != NULL) { 15322 kmem_free(component, MAXPATHLEN); 15323 } 15324 15325 15326 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 15327 } 15328 15329 static int 15330 mptsas_probe_smp(dev_info_t *pdip, uint64_t wwn) 15331 { 15332 mptsas_t *mpt = DIP2MPT(pdip); 15333 struct smp_device smp_sd; 15334 15335 /* XXX An HBA driver should not be allocating an smp_device. */ 15336 bzero(&smp_sd, sizeof (struct smp_device)); 15337 smp_sd.smp_sd_address.smp_a_hba_tran = mpt->m_smptran; 15338 bcopy(&wwn, smp_sd.smp_sd_address.smp_a_wwn, SAS_WWN_BYTE_SIZE); 15339 15340 if (smp_probe(&smp_sd) != DDI_PROBE_SUCCESS) 15341 return (NDI_FAILURE); 15342 return (NDI_SUCCESS); 15343 } 15344 15345 static int 15346 mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, dev_info_t **smp_dip) 15347 { 15348 mptsas_t *mpt = DIP2MPT(pdip); 15349 mptsas_smp_t *psmp = NULL; 15350 int rval; 15351 int phymask; 15352 15353 /* 15354 * Get the physical port associated to the iport 15355 * PHYMASK TODO 15356 */ 15357 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 15358 "phymask", 0); 15359 /* 15360 * Find the smp node in hash table with specified sas address and 15361 * physical port 15362 */ 15363 psmp = mptsas_wwid_to_psmp(mpt, phymask, sas_wwn); 15364 if (psmp == NULL) { 15365 return (DDI_FAILURE); 15366 } 15367 15368 rval = mptsas_online_smp(pdip, psmp, smp_dip); 15369 15370 return (rval); 15371 } 15372 15373 static int 15374 mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 15375 dev_info_t **smp_dip) 15376 { 15377 char wwn_str[MPTSAS_WWN_STRLEN]; 15378 char attached_wwn_str[MPTSAS_WWN_STRLEN]; 15379 int ndi_rtn = NDI_FAILURE; 15380 int rval = 0; 15381 mptsas_smp_t dev_info; 15382 uint32_t page_address; 15383 mptsas_t *mpt = DIP2MPT(pdip); 15384 uint16_t dev_hdl; 15385 uint64_t sas_wwn; 15386 uint64_t smp_sas_wwn; 15387 uint8_t physport; 15388 uint8_t phy_id; 15389 uint16_t pdev_hdl; 15390 uint8_t numphys = 0; 15391 uint16_t i = 0; 15392 char phymask[MPTSAS_MAX_PHYS]; 15393 char *iport = NULL; 15394 mptsas_phymask_t phy_mask = 0; 15395 uint16_t attached_devhdl; 15396 uint16_t bay_num, enclosure; 15397 15398 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr); 15399 15400 /* 15401 * Probe smp device, prevent the node of removed device from being 15402 * configured succesfully 15403 */ 15404 if (mptsas_probe_smp(pdip, smp_node->m_sasaddr) != NDI_SUCCESS) { 15405 return (DDI_FAILURE); 15406 } 15407 15408 if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) { 15409 return (DDI_SUCCESS); 15410 } 15411 15412 ndi_rtn = ndi_devi_alloc(pdip, "smp", DEVI_SID_NODEID, smp_dip); 15413 15414 /* 15415 * if lun alloc success, set props 15416 */ 15417 if (ndi_rtn == NDI_SUCCESS) { 15418 /* 15419 * Set the flavor of the child to be SMP flavored 15420 */ 15421 ndi_flavor_set(*smp_dip, SCSA_FLAVOR_SMP); 15422 15423 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15424 *smp_dip, SMP_WWN, wwn_str) != 15425 DDI_PROP_SUCCESS) { 15426 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15427 "property for smp device %s (sas_wwn)", 15428 wwn_str); 15429 ndi_rtn = NDI_FAILURE; 15430 goto smp_create_done; 15431 } 15432 (void) sprintf(wwn_str, "w%"PRIx64, smp_node->m_sasaddr); 15433 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15434 *smp_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != 15435 DDI_PROP_SUCCESS) { 15436 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15437 "property for iport target-port %s (sas_wwn)", 15438 wwn_str); 15439 ndi_rtn = NDI_FAILURE; 15440 goto smp_create_done; 15441 } 15442 15443 mutex_enter(&mpt->m_mutex); 15444 15445 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL & 15446 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | smp_node->m_devhdl; 15447 rval = mptsas_get_sas_expander_page0(mpt, page_address, 15448 &dev_info); 15449 if (rval != DDI_SUCCESS) { 15450 mutex_exit(&mpt->m_mutex); 15451 mptsas_log(mpt, CE_WARN, 15452 "mptsas unable to get expander " 15453 "parent device info for %x", page_address); 15454 ndi_rtn = NDI_FAILURE; 15455 goto smp_create_done; 15456 } 15457 15458 smp_node->m_pdevhdl = dev_info.m_pdevhdl; 15459 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 15460 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 15461 (uint32_t)dev_info.m_pdevhdl; 15462 rval = mptsas_get_sas_device_page0(mpt, page_address, 15463 &dev_hdl, &sas_wwn, &smp_node->m_pdevinfo, 15464 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure); 15465 if (rval != DDI_SUCCESS) { 15466 mutex_exit(&mpt->m_mutex); 15467 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 15468 "device info for %x", page_address); 15469 ndi_rtn = NDI_FAILURE; 15470 goto smp_create_done; 15471 } 15472 15473 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 15474 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 15475 (uint32_t)dev_info.m_devhdl; 15476 rval = mptsas_get_sas_device_page0(mpt, page_address, 15477 &dev_hdl, &smp_sas_wwn, &smp_node->m_deviceinfo, 15478 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure); 15479 if (rval != DDI_SUCCESS) { 15480 mutex_exit(&mpt->m_mutex); 15481 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 15482 "device info for %x", page_address); 15483 ndi_rtn = NDI_FAILURE; 15484 goto smp_create_done; 15485 } 15486 mutex_exit(&mpt->m_mutex); 15487 15488 /* 15489 * If this smp direct attached to the controller 15490 * set the attached-port to the base wwid 15491 */ 15492 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 15493 != DEVINFO_DIRECT_ATTACHED) { 15494 (void) sprintf(attached_wwn_str, "w%016"PRIx64, 15495 sas_wwn); 15496 } else { 15497 (void) sprintf(attached_wwn_str, "w%016"PRIx64, 15498 mpt->un.m_base_wwid); 15499 } 15500 15501 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15502 *smp_dip, SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwn_str) != 15503 DDI_PROP_SUCCESS) { 15504 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15505 "property for smp attached-port %s (sas_wwn)", 15506 attached_wwn_str); 15507 ndi_rtn = NDI_FAILURE; 15508 goto smp_create_done; 15509 } 15510 15511 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 15512 *smp_dip, SMP_PROP) != DDI_PROP_SUCCESS) { 15513 mptsas_log(mpt, CE_WARN, "mptsas unable to " 15514 "create property for SMP %s (SMP_PROP) ", 15515 wwn_str); 15516 ndi_rtn = NDI_FAILURE; 15517 goto smp_create_done; 15518 } 15519 15520 /* 15521 * check the smp to see whether it direct 15522 * attached to the controller 15523 */ 15524 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 15525 != DEVINFO_DIRECT_ATTACHED) { 15526 goto smp_create_done; 15527 } 15528 numphys = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 15529 DDI_PROP_DONTPASS, MPTSAS_NUM_PHYS, -1); 15530 if (numphys > 0) { 15531 goto smp_create_done; 15532 } 15533 /* 15534 * this iport is an old iport, we need to 15535 * reconfig the props for it. 15536 */ 15537 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip, 15538 MPTSAS_VIRTUAL_PORT, 0) != 15539 DDI_PROP_SUCCESS) { 15540 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 15541 MPTSAS_VIRTUAL_PORT); 15542 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 15543 "prop update failed"); 15544 goto smp_create_done; 15545 } 15546 15547 mutex_enter(&mpt->m_mutex); 15548 numphys = 0; 15549 iport = ddi_get_name_addr(pdip); 15550 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 15551 bzero(phymask, sizeof (phymask)); 15552 (void) sprintf(phymask, 15553 "%x", mpt->m_phy_info[i].phy_mask); 15554 if (strcmp(phymask, iport) == 0) { 15555 phy_mask = mpt->m_phy_info[i].phy_mask; 15556 break; 15557 } 15558 } 15559 15560 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 15561 if ((phy_mask >> i) & 0x01) { 15562 numphys++; 15563 } 15564 } 15565 /* 15566 * Update PHY info for smhba 15567 */ 15568 if (mptsas_smhba_phy_init(mpt)) { 15569 mutex_exit(&mpt->m_mutex); 15570 mptsas_log(mpt, CE_WARN, "mptsas phy update " 15571 "failed"); 15572 goto smp_create_done; 15573 } 15574 mutex_exit(&mpt->m_mutex); 15575 15576 mptsas_smhba_set_phy_props(mpt, iport, pdip, 15577 numphys, &attached_devhdl); 15578 15579 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip, 15580 MPTSAS_NUM_PHYS, numphys) != 15581 DDI_PROP_SUCCESS) { 15582 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 15583 MPTSAS_NUM_PHYS); 15584 mptsas_log(mpt, CE_WARN, "mptsas update " 15585 "num phys props failed"); 15586 goto smp_create_done; 15587 } 15588 /* 15589 * Add parent's props for SMHBA support 15590 */ 15591 if (ddi_prop_update_string(DDI_DEV_T_NONE, pdip, 15592 SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 15593 DDI_PROP_SUCCESS) { 15594 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 15595 SCSI_ADDR_PROP_ATTACHED_PORT); 15596 mptsas_log(mpt, CE_WARN, "mptsas update iport" 15597 "attached-port failed"); 15598 goto smp_create_done; 15599 } 15600 15601 smp_create_done: 15602 /* 15603 * If props were setup ok, online the lun 15604 */ 15605 if (ndi_rtn == NDI_SUCCESS) { 15606 /* 15607 * Try to online the new node 15608 */ 15609 ndi_rtn = ndi_devi_online(*smp_dip, NDI_ONLINE_ATTACH); 15610 } 15611 15612 /* 15613 * If success set rtn flag, else unwire alloc'd lun 15614 */ 15615 if (ndi_rtn != NDI_SUCCESS) { 15616 NDBG12(("mptsas unable to online " 15617 "SMP target %s", wwn_str)); 15618 ndi_prop_remove_all(*smp_dip); 15619 (void) ndi_devi_free(*smp_dip); 15620 } 15621 } 15622 15623 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 15624 } 15625 15626 /* smp transport routine */ 15627 static int mptsas_smp_start(struct smp_pkt *smp_pkt) 15628 { 15629 uint64_t wwn; 15630 Mpi2SmpPassthroughRequest_t req; 15631 Mpi2SmpPassthroughReply_t rep; 15632 uint32_t direction = 0; 15633 mptsas_t *mpt; 15634 int ret; 15635 uint64_t tmp64; 15636 15637 mpt = (mptsas_t *)smp_pkt->smp_pkt_address-> 15638 smp_a_hba_tran->smp_tran_hba_private; 15639 15640 bcopy(smp_pkt->smp_pkt_address->smp_a_wwn, &wwn, SAS_WWN_BYTE_SIZE); 15641 /* 15642 * Need to compose a SMP request message 15643 * and call mptsas_do_passthru() function 15644 */ 15645 bzero(&req, sizeof (req)); 15646 bzero(&rep, sizeof (rep)); 15647 req.PassthroughFlags = 0; 15648 req.PhysicalPort = 0xff; 15649 req.ChainOffset = 0; 15650 req.Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 15651 15652 if ((smp_pkt->smp_pkt_reqsize & 0xffff0000ul) != 0) { 15653 smp_pkt->smp_pkt_reason = ERANGE; 15654 return (DDI_FAILURE); 15655 } 15656 req.RequestDataLength = LE_16((uint16_t)(smp_pkt->smp_pkt_reqsize - 4)); 15657 15658 req.MsgFlags = 0; 15659 tmp64 = LE_64(wwn); 15660 bcopy(&tmp64, &req.SASAddress, SAS_WWN_BYTE_SIZE); 15661 if (smp_pkt->smp_pkt_rspsize > 0) { 15662 direction |= MPTSAS_PASS_THRU_DIRECTION_READ; 15663 } 15664 if (smp_pkt->smp_pkt_reqsize > 0) { 15665 direction |= MPTSAS_PASS_THRU_DIRECTION_WRITE; 15666 } 15667 15668 mutex_enter(&mpt->m_mutex); 15669 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, 15670 (uint8_t *)smp_pkt->smp_pkt_rsp, 15671 offsetof(Mpi2SmpPassthroughRequest_t, SGL), sizeof (rep), 15672 smp_pkt->smp_pkt_rspsize - 4, direction, 15673 (uint8_t *)smp_pkt->smp_pkt_req, smp_pkt->smp_pkt_reqsize - 4, 15674 smp_pkt->smp_pkt_timeout, FKIOCTL); 15675 mutex_exit(&mpt->m_mutex); 15676 if (ret != 0) { 15677 cmn_err(CE_WARN, "smp_start do passthru error %d", ret); 15678 smp_pkt->smp_pkt_reason = (uchar_t)(ret); 15679 return (DDI_FAILURE); 15680 } 15681 /* do passthrough success, check the smp status */ 15682 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 15683 switch (LE_16(rep.IOCStatus)) { 15684 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 15685 smp_pkt->smp_pkt_reason = ENODEV; 15686 break; 15687 case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN: 15688 smp_pkt->smp_pkt_reason = EOVERFLOW; 15689 break; 15690 case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED: 15691 smp_pkt->smp_pkt_reason = EIO; 15692 break; 15693 default: 15694 mptsas_log(mpt, CE_NOTE, "smp_start: get unknown ioc" 15695 "status:%x", LE_16(rep.IOCStatus)); 15696 smp_pkt->smp_pkt_reason = EIO; 15697 break; 15698 } 15699 return (DDI_FAILURE); 15700 } 15701 if (rep.SASStatus != MPI2_SASSTATUS_SUCCESS) { 15702 mptsas_log(mpt, CE_NOTE, "smp_start: get error SAS status:%x", 15703 rep.SASStatus); 15704 smp_pkt->smp_pkt_reason = EIO; 15705 return (DDI_FAILURE); 15706 } 15707 15708 return (DDI_SUCCESS); 15709 } 15710 15711 /* 15712 * If we didn't get a match, we need to get sas page0 for each device, and 15713 * untill we get a match. If failed, return NULL 15714 */ 15715 static mptsas_target_t * 15716 mptsas_phy_to_tgt(mptsas_t *mpt, int phymask, uint8_t phy) 15717 { 15718 int i, j = 0; 15719 int rval = 0; 15720 uint16_t cur_handle; 15721 uint32_t page_address; 15722 mptsas_target_t *ptgt = NULL; 15723 15724 /* 15725 * PHY named device must be direct attached and attaches to 15726 * narrow port, if the iport is not parent of the device which 15727 * we are looking for. 15728 */ 15729 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 15730 if ((1 << i) & phymask) 15731 j++; 15732 } 15733 15734 if (j > 1) 15735 return (NULL); 15736 15737 /* 15738 * Must be a narrow port and single device attached to the narrow port 15739 * So the physical port num of device which is equal to the iport's 15740 * port num is the device what we are looking for. 15741 */ 15742 15743 if (mpt->m_phy_info[phy].phy_mask != phymask) 15744 return (NULL); 15745 15746 mutex_enter(&mpt->m_mutex); 15747 15748 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 15749 MPTSAS_HASH_FIRST); 15750 while (ptgt != NULL) { 15751 if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) { 15752 mutex_exit(&mpt->m_mutex); 15753 return (ptgt); 15754 } 15755 15756 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 15757 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 15758 } 15759 15760 if (mpt->m_done_traverse_dev) { 15761 mutex_exit(&mpt->m_mutex); 15762 return (NULL); 15763 } 15764 15765 /* If didn't get a match, come here */ 15766 cur_handle = mpt->m_dev_handle; 15767 for (; ; ) { 15768 ptgt = NULL; 15769 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 15770 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)cur_handle; 15771 rval = mptsas_get_target_device_info(mpt, page_address, 15772 &cur_handle, &ptgt); 15773 if ((rval == DEV_INFO_FAIL_PAGE0) || 15774 (rval == DEV_INFO_FAIL_ALLOC)) { 15775 break; 15776 } 15777 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) || 15778 (rval == DEV_INFO_PHYS_DISK)) { 15779 continue; 15780 } 15781 mpt->m_dev_handle = cur_handle; 15782 15783 if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) { 15784 break; 15785 } 15786 } 15787 15788 mutex_exit(&mpt->m_mutex); 15789 return (ptgt); 15790 } 15791 15792 /* 15793 * The ptgt->m_sas_wwn contains the wwid for each disk. 15794 * For Raid volumes, we need to check m_raidvol[x].m_raidwwid 15795 * If we didn't get a match, we need to get sas page0 for each device, and 15796 * untill we get a match 15797 * If failed, return NULL 15798 */ 15799 static mptsas_target_t * 15800 mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask, uint64_t wwid) 15801 { 15802 int rval = 0; 15803 uint16_t cur_handle; 15804 uint32_t page_address; 15805 mptsas_target_t *tmp_tgt = NULL; 15806 15807 mutex_enter(&mpt->m_mutex); 15808 tmp_tgt = (struct mptsas_target *)mptsas_hash_search( 15809 &mpt->m_active->m_tgttbl, wwid, phymask); 15810 if (tmp_tgt != NULL) { 15811 mutex_exit(&mpt->m_mutex); 15812 return (tmp_tgt); 15813 } 15814 15815 if (phymask == 0) { 15816 /* 15817 * It's IR volume 15818 */ 15819 rval = mptsas_get_raid_info(mpt); 15820 if (rval) { 15821 tmp_tgt = (struct mptsas_target *)mptsas_hash_search( 15822 &mpt->m_active->m_tgttbl, wwid, phymask); 15823 } 15824 mutex_exit(&mpt->m_mutex); 15825 return (tmp_tgt); 15826 } 15827 15828 if (mpt->m_done_traverse_dev) { 15829 mutex_exit(&mpt->m_mutex); 15830 return (NULL); 15831 } 15832 15833 /* If didn't get a match, come here */ 15834 cur_handle = mpt->m_dev_handle; 15835 for (; ; ) { 15836 tmp_tgt = NULL; 15837 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 15838 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle; 15839 rval = mptsas_get_target_device_info(mpt, page_address, 15840 &cur_handle, &tmp_tgt); 15841 if ((rval == DEV_INFO_FAIL_PAGE0) || 15842 (rval == DEV_INFO_FAIL_ALLOC)) { 15843 tmp_tgt = NULL; 15844 break; 15845 } 15846 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) || 15847 (rval == DEV_INFO_PHYS_DISK)) { 15848 continue; 15849 } 15850 mpt->m_dev_handle = cur_handle; 15851 if ((tmp_tgt->m_sas_wwn) && (tmp_tgt->m_sas_wwn == wwid) && 15852 (tmp_tgt->m_phymask == phymask)) { 15853 break; 15854 } 15855 } 15856 15857 mutex_exit(&mpt->m_mutex); 15858 return (tmp_tgt); 15859 } 15860 15861 static mptsas_smp_t * 15862 mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask, uint64_t wwid) 15863 { 15864 int rval = 0; 15865 uint16_t cur_handle; 15866 uint32_t page_address; 15867 mptsas_smp_t smp_node, *psmp = NULL; 15868 15869 mutex_enter(&mpt->m_mutex); 15870 psmp = (struct mptsas_smp *)mptsas_hash_search(&mpt->m_active->m_smptbl, 15871 wwid, phymask); 15872 if (psmp != NULL) { 15873 mutex_exit(&mpt->m_mutex); 15874 return (psmp); 15875 } 15876 15877 if (mpt->m_done_traverse_smp) { 15878 mutex_exit(&mpt->m_mutex); 15879 return (NULL); 15880 } 15881 15882 /* If didn't get a match, come here */ 15883 cur_handle = mpt->m_smp_devhdl; 15884 for (; ; ) { 15885 psmp = NULL; 15886 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL & 15887 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle; 15888 rval = mptsas_get_sas_expander_page0(mpt, page_address, 15889 &smp_node); 15890 if (rval != DDI_SUCCESS) { 15891 break; 15892 } 15893 mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl; 15894 psmp = mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node); 15895 ASSERT(psmp); 15896 if ((psmp->m_sasaddr) && (psmp->m_sasaddr == wwid) && 15897 (psmp->m_phymask == phymask)) { 15898 break; 15899 } 15900 } 15901 15902 mutex_exit(&mpt->m_mutex); 15903 return (psmp); 15904 } 15905 15906 /* helper functions using hash */ 15907 15908 /* 15909 * Can't have duplicate entries for same devhdl, 15910 * if there are invalid entries, the devhdl should be set to 0xffff 15911 */ 15912 static void * 15913 mptsas_search_by_devhdl(mptsas_hash_table_t *hashtab, uint16_t devhdl) 15914 { 15915 mptsas_hash_data_t *data; 15916 15917 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST); 15918 while (data != NULL) { 15919 if (data->devhdl == devhdl) { 15920 break; 15921 } 15922 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT); 15923 } 15924 return (data); 15925 } 15926 15927 mptsas_target_t * 15928 mptsas_tgt_alloc(mptsas_hash_table_t *hashtab, uint16_t devhdl, uint64_t wwid, 15929 uint32_t devinfo, mptsas_phymask_t phymask, uint8_t phynum, mptsas_t *mpt) 15930 { 15931 mptsas_target_t *tmp_tgt = NULL; 15932 15933 tmp_tgt = mptsas_hash_search(hashtab, wwid, phymask); 15934 if (tmp_tgt != NULL) { 15935 NDBG20(("Hash item already exist")); 15936 tmp_tgt->m_deviceinfo = devinfo; 15937 tmp_tgt->m_devhdl = devhdl; 15938 return (tmp_tgt); 15939 } 15940 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP); 15941 if (tmp_tgt == NULL) { 15942 cmn_err(CE_WARN, "Fatal, allocated tgt failed"); 15943 return (NULL); 15944 } 15945 tmp_tgt->m_devhdl = devhdl; 15946 tmp_tgt->m_sas_wwn = wwid; 15947 tmp_tgt->m_deviceinfo = devinfo; 15948 tmp_tgt->m_phymask = phymask; 15949 tmp_tgt->m_phynum = phynum; 15950 /* Initialized the tgt structure */ 15951 tmp_tgt->m_qfull_retries = QFULL_RETRIES; 15952 tmp_tgt->m_qfull_retry_interval = 15953 drv_usectohz(QFULL_RETRY_INTERVAL * 1000); 15954 tmp_tgt->m_t_throttle = MAX_THROTTLE; 15955 mutex_init(&tmp_tgt->m_tgt_intr_mutex, NULL, MUTEX_DRIVER, 15956 DDI_INTR_PRI(mpt->m_intr_pri)); 15957 15958 mptsas_hash_add(hashtab, tmp_tgt); 15959 15960 return (tmp_tgt); 15961 } 15962 15963 static void 15964 mptsas_tgt_free(mptsas_hash_table_t *hashtab, uint64_t wwid, 15965 mptsas_phymask_t phymask) 15966 { 15967 mptsas_target_t *tmp_tgt; 15968 tmp_tgt = mptsas_hash_rem(hashtab, wwid, phymask); 15969 if (tmp_tgt == NULL) { 15970 cmn_err(CE_WARN, "Tgt not found, nothing to free"); 15971 } else { 15972 mutex_destroy(&tmp_tgt->m_tgt_intr_mutex); 15973 kmem_free(tmp_tgt, sizeof (struct mptsas_target)); 15974 } 15975 } 15976 15977 /* 15978 * Return the entry in the hash table 15979 */ 15980 static mptsas_smp_t * 15981 mptsas_smp_alloc(mptsas_hash_table_t *hashtab, mptsas_smp_t *data) 15982 { 15983 uint64_t key1 = data->m_sasaddr; 15984 mptsas_phymask_t key2 = data->m_phymask; 15985 mptsas_smp_t *ret_data; 15986 15987 ret_data = mptsas_hash_search(hashtab, key1, key2); 15988 if (ret_data != NULL) { 15989 bcopy(data, ret_data, sizeof (mptsas_smp_t)); 15990 return (ret_data); 15991 } 15992 15993 ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP); 15994 bcopy(data, ret_data, sizeof (mptsas_smp_t)); 15995 mptsas_hash_add(hashtab, ret_data); 15996 return (ret_data); 15997 } 15998 15999 static void 16000 mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid, 16001 mptsas_phymask_t phymask) 16002 { 16003 mptsas_smp_t *tmp_smp; 16004 tmp_smp = mptsas_hash_rem(hashtab, wwid, phymask); 16005 if (tmp_smp == NULL) { 16006 cmn_err(CE_WARN, "Smp element not found, nothing to free"); 16007 } else { 16008 kmem_free(tmp_smp, sizeof (struct mptsas_smp)); 16009 } 16010 } 16011 16012 /* 16013 * Hash operation functions 16014 * key1 is the sas_wwn, key2 is the phymask 16015 */ 16016 static void 16017 mptsas_hash_init(mptsas_hash_table_t *hashtab) 16018 { 16019 if (hashtab == NULL) { 16020 return; 16021 } 16022 bzero(hashtab->head, sizeof (mptsas_hash_node_t) * 16023 MPTSAS_HASH_ARRAY_SIZE); 16024 hashtab->cur = NULL; 16025 hashtab->line = 0; 16026 } 16027 16028 static void 16029 mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen) 16030 { 16031 uint16_t line = 0; 16032 mptsas_hash_node_t *cur = NULL, *last = NULL; 16033 16034 if (hashtab == NULL) { 16035 return; 16036 } 16037 for (line = 0; line < MPTSAS_HASH_ARRAY_SIZE; line++) { 16038 cur = hashtab->head[line]; 16039 while (cur != NULL) { 16040 last = cur; 16041 cur = cur->next; 16042 kmem_free(last->data, datalen); 16043 kmem_free(last, sizeof (mptsas_hash_node_t)); 16044 } 16045 } 16046 } 16047 16048 /* 16049 * You must guarantee the element doesn't exist in the hash table 16050 * before you call mptsas_hash_add() 16051 */ 16052 static void 16053 mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data) 16054 { 16055 uint64_t key1 = ((mptsas_hash_data_t *)data)->key1; 16056 mptsas_phymask_t key2 = ((mptsas_hash_data_t *)data)->key2; 16057 mptsas_hash_node_t **head = NULL; 16058 mptsas_hash_node_t *node = NULL; 16059 16060 if (hashtab == NULL) { 16061 return; 16062 } 16063 ASSERT(mptsas_hash_search(hashtab, key1, key2) == NULL); 16064 node = kmem_zalloc(sizeof (mptsas_hash_node_t), KM_NOSLEEP); 16065 node->data = data; 16066 16067 head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]); 16068 if (*head == NULL) { 16069 *head = node; 16070 } else { 16071 node->next = *head; 16072 *head = node; 16073 } 16074 } 16075 16076 static void * 16077 mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1, 16078 mptsas_phymask_t key2) 16079 { 16080 mptsas_hash_node_t **head = NULL; 16081 mptsas_hash_node_t *last = NULL, *cur = NULL; 16082 mptsas_hash_data_t *data; 16083 if (hashtab == NULL) { 16084 return (NULL); 16085 } 16086 head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]); 16087 cur = *head; 16088 while (cur != NULL) { 16089 data = cur->data; 16090 if ((data->key1 == key1) && (data->key2 == key2)) { 16091 if (last == NULL) { 16092 (*head) = cur->next; 16093 } else { 16094 last->next = cur->next; 16095 } 16096 kmem_free(cur, sizeof (mptsas_hash_node_t)); 16097 return (data); 16098 } else { 16099 last = cur; 16100 cur = cur->next; 16101 } 16102 } 16103 return (NULL); 16104 } 16105 16106 static void * 16107 mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1, 16108 mptsas_phymask_t key2) 16109 { 16110 mptsas_hash_node_t *cur = NULL; 16111 mptsas_hash_data_t *data; 16112 if (hashtab == NULL) { 16113 return (NULL); 16114 } 16115 cur = hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]; 16116 while (cur != NULL) { 16117 data = cur->data; 16118 if ((data->key1 == key1) && (data->key2 == key2)) { 16119 return (data); 16120 } else { 16121 cur = cur->next; 16122 } 16123 } 16124 return (NULL); 16125 } 16126 16127 static void * 16128 mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos) 16129 { 16130 mptsas_hash_node_t *this = NULL; 16131 16132 if (hashtab == NULL) { 16133 return (NULL); 16134 } 16135 16136 if (pos == MPTSAS_HASH_FIRST) { 16137 hashtab->line = 0; 16138 hashtab->cur = NULL; 16139 this = hashtab->head[0]; 16140 } else { 16141 if (hashtab->cur == NULL) { 16142 return (NULL); 16143 } else { 16144 this = hashtab->cur->next; 16145 } 16146 } 16147 16148 while (this == NULL) { 16149 hashtab->line++; 16150 if (hashtab->line >= MPTSAS_HASH_ARRAY_SIZE) { 16151 /* the traverse reaches the end */ 16152 hashtab->cur = NULL; 16153 return (NULL); 16154 } else { 16155 this = hashtab->head[hashtab->line]; 16156 } 16157 } 16158 hashtab->cur = this; 16159 return (this->data); 16160 } 16161 16162 /* 16163 * Functions for SGPIO LED support 16164 */ 16165 static dev_info_t * 16166 mptsas_get_dip_from_dev(dev_t dev, mptsas_phymask_t *phymask) 16167 { 16168 dev_info_t *dip; 16169 int prop; 16170 dip = e_ddi_hold_devi_by_dev(dev, 0); 16171 if (dip == NULL) 16172 return (dip); 16173 prop = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 16174 "phymask", 0); 16175 *phymask = (mptsas_phymask_t)prop; 16176 ddi_release_devi(dip); 16177 return (dip); 16178 } 16179 static mptsas_target_t * 16180 mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask) 16181 { 16182 uint8_t phynum; 16183 uint64_t wwn; 16184 int lun; 16185 mptsas_target_t *ptgt = NULL; 16186 16187 if (mptsas_parse_address(addr, &wwn, &phynum, &lun) != DDI_SUCCESS) { 16188 return (NULL); 16189 } 16190 if (addr[0] == 'w') { 16191 ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn); 16192 } else { 16193 ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum); 16194 } 16195 return (ptgt); 16196 } 16197 16198 static int 16199 mptsas_flush_led_status(mptsas_t *mpt, mptsas_target_t *ptgt) 16200 { 16201 uint32_t slotstatus = 0; 16202 16203 /* Build an MPI2 Slot Status based on our view of the world */ 16204 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_IDENT - 1))) 16205 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST; 16206 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_FAIL - 1))) 16207 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT; 16208 if (ptgt->m_led_status & (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1))) 16209 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE; 16210 16211 /* Write it to the controller */ 16212 NDBG14(("mptsas_ioctl: set LED status %x for slot %x", 16213 slotstatus, ptgt->m_slot_num)); 16214 return (mptsas_send_sep(mpt, ptgt, &slotstatus, 16215 MPI2_SEP_REQ_ACTION_WRITE_STATUS)); 16216 } 16217 16218 /* 16219 * send sep request, use enclosure/slot addressing 16220 */ 16221 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt, 16222 uint32_t *status, uint8_t act) 16223 { 16224 Mpi2SepRequest_t req; 16225 Mpi2SepReply_t rep; 16226 int ret; 16227 16228 ASSERT(mutex_owned(&mpt->m_mutex)); 16229 16230 bzero(&req, sizeof (req)); 16231 bzero(&rep, sizeof (rep)); 16232 16233 /* Do nothing for RAID volumes */ 16234 if (ptgt->m_phymask == 0) { 16235 NDBG14(("mptsas_send_sep: Skip RAID volumes")); 16236 return (DDI_FAILURE); 16237 } 16238 16239 req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; 16240 req.Action = act; 16241 req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS; 16242 req.EnclosureHandle = LE_16(ptgt->m_enclosure); 16243 req.Slot = LE_16(ptgt->m_slot_num); 16244 if (act == MPI2_SEP_REQ_ACTION_WRITE_STATUS) { 16245 req.SlotStatus = LE_32(*status); 16246 } 16247 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL, 16248 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL); 16249 if (ret != 0) { 16250 mptsas_log(mpt, CE_NOTE, "mptsas_send_sep: passthru SEP " 16251 "Processor Request message error %d", ret); 16252 return (DDI_FAILURE); 16253 } 16254 /* do passthrough success, check the ioc status */ 16255 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 16256 if ((LE_16(rep.IOCStatus) & MPI2_IOCSTATUS_MASK) == 16257 MPI2_IOCSTATUS_INVALID_FIELD) { 16258 mptsas_log(mpt, CE_NOTE, "send sep act %x: Not " 16259 "supported action, loginfo %x", act, 16260 LE_32(rep.IOCLogInfo)); 16261 return (DDI_FAILURE); 16262 } 16263 mptsas_log(mpt, CE_NOTE, "send_sep act %x: ioc " 16264 "status:%x", act, LE_16(rep.IOCStatus)); 16265 return (DDI_FAILURE); 16266 } 16267 if (act != MPI2_SEP_REQ_ACTION_WRITE_STATUS) { 16268 *status = LE_32(rep.SlotStatus); 16269 } 16270 16271 return (DDI_SUCCESS); 16272 } 16273 16274 int 16275 mptsas_dma_addr_create(mptsas_t *mpt, ddi_dma_attr_t dma_attr, 16276 ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp, caddr_t *dma_memp, 16277 uint32_t alloc_size, ddi_dma_cookie_t *cookiep) 16278 { 16279 ddi_dma_cookie_t new_cookie; 16280 size_t alloc_len; 16281 uint_t ncookie; 16282 16283 if (cookiep == NULL) 16284 cookiep = &new_cookie; 16285 16286 if (ddi_dma_alloc_handle(mpt->m_dip, &dma_attr, DDI_DMA_SLEEP, 16287 NULL, dma_hdp) != DDI_SUCCESS) { 16288 dma_hdp = NULL; 16289 return (FALSE); 16290 } 16291 16292 if (ddi_dma_mem_alloc(*dma_hdp, alloc_size, &mpt->m_dev_acc_attr, 16293 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, dma_memp, &alloc_len, 16294 acc_hdp) != DDI_SUCCESS) { 16295 ddi_dma_free_handle(dma_hdp); 16296 dma_hdp = NULL; 16297 return (FALSE); 16298 } 16299 16300 if (ddi_dma_addr_bind_handle(*dma_hdp, NULL, *dma_memp, alloc_len, 16301 (DDI_DMA_RDWR | DDI_DMA_CONSISTENT), DDI_DMA_SLEEP, NULL, 16302 cookiep, &ncookie) != DDI_DMA_MAPPED) { 16303 (void) ddi_dma_mem_free(acc_hdp); 16304 ddi_dma_free_handle(dma_hdp); 16305 dma_hdp = NULL; 16306 return (FALSE); 16307 } 16308 16309 return (TRUE); 16310 } 16311 16312 void 16313 mptsas_dma_addr_destroy(ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp) 16314 { 16315 if (*dma_hdp == NULL) 16316 return; 16317 16318 (void) ddi_dma_unbind_handle(*dma_hdp); 16319 (void) ddi_dma_mem_free(acc_hdp); 16320 ddi_dma_free_handle(dma_hdp); 16321 dma_hdp = NULL; 16322 } 16323 16324 static int 16325 mptsas_outstanding_cmds_n(mptsas_t *mpt) 16326 { 16327 int n = 0, i; 16328 for (i = 0; i < mpt->m_slot_freeq_pair_n; i++) { 16329 mutex_enter(&mpt->m_slot_freeq_pairp[i]. 16330 m_slot_allocq.s.m_fq_mutex); 16331 mutex_enter(&mpt->m_slot_freeq_pairp[i]. 16332 m_slot_releq.s.m_fq_mutex); 16333 n += (mpt->m_slot_freeq_pairp[i].m_slot_allocq.s.m_fq_n_init - 16334 mpt->m_slot_freeq_pairp[i].m_slot_allocq.s.m_fq_n - 16335 mpt->m_slot_freeq_pairp[i].m_slot_releq.s.m_fq_n); 16336 mutex_exit(&mpt->m_slot_freeq_pairp[i]. 16337 m_slot_releq.s.m_fq_mutex); 16338 mutex_exit(&mpt->m_slot_freeq_pairp[i]. 16339 m_slot_allocq.s.m_fq_mutex); 16340 } 16341 if (mpt->m_max_requests - 2 < n) 16342 panic("mptsas: free slot allocq and releq crazy"); 16343 return (n); 16344 }