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 */ 26 27 /* 28 * Copyright (c) 2000 to 2010, LSI Corporation. 29 * All rights reserved. 30 * 31 * Redistribution and use in source and binary forms of all code within 32 * this file that is exclusively owned by LSI, with or without 33 * modification, is permitted provided that, in addition to the CDDL 1.0 34 * License requirements, the following conditions are met: 35 * 36 * Neither the name of the author nor the names of its contributors may be 37 * used to endorse or promote products derived from this software without 38 * specific prior written permission. 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 43 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 44 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 45 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 46 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 47 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 48 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 49 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 50 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 51 * DAMAGE. 52 */ 53 54 /* 55 * mptsas - This is a driver based on LSI Logic's MPT2.0 interface. 56 * 57 */ 58 59 #if defined(lint) || defined(DEBUG) 60 #define MPTSAS_DEBUG 61 #endif 62 63 /* 64 * standard header files. 65 */ 66 #include <sys/note.h> 67 #include <sys/scsi/scsi.h> 68 #include <sys/pci.h> 69 #include <sys/file.h> 70 #include <sys/policy.h> 71 #include <sys/sysevent.h> 72 #include <sys/sysevent/eventdefs.h> 73 #include <sys/sysevent/dr.h> 74 #include <sys/sata/sata_defs.h> 75 #include <sys/scsi/generic/sas.h> 76 #include <sys/scsi/impl/scsi_sas.h> 77 78 #pragma pack(1) 79 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h> 80 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h> 81 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h> 82 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h> 83 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h> 84 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h> 85 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h> 86 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h> 87 #pragma pack() 88 89 /* 90 * private header files. 91 * 92 */ 93 #include <sys/scsi/impl/scsi_reset_notify.h> 94 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h> 95 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h> 96 #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h> 97 #include <sys/raidioctl.h> 98 99 #include <sys/fs/dv_node.h> /* devfs_clean */ 100 101 /* 102 * FMA header files 103 */ 104 #include <sys/ddifm.h> 105 #include <sys/fm/protocol.h> 106 #include <sys/fm/util.h> 107 #include <sys/fm/io/ddi.h> 108 109 /* 110 * autoconfiguration data and routines. 111 */ 112 static int mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 113 static int mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd); 114 static int mptsas_power(dev_info_t *dip, int component, int level); 115 116 /* 117 * cb_ops function 118 */ 119 static int mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, 120 cred_t *credp, int *rval); 121 #ifdef __sparc 122 static int mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd); 123 #else /* __sparc */ 124 static int mptsas_quiesce(dev_info_t *devi); 125 #endif /* __sparc */ 126 127 /* 128 * Resource initilaization for hardware 129 */ 130 static void mptsas_setup_cmd_reg(mptsas_t *mpt); 131 static void mptsas_disable_bus_master(mptsas_t *mpt); 132 static void mptsas_hba_fini(mptsas_t *mpt); 133 static void mptsas_cfg_fini(mptsas_t *mptsas_blkp); 134 static int mptsas_hba_setup(mptsas_t *mpt); 135 static void mptsas_hba_teardown(mptsas_t *mpt); 136 static int mptsas_config_space_init(mptsas_t *mpt); 137 static void mptsas_config_space_fini(mptsas_t *mpt); 138 static void mptsas_iport_register(mptsas_t *mpt); 139 static int mptsas_smp_setup(mptsas_t *mpt); 140 static void mptsas_smp_teardown(mptsas_t *mpt); 141 static int mptsas_cache_create(mptsas_t *mpt); 142 static void mptsas_cache_destroy(mptsas_t *mpt); 143 static int mptsas_alloc_request_frames(mptsas_t *mpt); 144 static int mptsas_alloc_reply_frames(mptsas_t *mpt); 145 static int mptsas_alloc_free_queue(mptsas_t *mpt); 146 static int mptsas_alloc_post_queue(mptsas_t *mpt); 147 static void mptsas_alloc_reply_args(mptsas_t *mpt); 148 static int mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd); 149 static void mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd); 150 static int mptsas_init_chip(mptsas_t *mpt, int first_time); 151 152 /* 153 * SCSA function prototypes 154 */ 155 static int mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt); 156 static int mptsas_scsi_reset(struct scsi_address *ap, int level); 157 static int mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt); 158 static int mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly); 159 static int mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, 160 int tgtonly); 161 static void mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt); 162 static struct scsi_pkt *mptsas_scsi_init_pkt(struct scsi_address *ap, 163 struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen, 164 int tgtlen, int flags, int (*callback)(), caddr_t arg); 165 static void mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt); 166 static void mptsas_scsi_destroy_pkt(struct scsi_address *ap, 167 struct scsi_pkt *pkt); 168 static int mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 169 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 170 static void mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 171 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 172 static int mptsas_scsi_reset_notify(struct scsi_address *ap, int flag, 173 void (*callback)(caddr_t), caddr_t arg); 174 static int mptsas_get_name(struct scsi_device *sd, char *name, int len); 175 static int mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len); 176 static int mptsas_scsi_quiesce(dev_info_t *dip); 177 static int mptsas_scsi_unquiesce(dev_info_t *dip); 178 static int mptsas_bus_config(dev_info_t *pdip, uint_t flags, 179 ddi_bus_config_op_t op, void *arg, dev_info_t **childp); 180 181 /* 182 * SMP functions 183 */ 184 static int mptsas_smp_start(struct smp_pkt *smp_pkt); 185 186 /* 187 * internal function prototypes. 188 */ 189 static void mptsas_list_add(mptsas_t *mpt); 190 static void mptsas_list_del(mptsas_t *mpt); 191 192 static int mptsas_quiesce_bus(mptsas_t *mpt); 193 static int mptsas_unquiesce_bus(mptsas_t *mpt); 194 195 static int mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size); 196 static void mptsas_free_handshake_msg(mptsas_t *mpt); 197 198 static void mptsas_ncmds_checkdrain(void *arg); 199 200 static int mptsas_prepare_pkt(mptsas_cmd_t *cmd); 201 static int mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *sp); 202 static int mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *sp); 203 static void mptsas_accept_tx_waitq(mptsas_t *mpt); 204 205 static int mptsas_do_detach(dev_info_t *dev); 206 static int mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl); 207 static int mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, 208 struct scsi_pkt *pkt); 209 static int mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp); 210 211 static void mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd); 212 static void mptsas_handle_event(void *args); 213 static int mptsas_handle_event_sync(void *args); 214 static void mptsas_handle_dr(void *args); 215 static void mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node, 216 dev_info_t *pdip); 217 218 static void mptsas_restart_cmd(void *); 219 220 static void mptsas_flush_hba(mptsas_t *mpt); 221 static void mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, 222 uint8_t tasktype); 223 static void mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, 224 uchar_t reason, uint_t stat); 225 226 static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2); 227 static void mptsas_process_intr(mptsas_t *mpt, 228 pMpi2ReplyDescriptorsUnion_t reply_desc_union); 229 static void mptsas_handle_scsi_io_success(mptsas_t *mpt, 230 pMpi2ReplyDescriptorsUnion_t reply_desc); 231 static void mptsas_handle_address_reply(mptsas_t *mpt, 232 pMpi2ReplyDescriptorsUnion_t reply_desc); 233 static int mptsas_wait_intr(mptsas_t *mpt, int polltime); 234 static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, 235 uint32_t *control, pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl); 236 237 static void mptsas_watch(void *arg); 238 static void mptsas_watchsubr(mptsas_t *mpt); 239 static void mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl); 240 241 static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd); 242 static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply, 243 uint8_t *data, uint32_t request_size, uint32_t reply_size, 244 uint32_t data_size, uint32_t direction, uint8_t *dataout, 245 uint32_t dataout_size, short timeout, int mode); 246 static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl); 247 248 static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, 249 uint32_t unique_id); 250 static void mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd); 251 static int mptsas_post_fw_diag_buffer(mptsas_t *mpt, 252 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code); 253 static int mptsas_release_fw_diag_buffer(mptsas_t *mpt, 254 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code, 255 uint32_t diag_type); 256 static int mptsas_diag_register(mptsas_t *mpt, 257 mptsas_fw_diag_register_t *diag_register, uint32_t *return_code); 258 static int mptsas_diag_unregister(mptsas_t *mpt, 259 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code); 260 static int mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query, 261 uint32_t *return_code); 262 static int mptsas_diag_read_buffer(mptsas_t *mpt, 263 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf, 264 uint32_t *return_code, int ioctl_mode); 265 static int mptsas_diag_release(mptsas_t *mpt, 266 mptsas_fw_diag_release_t *diag_release, uint32_t *return_code); 267 static int mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, 268 uint8_t *diag_action, uint32_t length, uint32_t *return_code, 269 int ioctl_mode); 270 static int mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *data, 271 int mode); 272 273 static int mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd, 274 int cmdlen, int tgtlen, int statuslen, int kf); 275 static void mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd); 276 277 static int mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags); 278 static void mptsas_kmem_cache_destructor(void *buf, void *cdrarg); 279 280 static int mptsas_cache_frames_constructor(void *buf, void *cdrarg, 281 int kmflags); 282 static void mptsas_cache_frames_destructor(void *buf, void *cdrarg); 283 284 static void mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, 285 mptsas_cmd_t *cmd); 286 static void mptsas_check_task_mgt(mptsas_t *mpt, 287 pMpi2SCSIManagementReply_t reply, mptsas_cmd_t *cmd); 288 static int mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap, 289 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp, 290 int *resid); 291 292 static int mptsas_alloc_active_slots(mptsas_t *mpt, int flag); 293 static void mptsas_free_active_slots(mptsas_t *mpt); 294 static int mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd); 295 296 static void mptsas_restart_hba(mptsas_t *mpt); 297 static void mptsas_restart_waitq(mptsas_t *mpt); 298 299 static void mptsas_deliver_doneq_thread(mptsas_t *mpt); 300 static void mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd); 301 static void mptsas_doneq_mv(mptsas_t *mpt, uint64_t t); 302 303 static mptsas_cmd_t *mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t); 304 static void mptsas_doneq_empty(mptsas_t *mpt); 305 static void mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg); 306 307 static mptsas_cmd_t *mptsas_waitq_rm(mptsas_t *mpt); 308 static void mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd); 309 static mptsas_cmd_t *mptsas_tx_waitq_rm(mptsas_t *mpt); 310 static void mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd); 311 312 313 static void mptsas_start_watch_reset_delay(); 314 static void mptsas_setup_bus_reset_delay(mptsas_t *mpt); 315 static void mptsas_watch_reset_delay(void *arg); 316 static int mptsas_watch_reset_delay_subr(mptsas_t *mpt); 317 318 /* 319 * helper functions 320 */ 321 static void mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd); 322 323 static dev_info_t *mptsas_find_child(dev_info_t *pdip, char *name); 324 static dev_info_t *mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy); 325 static dev_info_t *mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, 326 int lun); 327 static mdi_pathinfo_t *mptsas_find_path_addr(dev_info_t *pdip, uint64_t sasaddr, 328 int lun); 329 static mdi_pathinfo_t *mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy); 330 static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn); 331 332 static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, 333 int *lun); 334 static int mptsas_parse_smp_name(char *name, uint64_t *wwn); 335 336 static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt, int phymask, 337 uint8_t phy); 338 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask, 339 uint64_t wwid); 340 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask, 341 uint64_t wwid); 342 343 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, 344 uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd); 345 346 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address, 347 uint16_t *handle, mptsas_target_t **pptgt); 348 static void mptsas_update_phymask(mptsas_t *mpt); 349 350 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt, 351 uint32_t *status, uint8_t cmd); 352 static dev_info_t *mptsas_get_dip_from_dev(dev_t dev, 353 mptsas_phymask_t *phymask); 354 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, 355 mptsas_phymask_t phymask); 356 static int mptsas_set_led_status(mptsas_t *mpt, mptsas_target_t *ptgt, 357 uint32_t slotstatus); 358 359 360 /* 361 * Enumeration / DR functions 362 */ 363 static void mptsas_config_all(dev_info_t *pdip); 364 static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun, 365 dev_info_t **lundip); 366 static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun, 367 dev_info_t **lundip); 368 369 static int mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt); 370 static int mptsas_offline_target(dev_info_t *pdip, char *name); 371 372 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target, 373 dev_info_t **dip); 374 375 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt); 376 static int mptsas_probe_lun(dev_info_t *pdip, int lun, 377 dev_info_t **dip, mptsas_target_t *ptgt); 378 379 static int mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq, 380 dev_info_t **dip, mptsas_target_t *ptgt, int lun); 381 382 static int mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *sd, 383 char *guid, dev_info_t **dip, mptsas_target_t *ptgt, int lun); 384 static int mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *sd, 385 char *guid, dev_info_t **dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, 386 int lun); 387 388 static void mptsas_offline_missed_luns(dev_info_t *pdip, 389 uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt); 390 static int mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip, 391 mdi_pathinfo_t *rpip, uint_t flags); 392 393 static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, 394 dev_info_t **smp_dip); 395 static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 396 uint_t flags); 397 398 static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, 399 int mode, int *rval); 400 static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, 401 int mode, int *rval); 402 static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, 403 int mode, int *rval); 404 static void mptsas_record_event(void *args); 405 static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, 406 int mode); 407 408 static void mptsas_hash_init(mptsas_hash_table_t *hashtab); 409 static void mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen); 410 static void mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data); 411 static void * mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1, 412 mptsas_phymask_t key2); 413 static void * mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1, 414 mptsas_phymask_t key2); 415 static void * mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos); 416 417 mptsas_target_t *mptsas_tgt_alloc(mptsas_hash_table_t *, uint16_t, uint64_t, 418 uint32_t, mptsas_phymask_t, uint8_t); 419 static mptsas_smp_t *mptsas_smp_alloc(mptsas_hash_table_t *hashtab, 420 mptsas_smp_t *data); 421 static void mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid, 422 mptsas_phymask_t phymask); 423 static void mptsas_tgt_free(mptsas_hash_table_t *, uint64_t, mptsas_phymask_t); 424 static void * mptsas_search_by_devhdl(mptsas_hash_table_t *, uint16_t); 425 static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 426 dev_info_t **smp_dip); 427 428 /* 429 * Power management functions 430 */ 431 static int mptsas_get_pci_cap(mptsas_t *mpt); 432 static int mptsas_init_pm(mptsas_t *mpt); 433 434 /* 435 * MPT MSI tunable: 436 * 437 * By default MSI is enabled on all supported platforms. 438 */ 439 boolean_t mptsas_enable_msi = B_TRUE; 440 boolean_t mptsas_physical_bind_failed_page_83 = B_FALSE; 441 442 static int mptsas_register_intrs(mptsas_t *); 443 static void mptsas_unregister_intrs(mptsas_t *); 444 static int mptsas_add_intrs(mptsas_t *, int); 445 static void mptsas_rem_intrs(mptsas_t *); 446 447 /* 448 * FMA Prototypes 449 */ 450 static void mptsas_fm_init(mptsas_t *mpt); 451 static void mptsas_fm_fini(mptsas_t *mpt); 452 static int mptsas_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *); 453 454 extern pri_t minclsyspri, maxclsyspri; 455 456 /* 457 * This device is created by the SCSI pseudo nexus driver (SCSI vHCI). It is 458 * under this device that the paths to a physical device are created when 459 * MPxIO is used. 460 */ 461 extern dev_info_t *scsi_vhci_dip; 462 463 /* 464 * Tunable timeout value for Inquiry VPD page 0x83 465 * By default the value is 30 seconds. 466 */ 467 int mptsas_inq83_retry_timeout = 30; 468 469 /* 470 * This is used to allocate memory for message frame storage, not for 471 * data I/O DMA. All message frames must be stored in the first 4G of 472 * physical memory. 473 */ 474 ddi_dma_attr_t mptsas_dma_attrs = { 475 DMA_ATTR_V0, /* attribute layout version */ 476 0x0ull, /* address low - should be 0 (longlong) */ 477 0xffffffffull, /* address high - 32-bit max range */ 478 0x00ffffffull, /* count max - max DMA object size */ 479 4, /* allocation alignment requirements */ 480 0x78, /* burstsizes - binary encoded values */ 481 1, /* minxfer - gran. of DMA engine */ 482 0x00ffffffull, /* maxxfer - gran. of DMA engine */ 483 0xffffffffull, /* max segment size (DMA boundary) */ 484 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */ 485 512, /* granularity - device transfer size */ 486 0 /* flags, set to 0 */ 487 }; 488 489 /* 490 * This is used for data I/O DMA memory allocation. (full 64-bit DMA 491 * physical addresses are supported.) 492 */ 493 ddi_dma_attr_t mptsas_dma_attrs64 = { 494 DMA_ATTR_V0, /* attribute layout version */ 495 0x0ull, /* address low - should be 0 (longlong) */ 496 0xffffffffffffffffull, /* address high - 64-bit max */ 497 0x00ffffffull, /* count max - max DMA object size */ 498 4, /* allocation alignment requirements */ 499 0x78, /* burstsizes - binary encoded values */ 500 1, /* minxfer - gran. of DMA engine */ 501 0x00ffffffull, /* maxxfer - gran. of DMA engine */ 502 0xffffffffull, /* max segment size (DMA boundary) */ 503 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */ 504 512, /* granularity - device transfer size */ 505 DDI_DMA_RELAXED_ORDERING /* flags, enable relaxed ordering */ 506 }; 507 508 ddi_device_acc_attr_t mptsas_dev_attr = { 509 DDI_DEVICE_ATTR_V1, 510 DDI_STRUCTURE_LE_ACC, 511 DDI_STRICTORDER_ACC, 512 DDI_DEFAULT_ACC 513 }; 514 515 static struct cb_ops mptsas_cb_ops = { 516 scsi_hba_open, /* open */ 517 scsi_hba_close, /* close */ 518 nodev, /* strategy */ 519 nodev, /* print */ 520 nodev, /* dump */ 521 nodev, /* read */ 522 nodev, /* write */ 523 mptsas_ioctl, /* ioctl */ 524 nodev, /* devmap */ 525 nodev, /* mmap */ 526 nodev, /* segmap */ 527 nochpoll, /* chpoll */ 528 ddi_prop_op, /* cb_prop_op */ 529 NULL, /* streamtab */ 530 D_MP, /* cb_flag */ 531 CB_REV, /* rev */ 532 nodev, /* aread */ 533 nodev /* awrite */ 534 }; 535 536 static struct dev_ops mptsas_ops = { 537 DEVO_REV, /* devo_rev, */ 538 0, /* refcnt */ 539 ddi_no_info, /* info */ 540 nulldev, /* identify */ 541 nulldev, /* probe */ 542 mptsas_attach, /* attach */ 543 mptsas_detach, /* detach */ 544 #ifdef __sparc 545 mptsas_reset, 546 #else 547 nodev, /* reset */ 548 #endif /* __sparc */ 549 &mptsas_cb_ops, /* driver operations */ 550 NULL, /* bus operations */ 551 mptsas_power, /* power management */ 552 #ifdef __sparc 553 ddi_quiesce_not_needed 554 #else 555 mptsas_quiesce /* quiesce */ 556 #endif /* __sparc */ 557 }; 558 559 560 #define MPTSAS_MOD_STRING "MPTSAS HBA Driver 00.00.00.24" 561 562 static struct modldrv modldrv = { 563 &mod_driverops, /* Type of module. This one is a driver */ 564 MPTSAS_MOD_STRING, /* Name of the module. */ 565 &mptsas_ops, /* driver ops */ 566 }; 567 568 static struct modlinkage modlinkage = { 569 MODREV_1, &modldrv, NULL 570 }; 571 #define TARGET_PROP "target" 572 #define LUN_PROP "lun" 573 #define LUN64_PROP "lun64" 574 #define SAS_PROP "sas-mpt" 575 #define MDI_GUID "wwn" 576 #define NDI_GUID "guid" 577 #define MPTSAS_DEV_GONE "mptsas_dev_gone" 578 579 /* 580 * Local static data 581 */ 582 #if defined(MPTSAS_DEBUG) 583 uint32_t mptsas_debug_flags = 0; 584 #endif /* defined(MPTSAS_DEBUG) */ 585 uint32_t mptsas_debug_resets = 0; 586 587 static kmutex_t mptsas_global_mutex; 588 static void *mptsas_state; /* soft state ptr */ 589 static krwlock_t mptsas_global_rwlock; 590 591 static kmutex_t mptsas_log_mutex; 592 static char mptsas_log_buf[256]; 593 _NOTE(MUTEX_PROTECTS_DATA(mptsas_log_mutex, mptsas_log_buf)) 594 595 static mptsas_t *mptsas_head, *mptsas_tail; 596 static clock_t mptsas_scsi_watchdog_tick; 597 static clock_t mptsas_tick; 598 static timeout_id_t mptsas_reset_watch; 599 static timeout_id_t mptsas_timeout_id; 600 static int mptsas_timeouts_enabled = 0; 601 /* 602 * warlock directives 603 */ 604 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt \ 605 mptsas_cmd NcrTableIndirect buf scsi_cdb scsi_status)) 606 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", smp_pkt)) 607 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address)) 608 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", mptsas_tgt_private)) 609 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_hba_tran::tran_tgt_private)) 610 611 /* 612 * SM - HBA statics 613 */ 614 char *mptsas_driver_rev = MPTSAS_MOD_STRING; 615 616 #ifdef MPTSAS_DEBUG 617 void debug_enter(char *); 618 #endif 619 620 /* 621 * Notes: 622 * - scsi_hba_init(9F) initializes SCSI HBA modules 623 * - must call scsi_hba_fini(9F) if modload() fails 624 */ 625 int 626 _init(void) 627 { 628 int status; 629 /* CONSTCOND */ 630 ASSERT(NO_COMPETING_THREADS); 631 632 NDBG0(("_init")); 633 634 status = ddi_soft_state_init(&mptsas_state, MPTSAS_SIZE, 635 MPTSAS_INITIAL_SOFT_SPACE); 636 if (status != 0) { 637 return (status); 638 } 639 640 if ((status = scsi_hba_init(&modlinkage)) != 0) { 641 ddi_soft_state_fini(&mptsas_state); 642 return (status); 643 } 644 645 mutex_init(&mptsas_global_mutex, NULL, MUTEX_DRIVER, NULL); 646 rw_init(&mptsas_global_rwlock, NULL, RW_DRIVER, NULL); 647 mutex_init(&mptsas_log_mutex, NULL, MUTEX_DRIVER, NULL); 648 649 if ((status = mod_install(&modlinkage)) != 0) { 650 mutex_destroy(&mptsas_log_mutex); 651 rw_destroy(&mptsas_global_rwlock); 652 mutex_destroy(&mptsas_global_mutex); 653 ddi_soft_state_fini(&mptsas_state); 654 scsi_hba_fini(&modlinkage); 655 } 656 657 return (status); 658 } 659 660 /* 661 * Notes: 662 * - scsi_hba_fini(9F) uninitializes SCSI HBA modules 663 */ 664 int 665 _fini(void) 666 { 667 int status; 668 /* CONSTCOND */ 669 ASSERT(NO_COMPETING_THREADS); 670 671 NDBG0(("_fini")); 672 673 if ((status = mod_remove(&modlinkage)) == 0) { 674 ddi_soft_state_fini(&mptsas_state); 675 scsi_hba_fini(&modlinkage); 676 mutex_destroy(&mptsas_global_mutex); 677 rw_destroy(&mptsas_global_rwlock); 678 mutex_destroy(&mptsas_log_mutex); 679 } 680 return (status); 681 } 682 683 /* 684 * The loadable-module _info(9E) entry point 685 */ 686 int 687 _info(struct modinfo *modinfop) 688 { 689 /* CONSTCOND */ 690 ASSERT(NO_COMPETING_THREADS); 691 NDBG0(("mptsas _info")); 692 693 return (mod_info(&modlinkage, modinfop)); 694 } 695 696 697 static int 698 mptsas_iport_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 699 { 700 dev_info_t *pdip; 701 mptsas_t *mpt; 702 scsi_hba_tran_t *hba_tran; 703 char *iport = NULL; 704 char phymask[MPTSAS_MAX_PHYS]; 705 mptsas_phymask_t phy_mask = 0; 706 int dynamic_port = 0; 707 uint32_t page_address; 708 char initiator_wwnstr[MPTSAS_WWN_STRLEN]; 709 int rval = DDI_FAILURE; 710 int i = 0; 711 uint8_t numphys = 0; 712 uint8_t phy_id; 713 uint8_t phy_port = 0; 714 uint16_t attached_devhdl = 0; 715 uint32_t dev_info; 716 uint64_t attached_sas_wwn; 717 uint16_t dev_hdl; 718 uint16_t pdev_hdl; 719 uint16_t bay_num, enclosure; 720 char attached_wwnstr[MPTSAS_WWN_STRLEN]; 721 722 /* CONSTCOND */ 723 ASSERT(NO_COMPETING_THREADS); 724 725 switch (cmd) { 726 case DDI_ATTACH: 727 break; 728 729 case DDI_RESUME: 730 /* 731 * If this a scsi-iport node, nothing to do here. 732 */ 733 return (DDI_SUCCESS); 734 735 default: 736 return (DDI_FAILURE); 737 } 738 739 pdip = ddi_get_parent(dip); 740 741 if ((hba_tran = ndi_flavorv_get(pdip, SCSA_FLAVOR_SCSI_DEVICE)) == 742 NULL) { 743 cmn_err(CE_WARN, "Failed attach iport because fail to " 744 "get tran vector for the HBA node"); 745 return (DDI_FAILURE); 746 } 747 748 mpt = TRAN2MPT(hba_tran); 749 ASSERT(mpt != NULL); 750 if (mpt == NULL) 751 return (DDI_FAILURE); 752 753 if ((hba_tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == 754 NULL) { 755 mptsas_log(mpt, CE_WARN, "Failed attach iport because fail to " 756 "get tran vector for the iport node"); 757 return (DDI_FAILURE); 758 } 759 760 /* 761 * Overwrite parent's tran_hba_private to iport's tran vector 762 */ 763 hba_tran->tran_hba_private = mpt; 764 765 ddi_report_dev(dip); 766 767 /* 768 * Get SAS address for initiator port according dev_handle 769 */ 770 iport = ddi_get_name_addr(dip); 771 if (iport && strncmp(iport, "v0", 2) == 0) { 772 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 773 MPTSAS_VIRTUAL_PORT, 1) != 774 DDI_PROP_SUCCESS) { 775 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, 776 MPTSAS_VIRTUAL_PORT); 777 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 778 "prop update failed"); 779 return (DDI_FAILURE); 780 } 781 return (DDI_SUCCESS); 782 } 783 784 mutex_enter(&mpt->m_mutex); 785 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 786 bzero(phymask, sizeof (phymask)); 787 (void) sprintf(phymask, 788 "%x", mpt->m_phy_info[i].phy_mask); 789 if (strcmp(phymask, iport) == 0) { 790 break; 791 } 792 } 793 794 if (i == MPTSAS_MAX_PHYS) { 795 mptsas_log(mpt, CE_WARN, "Failed attach port %s because port" 796 "seems not exist", iport); 797 mutex_exit(&mpt->m_mutex); 798 return (DDI_FAILURE); 799 } 800 801 phy_mask = mpt->m_phy_info[i].phy_mask; 802 803 if (mpt->m_phy_info[i].port_flags & AUTO_PORT_CONFIGURATION) 804 dynamic_port = 1; 805 else 806 dynamic_port = 0; 807 808 /* 809 * Update PHY info for smhba 810 */ 811 if (mptsas_smhba_phy_init(mpt)) { 812 mutex_exit(&mpt->m_mutex); 813 mptsas_log(mpt, CE_WARN, "mptsas phy update " 814 "failed"); 815 return (DDI_FAILURE); 816 } 817 818 mutex_exit(&mpt->m_mutex); 819 820 numphys = 0; 821 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 822 if ((phy_mask >> i) & 0x01) { 823 numphys++; 824 } 825 } 826 827 bzero(initiator_wwnstr, sizeof (initiator_wwnstr)); 828 (void) sprintf(initiator_wwnstr, "w%016"PRIx64, 829 mpt->un.m_base_wwid); 830 831 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, 832 SCSI_ADDR_PROP_INITIATOR_PORT, initiator_wwnstr) != 833 DDI_PROP_SUCCESS) { 834 (void) ddi_prop_remove(DDI_DEV_T_NONE, 835 dip, SCSI_ADDR_PROP_INITIATOR_PORT); 836 mptsas_log(mpt, CE_WARN, "mptsas Initiator port " 837 "prop update failed"); 838 return (DDI_FAILURE); 839 } 840 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 841 MPTSAS_NUM_PHYS, numphys) != 842 DDI_PROP_SUCCESS) { 843 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, MPTSAS_NUM_PHYS); 844 return (DDI_FAILURE); 845 } 846 847 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 848 "phymask", phy_mask) != 849 DDI_PROP_SUCCESS) { 850 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "phymask"); 851 mptsas_log(mpt, CE_WARN, "mptsas phy mask " 852 "prop update failed"); 853 return (DDI_FAILURE); 854 } 855 856 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 857 "dynamic-port", dynamic_port) != 858 DDI_PROP_SUCCESS) { 859 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "dynamic-port"); 860 mptsas_log(mpt, CE_WARN, "mptsas dynamic port " 861 "prop update failed"); 862 return (DDI_FAILURE); 863 } 864 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 865 MPTSAS_VIRTUAL_PORT, 0) != 866 DDI_PROP_SUCCESS) { 867 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, 868 MPTSAS_VIRTUAL_PORT); 869 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 870 "prop update failed"); 871 return (DDI_FAILURE); 872 } 873 mptsas_smhba_set_phy_props(mpt, 874 iport, dip, numphys, &attached_devhdl); 875 876 mutex_enter(&mpt->m_mutex); 877 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 878 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)attached_devhdl; 879 rval = mptsas_get_sas_device_page0(mpt, page_address, &dev_hdl, 880 &attached_sas_wwn, &dev_info, &phy_port, &phy_id, 881 &pdev_hdl, &bay_num, &enclosure); 882 if (rval != DDI_SUCCESS) { 883 mptsas_log(mpt, CE_WARN, 884 "Failed to get device page0 for handle:%d", 885 attached_devhdl); 886 mutex_exit(&mpt->m_mutex); 887 return (DDI_FAILURE); 888 } 889 890 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 891 bzero(phymask, sizeof (phymask)); 892 (void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask); 893 if (strcmp(phymask, iport) == 0) { 894 (void) sprintf(&mpt->m_phy_info[i].smhba_info.path[0], 895 "%x", 896 mpt->m_phy_info[i].phy_mask); 897 } 898 } 899 mutex_exit(&mpt->m_mutex); 900 901 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 902 (void) sprintf(attached_wwnstr, "w%016"PRIx64, 903 attached_sas_wwn); 904 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, 905 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 906 DDI_PROP_SUCCESS) { 907 (void) ddi_prop_remove(DDI_DEV_T_NONE, 908 dip, SCSI_ADDR_PROP_ATTACHED_PORT); 909 return (DDI_FAILURE); 910 } 911 912 /* Create kstats for each phy on this iport */ 913 914 mptsas_create_phy_stats(mpt, iport, dip); 915 916 /* 917 * register sas hba iport with mdi (MPxIO/vhci) 918 */ 919 if (mdi_phci_register(MDI_HCI_CLASS_SCSI, 920 dip, 0) == MDI_SUCCESS) { 921 mpt->m_mpxio_enable = TRUE; 922 } 923 return (DDI_SUCCESS); 924 } 925 926 /* 927 * Notes: 928 * Set up all device state and allocate data structures, 929 * mutexes, condition variables, etc. for device operation. 930 * Add interrupts needed. 931 * Return DDI_SUCCESS if device is ready, else return DDI_FAILURE. 932 */ 933 static int 934 mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 935 { 936 mptsas_t *mpt = NULL; 937 int instance, i, j; 938 int doneq_thread_num; 939 char intr_added = 0; 940 char map_setup = 0; 941 char config_setup = 0; 942 char hba_attach_setup = 0; 943 char smp_attach_setup = 0; 944 char mutex_init_done = 0; 945 char event_taskq_create = 0; 946 char dr_taskq_create = 0; 947 char doneq_thread_create = 0; 948 scsi_hba_tran_t *hba_tran; 949 uint_t mem_bar = MEM_SPACE; 950 int rval = DDI_FAILURE; 951 952 /* CONSTCOND */ 953 ASSERT(NO_COMPETING_THREADS); 954 955 if (scsi_hba_iport_unit_address(dip)) { 956 return (mptsas_iport_attach(dip, cmd)); 957 } 958 959 switch (cmd) { 960 case DDI_ATTACH: 961 break; 962 963 case DDI_RESUME: 964 if ((hba_tran = ddi_get_driver_private(dip)) == NULL) 965 return (DDI_FAILURE); 966 967 mpt = TRAN2MPT(hba_tran); 968 969 if (!mpt) { 970 return (DDI_FAILURE); 971 } 972 973 /* 974 * Reset hardware and softc to "no outstanding commands" 975 * Note that a check condition can result on first command 976 * to a target. 977 */ 978 mutex_enter(&mpt->m_mutex); 979 980 /* 981 * raise power. 982 */ 983 if (mpt->m_options & MPTSAS_OPT_PM) { 984 mutex_exit(&mpt->m_mutex); 985 (void) pm_busy_component(dip, 0); 986 rval = pm_power_has_changed(dip, 0, PM_LEVEL_D0); 987 if (rval == DDI_SUCCESS) { 988 mutex_enter(&mpt->m_mutex); 989 } else { 990 /* 991 * The pm_raise_power() call above failed, 992 * and that can only occur if we were unable 993 * to reset the hardware. This is probably 994 * due to unhealty hardware, and because 995 * important filesystems(such as the root 996 * filesystem) could be on the attached disks, 997 * it would not be a good idea to continue, 998 * as we won't be entirely certain we are 999 * writing correct data. So we panic() here 1000 * to not only prevent possible data corruption, 1001 * but to give developers or end users a hope 1002 * of identifying and correcting any problems. 1003 */ 1004 fm_panic("mptsas could not reset hardware " 1005 "during resume"); 1006 } 1007 } 1008 1009 mpt->m_suspended = 0; 1010 1011 /* 1012 * Reinitialize ioc 1013 */ 1014 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1015 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) { 1016 mutex_exit(&mpt->m_mutex); 1017 if (mpt->m_options & MPTSAS_OPT_PM) { 1018 (void) pm_idle_component(dip, 0); 1019 } 1020 fm_panic("mptsas init chip fail during resume"); 1021 } 1022 /* 1023 * mptsas_update_driver_data needs interrupts so enable them 1024 * first. 1025 */ 1026 MPTSAS_ENABLE_INTR(mpt); 1027 mptsas_update_driver_data(mpt); 1028 1029 /* start requests, if possible */ 1030 mptsas_restart_hba(mpt); 1031 1032 mutex_exit(&mpt->m_mutex); 1033 1034 /* 1035 * Restart watch thread 1036 */ 1037 mutex_enter(&mptsas_global_mutex); 1038 if (mptsas_timeout_id == 0) { 1039 mptsas_timeout_id = timeout(mptsas_watch, NULL, 1040 mptsas_tick); 1041 mptsas_timeouts_enabled = 1; 1042 } 1043 mutex_exit(&mptsas_global_mutex); 1044 1045 /* report idle status to pm framework */ 1046 if (mpt->m_options & MPTSAS_OPT_PM) { 1047 (void) pm_idle_component(dip, 0); 1048 } 1049 1050 return (DDI_SUCCESS); 1051 1052 default: 1053 return (DDI_FAILURE); 1054 1055 } 1056 1057 instance = ddi_get_instance(dip); 1058 1059 /* 1060 * Allocate softc information. 1061 */ 1062 if (ddi_soft_state_zalloc(mptsas_state, instance) != DDI_SUCCESS) { 1063 mptsas_log(NULL, CE_WARN, 1064 "mptsas%d: cannot allocate soft state", instance); 1065 goto fail; 1066 } 1067 1068 mpt = ddi_get_soft_state(mptsas_state, instance); 1069 1070 if (mpt == NULL) { 1071 mptsas_log(NULL, CE_WARN, 1072 "mptsas%d: cannot get soft state", instance); 1073 goto fail; 1074 } 1075 1076 /* Indicate that we are 'sizeof (scsi_*(9S))' clean. */ 1077 scsi_size_clean(dip); 1078 1079 mpt->m_dip = dip; 1080 mpt->m_instance = instance; 1081 1082 /* Make a per-instance copy of the structures */ 1083 mpt->m_io_dma_attr = mptsas_dma_attrs64; 1084 mpt->m_msg_dma_attr = mptsas_dma_attrs; 1085 mpt->m_reg_acc_attr = mptsas_dev_attr; 1086 mpt->m_dev_acc_attr = mptsas_dev_attr; 1087 1088 /* 1089 * Initialize FMA 1090 */ 1091 mpt->m_fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, mpt->m_dip, 1092 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable", 1093 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE | 1094 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE); 1095 1096 mptsas_fm_init(mpt); 1097 1098 if (mptsas_alloc_handshake_msg(mpt, 1099 sizeof (Mpi2SCSITaskManagementRequest_t)) == DDI_FAILURE) { 1100 mptsas_log(mpt, CE_WARN, "cannot initialize handshake msg."); 1101 goto fail; 1102 } 1103 1104 /* 1105 * Setup configuration space 1106 */ 1107 if (mptsas_config_space_init(mpt) == FALSE) { 1108 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init failed"); 1109 goto fail; 1110 } 1111 config_setup++; 1112 1113 if (ddi_regs_map_setup(dip, mem_bar, (caddr_t *)&mpt->m_reg, 1114 0, 0, &mpt->m_reg_acc_attr, &mpt->m_datap) != DDI_SUCCESS) { 1115 mptsas_log(mpt, CE_WARN, "map setup failed"); 1116 goto fail; 1117 } 1118 map_setup++; 1119 1120 /* 1121 * A taskq is created for dealing with the event handler 1122 */ 1123 if ((mpt->m_event_taskq = ddi_taskq_create(dip, "mptsas_event_taskq", 1124 1, TASKQ_DEFAULTPRI, 0)) == NULL) { 1125 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create failed"); 1126 goto fail; 1127 } 1128 event_taskq_create++; 1129 1130 /* 1131 * A taskq is created for dealing with dr events 1132 */ 1133 if ((mpt->m_dr_taskq = ddi_taskq_create(dip, 1134 "mptsas_dr_taskq", 1135 1, TASKQ_DEFAULTPRI, 0)) == NULL) { 1136 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create for discovery " 1137 "failed"); 1138 goto fail; 1139 } 1140 dr_taskq_create++; 1141 1142 mpt->m_doneq_thread_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1143 0, "mptsas_doneq_thread_threshold_prop", 10); 1144 mpt->m_doneq_length_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1145 0, "mptsas_doneq_length_threshold_prop", 8); 1146 mpt->m_doneq_thread_n = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1147 0, "mptsas_doneq_thread_n_prop", 8); 1148 1149 if (mpt->m_doneq_thread_n) { 1150 cv_init(&mpt->m_doneq_thread_cv, NULL, CV_DRIVER, NULL); 1151 mutex_init(&mpt->m_doneq_mutex, NULL, MUTEX_DRIVER, NULL); 1152 1153 mutex_enter(&mpt->m_doneq_mutex); 1154 mpt->m_doneq_thread_id = 1155 kmem_zalloc(sizeof (mptsas_doneq_thread_list_t) 1156 * mpt->m_doneq_thread_n, KM_SLEEP); 1157 1158 for (j = 0; j < mpt->m_doneq_thread_n; j++) { 1159 cv_init(&mpt->m_doneq_thread_id[j].cv, NULL, 1160 CV_DRIVER, NULL); 1161 mutex_init(&mpt->m_doneq_thread_id[j].mutex, NULL, 1162 MUTEX_DRIVER, NULL); 1163 mutex_enter(&mpt->m_doneq_thread_id[j].mutex); 1164 mpt->m_doneq_thread_id[j].flag |= 1165 MPTSAS_DONEQ_THREAD_ACTIVE; 1166 mpt->m_doneq_thread_id[j].arg.mpt = mpt; 1167 mpt->m_doneq_thread_id[j].arg.t = j; 1168 mpt->m_doneq_thread_id[j].threadp = 1169 thread_create(NULL, 0, mptsas_doneq_thread, 1170 &mpt->m_doneq_thread_id[j].arg, 1171 0, &p0, TS_RUN, minclsyspri); 1172 mpt->m_doneq_thread_id[j].donetail = 1173 &mpt->m_doneq_thread_id[j].doneq; 1174 mutex_exit(&mpt->m_doneq_thread_id[j].mutex); 1175 } 1176 mutex_exit(&mpt->m_doneq_mutex); 1177 doneq_thread_create++; 1178 } 1179 1180 /* Initialize mutex used in interrupt handler */ 1181 mutex_init(&mpt->m_mutex, NULL, MUTEX_DRIVER, 1182 DDI_INTR_PRI(mpt->m_intr_pri)); 1183 mutex_init(&mpt->m_passthru_mutex, NULL, MUTEX_DRIVER, NULL); 1184 mutex_init(&mpt->m_tx_waitq_mutex, NULL, MUTEX_DRIVER, 1185 DDI_INTR_PRI(mpt->m_intr_pri)); 1186 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1187 mutex_init(&mpt->m_phy_info[i].smhba_info.phy_mutex, 1188 NULL, MUTEX_DRIVER, 1189 DDI_INTR_PRI(mpt->m_intr_pri)); 1190 } 1191 1192 cv_init(&mpt->m_cv, NULL, CV_DRIVER, NULL); 1193 cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL); 1194 cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL); 1195 cv_init(&mpt->m_config_cv, NULL, CV_DRIVER, NULL); 1196 cv_init(&mpt->m_fw_diag_cv, NULL, CV_DRIVER, NULL); 1197 mutex_init_done++; 1198 1199 /* 1200 * Disable hardware interrupt since we're not ready to 1201 * handle it yet. 1202 */ 1203 MPTSAS_DISABLE_INTR(mpt); 1204 if (mptsas_register_intrs(mpt) == FALSE) 1205 goto fail; 1206 intr_added++; 1207 1208 mutex_enter(&mpt->m_mutex); 1209 /* 1210 * Initialize power management component 1211 */ 1212 if (mpt->m_options & MPTSAS_OPT_PM) { 1213 if (mptsas_init_pm(mpt)) { 1214 mutex_exit(&mpt->m_mutex); 1215 mptsas_log(mpt, CE_WARN, "mptsas pm initialization " 1216 "failed"); 1217 goto fail; 1218 } 1219 } 1220 1221 /* 1222 * Initialize chip using Message Unit Reset, if allowed 1223 */ 1224 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1225 if (mptsas_init_chip(mpt, TRUE) == DDI_FAILURE) { 1226 mutex_exit(&mpt->m_mutex); 1227 mptsas_log(mpt, CE_WARN, "mptsas chip initialization failed"); 1228 goto fail; 1229 } 1230 1231 /* 1232 * Fill in the phy_info structure and get the base WWID 1233 */ 1234 if (mptsas_get_manufacture_page5(mpt) == DDI_FAILURE) { 1235 mptsas_log(mpt, CE_WARN, 1236 "mptsas_get_manufacture_page5 failed!"); 1237 goto fail; 1238 } 1239 1240 if (mptsas_get_sas_io_unit_page_hndshk(mpt)) { 1241 mptsas_log(mpt, CE_WARN, 1242 "mptsas_get_sas_io_unit_page_hndshk failed!"); 1243 goto fail; 1244 } 1245 1246 if (mptsas_get_manufacture_page0(mpt) == DDI_FAILURE) { 1247 mptsas_log(mpt, CE_WARN, 1248 "mptsas_get_manufacture_page0 failed!"); 1249 goto fail; 1250 } 1251 1252 mutex_exit(&mpt->m_mutex); 1253 1254 /* 1255 * Register the iport for multiple port HBA 1256 */ 1257 mptsas_iport_register(mpt); 1258 1259 /* 1260 * initialize SCSI HBA transport structure 1261 */ 1262 if (mptsas_hba_setup(mpt) == FALSE) 1263 goto fail; 1264 hba_attach_setup++; 1265 1266 if (mptsas_smp_setup(mpt) == FALSE) 1267 goto fail; 1268 smp_attach_setup++; 1269 1270 if (mptsas_cache_create(mpt) == FALSE) 1271 goto fail; 1272 1273 mpt->m_scsi_reset_delay = ddi_prop_get_int(DDI_DEV_T_ANY, 1274 dip, 0, "scsi-reset-delay", SCSI_DEFAULT_RESET_DELAY); 1275 if (mpt->m_scsi_reset_delay == 0) { 1276 mptsas_log(mpt, CE_NOTE, 1277 "scsi_reset_delay of 0 is not recommended," 1278 " resetting to SCSI_DEFAULT_RESET_DELAY\n"); 1279 mpt->m_scsi_reset_delay = SCSI_DEFAULT_RESET_DELAY; 1280 } 1281 1282 /* 1283 * Initialize the wait and done FIFO queue 1284 */ 1285 mpt->m_donetail = &mpt->m_doneq; 1286 mpt->m_waitqtail = &mpt->m_waitq; 1287 mpt->m_tx_waitqtail = &mpt->m_tx_waitq; 1288 mpt->m_tx_draining = 0; 1289 1290 /* 1291 * ioc cmd queue initialize 1292 */ 1293 mpt->m_ioc_event_cmdtail = &mpt->m_ioc_event_cmdq; 1294 mpt->m_dev_handle = 0xFFFF; 1295 1296 MPTSAS_ENABLE_INTR(mpt); 1297 1298 /* 1299 * enable event notification 1300 */ 1301 mutex_enter(&mpt->m_mutex); 1302 if (mptsas_ioc_enable_event_notification(mpt)) { 1303 mutex_exit(&mpt->m_mutex); 1304 goto fail; 1305 } 1306 mutex_exit(&mpt->m_mutex); 1307 1308 /* 1309 * Initialize PHY info for smhba 1310 */ 1311 if (mptsas_smhba_setup(mpt)) { 1312 mptsas_log(mpt, CE_WARN, "mptsas phy initialization " 1313 "failed"); 1314 goto fail; 1315 } 1316 1317 /* Check all dma handles allocated in attach */ 1318 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) 1319 != DDI_SUCCESS) || 1320 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) 1321 != DDI_SUCCESS) || 1322 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) 1323 != DDI_SUCCESS) || 1324 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) 1325 != DDI_SUCCESS) || 1326 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) 1327 != DDI_SUCCESS)) { 1328 goto fail; 1329 } 1330 1331 /* Check all acc handles allocated in attach */ 1332 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) || 1333 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) 1334 != DDI_SUCCESS) || 1335 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) 1336 != DDI_SUCCESS) || 1337 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) 1338 != DDI_SUCCESS) || 1339 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) 1340 != DDI_SUCCESS) || 1341 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) 1342 != DDI_SUCCESS) || 1343 (mptsas_check_acc_handle(mpt->m_config_handle) 1344 != DDI_SUCCESS)) { 1345 goto fail; 1346 } 1347 1348 /* 1349 * After this point, we are not going to fail the attach. 1350 */ 1351 /* 1352 * used for mptsas_watch 1353 */ 1354 mptsas_list_add(mpt); 1355 1356 mutex_enter(&mptsas_global_mutex); 1357 if (mptsas_timeouts_enabled == 0) { 1358 mptsas_scsi_watchdog_tick = ddi_prop_get_int(DDI_DEV_T_ANY, 1359 dip, 0, "scsi-watchdog-tick", DEFAULT_WD_TICK); 1360 1361 mptsas_tick = mptsas_scsi_watchdog_tick * 1362 drv_usectohz((clock_t)1000000); 1363 1364 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick); 1365 mptsas_timeouts_enabled = 1; 1366 } 1367 mutex_exit(&mptsas_global_mutex); 1368 1369 /* Print message of HBA present */ 1370 ddi_report_dev(dip); 1371 1372 /* report idle status to pm framework */ 1373 if (mpt->m_options & MPTSAS_OPT_PM) { 1374 (void) pm_idle_component(dip, 0); 1375 } 1376 1377 return (DDI_SUCCESS); 1378 1379 fail: 1380 mptsas_log(mpt, CE_WARN, "attach failed"); 1381 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 1382 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 1383 if (mpt) { 1384 mutex_enter(&mptsas_global_mutex); 1385 1386 if (mptsas_timeout_id && (mptsas_head == NULL)) { 1387 timeout_id_t tid = mptsas_timeout_id; 1388 mptsas_timeouts_enabled = 0; 1389 mptsas_timeout_id = 0; 1390 mutex_exit(&mptsas_global_mutex); 1391 (void) untimeout(tid); 1392 mutex_enter(&mptsas_global_mutex); 1393 } 1394 mutex_exit(&mptsas_global_mutex); 1395 /* deallocate in reverse order */ 1396 mptsas_cache_destroy(mpt); 1397 1398 if (smp_attach_setup) { 1399 mptsas_smp_teardown(mpt); 1400 } 1401 if (hba_attach_setup) { 1402 mptsas_hba_teardown(mpt); 1403 } 1404 1405 if (mpt->m_active) { 1406 mptsas_hash_uninit(&mpt->m_active->m_smptbl, 1407 sizeof (mptsas_smp_t)); 1408 mptsas_hash_uninit(&mpt->m_active->m_tgttbl, 1409 sizeof (mptsas_target_t)); 1410 mptsas_free_active_slots(mpt); 1411 } 1412 if (intr_added) { 1413 mptsas_unregister_intrs(mpt); 1414 } 1415 1416 if (doneq_thread_create) { 1417 mutex_enter(&mpt->m_doneq_mutex); 1418 doneq_thread_num = mpt->m_doneq_thread_n; 1419 for (j = 0; j < mpt->m_doneq_thread_n; j++) { 1420 mutex_enter(&mpt->m_doneq_thread_id[j].mutex); 1421 mpt->m_doneq_thread_id[j].flag &= 1422 (~MPTSAS_DONEQ_THREAD_ACTIVE); 1423 cv_signal(&mpt->m_doneq_thread_id[j].cv); 1424 mutex_exit(&mpt->m_doneq_thread_id[j].mutex); 1425 } 1426 while (mpt->m_doneq_thread_n) { 1427 cv_wait(&mpt->m_doneq_thread_cv, 1428 &mpt->m_doneq_mutex); 1429 } 1430 for (j = 0; j < doneq_thread_num; j++) { 1431 cv_destroy(&mpt->m_doneq_thread_id[j].cv); 1432 mutex_destroy(&mpt->m_doneq_thread_id[j].mutex); 1433 } 1434 kmem_free(mpt->m_doneq_thread_id, 1435 sizeof (mptsas_doneq_thread_list_t) 1436 * doneq_thread_num); 1437 mutex_exit(&mpt->m_doneq_mutex); 1438 cv_destroy(&mpt->m_doneq_thread_cv); 1439 mutex_destroy(&mpt->m_doneq_mutex); 1440 } 1441 if (event_taskq_create) { 1442 ddi_taskq_destroy(mpt->m_event_taskq); 1443 } 1444 if (dr_taskq_create) { 1445 ddi_taskq_destroy(mpt->m_dr_taskq); 1446 } 1447 if (mutex_init_done) { 1448 mutex_destroy(&mpt->m_tx_waitq_mutex); 1449 mutex_destroy(&mpt->m_passthru_mutex); 1450 mutex_destroy(&mpt->m_mutex); 1451 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1452 mutex_destroy( 1453 &mpt->m_phy_info[i].smhba_info.phy_mutex); 1454 } 1455 cv_destroy(&mpt->m_cv); 1456 cv_destroy(&mpt->m_passthru_cv); 1457 cv_destroy(&mpt->m_fw_cv); 1458 cv_destroy(&mpt->m_config_cv); 1459 cv_destroy(&mpt->m_fw_diag_cv); 1460 } 1461 1462 if (map_setup) { 1463 mptsas_cfg_fini(mpt); 1464 } 1465 if (config_setup) { 1466 mptsas_config_space_fini(mpt); 1467 } 1468 mptsas_free_handshake_msg(mpt); 1469 mptsas_hba_fini(mpt); 1470 1471 mptsas_fm_fini(mpt); 1472 ddi_soft_state_free(mptsas_state, instance); 1473 ddi_prop_remove_all(dip); 1474 } 1475 return (DDI_FAILURE); 1476 } 1477 1478 static int 1479 mptsas_suspend(dev_info_t *devi) 1480 { 1481 mptsas_t *mpt, *g; 1482 scsi_hba_tran_t *tran; 1483 1484 if (scsi_hba_iport_unit_address(devi)) { 1485 return (DDI_SUCCESS); 1486 } 1487 1488 if ((tran = ddi_get_driver_private(devi)) == NULL) 1489 return (DDI_SUCCESS); 1490 1491 mpt = TRAN2MPT(tran); 1492 if (!mpt) { 1493 return (DDI_SUCCESS); 1494 } 1495 1496 mutex_enter(&mpt->m_mutex); 1497 1498 if (mpt->m_suspended++) { 1499 mutex_exit(&mpt->m_mutex); 1500 return (DDI_SUCCESS); 1501 } 1502 1503 /* 1504 * Cancel timeout threads for this mpt 1505 */ 1506 if (mpt->m_quiesce_timeid) { 1507 timeout_id_t tid = mpt->m_quiesce_timeid; 1508 mpt->m_quiesce_timeid = 0; 1509 mutex_exit(&mpt->m_mutex); 1510 (void) untimeout(tid); 1511 mutex_enter(&mpt->m_mutex); 1512 } 1513 1514 if (mpt->m_restart_cmd_timeid) { 1515 timeout_id_t tid = mpt->m_restart_cmd_timeid; 1516 mpt->m_restart_cmd_timeid = 0; 1517 mutex_exit(&mpt->m_mutex); 1518 (void) untimeout(tid); 1519 mutex_enter(&mpt->m_mutex); 1520 } 1521 1522 mutex_exit(&mpt->m_mutex); 1523 1524 (void) pm_idle_component(mpt->m_dip, 0); 1525 1526 /* 1527 * Cancel watch threads if all mpts suspended 1528 */ 1529 rw_enter(&mptsas_global_rwlock, RW_WRITER); 1530 for (g = mptsas_head; g != NULL; g = g->m_next) { 1531 if (!g->m_suspended) 1532 break; 1533 } 1534 rw_exit(&mptsas_global_rwlock); 1535 1536 mutex_enter(&mptsas_global_mutex); 1537 if (g == NULL) { 1538 timeout_id_t tid; 1539 1540 mptsas_timeouts_enabled = 0; 1541 if (mptsas_timeout_id) { 1542 tid = mptsas_timeout_id; 1543 mptsas_timeout_id = 0; 1544 mutex_exit(&mptsas_global_mutex); 1545 (void) untimeout(tid); 1546 mutex_enter(&mptsas_global_mutex); 1547 } 1548 if (mptsas_reset_watch) { 1549 tid = mptsas_reset_watch; 1550 mptsas_reset_watch = 0; 1551 mutex_exit(&mptsas_global_mutex); 1552 (void) untimeout(tid); 1553 mutex_enter(&mptsas_global_mutex); 1554 } 1555 } 1556 mutex_exit(&mptsas_global_mutex); 1557 1558 mutex_enter(&mpt->m_mutex); 1559 1560 /* 1561 * If this mpt is not in full power(PM_LEVEL_D0), just return. 1562 */ 1563 if ((mpt->m_options & MPTSAS_OPT_PM) && 1564 (mpt->m_power_level != PM_LEVEL_D0)) { 1565 mutex_exit(&mpt->m_mutex); 1566 return (DDI_SUCCESS); 1567 } 1568 1569 /* Disable HBA interrupts in hardware */ 1570 MPTSAS_DISABLE_INTR(mpt); 1571 /* 1572 * Send RAID action system shutdown to sync IR 1573 */ 1574 mptsas_raid_action_system_shutdown(mpt); 1575 1576 mutex_exit(&mpt->m_mutex); 1577 1578 /* drain the taskq */ 1579 ddi_taskq_wait(mpt->m_event_taskq); 1580 ddi_taskq_wait(mpt->m_dr_taskq); 1581 1582 return (DDI_SUCCESS); 1583 } 1584 1585 #ifdef __sparc 1586 /*ARGSUSED*/ 1587 static int 1588 mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd) 1589 { 1590 mptsas_t *mpt; 1591 scsi_hba_tran_t *tran; 1592 1593 /* 1594 * If this call is for iport, just return. 1595 */ 1596 if (scsi_hba_iport_unit_address(devi)) 1597 return (DDI_SUCCESS); 1598 1599 if ((tran = ddi_get_driver_private(devi)) == NULL) 1600 return (DDI_SUCCESS); 1601 1602 if ((mpt = TRAN2MPT(tran)) == NULL) 1603 return (DDI_SUCCESS); 1604 1605 /* 1606 * Send RAID action system shutdown to sync IR. Disable HBA 1607 * interrupts in hardware first. 1608 */ 1609 MPTSAS_DISABLE_INTR(mpt); 1610 mptsas_raid_action_system_shutdown(mpt); 1611 1612 return (DDI_SUCCESS); 1613 } 1614 #else /* __sparc */ 1615 /* 1616 * quiesce(9E) entry point. 1617 * 1618 * This function is called when the system is single-threaded at high 1619 * PIL with preemption disabled. Therefore, this function must not be 1620 * blocked. 1621 * 1622 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 1623 * DDI_FAILURE indicates an error condition and should almost never happen. 1624 */ 1625 static int 1626 mptsas_quiesce(dev_info_t *devi) 1627 { 1628 mptsas_t *mpt; 1629 scsi_hba_tran_t *tran; 1630 1631 /* 1632 * If this call is for iport, just return. 1633 */ 1634 if (scsi_hba_iport_unit_address(devi)) 1635 return (DDI_SUCCESS); 1636 1637 if ((tran = ddi_get_driver_private(devi)) == NULL) 1638 return (DDI_SUCCESS); 1639 1640 if ((mpt = TRAN2MPT(tran)) == NULL) 1641 return (DDI_SUCCESS); 1642 1643 /* Disable HBA interrupts in hardware */ 1644 MPTSAS_DISABLE_INTR(mpt); 1645 /* Send RAID action system shutdonw to sync IR */ 1646 mptsas_raid_action_system_shutdown(mpt); 1647 1648 return (DDI_SUCCESS); 1649 } 1650 #endif /* __sparc */ 1651 1652 /* 1653 * detach(9E). Remove all device allocations and system resources; 1654 * disable device interrupts. 1655 * Return DDI_SUCCESS if done; DDI_FAILURE if there's a problem. 1656 */ 1657 static int 1658 mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 1659 { 1660 /* CONSTCOND */ 1661 ASSERT(NO_COMPETING_THREADS); 1662 NDBG0(("mptsas_detach: dip=0x%p cmd=0x%p", (void *)devi, (void *)cmd)); 1663 1664 switch (cmd) { 1665 case DDI_DETACH: 1666 return (mptsas_do_detach(devi)); 1667 1668 case DDI_SUSPEND: 1669 return (mptsas_suspend(devi)); 1670 1671 default: 1672 return (DDI_FAILURE); 1673 } 1674 /* NOTREACHED */ 1675 } 1676 1677 static int 1678 mptsas_do_detach(dev_info_t *dip) 1679 { 1680 mptsas_t *mpt; 1681 scsi_hba_tran_t *tran; 1682 int circ = 0; 1683 int circ1 = 0; 1684 mdi_pathinfo_t *pip = NULL; 1685 int i; 1686 int doneq_thread_num = 0; 1687 1688 NDBG0(("mptsas_do_detach: dip=0x%p", (void *)dip)); 1689 1690 if ((tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == NULL) 1691 return (DDI_FAILURE); 1692 1693 mpt = TRAN2MPT(tran); 1694 if (!mpt) { 1695 return (DDI_FAILURE); 1696 } 1697 /* 1698 * Still have pathinfo child, should not detach mpt driver 1699 */ 1700 if (scsi_hba_iport_unit_address(dip)) { 1701 if (mpt->m_mpxio_enable) { 1702 /* 1703 * MPxIO enabled for the iport 1704 */ 1705 ndi_devi_enter(scsi_vhci_dip, &circ1); 1706 ndi_devi_enter(dip, &circ); 1707 while (pip = mdi_get_next_client_path(dip, NULL)) { 1708 if (mdi_pi_free(pip, 0) == MDI_SUCCESS) { 1709 continue; 1710 } 1711 ndi_devi_exit(dip, circ); 1712 ndi_devi_exit(scsi_vhci_dip, circ1); 1713 NDBG12(("detach failed because of " 1714 "outstanding path info")); 1715 return (DDI_FAILURE); 1716 } 1717 ndi_devi_exit(dip, circ); 1718 ndi_devi_exit(scsi_vhci_dip, circ1); 1719 (void) mdi_phci_unregister(dip, 0); 1720 } 1721 1722 ddi_prop_remove_all(dip); 1723 1724 return (DDI_SUCCESS); 1725 } 1726 1727 /* Make sure power level is D0 before accessing registers */ 1728 if (mpt->m_options & MPTSAS_OPT_PM) { 1729 (void) pm_busy_component(dip, 0); 1730 if (mpt->m_power_level != PM_LEVEL_D0) { 1731 if (pm_raise_power(dip, 0, PM_LEVEL_D0) != 1732 DDI_SUCCESS) { 1733 mptsas_log(mpt, CE_WARN, 1734 "mptsas%d: Raise power request failed.", 1735 mpt->m_instance); 1736 (void) pm_idle_component(dip, 0); 1737 return (DDI_FAILURE); 1738 } 1739 } 1740 } 1741 1742 /* 1743 * Send RAID action system shutdown to sync IR. After action, send a 1744 * Message Unit Reset. Since after that DMA resource will be freed, 1745 * set ioc to READY state will avoid HBA initiated DMA operation. 1746 */ 1747 mutex_enter(&mpt->m_mutex); 1748 MPTSAS_DISABLE_INTR(mpt); 1749 mptsas_raid_action_system_shutdown(mpt); 1750 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1751 (void) mptsas_ioc_reset(mpt, FALSE); 1752 mutex_exit(&mpt->m_mutex); 1753 mptsas_rem_intrs(mpt); 1754 ddi_taskq_destroy(mpt->m_event_taskq); 1755 ddi_taskq_destroy(mpt->m_dr_taskq); 1756 1757 if (mpt->m_doneq_thread_n) { 1758 mutex_enter(&mpt->m_doneq_mutex); 1759 doneq_thread_num = mpt->m_doneq_thread_n; 1760 for (i = 0; i < mpt->m_doneq_thread_n; i++) { 1761 mutex_enter(&mpt->m_doneq_thread_id[i].mutex); 1762 mpt->m_doneq_thread_id[i].flag &= 1763 (~MPTSAS_DONEQ_THREAD_ACTIVE); 1764 cv_signal(&mpt->m_doneq_thread_id[i].cv); 1765 mutex_exit(&mpt->m_doneq_thread_id[i].mutex); 1766 } 1767 while (mpt->m_doneq_thread_n) { 1768 cv_wait(&mpt->m_doneq_thread_cv, 1769 &mpt->m_doneq_mutex); 1770 } 1771 for (i = 0; i < doneq_thread_num; i++) { 1772 cv_destroy(&mpt->m_doneq_thread_id[i].cv); 1773 mutex_destroy(&mpt->m_doneq_thread_id[i].mutex); 1774 } 1775 kmem_free(mpt->m_doneq_thread_id, 1776 sizeof (mptsas_doneq_thread_list_t) 1777 * doneq_thread_num); 1778 mutex_exit(&mpt->m_doneq_mutex); 1779 cv_destroy(&mpt->m_doneq_thread_cv); 1780 mutex_destroy(&mpt->m_doneq_mutex); 1781 } 1782 1783 scsi_hba_reset_notify_tear_down(mpt->m_reset_notify_listf); 1784 1785 mptsas_list_del(mpt); 1786 1787 /* 1788 * Cancel timeout threads for this mpt 1789 */ 1790 mutex_enter(&mpt->m_mutex); 1791 if (mpt->m_quiesce_timeid) { 1792 timeout_id_t tid = mpt->m_quiesce_timeid; 1793 mpt->m_quiesce_timeid = 0; 1794 mutex_exit(&mpt->m_mutex); 1795 (void) untimeout(tid); 1796 mutex_enter(&mpt->m_mutex); 1797 } 1798 1799 if (mpt->m_restart_cmd_timeid) { 1800 timeout_id_t tid = mpt->m_restart_cmd_timeid; 1801 mpt->m_restart_cmd_timeid = 0; 1802 mutex_exit(&mpt->m_mutex); 1803 (void) untimeout(tid); 1804 mutex_enter(&mpt->m_mutex); 1805 } 1806 1807 mutex_exit(&mpt->m_mutex); 1808 1809 /* 1810 * last mpt? ... if active, CANCEL watch threads. 1811 */ 1812 mutex_enter(&mptsas_global_mutex); 1813 if (mptsas_head == NULL) { 1814 timeout_id_t tid; 1815 /* 1816 * Clear mptsas_timeouts_enable so that the watch thread 1817 * gets restarted on DDI_ATTACH 1818 */ 1819 mptsas_timeouts_enabled = 0; 1820 if (mptsas_timeout_id) { 1821 tid = mptsas_timeout_id; 1822 mptsas_timeout_id = 0; 1823 mutex_exit(&mptsas_global_mutex); 1824 (void) untimeout(tid); 1825 mutex_enter(&mptsas_global_mutex); 1826 } 1827 if (mptsas_reset_watch) { 1828 tid = mptsas_reset_watch; 1829 mptsas_reset_watch = 0; 1830 mutex_exit(&mptsas_global_mutex); 1831 (void) untimeout(tid); 1832 mutex_enter(&mptsas_global_mutex); 1833 } 1834 } 1835 mutex_exit(&mptsas_global_mutex); 1836 1837 /* 1838 * Delete Phy stats 1839 */ 1840 mptsas_destroy_phy_stats(mpt); 1841 1842 /* 1843 * Delete nt_active. 1844 */ 1845 mutex_enter(&mpt->m_mutex); 1846 mptsas_hash_uninit(&mpt->m_active->m_tgttbl, sizeof (mptsas_target_t)); 1847 mptsas_hash_uninit(&mpt->m_active->m_smptbl, sizeof (mptsas_smp_t)); 1848 mptsas_free_active_slots(mpt); 1849 mutex_exit(&mpt->m_mutex); 1850 1851 /* deallocate everything that was allocated in mptsas_attach */ 1852 mptsas_cache_destroy(mpt); 1853 1854 mptsas_hba_fini(mpt); 1855 mptsas_cfg_fini(mpt); 1856 1857 /* Lower the power informing PM Framework */ 1858 if (mpt->m_options & MPTSAS_OPT_PM) { 1859 if (pm_lower_power(dip, 0, PM_LEVEL_D3) != DDI_SUCCESS) 1860 mptsas_log(mpt, CE_WARN, 1861 "!mptsas%d: Lower power request failed " 1862 "during detach, ignoring.", 1863 mpt->m_instance); 1864 } 1865 1866 mutex_destroy(&mpt->m_tx_waitq_mutex); 1867 mutex_destroy(&mpt->m_passthru_mutex); 1868 mutex_destroy(&mpt->m_mutex); 1869 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1870 mutex_destroy(&mpt->m_phy_info[i].smhba_info.phy_mutex); 1871 } 1872 cv_destroy(&mpt->m_cv); 1873 cv_destroy(&mpt->m_passthru_cv); 1874 cv_destroy(&mpt->m_fw_cv); 1875 cv_destroy(&mpt->m_config_cv); 1876 cv_destroy(&mpt->m_fw_diag_cv); 1877 1878 1879 mptsas_smp_teardown(mpt); 1880 mptsas_hba_teardown(mpt); 1881 1882 mptsas_config_space_fini(mpt); 1883 1884 mptsas_free_handshake_msg(mpt); 1885 1886 mptsas_fm_fini(mpt); 1887 ddi_soft_state_free(mptsas_state, ddi_get_instance(dip)); 1888 ddi_prop_remove_all(dip); 1889 1890 return (DDI_SUCCESS); 1891 } 1892 1893 static void 1894 mptsas_list_add(mptsas_t *mpt) 1895 { 1896 rw_enter(&mptsas_global_rwlock, RW_WRITER); 1897 1898 if (mptsas_head == NULL) { 1899 mptsas_head = mpt; 1900 } else { 1901 mptsas_tail->m_next = mpt; 1902 } 1903 mptsas_tail = mpt; 1904 rw_exit(&mptsas_global_rwlock); 1905 } 1906 1907 static void 1908 mptsas_list_del(mptsas_t *mpt) 1909 { 1910 mptsas_t *m; 1911 /* 1912 * Remove device instance from the global linked list 1913 */ 1914 rw_enter(&mptsas_global_rwlock, RW_WRITER); 1915 if (mptsas_head == mpt) { 1916 m = mptsas_head = mpt->m_next; 1917 } else { 1918 for (m = mptsas_head; m != NULL; m = m->m_next) { 1919 if (m->m_next == mpt) { 1920 m->m_next = mpt->m_next; 1921 break; 1922 } 1923 } 1924 if (m == NULL) { 1925 mptsas_log(mpt, CE_PANIC, "Not in softc list!"); 1926 } 1927 } 1928 1929 if (mptsas_tail == mpt) { 1930 mptsas_tail = m; 1931 } 1932 rw_exit(&mptsas_global_rwlock); 1933 } 1934 1935 static int 1936 mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size) 1937 { 1938 ddi_dma_attr_t task_dma_attrs; 1939 1940 task_dma_attrs = mpt->m_msg_dma_attr; 1941 task_dma_attrs.dma_attr_sgllen = 1; 1942 task_dma_attrs.dma_attr_granular = (uint32_t)(alloc_size); 1943 1944 /* allocate Task Management ddi_dma resources */ 1945 if (mptsas_dma_addr_create(mpt, task_dma_attrs, 1946 &mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl, &mpt->m_hshk_memp, 1947 alloc_size, NULL) == FALSE) { 1948 return (DDI_FAILURE); 1949 } 1950 mpt->m_hshk_dma_size = alloc_size; 1951 1952 return (DDI_SUCCESS); 1953 } 1954 1955 static void 1956 mptsas_free_handshake_msg(mptsas_t *mpt) 1957 { 1958 mptsas_dma_addr_destroy(&mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl); 1959 mpt->m_hshk_dma_size = 0; 1960 } 1961 1962 static int 1963 mptsas_hba_setup(mptsas_t *mpt) 1964 { 1965 scsi_hba_tran_t *hba_tran; 1966 int tran_flags; 1967 1968 /* Allocate a transport structure */ 1969 hba_tran = mpt->m_tran = scsi_hba_tran_alloc(mpt->m_dip, 1970 SCSI_HBA_CANSLEEP); 1971 ASSERT(mpt->m_tran != NULL); 1972 1973 hba_tran->tran_hba_private = mpt; 1974 hba_tran->tran_tgt_private = NULL; 1975 1976 hba_tran->tran_tgt_init = mptsas_scsi_tgt_init; 1977 hba_tran->tran_tgt_free = mptsas_scsi_tgt_free; 1978 1979 hba_tran->tran_start = mptsas_scsi_start; 1980 hba_tran->tran_reset = mptsas_scsi_reset; 1981 hba_tran->tran_abort = mptsas_scsi_abort; 1982 hba_tran->tran_getcap = mptsas_scsi_getcap; 1983 hba_tran->tran_setcap = mptsas_scsi_setcap; 1984 hba_tran->tran_init_pkt = mptsas_scsi_init_pkt; 1985 hba_tran->tran_destroy_pkt = mptsas_scsi_destroy_pkt; 1986 1987 hba_tran->tran_dmafree = mptsas_scsi_dmafree; 1988 hba_tran->tran_sync_pkt = mptsas_scsi_sync_pkt; 1989 hba_tran->tran_reset_notify = mptsas_scsi_reset_notify; 1990 1991 hba_tran->tran_get_bus_addr = mptsas_get_bus_addr; 1992 hba_tran->tran_get_name = mptsas_get_name; 1993 1994 hba_tran->tran_quiesce = mptsas_scsi_quiesce; 1995 hba_tran->tran_unquiesce = mptsas_scsi_unquiesce; 1996 hba_tran->tran_bus_reset = NULL; 1997 1998 hba_tran->tran_add_eventcall = NULL; 1999 hba_tran->tran_get_eventcookie = NULL; 2000 hba_tran->tran_post_event = NULL; 2001 hba_tran->tran_remove_eventcall = NULL; 2002 2003 hba_tran->tran_bus_config = mptsas_bus_config; 2004 2005 hba_tran->tran_interconnect_type = INTERCONNECT_SAS; 2006 2007 /* 2008 * All children of the HBA are iports. We need tran was cloned. 2009 * So we pass the flags to SCSA. SCSI_HBA_TRAN_CLONE will be 2010 * inherited to iport's tran vector. 2011 */ 2012 tran_flags = (SCSI_HBA_HBA | SCSI_HBA_TRAN_CLONE); 2013 2014 if (scsi_hba_attach_setup(mpt->m_dip, &mpt->m_msg_dma_attr, 2015 hba_tran, tran_flags) != DDI_SUCCESS) { 2016 mptsas_log(mpt, CE_WARN, "hba attach setup failed"); 2017 scsi_hba_tran_free(hba_tran); 2018 mpt->m_tran = NULL; 2019 return (FALSE); 2020 } 2021 return (TRUE); 2022 } 2023 2024 static void 2025 mptsas_hba_teardown(mptsas_t *mpt) 2026 { 2027 (void) scsi_hba_detach(mpt->m_dip); 2028 if (mpt->m_tran != NULL) { 2029 scsi_hba_tran_free(mpt->m_tran); 2030 mpt->m_tran = NULL; 2031 } 2032 } 2033 2034 static void 2035 mptsas_iport_register(mptsas_t *mpt) 2036 { 2037 int i, j; 2038 mptsas_phymask_t mask = 0x0; 2039 /* 2040 * initial value of mask is 0 2041 */ 2042 mutex_enter(&mpt->m_mutex); 2043 for (i = 0; i < mpt->m_num_phys; i++) { 2044 mptsas_phymask_t phy_mask = 0x0; 2045 char phy_mask_name[MPTSAS_MAX_PHYS]; 2046 uint8_t current_port; 2047 2048 if (mpt->m_phy_info[i].attached_devhdl == 0) 2049 continue; 2050 2051 bzero(phy_mask_name, sizeof (phy_mask_name)); 2052 2053 current_port = mpt->m_phy_info[i].port_num; 2054 2055 if ((mask & (1 << i)) != 0) 2056 continue; 2057 2058 for (j = 0; j < mpt->m_num_phys; j++) { 2059 if (mpt->m_phy_info[j].attached_devhdl && 2060 (mpt->m_phy_info[j].port_num == current_port)) { 2061 phy_mask |= (1 << j); 2062 } 2063 } 2064 mask = mask | phy_mask; 2065 2066 for (j = 0; j < mpt->m_num_phys; j++) { 2067 if ((phy_mask >> j) & 0x01) { 2068 mpt->m_phy_info[j].phy_mask = phy_mask; 2069 } 2070 } 2071 2072 (void) sprintf(phy_mask_name, "%x", phy_mask); 2073 2074 mutex_exit(&mpt->m_mutex); 2075 /* 2076 * register a iport 2077 */ 2078 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name); 2079 mutex_enter(&mpt->m_mutex); 2080 } 2081 mutex_exit(&mpt->m_mutex); 2082 /* 2083 * register a virtual port for RAID volume always 2084 */ 2085 (void) scsi_hba_iport_register(mpt->m_dip, "v0"); 2086 2087 } 2088 2089 static int 2090 mptsas_smp_setup(mptsas_t *mpt) 2091 { 2092 mpt->m_smptran = smp_hba_tran_alloc(mpt->m_dip); 2093 ASSERT(mpt->m_smptran != NULL); 2094 mpt->m_smptran->smp_tran_hba_private = mpt; 2095 mpt->m_smptran->smp_tran_start = mptsas_smp_start; 2096 if (smp_hba_attach_setup(mpt->m_dip, mpt->m_smptran) != DDI_SUCCESS) { 2097 mptsas_log(mpt, CE_WARN, "smp attach setup failed"); 2098 smp_hba_tran_free(mpt->m_smptran); 2099 mpt->m_smptran = NULL; 2100 return (FALSE); 2101 } 2102 /* 2103 * Initialize smp hash table 2104 */ 2105 mptsas_hash_init(&mpt->m_active->m_smptbl); 2106 mpt->m_smp_devhdl = 0xFFFF; 2107 2108 return (TRUE); 2109 } 2110 2111 static void 2112 mptsas_smp_teardown(mptsas_t *mpt) 2113 { 2114 (void) smp_hba_detach(mpt->m_dip); 2115 if (mpt->m_smptran != NULL) { 2116 smp_hba_tran_free(mpt->m_smptran); 2117 mpt->m_smptran = NULL; 2118 } 2119 mpt->m_smp_devhdl = 0; 2120 } 2121 2122 static int 2123 mptsas_cache_create(mptsas_t *mpt) 2124 { 2125 int instance = mpt->m_instance; 2126 char buf[64]; 2127 2128 /* 2129 * create kmem cache for packets 2130 */ 2131 (void) sprintf(buf, "mptsas%d_cache", instance); 2132 mpt->m_kmem_cache = kmem_cache_create(buf, 2133 sizeof (struct mptsas_cmd) + scsi_pkt_size(), 8, 2134 mptsas_kmem_cache_constructor, mptsas_kmem_cache_destructor, 2135 NULL, (void *)mpt, NULL, 0); 2136 2137 if (mpt->m_kmem_cache == NULL) { 2138 mptsas_log(mpt, CE_WARN, "creating kmem cache failed"); 2139 return (FALSE); 2140 } 2141 2142 /* 2143 * create kmem cache for extra SGL frames if SGL cannot 2144 * be accomodated into main request frame. 2145 */ 2146 (void) sprintf(buf, "mptsas%d_cache_frames", instance); 2147 mpt->m_cache_frames = kmem_cache_create(buf, 2148 sizeof (mptsas_cache_frames_t), 8, 2149 mptsas_cache_frames_constructor, mptsas_cache_frames_destructor, 2150 NULL, (void *)mpt, NULL, 0); 2151 2152 if (mpt->m_cache_frames == NULL) { 2153 mptsas_log(mpt, CE_WARN, "creating cache for frames failed"); 2154 return (FALSE); 2155 } 2156 2157 return (TRUE); 2158 } 2159 2160 static void 2161 mptsas_cache_destroy(mptsas_t *mpt) 2162 { 2163 /* deallocate in reverse order */ 2164 if (mpt->m_cache_frames) { 2165 kmem_cache_destroy(mpt->m_cache_frames); 2166 mpt->m_cache_frames = NULL; 2167 } 2168 if (mpt->m_kmem_cache) { 2169 kmem_cache_destroy(mpt->m_kmem_cache); 2170 mpt->m_kmem_cache = NULL; 2171 } 2172 } 2173 2174 static int 2175 mptsas_power(dev_info_t *dip, int component, int level) 2176 { 2177 #ifndef __lock_lint 2178 _NOTE(ARGUNUSED(component)) 2179 #endif 2180 mptsas_t *mpt; 2181 int rval = DDI_SUCCESS; 2182 int polls = 0; 2183 uint32_t ioc_status; 2184 2185 if (scsi_hba_iport_unit_address(dip) != 0) 2186 return (DDI_SUCCESS); 2187 2188 mpt = ddi_get_soft_state(mptsas_state, ddi_get_instance(dip)); 2189 if (mpt == NULL) { 2190 return (DDI_FAILURE); 2191 } 2192 2193 mutex_enter(&mpt->m_mutex); 2194 2195 /* 2196 * If the device is busy, don't lower its power level 2197 */ 2198 if (mpt->m_busy && (mpt->m_power_level > level)) { 2199 mutex_exit(&mpt->m_mutex); 2200 return (DDI_FAILURE); 2201 } 2202 switch (level) { 2203 case PM_LEVEL_D0: 2204 NDBG11(("mptsas%d: turning power ON.", mpt->m_instance)); 2205 MPTSAS_POWER_ON(mpt); 2206 /* 2207 * Wait up to 30 seconds for IOC to come out of reset. 2208 */ 2209 while (((ioc_status = ddi_get32(mpt->m_datap, 2210 &mpt->m_reg->Doorbell)) & 2211 MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_RESET) { 2212 if (polls++ > 3000) { 2213 break; 2214 } 2215 delay(drv_usectohz(10000)); 2216 } 2217 /* 2218 * If IOC is not in operational state, try to hard reset it. 2219 */ 2220 if ((ioc_status & MPI2_IOC_STATE_MASK) != 2221 MPI2_IOC_STATE_OPERATIONAL) { 2222 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 2223 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) { 2224 mptsas_log(mpt, CE_WARN, 2225 "mptsas_power: hard reset failed"); 2226 mutex_exit(&mpt->m_mutex); 2227 return (DDI_FAILURE); 2228 } 2229 } 2230 mpt->m_power_level = PM_LEVEL_D0; 2231 break; 2232 case PM_LEVEL_D3: 2233 NDBG11(("mptsas%d: turning power OFF.", mpt->m_instance)); 2234 MPTSAS_POWER_OFF(mpt); 2235 break; 2236 default: 2237 mptsas_log(mpt, CE_WARN, "mptsas%d: unknown power level <%x>.", 2238 mpt->m_instance, level); 2239 rval = DDI_FAILURE; 2240 break; 2241 } 2242 mutex_exit(&mpt->m_mutex); 2243 return (rval); 2244 } 2245 2246 /* 2247 * Initialize configuration space and figure out which 2248 * chip and revison of the chip the mpt driver is using. 2249 */ 2250 static int 2251 mptsas_config_space_init(mptsas_t *mpt) 2252 { 2253 NDBG0(("mptsas_config_space_init")); 2254 2255 if (mpt->m_config_handle != NULL) 2256 return (TRUE); 2257 2258 if (pci_config_setup(mpt->m_dip, 2259 &mpt->m_config_handle) != DDI_SUCCESS) { 2260 mptsas_log(mpt, CE_WARN, "cannot map configuration space."); 2261 return (FALSE); 2262 } 2263 2264 /* 2265 * This is a workaround for a XMITS ASIC bug which does not 2266 * drive the CBE upper bits. 2267 */ 2268 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) & 2269 PCI_STAT_PERROR) { 2270 pci_config_put16(mpt->m_config_handle, PCI_CONF_STAT, 2271 PCI_STAT_PERROR); 2272 } 2273 2274 mptsas_setup_cmd_reg(mpt); 2275 2276 /* 2277 * Get the chip device id: 2278 */ 2279 mpt->m_devid = pci_config_get16(mpt->m_config_handle, PCI_CONF_DEVID); 2280 2281 /* 2282 * Save the revision. 2283 */ 2284 mpt->m_revid = pci_config_get8(mpt->m_config_handle, PCI_CONF_REVID); 2285 2286 /* 2287 * Save the SubSystem Vendor and Device IDs 2288 */ 2289 mpt->m_svid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBVENID); 2290 mpt->m_ssid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBSYSID); 2291 2292 /* 2293 * Set the latency timer to 0x40 as specified by the upa -> pci 2294 * bridge chip design team. This may be done by the sparc pci 2295 * bus nexus driver, but the driver should make sure the latency 2296 * timer is correct for performance reasons. 2297 */ 2298 pci_config_put8(mpt->m_config_handle, PCI_CONF_LATENCY_TIMER, 2299 MPTSAS_LATENCY_TIMER); 2300 2301 (void) mptsas_get_pci_cap(mpt); 2302 return (TRUE); 2303 } 2304 2305 static void 2306 mptsas_config_space_fini(mptsas_t *mpt) 2307 { 2308 if (mpt->m_config_handle != NULL) { 2309 mptsas_disable_bus_master(mpt); 2310 pci_config_teardown(&mpt->m_config_handle); 2311 mpt->m_config_handle = NULL; 2312 } 2313 } 2314 2315 static void 2316 mptsas_setup_cmd_reg(mptsas_t *mpt) 2317 { 2318 ushort_t cmdreg; 2319 2320 /* 2321 * Set the command register to the needed values. 2322 */ 2323 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM); 2324 cmdreg |= (PCI_COMM_ME | PCI_COMM_SERR_ENABLE | 2325 PCI_COMM_PARITY_DETECT | PCI_COMM_MAE); 2326 cmdreg &= ~PCI_COMM_IO; 2327 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg); 2328 } 2329 2330 static void 2331 mptsas_disable_bus_master(mptsas_t *mpt) 2332 { 2333 ushort_t cmdreg; 2334 2335 /* 2336 * Clear the master enable bit in the PCI command register. 2337 * This prevents any bus mastering activity like DMA. 2338 */ 2339 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM); 2340 cmdreg &= ~PCI_COMM_ME; 2341 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg); 2342 } 2343 2344 int 2345 mptsas_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep) 2346 { 2347 ddi_dma_attr_t attrs; 2348 2349 attrs = mpt->m_io_dma_attr; 2350 attrs.dma_attr_sgllen = 1; 2351 2352 ASSERT(dma_statep != NULL); 2353 2354 if (mptsas_dma_addr_create(mpt, attrs, &dma_statep->handle, 2355 &dma_statep->accessp, &dma_statep->memp, dma_statep->size, 2356 &dma_statep->cookie) == FALSE) { 2357 return (DDI_FAILURE); 2358 } 2359 2360 return (DDI_SUCCESS); 2361 } 2362 2363 void 2364 mptsas_dma_free(mptsas_dma_alloc_state_t *dma_statep) 2365 { 2366 ASSERT(dma_statep != NULL); 2367 mptsas_dma_addr_destroy(&dma_statep->handle, &dma_statep->accessp); 2368 dma_statep->size = 0; 2369 } 2370 2371 int 2372 mptsas_do_dma(mptsas_t *mpt, uint32_t size, int var, int (*callback)()) 2373 { 2374 ddi_dma_attr_t attrs; 2375 ddi_dma_handle_t dma_handle; 2376 caddr_t memp; 2377 ddi_acc_handle_t accessp; 2378 int rval; 2379 2380 ASSERT(mutex_owned(&mpt->m_mutex)); 2381 2382 attrs = mpt->m_msg_dma_attr; 2383 attrs.dma_attr_sgllen = 1; 2384 attrs.dma_attr_granular = size; 2385 2386 if (mptsas_dma_addr_create(mpt, attrs, &dma_handle, 2387 &accessp, &memp, size, NULL) == FALSE) { 2388 return (DDI_FAILURE); 2389 } 2390 2391 rval = (*callback) (mpt, memp, var, accessp); 2392 2393 if ((mptsas_check_dma_handle(dma_handle) != DDI_SUCCESS) || 2394 (mptsas_check_acc_handle(accessp) != DDI_SUCCESS)) { 2395 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 2396 rval = DDI_FAILURE; 2397 } 2398 2399 mptsas_dma_addr_destroy(&dma_handle, &accessp); 2400 return (rval); 2401 2402 } 2403 2404 static int 2405 mptsas_alloc_request_frames(mptsas_t *mpt) 2406 { 2407 ddi_dma_attr_t frame_dma_attrs; 2408 caddr_t memp; 2409 ddi_dma_cookie_t cookie; 2410 size_t mem_size; 2411 2412 /* 2413 * re-alloc when it has already alloced 2414 */ 2415 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl, 2416 &mpt->m_acc_req_frame_hdl); 2417 2418 /* 2419 * The size of the request frame pool is: 2420 * Number of Request Frames * Request Frame Size 2421 */ 2422 mem_size = mpt->m_max_requests * mpt->m_req_frame_size; 2423 2424 /* 2425 * set the DMA attributes. System Request Message Frames must be 2426 * aligned on a 16-byte boundry. 2427 */ 2428 frame_dma_attrs = mpt->m_msg_dma_attr; 2429 frame_dma_attrs.dma_attr_align = 16; 2430 frame_dma_attrs.dma_attr_sgllen = 1; 2431 2432 /* 2433 * allocate the request frame pool. 2434 */ 2435 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2436 &mpt->m_dma_req_frame_hdl, &mpt->m_acc_req_frame_hdl, &memp, 2437 mem_size, &cookie) == FALSE) { 2438 return (DDI_FAILURE); 2439 } 2440 2441 /* 2442 * Store the request frame memory address. This chip uses this 2443 * address to dma to and from the driver's frame. The second 2444 * address is the address mpt uses to fill in the frame. 2445 */ 2446 mpt->m_req_frame_dma_addr = cookie.dmac_laddress; 2447 mpt->m_req_frame = memp; 2448 2449 /* 2450 * Clear the request frame pool. 2451 */ 2452 bzero(mpt->m_req_frame, mem_size); 2453 2454 return (DDI_SUCCESS); 2455 } 2456 2457 static int 2458 mptsas_alloc_reply_frames(mptsas_t *mpt) 2459 { 2460 ddi_dma_attr_t frame_dma_attrs; 2461 caddr_t memp; 2462 ddi_dma_cookie_t cookie; 2463 size_t mem_size; 2464 2465 /* 2466 * re-alloc when it has already alloced 2467 */ 2468 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl, 2469 &mpt->m_acc_reply_frame_hdl); 2470 2471 /* 2472 * The size of the reply frame pool is: 2473 * Number of Reply Frames * Reply Frame Size 2474 */ 2475 mem_size = mpt->m_max_replies * mpt->m_reply_frame_size; 2476 2477 /* 2478 * set the DMA attributes. System Reply Message Frames must be 2479 * aligned on a 4-byte boundry. This is the default. 2480 */ 2481 frame_dma_attrs = mpt->m_msg_dma_attr; 2482 frame_dma_attrs.dma_attr_sgllen = 1; 2483 2484 /* 2485 * allocate the reply frame pool 2486 */ 2487 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2488 &mpt->m_dma_reply_frame_hdl, &mpt->m_acc_reply_frame_hdl, &memp, 2489 mem_size, &cookie) == FALSE) { 2490 return (DDI_FAILURE); 2491 } 2492 2493 /* 2494 * Store the reply frame memory address. This chip uses this 2495 * address to dma to and from the driver's frame. The second 2496 * address is the address mpt uses to process the frame. 2497 */ 2498 mpt->m_reply_frame_dma_addr = cookie.dmac_laddress; 2499 mpt->m_reply_frame = memp; 2500 2501 /* 2502 * Clear the reply frame pool. 2503 */ 2504 bzero(mpt->m_reply_frame, mem_size); 2505 2506 return (DDI_SUCCESS); 2507 } 2508 2509 static int 2510 mptsas_alloc_free_queue(mptsas_t *mpt) 2511 { 2512 ddi_dma_attr_t frame_dma_attrs; 2513 caddr_t memp; 2514 ddi_dma_cookie_t cookie; 2515 size_t mem_size; 2516 2517 /* 2518 * re-alloc when it has already alloced 2519 */ 2520 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl, 2521 &mpt->m_acc_free_queue_hdl); 2522 2523 /* 2524 * The reply free queue size is: 2525 * Reply Free Queue Depth * 4 2526 * The "4" is the size of one 32 bit address (low part of 64-bit 2527 * address) 2528 */ 2529 mem_size = mpt->m_free_queue_depth * 4; 2530 2531 /* 2532 * set the DMA attributes The Reply Free Queue must be aligned on a 2533 * 16-byte boundry. 2534 */ 2535 frame_dma_attrs = mpt->m_msg_dma_attr; 2536 frame_dma_attrs.dma_attr_align = 16; 2537 frame_dma_attrs.dma_attr_sgllen = 1; 2538 2539 /* 2540 * allocate the reply free queue 2541 */ 2542 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2543 &mpt->m_dma_free_queue_hdl, &mpt->m_acc_free_queue_hdl, &memp, 2544 mem_size, &cookie) == FALSE) { 2545 return (DDI_FAILURE); 2546 } 2547 2548 /* 2549 * Store the reply free queue memory address. This chip uses this 2550 * address to read from the reply free queue. The second address 2551 * is the address mpt uses to manage the queue. 2552 */ 2553 mpt->m_free_queue_dma_addr = cookie.dmac_laddress; 2554 mpt->m_free_queue = memp; 2555 2556 /* 2557 * Clear the reply free queue memory. 2558 */ 2559 bzero(mpt->m_free_queue, mem_size); 2560 2561 return (DDI_SUCCESS); 2562 } 2563 2564 static int 2565 mptsas_alloc_post_queue(mptsas_t *mpt) 2566 { 2567 ddi_dma_attr_t frame_dma_attrs; 2568 caddr_t memp; 2569 ddi_dma_cookie_t cookie; 2570 size_t mem_size; 2571 2572 /* 2573 * re-alloc when it has already alloced 2574 */ 2575 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl, 2576 &mpt->m_acc_post_queue_hdl); 2577 2578 /* 2579 * The reply descriptor post queue size is: 2580 * Reply Descriptor Post Queue Depth * 8 2581 * The "8" is the size of each descriptor (8 bytes or 64 bits). 2582 */ 2583 mem_size = mpt->m_post_queue_depth * 8; 2584 2585 /* 2586 * set the DMA attributes. The Reply Descriptor Post Queue must be 2587 * aligned on a 16-byte boundry. 2588 */ 2589 frame_dma_attrs = mpt->m_msg_dma_attr; 2590 frame_dma_attrs.dma_attr_align = 16; 2591 frame_dma_attrs.dma_attr_sgllen = 1; 2592 2593 /* 2594 * allocate the reply post queue 2595 */ 2596 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2597 &mpt->m_dma_post_queue_hdl, &mpt->m_acc_post_queue_hdl, &memp, 2598 mem_size, &cookie) == FALSE) { 2599 return (DDI_FAILURE); 2600 } 2601 2602 /* 2603 * Store the reply descriptor post queue memory address. This chip 2604 * uses this address to write to the reply descriptor post queue. The 2605 * second address is the address mpt uses to manage the queue. 2606 */ 2607 mpt->m_post_queue_dma_addr = cookie.dmac_laddress; 2608 mpt->m_post_queue = memp; 2609 2610 /* 2611 * Clear the reply post queue memory. 2612 */ 2613 bzero(mpt->m_post_queue, mem_size); 2614 2615 return (DDI_SUCCESS); 2616 } 2617 2618 static void 2619 mptsas_alloc_reply_args(mptsas_t *mpt) 2620 { 2621 if (mpt->m_replyh_args != NULL) { 2622 kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t) 2623 * mpt->m_max_replies); 2624 mpt->m_replyh_args = NULL; 2625 } 2626 mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) * 2627 mpt->m_max_replies, KM_SLEEP); 2628 } 2629 2630 static int 2631 mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd) 2632 { 2633 mptsas_cache_frames_t *frames = NULL; 2634 if (cmd->cmd_extra_frames == NULL) { 2635 frames = kmem_cache_alloc(mpt->m_cache_frames, KM_NOSLEEP); 2636 if (frames == NULL) { 2637 return (DDI_FAILURE); 2638 } 2639 cmd->cmd_extra_frames = frames; 2640 } 2641 return (DDI_SUCCESS); 2642 } 2643 2644 static void 2645 mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd) 2646 { 2647 if (cmd->cmd_extra_frames) { 2648 kmem_cache_free(mpt->m_cache_frames, 2649 (void *)cmd->cmd_extra_frames); 2650 cmd->cmd_extra_frames = NULL; 2651 } 2652 } 2653 2654 static void 2655 mptsas_cfg_fini(mptsas_t *mpt) 2656 { 2657 NDBG0(("mptsas_cfg_fini")); 2658 ddi_regs_map_free(&mpt->m_datap); 2659 } 2660 2661 static void 2662 mptsas_hba_fini(mptsas_t *mpt) 2663 { 2664 NDBG0(("mptsas_hba_fini")); 2665 2666 /* 2667 * Free up any allocated memory 2668 */ 2669 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl, 2670 &mpt->m_acc_req_frame_hdl); 2671 2672 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl, 2673 &mpt->m_acc_reply_frame_hdl); 2674 2675 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl, 2676 &mpt->m_acc_free_queue_hdl); 2677 2678 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl, 2679 &mpt->m_acc_post_queue_hdl); 2680 2681 if (mpt->m_replyh_args != NULL) { 2682 kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t) 2683 * mpt->m_max_replies); 2684 } 2685 } 2686 2687 static int 2688 mptsas_name_child(dev_info_t *lun_dip, char *name, int len) 2689 { 2690 int lun = 0; 2691 char *sas_wwn = NULL; 2692 int phynum = -1; 2693 int reallen = 0; 2694 2695 /* Get the target num */ 2696 lun = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, DDI_PROP_DONTPASS, 2697 LUN_PROP, 0); 2698 2699 if ((phynum = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, 2700 DDI_PROP_DONTPASS, "sata-phy", -1)) != -1) { 2701 /* 2702 * Stick in the address of form "pPHY,LUN" 2703 */ 2704 reallen = snprintf(name, len, "p%x,%x", phynum, lun); 2705 } else if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lun_dip, 2706 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &sas_wwn) 2707 == DDI_PROP_SUCCESS) { 2708 /* 2709 * Stick in the address of the form "wWWN,LUN" 2710 */ 2711 reallen = snprintf(name, len, "%s,%x", sas_wwn, lun); 2712 ddi_prop_free(sas_wwn); 2713 } else { 2714 return (DDI_FAILURE); 2715 } 2716 2717 ASSERT(reallen < len); 2718 if (reallen >= len) { 2719 mptsas_log(0, CE_WARN, "!mptsas_get_name: name parameter " 2720 "length too small, it needs to be %d bytes", reallen + 1); 2721 } 2722 return (DDI_SUCCESS); 2723 } 2724 2725 /* 2726 * tran_tgt_init(9E) - target device instance initialization 2727 */ 2728 static int 2729 mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 2730 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 2731 { 2732 #ifndef __lock_lint 2733 _NOTE(ARGUNUSED(hba_tran)) 2734 #endif 2735 2736 /* 2737 * At this point, the scsi_device structure already exists 2738 * and has been initialized. 2739 * 2740 * Use this function to allocate target-private data structures, 2741 * if needed by this HBA. Add revised flow-control and queue 2742 * properties for child here, if desired and if you can tell they 2743 * support tagged queueing by now. 2744 */ 2745 mptsas_t *mpt; 2746 int lun = sd->sd_address.a_lun; 2747 mdi_pathinfo_t *pip = NULL; 2748 mptsas_tgt_private_t *tgt_private = NULL; 2749 mptsas_target_t *ptgt = NULL; 2750 char *psas_wwn = NULL; 2751 int phymask = 0; 2752 uint64_t sas_wwn = 0; 2753 mpt = SDEV2MPT(sd); 2754 2755 ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0); 2756 2757 NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d", 2758 (void *)hba_dip, (void *)tgt_dip, lun)); 2759 2760 if (ndi_dev_is_persistent_node(tgt_dip) == 0) { 2761 (void) ndi_merge_node(tgt_dip, mptsas_name_child); 2762 ddi_set_name_addr(tgt_dip, NULL); 2763 return (DDI_FAILURE); 2764 } 2765 /* 2766 * phymask is 0 means the virtual port for RAID 2767 */ 2768 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0, 2769 "phymask", 0); 2770 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) { 2771 if ((pip = (void *)(sd->sd_private)) == NULL) { 2772 /* 2773 * Very bad news if this occurs. Somehow scsi_vhci has 2774 * lost the pathinfo node for this target. 2775 */ 2776 return (DDI_NOT_WELL_FORMED); 2777 } 2778 2779 if (mdi_prop_lookup_int(pip, LUN_PROP, &lun) != 2780 DDI_PROP_SUCCESS) { 2781 mptsas_log(mpt, CE_WARN, "Get lun property failed\n"); 2782 return (DDI_FAILURE); 2783 } 2784 2785 if (mdi_prop_lookup_string(pip, SCSI_ADDR_PROP_TARGET_PORT, 2786 &psas_wwn) == MDI_SUCCESS) { 2787 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) { 2788 sas_wwn = 0; 2789 } 2790 (void) mdi_prop_free(psas_wwn); 2791 } 2792 } else { 2793 lun = ddi_prop_get_int(DDI_DEV_T_ANY, tgt_dip, 2794 DDI_PROP_DONTPASS, LUN_PROP, 0); 2795 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, tgt_dip, 2796 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &psas_wwn) == 2797 DDI_PROP_SUCCESS) { 2798 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) { 2799 sas_wwn = 0; 2800 } 2801 ddi_prop_free(psas_wwn); 2802 } else { 2803 sas_wwn = 0; 2804 } 2805 } 2806 ASSERT((sas_wwn != 0) || (phymask != 0)); 2807 mutex_enter(&mpt->m_mutex); 2808 ptgt = mptsas_hash_search(&mpt->m_active->m_tgttbl, sas_wwn, phymask); 2809 mutex_exit(&mpt->m_mutex); 2810 if (ptgt == NULL) { 2811 mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or " 2812 "gone already! phymask:%x, saswwn %"PRIx64, phymask, 2813 sas_wwn); 2814 return (DDI_FAILURE); 2815 } 2816 if (hba_tran->tran_tgt_private == NULL) { 2817 tgt_private = kmem_zalloc(sizeof (mptsas_tgt_private_t), 2818 KM_SLEEP); 2819 tgt_private->t_lun = lun; 2820 tgt_private->t_private = ptgt; 2821 hba_tran->tran_tgt_private = tgt_private; 2822 } 2823 2824 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) { 2825 return (DDI_SUCCESS); 2826 } 2827 mutex_enter(&mpt->m_mutex); 2828 2829 if (ptgt->m_deviceinfo & 2830 (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 2831 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 2832 uchar_t *inq89 = NULL; 2833 int inq89_len = 0x238; 2834 int reallen = 0; 2835 int rval = 0; 2836 struct sata_id *sid = NULL; 2837 char model[SATA_ID_MODEL_LEN + 1]; 2838 char fw[SATA_ID_FW_LEN + 1]; 2839 char *vid, *pid; 2840 int i; 2841 2842 mutex_exit(&mpt->m_mutex); 2843 /* 2844 * According SCSI/ATA Translation -2 (SAT-2) revision 01a 2845 * chapter 12.4.2 VPD page 89h includes 512 bytes ATA IDENTIFY 2846 * DEVICE data or ATA IDENTIFY PACKET DEVICE data. 2847 */ 2848 inq89 = kmem_zalloc(inq89_len, KM_SLEEP); 2849 rval = mptsas_inquiry(mpt, ptgt, 0, 0x89, 2850 inq89, inq89_len, &reallen, 1); 2851 2852 if (rval != 0) { 2853 if (inq89 != NULL) { 2854 kmem_free(inq89, inq89_len); 2855 } 2856 2857 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 2858 "0x89 for SATA target:%x failed!", ptgt->m_devhdl); 2859 return (DDI_SUCCESS); 2860 } 2861 sid = (void *)(&inq89[60]); 2862 2863 swab(sid->ai_model, model, SATA_ID_MODEL_LEN); 2864 swab(sid->ai_fw, fw, SATA_ID_FW_LEN); 2865 2866 model[SATA_ID_MODEL_LEN] = 0; 2867 fw[SATA_ID_FW_LEN] = 0; 2868 2869 /* 2870 * split model into into vid/pid 2871 */ 2872 for (i = 0, pid = model; i < SATA_ID_MODEL_LEN; i++, pid++) 2873 if ((*pid == ' ') || (*pid == '\t')) 2874 break; 2875 if (i < SATA_ID_MODEL_LEN) { 2876 vid = model; 2877 /* 2878 * terminate vid, establish pid 2879 */ 2880 *pid++ = 0; 2881 } else { 2882 /* 2883 * vid will stay "ATA ", the rule is same 2884 * as sata framework implementation. 2885 */ 2886 vid = NULL; 2887 /* 2888 * model is all pid 2889 */ 2890 pid = model; 2891 } 2892 2893 /* 2894 * override SCSA "inquiry-*" properties 2895 */ 2896 if (vid) 2897 (void) scsi_device_prop_update_inqstring(sd, 2898 INQUIRY_VENDOR_ID, vid, strlen(vid)); 2899 if (pid) 2900 (void) scsi_device_prop_update_inqstring(sd, 2901 INQUIRY_PRODUCT_ID, pid, strlen(pid)); 2902 (void) scsi_device_prop_update_inqstring(sd, 2903 INQUIRY_REVISION_ID, fw, strlen(fw)); 2904 2905 if (inq89 != NULL) { 2906 kmem_free(inq89, inq89_len); 2907 } 2908 } else { 2909 mutex_exit(&mpt->m_mutex); 2910 } 2911 2912 return (DDI_SUCCESS); 2913 } 2914 /* 2915 * tran_tgt_free(9E) - target device instance deallocation 2916 */ 2917 static void 2918 mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 2919 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 2920 { 2921 #ifndef __lock_lint 2922 _NOTE(ARGUNUSED(hba_dip, tgt_dip, hba_tran, sd)) 2923 #endif 2924 2925 mptsas_tgt_private_t *tgt_private = hba_tran->tran_tgt_private; 2926 2927 if (tgt_private != NULL) { 2928 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t)); 2929 hba_tran->tran_tgt_private = NULL; 2930 } 2931 } 2932 2933 /* 2934 * scsi_pkt handling 2935 * 2936 * Visible to the external world via the transport structure. 2937 */ 2938 2939 /* 2940 * Notes: 2941 * - transport the command to the addressed SCSI target/lun device 2942 * - normal operation is to schedule the command to be transported, 2943 * and return TRAN_ACCEPT if this is successful. 2944 * - if NO_INTR, tran_start must poll device for command completion 2945 */ 2946 static int 2947 mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt) 2948 { 2949 #ifndef __lock_lint 2950 _NOTE(ARGUNUSED(ap)) 2951 #endif 2952 mptsas_t *mpt = PKT2MPT(pkt); 2953 mptsas_cmd_t *cmd = PKT2CMD(pkt); 2954 int rval; 2955 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 2956 2957 NDBG1(("mptsas_scsi_start: pkt=0x%p", (void *)pkt)); 2958 ASSERT(ptgt); 2959 if (ptgt == NULL) 2960 return (TRAN_FATAL_ERROR); 2961 2962 /* 2963 * prepare the pkt before taking mutex. 2964 */ 2965 rval = mptsas_prepare_pkt(cmd); 2966 if (rval != TRAN_ACCEPT) { 2967 return (rval); 2968 } 2969 2970 /* 2971 * Send the command to target/lun, however your HBA requires it. 2972 * If busy, return TRAN_BUSY; if there's some other formatting error 2973 * in the packet, return TRAN_BADPKT; otherwise, fall through to the 2974 * return of TRAN_ACCEPT. 2975 * 2976 * Remember that access to shared resources, including the mptsas_t 2977 * data structure and the HBA hardware registers, must be protected 2978 * with mutexes, here and everywhere. 2979 * 2980 * Also remember that at interrupt time, you'll get an argument 2981 * to the interrupt handler which is a pointer to your mptsas_t 2982 * structure; you'll have to remember which commands are outstanding 2983 * and which scsi_pkt is the currently-running command so the 2984 * interrupt handler can refer to the pkt to set completion 2985 * status, call the target driver back through pkt_comp, etc. 2986 * 2987 * If the instance lock is held by other thread, don't spin to wait 2988 * for it. Instead, queue the cmd and next time when the instance lock 2989 * is not held, accept all the queued cmd. A extra tx_waitq is 2990 * introduced to protect the queue. 2991 * 2992 * The polled cmd will not be queud and accepted as usual. 2993 * 2994 * Under the tx_waitq mutex, record whether a thread is draining 2995 * the tx_waitq. An IO requesting thread that finds the instance 2996 * mutex contended appends to the tx_waitq and while holding the 2997 * tx_wait mutex, if the draining flag is not set, sets it and then 2998 * proceeds to spin for the instance mutex. This scheme ensures that 2999 * the last cmd in a burst be processed. 3000 * 3001 * we enable this feature only when the helper threads are enabled, 3002 * at which we think the loads are heavy. 3003 * 3004 * per instance mutex m_tx_waitq_mutex is introduced to protect the 3005 * m_tx_waitqtail, m_tx_waitq, m_tx_draining. 3006 */ 3007 3008 if (mpt->m_doneq_thread_n) { 3009 if (mutex_tryenter(&mpt->m_mutex) != 0) { 3010 rval = mptsas_accept_txwq_and_pkt(mpt, cmd); 3011 mutex_exit(&mpt->m_mutex); 3012 } else if (cmd->cmd_pkt_flags & FLAG_NOINTR) { 3013 mutex_enter(&mpt->m_mutex); 3014 rval = mptsas_accept_txwq_and_pkt(mpt, cmd); 3015 mutex_exit(&mpt->m_mutex); 3016 } else { 3017 mutex_enter(&mpt->m_tx_waitq_mutex); 3018 /* 3019 * ptgt->m_dr_flag is protected by m_mutex or 3020 * m_tx_waitq_mutex. In this case, m_tx_waitq_mutex 3021 * is acquired. 3022 */ 3023 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3024 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3025 /* 3026 * The command should be allowed to 3027 * retry by returning TRAN_BUSY to 3028 * to stall the I/O's which come from 3029 * scsi_vhci since the device/path is 3030 * in unstable state now. 3031 */ 3032 mutex_exit(&mpt->m_tx_waitq_mutex); 3033 return (TRAN_BUSY); 3034 } else { 3035 /* 3036 * The device is offline, just fail the 3037 * command by returning 3038 * TRAN_FATAL_ERROR. 3039 */ 3040 mutex_exit(&mpt->m_tx_waitq_mutex); 3041 return (TRAN_FATAL_ERROR); 3042 } 3043 } 3044 if (mpt->m_tx_draining) { 3045 cmd->cmd_flags |= CFLAG_TXQ; 3046 *mpt->m_tx_waitqtail = cmd; 3047 mpt->m_tx_waitqtail = &cmd->cmd_linkp; 3048 mutex_exit(&mpt->m_tx_waitq_mutex); 3049 } else { /* drain the queue */ 3050 mpt->m_tx_draining = 1; 3051 mutex_exit(&mpt->m_tx_waitq_mutex); 3052 mutex_enter(&mpt->m_mutex); 3053 rval = mptsas_accept_txwq_and_pkt(mpt, cmd); 3054 mutex_exit(&mpt->m_mutex); 3055 } 3056 } 3057 } else { 3058 mutex_enter(&mpt->m_mutex); 3059 /* 3060 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex 3061 * in this case, m_mutex is acquired. 3062 */ 3063 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3064 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3065 /* 3066 * commands should be allowed to retry by 3067 * returning TRAN_BUSY to stall the I/O's 3068 * which come from scsi_vhci since the device/ 3069 * path is in unstable state now. 3070 */ 3071 mutex_exit(&mpt->m_mutex); 3072 return (TRAN_BUSY); 3073 } else { 3074 /* 3075 * The device is offline, just fail the 3076 * command by returning TRAN_FATAL_ERROR. 3077 */ 3078 mutex_exit(&mpt->m_mutex); 3079 return (TRAN_FATAL_ERROR); 3080 } 3081 } 3082 rval = mptsas_accept_pkt(mpt, cmd); 3083 mutex_exit(&mpt->m_mutex); 3084 } 3085 3086 return (rval); 3087 } 3088 3089 /* 3090 * Accept all the queued cmds(if any) before accept the current one. 3091 */ 3092 static int 3093 mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd) 3094 { 3095 int rval; 3096 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3097 3098 ASSERT(mutex_owned(&mpt->m_mutex)); 3099 /* 3100 * The call to mptsas_accept_tx_waitq() must always be performed 3101 * because that is where mpt->m_tx_draining is cleared. 3102 */ 3103 mutex_enter(&mpt->m_tx_waitq_mutex); 3104 mptsas_accept_tx_waitq(mpt); 3105 mutex_exit(&mpt->m_tx_waitq_mutex); 3106 /* 3107 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex 3108 * in this case, m_mutex is acquired. 3109 */ 3110 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3111 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3112 /* 3113 * The command should be allowed to retry by returning 3114 * TRAN_BUSY to stall the I/O's which come from 3115 * scsi_vhci since the device/path is in unstable state 3116 * now. 3117 */ 3118 return (TRAN_BUSY); 3119 } else { 3120 /* 3121 * The device is offline, just fail the command by 3122 * return TRAN_FATAL_ERROR. 3123 */ 3124 return (TRAN_FATAL_ERROR); 3125 } 3126 } 3127 rval = mptsas_accept_pkt(mpt, cmd); 3128 3129 return (rval); 3130 } 3131 3132 static int 3133 mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd) 3134 { 3135 int rval = TRAN_ACCEPT; 3136 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3137 3138 NDBG1(("mptsas_accept_pkt: cmd=0x%p", (void *)cmd)); 3139 3140 ASSERT(mutex_owned(&mpt->m_mutex)); 3141 3142 if ((cmd->cmd_flags & CFLAG_PREPARED) == 0) { 3143 rval = mptsas_prepare_pkt(cmd); 3144 if (rval != TRAN_ACCEPT) { 3145 cmd->cmd_flags &= ~CFLAG_TRANFLAG; 3146 return (rval); 3147 } 3148 } 3149 3150 /* 3151 * reset the throttle if we were draining 3152 */ 3153 if ((ptgt->m_t_ncmds == 0) && 3154 (ptgt->m_t_throttle == DRAIN_THROTTLE)) { 3155 NDBG23(("reset throttle")); 3156 ASSERT(ptgt->m_reset_delay == 0); 3157 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 3158 } 3159 3160 /* 3161 * If HBA is being reset, the DevHandles are being re-initialized, 3162 * which means that they could be invalid even if the target is still 3163 * attached. Check if being reset and if DevHandle is being 3164 * re-initialized. If this is the case, return BUSY so the I/O can be 3165 * retried later. 3166 */ 3167 if ((ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) && mpt->m_in_reset) { 3168 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 3169 if (cmd->cmd_flags & CFLAG_TXQ) { 3170 mptsas_doneq_add(mpt, cmd); 3171 mptsas_doneq_empty(mpt); 3172 return (rval); 3173 } else { 3174 return (TRAN_BUSY); 3175 } 3176 } 3177 3178 /* 3179 * If device handle has already been invalidated, just 3180 * fail the command. In theory, command from scsi_vhci 3181 * client is impossible send down command with invalid 3182 * devhdl since devhdl is set after path offline, target 3183 * driver is not suppose to select a offlined path. 3184 */ 3185 if (ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) { 3186 NDBG20(("rejecting command, it might because invalid devhdl " 3187 "request.")); 3188 mptsas_set_pkt_reason(mpt, cmd, CMD_DEV_GONE, STAT_TERMINATED); 3189 if (cmd->cmd_flags & CFLAG_TXQ) { 3190 mptsas_doneq_add(mpt, cmd); 3191 mptsas_doneq_empty(mpt); 3192 return (rval); 3193 } else { 3194 return (TRAN_FATAL_ERROR); 3195 } 3196 } 3197 /* 3198 * The first case is the normal case. mpt gets a command from the 3199 * target driver and starts it. 3200 * Since SMID 0 is reserved and the TM slot is reserved, the actual max 3201 * commands is m_max_requests - 2. 3202 */ 3203 if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) && 3204 (ptgt->m_t_throttle > HOLD_THROTTLE) && 3205 (ptgt->m_t_ncmds < ptgt->m_t_throttle) && 3206 (ptgt->m_reset_delay == 0) && 3207 (ptgt->m_t_nwait == 0) && 3208 ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0)) { 3209 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 3210 (void) mptsas_start_cmd(mpt, cmd); 3211 } else { 3212 mptsas_waitq_add(mpt, cmd); 3213 } 3214 } else { 3215 /* 3216 * Add this pkt to the work queue 3217 */ 3218 mptsas_waitq_add(mpt, cmd); 3219 3220 if (cmd->cmd_pkt_flags & FLAG_NOINTR) { 3221 (void) mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME); 3222 3223 /* 3224 * Only flush the doneq if this is not a TM 3225 * cmd. For TM cmds the flushing of the 3226 * doneq will be done in those routines. 3227 */ 3228 if ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) { 3229 mptsas_doneq_empty(mpt); 3230 } 3231 } 3232 } 3233 return (rval); 3234 } 3235 3236 int 3237 mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 3238 { 3239 mptsas_slots_t *slots; 3240 int slot; 3241 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3242 3243 ASSERT(mutex_owned(&mpt->m_mutex)); 3244 slots = mpt->m_active; 3245 3246 /* 3247 * Account for reserved TM request slot and reserved SMID of 0. 3248 */ 3249 ASSERT(slots->m_n_slots == (mpt->m_max_requests - 2)); 3250 3251 /* 3252 * m_tags is equivalent to the SMID when sending requests. Since the 3253 * SMID cannot be 0, start out at one if rolling over past the size 3254 * of the request queue depth. Also, don't use the last SMID, which is 3255 * reserved for TM requests. 3256 */ 3257 slot = (slots->m_tags)++; 3258 if (slots->m_tags > slots->m_n_slots) { 3259 slots->m_tags = 1; 3260 } 3261 3262 alloc_tag: 3263 /* Validate tag, should never fail. */ 3264 if (slots->m_slot[slot] == NULL) { 3265 /* 3266 * Make sure SMID is not using reserved value of 0 3267 * and the TM request slot. 3268 */ 3269 ASSERT((slot > 0) && (slot <= slots->m_n_slots)); 3270 cmd->cmd_slot = slot; 3271 slots->m_slot[slot] = cmd; 3272 mpt->m_ncmds++; 3273 3274 /* 3275 * only increment per target ncmds if this is not a 3276 * command that has no target associated with it (i.e. a 3277 * event acknoledgment) 3278 */ 3279 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 3280 ptgt->m_t_ncmds++; 3281 } 3282 cmd->cmd_active_timeout = cmd->cmd_pkt->pkt_time; 3283 3284 /* 3285 * If initial timout is less than or equal to one tick, bump 3286 * the timeout by a tick so that command doesn't timeout before 3287 * its allotted time. 3288 */ 3289 if (cmd->cmd_active_timeout <= mptsas_scsi_watchdog_tick) { 3290 cmd->cmd_active_timeout += mptsas_scsi_watchdog_tick; 3291 } 3292 return (TRUE); 3293 } else { 3294 int i; 3295 3296 /* 3297 * If slot in use, scan until a free one is found. Don't use 0 3298 * or final slot, which is reserved for TM requests. 3299 */ 3300 for (i = 0; i < slots->m_n_slots; i++) { 3301 slot = slots->m_tags; 3302 if (++(slots->m_tags) > slots->m_n_slots) { 3303 slots->m_tags = 1; 3304 } 3305 if (slots->m_slot[slot] == NULL) { 3306 NDBG22(("found free slot %d", slot)); 3307 goto alloc_tag; 3308 } 3309 } 3310 } 3311 return (FALSE); 3312 } 3313 3314 /* 3315 * prepare the pkt: 3316 * the pkt may have been resubmitted or just reused so 3317 * initialize some fields and do some checks. 3318 */ 3319 static int 3320 mptsas_prepare_pkt(mptsas_cmd_t *cmd) 3321 { 3322 struct scsi_pkt *pkt = CMD2PKT(cmd); 3323 3324 NDBG1(("mptsas_prepare_pkt: cmd=0x%p", (void *)cmd)); 3325 3326 /* 3327 * Reinitialize some fields that need it; the packet may 3328 * have been resubmitted 3329 */ 3330 pkt->pkt_reason = CMD_CMPLT; 3331 pkt->pkt_state = 0; 3332 pkt->pkt_statistics = 0; 3333 pkt->pkt_resid = 0; 3334 cmd->cmd_age = 0; 3335 cmd->cmd_pkt_flags = pkt->pkt_flags; 3336 3337 /* 3338 * zero status byte. 3339 */ 3340 *(pkt->pkt_scbp) = 0; 3341 3342 if (cmd->cmd_flags & CFLAG_DMAVALID) { 3343 pkt->pkt_resid = cmd->cmd_dmacount; 3344 3345 /* 3346 * consistent packets need to be sync'ed first 3347 * (only for data going out) 3348 */ 3349 if ((cmd->cmd_flags & CFLAG_CMDIOPB) && 3350 (cmd->cmd_flags & CFLAG_DMASEND)) { 3351 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 3352 DDI_DMA_SYNC_FORDEV); 3353 } 3354 } 3355 3356 cmd->cmd_flags = 3357 (cmd->cmd_flags & ~(CFLAG_TRANFLAG)) | 3358 CFLAG_PREPARED | CFLAG_IN_TRANSPORT; 3359 3360 return (TRAN_ACCEPT); 3361 } 3362 3363 /* 3364 * tran_init_pkt(9E) - allocate scsi_pkt(9S) for command 3365 * 3366 * One of three possibilities: 3367 * - allocate scsi_pkt 3368 * - allocate scsi_pkt and DMA resources 3369 * - allocate DMA resources to an already-allocated pkt 3370 */ 3371 static struct scsi_pkt * 3372 mptsas_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt, 3373 struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags, 3374 int (*callback)(), caddr_t arg) 3375 { 3376 mptsas_cmd_t *cmd, *new_cmd; 3377 mptsas_t *mpt = ADDR2MPT(ap); 3378 int failure = 1; 3379 uint_t oldcookiec; 3380 mptsas_target_t *ptgt = NULL; 3381 int rval; 3382 mptsas_tgt_private_t *tgt_private; 3383 int kf; 3384 3385 kf = (callback == SLEEP_FUNC)? KM_SLEEP: KM_NOSLEEP; 3386 3387 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran-> 3388 tran_tgt_private; 3389 ASSERT(tgt_private != NULL); 3390 if (tgt_private == NULL) { 3391 return (NULL); 3392 } 3393 ptgt = tgt_private->t_private; 3394 ASSERT(ptgt != NULL); 3395 if (ptgt == NULL) 3396 return (NULL); 3397 ap->a_target = ptgt->m_devhdl; 3398 ap->a_lun = tgt_private->t_lun; 3399 3400 ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC); 3401 #ifdef MPTSAS_TEST_EXTRN_ALLOC 3402 statuslen *= 100; tgtlen *= 4; 3403 #endif 3404 NDBG3(("mptsas_scsi_init_pkt:\n" 3405 "\ttgt=%d in=0x%p bp=0x%p clen=%d slen=%d tlen=%d flags=%x", 3406 ap->a_target, (void *)pkt, (void *)bp, 3407 cmdlen, statuslen, tgtlen, flags)); 3408 3409 /* 3410 * Allocate the new packet. 3411 */ 3412 if (pkt == NULL) { 3413 ddi_dma_handle_t save_dma_handle; 3414 ddi_dma_handle_t save_arq_dma_handle; 3415 struct buf *save_arq_bp; 3416 ddi_dma_cookie_t save_arqcookie; 3417 3418 cmd = kmem_cache_alloc(mpt->m_kmem_cache, kf); 3419 3420 if (cmd) { 3421 save_dma_handle = cmd->cmd_dmahandle; 3422 save_arq_dma_handle = cmd->cmd_arqhandle; 3423 save_arq_bp = cmd->cmd_arq_buf; 3424 save_arqcookie = cmd->cmd_arqcookie; 3425 bzero(cmd, sizeof (*cmd) + scsi_pkt_size()); 3426 cmd->cmd_dmahandle = save_dma_handle; 3427 cmd->cmd_arqhandle = save_arq_dma_handle; 3428 cmd->cmd_arq_buf = save_arq_bp; 3429 cmd->cmd_arqcookie = save_arqcookie; 3430 3431 pkt = (void *)((uchar_t *)cmd + 3432 sizeof (struct mptsas_cmd)); 3433 pkt->pkt_ha_private = (opaque_t)cmd; 3434 pkt->pkt_address = *ap; 3435 pkt->pkt_private = (opaque_t)cmd->cmd_pkt_private; 3436 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; 3437 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb; 3438 cmd->cmd_pkt = (struct scsi_pkt *)pkt; 3439 cmd->cmd_cdblen = (uchar_t)cmdlen; 3440 cmd->cmd_scblen = statuslen; 3441 cmd->cmd_rqslen = SENSE_LENGTH; 3442 cmd->cmd_tgt_addr = ptgt; 3443 failure = 0; 3444 } 3445 3446 if (failure || (cmdlen > sizeof (cmd->cmd_cdb)) || 3447 (tgtlen > PKT_PRIV_LEN) || 3448 (statuslen > EXTCMDS_STATUS_SIZE)) { 3449 if (failure == 0) { 3450 /* 3451 * if extern alloc fails, all will be 3452 * deallocated, including cmd 3453 */ 3454 failure = mptsas_pkt_alloc_extern(mpt, cmd, 3455 cmdlen, tgtlen, statuslen, kf); 3456 } 3457 if (failure) { 3458 /* 3459 * if extern allocation fails, it will 3460 * deallocate the new pkt as well 3461 */ 3462 return (NULL); 3463 } 3464 } 3465 new_cmd = cmd; 3466 3467 } else { 3468 cmd = PKT2CMD(pkt); 3469 new_cmd = NULL; 3470 } 3471 3472 3473 /* grab cmd->cmd_cookiec here as oldcookiec */ 3474 3475 oldcookiec = cmd->cmd_cookiec; 3476 3477 /* 3478 * If the dma was broken up into PARTIAL transfers cmd_nwin will be 3479 * greater than 0 and we'll need to grab the next dma window 3480 */ 3481 /* 3482 * SLM-not doing extra command frame right now; may add later 3483 */ 3484 3485 if (cmd->cmd_nwin > 0) { 3486 3487 /* 3488 * Make sure we havn't gone past the the total number 3489 * of windows 3490 */ 3491 if (++cmd->cmd_winindex >= cmd->cmd_nwin) { 3492 return (NULL); 3493 } 3494 if (ddi_dma_getwin(cmd->cmd_dmahandle, cmd->cmd_winindex, 3495 &cmd->cmd_dma_offset, &cmd->cmd_dma_len, 3496 &cmd->cmd_cookie, &cmd->cmd_cookiec) == DDI_FAILURE) { 3497 return (NULL); 3498 } 3499 goto get_dma_cookies; 3500 } 3501 3502 3503 if (flags & PKT_XARQ) { 3504 cmd->cmd_flags |= CFLAG_XARQ; 3505 } 3506 3507 /* 3508 * DMA resource allocation. This version assumes your 3509 * HBA has some sort of bus-mastering or onboard DMA capability, with a 3510 * scatter-gather list of length MPTSAS_MAX_DMA_SEGS, as given in the 3511 * ddi_dma_attr_t structure and passed to scsi_impl_dmaget. 3512 */ 3513 if (bp && (bp->b_bcount != 0) && 3514 (cmd->cmd_flags & CFLAG_DMAVALID) == 0) { 3515 3516 int cnt, dma_flags; 3517 mptti_t *dmap; /* ptr to the S/G list */ 3518 3519 /* 3520 * Set up DMA memory and position to the next DMA segment. 3521 */ 3522 ASSERT(cmd->cmd_dmahandle != NULL); 3523 3524 if (bp->b_flags & B_READ) { 3525 dma_flags = DDI_DMA_READ; 3526 cmd->cmd_flags &= ~CFLAG_DMASEND; 3527 } else { 3528 dma_flags = DDI_DMA_WRITE; 3529 cmd->cmd_flags |= CFLAG_DMASEND; 3530 } 3531 if (flags & PKT_CONSISTENT) { 3532 cmd->cmd_flags |= CFLAG_CMDIOPB; 3533 dma_flags |= DDI_DMA_CONSISTENT; 3534 } 3535 3536 if (flags & PKT_DMA_PARTIAL) { 3537 dma_flags |= DDI_DMA_PARTIAL; 3538 } 3539 3540 /* 3541 * workaround for byte hole issue on psycho and 3542 * schizo pre 2.1 3543 */ 3544 if ((bp->b_flags & B_READ) && ((bp->b_flags & 3545 (B_PAGEIO|B_REMAPPED)) != B_PAGEIO) && 3546 ((uintptr_t)bp->b_un.b_addr & 0x7)) { 3547 dma_flags |= DDI_DMA_CONSISTENT; 3548 } 3549 3550 rval = ddi_dma_buf_bind_handle(cmd->cmd_dmahandle, bp, 3551 dma_flags, callback, arg, 3552 &cmd->cmd_cookie, &cmd->cmd_cookiec); 3553 if (rval == DDI_DMA_PARTIAL_MAP) { 3554 (void) ddi_dma_numwin(cmd->cmd_dmahandle, 3555 &cmd->cmd_nwin); 3556 cmd->cmd_winindex = 0; 3557 (void) ddi_dma_getwin(cmd->cmd_dmahandle, 3558 cmd->cmd_winindex, &cmd->cmd_dma_offset, 3559 &cmd->cmd_dma_len, &cmd->cmd_cookie, 3560 &cmd->cmd_cookiec); 3561 } else if (rval && (rval != DDI_DMA_MAPPED)) { 3562 switch (rval) { 3563 case DDI_DMA_NORESOURCES: 3564 bioerror(bp, 0); 3565 break; 3566 case DDI_DMA_BADATTR: 3567 case DDI_DMA_NOMAPPING: 3568 bioerror(bp, EFAULT); 3569 break; 3570 case DDI_DMA_TOOBIG: 3571 default: 3572 bioerror(bp, EINVAL); 3573 break; 3574 } 3575 cmd->cmd_flags &= ~CFLAG_DMAVALID; 3576 if (new_cmd) { 3577 mptsas_scsi_destroy_pkt(ap, pkt); 3578 } 3579 return ((struct scsi_pkt *)NULL); 3580 } 3581 3582 get_dma_cookies: 3583 cmd->cmd_flags |= CFLAG_DMAVALID; 3584 ASSERT(cmd->cmd_cookiec > 0); 3585 3586 if (cmd->cmd_cookiec > MPTSAS_MAX_CMD_SEGS) { 3587 mptsas_log(mpt, CE_NOTE, "large cookiec received %d\n", 3588 cmd->cmd_cookiec); 3589 bioerror(bp, EINVAL); 3590 if (new_cmd) { 3591 mptsas_scsi_destroy_pkt(ap, pkt); 3592 } 3593 return ((struct scsi_pkt *)NULL); 3594 } 3595 3596 /* 3597 * Allocate extra SGL buffer if needed. 3598 */ 3599 if ((cmd->cmd_cookiec > MPTSAS_MAX_FRAME_SGES64(mpt)) && 3600 (cmd->cmd_extra_frames == NULL)) { 3601 if (mptsas_alloc_extra_sgl_frame(mpt, cmd) == 3602 DDI_FAILURE) { 3603 mptsas_log(mpt, CE_WARN, "MPT SGL mem alloc " 3604 "failed"); 3605 bioerror(bp, ENOMEM); 3606 if (new_cmd) { 3607 mptsas_scsi_destroy_pkt(ap, pkt); 3608 } 3609 return ((struct scsi_pkt *)NULL); 3610 } 3611 } 3612 3613 /* 3614 * Always use scatter-gather transfer 3615 * Use the loop below to store physical addresses of 3616 * DMA segments, from the DMA cookies, into your HBA's 3617 * scatter-gather list. 3618 * We need to ensure we have enough kmem alloc'd 3619 * for the sg entries since we are no longer using an 3620 * array inside mptsas_cmd_t. 3621 * 3622 * We check cmd->cmd_cookiec against oldcookiec so 3623 * the scatter-gather list is correctly allocated 3624 */ 3625 3626 if (oldcookiec != cmd->cmd_cookiec) { 3627 if (cmd->cmd_sg != (mptti_t *)NULL) { 3628 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * 3629 oldcookiec); 3630 cmd->cmd_sg = NULL; 3631 } 3632 } 3633 3634 if (cmd->cmd_sg == (mptti_t *)NULL) { 3635 cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)* 3636 cmd->cmd_cookiec), kf); 3637 3638 if (cmd->cmd_sg == (mptti_t *)NULL) { 3639 mptsas_log(mpt, CE_WARN, 3640 "unable to kmem_alloc enough memory " 3641 "for scatter/gather list"); 3642 /* 3643 * if we have an ENOMEM condition we need to behave 3644 * the same way as the rest of this routine 3645 */ 3646 3647 bioerror(bp, ENOMEM); 3648 if (new_cmd) { 3649 mptsas_scsi_destroy_pkt(ap, pkt); 3650 } 3651 return ((struct scsi_pkt *)NULL); 3652 } 3653 } 3654 3655 dmap = cmd->cmd_sg; 3656 3657 ASSERT(cmd->cmd_cookie.dmac_size != 0); 3658 3659 /* 3660 * store the first segment into the S/G list 3661 */ 3662 dmap->count = cmd->cmd_cookie.dmac_size; 3663 dmap->addr.address64.Low = (uint32_t) 3664 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull); 3665 dmap->addr.address64.High = (uint32_t) 3666 (cmd->cmd_cookie.dmac_laddress >> 32); 3667 3668 /* 3669 * dmacount counts the size of the dma for this window 3670 * (if partial dma is being used). totaldmacount 3671 * keeps track of the total amount of dma we have 3672 * transferred for all the windows (needed to calculate 3673 * the resid value below). 3674 */ 3675 cmd->cmd_dmacount = cmd->cmd_cookie.dmac_size; 3676 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size; 3677 3678 /* 3679 * We already stored the first DMA scatter gather segment, 3680 * start at 1 if we need to store more. 3681 */ 3682 for (cnt = 1; cnt < cmd->cmd_cookiec; cnt++) { 3683 /* 3684 * Get next DMA cookie 3685 */ 3686 ddi_dma_nextcookie(cmd->cmd_dmahandle, 3687 &cmd->cmd_cookie); 3688 dmap++; 3689 3690 cmd->cmd_dmacount += cmd->cmd_cookie.dmac_size; 3691 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size; 3692 3693 /* 3694 * store the segment parms into the S/G list 3695 */ 3696 dmap->count = cmd->cmd_cookie.dmac_size; 3697 dmap->addr.address64.Low = (uint32_t) 3698 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull); 3699 dmap->addr.address64.High = (uint32_t) 3700 (cmd->cmd_cookie.dmac_laddress >> 32); 3701 } 3702 3703 /* 3704 * If this was partially allocated we set the resid 3705 * the amount of data NOT transferred in this window 3706 * If there is only one window, the resid will be 0 3707 */ 3708 pkt->pkt_resid = (bp->b_bcount - cmd->cmd_totaldmacount); 3709 NDBG16(("mptsas_dmaget: cmd_dmacount=%d.", cmd->cmd_dmacount)); 3710 } 3711 return (pkt); 3712 } 3713 3714 /* 3715 * tran_destroy_pkt(9E) - scsi_pkt(9s) deallocation 3716 * 3717 * Notes: 3718 * - also frees DMA resources if allocated 3719 * - implicit DMA synchonization 3720 */ 3721 static void 3722 mptsas_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 3723 { 3724 mptsas_cmd_t *cmd = PKT2CMD(pkt); 3725 mptsas_t *mpt = ADDR2MPT(ap); 3726 3727 NDBG3(("mptsas_scsi_destroy_pkt: target=%d pkt=0x%p", 3728 ap->a_target, (void *)pkt)); 3729 3730 if (cmd->cmd_flags & CFLAG_DMAVALID) { 3731 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle); 3732 cmd->cmd_flags &= ~CFLAG_DMAVALID; 3733 } 3734 3735 if (cmd->cmd_sg) { 3736 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * cmd->cmd_cookiec); 3737 cmd->cmd_sg = NULL; 3738 } 3739 3740 mptsas_free_extra_sgl_frame(mpt, cmd); 3741 3742 if ((cmd->cmd_flags & 3743 (CFLAG_FREE | CFLAG_CDBEXTERN | CFLAG_PRIVEXTERN | 3744 CFLAG_SCBEXTERN)) == 0) { 3745 cmd->cmd_flags = CFLAG_FREE; 3746 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd); 3747 } else { 3748 mptsas_pkt_destroy_extern(mpt, cmd); 3749 } 3750 } 3751 3752 /* 3753 * kmem cache constructor and destructor: 3754 * When constructing, we bzero the cmd and allocate the dma handle 3755 * When destructing, just free the dma handle 3756 */ 3757 static int 3758 mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags) 3759 { 3760 mptsas_cmd_t *cmd = buf; 3761 mptsas_t *mpt = cdrarg; 3762 struct scsi_address ap; 3763 uint_t cookiec; 3764 ddi_dma_attr_t arq_dma_attr; 3765 int (*callback)(caddr_t); 3766 3767 callback = (kmflags == KM_SLEEP)? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT; 3768 3769 NDBG4(("mptsas_kmem_cache_constructor")); 3770 3771 ap.a_hba_tran = mpt->m_tran; 3772 ap.a_target = 0; 3773 ap.a_lun = 0; 3774 3775 /* 3776 * allocate a dma handle 3777 */ 3778 if ((ddi_dma_alloc_handle(mpt->m_dip, &mpt->m_io_dma_attr, callback, 3779 NULL, &cmd->cmd_dmahandle)) != DDI_SUCCESS) { 3780 cmd->cmd_dmahandle = NULL; 3781 return (-1); 3782 } 3783 3784 cmd->cmd_arq_buf = scsi_alloc_consistent_buf(&ap, (struct buf *)NULL, 3785 SENSE_LENGTH, B_READ, callback, NULL); 3786 if (cmd->cmd_arq_buf == NULL) { 3787 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3788 cmd->cmd_dmahandle = NULL; 3789 return (-1); 3790 } 3791 3792 /* 3793 * allocate a arq handle 3794 */ 3795 arq_dma_attr = mpt->m_msg_dma_attr; 3796 arq_dma_attr.dma_attr_sgllen = 1; 3797 if ((ddi_dma_alloc_handle(mpt->m_dip, &arq_dma_attr, callback, 3798 NULL, &cmd->cmd_arqhandle)) != DDI_SUCCESS) { 3799 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3800 scsi_free_consistent_buf(cmd->cmd_arq_buf); 3801 cmd->cmd_dmahandle = NULL; 3802 cmd->cmd_arqhandle = NULL; 3803 return (-1); 3804 } 3805 3806 if (ddi_dma_buf_bind_handle(cmd->cmd_arqhandle, 3807 cmd->cmd_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT), 3808 callback, NULL, &cmd->cmd_arqcookie, &cookiec) != DDI_SUCCESS) { 3809 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3810 ddi_dma_free_handle(&cmd->cmd_arqhandle); 3811 scsi_free_consistent_buf(cmd->cmd_arq_buf); 3812 cmd->cmd_dmahandle = NULL; 3813 cmd->cmd_arqhandle = NULL; 3814 cmd->cmd_arq_buf = NULL; 3815 return (-1); 3816 } 3817 3818 return (0); 3819 } 3820 3821 static void 3822 mptsas_kmem_cache_destructor(void *buf, void *cdrarg) 3823 { 3824 #ifndef __lock_lint 3825 _NOTE(ARGUNUSED(cdrarg)) 3826 #endif 3827 mptsas_cmd_t *cmd = buf; 3828 3829 NDBG4(("mptsas_kmem_cache_destructor")); 3830 3831 if (cmd->cmd_arqhandle) { 3832 (void) ddi_dma_unbind_handle(cmd->cmd_arqhandle); 3833 ddi_dma_free_handle(&cmd->cmd_arqhandle); 3834 cmd->cmd_arqhandle = NULL; 3835 } 3836 if (cmd->cmd_arq_buf) { 3837 scsi_free_consistent_buf(cmd->cmd_arq_buf); 3838 cmd->cmd_arq_buf = NULL; 3839 } 3840 if (cmd->cmd_dmahandle) { 3841 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3842 cmd->cmd_dmahandle = NULL; 3843 } 3844 } 3845 3846 static int 3847 mptsas_cache_frames_constructor(void *buf, void *cdrarg, int kmflags) 3848 { 3849 mptsas_cache_frames_t *p = buf; 3850 mptsas_t *mpt = cdrarg; 3851 ddi_dma_attr_t frame_dma_attr; 3852 size_t mem_size, alloc_len; 3853 ddi_dma_cookie_t cookie; 3854 uint_t ncookie; 3855 int (*callback)(caddr_t) = (kmflags == KM_SLEEP) 3856 ? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT; 3857 3858 frame_dma_attr = mpt->m_msg_dma_attr; 3859 frame_dma_attr.dma_attr_align = 0x10; 3860 frame_dma_attr.dma_attr_sgllen = 1; 3861 3862 if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attr, callback, NULL, 3863 &p->m_dma_hdl) != DDI_SUCCESS) { 3864 mptsas_log(mpt, CE_WARN, "Unable to allocate dma handle for" 3865 " extra SGL."); 3866 return (DDI_FAILURE); 3867 } 3868 3869 mem_size = (mpt->m_max_request_frames - 1) * mpt->m_req_frame_size; 3870 3871 if (ddi_dma_mem_alloc(p->m_dma_hdl, mem_size, &mpt->m_dev_acc_attr, 3872 DDI_DMA_CONSISTENT, callback, NULL, (caddr_t *)&p->m_frames_addr, 3873 &alloc_len, &p->m_acc_hdl) != DDI_SUCCESS) { 3874 ddi_dma_free_handle(&p->m_dma_hdl); 3875 p->m_dma_hdl = NULL; 3876 mptsas_log(mpt, CE_WARN, "Unable to allocate dma memory for" 3877 " extra SGL."); 3878 return (DDI_FAILURE); 3879 } 3880 3881 if (ddi_dma_addr_bind_handle(p->m_dma_hdl, NULL, p->m_frames_addr, 3882 alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, callback, NULL, 3883 &cookie, &ncookie) != DDI_DMA_MAPPED) { 3884 (void) ddi_dma_mem_free(&p->m_acc_hdl); 3885 ddi_dma_free_handle(&p->m_dma_hdl); 3886 p->m_dma_hdl = NULL; 3887 mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources for" 3888 " extra SGL"); 3889 return (DDI_FAILURE); 3890 } 3891 3892 /* 3893 * Store the SGL memory address. This chip uses this 3894 * address to dma to and from the driver. The second 3895 * address is the address mpt uses to fill in the SGL. 3896 */ 3897 p->m_phys_addr = cookie.dmac_address; 3898 3899 return (DDI_SUCCESS); 3900 } 3901 3902 static void 3903 mptsas_cache_frames_destructor(void *buf, void *cdrarg) 3904 { 3905 #ifndef __lock_lint 3906 _NOTE(ARGUNUSED(cdrarg)) 3907 #endif 3908 mptsas_cache_frames_t *p = buf; 3909 if (p->m_dma_hdl != NULL) { 3910 (void) ddi_dma_unbind_handle(p->m_dma_hdl); 3911 (void) ddi_dma_mem_free(&p->m_acc_hdl); 3912 ddi_dma_free_handle(&p->m_dma_hdl); 3913 p->m_phys_addr = NULL; 3914 p->m_frames_addr = NULL; 3915 p->m_dma_hdl = NULL; 3916 p->m_acc_hdl = NULL; 3917 } 3918 3919 } 3920 3921 /* 3922 * allocate and deallocate external pkt space (ie. not part of mptsas_cmd) 3923 * for non-standard length cdb, pkt_private, status areas 3924 * if allocation fails, then deallocate all external space and the pkt 3925 */ 3926 /* ARGSUSED */ 3927 static int 3928 mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd, 3929 int cmdlen, int tgtlen, int statuslen, int kf) 3930 { 3931 caddr_t cdbp, scbp, tgt; 3932 int (*callback)(caddr_t) = (kf == KM_SLEEP) ? 3933 DDI_DMA_SLEEP : DDI_DMA_DONTWAIT; 3934 struct scsi_address ap; 3935 size_t senselength; 3936 ddi_dma_attr_t ext_arq_dma_attr; 3937 uint_t cookiec; 3938 3939 NDBG3(("mptsas_pkt_alloc_extern: " 3940 "cmd=0x%p cmdlen=%d tgtlen=%d statuslen=%d kf=%x", 3941 (void *)cmd, cmdlen, tgtlen, statuslen, kf)); 3942 3943 tgt = cdbp = scbp = NULL; 3944 cmd->cmd_scblen = statuslen; 3945 cmd->cmd_privlen = (uchar_t)tgtlen; 3946 3947 if (cmdlen > sizeof (cmd->cmd_cdb)) { 3948 if ((cdbp = kmem_zalloc((size_t)cmdlen, kf)) == NULL) { 3949 goto fail; 3950 } 3951 cmd->cmd_pkt->pkt_cdbp = (opaque_t)cdbp; 3952 cmd->cmd_flags |= CFLAG_CDBEXTERN; 3953 } 3954 if (tgtlen > PKT_PRIV_LEN) { 3955 if ((tgt = kmem_zalloc((size_t)tgtlen, kf)) == NULL) { 3956 goto fail; 3957 } 3958 cmd->cmd_flags |= CFLAG_PRIVEXTERN; 3959 cmd->cmd_pkt->pkt_private = tgt; 3960 } 3961 if (statuslen > EXTCMDS_STATUS_SIZE) { 3962 if ((scbp = kmem_zalloc((size_t)statuslen, kf)) == NULL) { 3963 goto fail; 3964 } 3965 cmd->cmd_flags |= CFLAG_SCBEXTERN; 3966 cmd->cmd_pkt->pkt_scbp = (opaque_t)scbp; 3967 3968 /* allocate sense data buf for DMA */ 3969 3970 senselength = statuslen - MPTSAS_GET_ITEM_OFF( 3971 struct scsi_arq_status, sts_sensedata); 3972 cmd->cmd_rqslen = (uchar_t)senselength; 3973 3974 ap.a_hba_tran = mpt->m_tran; 3975 ap.a_target = 0; 3976 ap.a_lun = 0; 3977 3978 cmd->cmd_ext_arq_buf = scsi_alloc_consistent_buf(&ap, 3979 (struct buf *)NULL, senselength, B_READ, 3980 callback, NULL); 3981 3982 if (cmd->cmd_ext_arq_buf == NULL) { 3983 goto fail; 3984 } 3985 /* 3986 * allocate a extern arq handle and bind the buf 3987 */ 3988 ext_arq_dma_attr = mpt->m_msg_dma_attr; 3989 ext_arq_dma_attr.dma_attr_sgllen = 1; 3990 if ((ddi_dma_alloc_handle(mpt->m_dip, 3991 &ext_arq_dma_attr, callback, 3992 NULL, &cmd->cmd_ext_arqhandle)) != DDI_SUCCESS) { 3993 goto fail; 3994 } 3995 3996 if (ddi_dma_buf_bind_handle(cmd->cmd_ext_arqhandle, 3997 cmd->cmd_ext_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT), 3998 callback, NULL, &cmd->cmd_ext_arqcookie, 3999 &cookiec) 4000 != DDI_SUCCESS) { 4001 goto fail; 4002 } 4003 cmd->cmd_flags |= CFLAG_EXTARQBUFVALID; 4004 } 4005 return (0); 4006 fail: 4007 mptsas_pkt_destroy_extern(mpt, cmd); 4008 return (1); 4009 } 4010 4011 /* 4012 * deallocate external pkt space and deallocate the pkt 4013 */ 4014 static void 4015 mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd) 4016 { 4017 NDBG3(("mptsas_pkt_destroy_extern: cmd=0x%p", (void *)cmd)); 4018 4019 if (cmd->cmd_flags & CFLAG_FREE) { 4020 mptsas_log(mpt, CE_PANIC, 4021 "mptsas_pkt_destroy_extern: freeing free packet"); 4022 _NOTE(NOT_REACHED) 4023 /* NOTREACHED */ 4024 } 4025 if (cmd->cmd_flags & CFLAG_CDBEXTERN) { 4026 kmem_free(cmd->cmd_pkt->pkt_cdbp, (size_t)cmd->cmd_cdblen); 4027 } 4028 if (cmd->cmd_flags & CFLAG_SCBEXTERN) { 4029 kmem_free(cmd->cmd_pkt->pkt_scbp, (size_t)cmd->cmd_scblen); 4030 if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) { 4031 (void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle); 4032 } 4033 if (cmd->cmd_ext_arqhandle) { 4034 ddi_dma_free_handle(&cmd->cmd_ext_arqhandle); 4035 cmd->cmd_ext_arqhandle = NULL; 4036 } 4037 if (cmd->cmd_ext_arq_buf) 4038 scsi_free_consistent_buf(cmd->cmd_ext_arq_buf); 4039 } 4040 if (cmd->cmd_flags & CFLAG_PRIVEXTERN) { 4041 kmem_free(cmd->cmd_pkt->pkt_private, (size_t)cmd->cmd_privlen); 4042 } 4043 cmd->cmd_flags = CFLAG_FREE; 4044 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd); 4045 } 4046 4047 /* 4048 * tran_sync_pkt(9E) - explicit DMA synchronization 4049 */ 4050 /*ARGSUSED*/ 4051 static void 4052 mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 4053 { 4054 mptsas_cmd_t *cmd = PKT2CMD(pkt); 4055 4056 NDBG3(("mptsas_scsi_sync_pkt: target=%d, pkt=0x%p", 4057 ap->a_target, (void *)pkt)); 4058 4059 if (cmd->cmd_dmahandle) { 4060 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 4061 (cmd->cmd_flags & CFLAG_DMASEND) ? 4062 DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU); 4063 } 4064 } 4065 4066 /* 4067 * tran_dmafree(9E) - deallocate DMA resources allocated for command 4068 */ 4069 /*ARGSUSED*/ 4070 static void 4071 mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt) 4072 { 4073 mptsas_cmd_t *cmd = PKT2CMD(pkt); 4074 mptsas_t *mpt = ADDR2MPT(ap); 4075 4076 NDBG3(("mptsas_scsi_dmafree: target=%d pkt=0x%p", 4077 ap->a_target, (void *)pkt)); 4078 4079 if (cmd->cmd_flags & CFLAG_DMAVALID) { 4080 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle); 4081 cmd->cmd_flags &= ~CFLAG_DMAVALID; 4082 } 4083 4084 if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) { 4085 (void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle); 4086 cmd->cmd_flags &= ~CFLAG_EXTARQBUFVALID; 4087 } 4088 4089 mptsas_free_extra_sgl_frame(mpt, cmd); 4090 } 4091 4092 static void 4093 mptsas_pkt_comp(struct scsi_pkt *pkt, mptsas_cmd_t *cmd) 4094 { 4095 if ((cmd->cmd_flags & CFLAG_CMDIOPB) && 4096 (!(cmd->cmd_flags & CFLAG_DMASEND))) { 4097 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 4098 DDI_DMA_SYNC_FORCPU); 4099 } 4100 (*pkt->pkt_comp)(pkt); 4101 } 4102 4103 static void 4104 mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, uint32_t *control, 4105 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl) 4106 { 4107 uint_t cookiec; 4108 mptti_t *dmap; 4109 uint32_t flags; 4110 pMpi2SGESimple64_t sge; 4111 pMpi2SGEChain64_t sgechain; 4112 ASSERT(cmd->cmd_flags & CFLAG_DMAVALID); 4113 4114 /* 4115 * Save the number of entries in the DMA 4116 * Scatter/Gather list 4117 */ 4118 cookiec = cmd->cmd_cookiec; 4119 4120 NDBG1(("mptsas_sge_setup: cookiec=%d", cookiec)); 4121 4122 /* 4123 * Set read/write bit in control. 4124 */ 4125 if (cmd->cmd_flags & CFLAG_DMASEND) { 4126 *control |= MPI2_SCSIIO_CONTROL_WRITE; 4127 } else { 4128 *control |= MPI2_SCSIIO_CONTROL_READ; 4129 } 4130 4131 ddi_put32(acc_hdl, &frame->DataLength, cmd->cmd_dmacount); 4132 4133 /* 4134 * We have 2 cases here. First where we can fit all the 4135 * SG elements into the main frame, and the case 4136 * where we can't. 4137 * If we have more cookies than we can attach to a frame 4138 * we will need to use a chain element to point 4139 * a location of memory where the rest of the S/G 4140 * elements reside. 4141 */ 4142 if (cookiec <= MPTSAS_MAX_FRAME_SGES64(mpt)) { 4143 dmap = cmd->cmd_sg; 4144 sge = (pMpi2SGESimple64_t)(&frame->SGL); 4145 while (cookiec--) { 4146 ddi_put32(acc_hdl, 4147 &sge->Address.Low, dmap->addr.address64.Low); 4148 ddi_put32(acc_hdl, 4149 &sge->Address.High, dmap->addr.address64.High); 4150 ddi_put32(acc_hdl, &sge->FlagsLength, 4151 dmap->count); 4152 flags = ddi_get32(acc_hdl, &sge->FlagsLength); 4153 flags |= ((uint32_t) 4154 (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4155 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4156 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4157 MPI2_SGE_FLAGS_SHIFT); 4158 4159 /* 4160 * If this is the last cookie, we set the flags 4161 * to indicate so 4162 */ 4163 if (cookiec == 0) { 4164 flags |= 4165 ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT 4166 | MPI2_SGE_FLAGS_END_OF_BUFFER 4167 | MPI2_SGE_FLAGS_END_OF_LIST) << 4168 MPI2_SGE_FLAGS_SHIFT); 4169 } 4170 if (cmd->cmd_flags & CFLAG_DMASEND) { 4171 flags |= (MPI2_SGE_FLAGS_HOST_TO_IOC << 4172 MPI2_SGE_FLAGS_SHIFT); 4173 } else { 4174 flags |= (MPI2_SGE_FLAGS_IOC_TO_HOST << 4175 MPI2_SGE_FLAGS_SHIFT); 4176 } 4177 ddi_put32(acc_hdl, &sge->FlagsLength, flags); 4178 dmap++; 4179 sge++; 4180 } 4181 } else { 4182 /* 4183 * Hereby we start to deal with multiple frames. 4184 * The process is as follows: 4185 * 1. Determine how many frames are needed for SGL element 4186 * storage; Note that all frames are stored in contiguous 4187 * memory space and in 64-bit DMA mode each element is 4188 * 3 double-words (12 bytes) long. 4189 * 2. Fill up the main frame. We need to do this separately 4190 * since it contains the SCSI IO request header and needs 4191 * dedicated processing. Note that the last 4 double-words 4192 * of the SCSI IO header is for SGL element storage 4193 * (MPI2_SGE_IO_UNION). 4194 * 3. Fill the chain element in the main frame, so the DMA 4195 * engine can use the following frames. 4196 * 4. Enter a loop to fill the remaining frames. Note that the 4197 * last frame contains no chain element. The remaining 4198 * frames go into the mpt SGL buffer allocated on the fly, 4199 * not immediately following the main message frame, as in 4200 * Gen1. 4201 * Some restrictions: 4202 * 1. For 64-bit DMA, the simple element and chain element 4203 * are both of 3 double-words (12 bytes) in size, even 4204 * though all frames are stored in the first 4G of mem 4205 * range and the higher 32-bits of the address are always 0. 4206 * 2. On some controllers (like the 1064/1068), a frame can 4207 * hold SGL elements with the last 1 or 2 double-words 4208 * (4 or 8 bytes) un-used. On these controllers, we should 4209 * recognize that there's not enough room for another SGL 4210 * element and move the sge pointer to the next frame. 4211 */ 4212 int i, j, k, l, frames, sgemax; 4213 int temp; 4214 uint8_t chainflags; 4215 uint16_t chainlength; 4216 mptsas_cache_frames_t *p; 4217 4218 /* 4219 * Sgemax is the number of SGE's that will fit 4220 * each extra frame and frames is total 4221 * number of frames we'll need. 1 sge entry per 4222 * frame is reseverd for the chain element thus the -1 below. 4223 */ 4224 sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_SGE_SIMPLE64)) 4225 - 1); 4226 temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax; 4227 4228 /* 4229 * A little check to see if we need to round up the number 4230 * of frames we need 4231 */ 4232 if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp * 4233 sgemax) > 1) { 4234 frames = (temp + 1); 4235 } else { 4236 frames = temp; 4237 } 4238 dmap = cmd->cmd_sg; 4239 sge = (pMpi2SGESimple64_t)(&frame->SGL); 4240 4241 /* 4242 * First fill in the main frame 4243 */ 4244 for (j = 1; j < MPTSAS_MAX_FRAME_SGES64(mpt); j++) { 4245 ddi_put32(acc_hdl, &sge->Address.Low, 4246 dmap->addr.address64.Low); 4247 ddi_put32(acc_hdl, &sge->Address.High, 4248 dmap->addr.address64.High); 4249 ddi_put32(acc_hdl, &sge->FlagsLength, dmap->count); 4250 flags = ddi_get32(acc_hdl, &sge->FlagsLength); 4251 flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4252 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4253 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4254 MPI2_SGE_FLAGS_SHIFT); 4255 4256 /* 4257 * If this is the last SGE of this frame 4258 * we set the end of list flag 4259 */ 4260 if (j == (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) { 4261 flags |= ((uint32_t) 4262 (MPI2_SGE_FLAGS_LAST_ELEMENT) << 4263 MPI2_SGE_FLAGS_SHIFT); 4264 } 4265 if (cmd->cmd_flags & CFLAG_DMASEND) { 4266 flags |= 4267 (MPI2_SGE_FLAGS_HOST_TO_IOC << 4268 MPI2_SGE_FLAGS_SHIFT); 4269 } else { 4270 flags |= 4271 (MPI2_SGE_FLAGS_IOC_TO_HOST << 4272 MPI2_SGE_FLAGS_SHIFT); 4273 } 4274 ddi_put32(acc_hdl, &sge->FlagsLength, flags); 4275 dmap++; 4276 sge++; 4277 } 4278 4279 /* 4280 * Fill in the chain element in the main frame. 4281 * About calculation on ChainOffset: 4282 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes) 4283 * in the end reserved for SGL element storage 4284 * (MPI2_SGE_IO_UNION); we should count it in our 4285 * calculation. See its definition in the header file. 4286 * 2. Constant j is the counter of the current SGL element 4287 * that will be processed, and (j - 1) is the number of 4288 * SGL elements that have been processed (stored in the 4289 * main frame). 4290 * 3. ChainOffset value should be in units of double-words (4 4291 * bytes) so the last value should be divided by 4. 4292 */ 4293 ddi_put8(acc_hdl, &frame->ChainOffset, 4294 (sizeof (MPI2_SCSI_IO_REQUEST) - 4295 sizeof (MPI2_SGE_IO_UNION) + 4296 (j - 1) * sizeof (MPI2_SGE_SIMPLE64)) >> 2); 4297 sgechain = (pMpi2SGEChain64_t)sge; 4298 chainflags = (MPI2_SGE_FLAGS_CHAIN_ELEMENT | 4299 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4300 MPI2_SGE_FLAGS_64_BIT_ADDRESSING); 4301 ddi_put8(acc_hdl, &sgechain->Flags, chainflags); 4302 4303 /* 4304 * The size of the next frame is the accurate size of space 4305 * (in bytes) used to store the SGL elements. j is the counter 4306 * of SGL elements. (j - 1) is the number of SGL elements that 4307 * have been processed (stored in frames). 4308 */ 4309 if (frames >= 2) { 4310 chainlength = mpt->m_req_frame_size / 4311 sizeof (MPI2_SGE_SIMPLE64) * 4312 sizeof (MPI2_SGE_SIMPLE64); 4313 } else { 4314 chainlength = ((cookiec - (j - 1)) * 4315 sizeof (MPI2_SGE_SIMPLE64)); 4316 } 4317 4318 p = cmd->cmd_extra_frames; 4319 4320 ddi_put16(acc_hdl, &sgechain->Length, chainlength); 4321 ddi_put32(acc_hdl, &sgechain->Address.Low, 4322 p->m_phys_addr); 4323 /* SGL is allocated in the first 4G mem range */ 4324 ddi_put32(acc_hdl, &sgechain->Address.High, 0); 4325 4326 /* 4327 * If there are more than 2 frames left we have to 4328 * fill in the next chain offset to the location of 4329 * the chain element in the next frame. 4330 * sgemax is the number of simple elements in an extra 4331 * frame. Note that the value NextChainOffset should be 4332 * in double-words (4 bytes). 4333 */ 4334 if (frames >= 2) { 4335 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 4336 (sgemax * sizeof (MPI2_SGE_SIMPLE64)) >> 2); 4337 } else { 4338 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 0); 4339 } 4340 4341 /* 4342 * Jump to next frame; 4343 * Starting here, chain buffers go into the per command SGL. 4344 * This buffer is allocated when chain buffers are needed. 4345 */ 4346 sge = (pMpi2SGESimple64_t)p->m_frames_addr; 4347 i = cookiec; 4348 4349 /* 4350 * Start filling in frames with SGE's. If we 4351 * reach the end of frame and still have SGE's 4352 * to fill we need to add a chain element and 4353 * use another frame. j will be our counter 4354 * for what cookie we are at and i will be 4355 * the total cookiec. k is the current frame 4356 */ 4357 for (k = 1; k <= frames; k++) { 4358 for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) { 4359 4360 /* 4361 * If we have reached the end of frame 4362 * and we have more SGE's to fill in 4363 * we have to fill the final entry 4364 * with a chain element and then 4365 * continue to the next frame 4366 */ 4367 if ((l == (sgemax + 1)) && (k != frames)) { 4368 sgechain = (pMpi2SGEChain64_t)sge; 4369 j--; 4370 chainflags = ( 4371 MPI2_SGE_FLAGS_CHAIN_ELEMENT | 4372 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4373 MPI2_SGE_FLAGS_64_BIT_ADDRESSING); 4374 ddi_put8(p->m_acc_hdl, 4375 &sgechain->Flags, chainflags); 4376 /* 4377 * k is the frame counter and (k + 1) 4378 * is the number of the next frame. 4379 * Note that frames are in contiguous 4380 * memory space. 4381 */ 4382 ddi_put32(p->m_acc_hdl, 4383 &sgechain->Address.Low, 4384 (p->m_phys_addr + 4385 (mpt->m_req_frame_size * k))); 4386 ddi_put32(p->m_acc_hdl, 4387 &sgechain->Address.High, 0); 4388 4389 /* 4390 * If there are more than 2 frames left 4391 * we have to next chain offset to 4392 * the location of the chain element 4393 * in the next frame and fill in the 4394 * length of the next chain 4395 */ 4396 if ((frames - k) >= 2) { 4397 ddi_put8(p->m_acc_hdl, 4398 &sgechain->NextChainOffset, 4399 (sgemax * 4400 sizeof (MPI2_SGE_SIMPLE64)) 4401 >> 2); 4402 ddi_put16(p->m_acc_hdl, 4403 &sgechain->Length, 4404 mpt->m_req_frame_size / 4405 sizeof (MPI2_SGE_SIMPLE64) * 4406 sizeof (MPI2_SGE_SIMPLE64)); 4407 } else { 4408 /* 4409 * This is the last frame. Set 4410 * the NextChainOffset to 0 and 4411 * Length is the total size of 4412 * all remaining simple elements 4413 */ 4414 ddi_put8(p->m_acc_hdl, 4415 &sgechain->NextChainOffset, 4416 0); 4417 ddi_put16(p->m_acc_hdl, 4418 &sgechain->Length, 4419 (cookiec - j) * 4420 sizeof (MPI2_SGE_SIMPLE64)); 4421 } 4422 4423 /* Jump to the next frame */ 4424 sge = (pMpi2SGESimple64_t) 4425 ((char *)p->m_frames_addr + 4426 (int)mpt->m_req_frame_size * k); 4427 4428 continue; 4429 } 4430 4431 ddi_put32(p->m_acc_hdl, 4432 &sge->Address.Low, 4433 dmap->addr.address64.Low); 4434 ddi_put32(p->m_acc_hdl, 4435 &sge->Address.High, 4436 dmap->addr.address64.High); 4437 ddi_put32(p->m_acc_hdl, 4438 &sge->FlagsLength, dmap->count); 4439 flags = ddi_get32(p->m_acc_hdl, 4440 &sge->FlagsLength); 4441 flags |= ((uint32_t)( 4442 MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4443 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4444 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4445 MPI2_SGE_FLAGS_SHIFT); 4446 4447 /* 4448 * If we are at the end of the frame and 4449 * there is another frame to fill in 4450 * we set the last simple element as last 4451 * element 4452 */ 4453 if ((l == sgemax) && (k != frames)) { 4454 flags |= ((uint32_t) 4455 (MPI2_SGE_FLAGS_LAST_ELEMENT) << 4456 MPI2_SGE_FLAGS_SHIFT); 4457 } 4458 4459 /* 4460 * If this is the final cookie we 4461 * indicate it by setting the flags 4462 */ 4463 if (j == i) { 4464 flags |= ((uint32_t) 4465 (MPI2_SGE_FLAGS_LAST_ELEMENT | 4466 MPI2_SGE_FLAGS_END_OF_BUFFER | 4467 MPI2_SGE_FLAGS_END_OF_LIST) << 4468 MPI2_SGE_FLAGS_SHIFT); 4469 } 4470 if (cmd->cmd_flags & CFLAG_DMASEND) { 4471 flags |= 4472 (MPI2_SGE_FLAGS_HOST_TO_IOC << 4473 MPI2_SGE_FLAGS_SHIFT); 4474 } else { 4475 flags |= 4476 (MPI2_SGE_FLAGS_IOC_TO_HOST << 4477 MPI2_SGE_FLAGS_SHIFT); 4478 } 4479 ddi_put32(p->m_acc_hdl, 4480 &sge->FlagsLength, flags); 4481 dmap++; 4482 sge++; 4483 } 4484 } 4485 4486 /* 4487 * Sync DMA with the chain buffers that were just created 4488 */ 4489 (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 4490 } 4491 } 4492 4493 /* 4494 * Interrupt handling 4495 * Utility routine. Poll for status of a command sent to HBA 4496 * without interrupts (a FLAG_NOINTR command). 4497 */ 4498 int 4499 mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime) 4500 { 4501 int rval = TRUE; 4502 4503 NDBG5(("mptsas_poll: cmd=0x%p", (void *)poll_cmd)); 4504 4505 if ((poll_cmd->cmd_flags & CFLAG_TM_CMD) == 0) { 4506 mptsas_restart_hba(mpt); 4507 } 4508 4509 /* 4510 * Wait, using drv_usecwait(), long enough for the command to 4511 * reasonably return from the target if the target isn't 4512 * "dead". A polled command may well be sent from scsi_poll, and 4513 * there are retries built in to scsi_poll if the transport 4514 * accepted the packet (TRAN_ACCEPT). scsi_poll waits 1 second 4515 * and retries the transport up to scsi_poll_busycnt times 4516 * (currently 60) if 4517 * 1. pkt_reason is CMD_INCOMPLETE and pkt_state is 0, or 4518 * 2. pkt_reason is CMD_CMPLT and *pkt_scbp has STATUS_BUSY 4519 * 4520 * limit the waiting to avoid a hang in the event that the 4521 * cmd never gets started but we are still receiving interrupts 4522 */ 4523 while (!(poll_cmd->cmd_flags & CFLAG_FINISHED)) { 4524 if (mptsas_wait_intr(mpt, polltime) == FALSE) { 4525 NDBG5(("mptsas_poll: command incomplete")); 4526 rval = FALSE; 4527 break; 4528 } 4529 } 4530 4531 if (rval == FALSE) { 4532 4533 /* 4534 * this isn't supposed to happen, the hba must be wedged 4535 * Mark this cmd as a timeout. 4536 */ 4537 mptsas_set_pkt_reason(mpt, poll_cmd, CMD_TIMEOUT, 4538 (STAT_TIMEOUT|STAT_ABORTED)); 4539 4540 if (poll_cmd->cmd_queued == FALSE) { 4541 4542 NDBG5(("mptsas_poll: not on waitq")); 4543 4544 poll_cmd->cmd_pkt->pkt_state |= 4545 (STATE_GOT_BUS|STATE_GOT_TARGET|STATE_SENT_CMD); 4546 } else { 4547 4548 /* find and remove it from the waitq */ 4549 NDBG5(("mptsas_poll: delete from waitq")); 4550 mptsas_waitq_delete(mpt, poll_cmd); 4551 } 4552 4553 } 4554 mptsas_fma_check(mpt, poll_cmd); 4555 NDBG5(("mptsas_poll: done")); 4556 return (rval); 4557 } 4558 4559 /* 4560 * Used for polling cmds and TM function 4561 */ 4562 static int 4563 mptsas_wait_intr(mptsas_t *mpt, int polltime) 4564 { 4565 int cnt; 4566 pMpi2ReplyDescriptorsUnion_t reply_desc_union; 4567 uint32_t int_mask; 4568 4569 NDBG5(("mptsas_wait_intr")); 4570 4571 mpt->m_polled_intr = 1; 4572 4573 /* 4574 * Get the current interrupt mask and disable interrupts. When 4575 * re-enabling ints, set mask to saved value. 4576 */ 4577 int_mask = ddi_get32(mpt->m_datap, &mpt->m_reg->HostInterruptMask); 4578 MPTSAS_DISABLE_INTR(mpt); 4579 4580 /* 4581 * Keep polling for at least (polltime * 1000) seconds 4582 */ 4583 for (cnt = 0; cnt < polltime; cnt++) { 4584 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 4585 DDI_DMA_SYNC_FORCPU); 4586 4587 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t) 4588 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index); 4589 4590 if (ddi_get32(mpt->m_acc_post_queue_hdl, 4591 &reply_desc_union->Words.Low) == 0xFFFFFFFF || 4592 ddi_get32(mpt->m_acc_post_queue_hdl, 4593 &reply_desc_union->Words.High) == 0xFFFFFFFF) { 4594 drv_usecwait(1000); 4595 continue; 4596 } 4597 4598 /* 4599 * The reply is valid, process it according to its 4600 * type. 4601 */ 4602 mptsas_process_intr(mpt, reply_desc_union); 4603 4604 if (++mpt->m_post_index == mpt->m_post_queue_depth) { 4605 mpt->m_post_index = 0; 4606 } 4607 4608 /* 4609 * Update the global reply index 4610 */ 4611 ddi_put32(mpt->m_datap, 4612 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); 4613 mpt->m_polled_intr = 0; 4614 4615 /* 4616 * Re-enable interrupts and quit. 4617 */ 4618 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, 4619 int_mask); 4620 return (TRUE); 4621 4622 } 4623 4624 /* 4625 * Clear polling flag, re-enable interrupts and quit. 4626 */ 4627 mpt->m_polled_intr = 0; 4628 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, int_mask); 4629 return (FALSE); 4630 } 4631 4632 static void 4633 mptsas_handle_scsi_io_success(mptsas_t *mpt, 4634 pMpi2ReplyDescriptorsUnion_t reply_desc) 4635 { 4636 pMpi2SCSIIOSuccessReplyDescriptor_t scsi_io_success; 4637 uint16_t SMID; 4638 mptsas_slots_t *slots = mpt->m_active; 4639 mptsas_cmd_t *cmd = NULL; 4640 struct scsi_pkt *pkt; 4641 4642 ASSERT(mutex_owned(&mpt->m_mutex)); 4643 4644 scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc; 4645 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &scsi_io_success->SMID); 4646 4647 /* 4648 * This is a success reply so just complete the IO. First, do a sanity 4649 * check on the SMID. The final slot is used for TM requests, which 4650 * would not come into this reply handler. 4651 */ 4652 if ((SMID == 0) || (SMID > slots->m_n_slots)) { 4653 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n", 4654 SMID); 4655 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 4656 return; 4657 } 4658 4659 cmd = slots->m_slot[SMID]; 4660 4661 /* 4662 * print warning and return if the slot is empty 4663 */ 4664 if (cmd == NULL) { 4665 mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO " 4666 "in slot %d", SMID); 4667 return; 4668 } 4669 4670 pkt = CMD2PKT(cmd); 4671 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD | 4672 STATE_GOT_STATUS); 4673 if (cmd->cmd_flags & CFLAG_DMAVALID) { 4674 pkt->pkt_state |= STATE_XFERRED_DATA; 4675 } 4676 pkt->pkt_resid = 0; 4677 4678 if (cmd->cmd_flags & CFLAG_PASSTHRU) { 4679 cmd->cmd_flags |= CFLAG_FINISHED; 4680 cv_broadcast(&mpt->m_passthru_cv); 4681 return; 4682 } else { 4683 mptsas_remove_cmd(mpt, cmd); 4684 } 4685 4686 if (cmd->cmd_flags & CFLAG_RETRY) { 4687 /* 4688 * The target returned QFULL or busy, do not add tihs 4689 * pkt to the doneq since the hba will retry 4690 * this cmd. 4691 * 4692 * The pkt has already been resubmitted in 4693 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error(). 4694 * Remove this cmd_flag here. 4695 */ 4696 cmd->cmd_flags &= ~CFLAG_RETRY; 4697 } else { 4698 mptsas_doneq_add(mpt, cmd); 4699 } 4700 } 4701 4702 static void 4703 mptsas_handle_address_reply(mptsas_t *mpt, 4704 pMpi2ReplyDescriptorsUnion_t reply_desc) 4705 { 4706 pMpi2AddressReplyDescriptor_t address_reply; 4707 pMPI2DefaultReply_t reply; 4708 mptsas_fw_diagnostic_buffer_t *pBuffer; 4709 uint32_t reply_addr; 4710 uint16_t SMID, iocstatus; 4711 mptsas_slots_t *slots = mpt->m_active; 4712 mptsas_cmd_t *cmd = NULL; 4713 uint8_t function, buffer_type; 4714 m_replyh_arg_t *args; 4715 int reply_frame_no; 4716 4717 ASSERT(mutex_owned(&mpt->m_mutex)); 4718 4719 address_reply = (pMpi2AddressReplyDescriptor_t)reply_desc; 4720 reply_addr = ddi_get32(mpt->m_acc_post_queue_hdl, 4721 &address_reply->ReplyFrameAddress); 4722 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &address_reply->SMID); 4723 4724 /* 4725 * If reply frame is not in the proper range we should ignore this 4726 * message and exit the interrupt handler. 4727 */ 4728 if ((reply_addr < mpt->m_reply_frame_dma_addr) || 4729 (reply_addr >= (mpt->m_reply_frame_dma_addr + 4730 (mpt->m_reply_frame_size * mpt->m_max_replies))) || 4731 ((reply_addr - mpt->m_reply_frame_dma_addr) % 4732 mpt->m_reply_frame_size != 0)) { 4733 mptsas_log(mpt, CE_WARN, "?Received invalid reply frame " 4734 "address 0x%x\n", reply_addr); 4735 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 4736 return; 4737 } 4738 4739 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 4740 DDI_DMA_SYNC_FORCPU); 4741 reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame + (reply_addr - 4742 mpt->m_reply_frame_dma_addr)); 4743 function = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Function); 4744 4745 /* 4746 * don't get slot information and command for events since these values 4747 * don't exist 4748 */ 4749 if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) && 4750 (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) { 4751 /* 4752 * This could be a TM reply, which use the last allocated SMID, 4753 * so allow for that. 4754 */ 4755 if ((SMID == 0) || (SMID > (slots->m_n_slots + 1))) { 4756 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of " 4757 "%d\n", SMID); 4758 ddi_fm_service_impact(mpt->m_dip, 4759 DDI_SERVICE_UNAFFECTED); 4760 return; 4761 } 4762 4763 cmd = slots->m_slot[SMID]; 4764 4765 /* 4766 * print warning and return if the slot is empty 4767 */ 4768 if (cmd == NULL) { 4769 mptsas_log(mpt, CE_WARN, "?NULL command for address " 4770 "reply in slot %d", SMID); 4771 return; 4772 } 4773 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 4774 (cmd->cmd_flags & CFLAG_CONFIG) || 4775 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 4776 cmd->cmd_rfm = reply_addr; 4777 cmd->cmd_flags |= CFLAG_FINISHED; 4778 cv_broadcast(&mpt->m_passthru_cv); 4779 cv_broadcast(&mpt->m_config_cv); 4780 cv_broadcast(&mpt->m_fw_diag_cv); 4781 return; 4782 } else if (!(cmd->cmd_flags & CFLAG_FW_CMD)) { 4783 mptsas_remove_cmd(mpt, cmd); 4784 } 4785 NDBG31(("\t\tmptsas_process_intr: slot=%d", SMID)); 4786 } 4787 /* 4788 * Depending on the function, we need to handle 4789 * the reply frame (and cmd) differently. 4790 */ 4791 switch (function) { 4792 case MPI2_FUNCTION_SCSI_IO_REQUEST: 4793 mptsas_check_scsi_io_error(mpt, (pMpi2SCSIIOReply_t)reply, cmd); 4794 break; 4795 case MPI2_FUNCTION_SCSI_TASK_MGMT: 4796 cmd->cmd_rfm = reply_addr; 4797 mptsas_check_task_mgt(mpt, (pMpi2SCSIManagementReply_t)reply, 4798 cmd); 4799 break; 4800 case MPI2_FUNCTION_FW_DOWNLOAD: 4801 cmd->cmd_flags |= CFLAG_FINISHED; 4802 cv_signal(&mpt->m_fw_cv); 4803 break; 4804 case MPI2_FUNCTION_EVENT_NOTIFICATION: 4805 reply_frame_no = (reply_addr - mpt->m_reply_frame_dma_addr) / 4806 mpt->m_reply_frame_size; 4807 args = &mpt->m_replyh_args[reply_frame_no]; 4808 args->mpt = (void *)mpt; 4809 args->rfm = reply_addr; 4810 4811 /* 4812 * Record the event if its type is enabled in 4813 * this mpt instance by ioctl. 4814 */ 4815 mptsas_record_event(args); 4816 4817 /* 4818 * Handle time critical events 4819 * NOT_RESPONDING/ADDED only now 4820 */ 4821 if (mptsas_handle_event_sync(args) == DDI_SUCCESS) { 4822 /* 4823 * Would not return main process, 4824 * just let taskq resolve ack action 4825 * and ack would be sent in taskq thread 4826 */ 4827 NDBG20(("send mptsas_handle_event_sync success")); 4828 } 4829 if ((ddi_taskq_dispatch(mpt->m_event_taskq, mptsas_handle_event, 4830 (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) { 4831 mptsas_log(mpt, CE_WARN, "No memory available" 4832 "for dispatch taskq"); 4833 /* 4834 * Return the reply frame to the free queue. 4835 */ 4836 ddi_put32(mpt->m_acc_free_queue_hdl, 4837 &((uint32_t *)(void *) 4838 mpt->m_free_queue)[mpt->m_free_index], reply_addr); 4839 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 4840 DDI_DMA_SYNC_FORDEV); 4841 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 4842 mpt->m_free_index = 0; 4843 } 4844 4845 ddi_put32(mpt->m_datap, 4846 &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index); 4847 } 4848 return; 4849 case MPI2_FUNCTION_DIAG_BUFFER_POST: 4850 /* 4851 * If SMID is 0, this implies that the reply is due to a 4852 * release function with a status that the buffer has been 4853 * released. Set the buffer flags accordingly. 4854 */ 4855 if (SMID == 0) { 4856 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 4857 &reply->IOCStatus); 4858 buffer_type = ddi_get8(mpt->m_acc_reply_frame_hdl, 4859 &(((pMpi2DiagBufferPostReply_t)reply)->BufferType)); 4860 if (iocstatus == MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED) { 4861 pBuffer = 4862 &mpt->m_fw_diag_buffer_list[buffer_type]; 4863 pBuffer->valid_data = TRUE; 4864 pBuffer->owned_by_firmware = FALSE; 4865 pBuffer->immediate = FALSE; 4866 } 4867 } else { 4868 /* 4869 * Normal handling of diag post reply with SMID. 4870 */ 4871 cmd = slots->m_slot[SMID]; 4872 4873 /* 4874 * print warning and return if the slot is empty 4875 */ 4876 if (cmd == NULL) { 4877 mptsas_log(mpt, CE_WARN, "?NULL command for " 4878 "address reply in slot %d", SMID); 4879 return; 4880 } 4881 cmd->cmd_rfm = reply_addr; 4882 cmd->cmd_flags |= CFLAG_FINISHED; 4883 cv_broadcast(&mpt->m_fw_diag_cv); 4884 } 4885 return; 4886 default: 4887 mptsas_log(mpt, CE_WARN, "Unknown function 0x%x ", function); 4888 break; 4889 } 4890 4891 /* 4892 * Return the reply frame to the free queue. 4893 */ 4894 ddi_put32(mpt->m_acc_free_queue_hdl, 4895 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 4896 reply_addr); 4897 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 4898 DDI_DMA_SYNC_FORDEV); 4899 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 4900 mpt->m_free_index = 0; 4901 } 4902 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 4903 mpt->m_free_index); 4904 4905 if (cmd->cmd_flags & CFLAG_FW_CMD) 4906 return; 4907 4908 if (cmd->cmd_flags & CFLAG_RETRY) { 4909 /* 4910 * The target returned QFULL or busy, do not add tihs 4911 * pkt to the doneq since the hba will retry 4912 * this cmd. 4913 * 4914 * The pkt has already been resubmitted in 4915 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error(). 4916 * Remove this cmd_flag here. 4917 */ 4918 cmd->cmd_flags &= ~CFLAG_RETRY; 4919 } else { 4920 mptsas_doneq_add(mpt, cmd); 4921 } 4922 } 4923 4924 static void 4925 mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, 4926 mptsas_cmd_t *cmd) 4927 { 4928 uint8_t scsi_status, scsi_state; 4929 uint16_t ioc_status; 4930 uint32_t xferred, sensecount, responsedata, loginfo = 0; 4931 struct scsi_pkt *pkt; 4932 struct scsi_arq_status *arqstat; 4933 struct buf *bp; 4934 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 4935 uint8_t *sensedata = NULL; 4936 4937 if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) == 4938 (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) { 4939 bp = cmd->cmd_ext_arq_buf; 4940 } else { 4941 bp = cmd->cmd_arq_buf; 4942 } 4943 4944 scsi_status = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIStatus); 4945 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus); 4946 scsi_state = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIState); 4947 xferred = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->TransferCount); 4948 sensecount = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->SenseCount); 4949 responsedata = ddi_get32(mpt->m_acc_reply_frame_hdl, 4950 &reply->ResponseInfo); 4951 4952 if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 4953 loginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 4954 &reply->IOCLogInfo); 4955 mptsas_log(mpt, CE_NOTE, 4956 "?Log info 0x%x received for target %d.\n" 4957 "\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x", 4958 loginfo, Tgt(cmd), scsi_status, ioc_status, 4959 scsi_state); 4960 } 4961 4962 NDBG31(("\t\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x", 4963 scsi_status, ioc_status, scsi_state)); 4964 4965 pkt = CMD2PKT(cmd); 4966 *(pkt->pkt_scbp) = scsi_status; 4967 4968 if (loginfo == 0x31170000) { 4969 /* 4970 * if loginfo PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY 4971 * 0x31170000 comes, that means the device missing delay 4972 * is in progressing, the command need retry later. 4973 */ 4974 *(pkt->pkt_scbp) = STATUS_BUSY; 4975 return; 4976 } 4977 4978 if ((scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS) && 4979 ((ioc_status & MPI2_IOCSTATUS_MASK) == 4980 MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE)) { 4981 pkt->pkt_reason = CMD_INCOMPLETE; 4982 pkt->pkt_state |= STATE_GOT_BUS; 4983 if (ptgt->m_reset_delay == 0) { 4984 mptsas_set_throttle(mpt, ptgt, 4985 DRAIN_THROTTLE); 4986 } 4987 return; 4988 } 4989 4990 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) { 4991 responsedata &= 0x000000FF; 4992 if (responsedata & MPTSAS_SCSI_RESPONSE_CODE_TLR_OFF) { 4993 mptsas_log(mpt, CE_NOTE, "Do not support the TLR\n"); 4994 pkt->pkt_reason = CMD_TLR_OFF; 4995 return; 4996 } 4997 } 4998 4999 5000 switch (scsi_status) { 5001 case MPI2_SCSI_STATUS_CHECK_CONDITION: 5002 pkt->pkt_resid = (cmd->cmd_dmacount - xferred); 5003 arqstat = (void*)(pkt->pkt_scbp); 5004 arqstat->sts_rqpkt_status = *((struct scsi_status *) 5005 (pkt->pkt_scbp)); 5006 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 5007 STATE_SENT_CMD | STATE_GOT_STATUS | STATE_ARQ_DONE); 5008 if (cmd->cmd_flags & CFLAG_XARQ) { 5009 pkt->pkt_state |= STATE_XARQ_DONE; 5010 } 5011 if (pkt->pkt_resid != cmd->cmd_dmacount) { 5012 pkt->pkt_state |= STATE_XFERRED_DATA; 5013 } 5014 arqstat->sts_rqpkt_reason = pkt->pkt_reason; 5015 arqstat->sts_rqpkt_state = pkt->pkt_state; 5016 arqstat->sts_rqpkt_state |= STATE_XFERRED_DATA; 5017 arqstat->sts_rqpkt_statistics = pkt->pkt_statistics; 5018 sensedata = (uint8_t *)&arqstat->sts_sensedata; 5019 5020 bcopy((uchar_t *)bp->b_un.b_addr, sensedata, 5021 ((cmd->cmd_rqslen >= sensecount) ? sensecount : 5022 cmd->cmd_rqslen)); 5023 arqstat->sts_rqpkt_resid = (cmd->cmd_rqslen - sensecount); 5024 cmd->cmd_flags |= CFLAG_CMDARQ; 5025 /* 5026 * Set proper status for pkt if autosense was valid 5027 */ 5028 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) { 5029 struct scsi_status zero_status = { 0 }; 5030 arqstat->sts_rqpkt_status = zero_status; 5031 } 5032 5033 /* 5034 * ASC=0x47 is parity error 5035 * ASC=0x48 is initiator detected error received 5036 */ 5037 if ((scsi_sense_key(sensedata) == KEY_ABORTED_COMMAND) && 5038 ((scsi_sense_asc(sensedata) == 0x47) || 5039 (scsi_sense_asc(sensedata) == 0x48))) { 5040 mptsas_log(mpt, CE_NOTE, "Aborted_command!"); 5041 } 5042 5043 /* 5044 * ASC/ASCQ=0x3F/0x0E means report_luns data changed 5045 * ASC/ASCQ=0x25/0x00 means invalid lun 5046 */ 5047 if (((scsi_sense_key(sensedata) == KEY_UNIT_ATTENTION) && 5048 (scsi_sense_asc(sensedata) == 0x3F) && 5049 (scsi_sense_ascq(sensedata) == 0x0E)) || 5050 ((scsi_sense_key(sensedata) == KEY_ILLEGAL_REQUEST) && 5051 (scsi_sense_asc(sensedata) == 0x25) && 5052 (scsi_sense_ascq(sensedata) == 0x00))) { 5053 mptsas_topo_change_list_t *topo_node = NULL; 5054 5055 topo_node = kmem_zalloc( 5056 sizeof (mptsas_topo_change_list_t), 5057 KM_NOSLEEP); 5058 if (topo_node == NULL) { 5059 mptsas_log(mpt, CE_NOTE, "No memory" 5060 "resource for handle SAS dynamic" 5061 "reconfigure.\n"); 5062 break; 5063 } 5064 topo_node->mpt = mpt; 5065 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET; 5066 topo_node->un.phymask = ptgt->m_phymask; 5067 topo_node->devhdl = ptgt->m_devhdl; 5068 topo_node->object = (void *)ptgt; 5069 topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED; 5070 5071 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 5072 mptsas_handle_dr, 5073 (void *)topo_node, 5074 DDI_NOSLEEP)) != DDI_SUCCESS) { 5075 mptsas_log(mpt, CE_NOTE, "mptsas start taskq" 5076 "for handle SAS dynamic reconfigure" 5077 "failed. \n"); 5078 } 5079 } 5080 break; 5081 case MPI2_SCSI_STATUS_GOOD: 5082 switch (ioc_status & MPI2_IOCSTATUS_MASK) { 5083 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 5084 pkt->pkt_reason = CMD_DEV_GONE; 5085 pkt->pkt_state |= STATE_GOT_BUS; 5086 if (ptgt->m_reset_delay == 0) { 5087 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5088 } 5089 NDBG31(("lost disk for target%d, command:%x", 5090 Tgt(cmd), pkt->pkt_cdbp[0])); 5091 break; 5092 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN: 5093 NDBG31(("data overrun: xferred=%d", xferred)); 5094 NDBG31(("dmacount=%d", cmd->cmd_dmacount)); 5095 pkt->pkt_reason = CMD_DATA_OVR; 5096 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET 5097 | STATE_SENT_CMD | STATE_GOT_STATUS 5098 | STATE_XFERRED_DATA); 5099 pkt->pkt_resid = 0; 5100 break; 5101 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: 5102 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN: 5103 NDBG31(("data underrun: xferred=%d", xferred)); 5104 NDBG31(("dmacount=%d", cmd->cmd_dmacount)); 5105 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET 5106 | STATE_SENT_CMD | STATE_GOT_STATUS); 5107 pkt->pkt_resid = (cmd->cmd_dmacount - xferred); 5108 if (pkt->pkt_resid != cmd->cmd_dmacount) { 5109 pkt->pkt_state |= STATE_XFERRED_DATA; 5110 } 5111 break; 5112 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: 5113 mptsas_set_pkt_reason(mpt, 5114 cmd, CMD_RESET, STAT_BUS_RESET); 5115 break; 5116 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: 5117 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: 5118 mptsas_set_pkt_reason(mpt, 5119 cmd, CMD_RESET, STAT_DEV_RESET); 5120 break; 5121 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR: 5122 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR: 5123 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET); 5124 mptsas_set_pkt_reason(mpt, 5125 cmd, CMD_TERMINATED, STAT_TERMINATED); 5126 break; 5127 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: 5128 case MPI2_IOCSTATUS_BUSY: 5129 /* 5130 * set throttles to drain 5131 */ 5132 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 5133 &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST); 5134 while (ptgt != NULL) { 5135 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5136 5137 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 5138 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 5139 } 5140 5141 /* 5142 * retry command 5143 */ 5144 cmd->cmd_flags |= CFLAG_RETRY; 5145 cmd->cmd_pkt_flags |= FLAG_HEAD; 5146 5147 (void) mptsas_accept_pkt(mpt, cmd); 5148 break; 5149 default: 5150 mptsas_log(mpt, CE_WARN, 5151 "unknown ioc_status = %x\n", ioc_status); 5152 mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer " 5153 "count = %x, scsi_status = %x", scsi_state, 5154 xferred, scsi_status); 5155 break; 5156 } 5157 break; 5158 case MPI2_SCSI_STATUS_TASK_SET_FULL: 5159 mptsas_handle_qfull(mpt, cmd); 5160 break; 5161 case MPI2_SCSI_STATUS_BUSY: 5162 NDBG31(("scsi_status busy received")); 5163 break; 5164 case MPI2_SCSI_STATUS_RESERVATION_CONFLICT: 5165 NDBG31(("scsi_status reservation conflict received")); 5166 break; 5167 default: 5168 mptsas_log(mpt, CE_WARN, "scsi_status=%x, ioc_status=%x\n", 5169 scsi_status, ioc_status); 5170 mptsas_log(mpt, CE_WARN, 5171 "mptsas_process_intr: invalid scsi status\n"); 5172 break; 5173 } 5174 } 5175 5176 static void 5177 mptsas_check_task_mgt(mptsas_t *mpt, pMpi2SCSIManagementReply_t reply, 5178 mptsas_cmd_t *cmd) 5179 { 5180 uint8_t task_type; 5181 uint16_t ioc_status; 5182 uint32_t log_info; 5183 uint16_t dev_handle; 5184 struct scsi_pkt *pkt = CMD2PKT(cmd); 5185 5186 task_type = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->TaskType); 5187 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus); 5188 log_info = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo); 5189 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->DevHandle); 5190 5191 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 5192 mptsas_log(mpt, CE_WARN, "mptsas_check_task_mgt: Task 0x%x " 5193 "failed. IOCStatus=0x%x IOCLogInfo=0x%x target=%d\n", 5194 task_type, ioc_status, log_info, dev_handle); 5195 pkt->pkt_reason = CMD_INCOMPLETE; 5196 return; 5197 } 5198 5199 switch (task_type) { 5200 case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK: 5201 case MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET: 5202 case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK: 5203 case MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA: 5204 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET: 5205 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION: 5206 break; 5207 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 5208 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 5209 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 5210 /* 5211 * Check for invalid DevHandle of 0 in case application 5212 * sends bad command. DevHandle of 0 could cause problems. 5213 */ 5214 if (dev_handle == 0) { 5215 mptsas_log(mpt, CE_WARN, "!Can't flush target with" 5216 " DevHandle of 0."); 5217 } else { 5218 mptsas_flush_target(mpt, dev_handle, Lun(cmd), 5219 task_type); 5220 } 5221 break; 5222 default: 5223 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.", 5224 task_type); 5225 mptsas_log(mpt, CE_WARN, "ioc status = %x", ioc_status); 5226 break; 5227 } 5228 } 5229 5230 static void 5231 mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg) 5232 { 5233 mptsas_t *mpt = arg->mpt; 5234 uint64_t t = arg->t; 5235 mptsas_cmd_t *cmd; 5236 struct scsi_pkt *pkt; 5237 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 5238 5239 mutex_enter(&item->mutex); 5240 while (item->flag & MPTSAS_DONEQ_THREAD_ACTIVE) { 5241 if (!item->doneq) { 5242 cv_wait(&item->cv, &item->mutex); 5243 } 5244 pkt = NULL; 5245 if ((cmd = mptsas_doneq_thread_rm(mpt, t)) != NULL) { 5246 cmd->cmd_flags |= CFLAG_COMPLETED; 5247 pkt = CMD2PKT(cmd); 5248 } 5249 mutex_exit(&item->mutex); 5250 if (pkt) { 5251 mptsas_pkt_comp(pkt, cmd); 5252 } 5253 mutex_enter(&item->mutex); 5254 } 5255 mutex_exit(&item->mutex); 5256 mutex_enter(&mpt->m_doneq_mutex); 5257 mpt->m_doneq_thread_n--; 5258 cv_broadcast(&mpt->m_doneq_thread_cv); 5259 mutex_exit(&mpt->m_doneq_mutex); 5260 } 5261 5262 5263 /* 5264 * mpt interrupt handler. 5265 */ 5266 static uint_t 5267 mptsas_intr(caddr_t arg1, caddr_t arg2) 5268 { 5269 mptsas_t *mpt = (void *)arg1; 5270 pMpi2ReplyDescriptorsUnion_t reply_desc_union; 5271 uchar_t did_reply = FALSE; 5272 5273 NDBG1(("mptsas_intr: arg1 0x%p arg2 0x%p", (void *)arg1, (void *)arg2)); 5274 5275 mutex_enter(&mpt->m_mutex); 5276 5277 /* 5278 * If interrupts are shared by two channels then check whether this 5279 * interrupt is genuinely for this channel by making sure first the 5280 * chip is in high power state. 5281 */ 5282 if ((mpt->m_options & MPTSAS_OPT_PM) && 5283 (mpt->m_power_level != PM_LEVEL_D0)) { 5284 mutex_exit(&mpt->m_mutex); 5285 return (DDI_INTR_UNCLAIMED); 5286 } 5287 5288 /* 5289 * If polling, interrupt was triggered by some shared interrupt because 5290 * IOC interrupts are disabled during polling, so polling routine will 5291 * handle any replies. Considering this, if polling is happening, 5292 * return with interrupt unclaimed. 5293 */ 5294 if (mpt->m_polled_intr) { 5295 mutex_exit(&mpt->m_mutex); 5296 mptsas_log(mpt, CE_WARN, "mpt_sas: Unclaimed interrupt"); 5297 return (DDI_INTR_UNCLAIMED); 5298 } 5299 5300 /* 5301 * Read the istat register. 5302 */ 5303 if ((INTPENDING(mpt)) != 0) { 5304 /* 5305 * read fifo until empty. 5306 */ 5307 #ifndef __lock_lint 5308 _NOTE(CONSTCOND) 5309 #endif 5310 while (TRUE) { 5311 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 5312 DDI_DMA_SYNC_FORCPU); 5313 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t) 5314 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index); 5315 5316 if (ddi_get32(mpt->m_acc_post_queue_hdl, 5317 &reply_desc_union->Words.Low) == 0xFFFFFFFF || 5318 ddi_get32(mpt->m_acc_post_queue_hdl, 5319 &reply_desc_union->Words.High) == 0xFFFFFFFF) { 5320 break; 5321 } 5322 5323 /* 5324 * The reply is valid, process it according to its 5325 * type. Also, set a flag for updating the reply index 5326 * after they've all been processed. 5327 */ 5328 did_reply = TRUE; 5329 5330 mptsas_process_intr(mpt, reply_desc_union); 5331 5332 /* 5333 * Increment post index and roll over if needed. 5334 */ 5335 if (++mpt->m_post_index == mpt->m_post_queue_depth) { 5336 mpt->m_post_index = 0; 5337 } 5338 } 5339 5340 /* 5341 * Update the global reply index if at least one reply was 5342 * processed. 5343 */ 5344 if (did_reply) { 5345 ddi_put32(mpt->m_datap, 5346 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); 5347 } 5348 } else { 5349 mutex_exit(&mpt->m_mutex); 5350 return (DDI_INTR_UNCLAIMED); 5351 } 5352 NDBG1(("mptsas_intr complete")); 5353 5354 /* 5355 * If no helper threads are created, process the doneq in ISR. If 5356 * helpers are created, use the doneq length as a metric to measure the 5357 * load on the interrupt CPU. If it is long enough, which indicates the 5358 * load is heavy, then we deliver the IO completions to the helpers. 5359 * This measurement has some limitations, although it is simple and 5360 * straightforward and works well for most of the cases at present. 5361 */ 5362 if (!mpt->m_doneq_thread_n || 5363 (mpt->m_doneq_len <= mpt->m_doneq_length_threshold)) { 5364 mptsas_doneq_empty(mpt); 5365 } else { 5366 mptsas_deliver_doneq_thread(mpt); 5367 } 5368 5369 /* 5370 * If there are queued cmd, start them now. 5371 */ 5372 if (mpt->m_waitq != NULL) { 5373 mptsas_restart_waitq(mpt); 5374 } 5375 5376 mutex_exit(&mpt->m_mutex); 5377 return (DDI_INTR_CLAIMED); 5378 } 5379 5380 static void 5381 mptsas_process_intr(mptsas_t *mpt, 5382 pMpi2ReplyDescriptorsUnion_t reply_desc_union) 5383 { 5384 uint8_t reply_type; 5385 5386 ASSERT(mutex_owned(&mpt->m_mutex)); 5387 5388 /* 5389 * The reply is valid, process it according to its 5390 * type. Also, set a flag for updated the reply index 5391 * after they've all been processed. 5392 */ 5393 reply_type = ddi_get8(mpt->m_acc_post_queue_hdl, 5394 &reply_desc_union->Default.ReplyFlags); 5395 reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; 5396 if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) { 5397 mptsas_handle_scsi_io_success(mpt, reply_desc_union); 5398 } else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { 5399 mptsas_handle_address_reply(mpt, reply_desc_union); 5400 } else { 5401 mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type); 5402 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 5403 } 5404 5405 /* 5406 * Clear the reply descriptor for re-use and increment 5407 * index. 5408 */ 5409 ddi_put64(mpt->m_acc_post_queue_hdl, 5410 &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index], 5411 0xFFFFFFFFFFFFFFFF); 5412 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 5413 DDI_DMA_SYNC_FORDEV); 5414 } 5415 5416 /* 5417 * handle qfull condition 5418 */ 5419 static void 5420 mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd) 5421 { 5422 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 5423 5424 if ((++cmd->cmd_qfull_retries > ptgt->m_qfull_retries) || 5425 (ptgt->m_qfull_retries == 0)) { 5426 /* 5427 * We have exhausted the retries on QFULL, or, 5428 * the target driver has indicated that it 5429 * wants to handle QFULL itself by setting 5430 * qfull-retries capability to 0. In either case 5431 * we want the target driver's QFULL handling 5432 * to kick in. We do this by having pkt_reason 5433 * as CMD_CMPLT and pkt_scbp as STATUS_QFULL. 5434 */ 5435 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5436 } else { 5437 if (ptgt->m_reset_delay == 0) { 5438 ptgt->m_t_throttle = 5439 max((ptgt->m_t_ncmds - 2), 0); 5440 } 5441 5442 cmd->cmd_pkt_flags |= FLAG_HEAD; 5443 cmd->cmd_flags &= ~(CFLAG_TRANFLAG); 5444 cmd->cmd_flags |= CFLAG_RETRY; 5445 5446 (void) mptsas_accept_pkt(mpt, cmd); 5447 5448 /* 5449 * when target gives queue full status with no commands 5450 * outstanding (m_t_ncmds == 0), throttle is set to 0 5451 * (HOLD_THROTTLE), and the queue full handling start 5452 * (see psarc/1994/313); if there are commands outstanding, 5453 * throttle is set to (m_t_ncmds - 2) 5454 */ 5455 if (ptgt->m_t_throttle == HOLD_THROTTLE) { 5456 /* 5457 * By setting throttle to QFULL_THROTTLE, we 5458 * avoid submitting new commands and in 5459 * mptsas_restart_cmd find out slots which need 5460 * their throttles to be cleared. 5461 */ 5462 mptsas_set_throttle(mpt, ptgt, QFULL_THROTTLE); 5463 if (mpt->m_restart_cmd_timeid == 0) { 5464 mpt->m_restart_cmd_timeid = 5465 timeout(mptsas_restart_cmd, mpt, 5466 ptgt->m_qfull_retry_interval); 5467 } 5468 } 5469 } 5470 } 5471 5472 mptsas_phymask_t 5473 mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport) 5474 { 5475 mptsas_phymask_t phy_mask = 0; 5476 uint8_t i = 0; 5477 5478 NDBG20(("mptsas%d physport_to_phymask enter", mpt->m_instance)); 5479 5480 ASSERT(mutex_owned(&mpt->m_mutex)); 5481 5482 /* 5483 * If physport is 0xFF, this is a RAID volume. Use phymask of 0. 5484 */ 5485 if (physport == 0xFF) { 5486 return (0); 5487 } 5488 5489 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 5490 if (mpt->m_phy_info[i].attached_devhdl && 5491 (mpt->m_phy_info[i].phy_mask != 0) && 5492 (mpt->m_phy_info[i].port_num == physport)) { 5493 phy_mask = mpt->m_phy_info[i].phy_mask; 5494 break; 5495 } 5496 } 5497 NDBG20(("mptsas%d physport_to_phymask:physport :%x phymask :%x, ", 5498 mpt->m_instance, physport, phy_mask)); 5499 return (phy_mask); 5500 } 5501 5502 /* 5503 * mpt free device handle after device gone, by use of passthrough 5504 */ 5505 static int 5506 mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl) 5507 { 5508 Mpi2SasIoUnitControlRequest_t req; 5509 Mpi2SasIoUnitControlReply_t rep; 5510 int ret; 5511 5512 ASSERT(mutex_owned(&mpt->m_mutex)); 5513 5514 /* 5515 * Need to compose a SAS IO Unit Control request message 5516 * and call mptsas_do_passthru() function 5517 */ 5518 bzero(&req, sizeof (req)); 5519 bzero(&rep, sizeof (rep)); 5520 5521 req.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 5522 req.Operation = MPI2_SAS_OP_REMOVE_DEVICE; 5523 req.DevHandle = LE_16(devhdl); 5524 5525 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL, 5526 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL); 5527 if (ret != 0) { 5528 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit " 5529 "Control error %d", ret); 5530 return (DDI_FAILURE); 5531 } 5532 5533 /* do passthrough success, check the ioc status */ 5534 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 5535 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit " 5536 "Control IOCStatus %d", LE_16(rep.IOCStatus)); 5537 return (DDI_FAILURE); 5538 } 5539 5540 return (DDI_SUCCESS); 5541 } 5542 5543 static void 5544 mptsas_update_phymask(mptsas_t *mpt) 5545 { 5546 mptsas_phymask_t mask = 0, phy_mask; 5547 char *phy_mask_name; 5548 uint8_t current_port; 5549 int i, j; 5550 5551 NDBG20(("mptsas%d update phymask ", mpt->m_instance)); 5552 5553 ASSERT(mutex_owned(&mpt->m_mutex)); 5554 5555 (void) mptsas_get_sas_io_unit_page(mpt); 5556 5557 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 5558 5559 for (i = 0; i < mpt->m_num_phys; i++) { 5560 phy_mask = 0x00; 5561 5562 if (mpt->m_phy_info[i].attached_devhdl == 0) 5563 continue; 5564 5565 bzero(phy_mask_name, sizeof (phy_mask_name)); 5566 5567 current_port = mpt->m_phy_info[i].port_num; 5568 5569 if ((mask & (1 << i)) != 0) 5570 continue; 5571 5572 for (j = 0; j < mpt->m_num_phys; j++) { 5573 if (mpt->m_phy_info[j].attached_devhdl && 5574 (mpt->m_phy_info[j].port_num == current_port)) { 5575 phy_mask |= (1 << j); 5576 } 5577 } 5578 mask = mask | phy_mask; 5579 5580 for (j = 0; j < mpt->m_num_phys; j++) { 5581 if ((phy_mask >> j) & 0x01) { 5582 mpt->m_phy_info[j].phy_mask = phy_mask; 5583 } 5584 } 5585 5586 (void) sprintf(phy_mask_name, "%x", phy_mask); 5587 5588 mutex_exit(&mpt->m_mutex); 5589 /* 5590 * register a iport, if the port has already been existed 5591 * SCSA will do nothing and just return. 5592 */ 5593 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name); 5594 mutex_enter(&mpt->m_mutex); 5595 } 5596 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 5597 NDBG20(("mptsas%d update phymask return", mpt->m_instance)); 5598 } 5599 5600 /* 5601 * mptsas_handle_dr is a task handler for DR, the DR action includes: 5602 * 1. Directly attched Device Added/Removed. 5603 * 2. Expander Device Added/Removed. 5604 * 3. Indirectly Attached Device Added/Expander. 5605 * 4. LUNs of a existing device status change. 5606 * 5. RAID volume created/deleted. 5607 * 6. Member of RAID volume is released because of RAID deletion. 5608 * 7. Physical disks are removed because of RAID creation. 5609 */ 5610 static void 5611 mptsas_handle_dr(void *args) { 5612 mptsas_topo_change_list_t *topo_node = NULL; 5613 mptsas_topo_change_list_t *save_node = NULL; 5614 mptsas_t *mpt; 5615 dev_info_t *parent = NULL; 5616 mptsas_phymask_t phymask = 0; 5617 char *phy_mask_name; 5618 uint8_t flags = 0, physport = 0xff; 5619 uint8_t port_update = 0; 5620 uint_t event; 5621 5622 topo_node = (mptsas_topo_change_list_t *)args; 5623 5624 mpt = topo_node->mpt; 5625 event = topo_node->event; 5626 flags = topo_node->flags; 5627 5628 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 5629 5630 NDBG20(("mptsas%d handle_dr enter", mpt->m_instance)); 5631 5632 switch (event) { 5633 case MPTSAS_DR_EVENT_RECONFIG_TARGET: 5634 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 5635 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE) || 5636 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) { 5637 /* 5638 * Direct attached or expander attached device added 5639 * into system or a Phys Disk that is being unhidden. 5640 */ 5641 port_update = 1; 5642 } 5643 break; 5644 case MPTSAS_DR_EVENT_RECONFIG_SMP: 5645 /* 5646 * New expander added into system, it must be the head 5647 * of topo_change_list_t 5648 */ 5649 port_update = 1; 5650 break; 5651 default: 5652 port_update = 0; 5653 break; 5654 } 5655 /* 5656 * All cases port_update == 1 may cause initiator port form change 5657 */ 5658 mutex_enter(&mpt->m_mutex); 5659 if (mpt->m_port_chng && port_update) { 5660 /* 5661 * mpt->m_port_chng flag indicates some PHYs of initiator 5662 * port have changed to online. So when expander added or 5663 * directly attached device online event come, we force to 5664 * update port information by issueing SAS IO Unit Page and 5665 * update PHYMASKs. 5666 */ 5667 (void) mptsas_update_phymask(mpt); 5668 mpt->m_port_chng = 0; 5669 5670 } 5671 mutex_exit(&mpt->m_mutex); 5672 while (topo_node) { 5673 phymask = 0; 5674 if (parent == NULL) { 5675 physport = topo_node->un.physport; 5676 event = topo_node->event; 5677 flags = topo_node->flags; 5678 if (event & (MPTSAS_DR_EVENT_OFFLINE_TARGET | 5679 MPTSAS_DR_EVENT_OFFLINE_SMP)) { 5680 /* 5681 * For all offline events, phymask is known 5682 */ 5683 phymask = topo_node->un.phymask; 5684 goto find_parent; 5685 } 5686 if (event & MPTSAS_TOPO_FLAG_REMOVE_HANDLE) { 5687 goto handle_topo_change; 5688 } 5689 if (flags & MPTSAS_TOPO_FLAG_LUN_ASSOCIATED) { 5690 phymask = topo_node->un.phymask; 5691 goto find_parent; 5692 } 5693 5694 if ((flags == 5695 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) && 5696 (event == MPTSAS_DR_EVENT_RECONFIG_TARGET)) { 5697 /* 5698 * There is no any field in IR_CONFIG_CHANGE 5699 * event indicate physport/phynum, let's get 5700 * parent after SAS Device Page0 request. 5701 */ 5702 goto handle_topo_change; 5703 } 5704 5705 mutex_enter(&mpt->m_mutex); 5706 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 5707 /* 5708 * If the direct attached device added or a 5709 * phys disk is being unhidden, argument 5710 * physport actually is PHY#, so we have to get 5711 * phymask according PHY#. 5712 */ 5713 physport = mpt->m_phy_info[physport].port_num; 5714 } 5715 5716 /* 5717 * Translate physport to phymask so that we can search 5718 * parent dip. 5719 */ 5720 phymask = mptsas_physport_to_phymask(mpt, 5721 physport); 5722 mutex_exit(&mpt->m_mutex); 5723 5724 find_parent: 5725 bzero(phy_mask_name, MPTSAS_MAX_PHYS); 5726 /* 5727 * For RAID topology change node, write the iport name 5728 * as v0. 5729 */ 5730 if (flags & MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 5731 (void) sprintf(phy_mask_name, "v0"); 5732 } else { 5733 /* 5734 * phymask can bo 0 if the drive has been 5735 * pulled by the time an add event is 5736 * processed. If phymask is 0, just skip this 5737 * event and continue. 5738 */ 5739 if (phymask == 0) { 5740 mutex_enter(&mpt->m_mutex); 5741 save_node = topo_node; 5742 topo_node = topo_node->next; 5743 ASSERT(save_node); 5744 kmem_free(save_node, 5745 sizeof (mptsas_topo_change_list_t)); 5746 mutex_exit(&mpt->m_mutex); 5747 5748 parent = NULL; 5749 continue; 5750 } 5751 (void) sprintf(phy_mask_name, "%x", phymask); 5752 } 5753 parent = scsi_hba_iport_find(mpt->m_dip, 5754 phy_mask_name); 5755 if (parent == NULL) { 5756 mptsas_log(mpt, CE_WARN, "Failed to find an " 5757 "iport, should not happen!"); 5758 goto out; 5759 } 5760 5761 } 5762 ASSERT(parent); 5763 handle_topo_change: 5764 5765 mutex_enter(&mpt->m_mutex); 5766 5767 mptsas_handle_topo_change(topo_node, parent); 5768 save_node = topo_node; 5769 topo_node = topo_node->next; 5770 ASSERT(save_node); 5771 kmem_free(save_node, sizeof (mptsas_topo_change_list_t)); 5772 mutex_exit(&mpt->m_mutex); 5773 5774 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 5775 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) || 5776 (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) { 5777 /* 5778 * If direct attached device associated, make sure 5779 * reset the parent before start the next one. But 5780 * all devices associated with expander shares the 5781 * parent. Also, reset parent if this is for RAID. 5782 */ 5783 parent = NULL; 5784 } 5785 } 5786 out: 5787 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 5788 } 5789 5790 static void 5791 mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node, 5792 dev_info_t *parent) 5793 { 5794 mptsas_target_t *ptgt = NULL; 5795 mptsas_smp_t *psmp = NULL; 5796 mptsas_t *mpt = (void *)topo_node->mpt; 5797 uint16_t devhdl; 5798 uint16_t attached_devhdl; 5799 uint64_t sas_wwn = 0; 5800 int rval = 0; 5801 uint32_t page_address; 5802 uint8_t phy, flags; 5803 char *addr = NULL; 5804 dev_info_t *lundip; 5805 int circ = 0, circ1 = 0; 5806 char attached_wwnstr[MPTSAS_WWN_STRLEN]; 5807 5808 NDBG20(("mptsas%d handle_topo_change enter", mpt->m_instance)); 5809 5810 ASSERT(mutex_owned(&mpt->m_mutex)); 5811 5812 switch (topo_node->event) { 5813 case MPTSAS_DR_EVENT_RECONFIG_TARGET: 5814 { 5815 char *phy_mask_name; 5816 mptsas_phymask_t phymask = 0; 5817 5818 if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 5819 /* 5820 * Get latest RAID info. 5821 */ 5822 (void) mptsas_get_raid_info(mpt); 5823 ptgt = mptsas_search_by_devhdl( 5824 &mpt->m_active->m_tgttbl, topo_node->devhdl); 5825 if (ptgt == NULL) 5826 break; 5827 } else { 5828 ptgt = (void *)topo_node->object; 5829 } 5830 5831 if (ptgt == NULL) { 5832 /* 5833 * If a Phys Disk was deleted, RAID info needs to be 5834 * updated to reflect the new topology. 5835 */ 5836 (void) mptsas_get_raid_info(mpt); 5837 5838 /* 5839 * Get sas device page 0 by DevHandle to make sure if 5840 * SSP/SATA end device exist. 5841 */ 5842 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 5843 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 5844 topo_node->devhdl; 5845 5846 rval = mptsas_get_target_device_info(mpt, page_address, 5847 &devhdl, &ptgt); 5848 if (rval == DEV_INFO_WRONG_DEVICE_TYPE) { 5849 mptsas_log(mpt, CE_NOTE, 5850 "mptsas_handle_topo_change: target %d is " 5851 "not a SAS/SATA device. \n", 5852 topo_node->devhdl); 5853 } else if (rval == DEV_INFO_FAIL_ALLOC) { 5854 mptsas_log(mpt, CE_NOTE, 5855 "mptsas_handle_topo_change: could not " 5856 "allocate memory. \n"); 5857 } 5858 /* 5859 * If rval is DEV_INFO_PHYS_DISK than there is nothing 5860 * else to do, just leave. 5861 */ 5862 if (rval != DEV_INFO_SUCCESS) { 5863 return; 5864 } 5865 } 5866 5867 ASSERT(ptgt->m_devhdl == topo_node->devhdl); 5868 5869 mutex_exit(&mpt->m_mutex); 5870 flags = topo_node->flags; 5871 5872 if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) { 5873 phymask = ptgt->m_phymask; 5874 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 5875 (void) sprintf(phy_mask_name, "%x", phymask); 5876 parent = scsi_hba_iport_find(mpt->m_dip, 5877 phy_mask_name); 5878 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 5879 if (parent == NULL) { 5880 mptsas_log(mpt, CE_WARN, "Failed to find a " 5881 "iport for PD, should not happen!"); 5882 mutex_enter(&mpt->m_mutex); 5883 break; 5884 } 5885 } 5886 5887 if (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 5888 ndi_devi_enter(parent, &circ1); 5889 (void) mptsas_config_raid(parent, topo_node->devhdl, 5890 &lundip); 5891 ndi_devi_exit(parent, circ1); 5892 } else { 5893 /* 5894 * hold nexus for bus configure 5895 */ 5896 ndi_devi_enter(scsi_vhci_dip, &circ); 5897 ndi_devi_enter(parent, &circ1); 5898 rval = mptsas_config_target(parent, ptgt); 5899 /* 5900 * release nexus for bus configure 5901 */ 5902 ndi_devi_exit(parent, circ1); 5903 ndi_devi_exit(scsi_vhci_dip, circ); 5904 5905 /* 5906 * Add parent's props for SMHBA support 5907 */ 5908 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 5909 bzero(attached_wwnstr, 5910 sizeof (attached_wwnstr)); 5911 (void) sprintf(attached_wwnstr, "w%016"PRIx64, 5912 ptgt->m_sas_wwn); 5913 if (ddi_prop_update_string(DDI_DEV_T_NONE, 5914 parent, 5915 SCSI_ADDR_PROP_ATTACHED_PORT, 5916 attached_wwnstr) 5917 != DDI_PROP_SUCCESS) { 5918 (void) ddi_prop_remove(DDI_DEV_T_NONE, 5919 parent, 5920 SCSI_ADDR_PROP_ATTACHED_PORT); 5921 mptsas_log(mpt, CE_WARN, "Failed to" 5922 "attached-port props"); 5923 return; 5924 } 5925 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 5926 MPTSAS_NUM_PHYS, 1) != 5927 DDI_PROP_SUCCESS) { 5928 (void) ddi_prop_remove(DDI_DEV_T_NONE, 5929 parent, MPTSAS_NUM_PHYS); 5930 mptsas_log(mpt, CE_WARN, "Failed to" 5931 " create num-phys props"); 5932 return; 5933 } 5934 5935 /* 5936 * Update PHY info for smhba 5937 */ 5938 mutex_enter(&mpt->m_mutex); 5939 if (mptsas_smhba_phy_init(mpt)) { 5940 mutex_exit(&mpt->m_mutex); 5941 mptsas_log(mpt, CE_WARN, "mptsas phy" 5942 " update failed"); 5943 return; 5944 } 5945 mutex_exit(&mpt->m_mutex); 5946 mptsas_smhba_set_phy_props(mpt, 5947 ddi_get_name_addr(parent), parent, 5948 1, &attached_devhdl); 5949 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 5950 MPTSAS_VIRTUAL_PORT, 0) != 5951 DDI_PROP_SUCCESS) { 5952 (void) ddi_prop_remove(DDI_DEV_T_NONE, 5953 parent, MPTSAS_VIRTUAL_PORT); 5954 mptsas_log(mpt, CE_WARN, 5955 "mptsas virtual-port" 5956 "port prop update failed"); 5957 return; 5958 } 5959 } 5960 } 5961 mutex_enter(&mpt->m_mutex); 5962 5963 NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, " 5964 "phymask:%x.", mpt->m_instance, ptgt->m_devhdl, 5965 ptgt->m_phymask)); 5966 break; 5967 } 5968 case MPTSAS_DR_EVENT_OFFLINE_TARGET: 5969 { 5970 mptsas_hash_table_t *tgttbl = &mpt->m_active->m_tgttbl; 5971 devhdl = topo_node->devhdl; 5972 ptgt = mptsas_search_by_devhdl(tgttbl, devhdl); 5973 if (ptgt == NULL) 5974 break; 5975 5976 sas_wwn = ptgt->m_sas_wwn; 5977 phy = ptgt->m_phynum; 5978 5979 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 5980 5981 if (sas_wwn) { 5982 (void) sprintf(addr, "w%016"PRIx64, sas_wwn); 5983 } else { 5984 (void) sprintf(addr, "p%x", phy); 5985 } 5986 ASSERT(ptgt->m_devhdl == devhdl); 5987 5988 if ((topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) || 5989 (topo_node->flags == 5990 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) { 5991 /* 5992 * Get latest RAID info if RAID volume status changes 5993 * or Phys Disk status changes 5994 */ 5995 (void) mptsas_get_raid_info(mpt); 5996 } 5997 /* 5998 * Abort all outstanding command on the device 5999 */ 6000 rval = mptsas_do_scsi_reset(mpt, devhdl); 6001 if (rval) { 6002 NDBG20(("mptsas%d handle_topo_change to reset target " 6003 "before offline devhdl:%x, phymask:%x, rval:%x", 6004 mpt->m_instance, ptgt->m_devhdl, ptgt->m_phymask, 6005 rval)); 6006 } 6007 6008 mutex_exit(&mpt->m_mutex); 6009 6010 ndi_devi_enter(scsi_vhci_dip, &circ); 6011 ndi_devi_enter(parent, &circ1); 6012 rval = mptsas_offline_target(parent, addr); 6013 ndi_devi_exit(parent, circ1); 6014 ndi_devi_exit(scsi_vhci_dip, circ); 6015 NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, " 6016 "phymask:%x, rval:%x", mpt->m_instance, 6017 ptgt->m_devhdl, ptgt->m_phymask, rval)); 6018 6019 kmem_free(addr, SCSI_MAXNAMELEN); 6020 6021 /* 6022 * Clear parent's props for SMHBA support 6023 */ 6024 flags = topo_node->flags; 6025 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 6026 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6027 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent, 6028 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 6029 DDI_PROP_SUCCESS) { 6030 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6031 SCSI_ADDR_PROP_ATTACHED_PORT); 6032 mptsas_log(mpt, CE_WARN, "mptsas attached port " 6033 "prop update failed"); 6034 break; 6035 } 6036 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6037 MPTSAS_NUM_PHYS, 0) != 6038 DDI_PROP_SUCCESS) { 6039 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6040 MPTSAS_NUM_PHYS); 6041 mptsas_log(mpt, CE_WARN, "mptsas num phys " 6042 "prop update failed"); 6043 break; 6044 } 6045 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6046 MPTSAS_VIRTUAL_PORT, 1) != 6047 DDI_PROP_SUCCESS) { 6048 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6049 MPTSAS_VIRTUAL_PORT); 6050 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 6051 "prop update failed"); 6052 break; 6053 } 6054 } 6055 6056 mutex_enter(&mpt->m_mutex); 6057 if (mptsas_set_led_status(mpt, ptgt, 0) != DDI_SUCCESS) { 6058 NDBG14(("mptsas: clear LED for tgt %x failed", 6059 ptgt->m_slot_num)); 6060 } 6061 if (rval == DDI_SUCCESS) { 6062 mptsas_tgt_free(&mpt->m_active->m_tgttbl, 6063 ptgt->m_sas_wwn, ptgt->m_phymask); 6064 ptgt = NULL; 6065 } else { 6066 /* 6067 * clean DR_INTRANSITION flag to allow I/O down to 6068 * PHCI driver since failover finished. 6069 * Invalidate the devhdl 6070 */ 6071 ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL; 6072 ptgt->m_tgt_unconfigured = 0; 6073 mutex_enter(&mpt->m_tx_waitq_mutex); 6074 ptgt->m_dr_flag = MPTSAS_DR_INACTIVE; 6075 mutex_exit(&mpt->m_tx_waitq_mutex); 6076 } 6077 6078 /* 6079 * Send SAS IO Unit Control to free the dev handle 6080 */ 6081 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 6082 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE)) { 6083 rval = mptsas_free_devhdl(mpt, devhdl); 6084 6085 NDBG20(("mptsas%d handle_topo_change to remove " 6086 "devhdl:%x, rval:%x", mpt->m_instance, devhdl, 6087 rval)); 6088 } 6089 6090 break; 6091 } 6092 case MPTSAS_TOPO_FLAG_REMOVE_HANDLE: 6093 { 6094 devhdl = topo_node->devhdl; 6095 /* 6096 * If this is the remove handle event, do a reset first. 6097 */ 6098 if (topo_node->event == MPTSAS_TOPO_FLAG_REMOVE_HANDLE) { 6099 rval = mptsas_do_scsi_reset(mpt, devhdl); 6100 if (rval) { 6101 NDBG20(("mpt%d reset target before remove " 6102 "devhdl:%x, rval:%x", mpt->m_instance, 6103 devhdl, rval)); 6104 } 6105 } 6106 6107 /* 6108 * Send SAS IO Unit Control to free the dev handle 6109 */ 6110 rval = mptsas_free_devhdl(mpt, devhdl); 6111 NDBG20(("mptsas%d handle_topo_change to remove " 6112 "devhdl:%x, rval:%x", mpt->m_instance, devhdl, 6113 rval)); 6114 break; 6115 } 6116 case MPTSAS_DR_EVENT_RECONFIG_SMP: 6117 { 6118 mptsas_smp_t smp; 6119 dev_info_t *smpdip; 6120 mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl; 6121 6122 devhdl = topo_node->devhdl; 6123 6124 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL & 6125 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl; 6126 rval = mptsas_get_sas_expander_page0(mpt, page_address, &smp); 6127 if (rval != DDI_SUCCESS) { 6128 mptsas_log(mpt, CE_WARN, "failed to online smp, " 6129 "handle %x", devhdl); 6130 return; 6131 } 6132 6133 psmp = mptsas_smp_alloc(smptbl, &smp); 6134 if (psmp == NULL) { 6135 return; 6136 } 6137 6138 mutex_exit(&mpt->m_mutex); 6139 ndi_devi_enter(parent, &circ1); 6140 (void) mptsas_online_smp(parent, psmp, &smpdip); 6141 ndi_devi_exit(parent, circ1); 6142 6143 mutex_enter(&mpt->m_mutex); 6144 break; 6145 } 6146 case MPTSAS_DR_EVENT_OFFLINE_SMP: 6147 { 6148 mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl; 6149 devhdl = topo_node->devhdl; 6150 uint32_t dev_info; 6151 6152 psmp = mptsas_search_by_devhdl(smptbl, devhdl); 6153 if (psmp == NULL) 6154 break; 6155 /* 6156 * The mptsas_smp_t data is released only if the dip is offlined 6157 * successfully. 6158 */ 6159 mutex_exit(&mpt->m_mutex); 6160 6161 ndi_devi_enter(parent, &circ1); 6162 rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE); 6163 ndi_devi_exit(parent, circ1); 6164 6165 dev_info = psmp->m_deviceinfo; 6166 if ((dev_info & DEVINFO_DIRECT_ATTACHED) == 6167 DEVINFO_DIRECT_ATTACHED) { 6168 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6169 MPTSAS_VIRTUAL_PORT, 1) != 6170 DDI_PROP_SUCCESS) { 6171 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6172 MPTSAS_VIRTUAL_PORT); 6173 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 6174 "prop update failed"); 6175 return; 6176 } 6177 /* 6178 * Check whether the smp connected to the iport, 6179 */ 6180 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6181 MPTSAS_NUM_PHYS, 0) != 6182 DDI_PROP_SUCCESS) { 6183 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6184 MPTSAS_NUM_PHYS); 6185 mptsas_log(mpt, CE_WARN, "mptsas num phys" 6186 "prop update failed"); 6187 return; 6188 } 6189 /* 6190 * Clear parent's attached-port props 6191 */ 6192 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6193 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent, 6194 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 6195 DDI_PROP_SUCCESS) { 6196 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6197 SCSI_ADDR_PROP_ATTACHED_PORT); 6198 mptsas_log(mpt, CE_WARN, "mptsas attached port " 6199 "prop update failed"); 6200 return; 6201 } 6202 } 6203 6204 mutex_enter(&mpt->m_mutex); 6205 NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, " 6206 "rval:%x", mpt->m_instance, psmp->m_devhdl, rval)); 6207 if (rval == DDI_SUCCESS) { 6208 mptsas_smp_free(smptbl, psmp->m_sasaddr, 6209 psmp->m_phymask); 6210 } else { 6211 psmp->m_devhdl = MPTSAS_INVALID_DEVHDL; 6212 } 6213 6214 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6215 6216 break; 6217 } 6218 default: 6219 return; 6220 } 6221 } 6222 6223 /* 6224 * Record the event if its type is enabled in mpt instance by ioctl. 6225 */ 6226 static void 6227 mptsas_record_event(void *args) 6228 { 6229 m_replyh_arg_t *replyh_arg; 6230 pMpi2EventNotificationReply_t eventreply; 6231 uint32_t event, rfm; 6232 mptsas_t *mpt; 6233 int i, j; 6234 uint16_t event_data_len; 6235 boolean_t sendAEN = FALSE; 6236 6237 replyh_arg = (m_replyh_arg_t *)args; 6238 rfm = replyh_arg->rfm; 6239 mpt = replyh_arg->mpt; 6240 6241 eventreply = (pMpi2EventNotificationReply_t) 6242 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr)); 6243 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 6244 6245 6246 /* 6247 * Generate a system event to let anyone who cares know that a 6248 * LOG_ENTRY_ADDED event has occurred. This is sent no matter what the 6249 * event mask is set to. 6250 */ 6251 if (event == MPI2_EVENT_LOG_ENTRY_ADDED) { 6252 sendAEN = TRUE; 6253 } 6254 6255 /* 6256 * Record the event only if it is not masked. Determine which dword 6257 * and bit of event mask to test. 6258 */ 6259 i = (uint8_t)(event / 32); 6260 j = (uint8_t)(event % 32); 6261 if ((i < 4) && ((1 << j) & mpt->m_event_mask[i])) { 6262 i = mpt->m_event_index; 6263 mpt->m_events[i].Type = event; 6264 mpt->m_events[i].Number = ++mpt->m_event_number; 6265 bzero(mpt->m_events[i].Data, MPTSAS_MAX_EVENT_DATA_LENGTH * 4); 6266 event_data_len = ddi_get16(mpt->m_acc_reply_frame_hdl, 6267 &eventreply->EventDataLength); 6268 6269 if (event_data_len > 0) { 6270 /* 6271 * Limit data to size in m_event entry 6272 */ 6273 if (event_data_len > MPTSAS_MAX_EVENT_DATA_LENGTH) { 6274 event_data_len = MPTSAS_MAX_EVENT_DATA_LENGTH; 6275 } 6276 for (j = 0; j < event_data_len; j++) { 6277 mpt->m_events[i].Data[j] = 6278 ddi_get32(mpt->m_acc_reply_frame_hdl, 6279 &(eventreply->EventData[j])); 6280 } 6281 6282 /* 6283 * check for index wrap-around 6284 */ 6285 if (++i == MPTSAS_EVENT_QUEUE_SIZE) { 6286 i = 0; 6287 } 6288 mpt->m_event_index = (uint8_t)i; 6289 6290 /* 6291 * Set flag to send the event. 6292 */ 6293 sendAEN = TRUE; 6294 } 6295 } 6296 6297 /* 6298 * Generate a system event if flag is set to let anyone who cares know 6299 * that an event has occurred. 6300 */ 6301 if (sendAEN) { 6302 (void) ddi_log_sysevent(mpt->m_dip, DDI_VENDOR_LSI, "MPT_SAS", 6303 "SAS", NULL, NULL, DDI_NOSLEEP); 6304 } 6305 } 6306 6307 #define SMP_RESET_IN_PROGRESS MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS 6308 /* 6309 * handle sync events from ioc in interrupt 6310 * return value: 6311 * DDI_SUCCESS: The event is handled by this func 6312 * DDI_FAILURE: Event is not handled 6313 */ 6314 static int 6315 mptsas_handle_event_sync(void *args) 6316 { 6317 m_replyh_arg_t *replyh_arg; 6318 pMpi2EventNotificationReply_t eventreply; 6319 uint32_t event, rfm; 6320 mptsas_t *mpt; 6321 uint_t iocstatus; 6322 6323 replyh_arg = (m_replyh_arg_t *)args; 6324 rfm = replyh_arg->rfm; 6325 mpt = replyh_arg->mpt; 6326 6327 ASSERT(mutex_owned(&mpt->m_mutex)); 6328 6329 eventreply = (pMpi2EventNotificationReply_t) 6330 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr)); 6331 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 6332 6333 if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 6334 &eventreply->IOCStatus)) { 6335 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 6336 mptsas_log(mpt, CE_WARN, 6337 "!mptsas_handle_event_sync: IOCStatus=0x%x, " 6338 "IOCLogInfo=0x%x", iocstatus, 6339 ddi_get32(mpt->m_acc_reply_frame_hdl, 6340 &eventreply->IOCLogInfo)); 6341 } else { 6342 mptsas_log(mpt, CE_WARN, 6343 "mptsas_handle_event_sync: IOCStatus=0x%x, " 6344 "IOCLogInfo=0x%x", iocstatus, 6345 ddi_get32(mpt->m_acc_reply_frame_hdl, 6346 &eventreply->IOCLogInfo)); 6347 } 6348 } 6349 6350 /* 6351 * figure out what kind of event we got and handle accordingly 6352 */ 6353 switch (event) { 6354 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 6355 { 6356 pMpi2EventDataSasTopologyChangeList_t sas_topo_change_list; 6357 uint8_t num_entries, expstatus, phy; 6358 uint8_t phystatus, physport, state, i; 6359 uint8_t start_phy_num, link_rate; 6360 uint16_t dev_handle, reason_code; 6361 uint16_t enc_handle, expd_handle; 6362 char string[80], curr[80], prev[80]; 6363 mptsas_topo_change_list_t *topo_head = NULL; 6364 mptsas_topo_change_list_t *topo_tail = NULL; 6365 mptsas_topo_change_list_t *topo_node = NULL; 6366 mptsas_target_t *ptgt; 6367 mptsas_smp_t *psmp; 6368 mptsas_hash_table_t *tgttbl, *smptbl; 6369 uint8_t flags = 0, exp_flag; 6370 smhba_info_t *pSmhba = NULL; 6371 6372 NDBG20(("mptsas_handle_event_sync: SAS topology change")); 6373 6374 tgttbl = &mpt->m_active->m_tgttbl; 6375 smptbl = &mpt->m_active->m_smptbl; 6376 6377 sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t) 6378 eventreply->EventData; 6379 6380 enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6381 &sas_topo_change_list->EnclosureHandle); 6382 expd_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6383 &sas_topo_change_list->ExpanderDevHandle); 6384 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl, 6385 &sas_topo_change_list->NumEntries); 6386 start_phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl, 6387 &sas_topo_change_list->StartPhyNum); 6388 expstatus = ddi_get8(mpt->m_acc_reply_frame_hdl, 6389 &sas_topo_change_list->ExpStatus); 6390 physport = ddi_get8(mpt->m_acc_reply_frame_hdl, 6391 &sas_topo_change_list->PhysicalPort); 6392 6393 string[0] = 0; 6394 if (expd_handle) { 6395 flags = MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED; 6396 switch (expstatus) { 6397 case MPI2_EVENT_SAS_TOPO_ES_ADDED: 6398 (void) sprintf(string, " added"); 6399 /* 6400 * New expander device added 6401 */ 6402 mpt->m_port_chng = 1; 6403 topo_node = kmem_zalloc( 6404 sizeof (mptsas_topo_change_list_t), 6405 KM_SLEEP); 6406 topo_node->mpt = mpt; 6407 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_SMP; 6408 topo_node->un.physport = physport; 6409 topo_node->devhdl = expd_handle; 6410 topo_node->flags = flags; 6411 topo_node->object = NULL; 6412 if (topo_head == NULL) { 6413 topo_head = topo_tail = topo_node; 6414 } else { 6415 topo_tail->next = topo_node; 6416 topo_tail = topo_node; 6417 } 6418 break; 6419 case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING: 6420 (void) sprintf(string, " not responding, " 6421 "removed"); 6422 psmp = mptsas_search_by_devhdl(smptbl, 6423 expd_handle); 6424 if (psmp == NULL) 6425 break; 6426 6427 topo_node = kmem_zalloc( 6428 sizeof (mptsas_topo_change_list_t), 6429 KM_SLEEP); 6430 topo_node->mpt = mpt; 6431 topo_node->un.phymask = psmp->m_phymask; 6432 topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP; 6433 topo_node->devhdl = expd_handle; 6434 topo_node->flags = flags; 6435 topo_node->object = NULL; 6436 if (topo_head == NULL) { 6437 topo_head = topo_tail = topo_node; 6438 } else { 6439 topo_tail->next = topo_node; 6440 topo_tail = topo_node; 6441 } 6442 break; 6443 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING: 6444 break; 6445 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING: 6446 (void) sprintf(string, " not responding, " 6447 "delaying removal"); 6448 break; 6449 default: 6450 break; 6451 } 6452 } else { 6453 flags = MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE; 6454 } 6455 6456 NDBG20(("SAS TOPOLOGY CHANGE for enclosure %x expander %x%s\n", 6457 enc_handle, expd_handle, string)); 6458 for (i = 0; i < num_entries; i++) { 6459 phy = i + start_phy_num; 6460 phystatus = ddi_get8(mpt->m_acc_reply_frame_hdl, 6461 &sas_topo_change_list->PHY[i].PhyStatus); 6462 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6463 &sas_topo_change_list->PHY[i].AttachedDevHandle); 6464 reason_code = phystatus & MPI2_EVENT_SAS_TOPO_RC_MASK; 6465 /* 6466 * Filter out processing of Phy Vacant Status unless 6467 * the reason code is "Not Responding". Process all 6468 * other combinations of Phy Status and Reason Codes. 6469 */ 6470 if ((phystatus & 6471 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) && 6472 (reason_code != 6473 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) { 6474 continue; 6475 } 6476 curr[0] = 0; 6477 prev[0] = 0; 6478 string[0] = 0; 6479 switch (reason_code) { 6480 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 6481 { 6482 NDBG20(("mptsas%d phy %d physical_port %d " 6483 "dev_handle %d added", mpt->m_instance, phy, 6484 physport, dev_handle)); 6485 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl, 6486 &sas_topo_change_list->PHY[i].LinkRate); 6487 state = (link_rate & 6488 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >> 6489 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT; 6490 switch (state) { 6491 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 6492 (void) sprintf(curr, "is disabled"); 6493 break; 6494 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 6495 (void) sprintf(curr, "is offline, " 6496 "failed speed negotiation"); 6497 break; 6498 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 6499 (void) sprintf(curr, "SATA OOB " 6500 "complete"); 6501 break; 6502 case SMP_RESET_IN_PROGRESS: 6503 (void) sprintf(curr, "SMP reset in " 6504 "progress"); 6505 break; 6506 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 6507 (void) sprintf(curr, "is online at " 6508 "1.5 Gbps"); 6509 break; 6510 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 6511 (void) sprintf(curr, "is online at 3.0 " 6512 "Gbps"); 6513 break; 6514 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 6515 (void) sprintf(curr, "is online at 6.0 " 6516 "Gbps"); 6517 break; 6518 default: 6519 (void) sprintf(curr, "state is " 6520 "unknown"); 6521 break; 6522 } 6523 /* 6524 * New target device added into the system. 6525 * Set association flag according to if an 6526 * expander is used or not. 6527 */ 6528 exp_flag = 6529 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE; 6530 if (flags == 6531 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) { 6532 flags = exp_flag; 6533 } 6534 topo_node = kmem_zalloc( 6535 sizeof (mptsas_topo_change_list_t), 6536 KM_SLEEP); 6537 topo_node->mpt = mpt; 6538 topo_node->event = 6539 MPTSAS_DR_EVENT_RECONFIG_TARGET; 6540 if (expd_handle == 0) { 6541 /* 6542 * Per MPI 2, if expander dev handle 6543 * is 0, it's a directly attached 6544 * device. So driver use PHY to decide 6545 * which iport is associated 6546 */ 6547 physport = phy; 6548 mpt->m_port_chng = 1; 6549 } 6550 topo_node->un.physport = physport; 6551 topo_node->devhdl = dev_handle; 6552 topo_node->flags = flags; 6553 topo_node->object = NULL; 6554 if (topo_head == NULL) { 6555 topo_head = topo_tail = topo_node; 6556 } else { 6557 topo_tail->next = topo_node; 6558 topo_tail = topo_node; 6559 } 6560 break; 6561 } 6562 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 6563 { 6564 NDBG20(("mptsas%d phy %d physical_port %d " 6565 "dev_handle %d removed", mpt->m_instance, 6566 phy, physport, dev_handle)); 6567 /* 6568 * Set association flag according to if an 6569 * expander is used or not. 6570 */ 6571 exp_flag = 6572 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE; 6573 if (flags == 6574 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) { 6575 flags = exp_flag; 6576 } 6577 /* 6578 * Target device is removed from the system 6579 * Before the device is really offline from 6580 * from system. 6581 */ 6582 ptgt = mptsas_search_by_devhdl(tgttbl, 6583 dev_handle); 6584 /* 6585 * If ptgt is NULL here, it means that the 6586 * DevHandle is not in the hash table. This is 6587 * reasonable sometimes. For example, if a 6588 * disk was pulled, then added, then pulled 6589 * again, the disk will not have been put into 6590 * the hash table because the add event will 6591 * have an invalid phymask. BUT, this does not 6592 * mean that the DevHandle is invalid. The 6593 * controller will still have a valid DevHandle 6594 * that must be removed. To do this, use the 6595 * MPTSAS_TOPO_FLAG_REMOVE_HANDLE event. 6596 */ 6597 if (ptgt == NULL) { 6598 topo_node = kmem_zalloc( 6599 sizeof (mptsas_topo_change_list_t), 6600 KM_SLEEP); 6601 topo_node->mpt = mpt; 6602 topo_node->un.phymask = 0; 6603 topo_node->event = 6604 MPTSAS_TOPO_FLAG_REMOVE_HANDLE; 6605 topo_node->devhdl = dev_handle; 6606 topo_node->flags = flags; 6607 topo_node->object = NULL; 6608 if (topo_head == NULL) { 6609 topo_head = topo_tail = 6610 topo_node; 6611 } else { 6612 topo_tail->next = topo_node; 6613 topo_tail = topo_node; 6614 } 6615 break; 6616 } 6617 6618 /* 6619 * Update DR flag immediately avoid I/O failure 6620 * before failover finish. Pay attention to the 6621 * mutex protect, we need grab m_tx_waitq_mutex 6622 * during set m_dr_flag because we won't add 6623 * the following command into waitq, instead, 6624 * we need return TRAN_BUSY in the tran_start 6625 * context. 6626 */ 6627 mutex_enter(&mpt->m_tx_waitq_mutex); 6628 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 6629 mutex_exit(&mpt->m_tx_waitq_mutex); 6630 6631 topo_node = kmem_zalloc( 6632 sizeof (mptsas_topo_change_list_t), 6633 KM_SLEEP); 6634 topo_node->mpt = mpt; 6635 topo_node->un.phymask = ptgt->m_phymask; 6636 topo_node->event = 6637 MPTSAS_DR_EVENT_OFFLINE_TARGET; 6638 topo_node->devhdl = dev_handle; 6639 topo_node->flags = flags; 6640 topo_node->object = NULL; 6641 if (topo_head == NULL) { 6642 topo_head = topo_tail = topo_node; 6643 } else { 6644 topo_tail->next = topo_node; 6645 topo_tail = topo_node; 6646 } 6647 break; 6648 } 6649 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 6650 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl, 6651 &sas_topo_change_list->PHY[i].LinkRate); 6652 state = (link_rate & 6653 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >> 6654 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT; 6655 pSmhba = &mpt->m_phy_info[i].smhba_info; 6656 pSmhba->negotiated_link_rate = state; 6657 switch (state) { 6658 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 6659 (void) sprintf(curr, "is disabled"); 6660 mptsas_smhba_log_sysevent(mpt, 6661 ESC_SAS_PHY_EVENT, 6662 SAS_PHY_REMOVE, 6663 &mpt->m_phy_info[i].smhba_info); 6664 mpt->m_phy_info[i].smhba_info. 6665 negotiated_link_rate 6666 = 0x1; 6667 break; 6668 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 6669 (void) sprintf(curr, "is offline, " 6670 "failed speed negotiation"); 6671 mptsas_smhba_log_sysevent(mpt, 6672 ESC_SAS_PHY_EVENT, 6673 SAS_PHY_OFFLINE, 6674 &mpt->m_phy_info[i].smhba_info); 6675 break; 6676 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 6677 (void) sprintf(curr, "SATA OOB " 6678 "complete"); 6679 break; 6680 case SMP_RESET_IN_PROGRESS: 6681 (void) sprintf(curr, "SMP reset in " 6682 "progress"); 6683 break; 6684 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 6685 (void) sprintf(curr, "is online at " 6686 "1.5 Gbps"); 6687 if ((expd_handle == 0) && 6688 (enc_handle == 1)) { 6689 mpt->m_port_chng = 1; 6690 } 6691 mptsas_smhba_log_sysevent(mpt, 6692 ESC_SAS_PHY_EVENT, 6693 SAS_PHY_ONLINE, 6694 &mpt->m_phy_info[i].smhba_info); 6695 break; 6696 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 6697 (void) sprintf(curr, "is online at 3.0 " 6698 "Gbps"); 6699 if ((expd_handle == 0) && 6700 (enc_handle == 1)) { 6701 mpt->m_port_chng = 1; 6702 } 6703 mptsas_smhba_log_sysevent(mpt, 6704 ESC_SAS_PHY_EVENT, 6705 SAS_PHY_ONLINE, 6706 &mpt->m_phy_info[i].smhba_info); 6707 break; 6708 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 6709 (void) sprintf(curr, "is online at " 6710 "6.0 Gbps"); 6711 if ((expd_handle == 0) && 6712 (enc_handle == 1)) { 6713 mpt->m_port_chng = 1; 6714 } 6715 mptsas_smhba_log_sysevent(mpt, 6716 ESC_SAS_PHY_EVENT, 6717 SAS_PHY_ONLINE, 6718 &mpt->m_phy_info[i].smhba_info); 6719 break; 6720 default: 6721 (void) sprintf(curr, "state is " 6722 "unknown"); 6723 break; 6724 } 6725 6726 state = (link_rate & 6727 MPI2_EVENT_SAS_TOPO_LR_PREV_MASK) >> 6728 MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT; 6729 switch (state) { 6730 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 6731 (void) sprintf(prev, ", was disabled"); 6732 break; 6733 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 6734 (void) sprintf(prev, ", was offline, " 6735 "failed speed negotiation"); 6736 break; 6737 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 6738 (void) sprintf(prev, ", was SATA OOB " 6739 "complete"); 6740 break; 6741 case SMP_RESET_IN_PROGRESS: 6742 (void) sprintf(prev, ", was SMP reset " 6743 "in progress"); 6744 break; 6745 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 6746 (void) sprintf(prev, ", was online at " 6747 "1.5 Gbps"); 6748 break; 6749 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 6750 (void) sprintf(prev, ", was online at " 6751 "3.0 Gbps"); 6752 break; 6753 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 6754 (void) sprintf(prev, ", was online at " 6755 "6.0 Gbps"); 6756 break; 6757 default: 6758 break; 6759 } 6760 (void) sprintf(&string[strlen(string)], "link " 6761 "changed, "); 6762 break; 6763 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE: 6764 continue; 6765 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING: 6766 (void) sprintf(&string[strlen(string)], 6767 "target not responding, delaying " 6768 "removal"); 6769 break; 6770 } 6771 NDBG20(("mptsas%d phy %d DevHandle %x, %s%s%s\n", 6772 mpt->m_instance, phy, dev_handle, string, curr, 6773 prev)); 6774 } 6775 if (topo_head != NULL) { 6776 /* 6777 * Launch DR taskq to handle topology change 6778 */ 6779 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 6780 mptsas_handle_dr, (void *)topo_head, 6781 DDI_NOSLEEP)) != DDI_SUCCESS) { 6782 mptsas_log(mpt, CE_NOTE, "mptsas start taskq " 6783 "for handle SAS DR event failed. \n"); 6784 } 6785 } 6786 break; 6787 } 6788 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 6789 { 6790 Mpi2EventDataIrConfigChangeList_t *irChangeList; 6791 mptsas_topo_change_list_t *topo_head = NULL; 6792 mptsas_topo_change_list_t *topo_tail = NULL; 6793 mptsas_topo_change_list_t *topo_node = NULL; 6794 mptsas_target_t *ptgt; 6795 mptsas_hash_table_t *tgttbl; 6796 uint8_t num_entries, i, reason; 6797 uint16_t volhandle, diskhandle; 6798 6799 irChangeList = (pMpi2EventDataIrConfigChangeList_t) 6800 eventreply->EventData; 6801 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl, 6802 &irChangeList->NumElements); 6803 6804 tgttbl = &mpt->m_active->m_tgttbl; 6805 6806 NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received", 6807 mpt->m_instance)); 6808 6809 for (i = 0; i < num_entries; i++) { 6810 reason = ddi_get8(mpt->m_acc_reply_frame_hdl, 6811 &irChangeList->ConfigElement[i].ReasonCode); 6812 volhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6813 &irChangeList->ConfigElement[i].VolDevHandle); 6814 diskhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6815 &irChangeList->ConfigElement[i].PhysDiskDevHandle); 6816 6817 switch (reason) { 6818 case MPI2_EVENT_IR_CHANGE_RC_ADDED: 6819 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: 6820 { 6821 NDBG20(("mptsas %d volume added\n", 6822 mpt->m_instance)); 6823 6824 topo_node = kmem_zalloc( 6825 sizeof (mptsas_topo_change_list_t), 6826 KM_SLEEP); 6827 6828 topo_node->mpt = mpt; 6829 topo_node->event = 6830 MPTSAS_DR_EVENT_RECONFIG_TARGET; 6831 topo_node->un.physport = 0xff; 6832 topo_node->devhdl = volhandle; 6833 topo_node->flags = 6834 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED; 6835 topo_node->object = NULL; 6836 if (topo_head == NULL) { 6837 topo_head = topo_tail = topo_node; 6838 } else { 6839 topo_tail->next = topo_node; 6840 topo_tail = topo_node; 6841 } 6842 break; 6843 } 6844 case MPI2_EVENT_IR_CHANGE_RC_REMOVED: 6845 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: 6846 { 6847 NDBG20(("mptsas %d volume deleted\n", 6848 mpt->m_instance)); 6849 ptgt = mptsas_search_by_devhdl(tgttbl, 6850 volhandle); 6851 if (ptgt == NULL) 6852 break; 6853 6854 /* 6855 * Clear any flags related to volume 6856 */ 6857 (void) mptsas_delete_volume(mpt, volhandle); 6858 6859 /* 6860 * Update DR flag immediately avoid I/O failure 6861 */ 6862 mutex_enter(&mpt->m_tx_waitq_mutex); 6863 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 6864 mutex_exit(&mpt->m_tx_waitq_mutex); 6865 6866 topo_node = kmem_zalloc( 6867 sizeof (mptsas_topo_change_list_t), 6868 KM_SLEEP); 6869 topo_node->mpt = mpt; 6870 topo_node->un.phymask = ptgt->m_phymask; 6871 topo_node->event = 6872 MPTSAS_DR_EVENT_OFFLINE_TARGET; 6873 topo_node->devhdl = volhandle; 6874 topo_node->flags = 6875 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED; 6876 topo_node->object = (void *)ptgt; 6877 if (topo_head == NULL) { 6878 topo_head = topo_tail = topo_node; 6879 } else { 6880 topo_tail->next = topo_node; 6881 topo_tail = topo_node; 6882 } 6883 break; 6884 } 6885 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: 6886 case MPI2_EVENT_IR_CHANGE_RC_HIDE: 6887 { 6888 ptgt = mptsas_search_by_devhdl(tgttbl, 6889 diskhandle); 6890 if (ptgt == NULL) 6891 break; 6892 6893 /* 6894 * Update DR flag immediately avoid I/O failure 6895 */ 6896 mutex_enter(&mpt->m_tx_waitq_mutex); 6897 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 6898 mutex_exit(&mpt->m_tx_waitq_mutex); 6899 6900 topo_node = kmem_zalloc( 6901 sizeof (mptsas_topo_change_list_t), 6902 KM_SLEEP); 6903 topo_node->mpt = mpt; 6904 topo_node->un.phymask = ptgt->m_phymask; 6905 topo_node->event = 6906 MPTSAS_DR_EVENT_OFFLINE_TARGET; 6907 topo_node->devhdl = diskhandle; 6908 topo_node->flags = 6909 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED; 6910 topo_node->object = (void *)ptgt; 6911 if (topo_head == NULL) { 6912 topo_head = topo_tail = topo_node; 6913 } else { 6914 topo_tail->next = topo_node; 6915 topo_tail = topo_node; 6916 } 6917 break; 6918 } 6919 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: 6920 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: 6921 { 6922 /* 6923 * The physical drive is released by a IR 6924 * volume. But we cannot get the the physport 6925 * or phynum from the event data, so we only 6926 * can get the physport/phynum after SAS 6927 * Device Page0 request for the devhdl. 6928 */ 6929 topo_node = kmem_zalloc( 6930 sizeof (mptsas_topo_change_list_t), 6931 KM_SLEEP); 6932 topo_node->mpt = mpt; 6933 topo_node->un.phymask = 0; 6934 topo_node->event = 6935 MPTSAS_DR_EVENT_RECONFIG_TARGET; 6936 topo_node->devhdl = diskhandle; 6937 topo_node->flags = 6938 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED; 6939 topo_node->object = NULL; 6940 mpt->m_port_chng = 1; 6941 if (topo_head == NULL) { 6942 topo_head = topo_tail = topo_node; 6943 } else { 6944 topo_tail->next = topo_node; 6945 topo_tail = topo_node; 6946 } 6947 break; 6948 } 6949 default: 6950 break; 6951 } 6952 } 6953 6954 if (topo_head != NULL) { 6955 /* 6956 * Launch DR taskq to handle topology change 6957 */ 6958 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 6959 mptsas_handle_dr, (void *)topo_head, 6960 DDI_NOSLEEP)) != DDI_SUCCESS) { 6961 mptsas_log(mpt, CE_NOTE, "mptsas start taskq " 6962 "for handle SAS DR event failed. \n"); 6963 } 6964 } 6965 break; 6966 } 6967 default: 6968 return (DDI_FAILURE); 6969 } 6970 6971 return (DDI_SUCCESS); 6972 } 6973 6974 /* 6975 * handle events from ioc 6976 */ 6977 static void 6978 mptsas_handle_event(void *args) 6979 { 6980 m_replyh_arg_t *replyh_arg; 6981 pMpi2EventNotificationReply_t eventreply; 6982 uint32_t event, iocloginfo, rfm; 6983 uint32_t status; 6984 uint8_t port; 6985 mptsas_t *mpt; 6986 uint_t iocstatus; 6987 6988 replyh_arg = (m_replyh_arg_t *)args; 6989 rfm = replyh_arg->rfm; 6990 mpt = replyh_arg->mpt; 6991 6992 mutex_enter(&mpt->m_mutex); 6993 6994 eventreply = (pMpi2EventNotificationReply_t) 6995 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr)); 6996 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 6997 6998 if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 6999 &eventreply->IOCStatus)) { 7000 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 7001 mptsas_log(mpt, CE_WARN, 7002 "!mptsas_handle_event: IOCStatus=0x%x, " 7003 "IOCLogInfo=0x%x", iocstatus, 7004 ddi_get32(mpt->m_acc_reply_frame_hdl, 7005 &eventreply->IOCLogInfo)); 7006 } else { 7007 mptsas_log(mpt, CE_WARN, 7008 "mptsas_handle_event: IOCStatus=0x%x, " 7009 "IOCLogInfo=0x%x", iocstatus, 7010 ddi_get32(mpt->m_acc_reply_frame_hdl, 7011 &eventreply->IOCLogInfo)); 7012 } 7013 } 7014 7015 /* 7016 * figure out what kind of event we got and handle accordingly 7017 */ 7018 switch (event) { 7019 case MPI2_EVENT_LOG_ENTRY_ADDED: 7020 break; 7021 case MPI2_EVENT_LOG_DATA: 7022 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 7023 &eventreply->IOCLogInfo); 7024 NDBG20(("mptsas %d log info %x received.\n", mpt->m_instance, 7025 iocloginfo)); 7026 break; 7027 case MPI2_EVENT_STATE_CHANGE: 7028 NDBG20(("mptsas%d state change.", mpt->m_instance)); 7029 break; 7030 case MPI2_EVENT_HARD_RESET_RECEIVED: 7031 NDBG20(("mptsas%d event change.", mpt->m_instance)); 7032 break; 7033 case MPI2_EVENT_SAS_DISCOVERY: 7034 { 7035 MPI2_EVENT_DATA_SAS_DISCOVERY *sasdiscovery; 7036 char string[80]; 7037 uint8_t rc; 7038 7039 sasdiscovery = 7040 (pMpi2EventDataSasDiscovery_t)eventreply->EventData; 7041 7042 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7043 &sasdiscovery->ReasonCode); 7044 port = ddi_get8(mpt->m_acc_reply_frame_hdl, 7045 &sasdiscovery->PhysicalPort); 7046 status = ddi_get32(mpt->m_acc_reply_frame_hdl, 7047 &sasdiscovery->DiscoveryStatus); 7048 7049 string[0] = 0; 7050 switch (rc) { 7051 case MPI2_EVENT_SAS_DISC_RC_STARTED: 7052 (void) sprintf(string, "STARTING"); 7053 break; 7054 case MPI2_EVENT_SAS_DISC_RC_COMPLETED: 7055 (void) sprintf(string, "COMPLETED"); 7056 break; 7057 default: 7058 (void) sprintf(string, "UNKNOWN"); 7059 break; 7060 } 7061 7062 NDBG20(("SAS DISCOVERY is %s for port %d, status %x", string, 7063 port, status)); 7064 7065 break; 7066 } 7067 case MPI2_EVENT_EVENT_CHANGE: 7068 NDBG20(("mptsas%d event change.", mpt->m_instance)); 7069 break; 7070 case MPI2_EVENT_TASK_SET_FULL: 7071 { 7072 pMpi2EventDataTaskSetFull_t taskfull; 7073 7074 taskfull = (pMpi2EventDataTaskSetFull_t)eventreply->EventData; 7075 7076 NDBG20(("TASK_SET_FULL received for mptsas%d, depth %d\n", 7077 mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl, 7078 &taskfull->CurrentDepth))); 7079 break; 7080 } 7081 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 7082 { 7083 /* 7084 * SAS TOPOLOGY CHANGE LIST Event has already been handled 7085 * in mptsas_handle_event_sync() of interrupt context 7086 */ 7087 break; 7088 } 7089 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: 7090 { 7091 pMpi2EventDataSasEnclDevStatusChange_t encstatus; 7092 uint8_t rc; 7093 char string[80]; 7094 7095 encstatus = (pMpi2EventDataSasEnclDevStatusChange_t) 7096 eventreply->EventData; 7097 7098 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7099 &encstatus->ReasonCode); 7100 switch (rc) { 7101 case MPI2_EVENT_SAS_ENCL_RC_ADDED: 7102 (void) sprintf(string, "added"); 7103 break; 7104 case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING: 7105 (void) sprintf(string, ", not responding"); 7106 break; 7107 default: 7108 break; 7109 } 7110 NDBG20(("mptsas%d ENCLOSURE STATUS CHANGE for enclosure %x%s\n", 7111 mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl, 7112 &encstatus->EnclosureHandle), string)); 7113 break; 7114 } 7115 7116 /* 7117 * MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE is handled by 7118 * mptsas_handle_event_sync,in here just send ack message. 7119 */ 7120 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: 7121 { 7122 pMpi2EventDataSasDeviceStatusChange_t statuschange; 7123 uint8_t rc; 7124 uint16_t devhdl; 7125 uint64_t wwn = 0; 7126 uint32_t wwn_lo, wwn_hi; 7127 7128 statuschange = (pMpi2EventDataSasDeviceStatusChange_t) 7129 eventreply->EventData; 7130 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7131 &statuschange->ReasonCode); 7132 wwn_lo = ddi_get32(mpt->m_acc_reply_frame_hdl, 7133 (uint32_t *)(void *)&statuschange->SASAddress); 7134 wwn_hi = ddi_get32(mpt->m_acc_reply_frame_hdl, 7135 (uint32_t *)(void *)&statuschange->SASAddress + 1); 7136 wwn = ((uint64_t)wwn_hi << 32) | wwn_lo; 7137 devhdl = ddi_get16(mpt->m_acc_reply_frame_hdl, 7138 &statuschange->DevHandle); 7139 7140 NDBG13(("MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE wwn is %"PRIx64, 7141 wwn)); 7142 7143 switch (rc) { 7144 case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA: 7145 NDBG20(("SMART data received, ASC/ASCQ = %02x/%02x", 7146 ddi_get8(mpt->m_acc_reply_frame_hdl, 7147 &statuschange->ASC), 7148 ddi_get8(mpt->m_acc_reply_frame_hdl, 7149 &statuschange->ASCQ))); 7150 break; 7151 7152 case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED: 7153 NDBG20(("Device not supported")); 7154 break; 7155 7156 case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: 7157 NDBG20(("IOC internally generated the Target Reset " 7158 "for devhdl:%x", devhdl)); 7159 break; 7160 7161 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET: 7162 NDBG20(("IOC's internally generated Target Reset " 7163 "completed for devhdl:%x", devhdl)); 7164 break; 7165 7166 case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: 7167 NDBG20(("IOC internally generated Abort Task")); 7168 break; 7169 7170 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL: 7171 NDBG20(("IOC's internally generated Abort Task " 7172 "completed")); 7173 break; 7174 7175 case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: 7176 NDBG20(("IOC internally generated Abort Task Set")); 7177 break; 7178 7179 case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: 7180 NDBG20(("IOC internally generated Clear Task Set")); 7181 break; 7182 7183 case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: 7184 NDBG20(("IOC internally generated Query Task")); 7185 break; 7186 7187 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION: 7188 NDBG20(("Device sent an Asynchronous Notification")); 7189 break; 7190 7191 default: 7192 break; 7193 } 7194 break; 7195 } 7196 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 7197 { 7198 /* 7199 * IR TOPOLOGY CHANGE LIST Event has already been handled 7200 * in mpt_handle_event_sync() of interrupt context 7201 */ 7202 break; 7203 } 7204 case MPI2_EVENT_IR_OPERATION_STATUS: 7205 { 7206 Mpi2EventDataIrOperationStatus_t *irOpStatus; 7207 char reason_str[80]; 7208 uint8_t rc, percent; 7209 uint16_t handle; 7210 7211 irOpStatus = (pMpi2EventDataIrOperationStatus_t) 7212 eventreply->EventData; 7213 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7214 &irOpStatus->RAIDOperation); 7215 percent = ddi_get8(mpt->m_acc_reply_frame_hdl, 7216 &irOpStatus->PercentComplete); 7217 handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7218 &irOpStatus->VolDevHandle); 7219 7220 switch (rc) { 7221 case MPI2_EVENT_IR_RAIDOP_RESYNC: 7222 (void) sprintf(reason_str, "resync"); 7223 break; 7224 case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION: 7225 (void) sprintf(reason_str, "online capacity " 7226 "expansion"); 7227 break; 7228 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK: 7229 (void) sprintf(reason_str, "consistency check"); 7230 break; 7231 default: 7232 (void) sprintf(reason_str, "unknown reason %x", 7233 rc); 7234 } 7235 7236 NDBG20(("mptsas%d raid operational status: (%s)" 7237 "\thandle(0x%04x), percent complete(%d)\n", 7238 mpt->m_instance, reason_str, handle, percent)); 7239 break; 7240 } 7241 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: 7242 { 7243 pMpi2EventDataSasBroadcastPrimitive_t sas_broadcast; 7244 uint8_t phy_num; 7245 uint8_t primitive; 7246 7247 sas_broadcast = (pMpi2EventDataSasBroadcastPrimitive_t) 7248 eventreply->EventData; 7249 7250 phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl, 7251 &sas_broadcast->PhyNum); 7252 primitive = ddi_get8(mpt->m_acc_reply_frame_hdl, 7253 &sas_broadcast->Primitive); 7254 7255 switch (primitive) { 7256 case MPI2_EVENT_PRIMITIVE_CHANGE: 7257 mptsas_smhba_log_sysevent(mpt, 7258 ESC_SAS_HBA_PORT_BROADCAST, 7259 SAS_PORT_BROADCAST_CHANGE, 7260 &mpt->m_phy_info[phy_num].smhba_info); 7261 break; 7262 case MPI2_EVENT_PRIMITIVE_SES: 7263 mptsas_smhba_log_sysevent(mpt, 7264 ESC_SAS_HBA_PORT_BROADCAST, 7265 SAS_PORT_BROADCAST_SES, 7266 &mpt->m_phy_info[phy_num].smhba_info); 7267 break; 7268 case MPI2_EVENT_PRIMITIVE_EXPANDER: 7269 mptsas_smhba_log_sysevent(mpt, 7270 ESC_SAS_HBA_PORT_BROADCAST, 7271 SAS_PORT_BROADCAST_D01_4, 7272 &mpt->m_phy_info[phy_num].smhba_info); 7273 break; 7274 case MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT: 7275 mptsas_smhba_log_sysevent(mpt, 7276 ESC_SAS_HBA_PORT_BROADCAST, 7277 SAS_PORT_BROADCAST_D04_7, 7278 &mpt->m_phy_info[phy_num].smhba_info); 7279 break; 7280 case MPI2_EVENT_PRIMITIVE_RESERVED3: 7281 mptsas_smhba_log_sysevent(mpt, 7282 ESC_SAS_HBA_PORT_BROADCAST, 7283 SAS_PORT_BROADCAST_D16_7, 7284 &mpt->m_phy_info[phy_num].smhba_info); 7285 break; 7286 case MPI2_EVENT_PRIMITIVE_RESERVED4: 7287 mptsas_smhba_log_sysevent(mpt, 7288 ESC_SAS_HBA_PORT_BROADCAST, 7289 SAS_PORT_BROADCAST_D29_7, 7290 &mpt->m_phy_info[phy_num].smhba_info); 7291 break; 7292 case MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED: 7293 mptsas_smhba_log_sysevent(mpt, 7294 ESC_SAS_HBA_PORT_BROADCAST, 7295 SAS_PORT_BROADCAST_D24_0, 7296 &mpt->m_phy_info[phy_num].smhba_info); 7297 break; 7298 case MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED: 7299 mptsas_smhba_log_sysevent(mpt, 7300 ESC_SAS_HBA_PORT_BROADCAST, 7301 SAS_PORT_BROADCAST_D27_4, 7302 &mpt->m_phy_info[phy_num].smhba_info); 7303 break; 7304 default: 7305 NDBG20(("mptsas%d: unknown BROADCAST PRIMITIVE" 7306 " %x received", 7307 mpt->m_instance, primitive)); 7308 break; 7309 } 7310 NDBG20(("mptsas%d sas broadcast primitive: " 7311 "\tprimitive(0x%04x), phy(%d) complete\n", 7312 mpt->m_instance, primitive, phy_num)); 7313 break; 7314 } 7315 case MPI2_EVENT_IR_VOLUME: 7316 { 7317 Mpi2EventDataIrVolume_t *irVolume; 7318 uint16_t devhandle; 7319 uint32_t state; 7320 int config, vol; 7321 mptsas_slots_t *slots = mpt->m_active; 7322 uint8_t found = FALSE; 7323 7324 irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData; 7325 state = ddi_get32(mpt->m_acc_reply_frame_hdl, 7326 &irVolume->NewValue); 7327 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7328 &irVolume->VolDevHandle); 7329 7330 NDBG20(("EVENT_IR_VOLUME event is received")); 7331 7332 /* 7333 * Get latest RAID info and then find the DevHandle for this 7334 * event in the configuration. If the DevHandle is not found 7335 * just exit the event. 7336 */ 7337 (void) mptsas_get_raid_info(mpt); 7338 for (config = 0; (config < slots->m_num_raid_configs) && 7339 (!found); config++) { 7340 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) { 7341 if (slots->m_raidconfig[config].m_raidvol[vol]. 7342 m_raidhandle == devhandle) { 7343 found = TRUE; 7344 break; 7345 } 7346 } 7347 } 7348 if (!found) { 7349 break; 7350 } 7351 7352 switch (irVolume->ReasonCode) { 7353 case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED: 7354 { 7355 uint32_t i; 7356 slots->m_raidconfig[config].m_raidvol[vol].m_settings = 7357 state; 7358 7359 i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING; 7360 mptsas_log(mpt, CE_NOTE, " Volume %d settings changed" 7361 ", auto-config of hot-swap drives is %s" 7362 ", write caching is %s" 7363 ", hot-spare pool mask is %02x\n", 7364 vol, state & 7365 MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE 7366 ? "disabled" : "enabled", 7367 i == MPI2_RAIDVOL0_SETTING_UNCHANGED 7368 ? "controlled by member disks" : 7369 i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING 7370 ? "disabled" : 7371 i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING 7372 ? "enabled" : 7373 "incorrectly set", 7374 (state >> 16) & 0xff); 7375 break; 7376 } 7377 case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED: 7378 { 7379 slots->m_raidconfig[config].m_raidvol[vol].m_state = 7380 (uint8_t)state; 7381 7382 mptsas_log(mpt, CE_NOTE, 7383 "Volume %d is now %s\n", vol, 7384 state == MPI2_RAID_VOL_STATE_OPTIMAL 7385 ? "optimal" : 7386 state == MPI2_RAID_VOL_STATE_DEGRADED 7387 ? "degraded" : 7388 state == MPI2_RAID_VOL_STATE_ONLINE 7389 ? "online" : 7390 state == MPI2_RAID_VOL_STATE_INITIALIZING 7391 ? "initializing" : 7392 state == MPI2_RAID_VOL_STATE_FAILED 7393 ? "failed" : 7394 state == MPI2_RAID_VOL_STATE_MISSING 7395 ? "missing" : 7396 "state unknown"); 7397 break; 7398 } 7399 case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED: 7400 { 7401 slots->m_raidconfig[config].m_raidvol[vol]. 7402 m_statusflags = state; 7403 7404 mptsas_log(mpt, CE_NOTE, 7405 " Volume %d is now %s%s%s%s%s%s%s%s%s\n", 7406 vol, 7407 state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED 7408 ? ", enabled" : ", disabled", 7409 state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED 7410 ? ", quiesced" : "", 7411 state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE 7412 ? ", inactive" : ", active", 7413 state & 7414 MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL 7415 ? ", bad block table is full" : "", 7416 state & 7417 MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS 7418 ? ", resync in progress" : "", 7419 state & MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT 7420 ? ", background initialization in progress" : "", 7421 state & 7422 MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION 7423 ? ", capacity expansion in progress" : "", 7424 state & 7425 MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK 7426 ? ", consistency check in progress" : "", 7427 state & MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB 7428 ? ", data scrub in progress" : ""); 7429 break; 7430 } 7431 default: 7432 break; 7433 } 7434 break; 7435 } 7436 case MPI2_EVENT_IR_PHYSICAL_DISK: 7437 { 7438 Mpi2EventDataIrPhysicalDisk_t *irPhysDisk; 7439 uint16_t devhandle, enchandle, slot; 7440 uint32_t status, state; 7441 uint8_t physdisknum, reason; 7442 7443 irPhysDisk = (Mpi2EventDataIrPhysicalDisk_t *) 7444 eventreply->EventData; 7445 physdisknum = ddi_get8(mpt->m_acc_reply_frame_hdl, 7446 &irPhysDisk->PhysDiskNum); 7447 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7448 &irPhysDisk->PhysDiskDevHandle); 7449 enchandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7450 &irPhysDisk->EnclosureHandle); 7451 slot = ddi_get16(mpt->m_acc_reply_frame_hdl, 7452 &irPhysDisk->Slot); 7453 state = ddi_get32(mpt->m_acc_reply_frame_hdl, 7454 &irPhysDisk->NewValue); 7455 reason = ddi_get8(mpt->m_acc_reply_frame_hdl, 7456 &irPhysDisk->ReasonCode); 7457 7458 NDBG20(("EVENT_IR_PHYSICAL_DISK event is received")); 7459 7460 switch (reason) { 7461 case MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED: 7462 mptsas_log(mpt, CE_NOTE, 7463 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 7464 "for enclosure with handle 0x%x is now in hot " 7465 "spare pool %d", 7466 physdisknum, devhandle, slot, enchandle, 7467 (state >> 16) & 0xff); 7468 break; 7469 7470 case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED: 7471 status = state; 7472 mptsas_log(mpt, CE_NOTE, 7473 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 7474 "for enclosure with handle 0x%x is now " 7475 "%s%s%s%s%s\n", physdisknum, devhandle, slot, 7476 enchandle, 7477 status & MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME 7478 ? ", inactive" : ", active", 7479 status & MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC 7480 ? ", out of sync" : "", 7481 status & MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED 7482 ? ", quiesced" : "", 7483 status & 7484 MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED 7485 ? ", write cache enabled" : "", 7486 status & MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET 7487 ? ", capacity expansion target" : ""); 7488 break; 7489 7490 case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED: 7491 mptsas_log(mpt, CE_NOTE, 7492 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 7493 "for enclosure with handle 0x%x is now %s\n", 7494 physdisknum, devhandle, slot, enchandle, 7495 state == MPI2_RAID_PD_STATE_OPTIMAL 7496 ? "optimal" : 7497 state == MPI2_RAID_PD_STATE_REBUILDING 7498 ? "rebuilding" : 7499 state == MPI2_RAID_PD_STATE_DEGRADED 7500 ? "degraded" : 7501 state == MPI2_RAID_PD_STATE_HOT_SPARE 7502 ? "a hot spare" : 7503 state == MPI2_RAID_PD_STATE_ONLINE 7504 ? "online" : 7505 state == MPI2_RAID_PD_STATE_OFFLINE 7506 ? "offline" : 7507 state == MPI2_RAID_PD_STATE_NOT_COMPATIBLE 7508 ? "not compatible" : 7509 state == MPI2_RAID_PD_STATE_NOT_CONFIGURED 7510 ? "not configured" : 7511 "state unknown"); 7512 break; 7513 } 7514 break; 7515 } 7516 default: 7517 NDBG20(("mptsas%d: unknown event %x received", 7518 mpt->m_instance, event)); 7519 break; 7520 } 7521 7522 /* 7523 * Return the reply frame to the free queue. 7524 */ 7525 ddi_put32(mpt->m_acc_free_queue_hdl, 7526 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], rfm); 7527 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 7528 DDI_DMA_SYNC_FORDEV); 7529 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 7530 mpt->m_free_index = 0; 7531 } 7532 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 7533 mpt->m_free_index); 7534 mutex_exit(&mpt->m_mutex); 7535 } 7536 7537 /* 7538 * invoked from timeout() to restart qfull cmds with throttle == 0 7539 */ 7540 static void 7541 mptsas_restart_cmd(void *arg) 7542 { 7543 mptsas_t *mpt = arg; 7544 mptsas_target_t *ptgt = NULL; 7545 7546 mutex_enter(&mpt->m_mutex); 7547 7548 mpt->m_restart_cmd_timeid = 0; 7549 7550 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 7551 MPTSAS_HASH_FIRST); 7552 while (ptgt != NULL) { 7553 if (ptgt->m_reset_delay == 0) { 7554 if (ptgt->m_t_throttle == QFULL_THROTTLE) { 7555 mptsas_set_throttle(mpt, ptgt, 7556 MAX_THROTTLE); 7557 } 7558 } 7559 7560 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 7561 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 7562 } 7563 mptsas_restart_hba(mpt); 7564 mutex_exit(&mpt->m_mutex); 7565 } 7566 7567 void 7568 mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 7569 { 7570 int slot; 7571 mptsas_slots_t *slots = mpt->m_active; 7572 int t; 7573 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 7574 7575 ASSERT(cmd != NULL); 7576 ASSERT(cmd->cmd_queued == FALSE); 7577 7578 /* 7579 * Task Management cmds are removed in their own routines. Also, 7580 * we don't want to modify timeout based on TM cmds. 7581 */ 7582 if (cmd->cmd_flags & CFLAG_TM_CMD) { 7583 return; 7584 } 7585 7586 t = Tgt(cmd); 7587 slot = cmd->cmd_slot; 7588 7589 /* 7590 * remove the cmd. 7591 */ 7592 if (cmd == slots->m_slot[slot]) { 7593 NDBG31(("mptsas_remove_cmd: removing cmd=0x%p", (void *)cmd)); 7594 slots->m_slot[slot] = NULL; 7595 mpt->m_ncmds--; 7596 7597 /* 7598 * only decrement per target ncmds if command 7599 * has a target associated with it. 7600 */ 7601 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 7602 ptgt->m_t_ncmds--; 7603 /* 7604 * reset throttle if we just ran an untagged command 7605 * to a tagged target 7606 */ 7607 if ((ptgt->m_t_ncmds == 0) && 7608 ((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0)) { 7609 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 7610 } 7611 } 7612 7613 } 7614 7615 /* 7616 * This is all we need to do for ioc commands. 7617 */ 7618 if (cmd->cmd_flags & CFLAG_CMDIOC) { 7619 mptsas_return_to_pool(mpt, cmd); 7620 return; 7621 } 7622 7623 /* 7624 * Figure out what to set tag Q timeout for... 7625 * 7626 * Optimize: If we have duplicate's of same timeout 7627 * we're using, then we'll use it again until we run 7628 * out of duplicates. This should be the normal case 7629 * for block and raw I/O. 7630 * If no duplicates, we have to scan through tag que and 7631 * find the longest timeout value and use it. This is 7632 * going to take a while... 7633 * Add 1 to m_n_slots to account for TM request. 7634 */ 7635 if (cmd->cmd_pkt->pkt_time == ptgt->m_timebase) { 7636 if (--(ptgt->m_dups) == 0) { 7637 if (ptgt->m_t_ncmds) { 7638 mptsas_cmd_t *ssp; 7639 uint_t n = 0; 7640 ushort_t nslots = (slots->m_n_slots + 1); 7641 ushort_t i; 7642 /* 7643 * This crude check assumes we don't do 7644 * this too often which seems reasonable 7645 * for block and raw I/O. 7646 */ 7647 for (i = 0; i < nslots; i++) { 7648 ssp = slots->m_slot[i]; 7649 if (ssp && (Tgt(ssp) == t) && 7650 (ssp->cmd_pkt->pkt_time > n)) { 7651 n = ssp->cmd_pkt->pkt_time; 7652 ptgt->m_dups = 1; 7653 } else if (ssp && (Tgt(ssp) == t) && 7654 (ssp->cmd_pkt->pkt_time == n)) { 7655 ptgt->m_dups++; 7656 } 7657 } 7658 ptgt->m_timebase = n; 7659 } else { 7660 ptgt->m_dups = 0; 7661 ptgt->m_timebase = 0; 7662 } 7663 } 7664 } 7665 ptgt->m_timeout = ptgt->m_timebase; 7666 7667 ASSERT(cmd != slots->m_slot[cmd->cmd_slot]); 7668 } 7669 7670 /* 7671 * accept all cmds on the tx_waitq if any and then 7672 * start a fresh request from the top of the device queue. 7673 * 7674 * since there are always cmds queued on the tx_waitq, and rare cmds on 7675 * the instance waitq, so this function should not be invoked in the ISR, 7676 * the mptsas_restart_waitq() is invoked in the ISR instead. otherwise, the 7677 * burden belongs to the IO dispatch CPUs is moved the interrupt CPU. 7678 */ 7679 static void 7680 mptsas_restart_hba(mptsas_t *mpt) 7681 { 7682 ASSERT(mutex_owned(&mpt->m_mutex)); 7683 7684 mutex_enter(&mpt->m_tx_waitq_mutex); 7685 if (mpt->m_tx_waitq) { 7686 mptsas_accept_tx_waitq(mpt); 7687 } 7688 mutex_exit(&mpt->m_tx_waitq_mutex); 7689 mptsas_restart_waitq(mpt); 7690 } 7691 7692 /* 7693 * start a fresh request from the top of the device queue 7694 */ 7695 static void 7696 mptsas_restart_waitq(mptsas_t *mpt) 7697 { 7698 mptsas_cmd_t *cmd, *next_cmd; 7699 mptsas_target_t *ptgt = NULL; 7700 7701 NDBG1(("mptsas_restart_waitq: mpt=0x%p", (void *)mpt)); 7702 7703 ASSERT(mutex_owned(&mpt->m_mutex)); 7704 7705 /* 7706 * If there is a reset delay, don't start any cmds. Otherwise, start 7707 * as many cmds as possible. 7708 * Since SMID 0 is reserved and the TM slot is reserved, the actual max 7709 * commands is m_max_requests - 2. 7710 */ 7711 cmd = mpt->m_waitq; 7712 7713 while (cmd != NULL) { 7714 next_cmd = cmd->cmd_linkp; 7715 if (cmd->cmd_flags & CFLAG_PASSTHRU) { 7716 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 7717 /* 7718 * passthru command get slot need 7719 * set CFLAG_PREPARED. 7720 */ 7721 cmd->cmd_flags |= CFLAG_PREPARED; 7722 mptsas_waitq_delete(mpt, cmd); 7723 mptsas_start_passthru(mpt, cmd); 7724 } 7725 cmd = next_cmd; 7726 continue; 7727 } 7728 if (cmd->cmd_flags & CFLAG_CONFIG) { 7729 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 7730 /* 7731 * Send the config page request and delete it 7732 * from the waitq. 7733 */ 7734 cmd->cmd_flags |= CFLAG_PREPARED; 7735 mptsas_waitq_delete(mpt, cmd); 7736 mptsas_start_config_page_access(mpt, cmd); 7737 } 7738 cmd = next_cmd; 7739 continue; 7740 } 7741 if (cmd->cmd_flags & CFLAG_FW_DIAG) { 7742 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 7743 /* 7744 * Send the FW Diag request and delete if from 7745 * the waitq. 7746 */ 7747 cmd->cmd_flags |= CFLAG_PREPARED; 7748 mptsas_waitq_delete(mpt, cmd); 7749 mptsas_start_diag(mpt, cmd); 7750 } 7751 cmd = next_cmd; 7752 continue; 7753 } 7754 7755 ptgt = cmd->cmd_tgt_addr; 7756 if (ptgt && (ptgt->m_t_throttle == DRAIN_THROTTLE) && 7757 (ptgt->m_t_ncmds == 0)) { 7758 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 7759 } 7760 if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) && 7761 (ptgt && (ptgt->m_reset_delay == 0)) && 7762 (ptgt && (ptgt->m_t_ncmds < 7763 ptgt->m_t_throttle))) { 7764 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 7765 mptsas_waitq_delete(mpt, cmd); 7766 (void) mptsas_start_cmd(mpt, cmd); 7767 } 7768 } 7769 cmd = next_cmd; 7770 } 7771 } 7772 /* 7773 * Cmds are queued if tran_start() doesn't get the m_mutexlock(no wait). 7774 * Accept all those queued cmds before new cmd is accept so that the 7775 * cmds are sent in order. 7776 */ 7777 static void 7778 mptsas_accept_tx_waitq(mptsas_t *mpt) 7779 { 7780 mptsas_cmd_t *cmd; 7781 7782 ASSERT(mutex_owned(&mpt->m_mutex)); 7783 ASSERT(mutex_owned(&mpt->m_tx_waitq_mutex)); 7784 7785 /* 7786 * A Bus Reset could occur at any time and flush the tx_waitq, 7787 * so we cannot count on the tx_waitq to contain even one cmd. 7788 * And when the m_tx_waitq_mutex is released and run 7789 * mptsas_accept_pkt(), the tx_waitq may be flushed. 7790 */ 7791 cmd = mpt->m_tx_waitq; 7792 for (;;) { 7793 if ((cmd = mpt->m_tx_waitq) == NULL) { 7794 mpt->m_tx_draining = 0; 7795 break; 7796 } 7797 if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) { 7798 mpt->m_tx_waitqtail = &mpt->m_tx_waitq; 7799 } 7800 cmd->cmd_linkp = NULL; 7801 mutex_exit(&mpt->m_tx_waitq_mutex); 7802 if (mptsas_accept_pkt(mpt, cmd) != TRAN_ACCEPT) 7803 cmn_err(CE_WARN, "mpt: mptsas_accept_tx_waitq: failed " 7804 "to accept cmd on queue\n"); 7805 mutex_enter(&mpt->m_tx_waitq_mutex); 7806 } 7807 } 7808 7809 7810 /* 7811 * mpt tag type lookup 7812 */ 7813 static char mptsas_tag_lookup[] = 7814 {0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG}; 7815 7816 static int 7817 mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 7818 { 7819 struct scsi_pkt *pkt = CMD2PKT(cmd); 7820 uint32_t control = 0; 7821 int n; 7822 caddr_t mem; 7823 pMpi2SCSIIORequest_t io_request; 7824 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; 7825 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl; 7826 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 7827 uint16_t SMID, io_flags = 0; 7828 uint32_t request_desc_low, request_desc_high; 7829 7830 NDBG1(("mptsas_start_cmd: cmd=0x%p", (void *)cmd)); 7831 7832 /* 7833 * Set SMID and increment index. Rollover to 1 instead of 0 if index 7834 * is at the max. 0 is an invalid SMID, so we call the first index 1. 7835 */ 7836 SMID = cmd->cmd_slot; 7837 7838 /* 7839 * It is possible for back to back device reset to 7840 * happen before the reset delay has expired. That's 7841 * ok, just let the device reset go out on the bus. 7842 */ 7843 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 7844 ASSERT(ptgt->m_reset_delay == 0); 7845 } 7846 7847 /* 7848 * if a non-tagged cmd is submitted to an active tagged target 7849 * then drain before submitting this cmd; SCSI-2 allows RQSENSE 7850 * to be untagged 7851 */ 7852 if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) && 7853 (ptgt->m_t_ncmds > 1) && 7854 ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) && 7855 (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) { 7856 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 7857 NDBG23(("target=%d, untagged cmd, start draining\n", 7858 ptgt->m_devhdl)); 7859 7860 if (ptgt->m_reset_delay == 0) { 7861 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 7862 } 7863 7864 mptsas_remove_cmd(mpt, cmd); 7865 cmd->cmd_pkt_flags |= FLAG_HEAD; 7866 mptsas_waitq_add(mpt, cmd); 7867 } 7868 return (DDI_FAILURE); 7869 } 7870 7871 /* 7872 * Set correct tag bits. 7873 */ 7874 if (cmd->cmd_pkt_flags & FLAG_TAGMASK) { 7875 switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags & 7876 FLAG_TAGMASK) >> 12)]) { 7877 case MSG_SIMPLE_QTAG: 7878 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 7879 break; 7880 case MSG_HEAD_QTAG: 7881 control |= MPI2_SCSIIO_CONTROL_HEADOFQ; 7882 break; 7883 case MSG_ORDERED_QTAG: 7884 control |= MPI2_SCSIIO_CONTROL_ORDEREDQ; 7885 break; 7886 default: 7887 mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n"); 7888 break; 7889 } 7890 } else { 7891 if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) { 7892 ptgt->m_t_throttle = 1; 7893 } 7894 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 7895 } 7896 7897 if (cmd->cmd_pkt_flags & FLAG_TLR) { 7898 control |= MPI2_SCSIIO_CONTROL_TLR_ON; 7899 } 7900 7901 mem = mpt->m_req_frame + (mpt->m_req_frame_size * SMID); 7902 io_request = (pMpi2SCSIIORequest_t)mem; 7903 7904 bzero(io_request, sizeof (Mpi2SCSIIORequest_t)); 7905 ddi_put8(acc_hdl, &io_request->SGLOffset0, offsetof 7906 (MPI2_SCSI_IO_REQUEST, SGL) / 4); 7907 mptsas_init_std_hdr(acc_hdl, io_request, ptgt->m_devhdl, Lun(cmd), 0, 7908 MPI2_FUNCTION_SCSI_IO_REQUEST); 7909 7910 (void) ddi_rep_put8(acc_hdl, (uint8_t *)pkt->pkt_cdbp, 7911 io_request->CDB.CDB32, cmd->cmd_cdblen, DDI_DEV_AUTOINCR); 7912 7913 io_flags = cmd->cmd_cdblen; 7914 ddi_put16(acc_hdl, &io_request->IoFlags, io_flags); 7915 /* 7916 * setup the Scatter/Gather DMA list for this request 7917 */ 7918 if (cmd->cmd_cookiec > 0) { 7919 mptsas_sge_setup(mpt, cmd, &control, io_request, acc_hdl); 7920 } else { 7921 ddi_put32(acc_hdl, &io_request->SGL.MpiSimple.FlagsLength, 7922 ((uint32_t)MPI2_SGE_FLAGS_LAST_ELEMENT | 7923 MPI2_SGE_FLAGS_END_OF_BUFFER | 7924 MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 7925 MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); 7926 } 7927 7928 /* 7929 * save ARQ information 7930 */ 7931 ddi_put8(acc_hdl, &io_request->SenseBufferLength, cmd->cmd_rqslen); 7932 if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) == 7933 (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) { 7934 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, 7935 cmd->cmd_ext_arqcookie.dmac_address); 7936 } else { 7937 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, 7938 cmd->cmd_arqcookie.dmac_address); 7939 } 7940 7941 ddi_put32(acc_hdl, &io_request->Control, control); 7942 7943 NDBG31(("starting message=0x%p, with cmd=0x%p", 7944 (void *)(uintptr_t)mpt->m_req_frame_dma_addr, (void *)cmd)); 7945 7946 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 7947 7948 /* 7949 * Build request descriptor and write it to the request desc post reg. 7950 */ 7951 request_desc_low = (SMID << 16) + MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 7952 request_desc_high = ptgt->m_devhdl << 16; 7953 MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high); 7954 7955 /* 7956 * Start timeout. 7957 */ 7958 #ifdef MPTSAS_TEST 7959 /* 7960 * Temporarily set timebase = 0; needed for 7961 * timeout torture test. 7962 */ 7963 if (mptsas_test_timeouts) { 7964 ptgt->m_timebase = 0; 7965 } 7966 #endif 7967 n = pkt->pkt_time - ptgt->m_timebase; 7968 7969 if (n == 0) { 7970 (ptgt->m_dups)++; 7971 ptgt->m_timeout = ptgt->m_timebase; 7972 } else if (n > 0) { 7973 ptgt->m_timeout = 7974 ptgt->m_timebase = pkt->pkt_time; 7975 ptgt->m_dups = 1; 7976 } else if (n < 0) { 7977 ptgt->m_timeout = ptgt->m_timebase; 7978 } 7979 #ifdef MPTSAS_TEST 7980 /* 7981 * Set back to a number higher than 7982 * mptsas_scsi_watchdog_tick 7983 * so timeouts will happen in mptsas_watchsubr 7984 */ 7985 if (mptsas_test_timeouts) { 7986 ptgt->m_timebase = 60; 7987 } 7988 #endif 7989 7990 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || 7991 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { 7992 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 7993 return (DDI_FAILURE); 7994 } 7995 return (DDI_SUCCESS); 7996 } 7997 7998 /* 7999 * Select a helper thread to handle current doneq 8000 */ 8001 static void 8002 mptsas_deliver_doneq_thread(mptsas_t *mpt) 8003 { 8004 uint64_t t, i; 8005 uint32_t min = 0xffffffff; 8006 mptsas_doneq_thread_list_t *item; 8007 8008 for (i = 0; i < mpt->m_doneq_thread_n; i++) { 8009 item = &mpt->m_doneq_thread_id[i]; 8010 /* 8011 * If the completed command on help thread[i] less than 8012 * doneq_thread_threshold, then pick the thread[i]. Otherwise 8013 * pick a thread which has least completed command. 8014 */ 8015 8016 mutex_enter(&item->mutex); 8017 if (item->len < mpt->m_doneq_thread_threshold) { 8018 t = i; 8019 mutex_exit(&item->mutex); 8020 break; 8021 } 8022 if (item->len < min) { 8023 min = item->len; 8024 t = i; 8025 } 8026 mutex_exit(&item->mutex); 8027 } 8028 mutex_enter(&mpt->m_doneq_thread_id[t].mutex); 8029 mptsas_doneq_mv(mpt, t); 8030 cv_signal(&mpt->m_doneq_thread_id[t].cv); 8031 mutex_exit(&mpt->m_doneq_thread_id[t].mutex); 8032 } 8033 8034 /* 8035 * move the current global doneq to the doneq of thead[t] 8036 */ 8037 static void 8038 mptsas_doneq_mv(mptsas_t *mpt, uint64_t t) 8039 { 8040 mptsas_cmd_t *cmd; 8041 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 8042 8043 ASSERT(mutex_owned(&item->mutex)); 8044 while ((cmd = mpt->m_doneq) != NULL) { 8045 if ((mpt->m_doneq = cmd->cmd_linkp) == NULL) { 8046 mpt->m_donetail = &mpt->m_doneq; 8047 } 8048 cmd->cmd_linkp = NULL; 8049 *item->donetail = cmd; 8050 item->donetail = &cmd->cmd_linkp; 8051 mpt->m_doneq_len--; 8052 item->len++; 8053 } 8054 } 8055 8056 void 8057 mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd) 8058 { 8059 struct scsi_pkt *pkt = CMD2PKT(cmd); 8060 8061 /* Check all acc and dma handles */ 8062 if ((mptsas_check_acc_handle(mpt->m_datap) != 8063 DDI_SUCCESS) || 8064 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 8065 DDI_SUCCESS) || 8066 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) != 8067 DDI_SUCCESS) || 8068 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) != 8069 DDI_SUCCESS) || 8070 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) != 8071 DDI_SUCCESS) || 8072 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) != 8073 DDI_SUCCESS) || 8074 (mptsas_check_acc_handle(mpt->m_config_handle) != 8075 DDI_SUCCESS)) { 8076 ddi_fm_service_impact(mpt->m_dip, 8077 DDI_SERVICE_UNAFFECTED); 8078 ddi_fm_acc_err_clear(mpt->m_config_handle, 8079 DDI_FME_VER0); 8080 pkt->pkt_reason = CMD_TRAN_ERR; 8081 pkt->pkt_statistics = 0; 8082 } 8083 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 8084 DDI_SUCCESS) || 8085 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) != 8086 DDI_SUCCESS) || 8087 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) != 8088 DDI_SUCCESS) || 8089 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) != 8090 DDI_SUCCESS) || 8091 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) != 8092 DDI_SUCCESS)) { 8093 ddi_fm_service_impact(mpt->m_dip, 8094 DDI_SERVICE_UNAFFECTED); 8095 pkt->pkt_reason = CMD_TRAN_ERR; 8096 pkt->pkt_statistics = 0; 8097 } 8098 if (cmd->cmd_dmahandle && 8099 (mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS)) { 8100 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8101 pkt->pkt_reason = CMD_TRAN_ERR; 8102 pkt->pkt_statistics = 0; 8103 } 8104 if ((cmd->cmd_extra_frames && 8105 ((mptsas_check_dma_handle(cmd->cmd_extra_frames->m_dma_hdl) != 8106 DDI_SUCCESS) || 8107 (mptsas_check_acc_handle(cmd->cmd_extra_frames->m_acc_hdl) != 8108 DDI_SUCCESS)))) { 8109 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8110 pkt->pkt_reason = CMD_TRAN_ERR; 8111 pkt->pkt_statistics = 0; 8112 } 8113 if (cmd->cmd_arqhandle && 8114 (mptsas_check_dma_handle(cmd->cmd_arqhandle) != DDI_SUCCESS)) { 8115 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8116 pkt->pkt_reason = CMD_TRAN_ERR; 8117 pkt->pkt_statistics = 0; 8118 } 8119 if (cmd->cmd_ext_arqhandle && 8120 (mptsas_check_dma_handle(cmd->cmd_ext_arqhandle) != DDI_SUCCESS)) { 8121 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8122 pkt->pkt_reason = CMD_TRAN_ERR; 8123 pkt->pkt_statistics = 0; 8124 } 8125 } 8126 8127 /* 8128 * These routines manipulate the queue of commands that 8129 * are waiting for their completion routines to be called. 8130 * The queue is usually in FIFO order but on an MP system 8131 * it's possible for the completion routines to get out 8132 * of order. If that's a problem you need to add a global 8133 * mutex around the code that calls the completion routine 8134 * in the interrupt handler. 8135 */ 8136 static void 8137 mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd) 8138 { 8139 struct scsi_pkt *pkt = CMD2PKT(cmd); 8140 8141 NDBG31(("mptsas_doneq_add: cmd=0x%p", (void *)cmd)); 8142 8143 ASSERT((cmd->cmd_flags & CFLAG_COMPLETED) == 0); 8144 cmd->cmd_linkp = NULL; 8145 cmd->cmd_flags |= CFLAG_FINISHED; 8146 cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT; 8147 8148 mptsas_fma_check(mpt, cmd); 8149 8150 /* 8151 * only add scsi pkts that have completion routines to 8152 * the doneq. no intr cmds do not have callbacks. 8153 */ 8154 if (pkt && (pkt->pkt_comp)) { 8155 *mpt->m_donetail = cmd; 8156 mpt->m_donetail = &cmd->cmd_linkp; 8157 mpt->m_doneq_len++; 8158 } 8159 } 8160 8161 static mptsas_cmd_t * 8162 mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t) 8163 { 8164 mptsas_cmd_t *cmd; 8165 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 8166 8167 /* pop one off the done queue */ 8168 if ((cmd = item->doneq) != NULL) { 8169 /* if the queue is now empty fix the tail pointer */ 8170 NDBG31(("mptsas_doneq_thread_rm: cmd=0x%p", (void *)cmd)); 8171 if ((item->doneq = cmd->cmd_linkp) == NULL) { 8172 item->donetail = &item->doneq; 8173 } 8174 cmd->cmd_linkp = NULL; 8175 item->len--; 8176 } 8177 return (cmd); 8178 } 8179 8180 static void 8181 mptsas_doneq_empty(mptsas_t *mpt) 8182 { 8183 if (mpt->m_doneq && !mpt->m_in_callback) { 8184 mptsas_cmd_t *cmd, *next; 8185 struct scsi_pkt *pkt; 8186 8187 mpt->m_in_callback = 1; 8188 cmd = mpt->m_doneq; 8189 mpt->m_doneq = NULL; 8190 mpt->m_donetail = &mpt->m_doneq; 8191 mpt->m_doneq_len = 0; 8192 8193 mutex_exit(&mpt->m_mutex); 8194 /* 8195 * run the completion routines of all the 8196 * completed commands 8197 */ 8198 while (cmd != NULL) { 8199 next = cmd->cmd_linkp; 8200 cmd->cmd_linkp = NULL; 8201 /* run this command's completion routine */ 8202 cmd->cmd_flags |= CFLAG_COMPLETED; 8203 pkt = CMD2PKT(cmd); 8204 mptsas_pkt_comp(pkt, cmd); 8205 cmd = next; 8206 } 8207 mutex_enter(&mpt->m_mutex); 8208 mpt->m_in_callback = 0; 8209 } 8210 } 8211 8212 /* 8213 * These routines manipulate the target's queue of pending requests 8214 */ 8215 void 8216 mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd) 8217 { 8218 NDBG7(("mptsas_waitq_add: cmd=0x%p", (void *)cmd)); 8219 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8220 cmd->cmd_queued = TRUE; 8221 if (ptgt) 8222 ptgt->m_t_nwait++; 8223 if (cmd->cmd_pkt_flags & FLAG_HEAD) { 8224 if ((cmd->cmd_linkp = mpt->m_waitq) == NULL) { 8225 mpt->m_waitqtail = &cmd->cmd_linkp; 8226 } 8227 mpt->m_waitq = cmd; 8228 } else { 8229 cmd->cmd_linkp = NULL; 8230 *(mpt->m_waitqtail) = cmd; 8231 mpt->m_waitqtail = &cmd->cmd_linkp; 8232 } 8233 } 8234 8235 static mptsas_cmd_t * 8236 mptsas_waitq_rm(mptsas_t *mpt) 8237 { 8238 mptsas_cmd_t *cmd; 8239 mptsas_target_t *ptgt; 8240 NDBG7(("mptsas_waitq_rm")); 8241 8242 MPTSAS_WAITQ_RM(mpt, cmd); 8243 8244 NDBG7(("mptsas_waitq_rm: cmd=0x%p", (void *)cmd)); 8245 if (cmd) { 8246 ptgt = cmd->cmd_tgt_addr; 8247 if (ptgt) { 8248 ptgt->m_t_nwait--; 8249 ASSERT(ptgt->m_t_nwait >= 0); 8250 } 8251 } 8252 return (cmd); 8253 } 8254 8255 /* 8256 * remove specified cmd from the middle of the wait queue. 8257 */ 8258 static void 8259 mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd) 8260 { 8261 mptsas_cmd_t *prevp = mpt->m_waitq; 8262 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8263 8264 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8265 (void *)mpt, (void *)cmd)); 8266 if (ptgt) { 8267 ptgt->m_t_nwait--; 8268 ASSERT(ptgt->m_t_nwait >= 0); 8269 } 8270 8271 if (prevp == cmd) { 8272 if ((mpt->m_waitq = cmd->cmd_linkp) == NULL) 8273 mpt->m_waitqtail = &mpt->m_waitq; 8274 8275 cmd->cmd_linkp = NULL; 8276 cmd->cmd_queued = FALSE; 8277 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8278 (void *)mpt, (void *)cmd)); 8279 return; 8280 } 8281 8282 while (prevp != NULL) { 8283 if (prevp->cmd_linkp == cmd) { 8284 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL) 8285 mpt->m_waitqtail = &prevp->cmd_linkp; 8286 8287 cmd->cmd_linkp = NULL; 8288 cmd->cmd_queued = FALSE; 8289 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8290 (void *)mpt, (void *)cmd)); 8291 return; 8292 } 8293 prevp = prevp->cmd_linkp; 8294 } 8295 cmn_err(CE_PANIC, "mpt: mptsas_waitq_delete: queue botch"); 8296 } 8297 8298 static mptsas_cmd_t * 8299 mptsas_tx_waitq_rm(mptsas_t *mpt) 8300 { 8301 mptsas_cmd_t *cmd; 8302 NDBG7(("mptsas_tx_waitq_rm")); 8303 8304 MPTSAS_TX_WAITQ_RM(mpt, cmd); 8305 8306 NDBG7(("mptsas_tx_waitq_rm: cmd=0x%p", (void *)cmd)); 8307 8308 return (cmd); 8309 } 8310 8311 /* 8312 * remove specified cmd from the middle of the tx_waitq. 8313 */ 8314 static void 8315 mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd) 8316 { 8317 mptsas_cmd_t *prevp = mpt->m_tx_waitq; 8318 8319 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p", 8320 (void *)mpt, (void *)cmd)); 8321 8322 if (prevp == cmd) { 8323 if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) 8324 mpt->m_tx_waitqtail = &mpt->m_tx_waitq; 8325 8326 cmd->cmd_linkp = NULL; 8327 cmd->cmd_queued = FALSE; 8328 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p", 8329 (void *)mpt, (void *)cmd)); 8330 return; 8331 } 8332 8333 while (prevp != NULL) { 8334 if (prevp->cmd_linkp == cmd) { 8335 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL) 8336 mpt->m_tx_waitqtail = &prevp->cmd_linkp; 8337 8338 cmd->cmd_linkp = NULL; 8339 cmd->cmd_queued = FALSE; 8340 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p", 8341 (void *)mpt, (void *)cmd)); 8342 return; 8343 } 8344 prevp = prevp->cmd_linkp; 8345 } 8346 cmn_err(CE_PANIC, "mpt: mptsas_tx_waitq_delete: queue botch"); 8347 } 8348 8349 /* 8350 * device and bus reset handling 8351 * 8352 * Notes: 8353 * - RESET_ALL: reset the controller 8354 * - RESET_TARGET: reset the target specified in scsi_address 8355 */ 8356 static int 8357 mptsas_scsi_reset(struct scsi_address *ap, int level) 8358 { 8359 mptsas_t *mpt = ADDR2MPT(ap); 8360 int rval; 8361 mptsas_tgt_private_t *tgt_private; 8362 mptsas_target_t *ptgt = NULL; 8363 8364 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->tran_tgt_private; 8365 ptgt = tgt_private->t_private; 8366 if (ptgt == NULL) { 8367 return (FALSE); 8368 } 8369 NDBG22(("mptsas_scsi_reset: target=%d level=%d", ptgt->m_devhdl, 8370 level)); 8371 8372 mutex_enter(&mpt->m_mutex); 8373 /* 8374 * if we are not in panic set up a reset delay for this target 8375 */ 8376 if (!ddi_in_panic()) { 8377 mptsas_setup_bus_reset_delay(mpt); 8378 } else { 8379 drv_usecwait(mpt->m_scsi_reset_delay * 1000); 8380 } 8381 rval = mptsas_do_scsi_reset(mpt, ptgt->m_devhdl); 8382 mutex_exit(&mpt->m_mutex); 8383 8384 /* 8385 * The transport layer expect to only see TRUE and 8386 * FALSE. Therefore, we will adjust the return value 8387 * if mptsas_do_scsi_reset returns FAILED. 8388 */ 8389 if (rval == FAILED) 8390 rval = FALSE; 8391 return (rval); 8392 } 8393 8394 static int 8395 mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl) 8396 { 8397 int rval = FALSE; 8398 uint8_t config, disk; 8399 mptsas_slots_t *slots = mpt->m_active; 8400 8401 ASSERT(mutex_owned(&mpt->m_mutex)); 8402 8403 if (mptsas_debug_resets) { 8404 mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d", 8405 devhdl); 8406 } 8407 8408 /* 8409 * Issue a Target Reset message to the target specified but not to a 8410 * disk making up a raid volume. Just look through the RAID config 8411 * Phys Disk list of DevHandles. If the target's DevHandle is in this 8412 * list, then don't reset this target. 8413 */ 8414 for (config = 0; config < slots->m_num_raid_configs; config++) { 8415 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) { 8416 if (devhdl == slots->m_raidconfig[config]. 8417 m_physdisk_devhdl[disk]) { 8418 return (TRUE); 8419 } 8420 } 8421 } 8422 8423 rval = mptsas_ioc_task_management(mpt, 8424 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, devhdl, 0, NULL, 0, 0); 8425 8426 mptsas_doneq_empty(mpt); 8427 return (rval); 8428 } 8429 8430 static int 8431 mptsas_scsi_reset_notify(struct scsi_address *ap, int flag, 8432 void (*callback)(caddr_t), caddr_t arg) 8433 { 8434 mptsas_t *mpt = ADDR2MPT(ap); 8435 8436 NDBG22(("mptsas_scsi_reset_notify: tgt=%d", ap->a_target)); 8437 8438 return (scsi_hba_reset_notify_setup(ap, flag, callback, arg, 8439 &mpt->m_mutex, &mpt->m_reset_notify_listf)); 8440 } 8441 8442 static int 8443 mptsas_get_name(struct scsi_device *sd, char *name, int len) 8444 { 8445 dev_info_t *lun_dip = NULL; 8446 8447 ASSERT(sd != NULL); 8448 ASSERT(name != NULL); 8449 lun_dip = sd->sd_dev; 8450 ASSERT(lun_dip != NULL); 8451 8452 if (mptsas_name_child(lun_dip, name, len) == DDI_SUCCESS) { 8453 return (1); 8454 } else { 8455 return (0); 8456 } 8457 } 8458 8459 static int 8460 mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len) 8461 { 8462 return (mptsas_get_name(sd, name, len)); 8463 } 8464 8465 void 8466 mptsas_set_throttle(mptsas_t *mpt, mptsas_target_t *ptgt, int what) 8467 { 8468 8469 NDBG25(("mptsas_set_throttle: throttle=%x", what)); 8470 8471 /* 8472 * if the bus is draining/quiesced, no changes to the throttles 8473 * are allowed. Not allowing change of throttles during draining 8474 * limits error recovery but will reduce draining time 8475 * 8476 * all throttles should have been set to HOLD_THROTTLE 8477 */ 8478 if (mpt->m_softstate & (MPTSAS_SS_QUIESCED | MPTSAS_SS_DRAINING)) { 8479 return; 8480 } 8481 8482 if (what == HOLD_THROTTLE) { 8483 ptgt->m_t_throttle = HOLD_THROTTLE; 8484 } else if (ptgt->m_reset_delay == 0) { 8485 ptgt->m_t_throttle = what; 8486 } 8487 } 8488 8489 /* 8490 * Clean up from a device reset. 8491 * For the case of target reset, this function clears the waitq of all 8492 * commands for a particular target. For the case of abort task set, this 8493 * function clears the waitq of all commonds for a particular target/lun. 8494 */ 8495 static void 8496 mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype) 8497 { 8498 mptsas_slots_t *slots = mpt->m_active; 8499 mptsas_cmd_t *cmd, *next_cmd; 8500 int slot; 8501 uchar_t reason; 8502 uint_t stat; 8503 8504 NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun)); 8505 8506 /* 8507 * Make sure the I/O Controller has flushed all cmds 8508 * that are associated with this target for a target reset 8509 * and target/lun for abort task set. 8510 * Account for TM requests, which use the last SMID. 8511 */ 8512 for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) { 8513 if ((cmd = slots->m_slot[slot]) == NULL) 8514 continue; 8515 reason = CMD_RESET; 8516 stat = STAT_DEV_RESET; 8517 switch (tasktype) { 8518 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 8519 if (Tgt(cmd) == target) { 8520 NDBG25(("mptsas_flush_target discovered non-" 8521 "NULL cmd in slot %d, tasktype 0x%x", slot, 8522 tasktype)); 8523 mptsas_dump_cmd(mpt, cmd); 8524 mptsas_remove_cmd(mpt, cmd); 8525 mptsas_set_pkt_reason(mpt, cmd, reason, stat); 8526 mptsas_doneq_add(mpt, cmd); 8527 } 8528 break; 8529 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 8530 reason = CMD_ABORTED; 8531 stat = STAT_ABORTED; 8532 /*FALLTHROUGH*/ 8533 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 8534 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 8535 8536 NDBG25(("mptsas_flush_target discovered non-" 8537 "NULL cmd in slot %d, tasktype 0x%x", slot, 8538 tasktype)); 8539 mptsas_dump_cmd(mpt, cmd); 8540 mptsas_remove_cmd(mpt, cmd); 8541 mptsas_set_pkt_reason(mpt, cmd, reason, 8542 stat); 8543 mptsas_doneq_add(mpt, cmd); 8544 } 8545 break; 8546 default: 8547 break; 8548 } 8549 } 8550 8551 /* 8552 * Flush the waitq and tx_waitq of this target's cmds 8553 */ 8554 cmd = mpt->m_waitq; 8555 8556 reason = CMD_RESET; 8557 stat = STAT_DEV_RESET; 8558 8559 switch (tasktype) { 8560 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 8561 while (cmd != NULL) { 8562 next_cmd = cmd->cmd_linkp; 8563 if (Tgt(cmd) == target) { 8564 mptsas_waitq_delete(mpt, cmd); 8565 mptsas_set_pkt_reason(mpt, cmd, 8566 reason, stat); 8567 mptsas_doneq_add(mpt, cmd); 8568 } 8569 cmd = next_cmd; 8570 } 8571 mutex_enter(&mpt->m_tx_waitq_mutex); 8572 cmd = mpt->m_tx_waitq; 8573 while (cmd != NULL) { 8574 next_cmd = cmd->cmd_linkp; 8575 if (Tgt(cmd) == target) { 8576 mptsas_tx_waitq_delete(mpt, cmd); 8577 mutex_exit(&mpt->m_tx_waitq_mutex); 8578 mptsas_set_pkt_reason(mpt, cmd, 8579 reason, stat); 8580 mptsas_doneq_add(mpt, cmd); 8581 mutex_enter(&mpt->m_tx_waitq_mutex); 8582 } 8583 cmd = next_cmd; 8584 } 8585 mutex_exit(&mpt->m_tx_waitq_mutex); 8586 break; 8587 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 8588 reason = CMD_ABORTED; 8589 stat = STAT_ABORTED; 8590 /*FALLTHROUGH*/ 8591 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 8592 while (cmd != NULL) { 8593 next_cmd = cmd->cmd_linkp; 8594 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 8595 mptsas_waitq_delete(mpt, cmd); 8596 mptsas_set_pkt_reason(mpt, cmd, 8597 reason, stat); 8598 mptsas_doneq_add(mpt, cmd); 8599 } 8600 cmd = next_cmd; 8601 } 8602 mutex_enter(&mpt->m_tx_waitq_mutex); 8603 cmd = mpt->m_tx_waitq; 8604 while (cmd != NULL) { 8605 next_cmd = cmd->cmd_linkp; 8606 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 8607 mptsas_tx_waitq_delete(mpt, cmd); 8608 mutex_exit(&mpt->m_tx_waitq_mutex); 8609 mptsas_set_pkt_reason(mpt, cmd, 8610 reason, stat); 8611 mptsas_doneq_add(mpt, cmd); 8612 mutex_enter(&mpt->m_tx_waitq_mutex); 8613 } 8614 cmd = next_cmd; 8615 } 8616 mutex_exit(&mpt->m_tx_waitq_mutex); 8617 break; 8618 default: 8619 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.", 8620 tasktype); 8621 break; 8622 } 8623 } 8624 8625 /* 8626 * Clean up hba state, abort all outstanding command and commands in waitq 8627 * reset timeout of all targets. 8628 */ 8629 static void 8630 mptsas_flush_hba(mptsas_t *mpt) 8631 { 8632 mptsas_slots_t *slots = mpt->m_active; 8633 mptsas_cmd_t *cmd; 8634 int slot; 8635 8636 NDBG25(("mptsas_flush_hba")); 8637 8638 /* 8639 * The I/O Controller should have already sent back 8640 * all commands via the scsi I/O reply frame. Make 8641 * sure all commands have been flushed. 8642 * Account for TM request, which use the last SMID. 8643 */ 8644 for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) { 8645 if ((cmd = slots->m_slot[slot]) == NULL) 8646 continue; 8647 8648 if (cmd->cmd_flags & CFLAG_CMDIOC) { 8649 /* 8650 * Need to make sure to tell everyone that might be 8651 * waiting on this command that it's going to fail. If 8652 * we get here, this command will never timeout because 8653 * the active command table is going to be re-allocated, 8654 * so there will be nothing to check against a time out. 8655 * Instead, mark the command as failed due to reset. 8656 */ 8657 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, 8658 STAT_BUS_RESET); 8659 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 8660 (cmd->cmd_flags & CFLAG_CONFIG) || 8661 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 8662 cmd->cmd_flags |= CFLAG_FINISHED; 8663 cv_broadcast(&mpt->m_passthru_cv); 8664 cv_broadcast(&mpt->m_config_cv); 8665 cv_broadcast(&mpt->m_fw_diag_cv); 8666 } 8667 continue; 8668 } 8669 8670 NDBG25(("mptsas_flush_hba discovered non-NULL cmd in slot %d", 8671 slot)); 8672 mptsas_dump_cmd(mpt, cmd); 8673 8674 mptsas_remove_cmd(mpt, cmd); 8675 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 8676 mptsas_doneq_add(mpt, cmd); 8677 } 8678 8679 /* 8680 * Flush the waitq. 8681 */ 8682 while ((cmd = mptsas_waitq_rm(mpt)) != NULL) { 8683 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 8684 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 8685 (cmd->cmd_flags & CFLAG_CONFIG) || 8686 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 8687 cmd->cmd_flags |= CFLAG_FINISHED; 8688 cv_broadcast(&mpt->m_passthru_cv); 8689 cv_broadcast(&mpt->m_config_cv); 8690 cv_broadcast(&mpt->m_fw_diag_cv); 8691 } else { 8692 mptsas_doneq_add(mpt, cmd); 8693 } 8694 } 8695 8696 /* 8697 * Flush the tx_waitq 8698 */ 8699 mutex_enter(&mpt->m_tx_waitq_mutex); 8700 while ((cmd = mptsas_tx_waitq_rm(mpt)) != NULL) { 8701 mutex_exit(&mpt->m_tx_waitq_mutex); 8702 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 8703 mptsas_doneq_add(mpt, cmd); 8704 mutex_enter(&mpt->m_tx_waitq_mutex); 8705 } 8706 mutex_exit(&mpt->m_tx_waitq_mutex); 8707 } 8708 8709 /* 8710 * set pkt_reason and OR in pkt_statistics flag 8711 */ 8712 static void 8713 mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, uchar_t reason, 8714 uint_t stat) 8715 { 8716 #ifndef __lock_lint 8717 _NOTE(ARGUNUSED(mpt)) 8718 #endif 8719 8720 NDBG25(("mptsas_set_pkt_reason: cmd=0x%p reason=%x stat=%x", 8721 (void *)cmd, reason, stat)); 8722 8723 if (cmd) { 8724 if (cmd->cmd_pkt->pkt_reason == CMD_CMPLT) { 8725 cmd->cmd_pkt->pkt_reason = reason; 8726 } 8727 cmd->cmd_pkt->pkt_statistics |= stat; 8728 } 8729 } 8730 8731 static void 8732 mptsas_start_watch_reset_delay() 8733 { 8734 NDBG22(("mptsas_start_watch_reset_delay")); 8735 8736 mutex_enter(&mptsas_global_mutex); 8737 if (mptsas_reset_watch == NULL && mptsas_timeouts_enabled) { 8738 mptsas_reset_watch = timeout(mptsas_watch_reset_delay, NULL, 8739 drv_usectohz((clock_t) 8740 MPTSAS_WATCH_RESET_DELAY_TICK * 1000)); 8741 ASSERT(mptsas_reset_watch != NULL); 8742 } 8743 mutex_exit(&mptsas_global_mutex); 8744 } 8745 8746 static void 8747 mptsas_setup_bus_reset_delay(mptsas_t *mpt) 8748 { 8749 mptsas_target_t *ptgt = NULL; 8750 8751 NDBG22(("mptsas_setup_bus_reset_delay")); 8752 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 8753 MPTSAS_HASH_FIRST); 8754 while (ptgt != NULL) { 8755 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 8756 ptgt->m_reset_delay = mpt->m_scsi_reset_delay; 8757 8758 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 8759 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 8760 } 8761 8762 mptsas_start_watch_reset_delay(); 8763 } 8764 8765 /* 8766 * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every 8767 * mpt instance for active reset delays 8768 */ 8769 static void 8770 mptsas_watch_reset_delay(void *arg) 8771 { 8772 #ifndef __lock_lint 8773 _NOTE(ARGUNUSED(arg)) 8774 #endif 8775 8776 mptsas_t *mpt; 8777 int not_done = 0; 8778 8779 NDBG22(("mptsas_watch_reset_delay")); 8780 8781 mutex_enter(&mptsas_global_mutex); 8782 mptsas_reset_watch = 0; 8783 mutex_exit(&mptsas_global_mutex); 8784 rw_enter(&mptsas_global_rwlock, RW_READER); 8785 for (mpt = mptsas_head; mpt != NULL; mpt = mpt->m_next) { 8786 if (mpt->m_tran == 0) { 8787 continue; 8788 } 8789 mutex_enter(&mpt->m_mutex); 8790 not_done += mptsas_watch_reset_delay_subr(mpt); 8791 mutex_exit(&mpt->m_mutex); 8792 } 8793 rw_exit(&mptsas_global_rwlock); 8794 8795 if (not_done) { 8796 mptsas_start_watch_reset_delay(); 8797 } 8798 } 8799 8800 static int 8801 mptsas_watch_reset_delay_subr(mptsas_t *mpt) 8802 { 8803 int done = 0; 8804 int restart = 0; 8805 mptsas_target_t *ptgt = NULL; 8806 8807 NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt)); 8808 8809 ASSERT(mutex_owned(&mpt->m_mutex)); 8810 8811 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 8812 MPTSAS_HASH_FIRST); 8813 while (ptgt != NULL) { 8814 if (ptgt->m_reset_delay != 0) { 8815 ptgt->m_reset_delay -= 8816 MPTSAS_WATCH_RESET_DELAY_TICK; 8817 if (ptgt->m_reset_delay <= 0) { 8818 ptgt->m_reset_delay = 0; 8819 mptsas_set_throttle(mpt, ptgt, 8820 MAX_THROTTLE); 8821 restart++; 8822 } else { 8823 done = -1; 8824 } 8825 } 8826 8827 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 8828 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 8829 } 8830 8831 if (restart > 0) { 8832 mptsas_restart_hba(mpt); 8833 } 8834 return (done); 8835 } 8836 8837 #ifdef MPTSAS_TEST 8838 static void 8839 mptsas_test_reset(mptsas_t *mpt, int target) 8840 { 8841 mptsas_target_t *ptgt = NULL; 8842 8843 if (mptsas_rtest == target) { 8844 if (mptsas_do_scsi_reset(mpt, target) == TRUE) { 8845 mptsas_rtest = -1; 8846 } 8847 if (mptsas_rtest == -1) { 8848 NDBG22(("mptsas_test_reset success")); 8849 } 8850 } 8851 } 8852 #endif 8853 8854 /* 8855 * abort handling: 8856 * 8857 * Notes: 8858 * - if pkt is not NULL, abort just that command 8859 * - if pkt is NULL, abort all outstanding commands for target 8860 */ 8861 static int 8862 mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt) 8863 { 8864 mptsas_t *mpt = ADDR2MPT(ap); 8865 int rval; 8866 mptsas_tgt_private_t *tgt_private; 8867 int target, lun; 8868 8869 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran-> 8870 tran_tgt_private; 8871 ASSERT(tgt_private != NULL); 8872 target = tgt_private->t_private->m_devhdl; 8873 lun = tgt_private->t_lun; 8874 8875 NDBG23(("mptsas_scsi_abort: target=%d.%d", target, lun)); 8876 8877 mutex_enter(&mpt->m_mutex); 8878 rval = mptsas_do_scsi_abort(mpt, target, lun, pkt); 8879 mutex_exit(&mpt->m_mutex); 8880 return (rval); 8881 } 8882 8883 static int 8884 mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, struct scsi_pkt *pkt) 8885 { 8886 mptsas_cmd_t *sp = NULL; 8887 mptsas_slots_t *slots = mpt->m_active; 8888 int rval = FALSE; 8889 8890 ASSERT(mutex_owned(&mpt->m_mutex)); 8891 8892 /* 8893 * Abort the command pkt on the target/lun in ap. If pkt is 8894 * NULL, abort all outstanding commands on that target/lun. 8895 * If you can abort them, return 1, else return 0. 8896 * Each packet that's aborted should be sent back to the target 8897 * driver through the callback routine, with pkt_reason set to 8898 * CMD_ABORTED. 8899 * 8900 * abort cmd pkt on HBA hardware; clean out of outstanding 8901 * command lists, etc. 8902 */ 8903 if (pkt != NULL) { 8904 /* abort the specified packet */ 8905 sp = PKT2CMD(pkt); 8906 8907 if (sp->cmd_queued) { 8908 NDBG23(("mptsas_do_scsi_abort: queued sp=0x%p aborted", 8909 (void *)sp)); 8910 mptsas_waitq_delete(mpt, sp); 8911 mptsas_set_pkt_reason(mpt, sp, CMD_ABORTED, 8912 STAT_ABORTED); 8913 mptsas_doneq_add(mpt, sp); 8914 rval = TRUE; 8915 goto done; 8916 } 8917 8918 /* 8919 * Have mpt firmware abort this command 8920 */ 8921 8922 if (slots->m_slot[sp->cmd_slot] != NULL) { 8923 rval = mptsas_ioc_task_management(mpt, 8924 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, target, 8925 lun, NULL, 0, 0); 8926 8927 /* 8928 * The transport layer expects only TRUE and FALSE. 8929 * Therefore, if mptsas_ioc_task_management returns 8930 * FAILED we will return FALSE. 8931 */ 8932 if (rval == FAILED) 8933 rval = FALSE; 8934 goto done; 8935 } 8936 } 8937 8938 /* 8939 * If pkt is NULL then abort task set 8940 */ 8941 rval = mptsas_ioc_task_management(mpt, 8942 MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, target, lun, NULL, 0, 0); 8943 8944 /* 8945 * The transport layer expects only TRUE and FALSE. 8946 * Therefore, if mptsas_ioc_task_management returns 8947 * FAILED we will return FALSE. 8948 */ 8949 if (rval == FAILED) 8950 rval = FALSE; 8951 8952 #ifdef MPTSAS_TEST 8953 if (rval && mptsas_test_stop) { 8954 debug_enter("mptsas_do_scsi_abort"); 8955 } 8956 #endif 8957 8958 done: 8959 mptsas_doneq_empty(mpt); 8960 return (rval); 8961 } 8962 8963 /* 8964 * capability handling: 8965 * (*tran_getcap). Get the capability named, and return its value. 8966 */ 8967 static int 8968 mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly) 8969 { 8970 mptsas_t *mpt = ADDR2MPT(ap); 8971 int ckey; 8972 int rval = FALSE; 8973 8974 NDBG24(("mptsas_scsi_getcap: target=%d, cap=%s tgtonly=%x", 8975 ap->a_target, cap, tgtonly)); 8976 8977 mutex_enter(&mpt->m_mutex); 8978 8979 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) { 8980 mutex_exit(&mpt->m_mutex); 8981 return (UNDEFINED); 8982 } 8983 8984 switch (ckey) { 8985 case SCSI_CAP_DMA_MAX: 8986 rval = (int)mpt->m_msg_dma_attr.dma_attr_maxxfer; 8987 break; 8988 case SCSI_CAP_ARQ: 8989 rval = TRUE; 8990 break; 8991 case SCSI_CAP_MSG_OUT: 8992 case SCSI_CAP_PARITY: 8993 case SCSI_CAP_UNTAGGED_QING: 8994 rval = TRUE; 8995 break; 8996 case SCSI_CAP_TAGGED_QING: 8997 rval = TRUE; 8998 break; 8999 case SCSI_CAP_RESET_NOTIFICATION: 9000 rval = TRUE; 9001 break; 9002 case SCSI_CAP_LINKED_CMDS: 9003 rval = FALSE; 9004 break; 9005 case SCSI_CAP_QFULL_RETRIES: 9006 rval = ((mptsas_tgt_private_t *)(ap->a_hba_tran-> 9007 tran_tgt_private))->t_private->m_qfull_retries; 9008 break; 9009 case SCSI_CAP_QFULL_RETRY_INTERVAL: 9010 rval = drv_hztousec(((mptsas_tgt_private_t *) 9011 (ap->a_hba_tran->tran_tgt_private))-> 9012 t_private->m_qfull_retry_interval) / 1000; 9013 break; 9014 case SCSI_CAP_CDB_LEN: 9015 rval = CDB_GROUP4; 9016 break; 9017 case SCSI_CAP_INTERCONNECT_TYPE: 9018 rval = INTERCONNECT_SAS; 9019 break; 9020 case SCSI_CAP_TRAN_LAYER_RETRIES: 9021 if (mpt->m_ioc_capabilities & 9022 MPI2_IOCFACTS_CAPABILITY_TLR) 9023 rval = TRUE; 9024 else 9025 rval = FALSE; 9026 break; 9027 default: 9028 rval = UNDEFINED; 9029 break; 9030 } 9031 9032 NDBG24(("mptsas_scsi_getcap: %s, rval=%x", cap, rval)); 9033 9034 mutex_exit(&mpt->m_mutex); 9035 return (rval); 9036 } 9037 9038 /* 9039 * (*tran_setcap). Set the capability named to the value given. 9040 */ 9041 static int 9042 mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, int tgtonly) 9043 { 9044 mptsas_t *mpt = ADDR2MPT(ap); 9045 int ckey; 9046 int rval = FALSE; 9047 9048 NDBG24(("mptsas_scsi_setcap: target=%d, cap=%s value=%x tgtonly=%x", 9049 ap->a_target, cap, value, tgtonly)); 9050 9051 if (!tgtonly) { 9052 return (rval); 9053 } 9054 9055 mutex_enter(&mpt->m_mutex); 9056 9057 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) { 9058 mutex_exit(&mpt->m_mutex); 9059 return (UNDEFINED); 9060 } 9061 9062 switch (ckey) { 9063 case SCSI_CAP_DMA_MAX: 9064 case SCSI_CAP_MSG_OUT: 9065 case SCSI_CAP_PARITY: 9066 case SCSI_CAP_INITIATOR_ID: 9067 case SCSI_CAP_LINKED_CMDS: 9068 case SCSI_CAP_UNTAGGED_QING: 9069 case SCSI_CAP_RESET_NOTIFICATION: 9070 /* 9071 * None of these are settable via 9072 * the capability interface. 9073 */ 9074 break; 9075 case SCSI_CAP_ARQ: 9076 /* 9077 * We cannot turn off arq so return false if asked to 9078 */ 9079 if (value) { 9080 rval = TRUE; 9081 } else { 9082 rval = FALSE; 9083 } 9084 break; 9085 case SCSI_CAP_TAGGED_QING: 9086 mptsas_set_throttle(mpt, ((mptsas_tgt_private_t *) 9087 (ap->a_hba_tran->tran_tgt_private))->t_private, 9088 MAX_THROTTLE); 9089 rval = TRUE; 9090 break; 9091 case SCSI_CAP_QFULL_RETRIES: 9092 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))-> 9093 t_private->m_qfull_retries = (uchar_t)value; 9094 rval = TRUE; 9095 break; 9096 case SCSI_CAP_QFULL_RETRY_INTERVAL: 9097 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))-> 9098 t_private->m_qfull_retry_interval = 9099 drv_usectohz(value * 1000); 9100 rval = TRUE; 9101 break; 9102 default: 9103 rval = UNDEFINED; 9104 break; 9105 } 9106 mutex_exit(&mpt->m_mutex); 9107 return (rval); 9108 } 9109 9110 /* 9111 * Utility routine for mptsas_ifsetcap/ifgetcap 9112 */ 9113 /*ARGSUSED*/ 9114 static int 9115 mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp) 9116 { 9117 NDBG24(("mptsas_scsi_capchk: cap=%s", cap)); 9118 9119 if (!cap) 9120 return (FALSE); 9121 9122 *cidxp = scsi_hba_lookup_capstr(cap); 9123 return (TRUE); 9124 } 9125 9126 static int 9127 mptsas_alloc_active_slots(mptsas_t *mpt, int flag) 9128 { 9129 mptsas_slots_t *old_active = mpt->m_active; 9130 mptsas_slots_t *new_active; 9131 size_t size; 9132 int rval = -1, i; 9133 9134 /* 9135 * if there are active commands, then we cannot 9136 * change size of active slots array. 9137 */ 9138 ASSERT(mpt->m_ncmds == 0); 9139 9140 size = MPTSAS_SLOTS_SIZE(mpt); 9141 new_active = kmem_zalloc(size, flag); 9142 if (new_active == NULL) { 9143 NDBG1(("new active alloc failed")); 9144 return (rval); 9145 } 9146 /* 9147 * Since SMID 0 is reserved and the TM slot is reserved, the 9148 * number of slots that can be used at any one time is 9149 * m_max_requests - 2. 9150 */ 9151 new_active->m_n_slots = (mpt->m_max_requests - 2); 9152 new_active->m_size = size; 9153 new_active->m_tags = 1; 9154 if (old_active) { 9155 new_active->m_tgttbl = old_active->m_tgttbl; 9156 new_active->m_smptbl = old_active->m_smptbl; 9157 new_active->m_num_raid_configs = 9158 old_active->m_num_raid_configs; 9159 for (i = 0; i < new_active->m_num_raid_configs; i++) { 9160 new_active->m_raidconfig[i] = 9161 old_active->m_raidconfig[i]; 9162 } 9163 mptsas_free_active_slots(mpt); 9164 } 9165 mpt->m_active = new_active; 9166 rval = 0; 9167 9168 return (rval); 9169 } 9170 9171 static void 9172 mptsas_free_active_slots(mptsas_t *mpt) 9173 { 9174 mptsas_slots_t *active = mpt->m_active; 9175 size_t size; 9176 9177 if (active == NULL) 9178 return; 9179 size = active->m_size; 9180 kmem_free(active, size); 9181 mpt->m_active = NULL; 9182 } 9183 9184 /* 9185 * Error logging, printing, and debug print routines. 9186 */ 9187 static char *mptsas_label = "mpt_sas"; 9188 9189 /*PRINTFLIKE3*/ 9190 void 9191 mptsas_log(mptsas_t *mpt, int level, char *fmt, ...) 9192 { 9193 dev_info_t *dev; 9194 va_list ap; 9195 9196 if (mpt) { 9197 dev = mpt->m_dip; 9198 } else { 9199 dev = 0; 9200 } 9201 9202 mutex_enter(&mptsas_log_mutex); 9203 9204 va_start(ap, fmt); 9205 (void) vsprintf(mptsas_log_buf, fmt, ap); 9206 va_end(ap); 9207 9208 if (level == CE_CONT) { 9209 scsi_log(dev, mptsas_label, level, "%s\n", mptsas_log_buf); 9210 } else { 9211 scsi_log(dev, mptsas_label, level, "%s", mptsas_log_buf); 9212 } 9213 9214 mutex_exit(&mptsas_log_mutex); 9215 } 9216 9217 #ifdef MPTSAS_DEBUG 9218 /*PRINTFLIKE1*/ 9219 void 9220 mptsas_printf(char *fmt, ...) 9221 { 9222 dev_info_t *dev = 0; 9223 va_list ap; 9224 9225 mutex_enter(&mptsas_log_mutex); 9226 9227 va_start(ap, fmt); 9228 (void) vsprintf(mptsas_log_buf, fmt, ap); 9229 va_end(ap); 9230 9231 #ifdef PROM_PRINTF 9232 prom_printf("%s:\t%s\n", mptsas_label, mptsas_log_buf); 9233 #else 9234 scsi_log(dev, mptsas_label, SCSI_DEBUG, "%s\n", mptsas_log_buf); 9235 #endif 9236 mutex_exit(&mptsas_log_mutex); 9237 } 9238 #endif 9239 9240 /* 9241 * timeout handling 9242 */ 9243 static void 9244 mptsas_watch(void *arg) 9245 { 9246 #ifndef __lock_lint 9247 _NOTE(ARGUNUSED(arg)) 9248 #endif 9249 9250 mptsas_t *mpt; 9251 uint32_t doorbell; 9252 9253 NDBG30(("mptsas_watch")); 9254 9255 rw_enter(&mptsas_global_rwlock, RW_READER); 9256 for (mpt = mptsas_head; mpt != (mptsas_t *)NULL; mpt = mpt->m_next) { 9257 9258 mutex_enter(&mpt->m_mutex); 9259 9260 /* Skip device if not powered on */ 9261 if (mpt->m_options & MPTSAS_OPT_PM) { 9262 if (mpt->m_power_level == PM_LEVEL_D0) { 9263 (void) pm_busy_component(mpt->m_dip, 0); 9264 mpt->m_busy = 1; 9265 } else { 9266 mutex_exit(&mpt->m_mutex); 9267 continue; 9268 } 9269 } 9270 9271 /* 9272 * Check if controller is in a FAULT state. If so, reset it. 9273 */ 9274 doorbell = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell); 9275 if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { 9276 doorbell &= MPI2_DOORBELL_DATA_MASK; 9277 mptsas_log(mpt, CE_WARN, "MPT Firmware Fault, " 9278 "code: %04x", doorbell); 9279 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 9280 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 9281 mptsas_log(mpt, CE_WARN, "Reset failed" 9282 "after fault was detected"); 9283 } 9284 } 9285 9286 /* 9287 * For now, always call mptsas_watchsubr. 9288 */ 9289 mptsas_watchsubr(mpt); 9290 9291 if (mpt->m_options & MPTSAS_OPT_PM) { 9292 mpt->m_busy = 0; 9293 (void) pm_idle_component(mpt->m_dip, 0); 9294 } 9295 9296 mutex_exit(&mpt->m_mutex); 9297 } 9298 rw_exit(&mptsas_global_rwlock); 9299 9300 mutex_enter(&mptsas_global_mutex); 9301 if (mptsas_timeouts_enabled) 9302 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick); 9303 mutex_exit(&mptsas_global_mutex); 9304 } 9305 9306 static void 9307 mptsas_watchsubr(mptsas_t *mpt) 9308 { 9309 int i; 9310 mptsas_cmd_t *cmd; 9311 mptsas_target_t *ptgt = NULL; 9312 9313 NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt)); 9314 9315 #ifdef MPTSAS_TEST 9316 if (mptsas_enable_untagged) { 9317 mptsas_test_untagged++; 9318 } 9319 #endif 9320 9321 /* 9322 * Check for commands stuck in active slot 9323 * Account for TM requests, which use the last SMID. 9324 */ 9325 for (i = 0; i <= mpt->m_active->m_n_slots; i++) { 9326 if ((cmd = mpt->m_active->m_slot[i]) != NULL) { 9327 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 9328 cmd->cmd_active_timeout -= 9329 mptsas_scsi_watchdog_tick; 9330 if (cmd->cmd_active_timeout <= 0) { 9331 /* 9332 * There seems to be a command stuck 9333 * in the active slot. Drain throttle. 9334 */ 9335 mptsas_set_throttle(mpt, 9336 cmd->cmd_tgt_addr, 9337 DRAIN_THROTTLE); 9338 } 9339 } 9340 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 9341 (cmd->cmd_flags & CFLAG_CONFIG) || 9342 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 9343 cmd->cmd_active_timeout -= 9344 mptsas_scsi_watchdog_tick; 9345 if (cmd->cmd_active_timeout <= 0) { 9346 /* 9347 * passthrough command timeout 9348 */ 9349 cmd->cmd_flags |= (CFLAG_FINISHED | 9350 CFLAG_TIMEOUT); 9351 cv_broadcast(&mpt->m_passthru_cv); 9352 cv_broadcast(&mpt->m_config_cv); 9353 cv_broadcast(&mpt->m_fw_diag_cv); 9354 } 9355 } 9356 } 9357 } 9358 9359 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 9360 MPTSAS_HASH_FIRST); 9361 while (ptgt != NULL) { 9362 /* 9363 * If we were draining due to a qfull condition, 9364 * go back to full throttle. 9365 */ 9366 if ((ptgt->m_t_throttle < MAX_THROTTLE) && 9367 (ptgt->m_t_throttle > HOLD_THROTTLE) && 9368 (ptgt->m_t_ncmds < ptgt->m_t_throttle)) { 9369 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 9370 mptsas_restart_hba(mpt); 9371 } 9372 9373 if ((ptgt->m_t_ncmds > 0) && 9374 (ptgt->m_timebase)) { 9375 9376 if (ptgt->m_timebase <= 9377 mptsas_scsi_watchdog_tick) { 9378 ptgt->m_timebase += 9379 mptsas_scsi_watchdog_tick; 9380 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9381 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9382 continue; 9383 } 9384 9385 ptgt->m_timeout -= mptsas_scsi_watchdog_tick; 9386 9387 if (ptgt->m_timeout < 0) { 9388 mptsas_cmd_timeout(mpt, ptgt->m_devhdl); 9389 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9390 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9391 continue; 9392 } 9393 9394 if ((ptgt->m_timeout) <= 9395 mptsas_scsi_watchdog_tick) { 9396 NDBG23(("pending timeout")); 9397 mptsas_set_throttle(mpt, ptgt, 9398 DRAIN_THROTTLE); 9399 } 9400 } 9401 9402 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9403 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9404 } 9405 } 9406 9407 /* 9408 * timeout recovery 9409 */ 9410 static void 9411 mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl) 9412 { 9413 9414 NDBG29(("mptsas_cmd_timeout: target=%d", devhdl)); 9415 mptsas_log(mpt, CE_WARN, "Disconnected command timeout for " 9416 "Target %d", devhdl); 9417 9418 /* 9419 * If the current target is not the target passed in, 9420 * try to reset that target. 9421 */ 9422 NDBG29(("mptsas_cmd_timeout: device reset")); 9423 if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) { 9424 mptsas_log(mpt, CE_WARN, "Target %d reset for command timeout " 9425 "recovery failed!", devhdl); 9426 } 9427 } 9428 9429 /* 9430 * Device / Hotplug control 9431 */ 9432 static int 9433 mptsas_scsi_quiesce(dev_info_t *dip) 9434 { 9435 mptsas_t *mpt; 9436 scsi_hba_tran_t *tran; 9437 9438 tran = ddi_get_driver_private(dip); 9439 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL) 9440 return (-1); 9441 9442 return (mptsas_quiesce_bus(mpt)); 9443 } 9444 9445 static int 9446 mptsas_scsi_unquiesce(dev_info_t *dip) 9447 { 9448 mptsas_t *mpt; 9449 scsi_hba_tran_t *tran; 9450 9451 tran = ddi_get_driver_private(dip); 9452 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL) 9453 return (-1); 9454 9455 return (mptsas_unquiesce_bus(mpt)); 9456 } 9457 9458 static int 9459 mptsas_quiesce_bus(mptsas_t *mpt) 9460 { 9461 mptsas_target_t *ptgt = NULL; 9462 9463 NDBG28(("mptsas_quiesce_bus")); 9464 mutex_enter(&mpt->m_mutex); 9465 9466 /* Set all the throttles to zero */ 9467 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 9468 MPTSAS_HASH_FIRST); 9469 while (ptgt != NULL) { 9470 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 9471 9472 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9473 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9474 } 9475 9476 /* If there are any outstanding commands in the queue */ 9477 if (mpt->m_ncmds) { 9478 mpt->m_softstate |= MPTSAS_SS_DRAINING; 9479 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain, 9480 mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000))); 9481 if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) { 9482 /* 9483 * Quiesce has been interrupted 9484 */ 9485 mpt->m_softstate &= ~MPTSAS_SS_DRAINING; 9486 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9487 &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST); 9488 while (ptgt != NULL) { 9489 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 9490 9491 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9492 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9493 } 9494 mptsas_restart_hba(mpt); 9495 if (mpt->m_quiesce_timeid != 0) { 9496 timeout_id_t tid = mpt->m_quiesce_timeid; 9497 mpt->m_quiesce_timeid = 0; 9498 mutex_exit(&mpt->m_mutex); 9499 (void) untimeout(tid); 9500 return (-1); 9501 } 9502 mutex_exit(&mpt->m_mutex); 9503 return (-1); 9504 } else { 9505 /* Bus has been quiesced */ 9506 ASSERT(mpt->m_quiesce_timeid == 0); 9507 mpt->m_softstate &= ~MPTSAS_SS_DRAINING; 9508 mpt->m_softstate |= MPTSAS_SS_QUIESCED; 9509 mutex_exit(&mpt->m_mutex); 9510 return (0); 9511 } 9512 } 9513 /* Bus was not busy - QUIESCED */ 9514 mutex_exit(&mpt->m_mutex); 9515 9516 return (0); 9517 } 9518 9519 static int 9520 mptsas_unquiesce_bus(mptsas_t *mpt) 9521 { 9522 mptsas_target_t *ptgt = NULL; 9523 9524 NDBG28(("mptsas_unquiesce_bus")); 9525 mutex_enter(&mpt->m_mutex); 9526 mpt->m_softstate &= ~MPTSAS_SS_QUIESCED; 9527 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 9528 MPTSAS_HASH_FIRST); 9529 while (ptgt != NULL) { 9530 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 9531 9532 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9533 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9534 } 9535 mptsas_restart_hba(mpt); 9536 mutex_exit(&mpt->m_mutex); 9537 return (0); 9538 } 9539 9540 static void 9541 mptsas_ncmds_checkdrain(void *arg) 9542 { 9543 mptsas_t *mpt = arg; 9544 mptsas_target_t *ptgt = NULL; 9545 9546 mutex_enter(&mpt->m_mutex); 9547 if (mpt->m_softstate & MPTSAS_SS_DRAINING) { 9548 mpt->m_quiesce_timeid = 0; 9549 if (mpt->m_ncmds == 0) { 9550 /* Command queue has been drained */ 9551 cv_signal(&mpt->m_cv); 9552 } else { 9553 /* 9554 * The throttle may have been reset because 9555 * of a SCSI bus reset 9556 */ 9557 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9558 &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST); 9559 while (ptgt != NULL) { 9560 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 9561 9562 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9563 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9564 } 9565 9566 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain, 9567 mpt, (MPTSAS_QUIESCE_TIMEOUT * 9568 drv_usectohz(1000000))); 9569 } 9570 } 9571 mutex_exit(&mpt->m_mutex); 9572 } 9573 9574 /*ARGSUSED*/ 9575 static void 9576 mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 9577 { 9578 int i; 9579 uint8_t *cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp; 9580 char buf[128]; 9581 9582 buf[0] = '\0'; 9583 NDBG25(("?Cmd (0x%p) dump for Target %d Lun %d:\n", (void *)cmd, 9584 Tgt(cmd), Lun(cmd))); 9585 (void) sprintf(&buf[0], "\tcdb=["); 9586 for (i = 0; i < (int)cmd->cmd_cdblen; i++) { 9587 (void) sprintf(&buf[strlen(buf)], " 0x%x", *cp++); 9588 } 9589 (void) sprintf(&buf[strlen(buf)], " ]"); 9590 NDBG25(("?%s\n", buf)); 9591 NDBG25(("?pkt_flags=0x%x pkt_statistics=0x%x pkt_state=0x%x\n", 9592 cmd->cmd_pkt->pkt_flags, cmd->cmd_pkt->pkt_statistics, 9593 cmd->cmd_pkt->pkt_state)); 9594 NDBG25(("?pkt_scbp=0x%x cmd_flags=0x%x\n", cmd->cmd_pkt->pkt_scbp ? 9595 *(cmd->cmd_pkt->pkt_scbp) : 0, cmd->cmd_flags)); 9596 } 9597 9598 static void 9599 mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd) 9600 { 9601 caddr_t memp; 9602 pMPI2RequestHeader_t request_hdrp; 9603 struct scsi_pkt *pkt = cmd->cmd_pkt; 9604 mptsas_pt_request_t *pt = pkt->pkt_ha_private; 9605 uint32_t request_size, data_size, dataout_size; 9606 uint32_t direction; 9607 ddi_dma_cookie_t data_cookie; 9608 ddi_dma_cookie_t dataout_cookie; 9609 uint32_t request_desc_low, request_desc_high = 0; 9610 uint32_t i, sense_bufp; 9611 uint8_t desc_type; 9612 uint8_t *request, function; 9613 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; 9614 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl; 9615 9616 desc_type = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 9617 9618 request = pt->request; 9619 direction = pt->direction; 9620 request_size = pt->request_size; 9621 data_size = pt->data_size; 9622 dataout_size = pt->dataout_size; 9623 data_cookie = pt->data_cookie; 9624 dataout_cookie = pt->dataout_cookie; 9625 9626 /* 9627 * Store the passthrough message in memory location 9628 * corresponding to our slot number 9629 */ 9630 memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot); 9631 request_hdrp = (pMPI2RequestHeader_t)memp; 9632 bzero(memp, mpt->m_req_frame_size); 9633 9634 for (i = 0; i < request_size; i++) { 9635 bcopy(request + i, memp + i, 1); 9636 } 9637 9638 if (data_size || dataout_size) { 9639 pMpi2SGESimple64_t sgep; 9640 uint32_t sge_flags; 9641 9642 sgep = (pMpi2SGESimple64_t)((uint8_t *)request_hdrp + 9643 request_size); 9644 if (dataout_size) { 9645 9646 sge_flags = dataout_size | 9647 ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 9648 MPI2_SGE_FLAGS_END_OF_BUFFER | 9649 MPI2_SGE_FLAGS_HOST_TO_IOC | 9650 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 9651 MPI2_SGE_FLAGS_SHIFT); 9652 ddi_put32(acc_hdl, &sgep->FlagsLength, sge_flags); 9653 ddi_put32(acc_hdl, &sgep->Address.Low, 9654 (uint32_t)(dataout_cookie.dmac_laddress & 9655 0xffffffffull)); 9656 ddi_put32(acc_hdl, &sgep->Address.High, 9657 (uint32_t)(dataout_cookie.dmac_laddress 9658 >> 32)); 9659 sgep++; 9660 } 9661 sge_flags = data_size; 9662 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 9663 MPI2_SGE_FLAGS_LAST_ELEMENT | 9664 MPI2_SGE_FLAGS_END_OF_BUFFER | 9665 MPI2_SGE_FLAGS_END_OF_LIST | 9666 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 9667 MPI2_SGE_FLAGS_SHIFT); 9668 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) { 9669 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_HOST_TO_IOC) << 9670 MPI2_SGE_FLAGS_SHIFT); 9671 } else { 9672 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_IOC_TO_HOST) << 9673 MPI2_SGE_FLAGS_SHIFT); 9674 } 9675 ddi_put32(acc_hdl, &sgep->FlagsLength, 9676 sge_flags); 9677 ddi_put32(acc_hdl, &sgep->Address.Low, 9678 (uint32_t)(data_cookie.dmac_laddress & 9679 0xffffffffull)); 9680 ddi_put32(acc_hdl, &sgep->Address.High, 9681 (uint32_t)(data_cookie.dmac_laddress >> 32)); 9682 } 9683 9684 function = request_hdrp->Function; 9685 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) || 9686 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 9687 pMpi2SCSIIORequest_t scsi_io_req; 9688 9689 scsi_io_req = (pMpi2SCSIIORequest_t)request_hdrp; 9690 /* 9691 * Put SGE for data and data_out buffer at the end of 9692 * scsi_io_request message header.(64 bytes in total) 9693 * Following above SGEs, the residual space will be 9694 * used by sense data. 9695 */ 9696 ddi_put8(acc_hdl, 9697 &scsi_io_req->SenseBufferLength, 9698 (uint8_t)(request_size - 64)); 9699 9700 sense_bufp = mpt->m_req_frame_dma_addr + 9701 (mpt->m_req_frame_size * cmd->cmd_slot); 9702 sense_bufp += 64; 9703 ddi_put32(acc_hdl, 9704 &scsi_io_req->SenseBufferLowAddress, sense_bufp); 9705 9706 /* 9707 * Set SGLOffset0 value 9708 */ 9709 ddi_put8(acc_hdl, &scsi_io_req->SGLOffset0, 9710 offsetof(MPI2_SCSI_IO_REQUEST, SGL) / 4); 9711 9712 /* 9713 * Setup descriptor info. RAID passthrough must use the 9714 * default request descriptor which is already set, so if this 9715 * is a SCSI IO request, change the descriptor to SCSI IO. 9716 */ 9717 if (function == MPI2_FUNCTION_SCSI_IO_REQUEST) { 9718 desc_type = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 9719 request_desc_high = (ddi_get16(acc_hdl, 9720 &scsi_io_req->DevHandle) << 16); 9721 } 9722 } 9723 9724 /* 9725 * We must wait till the message has been completed before 9726 * beginning the next message so we wait for this one to 9727 * finish. 9728 */ 9729 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 9730 request_desc_low = (cmd->cmd_slot << 16) + desc_type; 9731 cmd->cmd_rfm = NULL; 9732 MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high); 9733 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || 9734 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { 9735 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 9736 } 9737 } 9738 9739 9740 9741 static int 9742 mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply, 9743 uint8_t *data, uint32_t request_size, uint32_t reply_size, 9744 uint32_t data_size, uint32_t direction, uint8_t *dataout, 9745 uint32_t dataout_size, short timeout, int mode) 9746 { 9747 mptsas_pt_request_t pt; 9748 mptsas_dma_alloc_state_t data_dma_state; 9749 mptsas_dma_alloc_state_t dataout_dma_state; 9750 caddr_t memp; 9751 mptsas_cmd_t *cmd = NULL; 9752 struct scsi_pkt *pkt; 9753 uint32_t reply_len = 0, sense_len = 0; 9754 pMPI2RequestHeader_t request_hdrp; 9755 pMPI2RequestHeader_t request_msg; 9756 pMPI2DefaultReply_t reply_msg; 9757 Mpi2SCSIIOReply_t rep_msg; 9758 int i, status = 0, pt_flags = 0, rv = 0; 9759 int rvalue; 9760 uint8_t function; 9761 9762 ASSERT(mutex_owned(&mpt->m_mutex)); 9763 9764 reply_msg = (pMPI2DefaultReply_t)(&rep_msg); 9765 bzero(reply_msg, sizeof (MPI2_DEFAULT_REPLY)); 9766 request_msg = kmem_zalloc(request_size, KM_SLEEP); 9767 9768 mutex_exit(&mpt->m_mutex); 9769 /* 9770 * copy in the request buffer since it could be used by 9771 * another thread when the pt request into waitq 9772 */ 9773 if (ddi_copyin(request, request_msg, request_size, mode)) { 9774 mutex_enter(&mpt->m_mutex); 9775 status = EFAULT; 9776 mptsas_log(mpt, CE_WARN, "failed to copy request data"); 9777 goto out; 9778 } 9779 mutex_enter(&mpt->m_mutex); 9780 9781 function = request_msg->Function; 9782 if (function == MPI2_FUNCTION_SCSI_TASK_MGMT) { 9783 pMpi2SCSITaskManagementRequest_t task; 9784 task = (pMpi2SCSITaskManagementRequest_t)request_msg; 9785 mptsas_setup_bus_reset_delay(mpt); 9786 rv = mptsas_ioc_task_management(mpt, task->TaskType, 9787 task->DevHandle, (int)task->LUN[1], reply, reply_size, 9788 mode); 9789 9790 if (rv != TRUE) { 9791 status = EIO; 9792 mptsas_log(mpt, CE_WARN, "task management failed"); 9793 } 9794 goto out; 9795 } 9796 9797 if (data_size != 0) { 9798 data_dma_state.size = data_size; 9799 if (mptsas_dma_alloc(mpt, &data_dma_state) != DDI_SUCCESS) { 9800 status = ENOMEM; 9801 mptsas_log(mpt, CE_WARN, "failed to alloc DMA " 9802 "resource"); 9803 goto out; 9804 } 9805 pt_flags |= MPTSAS_DATA_ALLOCATED; 9806 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) { 9807 mutex_exit(&mpt->m_mutex); 9808 for (i = 0; i < data_size; i++) { 9809 if (ddi_copyin(data + i, (uint8_t *) 9810 data_dma_state.memp + i, 1, mode)) { 9811 mutex_enter(&mpt->m_mutex); 9812 status = EFAULT; 9813 mptsas_log(mpt, CE_WARN, "failed to " 9814 "copy read data"); 9815 goto out; 9816 } 9817 } 9818 mutex_enter(&mpt->m_mutex); 9819 } 9820 } 9821 9822 if (dataout_size != 0) { 9823 dataout_dma_state.size = dataout_size; 9824 if (mptsas_dma_alloc(mpt, &dataout_dma_state) != DDI_SUCCESS) { 9825 status = ENOMEM; 9826 mptsas_log(mpt, CE_WARN, "failed to alloc DMA " 9827 "resource"); 9828 goto out; 9829 } 9830 pt_flags |= MPTSAS_DATAOUT_ALLOCATED; 9831 mutex_exit(&mpt->m_mutex); 9832 for (i = 0; i < dataout_size; i++) { 9833 if (ddi_copyin(dataout + i, (uint8_t *) 9834 dataout_dma_state.memp + i, 1, mode)) { 9835 mutex_enter(&mpt->m_mutex); 9836 mptsas_log(mpt, CE_WARN, "failed to copy out" 9837 " data"); 9838 status = EFAULT; 9839 goto out; 9840 } 9841 } 9842 mutex_enter(&mpt->m_mutex); 9843 } 9844 9845 if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 9846 status = EAGAIN; 9847 mptsas_log(mpt, CE_NOTE, "event ack command pool is full"); 9848 goto out; 9849 } 9850 pt_flags |= MPTSAS_REQUEST_POOL_CMD; 9851 9852 bzero((caddr_t)cmd, sizeof (*cmd)); 9853 bzero((caddr_t)pkt, scsi_pkt_size()); 9854 bzero((caddr_t)&pt, sizeof (pt)); 9855 9856 cmd->ioc_cmd_slot = (uint32_t)(rvalue); 9857 9858 pt.request = (uint8_t *)request_msg; 9859 pt.direction = direction; 9860 pt.request_size = request_size; 9861 pt.data_size = data_size; 9862 pt.dataout_size = dataout_size; 9863 pt.data_cookie = data_dma_state.cookie; 9864 pt.dataout_cookie = dataout_dma_state.cookie; 9865 9866 /* 9867 * Form a blank cmd/pkt to store the acknowledgement message 9868 */ 9869 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb[0]; 9870 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; 9871 pkt->pkt_ha_private = (opaque_t)&pt; 9872 pkt->pkt_flags = FLAG_HEAD; 9873 pkt->pkt_time = timeout; 9874 cmd->cmd_pkt = pkt; 9875 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_PASSTHRU; 9876 9877 /* 9878 * Save the command in a slot 9879 */ 9880 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 9881 /* 9882 * Once passthru command get slot, set cmd_flags 9883 * CFLAG_PREPARED. 9884 */ 9885 cmd->cmd_flags |= CFLAG_PREPARED; 9886 mptsas_start_passthru(mpt, cmd); 9887 } else { 9888 mptsas_waitq_add(mpt, cmd); 9889 } 9890 9891 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 9892 cv_wait(&mpt->m_passthru_cv, &mpt->m_mutex); 9893 } 9894 9895 if (cmd->cmd_flags & CFLAG_PREPARED) { 9896 memp = mpt->m_req_frame + (mpt->m_req_frame_size * 9897 cmd->cmd_slot); 9898 request_hdrp = (pMPI2RequestHeader_t)memp; 9899 } 9900 9901 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 9902 status = ETIMEDOUT; 9903 mptsas_log(mpt, CE_WARN, "passthrough command timeout"); 9904 pt_flags |= MPTSAS_CMD_TIMEOUT; 9905 goto out; 9906 } 9907 9908 if (cmd->cmd_rfm) { 9909 /* 9910 * cmd_rfm is zero means the command reply is a CONTEXT 9911 * reply and no PCI Write to post the free reply SMFA 9912 * because no reply message frame is used. 9913 * cmd_rfm is non-zero means the reply is a ADDRESS 9914 * reply and reply message frame is used. 9915 */ 9916 pt_flags |= MPTSAS_ADDRESS_REPLY; 9917 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 9918 DDI_DMA_SYNC_FORCPU); 9919 reply_msg = (pMPI2DefaultReply_t) 9920 (mpt->m_reply_frame + (cmd->cmd_rfm - 9921 mpt->m_reply_frame_dma_addr)); 9922 } 9923 9924 mptsas_fma_check(mpt, cmd); 9925 if (pkt->pkt_reason == CMD_TRAN_ERR) { 9926 status = EAGAIN; 9927 mptsas_log(mpt, CE_WARN, "passthru fma error"); 9928 goto out; 9929 } 9930 if (pkt->pkt_reason == CMD_RESET) { 9931 status = EAGAIN; 9932 mptsas_log(mpt, CE_WARN, "ioc reset abort passthru"); 9933 goto out; 9934 } 9935 9936 if (pkt->pkt_reason == CMD_INCOMPLETE) { 9937 status = EIO; 9938 mptsas_log(mpt, CE_WARN, "passthrough command incomplete"); 9939 goto out; 9940 } 9941 9942 mutex_exit(&mpt->m_mutex); 9943 if (cmd->cmd_flags & CFLAG_PREPARED) { 9944 function = request_hdrp->Function; 9945 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) || 9946 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 9947 reply_len = sizeof (MPI2_SCSI_IO_REPLY); 9948 sense_len = reply_size - reply_len; 9949 } else { 9950 reply_len = reply_size; 9951 sense_len = 0; 9952 } 9953 9954 for (i = 0; i < reply_len; i++) { 9955 if (ddi_copyout((uint8_t *)reply_msg + i, reply + i, 1, 9956 mode)) { 9957 mutex_enter(&mpt->m_mutex); 9958 status = EFAULT; 9959 mptsas_log(mpt, CE_WARN, "failed to copy out " 9960 "reply data"); 9961 goto out; 9962 } 9963 } 9964 for (i = 0; i < sense_len; i++) { 9965 if (ddi_copyout((uint8_t *)request_hdrp + 64 + i, 9966 reply + reply_len + i, 1, mode)) { 9967 mutex_enter(&mpt->m_mutex); 9968 status = EFAULT; 9969 mptsas_log(mpt, CE_WARN, "failed to copy out " 9970 "sense data"); 9971 goto out; 9972 } 9973 } 9974 } 9975 9976 if (data_size) { 9977 if (direction != MPTSAS_PASS_THRU_DIRECTION_WRITE) { 9978 (void) ddi_dma_sync(data_dma_state.handle, 0, 0, 9979 DDI_DMA_SYNC_FORCPU); 9980 for (i = 0; i < data_size; i++) { 9981 if (ddi_copyout((uint8_t *)( 9982 data_dma_state.memp + i), data + i, 1, 9983 mode)) { 9984 mutex_enter(&mpt->m_mutex); 9985 status = EFAULT; 9986 mptsas_log(mpt, CE_WARN, "failed to " 9987 "copy out the reply data"); 9988 goto out; 9989 } 9990 } 9991 } 9992 } 9993 mutex_enter(&mpt->m_mutex); 9994 out: 9995 /* 9996 * Put the reply frame back on the free queue, increment the free 9997 * index, and write the new index to the free index register. But only 9998 * if this reply is an ADDRESS reply. 9999 */ 10000 if (pt_flags & MPTSAS_ADDRESS_REPLY) { 10001 ddi_put32(mpt->m_acc_free_queue_hdl, 10002 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 10003 cmd->cmd_rfm); 10004 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 10005 DDI_DMA_SYNC_FORDEV); 10006 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 10007 mpt->m_free_index = 0; 10008 } 10009 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 10010 mpt->m_free_index); 10011 } 10012 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 10013 mptsas_remove_cmd(mpt, cmd); 10014 pt_flags &= (~MPTSAS_REQUEST_POOL_CMD); 10015 } 10016 if (pt_flags & MPTSAS_REQUEST_POOL_CMD) 10017 mptsas_return_to_pool(mpt, cmd); 10018 if (pt_flags & MPTSAS_DATA_ALLOCATED) { 10019 if (mptsas_check_dma_handle(data_dma_state.handle) != 10020 DDI_SUCCESS) { 10021 ddi_fm_service_impact(mpt->m_dip, 10022 DDI_SERVICE_UNAFFECTED); 10023 status = EFAULT; 10024 } 10025 mptsas_dma_free(&data_dma_state); 10026 } 10027 if (pt_flags & MPTSAS_DATAOUT_ALLOCATED) { 10028 if (mptsas_check_dma_handle(dataout_dma_state.handle) != 10029 DDI_SUCCESS) { 10030 ddi_fm_service_impact(mpt->m_dip, 10031 DDI_SERVICE_UNAFFECTED); 10032 status = EFAULT; 10033 } 10034 mptsas_dma_free(&dataout_dma_state); 10035 } 10036 if (pt_flags & MPTSAS_CMD_TIMEOUT) { 10037 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 10038 mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed"); 10039 } 10040 } 10041 if (request_msg) 10042 kmem_free(request_msg, request_size); 10043 10044 return (status); 10045 } 10046 10047 static int 10048 mptsas_pass_thru(mptsas_t *mpt, mptsas_pass_thru_t *data, int mode) 10049 { 10050 /* 10051 * If timeout is 0, set timeout to default of 60 seconds. 10052 */ 10053 if (data->Timeout == 0) { 10054 data->Timeout = MPTSAS_PASS_THRU_TIME_DEFAULT; 10055 } 10056 10057 if (((data->DataSize == 0) && 10058 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_NONE)) || 10059 ((data->DataSize != 0) && 10060 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_READ) || 10061 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_WRITE) || 10062 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) && 10063 (data->DataOutSize != 0))))) { 10064 if (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) { 10065 data->DataDirection = MPTSAS_PASS_THRU_DIRECTION_READ; 10066 } else { 10067 data->DataOutSize = 0; 10068 } 10069 /* 10070 * Send passthru request messages 10071 */ 10072 return (mptsas_do_passthru(mpt, 10073 (uint8_t *)((uintptr_t)data->PtrRequest), 10074 (uint8_t *)((uintptr_t)data->PtrReply), 10075 (uint8_t *)((uintptr_t)data->PtrData), 10076 data->RequestSize, data->ReplySize, 10077 data->DataSize, data->DataDirection, 10078 (uint8_t *)((uintptr_t)data->PtrDataOut), 10079 data->DataOutSize, data->Timeout, mode)); 10080 } else { 10081 return (EINVAL); 10082 } 10083 } 10084 10085 static uint8_t 10086 mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, uint32_t unique_id) 10087 { 10088 uint8_t index; 10089 10090 for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) { 10091 if (mpt->m_fw_diag_buffer_list[index].unique_id == unique_id) { 10092 return (index); 10093 } 10094 } 10095 10096 return (MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND); 10097 } 10098 10099 static void 10100 mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd) 10101 { 10102 pMpi2DiagBufferPostRequest_t pDiag_post_msg; 10103 pMpi2DiagReleaseRequest_t pDiag_release_msg; 10104 struct scsi_pkt *pkt = cmd->cmd_pkt; 10105 mptsas_diag_request_t *diag = pkt->pkt_ha_private; 10106 uint32_t request_desc_low, i; 10107 10108 ASSERT(mutex_owned(&mpt->m_mutex)); 10109 10110 /* 10111 * Form the diag message depending on the post or release function. 10112 */ 10113 if (diag->function == MPI2_FUNCTION_DIAG_BUFFER_POST) { 10114 pDiag_post_msg = (pMpi2DiagBufferPostRequest_t) 10115 (mpt->m_req_frame + (mpt->m_req_frame_size * 10116 cmd->cmd_slot)); 10117 bzero(pDiag_post_msg, mpt->m_req_frame_size); 10118 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->Function, 10119 diag->function); 10120 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->BufferType, 10121 diag->pBuffer->buffer_type); 10122 ddi_put8(mpt->m_acc_req_frame_hdl, 10123 &pDiag_post_msg->ExtendedType, 10124 diag->pBuffer->extended_type); 10125 ddi_put32(mpt->m_acc_req_frame_hdl, 10126 &pDiag_post_msg->BufferLength, 10127 diag->pBuffer->buffer_data.size); 10128 for (i = 0; i < (sizeof (pDiag_post_msg->ProductSpecific) / 4); 10129 i++) { 10130 ddi_put32(mpt->m_acc_req_frame_hdl, 10131 &pDiag_post_msg->ProductSpecific[i], 10132 diag->pBuffer->product_specific[i]); 10133 } 10134 ddi_put32(mpt->m_acc_req_frame_hdl, 10135 &pDiag_post_msg->BufferAddress.Low, 10136 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress 10137 & 0xffffffffull)); 10138 ddi_put32(mpt->m_acc_req_frame_hdl, 10139 &pDiag_post_msg->BufferAddress.High, 10140 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress 10141 >> 32)); 10142 } else { 10143 pDiag_release_msg = (pMpi2DiagReleaseRequest_t) 10144 (mpt->m_req_frame + (mpt->m_req_frame_size * 10145 cmd->cmd_slot)); 10146 bzero(pDiag_release_msg, mpt->m_req_frame_size); 10147 ddi_put8(mpt->m_acc_req_frame_hdl, 10148 &pDiag_release_msg->Function, diag->function); 10149 ddi_put8(mpt->m_acc_req_frame_hdl, 10150 &pDiag_release_msg->BufferType, 10151 diag->pBuffer->buffer_type); 10152 } 10153 10154 /* 10155 * Send the message 10156 */ 10157 (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0, 10158 DDI_DMA_SYNC_FORDEV); 10159 request_desc_low = (cmd->cmd_slot << 16) + 10160 MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 10161 cmd->cmd_rfm = NULL; 10162 MPTSAS_START_CMD(mpt, request_desc_low, 0); 10163 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 10164 DDI_SUCCESS) || 10165 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 10166 DDI_SUCCESS)) { 10167 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 10168 } 10169 } 10170 10171 static int 10172 mptsas_post_fw_diag_buffer(mptsas_t *mpt, 10173 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code) 10174 { 10175 mptsas_diag_request_t diag; 10176 int status, slot_num, post_flags = 0; 10177 mptsas_cmd_t *cmd = NULL; 10178 struct scsi_pkt *pkt; 10179 pMpi2DiagBufferPostReply_t reply; 10180 uint16_t iocstatus; 10181 uint32_t iocloginfo, transfer_length; 10182 10183 /* 10184 * If buffer is not enabled, just leave. 10185 */ 10186 *return_code = MPTSAS_FW_DIAG_ERROR_POST_FAILED; 10187 if (!pBuffer->enabled) { 10188 status = DDI_FAILURE; 10189 goto out; 10190 } 10191 10192 /* 10193 * Clear some flags initially. 10194 */ 10195 pBuffer->force_release = FALSE; 10196 pBuffer->valid_data = FALSE; 10197 pBuffer->owned_by_firmware = FALSE; 10198 10199 /* 10200 * Get a cmd buffer from the cmd buffer pool 10201 */ 10202 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 10203 status = DDI_FAILURE; 10204 mptsas_log(mpt, CE_NOTE, "command pool is full: Post FW Diag"); 10205 goto out; 10206 } 10207 post_flags |= MPTSAS_REQUEST_POOL_CMD; 10208 10209 bzero((caddr_t)cmd, sizeof (*cmd)); 10210 bzero((caddr_t)pkt, scsi_pkt_size()); 10211 10212 cmd->ioc_cmd_slot = (uint32_t)(slot_num); 10213 10214 diag.pBuffer = pBuffer; 10215 diag.function = MPI2_FUNCTION_DIAG_BUFFER_POST; 10216 10217 /* 10218 * Form a blank cmd/pkt to store the acknowledgement message 10219 */ 10220 pkt->pkt_ha_private = (opaque_t)&diag; 10221 pkt->pkt_flags = FLAG_HEAD; 10222 pkt->pkt_time = 60; 10223 cmd->cmd_pkt = pkt; 10224 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG; 10225 10226 /* 10227 * Save the command in a slot 10228 */ 10229 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 10230 /* 10231 * Once passthru command get slot, set cmd_flags 10232 * CFLAG_PREPARED. 10233 */ 10234 cmd->cmd_flags |= CFLAG_PREPARED; 10235 mptsas_start_diag(mpt, cmd); 10236 } else { 10237 mptsas_waitq_add(mpt, cmd); 10238 } 10239 10240 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 10241 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex); 10242 } 10243 10244 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 10245 status = DDI_FAILURE; 10246 mptsas_log(mpt, CE_WARN, "Post FW Diag command timeout"); 10247 goto out; 10248 } 10249 10250 /* 10251 * cmd_rfm points to the reply message if a reply was given. Check the 10252 * IOCStatus to make sure everything went OK with the FW diag request 10253 * and set buffer flags. 10254 */ 10255 if (cmd->cmd_rfm) { 10256 post_flags |= MPTSAS_ADDRESS_REPLY; 10257 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 10258 DDI_DMA_SYNC_FORCPU); 10259 reply = (pMpi2DiagBufferPostReply_t)(mpt->m_reply_frame + 10260 (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr)); 10261 10262 /* 10263 * Get the reply message data 10264 */ 10265 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 10266 &reply->IOCStatus); 10267 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 10268 &reply->IOCLogInfo); 10269 transfer_length = ddi_get32(mpt->m_acc_reply_frame_hdl, 10270 &reply->TransferLength); 10271 10272 /* 10273 * If post failed quit. 10274 */ 10275 if (iocstatus != MPI2_IOCSTATUS_SUCCESS) { 10276 status = DDI_FAILURE; 10277 NDBG13(("post FW Diag Buffer failed: IOCStatus=0x%x, " 10278 "IOCLogInfo=0x%x, TransferLength=0x%x", iocstatus, 10279 iocloginfo, transfer_length)); 10280 goto out; 10281 } 10282 10283 /* 10284 * Post was successful. 10285 */ 10286 pBuffer->valid_data = TRUE; 10287 pBuffer->owned_by_firmware = TRUE; 10288 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 10289 status = DDI_SUCCESS; 10290 } 10291 10292 out: 10293 /* 10294 * Put the reply frame back on the free queue, increment the free 10295 * index, and write the new index to the free index register. But only 10296 * if this reply is an ADDRESS reply. 10297 */ 10298 if (post_flags & MPTSAS_ADDRESS_REPLY) { 10299 ddi_put32(mpt->m_acc_free_queue_hdl, 10300 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 10301 cmd->cmd_rfm); 10302 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 10303 DDI_DMA_SYNC_FORDEV); 10304 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 10305 mpt->m_free_index = 0; 10306 } 10307 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 10308 mpt->m_free_index); 10309 } 10310 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 10311 mptsas_remove_cmd(mpt, cmd); 10312 post_flags &= (~MPTSAS_REQUEST_POOL_CMD); 10313 } 10314 if (post_flags & MPTSAS_REQUEST_POOL_CMD) { 10315 mptsas_return_to_pool(mpt, cmd); 10316 } 10317 10318 return (status); 10319 } 10320 10321 static int 10322 mptsas_release_fw_diag_buffer(mptsas_t *mpt, 10323 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code, 10324 uint32_t diag_type) 10325 { 10326 mptsas_diag_request_t diag; 10327 int status, slot_num, rel_flags = 0; 10328 mptsas_cmd_t *cmd = NULL; 10329 struct scsi_pkt *pkt; 10330 pMpi2DiagReleaseReply_t reply; 10331 uint16_t iocstatus; 10332 uint32_t iocloginfo; 10333 10334 /* 10335 * If buffer is not enabled, just leave. 10336 */ 10337 *return_code = MPTSAS_FW_DIAG_ERROR_RELEASE_FAILED; 10338 if (!pBuffer->enabled) { 10339 mptsas_log(mpt, CE_NOTE, "This buffer type is not supported " 10340 "by the IOC"); 10341 status = DDI_FAILURE; 10342 goto out; 10343 } 10344 10345 /* 10346 * Clear some flags initially. 10347 */ 10348 pBuffer->force_release = FALSE; 10349 pBuffer->valid_data = FALSE; 10350 pBuffer->owned_by_firmware = FALSE; 10351 10352 /* 10353 * Get a cmd buffer from the cmd buffer pool 10354 */ 10355 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 10356 status = DDI_FAILURE; 10357 mptsas_log(mpt, CE_NOTE, "command pool is full: Release FW " 10358 "Diag"); 10359 goto out; 10360 } 10361 rel_flags |= MPTSAS_REQUEST_POOL_CMD; 10362 10363 bzero((caddr_t)cmd, sizeof (*cmd)); 10364 bzero((caddr_t)pkt, scsi_pkt_size()); 10365 10366 cmd->ioc_cmd_slot = (uint32_t)(slot_num); 10367 10368 diag.pBuffer = pBuffer; 10369 diag.function = MPI2_FUNCTION_DIAG_RELEASE; 10370 10371 /* 10372 * Form a blank cmd/pkt to store the acknowledgement message 10373 */ 10374 pkt->pkt_ha_private = (opaque_t)&diag; 10375 pkt->pkt_flags = FLAG_HEAD; 10376 pkt->pkt_time = 60; 10377 cmd->cmd_pkt = pkt; 10378 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG; 10379 10380 /* 10381 * Save the command in a slot 10382 */ 10383 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 10384 /* 10385 * Once passthru command get slot, set cmd_flags 10386 * CFLAG_PREPARED. 10387 */ 10388 cmd->cmd_flags |= CFLAG_PREPARED; 10389 mptsas_start_diag(mpt, cmd); 10390 } else { 10391 mptsas_waitq_add(mpt, cmd); 10392 } 10393 10394 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 10395 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex); 10396 } 10397 10398 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 10399 status = DDI_FAILURE; 10400 mptsas_log(mpt, CE_WARN, "Release FW Diag command timeout"); 10401 goto out; 10402 } 10403 10404 /* 10405 * cmd_rfm points to the reply message if a reply was given. Check the 10406 * IOCStatus to make sure everything went OK with the FW diag request 10407 * and set buffer flags. 10408 */ 10409 if (cmd->cmd_rfm) { 10410 rel_flags |= MPTSAS_ADDRESS_REPLY; 10411 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 10412 DDI_DMA_SYNC_FORCPU); 10413 reply = (pMpi2DiagReleaseReply_t)(mpt->m_reply_frame + 10414 (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr)); 10415 10416 /* 10417 * Get the reply message data 10418 */ 10419 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 10420 &reply->IOCStatus); 10421 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 10422 &reply->IOCLogInfo); 10423 10424 /* 10425 * If release failed quit. 10426 */ 10427 if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) || 10428 pBuffer->owned_by_firmware) { 10429 status = DDI_FAILURE; 10430 NDBG13(("release FW Diag Buffer failed: " 10431 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus, 10432 iocloginfo)); 10433 goto out; 10434 } 10435 10436 /* 10437 * Release was successful. 10438 */ 10439 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 10440 status = DDI_SUCCESS; 10441 10442 /* 10443 * If this was for an UNREGISTER diag type command, clear the 10444 * unique ID. 10445 */ 10446 if (diag_type == MPTSAS_FW_DIAG_TYPE_UNREGISTER) { 10447 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID; 10448 } 10449 } 10450 10451 out: 10452 /* 10453 * Put the reply frame back on the free queue, increment the free 10454 * index, and write the new index to the free index register. But only 10455 * if this reply is an ADDRESS reply. 10456 */ 10457 if (rel_flags & MPTSAS_ADDRESS_REPLY) { 10458 ddi_put32(mpt->m_acc_free_queue_hdl, 10459 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 10460 cmd->cmd_rfm); 10461 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 10462 DDI_DMA_SYNC_FORDEV); 10463 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 10464 mpt->m_free_index = 0; 10465 } 10466 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 10467 mpt->m_free_index); 10468 } 10469 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 10470 mptsas_remove_cmd(mpt, cmd); 10471 rel_flags &= (~MPTSAS_REQUEST_POOL_CMD); 10472 } 10473 if (rel_flags & MPTSAS_REQUEST_POOL_CMD) { 10474 mptsas_return_to_pool(mpt, cmd); 10475 } 10476 10477 return (status); 10478 } 10479 10480 static int 10481 mptsas_diag_register(mptsas_t *mpt, mptsas_fw_diag_register_t *diag_register, 10482 uint32_t *return_code) 10483 { 10484 mptsas_fw_diagnostic_buffer_t *pBuffer; 10485 uint8_t extended_type, buffer_type, i; 10486 uint32_t buffer_size; 10487 uint32_t unique_id; 10488 int status; 10489 10490 ASSERT(mutex_owned(&mpt->m_mutex)); 10491 10492 extended_type = diag_register->ExtendedType; 10493 buffer_type = diag_register->BufferType; 10494 buffer_size = diag_register->RequestedBufferSize; 10495 unique_id = diag_register->UniqueId; 10496 10497 /* 10498 * Check for valid buffer type 10499 */ 10500 if (buffer_type >= MPI2_DIAG_BUF_TYPE_COUNT) { 10501 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10502 return (DDI_FAILURE); 10503 } 10504 10505 /* 10506 * Get the current buffer and look up the unique ID. The unique ID 10507 * should not be found. If it is, the ID is already in use. 10508 */ 10509 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 10510 pBuffer = &mpt->m_fw_diag_buffer_list[buffer_type]; 10511 if (i != MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 10512 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10513 return (DDI_FAILURE); 10514 } 10515 10516 /* 10517 * The buffer's unique ID should not be registered yet, and the given 10518 * unique ID cannot be 0. 10519 */ 10520 if ((pBuffer->unique_id != MPTSAS_FW_DIAG_INVALID_UID) || 10521 (unique_id == MPTSAS_FW_DIAG_INVALID_UID)) { 10522 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10523 return (DDI_FAILURE); 10524 } 10525 10526 /* 10527 * If this buffer is already posted as immediate, just change owner. 10528 */ 10529 if (pBuffer->immediate && pBuffer->owned_by_firmware && 10530 (pBuffer->unique_id == MPTSAS_FW_DIAG_INVALID_UID)) { 10531 pBuffer->immediate = FALSE; 10532 pBuffer->unique_id = unique_id; 10533 return (DDI_SUCCESS); 10534 } 10535 10536 /* 10537 * Post a new buffer after checking if it's enabled. The DMA buffer 10538 * that is allocated will be contiguous (sgl_len = 1). 10539 */ 10540 if (!pBuffer->enabled) { 10541 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER; 10542 return (DDI_FAILURE); 10543 } 10544 bzero(&pBuffer->buffer_data, sizeof (mptsas_dma_alloc_state_t)); 10545 pBuffer->buffer_data.size = buffer_size; 10546 if (mptsas_dma_alloc(mpt, &pBuffer->buffer_data) != DDI_SUCCESS) { 10547 mptsas_log(mpt, CE_WARN, "failed to alloc DMA resource for " 10548 "diag buffer: size = %d bytes", buffer_size); 10549 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER; 10550 return (DDI_FAILURE); 10551 } 10552 10553 /* 10554 * Copy the given info to the diag buffer and post the buffer. 10555 */ 10556 pBuffer->buffer_type = buffer_type; 10557 pBuffer->immediate = FALSE; 10558 if (buffer_type == MPI2_DIAG_BUF_TYPE_TRACE) { 10559 for (i = 0; i < (sizeof (pBuffer->product_specific) / 4); 10560 i++) { 10561 pBuffer->product_specific[i] = 10562 diag_register->ProductSpecific[i]; 10563 } 10564 } 10565 pBuffer->extended_type = extended_type; 10566 pBuffer->unique_id = unique_id; 10567 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, return_code); 10568 10569 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) != 10570 DDI_SUCCESS) { 10571 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed in " 10572 "mptsas_diag_register."); 10573 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 10574 status = DDI_FAILURE; 10575 } 10576 10577 /* 10578 * In case there was a failure, free the DMA buffer. 10579 */ 10580 if (status == DDI_FAILURE) { 10581 mptsas_dma_free(&pBuffer->buffer_data); 10582 } 10583 10584 return (status); 10585 } 10586 10587 static int 10588 mptsas_diag_unregister(mptsas_t *mpt, 10589 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code) 10590 { 10591 mptsas_fw_diagnostic_buffer_t *pBuffer; 10592 uint8_t i; 10593 uint32_t unique_id; 10594 int status; 10595 10596 ASSERT(mutex_owned(&mpt->m_mutex)); 10597 10598 unique_id = diag_unregister->UniqueId; 10599 10600 /* 10601 * Get the current buffer and look up the unique ID. The unique ID 10602 * should be there. 10603 */ 10604 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 10605 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 10606 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10607 return (DDI_FAILURE); 10608 } 10609 10610 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 10611 10612 /* 10613 * Try to release the buffer from FW before freeing it. If release 10614 * fails, don't free the DMA buffer in case FW tries to access it 10615 * later. If buffer is not owned by firmware, can't release it. 10616 */ 10617 if (!pBuffer->owned_by_firmware) { 10618 status = DDI_SUCCESS; 10619 } else { 10620 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, 10621 return_code, MPTSAS_FW_DIAG_TYPE_UNREGISTER); 10622 } 10623 10624 /* 10625 * At this point, return the current status no matter what happens with 10626 * the DMA buffer. 10627 */ 10628 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID; 10629 if (status == DDI_SUCCESS) { 10630 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) != 10631 DDI_SUCCESS) { 10632 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed " 10633 "in mptsas_diag_unregister."); 10634 ddi_fm_service_impact(mpt->m_dip, 10635 DDI_SERVICE_UNAFFECTED); 10636 } 10637 mptsas_dma_free(&pBuffer->buffer_data); 10638 } 10639 10640 return (status); 10641 } 10642 10643 static int 10644 mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query, 10645 uint32_t *return_code) 10646 { 10647 mptsas_fw_diagnostic_buffer_t *pBuffer; 10648 uint8_t i; 10649 uint32_t unique_id; 10650 10651 ASSERT(mutex_owned(&mpt->m_mutex)); 10652 10653 unique_id = diag_query->UniqueId; 10654 10655 /* 10656 * If ID is valid, query on ID. 10657 * If ID is invalid, query on buffer type. 10658 */ 10659 if (unique_id == MPTSAS_FW_DIAG_INVALID_UID) { 10660 i = diag_query->BufferType; 10661 if (i >= MPI2_DIAG_BUF_TYPE_COUNT) { 10662 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10663 return (DDI_FAILURE); 10664 } 10665 } else { 10666 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 10667 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 10668 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10669 return (DDI_FAILURE); 10670 } 10671 } 10672 10673 /* 10674 * Fill query structure with the diag buffer info. 10675 */ 10676 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 10677 diag_query->BufferType = pBuffer->buffer_type; 10678 diag_query->ExtendedType = pBuffer->extended_type; 10679 if (diag_query->BufferType == MPI2_DIAG_BUF_TYPE_TRACE) { 10680 for (i = 0; i < (sizeof (diag_query->ProductSpecific) / 4); 10681 i++) { 10682 diag_query->ProductSpecific[i] = 10683 pBuffer->product_specific[i]; 10684 } 10685 } 10686 diag_query->TotalBufferSize = pBuffer->buffer_data.size; 10687 diag_query->DriverAddedBufferSize = 0; 10688 diag_query->UniqueId = pBuffer->unique_id; 10689 diag_query->ApplicationFlags = 0; 10690 diag_query->DiagnosticFlags = 0; 10691 10692 /* 10693 * Set/Clear application flags 10694 */ 10695 if (pBuffer->immediate) { 10696 diag_query->ApplicationFlags &= ~MPTSAS_FW_DIAG_FLAG_APP_OWNED; 10697 } else { 10698 diag_query->ApplicationFlags |= MPTSAS_FW_DIAG_FLAG_APP_OWNED; 10699 } 10700 if (pBuffer->valid_data || pBuffer->owned_by_firmware) { 10701 diag_query->ApplicationFlags |= 10702 MPTSAS_FW_DIAG_FLAG_BUFFER_VALID; 10703 } else { 10704 diag_query->ApplicationFlags &= 10705 ~MPTSAS_FW_DIAG_FLAG_BUFFER_VALID; 10706 } 10707 if (pBuffer->owned_by_firmware) { 10708 diag_query->ApplicationFlags |= 10709 MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS; 10710 } else { 10711 diag_query->ApplicationFlags &= 10712 ~MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS; 10713 } 10714 10715 return (DDI_SUCCESS); 10716 } 10717 10718 static int 10719 mptsas_diag_read_buffer(mptsas_t *mpt, 10720 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf, 10721 uint32_t *return_code, int ioctl_mode) 10722 { 10723 mptsas_fw_diagnostic_buffer_t *pBuffer; 10724 uint8_t i, *pData; 10725 uint32_t unique_id, byte; 10726 int status; 10727 10728 ASSERT(mutex_owned(&mpt->m_mutex)); 10729 10730 unique_id = diag_read_buffer->UniqueId; 10731 10732 /* 10733 * Get the current buffer and look up the unique ID. The unique ID 10734 * should be there. 10735 */ 10736 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 10737 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 10738 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10739 return (DDI_FAILURE); 10740 } 10741 10742 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 10743 10744 /* 10745 * Make sure requested read is within limits 10746 */ 10747 if (diag_read_buffer->StartingOffset + diag_read_buffer->BytesToRead > 10748 pBuffer->buffer_data.size) { 10749 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10750 return (DDI_FAILURE); 10751 } 10752 10753 /* 10754 * Copy the requested data from DMA to the diag_read_buffer. The DMA 10755 * buffer that was allocated is one contiguous buffer. 10756 */ 10757 pData = (uint8_t *)(pBuffer->buffer_data.memp + 10758 diag_read_buffer->StartingOffset); 10759 (void) ddi_dma_sync(pBuffer->buffer_data.handle, 0, 0, 10760 DDI_DMA_SYNC_FORCPU); 10761 for (byte = 0; byte < diag_read_buffer->BytesToRead; byte++) { 10762 if (ddi_copyout(pData + byte, ioctl_buf + byte, 1, ioctl_mode) 10763 != 0) { 10764 return (DDI_FAILURE); 10765 } 10766 } 10767 diag_read_buffer->Status = 0; 10768 10769 /* 10770 * Set or clear the Force Release flag. 10771 */ 10772 if (pBuffer->force_release) { 10773 diag_read_buffer->Flags |= MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE; 10774 } else { 10775 diag_read_buffer->Flags &= ~MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE; 10776 } 10777 10778 /* 10779 * If buffer is to be reregistered, make sure it's not already owned by 10780 * firmware first. 10781 */ 10782 status = DDI_SUCCESS; 10783 if (!pBuffer->owned_by_firmware) { 10784 if (diag_read_buffer->Flags & MPTSAS_FW_DIAG_FLAG_REREGISTER) { 10785 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, 10786 return_code); 10787 } 10788 } 10789 10790 return (status); 10791 } 10792 10793 static int 10794 mptsas_diag_release(mptsas_t *mpt, mptsas_fw_diag_release_t *diag_release, 10795 uint32_t *return_code) 10796 { 10797 mptsas_fw_diagnostic_buffer_t *pBuffer; 10798 uint8_t i; 10799 uint32_t unique_id; 10800 int status; 10801 10802 ASSERT(mutex_owned(&mpt->m_mutex)); 10803 10804 unique_id = diag_release->UniqueId; 10805 10806 /* 10807 * Get the current buffer and look up the unique ID. The unique ID 10808 * should be there. 10809 */ 10810 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 10811 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 10812 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 10813 return (DDI_FAILURE); 10814 } 10815 10816 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 10817 10818 /* 10819 * If buffer is not owned by firmware, it's already been released. 10820 */ 10821 if (!pBuffer->owned_by_firmware) { 10822 *return_code = MPTSAS_FW_DIAG_ERROR_ALREADY_RELEASED; 10823 return (DDI_FAILURE); 10824 } 10825 10826 /* 10827 * Release the buffer. 10828 */ 10829 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, return_code, 10830 MPTSAS_FW_DIAG_TYPE_RELEASE); 10831 return (status); 10832 } 10833 10834 static int 10835 mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, uint8_t *diag_action, 10836 uint32_t length, uint32_t *return_code, int ioctl_mode) 10837 { 10838 mptsas_fw_diag_register_t diag_register; 10839 mptsas_fw_diag_unregister_t diag_unregister; 10840 mptsas_fw_diag_query_t diag_query; 10841 mptsas_diag_read_buffer_t diag_read_buffer; 10842 mptsas_fw_diag_release_t diag_release; 10843 int status = DDI_SUCCESS; 10844 uint32_t original_return_code, read_buf_len; 10845 10846 ASSERT(mutex_owned(&mpt->m_mutex)); 10847 10848 original_return_code = *return_code; 10849 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 10850 10851 switch (action) { 10852 case MPTSAS_FW_DIAG_TYPE_REGISTER: 10853 if (!length) { 10854 *return_code = 10855 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10856 status = DDI_FAILURE; 10857 break; 10858 } 10859 if (ddi_copyin(diag_action, &diag_register, 10860 sizeof (diag_register), ioctl_mode) != 0) { 10861 return (DDI_FAILURE); 10862 } 10863 status = mptsas_diag_register(mpt, &diag_register, 10864 return_code); 10865 break; 10866 10867 case MPTSAS_FW_DIAG_TYPE_UNREGISTER: 10868 if (length < sizeof (diag_unregister)) { 10869 *return_code = 10870 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10871 status = DDI_FAILURE; 10872 break; 10873 } 10874 if (ddi_copyin(diag_action, &diag_unregister, 10875 sizeof (diag_unregister), ioctl_mode) != 0) { 10876 return (DDI_FAILURE); 10877 } 10878 status = mptsas_diag_unregister(mpt, &diag_unregister, 10879 return_code); 10880 break; 10881 10882 case MPTSAS_FW_DIAG_TYPE_QUERY: 10883 if (length < sizeof (diag_query)) { 10884 *return_code = 10885 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10886 status = DDI_FAILURE; 10887 break; 10888 } 10889 if (ddi_copyin(diag_action, &diag_query, 10890 sizeof (diag_query), ioctl_mode) != 0) { 10891 return (DDI_FAILURE); 10892 } 10893 status = mptsas_diag_query(mpt, &diag_query, 10894 return_code); 10895 if (status == DDI_SUCCESS) { 10896 if (ddi_copyout(&diag_query, diag_action, 10897 sizeof (diag_query), ioctl_mode) != 0) { 10898 return (DDI_FAILURE); 10899 } 10900 } 10901 break; 10902 10903 case MPTSAS_FW_DIAG_TYPE_READ_BUFFER: 10904 if (ddi_copyin(diag_action, &diag_read_buffer, 10905 sizeof (diag_read_buffer) - 4, ioctl_mode) != 0) { 10906 return (DDI_FAILURE); 10907 } 10908 read_buf_len = sizeof (diag_read_buffer) - 10909 sizeof (diag_read_buffer.DataBuffer) + 10910 diag_read_buffer.BytesToRead; 10911 if (length < read_buf_len) { 10912 *return_code = 10913 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10914 status = DDI_FAILURE; 10915 break; 10916 } 10917 status = mptsas_diag_read_buffer(mpt, 10918 &diag_read_buffer, diag_action + 10919 sizeof (diag_read_buffer) - 4, return_code, 10920 ioctl_mode); 10921 if (status == DDI_SUCCESS) { 10922 if (ddi_copyout(&diag_read_buffer, diag_action, 10923 sizeof (diag_read_buffer) - 4, ioctl_mode) 10924 != 0) { 10925 return (DDI_FAILURE); 10926 } 10927 } 10928 break; 10929 10930 case MPTSAS_FW_DIAG_TYPE_RELEASE: 10931 if (length < sizeof (diag_release)) { 10932 *return_code = 10933 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10934 status = DDI_FAILURE; 10935 break; 10936 } 10937 if (ddi_copyin(diag_action, &diag_release, 10938 sizeof (diag_release), ioctl_mode) != 0) { 10939 return (DDI_FAILURE); 10940 } 10941 status = mptsas_diag_release(mpt, &diag_release, 10942 return_code); 10943 break; 10944 10945 default: 10946 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 10947 status = DDI_FAILURE; 10948 break; 10949 } 10950 10951 if ((status == DDI_FAILURE) && 10952 (original_return_code == MPTSAS_FW_DIAG_NEW) && 10953 (*return_code != MPTSAS_FW_DIAG_ERROR_SUCCESS)) { 10954 status = DDI_SUCCESS; 10955 } 10956 10957 return (status); 10958 } 10959 10960 static int 10961 mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *user_data, int mode) 10962 { 10963 int status; 10964 mptsas_diag_action_t driver_data; 10965 10966 ASSERT(mutex_owned(&mpt->m_mutex)); 10967 10968 /* 10969 * Copy the user data to a driver data buffer. 10970 */ 10971 if (ddi_copyin(user_data, &driver_data, sizeof (mptsas_diag_action_t), 10972 mode) == 0) { 10973 /* 10974 * Send diag action request if Action is valid 10975 */ 10976 if (driver_data.Action == MPTSAS_FW_DIAG_TYPE_REGISTER || 10977 driver_data.Action == MPTSAS_FW_DIAG_TYPE_UNREGISTER || 10978 driver_data.Action == MPTSAS_FW_DIAG_TYPE_QUERY || 10979 driver_data.Action == MPTSAS_FW_DIAG_TYPE_READ_BUFFER || 10980 driver_data.Action == MPTSAS_FW_DIAG_TYPE_RELEASE) { 10981 status = mptsas_do_diag_action(mpt, driver_data.Action, 10982 (void *)(uintptr_t)driver_data.PtrDiagAction, 10983 driver_data.Length, &driver_data.ReturnCode, 10984 mode); 10985 if (status == DDI_SUCCESS) { 10986 if (ddi_copyout(&driver_data.ReturnCode, 10987 &user_data->ReturnCode, 10988 sizeof (user_data->ReturnCode), mode) 10989 != 0) { 10990 status = EFAULT; 10991 } else { 10992 status = 0; 10993 } 10994 } else { 10995 status = EIO; 10996 } 10997 } else { 10998 status = EINVAL; 10999 } 11000 } else { 11001 status = EFAULT; 11002 } 11003 11004 return (status); 11005 } 11006 11007 /* 11008 * This routine handles the "event query" ioctl. 11009 */ 11010 static int 11011 mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, int mode, 11012 int *rval) 11013 { 11014 int status; 11015 mptsas_event_query_t driverdata; 11016 uint8_t i; 11017 11018 driverdata.Entries = MPTSAS_EVENT_QUEUE_SIZE; 11019 11020 mutex_enter(&mpt->m_mutex); 11021 for (i = 0; i < 4; i++) { 11022 driverdata.Types[i] = mpt->m_event_mask[i]; 11023 } 11024 mutex_exit(&mpt->m_mutex); 11025 11026 if (ddi_copyout(&driverdata, data, sizeof (driverdata), mode) != 0) { 11027 status = EFAULT; 11028 } else { 11029 *rval = MPTIOCTL_STATUS_GOOD; 11030 status = 0; 11031 } 11032 11033 return (status); 11034 } 11035 11036 /* 11037 * This routine handles the "event enable" ioctl. 11038 */ 11039 static int 11040 mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, int mode, 11041 int *rval) 11042 { 11043 int status; 11044 mptsas_event_enable_t driverdata; 11045 uint8_t i; 11046 11047 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) { 11048 mutex_enter(&mpt->m_mutex); 11049 for (i = 0; i < 4; i++) { 11050 mpt->m_event_mask[i] = driverdata.Types[i]; 11051 } 11052 mutex_exit(&mpt->m_mutex); 11053 11054 *rval = MPTIOCTL_STATUS_GOOD; 11055 status = 0; 11056 } else { 11057 status = EFAULT; 11058 } 11059 return (status); 11060 } 11061 11062 /* 11063 * This routine handles the "event report" ioctl. 11064 */ 11065 static int 11066 mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, int mode, 11067 int *rval) 11068 { 11069 int status; 11070 mptsas_event_report_t driverdata; 11071 11072 mutex_enter(&mpt->m_mutex); 11073 11074 if (ddi_copyin(&data->Size, &driverdata.Size, sizeof (driverdata.Size), 11075 mode) == 0) { 11076 if (driverdata.Size >= sizeof (mpt->m_events)) { 11077 if (ddi_copyout(mpt->m_events, data->Events, 11078 sizeof (mpt->m_events), mode) != 0) { 11079 status = EFAULT; 11080 } else { 11081 if (driverdata.Size > sizeof (mpt->m_events)) { 11082 driverdata.Size = 11083 sizeof (mpt->m_events); 11084 if (ddi_copyout(&driverdata.Size, 11085 &data->Size, 11086 sizeof (driverdata.Size), 11087 mode) != 0) { 11088 status = EFAULT; 11089 } else { 11090 *rval = MPTIOCTL_STATUS_GOOD; 11091 status = 0; 11092 } 11093 } else { 11094 *rval = MPTIOCTL_STATUS_GOOD; 11095 status = 0; 11096 } 11097 } 11098 } else { 11099 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT; 11100 status = 0; 11101 } 11102 } else { 11103 status = EFAULT; 11104 } 11105 11106 mutex_exit(&mpt->m_mutex); 11107 return (status); 11108 } 11109 11110 static void 11111 mptsas_lookup_pci_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data) 11112 { 11113 int *reg_data; 11114 uint_t reglen; 11115 11116 /* 11117 * Lookup the 'reg' property and extract the other data 11118 */ 11119 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip, 11120 DDI_PROP_DONTPASS, "reg", ®_data, ®len) == 11121 DDI_PROP_SUCCESS) { 11122 /* 11123 * Extract the PCI data from the 'reg' property first DWORD. 11124 * The entry looks like the following: 11125 * First DWORD: 11126 * Bits 0 - 7 8-bit Register number 11127 * Bits 8 - 10 3-bit Function number 11128 * Bits 11 - 15 5-bit Device number 11129 * Bits 16 - 23 8-bit Bus number 11130 * Bits 24 - 25 2-bit Address Space type identifier 11131 * 11132 */ 11133 adapter_data->PciInformation.u.bits.BusNumber = 11134 (reg_data[0] & 0x00FF0000) >> 16; 11135 adapter_data->PciInformation.u.bits.DeviceNumber = 11136 (reg_data[0] & 0x0000F800) >> 11; 11137 adapter_data->PciInformation.u.bits.FunctionNumber = 11138 (reg_data[0] & 0x00000700) >> 8; 11139 ddi_prop_free((void *)reg_data); 11140 } else { 11141 /* 11142 * If we can't determine the PCI data then we fill in FF's for 11143 * the data to indicate this. 11144 */ 11145 adapter_data->PCIDeviceHwId = 0xFFFFFFFF; 11146 adapter_data->MpiPortNumber = 0xFFFFFFFF; 11147 adapter_data->PciInformation.u.AsDWORD = 0xFFFFFFFF; 11148 } 11149 11150 /* 11151 * Saved in the mpt->m_fwversion 11152 */ 11153 adapter_data->MpiFirmwareVersion = mpt->m_fwversion; 11154 } 11155 11156 static void 11157 mptsas_read_adapter_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data) 11158 { 11159 char *driver_verstr = MPTSAS_MOD_STRING; 11160 11161 mptsas_lookup_pci_data(mpt, adapter_data); 11162 adapter_data->AdapterType = MPTIOCTL_ADAPTER_TYPE_SAS2; 11163 adapter_data->PCIDeviceHwId = (uint32_t)mpt->m_devid; 11164 adapter_data->PCIDeviceHwRev = (uint32_t)mpt->m_revid; 11165 adapter_data->SubSystemId = (uint32_t)mpt->m_ssid; 11166 adapter_data->SubsystemVendorId = (uint32_t)mpt->m_svid; 11167 (void) strcpy((char *)&adapter_data->DriverVersion[0], driver_verstr); 11168 adapter_data->BiosVersion = 0; 11169 (void) mptsas_get_bios_page3(mpt, &adapter_data->BiosVersion); 11170 } 11171 11172 static void 11173 mptsas_read_pci_info(mptsas_t *mpt, mptsas_pci_info_t *pci_info) 11174 { 11175 int *reg_data, i; 11176 uint_t reglen; 11177 11178 /* 11179 * Lookup the 'reg' property and extract the other data 11180 */ 11181 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip, 11182 DDI_PROP_DONTPASS, "reg", ®_data, ®len) == 11183 DDI_PROP_SUCCESS) { 11184 /* 11185 * Extract the PCI data from the 'reg' property first DWORD. 11186 * The entry looks like the following: 11187 * First DWORD: 11188 * Bits 8 - 10 3-bit Function number 11189 * Bits 11 - 15 5-bit Device number 11190 * Bits 16 - 23 8-bit Bus number 11191 */ 11192 pci_info->BusNumber = (reg_data[0] & 0x00FF0000) >> 16; 11193 pci_info->DeviceNumber = (reg_data[0] & 0x0000F800) >> 11; 11194 pci_info->FunctionNumber = (reg_data[0] & 0x00000700) >> 8; 11195 ddi_prop_free((void *)reg_data); 11196 } else { 11197 /* 11198 * If we can't determine the PCI info then we fill in FF's for 11199 * the data to indicate this. 11200 */ 11201 pci_info->BusNumber = 0xFFFFFFFF; 11202 pci_info->DeviceNumber = 0xFF; 11203 pci_info->FunctionNumber = 0xFF; 11204 } 11205 11206 /* 11207 * Now get the interrupt vector and the pci header. The vector can 11208 * only be 0 right now. The header is the first 256 bytes of config 11209 * space. 11210 */ 11211 pci_info->InterruptVector = 0; 11212 for (i = 0; i < sizeof (pci_info->PciHeader); i++) { 11213 pci_info->PciHeader[i] = pci_config_get8(mpt->m_config_handle, 11214 i); 11215 } 11216 } 11217 11218 static int 11219 mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, int mode) 11220 { 11221 int status = 0; 11222 mptsas_reg_access_t driverdata; 11223 11224 mutex_enter(&mpt->m_mutex); 11225 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) { 11226 switch (driverdata.Command) { 11227 /* 11228 * IO access is not supported. 11229 */ 11230 case REG_IO_READ: 11231 case REG_IO_WRITE: 11232 mptsas_log(mpt, CE_WARN, "IO access is not " 11233 "supported. Use memory access."); 11234 status = EINVAL; 11235 break; 11236 11237 case REG_MEM_READ: 11238 driverdata.RegData = ddi_get32(mpt->m_datap, 11239 (uint32_t *)(void *)mpt->m_reg + 11240 driverdata.RegOffset); 11241 if (ddi_copyout(&driverdata.RegData, 11242 &data->RegData, 11243 sizeof (driverdata.RegData), mode) != 0) { 11244 mptsas_log(mpt, CE_WARN, "Register " 11245 "Read Failed"); 11246 status = EFAULT; 11247 } 11248 break; 11249 11250 case REG_MEM_WRITE: 11251 ddi_put32(mpt->m_datap, 11252 (uint32_t *)(void *)mpt->m_reg + 11253 driverdata.RegOffset, 11254 driverdata.RegData); 11255 break; 11256 11257 default: 11258 status = EINVAL; 11259 break; 11260 } 11261 } else { 11262 status = EFAULT; 11263 } 11264 11265 mutex_exit(&mpt->m_mutex); 11266 return (status); 11267 } 11268 11269 static int 11270 mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp, 11271 int *rval) 11272 { 11273 int status = 0; 11274 mptsas_t *mpt; 11275 mptsas_update_flash_t flashdata; 11276 mptsas_pass_thru_t passthru_data; 11277 mptsas_adapter_data_t adapter_data; 11278 mptsas_pci_info_t pci_info; 11279 int copylen; 11280 11281 int iport_flag = 0; 11282 dev_info_t *dip = NULL; 11283 mptsas_phymask_t phymask = 0; 11284 struct devctl_iocdata *dcp = NULL; 11285 uint32_t slotstatus = 0; 11286 char *addr = NULL; 11287 mptsas_target_t *ptgt = NULL; 11288 11289 *rval = MPTIOCTL_STATUS_GOOD; 11290 if (secpolicy_sys_config(credp, B_FALSE) != 0) { 11291 return (EPERM); 11292 } 11293 11294 mpt = ddi_get_soft_state(mptsas_state, MINOR2INST(getminor(dev))); 11295 if (mpt == NULL) { 11296 /* 11297 * Called from iport node, get the states 11298 */ 11299 iport_flag = 1; 11300 dip = mptsas_get_dip_from_dev(dev, &phymask); 11301 if (dip == NULL) { 11302 return (ENXIO); 11303 } 11304 mpt = DIP2MPT(dip); 11305 } 11306 /* Make sure power level is D0 before accessing registers */ 11307 mutex_enter(&mpt->m_mutex); 11308 if (mpt->m_options & MPTSAS_OPT_PM) { 11309 (void) pm_busy_component(mpt->m_dip, 0); 11310 if (mpt->m_power_level != PM_LEVEL_D0) { 11311 mutex_exit(&mpt->m_mutex); 11312 if (pm_raise_power(mpt->m_dip, 0, PM_LEVEL_D0) != 11313 DDI_SUCCESS) { 11314 mptsas_log(mpt, CE_WARN, 11315 "mptsas%d: mptsas_ioctl: Raise power " 11316 "request failed.", mpt->m_instance); 11317 (void) pm_idle_component(mpt->m_dip, 0); 11318 return (ENXIO); 11319 } 11320 } else { 11321 mutex_exit(&mpt->m_mutex); 11322 } 11323 } else { 11324 mutex_exit(&mpt->m_mutex); 11325 } 11326 11327 if (iport_flag) { 11328 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, rval); 11329 if (status != 0) { 11330 goto out; 11331 } 11332 /* 11333 * The following code control the OK2RM LED, it doesn't affect 11334 * the ioctl return status. 11335 */ 11336 if ((cmd == DEVCTL_DEVICE_ONLINE) || 11337 (cmd == DEVCTL_DEVICE_OFFLINE)) { 11338 if (ndi_dc_allochdl((void *)data, &dcp) != 11339 NDI_SUCCESS) { 11340 goto out; 11341 } 11342 addr = ndi_dc_getaddr(dcp); 11343 ptgt = mptsas_addr_to_ptgt(mpt, addr, phymask); 11344 if (ptgt == NULL) { 11345 NDBG14(("mptsas_ioctl led control: tgt %s not " 11346 "found", addr)); 11347 ndi_dc_freehdl(dcp); 11348 goto out; 11349 } 11350 mutex_enter(&mpt->m_mutex); 11351 if (cmd == DEVCTL_DEVICE_ONLINE) { 11352 ptgt->m_tgt_unconfigured = 0; 11353 } else if (cmd == DEVCTL_DEVICE_OFFLINE) { 11354 ptgt->m_tgt_unconfigured = 1; 11355 } 11356 slotstatus = 0; 11357 #ifdef MPTSAS_GET_LED 11358 /* 11359 * The get led status can't get a valid/reasonable 11360 * state, so ignore the get led status, and write the 11361 * required value directly 11362 */ 11363 if (mptsas_get_led_status(mpt, ptgt, &slotstatus) != 11364 DDI_SUCCESS) { 11365 NDBG14(("mptsas_ioctl: get LED for tgt %s " 11366 "failed %x", addr, slotstatus)); 11367 slotstatus = 0; 11368 } 11369 NDBG14(("mptsas_ioctl: LED status %x for %s", 11370 slotstatus, addr)); 11371 #endif 11372 if (cmd == DEVCTL_DEVICE_OFFLINE) { 11373 slotstatus |= 11374 MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE; 11375 } else { 11376 slotstatus &= 11377 ~MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE; 11378 } 11379 if (mptsas_set_led_status(mpt, ptgt, slotstatus) != 11380 DDI_SUCCESS) { 11381 NDBG14(("mptsas_ioctl: set LED for tgt %s " 11382 "failed %x", addr, slotstatus)); 11383 } 11384 mutex_exit(&mpt->m_mutex); 11385 ndi_dc_freehdl(dcp); 11386 } 11387 goto out; 11388 } 11389 switch (cmd) { 11390 case MPTIOCTL_UPDATE_FLASH: 11391 if (ddi_copyin((void *)data, &flashdata, 11392 sizeof (struct mptsas_update_flash), mode)) { 11393 status = EFAULT; 11394 break; 11395 } 11396 11397 mutex_enter(&mpt->m_mutex); 11398 if (mptsas_update_flash(mpt, 11399 (caddr_t)(long)flashdata.PtrBuffer, 11400 flashdata.ImageSize, flashdata.ImageType, mode)) { 11401 status = EFAULT; 11402 } 11403 11404 /* 11405 * Reset the chip to start using the new 11406 * firmware. Reset if failed also. 11407 */ 11408 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 11409 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) { 11410 status = EFAULT; 11411 } 11412 mutex_exit(&mpt->m_mutex); 11413 break; 11414 case MPTIOCTL_PASS_THRU: 11415 /* 11416 * The user has requested to pass through a command to 11417 * be executed by the MPT firmware. Call our routine 11418 * which does this. Only allow one passthru IOCTL at 11419 * one time. Other threads will block on 11420 * m_passthru_mutex, which is of adaptive variant. 11421 */ 11422 if (ddi_copyin((void *)data, &passthru_data, 11423 sizeof (mptsas_pass_thru_t), mode)) { 11424 status = EFAULT; 11425 break; 11426 } 11427 mutex_enter(&mpt->m_passthru_mutex); 11428 mutex_enter(&mpt->m_mutex); 11429 status = mptsas_pass_thru(mpt, &passthru_data, mode); 11430 mutex_exit(&mpt->m_mutex); 11431 mutex_exit(&mpt->m_passthru_mutex); 11432 11433 break; 11434 case MPTIOCTL_GET_ADAPTER_DATA: 11435 /* 11436 * The user has requested to read adapter data. Call 11437 * our routine which does this. 11438 */ 11439 bzero(&adapter_data, sizeof (mptsas_adapter_data_t)); 11440 if (ddi_copyin((void *)data, (void *)&adapter_data, 11441 sizeof (mptsas_adapter_data_t), mode)) { 11442 status = EFAULT; 11443 break; 11444 } 11445 if (adapter_data.StructureLength >= 11446 sizeof (mptsas_adapter_data_t)) { 11447 adapter_data.StructureLength = (uint32_t) 11448 sizeof (mptsas_adapter_data_t); 11449 copylen = sizeof (mptsas_adapter_data_t); 11450 mutex_enter(&mpt->m_mutex); 11451 mptsas_read_adapter_data(mpt, &adapter_data); 11452 mutex_exit(&mpt->m_mutex); 11453 } else { 11454 adapter_data.StructureLength = (uint32_t) 11455 sizeof (mptsas_adapter_data_t); 11456 copylen = sizeof (adapter_data.StructureLength); 11457 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT; 11458 } 11459 if (ddi_copyout((void *)(&adapter_data), (void *)data, 11460 copylen, mode) != 0) { 11461 status = EFAULT; 11462 } 11463 break; 11464 case MPTIOCTL_GET_PCI_INFO: 11465 /* 11466 * The user has requested to read pci info. Call 11467 * our routine which does this. 11468 */ 11469 bzero(&pci_info, sizeof (mptsas_pci_info_t)); 11470 mutex_enter(&mpt->m_mutex); 11471 mptsas_read_pci_info(mpt, &pci_info); 11472 mutex_exit(&mpt->m_mutex); 11473 if (ddi_copyout((void *)(&pci_info), (void *)data, 11474 sizeof (mptsas_pci_info_t), mode) != 0) { 11475 status = EFAULT; 11476 } 11477 break; 11478 case MPTIOCTL_RESET_ADAPTER: 11479 mutex_enter(&mpt->m_mutex); 11480 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 11481 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 11482 mptsas_log(mpt, CE_WARN, "reset adapter IOCTL " 11483 "failed"); 11484 status = EFAULT; 11485 } 11486 mutex_exit(&mpt->m_mutex); 11487 break; 11488 case MPTIOCTL_DIAG_ACTION: 11489 /* 11490 * The user has done a diag buffer action. Call our 11491 * routine which does this. Only allow one diag action 11492 * at one time. 11493 */ 11494 mutex_enter(&mpt->m_mutex); 11495 if (mpt->m_diag_action_in_progress) { 11496 mutex_exit(&mpt->m_mutex); 11497 return (EBUSY); 11498 } 11499 mpt->m_diag_action_in_progress = 1; 11500 status = mptsas_diag_action(mpt, 11501 (mptsas_diag_action_t *)data, mode); 11502 mpt->m_diag_action_in_progress = 0; 11503 mutex_exit(&mpt->m_mutex); 11504 break; 11505 case MPTIOCTL_EVENT_QUERY: 11506 /* 11507 * The user has done an event query. Call our routine 11508 * which does this. 11509 */ 11510 status = mptsas_event_query(mpt, 11511 (mptsas_event_query_t *)data, mode, rval); 11512 break; 11513 case MPTIOCTL_EVENT_ENABLE: 11514 /* 11515 * The user has done an event enable. Call our routine 11516 * which does this. 11517 */ 11518 status = mptsas_event_enable(mpt, 11519 (mptsas_event_enable_t *)data, mode, rval); 11520 break; 11521 case MPTIOCTL_EVENT_REPORT: 11522 /* 11523 * The user has done an event report. Call our routine 11524 * which does this. 11525 */ 11526 status = mptsas_event_report(mpt, 11527 (mptsas_event_report_t *)data, mode, rval); 11528 break; 11529 case MPTIOCTL_REG_ACCESS: 11530 /* 11531 * The user has requested register access. Call our 11532 * routine which does this. 11533 */ 11534 status = mptsas_reg_access(mpt, 11535 (mptsas_reg_access_t *)data, mode); 11536 break; 11537 default: 11538 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, 11539 rval); 11540 break; 11541 } 11542 11543 out: 11544 return (status); 11545 } 11546 11547 int 11548 mptsas_restart_ioc(mptsas_t *mpt) 11549 { 11550 int rval = DDI_SUCCESS; 11551 mptsas_target_t *ptgt = NULL; 11552 11553 ASSERT(mutex_owned(&mpt->m_mutex)); 11554 11555 /* 11556 * Set a flag telling I/O path that we're processing a reset. This is 11557 * needed because after the reset is complete, the hash table still 11558 * needs to be rebuilt. If I/Os are started before the hash table is 11559 * rebuilt, I/O errors will occur. This flag allows I/Os to be marked 11560 * so that they can be retried. 11561 */ 11562 mpt->m_in_reset = TRUE; 11563 11564 /* 11565 * Set all throttles to HOLD 11566 */ 11567 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 11568 MPTSAS_HASH_FIRST); 11569 while (ptgt != NULL) { 11570 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 11571 11572 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 11573 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 11574 } 11575 11576 /* 11577 * Disable interrupts 11578 */ 11579 MPTSAS_DISABLE_INTR(mpt); 11580 11581 /* 11582 * Abort all commands: outstanding commands, commands in waitq and 11583 * tx_waitq. 11584 */ 11585 mptsas_flush_hba(mpt); 11586 11587 /* 11588 * Reinitialize the chip. 11589 */ 11590 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) { 11591 rval = DDI_FAILURE; 11592 } 11593 11594 /* 11595 * Enable interrupts again 11596 */ 11597 MPTSAS_ENABLE_INTR(mpt); 11598 11599 /* 11600 * If mptsas_init_chip was successful, update the driver data. 11601 */ 11602 if (rval == DDI_SUCCESS) { 11603 mptsas_update_driver_data(mpt); 11604 } 11605 11606 /* 11607 * Reset the throttles 11608 */ 11609 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 11610 MPTSAS_HASH_FIRST); 11611 while (ptgt != NULL) { 11612 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 11613 11614 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 11615 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 11616 } 11617 11618 mptsas_doneq_empty(mpt); 11619 mptsas_restart_hba(mpt); 11620 11621 if (rval != DDI_SUCCESS) { 11622 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 11623 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 11624 } 11625 11626 /* 11627 * Clear the reset flag so that I/Os can continue. 11628 */ 11629 mpt->m_in_reset = FALSE; 11630 11631 return (rval); 11632 } 11633 11634 static int 11635 mptsas_init_chip(mptsas_t *mpt, int first_time) 11636 { 11637 ddi_dma_cookie_t cookie; 11638 uint32_t i; 11639 int rval; 11640 11641 /* 11642 * Check to see if the firmware image is valid 11643 */ 11644 if (ddi_get32(mpt->m_datap, &mpt->m_reg->HostDiagnostic) & 11645 MPI2_DIAG_FLASH_BAD_SIG) { 11646 mptsas_log(mpt, CE_WARN, "mptsas bad flash signature!"); 11647 goto fail; 11648 } 11649 11650 /* 11651 * Reset the chip 11652 */ 11653 rval = mptsas_ioc_reset(mpt, first_time); 11654 if (rval == MPTSAS_RESET_FAIL) { 11655 mptsas_log(mpt, CE_WARN, "hard reset failed!"); 11656 goto fail; 11657 } 11658 11659 if ((rval == MPTSAS_SUCCESS_MUR) && (!first_time)) { 11660 goto mur; 11661 } 11662 /* 11663 * Setup configuration space 11664 */ 11665 if (mptsas_config_space_init(mpt) == FALSE) { 11666 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init " 11667 "failed!"); 11668 goto fail; 11669 } 11670 11671 /* 11672 * IOC facts can change after a diag reset so all buffers that are 11673 * based on these numbers must be de-allocated and re-allocated. Get 11674 * new IOC facts each time chip is initialized. 11675 */ 11676 if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) { 11677 mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed"); 11678 goto fail; 11679 } 11680 11681 if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) { 11682 goto fail; 11683 } 11684 /* 11685 * Allocate request message frames, reply free queue, reply descriptor 11686 * post queue, and reply message frames using latest IOC facts. 11687 */ 11688 if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) { 11689 mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed"); 11690 goto fail; 11691 } 11692 if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) { 11693 mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue failed!"); 11694 goto fail; 11695 } 11696 if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) { 11697 mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue failed!"); 11698 goto fail; 11699 } 11700 if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) { 11701 mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames failed!"); 11702 goto fail; 11703 } 11704 11705 mur: 11706 /* 11707 * Re-Initialize ioc to operational state 11708 */ 11709 if (mptsas_ioc_init(mpt) == DDI_FAILURE) { 11710 mptsas_log(mpt, CE_WARN, "mptsas_ioc_init failed"); 11711 goto fail; 11712 } 11713 11714 mptsas_alloc_reply_args(mpt); 11715 11716 /* 11717 * Initialize reply post index. Reply free index is initialized after 11718 * the next loop. 11719 */ 11720 mpt->m_post_index = 0; 11721 11722 /* 11723 * Initialize the Reply Free Queue with the physical addresses of our 11724 * reply frames. 11725 */ 11726 cookie.dmac_address = mpt->m_reply_frame_dma_addr; 11727 for (i = 0; i < mpt->m_max_replies; i++) { 11728 ddi_put32(mpt->m_acc_free_queue_hdl, 11729 &((uint32_t *)(void *)mpt->m_free_queue)[i], 11730 cookie.dmac_address); 11731 cookie.dmac_address += mpt->m_reply_frame_size; 11732 } 11733 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 11734 DDI_DMA_SYNC_FORDEV); 11735 11736 /* 11737 * Initialize the reply free index to one past the last frame on the 11738 * queue. This will signify that the queue is empty to start with. 11739 */ 11740 mpt->m_free_index = i; 11741 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, i); 11742 11743 /* 11744 * Initialize the reply post queue to 0xFFFFFFFF,0xFFFFFFFF's. 11745 */ 11746 for (i = 0; i < mpt->m_post_queue_depth; i++) { 11747 ddi_put64(mpt->m_acc_post_queue_hdl, 11748 &((uint64_t *)(void *)mpt->m_post_queue)[i], 11749 0xFFFFFFFFFFFFFFFF); 11750 } 11751 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 11752 DDI_DMA_SYNC_FORDEV); 11753 11754 /* 11755 * Enable ports 11756 */ 11757 if (mptsas_ioc_enable_port(mpt) == DDI_FAILURE) { 11758 mptsas_log(mpt, CE_WARN, "mptsas_ioc_enable_port failed"); 11759 goto fail; 11760 } 11761 11762 /* 11763 * enable events 11764 */ 11765 if (mptsas_ioc_enable_event_notification(mpt)) { 11766 goto fail; 11767 } 11768 11769 /* 11770 * We need checks in attach and these. 11771 * chip_init is called in mult. places 11772 */ 11773 11774 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 11775 DDI_SUCCESS) || 11776 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) != 11777 DDI_SUCCESS) || 11778 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) != 11779 DDI_SUCCESS) || 11780 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) != 11781 DDI_SUCCESS) || 11782 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) != 11783 DDI_SUCCESS)) { 11784 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 11785 goto fail; 11786 } 11787 11788 /* Check all acc handles */ 11789 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) || 11790 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 11791 DDI_SUCCESS) || 11792 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) != 11793 DDI_SUCCESS) || 11794 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) != 11795 DDI_SUCCESS) || 11796 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) != 11797 DDI_SUCCESS) || 11798 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) != 11799 DDI_SUCCESS) || 11800 (mptsas_check_acc_handle(mpt->m_config_handle) != 11801 DDI_SUCCESS)) { 11802 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 11803 goto fail; 11804 } 11805 11806 return (DDI_SUCCESS); 11807 11808 fail: 11809 return (DDI_FAILURE); 11810 } 11811 11812 static int 11813 mptsas_get_pci_cap(mptsas_t *mpt) 11814 { 11815 ushort_t caps_ptr, cap, cap_count; 11816 11817 if (mpt->m_config_handle == NULL) 11818 return (FALSE); 11819 /* 11820 * Check if capabilities list is supported and if so, 11821 * get initial capabilities pointer and clear bits 0,1. 11822 */ 11823 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) 11824 & PCI_STAT_CAP) { 11825 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle, 11826 PCI_CONF_CAP_PTR), 4); 11827 } else { 11828 caps_ptr = PCI_CAP_NEXT_PTR_NULL; 11829 } 11830 11831 /* 11832 * Walk capabilities if supported. 11833 */ 11834 for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) { 11835 11836 /* 11837 * Check that we haven't exceeded the maximum number of 11838 * capabilities and that the pointer is in a valid range. 11839 */ 11840 if (++cap_count > 48) { 11841 mptsas_log(mpt, CE_WARN, 11842 "too many device capabilities.\n"); 11843 break; 11844 } 11845 if (caps_ptr < 64) { 11846 mptsas_log(mpt, CE_WARN, 11847 "capabilities pointer 0x%x out of range.\n", 11848 caps_ptr); 11849 break; 11850 } 11851 11852 /* 11853 * Get next capability and check that it is valid. 11854 * For now, we only support power management. 11855 */ 11856 cap = pci_config_get8(mpt->m_config_handle, caps_ptr); 11857 switch (cap) { 11858 case PCI_CAP_ID_PM: 11859 mptsas_log(mpt, CE_NOTE, 11860 "?mptsas%d supports power management.\n", 11861 mpt->m_instance); 11862 mpt->m_options |= MPTSAS_OPT_PM; 11863 11864 /* Save PMCSR offset */ 11865 mpt->m_pmcsr_offset = caps_ptr + PCI_PMCSR; 11866 break; 11867 /* 11868 * The following capabilities are valid. Any others 11869 * will cause a message to be logged. 11870 */ 11871 case PCI_CAP_ID_VPD: 11872 case PCI_CAP_ID_MSI: 11873 case PCI_CAP_ID_PCIX: 11874 case PCI_CAP_ID_PCI_E: 11875 case PCI_CAP_ID_MSI_X: 11876 break; 11877 default: 11878 mptsas_log(mpt, CE_NOTE, 11879 "?mptsas%d unrecognized capability " 11880 "0x%x.\n", mpt->m_instance, cap); 11881 break; 11882 } 11883 11884 /* 11885 * Get next capabilities pointer and clear bits 0,1. 11886 */ 11887 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle, 11888 (caps_ptr + PCI_CAP_NEXT_PTR)), 4); 11889 } 11890 return (TRUE); 11891 } 11892 11893 static int 11894 mptsas_init_pm(mptsas_t *mpt) 11895 { 11896 char pmc_name[16]; 11897 char *pmc[] = { 11898 NULL, 11899 "0=Off (PCI D3 State)", 11900 "3=On (PCI D0 State)", 11901 NULL 11902 }; 11903 uint16_t pmcsr_stat; 11904 11905 if (mptsas_get_pci_cap(mpt) == FALSE) { 11906 return (DDI_FAILURE); 11907 } 11908 /* 11909 * If PCI's capability does not support PM, then don't need 11910 * to registe the pm-components 11911 */ 11912 if (!(mpt->m_options & MPTSAS_OPT_PM)) 11913 return (DDI_SUCCESS); 11914 /* 11915 * If power management is supported by this chip, create 11916 * pm-components property for the power management framework 11917 */ 11918 (void) sprintf(pmc_name, "NAME=mptsas%d", mpt->m_instance); 11919 pmc[0] = pmc_name; 11920 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, mpt->m_dip, 11921 "pm-components", pmc, 3) != DDI_PROP_SUCCESS) { 11922 mpt->m_options &= ~MPTSAS_OPT_PM; 11923 mptsas_log(mpt, CE_WARN, 11924 "mptsas%d: pm-component property creation failed.", 11925 mpt->m_instance); 11926 return (DDI_FAILURE); 11927 } 11928 11929 /* 11930 * Power on device. 11931 */ 11932 (void) pm_busy_component(mpt->m_dip, 0); 11933 pmcsr_stat = pci_config_get16(mpt->m_config_handle, 11934 mpt->m_pmcsr_offset); 11935 if ((pmcsr_stat & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_D0) { 11936 mptsas_log(mpt, CE_WARN, "mptsas%d: Power up the device", 11937 mpt->m_instance); 11938 pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset, 11939 PCI_PMCSR_D0); 11940 } 11941 if (pm_power_has_changed(mpt->m_dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) { 11942 mptsas_log(mpt, CE_WARN, "pm_power_has_changed failed"); 11943 return (DDI_FAILURE); 11944 } 11945 mpt->m_power_level = PM_LEVEL_D0; 11946 /* 11947 * Set pm idle delay. 11948 */ 11949 mpt->m_pm_idle_delay = ddi_prop_get_int(DDI_DEV_T_ANY, 11950 mpt->m_dip, 0, "mptsas-pm-idle-delay", MPTSAS_PM_IDLE_TIMEOUT); 11951 11952 return (DDI_SUCCESS); 11953 } 11954 11955 static int 11956 mptsas_register_intrs(mptsas_t *mpt) 11957 { 11958 dev_info_t *dip; 11959 int intr_types; 11960 11961 dip = mpt->m_dip; 11962 11963 /* Get supported interrupt types */ 11964 if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) { 11965 mptsas_log(mpt, CE_WARN, "ddi_intr_get_supported_types " 11966 "failed\n"); 11967 return (FALSE); 11968 } 11969 11970 NDBG6(("ddi_intr_get_supported_types() returned: 0x%x", intr_types)); 11971 11972 /* 11973 * Try MSI, but fall back to FIXED 11974 */ 11975 if (mptsas_enable_msi && (intr_types & DDI_INTR_TYPE_MSI)) { 11976 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_MSI) == DDI_SUCCESS) { 11977 NDBG0(("Using MSI interrupt type")); 11978 mpt->m_intr_type = DDI_INTR_TYPE_MSI; 11979 return (TRUE); 11980 } 11981 } 11982 if (intr_types & DDI_INTR_TYPE_FIXED) { 11983 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_FIXED) == DDI_SUCCESS) { 11984 NDBG0(("Using FIXED interrupt type")); 11985 mpt->m_intr_type = DDI_INTR_TYPE_FIXED; 11986 return (TRUE); 11987 } else { 11988 NDBG0(("FIXED interrupt registration failed")); 11989 return (FALSE); 11990 } 11991 } 11992 11993 return (FALSE); 11994 } 11995 11996 static void 11997 mptsas_unregister_intrs(mptsas_t *mpt) 11998 { 11999 mptsas_rem_intrs(mpt); 12000 } 12001 12002 /* 12003 * mptsas_add_intrs: 12004 * 12005 * Register FIXED or MSI interrupts. 12006 */ 12007 static int 12008 mptsas_add_intrs(mptsas_t *mpt, int intr_type) 12009 { 12010 dev_info_t *dip = mpt->m_dip; 12011 int avail, actual, count = 0; 12012 int i, flag, ret; 12013 12014 NDBG6(("mptsas_add_intrs:interrupt type 0x%x", intr_type)); 12015 12016 /* Get number of interrupts */ 12017 ret = ddi_intr_get_nintrs(dip, intr_type, &count); 12018 if ((ret != DDI_SUCCESS) || (count <= 0)) { 12019 mptsas_log(mpt, CE_WARN, "ddi_intr_get_nintrs() failed, " 12020 "ret %d count %d\n", ret, count); 12021 12022 return (DDI_FAILURE); 12023 } 12024 12025 /* Get number of available interrupts */ 12026 ret = ddi_intr_get_navail(dip, intr_type, &avail); 12027 if ((ret != DDI_SUCCESS) || (avail == 0)) { 12028 mptsas_log(mpt, CE_WARN, "ddi_intr_get_navail() failed, " 12029 "ret %d avail %d\n", ret, avail); 12030 12031 return (DDI_FAILURE); 12032 } 12033 12034 if (avail < count) { 12035 mptsas_log(mpt, CE_NOTE, "ddi_intr_get_nvail returned %d, " 12036 "navail() returned %d", count, avail); 12037 } 12038 12039 /* Mpt only have one interrupt routine */ 12040 if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) { 12041 count = 1; 12042 } 12043 12044 /* Allocate an array of interrupt handles */ 12045 mpt->m_intr_size = count * sizeof (ddi_intr_handle_t); 12046 mpt->m_htable = kmem_alloc(mpt->m_intr_size, KM_SLEEP); 12047 12048 flag = DDI_INTR_ALLOC_NORMAL; 12049 12050 /* call ddi_intr_alloc() */ 12051 ret = ddi_intr_alloc(dip, mpt->m_htable, intr_type, 0, 12052 count, &actual, flag); 12053 12054 if ((ret != DDI_SUCCESS) || (actual == 0)) { 12055 mptsas_log(mpt, CE_WARN, "ddi_intr_alloc() failed, ret %d\n", 12056 ret); 12057 kmem_free(mpt->m_htable, mpt->m_intr_size); 12058 return (DDI_FAILURE); 12059 } 12060 12061 /* use interrupt count returned or abort? */ 12062 if (actual < count) { 12063 mptsas_log(mpt, CE_NOTE, "Requested: %d, Received: %d\n", 12064 count, actual); 12065 } 12066 12067 mpt->m_intr_cnt = actual; 12068 12069 /* 12070 * Get priority for first msi, assume remaining are all the same 12071 */ 12072 if ((ret = ddi_intr_get_pri(mpt->m_htable[0], 12073 &mpt->m_intr_pri)) != DDI_SUCCESS) { 12074 mptsas_log(mpt, CE_WARN, "ddi_intr_get_pri() failed %d\n", ret); 12075 12076 /* Free already allocated intr */ 12077 for (i = 0; i < actual; i++) { 12078 (void) ddi_intr_free(mpt->m_htable[i]); 12079 } 12080 12081 kmem_free(mpt->m_htable, mpt->m_intr_size); 12082 return (DDI_FAILURE); 12083 } 12084 12085 /* Test for high level mutex */ 12086 if (mpt->m_intr_pri >= ddi_intr_get_hilevel_pri()) { 12087 mptsas_log(mpt, CE_WARN, "mptsas_add_intrs: " 12088 "Hi level interrupt not supported\n"); 12089 12090 /* Free already allocated intr */ 12091 for (i = 0; i < actual; i++) { 12092 (void) ddi_intr_free(mpt->m_htable[i]); 12093 } 12094 12095 kmem_free(mpt->m_htable, mpt->m_intr_size); 12096 return (DDI_FAILURE); 12097 } 12098 12099 /* Call ddi_intr_add_handler() */ 12100 for (i = 0; i < actual; i++) { 12101 if ((ret = ddi_intr_add_handler(mpt->m_htable[i], mptsas_intr, 12102 (caddr_t)mpt, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) { 12103 mptsas_log(mpt, CE_WARN, "ddi_intr_add_handler() " 12104 "failed %d\n", ret); 12105 12106 /* Free already allocated intr */ 12107 for (i = 0; i < actual; i++) { 12108 (void) ddi_intr_free(mpt->m_htable[i]); 12109 } 12110 12111 kmem_free(mpt->m_htable, mpt->m_intr_size); 12112 return (DDI_FAILURE); 12113 } 12114 } 12115 12116 if ((ret = ddi_intr_get_cap(mpt->m_htable[0], &mpt->m_intr_cap)) 12117 != DDI_SUCCESS) { 12118 mptsas_log(mpt, CE_WARN, "ddi_intr_get_cap() failed %d\n", ret); 12119 12120 /* Free already allocated intr */ 12121 for (i = 0; i < actual; i++) { 12122 (void) ddi_intr_free(mpt->m_htable[i]); 12123 } 12124 12125 kmem_free(mpt->m_htable, mpt->m_intr_size); 12126 return (DDI_FAILURE); 12127 } 12128 12129 /* 12130 * Enable interrupts 12131 */ 12132 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) { 12133 /* Call ddi_intr_block_enable() for MSI interrupts */ 12134 (void) ddi_intr_block_enable(mpt->m_htable, mpt->m_intr_cnt); 12135 } else { 12136 /* Call ddi_intr_enable for MSI or FIXED interrupts */ 12137 for (i = 0; i < mpt->m_intr_cnt; i++) { 12138 (void) ddi_intr_enable(mpt->m_htable[i]); 12139 } 12140 } 12141 return (DDI_SUCCESS); 12142 } 12143 12144 /* 12145 * mptsas_rem_intrs: 12146 * 12147 * Unregister FIXED or MSI interrupts 12148 */ 12149 static void 12150 mptsas_rem_intrs(mptsas_t *mpt) 12151 { 12152 int i; 12153 12154 NDBG6(("mptsas_rem_intrs")); 12155 12156 /* Disable all interrupts */ 12157 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) { 12158 /* Call ddi_intr_block_disable() */ 12159 (void) ddi_intr_block_disable(mpt->m_htable, mpt->m_intr_cnt); 12160 } else { 12161 for (i = 0; i < mpt->m_intr_cnt; i++) { 12162 (void) ddi_intr_disable(mpt->m_htable[i]); 12163 } 12164 } 12165 12166 /* Call ddi_intr_remove_handler() */ 12167 for (i = 0; i < mpt->m_intr_cnt; i++) { 12168 (void) ddi_intr_remove_handler(mpt->m_htable[i]); 12169 (void) ddi_intr_free(mpt->m_htable[i]); 12170 } 12171 12172 kmem_free(mpt->m_htable, mpt->m_intr_size); 12173 } 12174 12175 /* 12176 * The IO fault service error handling callback function 12177 */ 12178 /*ARGSUSED*/ 12179 static int 12180 mptsas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data) 12181 { 12182 /* 12183 * as the driver can always deal with an error in any dma or 12184 * access handle, we can just return the fme_status value. 12185 */ 12186 pci_ereport_post(dip, err, NULL); 12187 return (err->fme_status); 12188 } 12189 12190 /* 12191 * mptsas_fm_init - initialize fma capabilities and register with IO 12192 * fault services. 12193 */ 12194 static void 12195 mptsas_fm_init(mptsas_t *mpt) 12196 { 12197 /* 12198 * Need to change iblock to priority for new MSI intr 12199 */ 12200 ddi_iblock_cookie_t fm_ibc; 12201 12202 /* Only register with IO Fault Services if we have some capability */ 12203 if (mpt->m_fm_capabilities) { 12204 /* Adjust access and dma attributes for FMA */ 12205 mpt->m_reg_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC; 12206 mpt->m_msg_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 12207 mpt->m_io_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 12208 12209 /* 12210 * Register capabilities with IO Fault Services. 12211 * mpt->m_fm_capabilities will be updated to indicate 12212 * capabilities actually supported (not requested.) 12213 */ 12214 ddi_fm_init(mpt->m_dip, &mpt->m_fm_capabilities, &fm_ibc); 12215 12216 /* 12217 * Initialize pci ereport capabilities if ereport 12218 * capable (should always be.) 12219 */ 12220 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) || 12221 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 12222 pci_ereport_setup(mpt->m_dip); 12223 } 12224 12225 /* 12226 * Register error callback if error callback capable. 12227 */ 12228 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 12229 ddi_fm_handler_register(mpt->m_dip, 12230 mptsas_fm_error_cb, (void *) mpt); 12231 } 12232 } 12233 } 12234 12235 /* 12236 * mptsas_fm_fini - Releases fma capabilities and un-registers with IO 12237 * fault services. 12238 * 12239 */ 12240 static void 12241 mptsas_fm_fini(mptsas_t *mpt) 12242 { 12243 /* Only unregister FMA capabilities if registered */ 12244 if (mpt->m_fm_capabilities) { 12245 12246 /* 12247 * Un-register error callback if error callback capable. 12248 */ 12249 12250 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 12251 ddi_fm_handler_unregister(mpt->m_dip); 12252 } 12253 12254 /* 12255 * Release any resources allocated by pci_ereport_setup() 12256 */ 12257 12258 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) || 12259 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 12260 pci_ereport_teardown(mpt->m_dip); 12261 } 12262 12263 /* Unregister from IO Fault Services */ 12264 ddi_fm_fini(mpt->m_dip); 12265 12266 /* Adjust access and dma attributes for FMA */ 12267 mpt->m_reg_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC; 12268 mpt->m_msg_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 12269 mpt->m_io_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 12270 12271 } 12272 } 12273 12274 int 12275 mptsas_check_acc_handle(ddi_acc_handle_t handle) 12276 { 12277 ddi_fm_error_t de; 12278 12279 if (handle == NULL) 12280 return (DDI_FAILURE); 12281 ddi_fm_acc_err_get(handle, &de, DDI_FME_VER0); 12282 return (de.fme_status); 12283 } 12284 12285 int 12286 mptsas_check_dma_handle(ddi_dma_handle_t handle) 12287 { 12288 ddi_fm_error_t de; 12289 12290 if (handle == NULL) 12291 return (DDI_FAILURE); 12292 ddi_fm_dma_err_get(handle, &de, DDI_FME_VER0); 12293 return (de.fme_status); 12294 } 12295 12296 void 12297 mptsas_fm_ereport(mptsas_t *mpt, char *detail) 12298 { 12299 uint64_t ena; 12300 char buf[FM_MAX_CLASS]; 12301 12302 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail); 12303 ena = fm_ena_generate(0, FM_ENA_FMT1); 12304 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities)) { 12305 ddi_fm_ereport_post(mpt->m_dip, buf, ena, DDI_NOSLEEP, 12306 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL); 12307 } 12308 } 12309 12310 static int 12311 mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address, 12312 uint16_t *dev_handle, mptsas_target_t **pptgt) 12313 { 12314 int rval; 12315 uint32_t dev_info; 12316 uint64_t sas_wwn; 12317 mptsas_phymask_t phymask; 12318 uint8_t physport, phynum, config, disk; 12319 mptsas_slots_t *slots = mpt->m_active; 12320 uint64_t devicename; 12321 uint16_t pdev_hdl; 12322 mptsas_target_t *tmp_tgt = NULL; 12323 uint16_t bay_num, enclosure; 12324 12325 ASSERT(*pptgt == NULL); 12326 12327 rval = mptsas_get_sas_device_page0(mpt, page_address, dev_handle, 12328 &sas_wwn, &dev_info, &physport, &phynum, &pdev_hdl, 12329 &bay_num, &enclosure); 12330 if (rval != DDI_SUCCESS) { 12331 rval = DEV_INFO_FAIL_PAGE0; 12332 return (rval); 12333 } 12334 12335 if ((dev_info & (MPI2_SAS_DEVICE_INFO_SSP_TARGET | 12336 MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 12337 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) == NULL) { 12338 rval = DEV_INFO_WRONG_DEVICE_TYPE; 12339 return (rval); 12340 } 12341 12342 /* 12343 * Check if the dev handle is for a Phys Disk. If so, set return value 12344 * and exit. Don't add Phys Disks to hash. 12345 */ 12346 for (config = 0; config < slots->m_num_raid_configs; config++) { 12347 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) { 12348 if (*dev_handle == slots->m_raidconfig[config]. 12349 m_physdisk_devhdl[disk]) { 12350 rval = DEV_INFO_PHYS_DISK; 12351 return (rval); 12352 } 12353 } 12354 } 12355 12356 /* 12357 * Get SATA Device Name from SAS device page0 for 12358 * sata device, if device name doesn't exist, set m_sas_wwn to 12359 * 0 for direct attached SATA. For the device behind the expander 12360 * we still can use STP address assigned by expander. 12361 */ 12362 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 12363 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 12364 mutex_exit(&mpt->m_mutex); 12365 /* alloc a tmp_tgt to send the cmd */ 12366 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), 12367 KM_SLEEP); 12368 tmp_tgt->m_devhdl = *dev_handle; 12369 tmp_tgt->m_deviceinfo = dev_info; 12370 tmp_tgt->m_qfull_retries = QFULL_RETRIES; 12371 tmp_tgt->m_qfull_retry_interval = 12372 drv_usectohz(QFULL_RETRY_INTERVAL * 1000); 12373 tmp_tgt->m_t_throttle = MAX_THROTTLE; 12374 devicename = mptsas_get_sata_guid(mpt, tmp_tgt, 0); 12375 kmem_free(tmp_tgt, sizeof (struct mptsas_target)); 12376 mutex_enter(&mpt->m_mutex); 12377 if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) { 12378 sas_wwn = devicename; 12379 } else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) { 12380 sas_wwn = 0; 12381 } 12382 } 12383 12384 phymask = mptsas_physport_to_phymask(mpt, physport); 12385 *pptgt = mptsas_tgt_alloc(&slots->m_tgttbl, *dev_handle, sas_wwn, 12386 dev_info, phymask, phynum); 12387 if (*pptgt == NULL) { 12388 mptsas_log(mpt, CE_WARN, "Failed to allocated target" 12389 "structure!"); 12390 rval = DEV_INFO_FAIL_ALLOC; 12391 return (rval); 12392 } 12393 (*pptgt)->m_enclosure = enclosure; 12394 (*pptgt)->m_slot_num = bay_num; 12395 return (DEV_INFO_SUCCESS); 12396 } 12397 12398 uint64_t 12399 mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun) 12400 { 12401 uint64_t sata_guid = 0, *pwwn = NULL; 12402 int target = ptgt->m_devhdl; 12403 uchar_t *inq83 = NULL; 12404 int inq83_len = 0xFF; 12405 uchar_t *dblk = NULL; 12406 int inq83_retry = 3; 12407 int rval = DDI_FAILURE; 12408 12409 inq83 = kmem_zalloc(inq83_len, KM_SLEEP); 12410 12411 inq83_retry: 12412 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83, 12413 inq83_len, NULL, 1); 12414 if (rval != DDI_SUCCESS) { 12415 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 12416 "0x83 for target:%x, lun:%x failed!", target, lun); 12417 goto out; 12418 } 12419 /* According to SAT2, the first descriptor is logic unit name */ 12420 dblk = &inq83[4]; 12421 if ((dblk[1] & 0x30) != 0) { 12422 mptsas_log(mpt, CE_WARN, "!Descriptor is not lun associated."); 12423 goto out; 12424 } 12425 pwwn = (uint64_t *)(void *)(&dblk[4]); 12426 if ((dblk[4] & 0xf0) == 0x50) { 12427 sata_guid = BE_64(*pwwn); 12428 goto out; 12429 } else if (dblk[4] == 'A') { 12430 NDBG20(("SATA drive has no NAA format GUID.")); 12431 goto out; 12432 } else { 12433 /* The data is not ready, wait and retry */ 12434 inq83_retry--; 12435 if (inq83_retry <= 0) { 12436 goto out; 12437 } 12438 NDBG20(("The GUID is not ready, retry...")); 12439 delay(1 * drv_usectohz(1000000)); 12440 goto inq83_retry; 12441 } 12442 out: 12443 kmem_free(inq83, inq83_len); 12444 return (sata_guid); 12445 } 12446 12447 static int 12448 mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, uchar_t page, 12449 unsigned char *buf, int len, int *reallen, uchar_t evpd) 12450 { 12451 uchar_t cdb[CDB_GROUP0]; 12452 struct scsi_address ap; 12453 struct buf *data_bp = NULL; 12454 int resid = 0; 12455 int ret = DDI_FAILURE; 12456 12457 ASSERT(len <= 0xffff); 12458 12459 ap.a_target = MPTSAS_INVALID_DEVHDL; 12460 ap.a_lun = (uchar_t)(lun); 12461 ap.a_hba_tran = mpt->m_tran; 12462 12463 data_bp = scsi_alloc_consistent_buf(&ap, 12464 (struct buf *)NULL, len, B_READ, NULL_FUNC, NULL); 12465 if (data_bp == NULL) { 12466 return (ret); 12467 } 12468 bzero(cdb, CDB_GROUP0); 12469 cdb[0] = SCMD_INQUIRY; 12470 cdb[1] = evpd; 12471 cdb[2] = page; 12472 cdb[3] = (len & 0xff00) >> 8; 12473 cdb[4] = (len & 0x00ff); 12474 cdb[5] = 0; 12475 12476 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP0, data_bp, 12477 &resid); 12478 if (ret == DDI_SUCCESS) { 12479 if (reallen) { 12480 *reallen = len - resid; 12481 } 12482 bcopy((caddr_t)data_bp->b_un.b_addr, buf, len); 12483 } 12484 if (data_bp) { 12485 scsi_free_consistent_buf(data_bp); 12486 } 12487 return (ret); 12488 } 12489 12490 static int 12491 mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap, 12492 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp, 12493 int *resid) 12494 { 12495 struct scsi_pkt *pktp = NULL; 12496 scsi_hba_tran_t *tran_clone = NULL; 12497 mptsas_tgt_private_t *tgt_private = NULL; 12498 int ret = DDI_FAILURE; 12499 12500 /* 12501 * scsi_hba_tran_t->tran_tgt_private is used to pass the address 12502 * information to scsi_init_pkt, allocate a scsi_hba_tran structure 12503 * to simulate the cmds from sd 12504 */ 12505 tran_clone = kmem_alloc( 12506 sizeof (scsi_hba_tran_t), KM_SLEEP); 12507 if (tran_clone == NULL) { 12508 goto out; 12509 } 12510 bcopy((caddr_t)mpt->m_tran, 12511 (caddr_t)tran_clone, sizeof (scsi_hba_tran_t)); 12512 tgt_private = kmem_alloc( 12513 sizeof (mptsas_tgt_private_t), KM_SLEEP); 12514 if (tgt_private == NULL) { 12515 goto out; 12516 } 12517 tgt_private->t_lun = ap->a_lun; 12518 tgt_private->t_private = ptgt; 12519 tran_clone->tran_tgt_private = tgt_private; 12520 ap->a_hba_tran = tran_clone; 12521 12522 pktp = scsi_init_pkt(ap, (struct scsi_pkt *)NULL, 12523 data_bp, cdblen, sizeof (struct scsi_arq_status), 12524 0, PKT_CONSISTENT, NULL, NULL); 12525 if (pktp == NULL) { 12526 goto out; 12527 } 12528 bcopy(cdb, pktp->pkt_cdbp, cdblen); 12529 pktp->pkt_flags = FLAG_NOPARITY; 12530 if (scsi_poll(pktp) < 0) { 12531 goto out; 12532 } 12533 if (((struct scsi_status *)pktp->pkt_scbp)->sts_chk) { 12534 goto out; 12535 } 12536 if (resid != NULL) { 12537 *resid = pktp->pkt_resid; 12538 } 12539 12540 ret = DDI_SUCCESS; 12541 out: 12542 if (pktp) { 12543 scsi_destroy_pkt(pktp); 12544 } 12545 if (tran_clone) { 12546 kmem_free(tran_clone, sizeof (scsi_hba_tran_t)); 12547 } 12548 if (tgt_private) { 12549 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t)); 12550 } 12551 return (ret); 12552 } 12553 static int 12554 mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, int *lun) 12555 { 12556 char *cp = NULL; 12557 char *ptr = NULL; 12558 size_t s = 0; 12559 char *wwid_str = NULL; 12560 char *lun_str = NULL; 12561 long lunnum; 12562 long phyid = -1; 12563 int rc = DDI_FAILURE; 12564 12565 ptr = name; 12566 ASSERT(ptr[0] == 'w' || ptr[0] == 'p'); 12567 ptr++; 12568 if ((cp = strchr(ptr, ',')) == NULL) { 12569 return (DDI_FAILURE); 12570 } 12571 12572 wwid_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 12573 s = (uintptr_t)cp - (uintptr_t)ptr; 12574 12575 bcopy(ptr, wwid_str, s); 12576 wwid_str[s] = '\0'; 12577 12578 ptr = ++cp; 12579 12580 if ((cp = strchr(ptr, '\0')) == NULL) { 12581 goto out; 12582 } 12583 lun_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 12584 s = (uintptr_t)cp - (uintptr_t)ptr; 12585 12586 bcopy(ptr, lun_str, s); 12587 lun_str[s] = '\0'; 12588 12589 if (name[0] == 'p') { 12590 rc = ddi_strtol(wwid_str, NULL, 0x10, &phyid); 12591 } else { 12592 rc = scsi_wwnstr_to_wwn(wwid_str, wwid); 12593 } 12594 if (rc != DDI_SUCCESS) 12595 goto out; 12596 12597 if (phyid != -1) { 12598 ASSERT(phyid < MPTSAS_MAX_PHYS); 12599 *phy = (uint8_t)phyid; 12600 } 12601 rc = ddi_strtol(lun_str, NULL, 0x10, &lunnum); 12602 if (rc != 0) 12603 goto out; 12604 12605 *lun = (int)lunnum; 12606 rc = DDI_SUCCESS; 12607 out: 12608 if (wwid_str) 12609 kmem_free(wwid_str, SCSI_MAXNAMELEN); 12610 if (lun_str) 12611 kmem_free(lun_str, SCSI_MAXNAMELEN); 12612 12613 return (rc); 12614 } 12615 12616 /* 12617 * mptsas_parse_smp_name() is to parse sas wwn string 12618 * which format is "wWWN" 12619 */ 12620 static int 12621 mptsas_parse_smp_name(char *name, uint64_t *wwn) 12622 { 12623 char *ptr = name; 12624 12625 if (*ptr != 'w') { 12626 return (DDI_FAILURE); 12627 } 12628 12629 ptr++; 12630 if (scsi_wwnstr_to_wwn(ptr, wwn)) { 12631 return (DDI_FAILURE); 12632 } 12633 return (DDI_SUCCESS); 12634 } 12635 12636 static int 12637 mptsas_bus_config(dev_info_t *pdip, uint_t flag, 12638 ddi_bus_config_op_t op, void *arg, dev_info_t **childp) 12639 { 12640 int ret = NDI_FAILURE; 12641 int circ = 0; 12642 int circ1 = 0; 12643 mptsas_t *mpt; 12644 char *ptr = NULL; 12645 char *devnm = NULL; 12646 uint64_t wwid = 0; 12647 uint8_t phy = 0xFF; 12648 int lun = 0; 12649 uint_t mflags = flag; 12650 int bconfig = TRUE; 12651 12652 if (scsi_hba_iport_unit_address(pdip) == 0) { 12653 return (DDI_FAILURE); 12654 } 12655 12656 mpt = DIP2MPT(pdip); 12657 if (!mpt) { 12658 return (DDI_FAILURE); 12659 } 12660 /* 12661 * Hold the nexus across the bus_config 12662 */ 12663 ndi_devi_enter(scsi_vhci_dip, &circ); 12664 ndi_devi_enter(pdip, &circ1); 12665 switch (op) { 12666 case BUS_CONFIG_ONE: 12667 /* parse wwid/target name out of name given */ 12668 if ((ptr = strchr((char *)arg, '@')) == NULL) { 12669 ret = NDI_FAILURE; 12670 break; 12671 } 12672 ptr++; 12673 if (strncmp((char *)arg, "smp", 3) == 0) { 12674 /* 12675 * This is a SMP target device 12676 */ 12677 ret = mptsas_parse_smp_name(ptr, &wwid); 12678 if (ret != DDI_SUCCESS) { 12679 ret = NDI_FAILURE; 12680 break; 12681 } 12682 ret = mptsas_config_smp(pdip, wwid, childp); 12683 } else if ((ptr[0] == 'w') || (ptr[0] == 'p')) { 12684 /* 12685 * OBP could pass down a non-canonical form 12686 * bootpath without LUN part when LUN is 0. 12687 * So driver need adjust the string. 12688 */ 12689 if (strchr(ptr, ',') == NULL) { 12690 devnm = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 12691 (void) sprintf(devnm, "%s,0", (char *)arg); 12692 ptr = strchr(devnm, '@'); 12693 ptr++; 12694 } 12695 12696 /* 12697 * The device path is wWWID format and the device 12698 * is not SMP target device. 12699 */ 12700 ret = mptsas_parse_address(ptr, &wwid, &phy, &lun); 12701 if (ret != DDI_SUCCESS) { 12702 ret = NDI_FAILURE; 12703 break; 12704 } 12705 *childp = NULL; 12706 if (ptr[0] == 'w') { 12707 ret = mptsas_config_one_addr(pdip, wwid, 12708 lun, childp); 12709 } else if (ptr[0] == 'p') { 12710 ret = mptsas_config_one_phy(pdip, phy, lun, 12711 childp); 12712 } 12713 12714 /* 12715 * If this is CD/DVD device in OBP path, the 12716 * ndi_busop_bus_config can be skipped as config one 12717 * operation is done above. 12718 */ 12719 if ((ret == NDI_SUCCESS) && (*childp != NULL) && 12720 (strcmp(ddi_node_name(*childp), "cdrom") == 0) && 12721 (strncmp((char *)arg, "disk", 4) == 0)) { 12722 bconfig = FALSE; 12723 ndi_hold_devi(*childp); 12724 } 12725 } else { 12726 ret = NDI_FAILURE; 12727 break; 12728 } 12729 12730 /* 12731 * DDI group instructed us to use this flag. 12732 */ 12733 mflags |= NDI_MDI_FALLBACK; 12734 break; 12735 case BUS_CONFIG_DRIVER: 12736 case BUS_CONFIG_ALL: 12737 mptsas_config_all(pdip); 12738 ret = NDI_SUCCESS; 12739 break; 12740 } 12741 12742 if ((ret == NDI_SUCCESS) && bconfig) { 12743 ret = ndi_busop_bus_config(pdip, mflags, op, 12744 (devnm == NULL) ? arg : devnm, childp, 0); 12745 } 12746 12747 ndi_devi_exit(pdip, circ1); 12748 ndi_devi_exit(scsi_vhci_dip, circ); 12749 if (devnm != NULL) 12750 kmem_free(devnm, SCSI_MAXNAMELEN); 12751 return (ret); 12752 } 12753 12754 static int 12755 mptsas_probe_lun(dev_info_t *pdip, int lun, dev_info_t **dip, 12756 mptsas_target_t *ptgt) 12757 { 12758 int rval = DDI_FAILURE; 12759 struct scsi_inquiry *sd_inq = NULL; 12760 mptsas_t *mpt = DIP2MPT(pdip); 12761 12762 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP); 12763 12764 rval = mptsas_inquiry(mpt, ptgt, lun, 0, (uchar_t *)sd_inq, 12765 SUN_INQSIZE, 0, (uchar_t)0); 12766 12767 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) { 12768 rval = mptsas_create_lun(pdip, sd_inq, dip, ptgt, lun); 12769 } else { 12770 rval = DDI_FAILURE; 12771 } 12772 12773 kmem_free(sd_inq, SUN_INQSIZE); 12774 return (rval); 12775 } 12776 12777 static int 12778 mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun, 12779 dev_info_t **lundip) 12780 { 12781 int rval; 12782 mptsas_t *mpt = DIP2MPT(pdip); 12783 int phymask; 12784 mptsas_target_t *ptgt = NULL; 12785 12786 /* 12787 * Get the physical port associated to the iport 12788 */ 12789 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 12790 "phymask", 0); 12791 12792 ptgt = mptsas_wwid_to_ptgt(mpt, phymask, sasaddr); 12793 if (ptgt == NULL) { 12794 /* 12795 * didn't match any device by searching 12796 */ 12797 return (DDI_FAILURE); 12798 } 12799 /* 12800 * If the LUN already exists and the status is online, 12801 * we just return the pointer to dev_info_t directly. 12802 * For the mdi_pathinfo node, we'll handle it in 12803 * mptsas_create_virt_lun() 12804 * TODO should be also in mptsas_handle_dr 12805 */ 12806 12807 *lundip = mptsas_find_child_addr(pdip, sasaddr, lun); 12808 if (*lundip != NULL) { 12809 /* 12810 * TODO Another senario is, we hotplug the same disk 12811 * on the same slot, the devhdl changed, is this 12812 * possible? 12813 * tgt_private->t_private != ptgt 12814 */ 12815 if (sasaddr != ptgt->m_sas_wwn) { 12816 /* 12817 * The device has changed although the devhdl is the 12818 * same (Enclosure mapping mode, change drive on the 12819 * same slot) 12820 */ 12821 return (DDI_FAILURE); 12822 } 12823 return (DDI_SUCCESS); 12824 } 12825 12826 if (phymask == 0) { 12827 /* 12828 * Configure IR volume 12829 */ 12830 rval = mptsas_config_raid(pdip, ptgt->m_devhdl, lundip); 12831 return (rval); 12832 } 12833 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt); 12834 12835 return (rval); 12836 } 12837 12838 static int 12839 mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun, 12840 dev_info_t **lundip) 12841 { 12842 int rval; 12843 mptsas_t *mpt = DIP2MPT(pdip); 12844 int phymask; 12845 mptsas_target_t *ptgt = NULL; 12846 12847 /* 12848 * Get the physical port associated to the iport 12849 */ 12850 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 12851 "phymask", 0); 12852 12853 ptgt = mptsas_phy_to_tgt(mpt, phymask, phy); 12854 if (ptgt == NULL) { 12855 /* 12856 * didn't match any device by searching 12857 */ 12858 return (DDI_FAILURE); 12859 } 12860 12861 /* 12862 * If the LUN already exists and the status is online, 12863 * we just return the pointer to dev_info_t directly. 12864 * For the mdi_pathinfo node, we'll handle it in 12865 * mptsas_create_virt_lun(). 12866 */ 12867 12868 *lundip = mptsas_find_child_phy(pdip, phy); 12869 if (*lundip != NULL) { 12870 return (DDI_SUCCESS); 12871 } 12872 12873 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt); 12874 12875 return (rval); 12876 } 12877 12878 static int 12879 mptsas_retrieve_lundata(int lun_cnt, uint8_t *buf, uint16_t *lun_num, 12880 uint8_t *lun_addr_type) 12881 { 12882 uint32_t lun_idx = 0; 12883 12884 ASSERT(lun_num != NULL); 12885 ASSERT(lun_addr_type != NULL); 12886 12887 lun_idx = (lun_cnt + 1) * MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE; 12888 /* determine report luns addressing type */ 12889 switch (buf[lun_idx] & MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) { 12890 /* 12891 * Vendors in the field have been found to be concatenating 12892 * bus/target/lun to equal the complete lun value instead 12893 * of switching to flat space addressing 12894 */ 12895 /* 00b - peripheral device addressing method */ 12896 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_PERIPHERAL: 12897 /* FALLTHRU */ 12898 /* 10b - logical unit addressing method */ 12899 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT: 12900 /* FALLTHRU */ 12901 /* 01b - flat space addressing method */ 12902 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE: 12903 /* byte0 bit0-5=msb lun byte1 bit0-7=lsb lun */ 12904 *lun_addr_type = (buf[lun_idx] & 12905 MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) >> 6; 12906 *lun_num = (buf[lun_idx] & 0x3F) << 8; 12907 *lun_num |= buf[lun_idx + 1]; 12908 return (DDI_SUCCESS); 12909 default: 12910 return (DDI_FAILURE); 12911 } 12912 } 12913 12914 static int 12915 mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt) 12916 { 12917 struct buf *repluns_bp = NULL; 12918 struct scsi_address ap; 12919 uchar_t cdb[CDB_GROUP5]; 12920 int ret = DDI_FAILURE; 12921 int retry = 0; 12922 int lun_list_len = 0; 12923 uint16_t lun_num = 0; 12924 uint8_t lun_addr_type = 0; 12925 uint32_t lun_cnt = 0; 12926 uint32_t lun_total = 0; 12927 dev_info_t *cdip = NULL; 12928 uint16_t *saved_repluns = NULL; 12929 char *buffer = NULL; 12930 int buf_len = 128; 12931 mptsas_t *mpt = DIP2MPT(pdip); 12932 uint64_t sas_wwn = 0; 12933 uint8_t phy = 0xFF; 12934 uint32_t dev_info = 0; 12935 12936 mutex_enter(&mpt->m_mutex); 12937 sas_wwn = ptgt->m_sas_wwn; 12938 phy = ptgt->m_phynum; 12939 dev_info = ptgt->m_deviceinfo; 12940 mutex_exit(&mpt->m_mutex); 12941 12942 if (sas_wwn == 0) { 12943 /* 12944 * It's a SATA without Device Name 12945 * So don't try multi-LUNs 12946 */ 12947 if (mptsas_find_child_phy(pdip, phy)) { 12948 return (DDI_SUCCESS); 12949 } else { 12950 /* 12951 * need configure and create node 12952 */ 12953 return (DDI_FAILURE); 12954 } 12955 } 12956 12957 /* 12958 * WWN (SAS address or Device Name exist) 12959 */ 12960 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 12961 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 12962 /* 12963 * SATA device with Device Name 12964 * So don't try multi-LUNs 12965 */ 12966 if (mptsas_find_child_addr(pdip, sas_wwn, 0)) { 12967 return (DDI_SUCCESS); 12968 } else { 12969 return (DDI_FAILURE); 12970 } 12971 } 12972 12973 do { 12974 ap.a_target = MPTSAS_INVALID_DEVHDL; 12975 ap.a_lun = 0; 12976 ap.a_hba_tran = mpt->m_tran; 12977 repluns_bp = scsi_alloc_consistent_buf(&ap, 12978 (struct buf *)NULL, buf_len, B_READ, NULL_FUNC, NULL); 12979 if (repluns_bp == NULL) { 12980 retry++; 12981 continue; 12982 } 12983 bzero(cdb, CDB_GROUP5); 12984 cdb[0] = SCMD_REPORT_LUNS; 12985 cdb[6] = (buf_len & 0xff000000) >> 24; 12986 cdb[7] = (buf_len & 0x00ff0000) >> 16; 12987 cdb[8] = (buf_len & 0x0000ff00) >> 8; 12988 cdb[9] = (buf_len & 0x000000ff); 12989 12990 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP5, 12991 repluns_bp, NULL); 12992 if (ret != DDI_SUCCESS) { 12993 scsi_free_consistent_buf(repluns_bp); 12994 retry++; 12995 continue; 12996 } 12997 lun_list_len = BE_32(*(int *)((void *)( 12998 repluns_bp->b_un.b_addr))); 12999 if (buf_len >= lun_list_len + 8) { 13000 ret = DDI_SUCCESS; 13001 break; 13002 } 13003 scsi_free_consistent_buf(repluns_bp); 13004 buf_len = lun_list_len + 8; 13005 13006 } while (retry < 3); 13007 13008 if (ret != DDI_SUCCESS) 13009 return (ret); 13010 buffer = (char *)repluns_bp->b_un.b_addr; 13011 /* 13012 * find out the number of luns returned by the SCSI ReportLun call 13013 * and allocate buffer space 13014 */ 13015 lun_total = lun_list_len / MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE; 13016 saved_repluns = kmem_zalloc(sizeof (uint16_t) * lun_total, KM_SLEEP); 13017 if (saved_repluns == NULL) { 13018 scsi_free_consistent_buf(repluns_bp); 13019 return (DDI_FAILURE); 13020 } 13021 for (lun_cnt = 0; lun_cnt < lun_total; lun_cnt++) { 13022 if (mptsas_retrieve_lundata(lun_cnt, (uint8_t *)(buffer), 13023 &lun_num, &lun_addr_type) != DDI_SUCCESS) { 13024 continue; 13025 } 13026 saved_repluns[lun_cnt] = lun_num; 13027 if (cdip = mptsas_find_child_addr(pdip, sas_wwn, lun_num)) 13028 ret = DDI_SUCCESS; 13029 else 13030 ret = mptsas_probe_lun(pdip, lun_num, &cdip, 13031 ptgt); 13032 if ((ret == DDI_SUCCESS) && (cdip != NULL)) { 13033 (void) ndi_prop_remove(DDI_DEV_T_NONE, cdip, 13034 MPTSAS_DEV_GONE); 13035 } 13036 } 13037 mptsas_offline_missed_luns(pdip, saved_repluns, lun_total, ptgt); 13038 kmem_free(saved_repluns, sizeof (uint16_t) * lun_total); 13039 scsi_free_consistent_buf(repluns_bp); 13040 return (DDI_SUCCESS); 13041 } 13042 13043 static int 13044 mptsas_config_raid(dev_info_t *pdip, uint16_t target, dev_info_t **dip) 13045 { 13046 int rval = DDI_FAILURE; 13047 struct scsi_inquiry *sd_inq = NULL; 13048 mptsas_t *mpt = DIP2MPT(pdip); 13049 mptsas_target_t *ptgt = NULL; 13050 13051 mutex_enter(&mpt->m_mutex); 13052 ptgt = mptsas_search_by_devhdl(&mpt->m_active->m_tgttbl, target); 13053 mutex_exit(&mpt->m_mutex); 13054 if (ptgt == NULL) { 13055 mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x " 13056 "not found.", target); 13057 return (rval); 13058 } 13059 13060 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP); 13061 rval = mptsas_inquiry(mpt, ptgt, 0, 0, (uchar_t *)sd_inq, 13062 SUN_INQSIZE, 0, (uchar_t)0); 13063 13064 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) { 13065 rval = mptsas_create_phys_lun(pdip, sd_inq, NULL, dip, ptgt, 13066 0); 13067 } else { 13068 rval = DDI_FAILURE; 13069 } 13070 13071 kmem_free(sd_inq, SUN_INQSIZE); 13072 return (rval); 13073 } 13074 13075 /* 13076 * configure all RAID volumes for virtual iport 13077 */ 13078 static void 13079 mptsas_config_all_viport(dev_info_t *pdip) 13080 { 13081 mptsas_t *mpt = DIP2MPT(pdip); 13082 int config, vol; 13083 int target; 13084 dev_info_t *lundip = NULL; 13085 mptsas_slots_t *slots = mpt->m_active; 13086 13087 /* 13088 * Get latest RAID info and search for any Volume DevHandles. If any 13089 * are found, configure the volume. 13090 */ 13091 mutex_enter(&mpt->m_mutex); 13092 for (config = 0; config < slots->m_num_raid_configs; config++) { 13093 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) { 13094 if (slots->m_raidconfig[config].m_raidvol[vol].m_israid 13095 == 1) { 13096 target = slots->m_raidconfig[config]. 13097 m_raidvol[vol].m_raidhandle; 13098 mutex_exit(&mpt->m_mutex); 13099 (void) mptsas_config_raid(pdip, target, 13100 &lundip); 13101 mutex_enter(&mpt->m_mutex); 13102 } 13103 } 13104 } 13105 mutex_exit(&mpt->m_mutex); 13106 } 13107 13108 static void 13109 mptsas_offline_missed_luns(dev_info_t *pdip, uint16_t *repluns, 13110 int lun_cnt, mptsas_target_t *ptgt) 13111 { 13112 dev_info_t *child = NULL, *savechild = NULL; 13113 mdi_pathinfo_t *pip = NULL, *savepip = NULL; 13114 uint64_t sas_wwn, wwid; 13115 uint8_t phy; 13116 int lun; 13117 int i; 13118 int find; 13119 char *addr; 13120 char *nodename; 13121 mptsas_t *mpt = DIP2MPT(pdip); 13122 13123 mutex_enter(&mpt->m_mutex); 13124 wwid = ptgt->m_sas_wwn; 13125 mutex_exit(&mpt->m_mutex); 13126 13127 child = ddi_get_child(pdip); 13128 while (child) { 13129 find = 0; 13130 savechild = child; 13131 child = ddi_get_next_sibling(child); 13132 13133 nodename = ddi_node_name(savechild); 13134 if (strcmp(nodename, "smp") == 0) { 13135 continue; 13136 } 13137 13138 addr = ddi_get_name_addr(savechild); 13139 if (addr == NULL) { 13140 continue; 13141 } 13142 13143 if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) != 13144 DDI_SUCCESS) { 13145 continue; 13146 } 13147 13148 if (wwid == sas_wwn) { 13149 for (i = 0; i < lun_cnt; i++) { 13150 if (repluns[i] == lun) { 13151 find = 1; 13152 break; 13153 } 13154 } 13155 } else { 13156 continue; 13157 } 13158 if (find == 0) { 13159 /* 13160 * The lun has not been there already 13161 */ 13162 (void) mptsas_offline_lun(pdip, savechild, NULL, 13163 NDI_DEVI_REMOVE); 13164 } 13165 } 13166 13167 pip = mdi_get_next_client_path(pdip, NULL); 13168 while (pip) { 13169 find = 0; 13170 savepip = pip; 13171 addr = MDI_PI(pip)->pi_addr; 13172 13173 pip = mdi_get_next_client_path(pdip, pip); 13174 13175 if (addr == NULL) { 13176 continue; 13177 } 13178 13179 if (mptsas_parse_address(addr, &sas_wwn, &phy, 13180 &lun) != DDI_SUCCESS) { 13181 continue; 13182 } 13183 13184 if (sas_wwn == wwid) { 13185 for (i = 0; i < lun_cnt; i++) { 13186 if (repluns[i] == lun) { 13187 find = 1; 13188 break; 13189 } 13190 } 13191 } else { 13192 continue; 13193 } 13194 13195 if (find == 0) { 13196 /* 13197 * The lun has not been there already 13198 */ 13199 (void) mptsas_offline_lun(pdip, NULL, savepip, 13200 NDI_DEVI_REMOVE); 13201 } 13202 } 13203 } 13204 13205 void 13206 mptsas_update_hashtab(struct mptsas *mpt) 13207 { 13208 uint32_t page_address; 13209 int rval = 0; 13210 uint16_t dev_handle; 13211 mptsas_target_t *ptgt = NULL; 13212 mptsas_smp_t smp_node; 13213 13214 /* 13215 * Get latest RAID info. 13216 */ 13217 (void) mptsas_get_raid_info(mpt); 13218 13219 dev_handle = mpt->m_smp_devhdl; 13220 for (; mpt->m_done_traverse_smp == 0; ) { 13221 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL & 13222 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)dev_handle; 13223 if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node) 13224 != DDI_SUCCESS) { 13225 break; 13226 } 13227 mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl; 13228 (void) mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node); 13229 } 13230 13231 /* 13232 * Config target devices 13233 */ 13234 dev_handle = mpt->m_dev_handle; 13235 13236 /* 13237 * Do loop to get sas device page 0 by GetNextHandle till the 13238 * the last handle. If the sas device is a SATA/SSP target, 13239 * we try to config it. 13240 */ 13241 for (; mpt->m_done_traverse_dev == 0; ) { 13242 ptgt = NULL; 13243 page_address = 13244 (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 13245 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 13246 (uint32_t)dev_handle; 13247 rval = mptsas_get_target_device_info(mpt, page_address, 13248 &dev_handle, &ptgt); 13249 if ((rval == DEV_INFO_FAIL_PAGE0) || 13250 (rval == DEV_INFO_FAIL_ALLOC)) { 13251 break; 13252 } 13253 13254 mpt->m_dev_handle = dev_handle; 13255 } 13256 13257 } 13258 13259 void 13260 mptsas_invalid_hashtab(mptsas_hash_table_t *hashtab) 13261 { 13262 mptsas_hash_data_t *data; 13263 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST); 13264 while (data != NULL) { 13265 data->devhdl = MPTSAS_INVALID_DEVHDL; 13266 data->device_info = 0; 13267 /* 13268 * For tgttbl, clear dr_flag. 13269 */ 13270 data->dr_flag = MPTSAS_DR_INACTIVE; 13271 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT); 13272 } 13273 } 13274 13275 void 13276 mptsas_update_driver_data(struct mptsas *mpt) 13277 { 13278 /* 13279 * TODO after hard reset, update the driver data structures 13280 * 1. update port/phymask mapping table mpt->m_phy_info 13281 * 2. invalid all the entries in hash table 13282 * m_devhdl = 0xffff and m_deviceinfo = 0 13283 * 3. call sas_device_page/expander_page to update hash table 13284 */ 13285 mptsas_update_phymask(mpt); 13286 /* 13287 * Invalid the existing entries 13288 */ 13289 mptsas_invalid_hashtab(&mpt->m_active->m_tgttbl); 13290 mptsas_invalid_hashtab(&mpt->m_active->m_smptbl); 13291 mpt->m_done_traverse_dev = 0; 13292 mpt->m_done_traverse_smp = 0; 13293 mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL; 13294 mptsas_update_hashtab(mpt); 13295 } 13296 13297 static void 13298 mptsas_config_all(dev_info_t *pdip) 13299 { 13300 dev_info_t *smpdip = NULL; 13301 mptsas_t *mpt = DIP2MPT(pdip); 13302 int phymask = 0; 13303 mptsas_phymask_t phy_mask; 13304 mptsas_target_t *ptgt = NULL; 13305 mptsas_smp_t *psmp; 13306 13307 /* 13308 * Get the phymask associated to the iport 13309 */ 13310 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 13311 "phymask", 0); 13312 13313 /* 13314 * Enumerate RAID volumes here (phymask == 0). 13315 */ 13316 if (phymask == 0) { 13317 mptsas_config_all_viport(pdip); 13318 return; 13319 } 13320 13321 mutex_enter(&mpt->m_mutex); 13322 13323 if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp) { 13324 mptsas_update_hashtab(mpt); 13325 } 13326 13327 psmp = (mptsas_smp_t *)mptsas_hash_traverse(&mpt->m_active->m_smptbl, 13328 MPTSAS_HASH_FIRST); 13329 while (psmp != NULL) { 13330 phy_mask = psmp->m_phymask; 13331 if (phy_mask == phymask) { 13332 smpdip = NULL; 13333 mutex_exit(&mpt->m_mutex); 13334 (void) mptsas_online_smp(pdip, psmp, &smpdip); 13335 mutex_enter(&mpt->m_mutex); 13336 } 13337 psmp = (mptsas_smp_t *)mptsas_hash_traverse( 13338 &mpt->m_active->m_smptbl, MPTSAS_HASH_NEXT); 13339 } 13340 13341 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 13342 MPTSAS_HASH_FIRST); 13343 while (ptgt != NULL) { 13344 phy_mask = ptgt->m_phymask; 13345 if (phy_mask == phymask) { 13346 mutex_exit(&mpt->m_mutex); 13347 (void) mptsas_config_target(pdip, ptgt); 13348 mutex_enter(&mpt->m_mutex); 13349 } 13350 13351 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 13352 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 13353 } 13354 mutex_exit(&mpt->m_mutex); 13355 } 13356 13357 static int 13358 mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt) 13359 { 13360 int rval = DDI_FAILURE; 13361 dev_info_t *tdip; 13362 13363 rval = mptsas_config_luns(pdip, ptgt); 13364 if (rval != DDI_SUCCESS) { 13365 /* 13366 * The return value means the SCMD_REPORT_LUNS 13367 * did not execute successfully. The target maybe 13368 * doesn't support such command. 13369 */ 13370 rval = mptsas_probe_lun(pdip, 0, &tdip, ptgt); 13371 } 13372 return (rval); 13373 } 13374 13375 /* 13376 * Return fail if not all the childs/paths are freed. 13377 * if there is any path under the HBA, the return value will be always fail 13378 * because we didn't call mdi_pi_free for path 13379 */ 13380 static int 13381 mptsas_offline_target(dev_info_t *pdip, char *name) 13382 { 13383 dev_info_t *child = NULL, *prechild = NULL; 13384 mdi_pathinfo_t *pip = NULL, *savepip = NULL; 13385 int tmp_rval, rval = DDI_SUCCESS; 13386 char *addr, *cp; 13387 size_t s; 13388 mptsas_t *mpt = DIP2MPT(pdip); 13389 13390 child = ddi_get_child(pdip); 13391 while (child) { 13392 addr = ddi_get_name_addr(child); 13393 prechild = child; 13394 child = ddi_get_next_sibling(child); 13395 13396 if (addr == NULL) { 13397 continue; 13398 } 13399 if ((cp = strchr(addr, ',')) == NULL) { 13400 continue; 13401 } 13402 13403 s = (uintptr_t)cp - (uintptr_t)addr; 13404 13405 if (strncmp(addr, name, s) != 0) { 13406 continue; 13407 } 13408 13409 tmp_rval = mptsas_offline_lun(pdip, prechild, NULL, 13410 NDI_DEVI_REMOVE); 13411 if (tmp_rval != DDI_SUCCESS) { 13412 rval = DDI_FAILURE; 13413 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 13414 prechild, MPTSAS_DEV_GONE) != 13415 DDI_PROP_SUCCESS) { 13416 mptsas_log(mpt, CE_WARN, "mptsas driver " 13417 "unable to create property for " 13418 "SAS %s (MPTSAS_DEV_GONE)", addr); 13419 } 13420 } 13421 } 13422 13423 pip = mdi_get_next_client_path(pdip, NULL); 13424 while (pip) { 13425 addr = MDI_PI(pip)->pi_addr; 13426 savepip = pip; 13427 pip = mdi_get_next_client_path(pdip, pip); 13428 if (addr == NULL) { 13429 continue; 13430 } 13431 13432 if ((cp = strchr(addr, ',')) == NULL) { 13433 continue; 13434 } 13435 13436 s = (uintptr_t)cp - (uintptr_t)addr; 13437 13438 if (strncmp(addr, name, s) != 0) { 13439 continue; 13440 } 13441 13442 (void) mptsas_offline_lun(pdip, NULL, savepip, 13443 NDI_DEVI_REMOVE); 13444 /* 13445 * driver will not invoke mdi_pi_free, so path will not 13446 * be freed forever, return DDI_FAILURE. 13447 */ 13448 rval = DDI_FAILURE; 13449 } 13450 return (rval); 13451 } 13452 13453 static int 13454 mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip, 13455 mdi_pathinfo_t *rpip, uint_t flags) 13456 { 13457 int rval = DDI_FAILURE; 13458 char *devname; 13459 dev_info_t *cdip, *parent; 13460 13461 if (rpip != NULL) { 13462 parent = scsi_vhci_dip; 13463 cdip = mdi_pi_get_client(rpip); 13464 } else if (rdip != NULL) { 13465 parent = pdip; 13466 cdip = rdip; 13467 } else { 13468 return (DDI_FAILURE); 13469 } 13470 13471 /* 13472 * Make sure node is attached otherwise 13473 * it won't have related cache nodes to 13474 * clean up. i_ddi_devi_attached is 13475 * similiar to i_ddi_node_state(cdip) >= 13476 * DS_ATTACHED. 13477 */ 13478 if (i_ddi_devi_attached(cdip)) { 13479 13480 /* Get full devname */ 13481 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 13482 (void) ddi_deviname(cdip, devname); 13483 /* Clean cache */ 13484 (void) devfs_clean(parent, devname + 1, 13485 DV_CLEAN_FORCE); 13486 kmem_free(devname, MAXNAMELEN + 1); 13487 } 13488 if (rpip != NULL) { 13489 if (MDI_PI_IS_OFFLINE(rpip)) { 13490 rval = DDI_SUCCESS; 13491 } else { 13492 rval = mdi_pi_offline(rpip, 0); 13493 } 13494 } else { 13495 rval = ndi_devi_offline(cdip, flags); 13496 } 13497 13498 return (rval); 13499 } 13500 13501 static dev_info_t * 13502 mptsas_find_smp_child(dev_info_t *parent, char *str_wwn) 13503 { 13504 dev_info_t *child = NULL; 13505 char *smp_wwn = NULL; 13506 13507 child = ddi_get_child(parent); 13508 while (child) { 13509 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child, 13510 DDI_PROP_DONTPASS, SMP_WWN, &smp_wwn) 13511 != DDI_SUCCESS) { 13512 child = ddi_get_next_sibling(child); 13513 continue; 13514 } 13515 13516 if (strcmp(smp_wwn, str_wwn) == 0) { 13517 ddi_prop_free(smp_wwn); 13518 break; 13519 } 13520 child = ddi_get_next_sibling(child); 13521 ddi_prop_free(smp_wwn); 13522 } 13523 return (child); 13524 } 13525 13526 static int 13527 mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags) 13528 { 13529 int rval = DDI_FAILURE; 13530 char *devname; 13531 char wwn_str[MPTSAS_WWN_STRLEN]; 13532 dev_info_t *cdip; 13533 13534 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr); 13535 13536 cdip = mptsas_find_smp_child(pdip, wwn_str); 13537 13538 if (cdip == NULL) 13539 return (DDI_SUCCESS); 13540 13541 /* 13542 * Make sure node is attached otherwise 13543 * it won't have related cache nodes to 13544 * clean up. i_ddi_devi_attached is 13545 * similiar to i_ddi_node_state(cdip) >= 13546 * DS_ATTACHED. 13547 */ 13548 if (i_ddi_devi_attached(cdip)) { 13549 13550 /* Get full devname */ 13551 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 13552 (void) ddi_deviname(cdip, devname); 13553 /* Clean cache */ 13554 (void) devfs_clean(pdip, devname + 1, 13555 DV_CLEAN_FORCE); 13556 kmem_free(devname, MAXNAMELEN + 1); 13557 } 13558 13559 rval = ndi_devi_offline(cdip, flags); 13560 13561 return (rval); 13562 } 13563 13564 static dev_info_t * 13565 mptsas_find_child(dev_info_t *pdip, char *name) 13566 { 13567 dev_info_t *child = NULL; 13568 char *rname = NULL; 13569 int rval = DDI_FAILURE; 13570 13571 rname = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13572 13573 child = ddi_get_child(pdip); 13574 while (child) { 13575 rval = mptsas_name_child(child, rname, SCSI_MAXNAMELEN); 13576 if (rval != DDI_SUCCESS) { 13577 child = ddi_get_next_sibling(child); 13578 bzero(rname, SCSI_MAXNAMELEN); 13579 continue; 13580 } 13581 13582 if (strcmp(rname, name) == 0) { 13583 break; 13584 } 13585 child = ddi_get_next_sibling(child); 13586 bzero(rname, SCSI_MAXNAMELEN); 13587 } 13588 13589 kmem_free(rname, SCSI_MAXNAMELEN); 13590 13591 return (child); 13592 } 13593 13594 13595 static dev_info_t * 13596 mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, int lun) 13597 { 13598 dev_info_t *child = NULL; 13599 char *name = NULL; 13600 char *addr = NULL; 13601 13602 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13603 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13604 (void) sprintf(name, "%016"PRIx64, sasaddr); 13605 (void) sprintf(addr, "w%s,%x", name, lun); 13606 child = mptsas_find_child(pdip, addr); 13607 kmem_free(name, SCSI_MAXNAMELEN); 13608 kmem_free(addr, SCSI_MAXNAMELEN); 13609 return (child); 13610 } 13611 13612 static dev_info_t * 13613 mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy) 13614 { 13615 dev_info_t *child; 13616 char *addr; 13617 13618 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13619 (void) sprintf(addr, "p%x,0", phy); 13620 child = mptsas_find_child(pdip, addr); 13621 kmem_free(addr, SCSI_MAXNAMELEN); 13622 return (child); 13623 } 13624 13625 static mdi_pathinfo_t * 13626 mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy) 13627 { 13628 mdi_pathinfo_t *path; 13629 char *addr = NULL; 13630 13631 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13632 (void) sprintf(addr, "p%x,0", phy); 13633 path = mdi_pi_find(pdip, NULL, addr); 13634 kmem_free(addr, SCSI_MAXNAMELEN); 13635 return (path); 13636 } 13637 13638 static mdi_pathinfo_t * 13639 mptsas_find_path_addr(dev_info_t *parent, uint64_t sasaddr, int lun) 13640 { 13641 mdi_pathinfo_t *path; 13642 char *name = NULL; 13643 char *addr = NULL; 13644 13645 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13646 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13647 (void) sprintf(name, "%016"PRIx64, sasaddr); 13648 (void) sprintf(addr, "w%s,%x", name, lun); 13649 path = mdi_pi_find(parent, NULL, addr); 13650 kmem_free(name, SCSI_MAXNAMELEN); 13651 kmem_free(addr, SCSI_MAXNAMELEN); 13652 13653 return (path); 13654 } 13655 13656 static int 13657 mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq, 13658 dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun) 13659 { 13660 int i = 0; 13661 uchar_t *inq83 = NULL; 13662 int inq83_len1 = 0xFF; 13663 int inq83_len = 0; 13664 int rval = DDI_FAILURE; 13665 ddi_devid_t devid; 13666 char *guid = NULL; 13667 int target = ptgt->m_devhdl; 13668 mdi_pathinfo_t *pip = NULL; 13669 mptsas_t *mpt = DIP2MPT(pdip); 13670 13671 /* 13672 * For DVD/CD ROM and tape devices and optical 13673 * devices, we won't try to enumerate them under 13674 * scsi_vhci, so no need to try page83 13675 */ 13676 if (sd_inq && (sd_inq->inq_dtype == DTYPE_RODIRECT || 13677 sd_inq->inq_dtype == DTYPE_OPTICAL || 13678 sd_inq->inq_dtype == DTYPE_ESI)) 13679 goto create_lun; 13680 13681 /* 13682 * The LCA returns good SCSI status, but corrupt page 83 data the first 13683 * time it is queried. The solution is to keep trying to request page83 13684 * and verify the GUID is not (DDI_NOT_WELL_FORMED) in 13685 * mptsas_inq83_retry_timeout seconds. If the timeout expires, driver 13686 * give up to get VPD page at this stage and fail the enumeration. 13687 */ 13688 13689 inq83 = kmem_zalloc(inq83_len1, KM_SLEEP); 13690 13691 for (i = 0; i < mptsas_inq83_retry_timeout; i++) { 13692 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83, 13693 inq83_len1, &inq83_len, 1); 13694 if (rval != 0) { 13695 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 13696 "0x83 for target:%x, lun:%x failed!", target, lun); 13697 if (mptsas_physical_bind_failed_page_83 != B_FALSE) 13698 goto create_lun; 13699 goto out; 13700 } 13701 /* 13702 * create DEVID from inquiry data 13703 */ 13704 if ((rval = ddi_devid_scsi_encode( 13705 DEVID_SCSI_ENCODE_VERSION_LATEST, NULL, (uchar_t *)sd_inq, 13706 sizeof (struct scsi_inquiry), NULL, 0, inq83, 13707 (size_t)inq83_len, &devid)) == DDI_SUCCESS) { 13708 /* 13709 * extract GUID from DEVID 13710 */ 13711 guid = ddi_devid_to_guid(devid); 13712 13713 /* 13714 * Do not enable MPXIO if the strlen(guid) is greater 13715 * than MPTSAS_MAX_GUID_LEN, this constrain would be 13716 * handled by framework later. 13717 */ 13718 if (guid && (strlen(guid) > MPTSAS_MAX_GUID_LEN)) { 13719 ddi_devid_free_guid(guid); 13720 guid = NULL; 13721 if (mpt->m_mpxio_enable == TRUE) { 13722 mptsas_log(mpt, CE_NOTE, "!Target:%x, " 13723 "lun:%x doesn't have a valid GUID, " 13724 "multipathing for this drive is " 13725 "not enabled", target, lun); 13726 } 13727 } 13728 13729 /* 13730 * devid no longer needed 13731 */ 13732 ddi_devid_free(devid); 13733 break; 13734 } else if (rval == DDI_NOT_WELL_FORMED) { 13735 /* 13736 * return value of ddi_devid_scsi_encode equal to 13737 * DDI_NOT_WELL_FORMED means DEVID_RETRY, it worth 13738 * to retry inquiry page 0x83 and get GUID. 13739 */ 13740 NDBG20(("Not well formed devid, retry...")); 13741 delay(1 * drv_usectohz(1000000)); 13742 continue; 13743 } else { 13744 mptsas_log(mpt, CE_WARN, "!Encode devid failed for " 13745 "path target:%x, lun:%x", target, lun); 13746 rval = DDI_FAILURE; 13747 goto create_lun; 13748 } 13749 } 13750 13751 if (i == mptsas_inq83_retry_timeout) { 13752 mptsas_log(mpt, CE_WARN, "!Repeated page83 requests timeout " 13753 "for path target:%x, lun:%x", target, lun); 13754 } 13755 13756 rval = DDI_FAILURE; 13757 13758 create_lun: 13759 if ((guid != NULL) && (mpt->m_mpxio_enable == TRUE)) { 13760 rval = mptsas_create_virt_lun(pdip, sd_inq, guid, lun_dip, &pip, 13761 ptgt, lun); 13762 } 13763 if (rval != DDI_SUCCESS) { 13764 rval = mptsas_create_phys_lun(pdip, sd_inq, guid, lun_dip, 13765 ptgt, lun); 13766 13767 } 13768 out: 13769 if (guid != NULL) { 13770 /* 13771 * guid no longer needed 13772 */ 13773 ddi_devid_free_guid(guid); 13774 } 13775 if (inq83 != NULL) 13776 kmem_free(inq83, inq83_len1); 13777 return (rval); 13778 } 13779 13780 static int 13781 mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *inq, char *guid, 13782 dev_info_t **lun_dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, int lun) 13783 { 13784 int target; 13785 char *nodename = NULL; 13786 char **compatible = NULL; 13787 int ncompatible = 0; 13788 int mdi_rtn = MDI_FAILURE; 13789 int rval = DDI_FAILURE; 13790 char *old_guid = NULL; 13791 mptsas_t *mpt = DIP2MPT(pdip); 13792 char *lun_addr = NULL; 13793 char *wwn_str = NULL; 13794 char *attached_wwn_str = NULL; 13795 char *component = NULL; 13796 uint8_t phy = 0xFF; 13797 uint64_t sas_wwn; 13798 int64_t lun64 = 0; 13799 uint32_t devinfo; 13800 uint16_t dev_hdl; 13801 uint16_t pdev_hdl; 13802 uint64_t dev_sas_wwn; 13803 uint64_t pdev_sas_wwn; 13804 uint32_t pdev_info; 13805 uint8_t physport; 13806 uint8_t phy_id; 13807 uint32_t page_address; 13808 uint16_t bay_num, enclosure; 13809 char pdev_wwn_str[MPTSAS_WWN_STRLEN]; 13810 uint32_t dev_info; 13811 13812 mutex_enter(&mpt->m_mutex); 13813 target = ptgt->m_devhdl; 13814 sas_wwn = ptgt->m_sas_wwn; 13815 devinfo = ptgt->m_deviceinfo; 13816 phy = ptgt->m_phynum; 13817 mutex_exit(&mpt->m_mutex); 13818 13819 if (sas_wwn) { 13820 *pip = mptsas_find_path_addr(pdip, sas_wwn, lun); 13821 } else { 13822 *pip = mptsas_find_path_phy(pdip, phy); 13823 } 13824 13825 if (*pip != NULL) { 13826 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip; 13827 ASSERT(*lun_dip != NULL); 13828 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip, 13829 (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM), 13830 MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) { 13831 if (strncmp(guid, old_guid, strlen(guid)) == 0) { 13832 /* 13833 * Same path back online again. 13834 */ 13835 (void) ddi_prop_free(old_guid); 13836 if ((!MDI_PI_IS_ONLINE(*pip)) && 13837 (!MDI_PI_IS_STANDBY(*pip)) && 13838 (ptgt->m_tgt_unconfigured == 0)) { 13839 rval = mdi_pi_online(*pip, 0); 13840 mutex_enter(&mpt->m_mutex); 13841 (void) mptsas_set_led_status(mpt, ptgt, 13842 0); 13843 mutex_exit(&mpt->m_mutex); 13844 } else { 13845 rval = DDI_SUCCESS; 13846 } 13847 if (rval != DDI_SUCCESS) { 13848 mptsas_log(mpt, CE_WARN, "path:target: " 13849 "%x, lun:%x online failed!", target, 13850 lun); 13851 *pip = NULL; 13852 *lun_dip = NULL; 13853 } 13854 return (rval); 13855 } else { 13856 /* 13857 * The GUID of the LUN has changed which maybe 13858 * because customer mapped another volume to the 13859 * same LUN. 13860 */ 13861 mptsas_log(mpt, CE_WARN, "The GUID of the " 13862 "target:%x, lun:%x was changed, maybe " 13863 "because someone mapped another volume " 13864 "to the same LUN", target, lun); 13865 (void) ddi_prop_free(old_guid); 13866 if (!MDI_PI_IS_OFFLINE(*pip)) { 13867 rval = mdi_pi_offline(*pip, 0); 13868 if (rval != MDI_SUCCESS) { 13869 mptsas_log(mpt, CE_WARN, "path:" 13870 "target:%x, lun:%x offline " 13871 "failed!", target, lun); 13872 *pip = NULL; 13873 *lun_dip = NULL; 13874 return (DDI_FAILURE); 13875 } 13876 } 13877 if (mdi_pi_free(*pip, 0) != MDI_SUCCESS) { 13878 mptsas_log(mpt, CE_WARN, "path:target:" 13879 "%x, lun:%x free failed!", target, 13880 lun); 13881 *pip = NULL; 13882 *lun_dip = NULL; 13883 return (DDI_FAILURE); 13884 } 13885 } 13886 } else { 13887 mptsas_log(mpt, CE_WARN, "Can't get client-guid " 13888 "property for path:target:%x, lun:%x", target, lun); 13889 *pip = NULL; 13890 *lun_dip = NULL; 13891 return (DDI_FAILURE); 13892 } 13893 } 13894 scsi_hba_nodename_compatible_get(inq, NULL, 13895 inq->inq_dtype, NULL, &nodename, &compatible, &ncompatible); 13896 13897 /* 13898 * if nodename can't be determined then print a message and skip it 13899 */ 13900 if (nodename == NULL) { 13901 mptsas_log(mpt, CE_WARN, "mptsas driver found no compatible " 13902 "driver for target%d lun %d dtype:0x%02x", target, lun, 13903 inq->inq_dtype); 13904 return (DDI_FAILURE); 13905 } 13906 13907 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP); 13908 /* The property is needed by MPAPI */ 13909 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn); 13910 13911 lun_addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13912 if (guid) { 13913 (void) sprintf(lun_addr, "w%s,%x", wwn_str, lun); 13914 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 13915 } else { 13916 (void) sprintf(lun_addr, "p%x,%x", phy, lun); 13917 (void) sprintf(wwn_str, "p%x", phy); 13918 } 13919 13920 mdi_rtn = mdi_pi_alloc_compatible(pdip, nodename, 13921 guid, lun_addr, compatible, ncompatible, 13922 0, pip); 13923 if (mdi_rtn == MDI_SUCCESS) { 13924 13925 if (mdi_prop_update_string(*pip, MDI_GUID, 13926 guid) != DDI_SUCCESS) { 13927 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 13928 "create prop for target %d lun %d (MDI_GUID)", 13929 target, lun); 13930 mdi_rtn = MDI_FAILURE; 13931 goto virt_create_done; 13932 } 13933 13934 if (mdi_prop_update_int(*pip, LUN_PROP, 13935 lun) != DDI_SUCCESS) { 13936 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 13937 "create prop for target %d lun %d (LUN_PROP)", 13938 target, lun); 13939 mdi_rtn = MDI_FAILURE; 13940 goto virt_create_done; 13941 } 13942 lun64 = (int64_t)lun; 13943 if (mdi_prop_update_int64(*pip, LUN64_PROP, 13944 lun64) != DDI_SUCCESS) { 13945 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 13946 "create prop for target %d (LUN64_PROP)", 13947 target); 13948 mdi_rtn = MDI_FAILURE; 13949 goto virt_create_done; 13950 } 13951 if (mdi_prop_update_string_array(*pip, "compatible", 13952 compatible, ncompatible) != 13953 DDI_PROP_SUCCESS) { 13954 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 13955 "create prop for target %d lun %d (COMPATIBLE)", 13956 target, lun); 13957 mdi_rtn = MDI_FAILURE; 13958 goto virt_create_done; 13959 } 13960 if (sas_wwn && (mdi_prop_update_string(*pip, 13961 SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != DDI_PROP_SUCCESS)) { 13962 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 13963 "create prop for target %d lun %d " 13964 "(target-port)", target, lun); 13965 mdi_rtn = MDI_FAILURE; 13966 goto virt_create_done; 13967 } else if ((sas_wwn == 0) && (mdi_prop_update_int(*pip, 13968 "sata-phy", phy) != DDI_PROP_SUCCESS)) { 13969 /* 13970 * Direct attached SATA device without DeviceName 13971 */ 13972 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 13973 "create prop for SAS target %d lun %d " 13974 "(sata-phy)", target, lun); 13975 mdi_rtn = MDI_FAILURE; 13976 goto virt_create_done; 13977 } 13978 mutex_enter(&mpt->m_mutex); 13979 13980 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 13981 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 13982 (uint32_t)ptgt->m_devhdl; 13983 rval = mptsas_get_sas_device_page0(mpt, page_address, 13984 &dev_hdl, &dev_sas_wwn, &dev_info, &physport, 13985 &phy_id, &pdev_hdl, &bay_num, &enclosure); 13986 if (rval != DDI_SUCCESS) { 13987 mutex_exit(&mpt->m_mutex); 13988 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 13989 "parent device for handle %d", page_address); 13990 mdi_rtn = MDI_FAILURE; 13991 goto virt_create_done; 13992 } 13993 13994 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 13995 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl; 13996 rval = mptsas_get_sas_device_page0(mpt, page_address, 13997 &dev_hdl, &pdev_sas_wwn, &pdev_info, &physport, 13998 &phy_id, &pdev_hdl, &bay_num, &enclosure); 13999 if (rval != DDI_SUCCESS) { 14000 mutex_exit(&mpt->m_mutex); 14001 mptsas_log(mpt, CE_WARN, "mptsas unable to get" 14002 "device info for handle %d", page_address); 14003 mdi_rtn = MDI_FAILURE; 14004 goto virt_create_done; 14005 } 14006 14007 mutex_exit(&mpt->m_mutex); 14008 14009 /* 14010 * If this device direct attached to the controller 14011 * set the attached-port to the base wwid 14012 */ 14013 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 14014 != DEVINFO_DIRECT_ATTACHED) { 14015 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 14016 pdev_sas_wwn); 14017 } else { 14018 /* 14019 * Update the iport's attached-port to guid 14020 */ 14021 if (sas_wwn == 0) { 14022 (void) sprintf(wwn_str, "p%x", phy); 14023 } else { 14024 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 14025 } 14026 if (ddi_prop_update_string(DDI_DEV_T_NONE, 14027 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 14028 DDI_PROP_SUCCESS) { 14029 mptsas_log(mpt, CE_WARN, 14030 "mptsas unable to create " 14031 "property for iport target-port" 14032 " %s (sas_wwn)", 14033 wwn_str); 14034 mdi_rtn = MDI_FAILURE; 14035 goto virt_create_done; 14036 } 14037 14038 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 14039 mpt->un.m_base_wwid); 14040 } 14041 14042 if (mdi_prop_update_string(*pip, 14043 SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) != 14044 DDI_PROP_SUCCESS) { 14045 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14046 "property for iport attached-port %s (sas_wwn)", 14047 attached_wwn_str); 14048 mdi_rtn = MDI_FAILURE; 14049 goto virt_create_done; 14050 } 14051 14052 14053 if (inq->inq_dtype == 0) { 14054 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 14055 /* 14056 * set obp path for pathinfo 14057 */ 14058 (void) snprintf(component, MAXPATHLEN, 14059 "disk@%s", lun_addr); 14060 14061 if (mdi_pi_pathname_obp_set(*pip, component) != 14062 DDI_SUCCESS) { 14063 mptsas_log(mpt, CE_WARN, "mpt_sas driver " 14064 "unable to set obp-path for object %s", 14065 component); 14066 mdi_rtn = MDI_FAILURE; 14067 goto virt_create_done; 14068 } 14069 } 14070 14071 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip; 14072 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 14073 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 14074 if ((ndi_prop_update_int(DDI_DEV_T_NONE, *lun_dip, 14075 "pm-capable", 1)) != 14076 DDI_PROP_SUCCESS) { 14077 mptsas_log(mpt, CE_WARN, "mptsas driver" 14078 "failed to create pm-capable " 14079 "property, target %d", target); 14080 mdi_rtn = MDI_FAILURE; 14081 goto virt_create_done; 14082 } 14083 } 14084 /* 14085 * Create the phy-num property 14086 */ 14087 if (mdi_prop_update_int(*pip, "phy-num", 14088 ptgt->m_phynum) != DDI_SUCCESS) { 14089 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14090 "create phy-num property for target %d lun %d", 14091 target, lun); 14092 mdi_rtn = MDI_FAILURE; 14093 goto virt_create_done; 14094 } 14095 NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr)); 14096 mdi_rtn = mdi_pi_online(*pip, 0); 14097 if (mdi_rtn == MDI_SUCCESS) { 14098 mutex_enter(&mpt->m_mutex); 14099 if (mptsas_set_led_status(mpt, ptgt, 0) != 14100 DDI_SUCCESS) { 14101 NDBG14(("mptsas: clear LED for slot %x " 14102 "failed", ptgt->m_slot_num)); 14103 } 14104 mutex_exit(&mpt->m_mutex); 14105 } 14106 if (mdi_rtn == MDI_NOT_SUPPORTED) { 14107 mdi_rtn = MDI_FAILURE; 14108 } 14109 virt_create_done: 14110 if (*pip && mdi_rtn != MDI_SUCCESS) { 14111 (void) mdi_pi_free(*pip, 0); 14112 *pip = NULL; 14113 *lun_dip = NULL; 14114 } 14115 } 14116 14117 scsi_hba_nodename_compatible_free(nodename, compatible); 14118 if (lun_addr != NULL) { 14119 kmem_free(lun_addr, SCSI_MAXNAMELEN); 14120 } 14121 if (wwn_str != NULL) { 14122 kmem_free(wwn_str, MPTSAS_WWN_STRLEN); 14123 } 14124 if (component != NULL) { 14125 kmem_free(component, MAXPATHLEN); 14126 } 14127 14128 return ((mdi_rtn == MDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 14129 } 14130 14131 static int 14132 mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *inq, 14133 char *guid, dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun) 14134 { 14135 int target; 14136 int rval; 14137 int ndi_rtn = NDI_FAILURE; 14138 uint64_t be_sas_wwn; 14139 char *nodename = NULL; 14140 char **compatible = NULL; 14141 int ncompatible = 0; 14142 int instance = 0; 14143 mptsas_t *mpt = DIP2MPT(pdip); 14144 char *wwn_str = NULL; 14145 char *component = NULL; 14146 char *attached_wwn_str = NULL; 14147 uint8_t phy = 0xFF; 14148 uint64_t sas_wwn; 14149 uint32_t devinfo; 14150 uint16_t dev_hdl; 14151 uint16_t pdev_hdl; 14152 uint64_t pdev_sas_wwn; 14153 uint64_t dev_sas_wwn; 14154 uint32_t pdev_info; 14155 uint8_t physport; 14156 uint8_t phy_id; 14157 uint32_t page_address; 14158 uint16_t bay_num, enclosure; 14159 char pdev_wwn_str[MPTSAS_WWN_STRLEN]; 14160 uint32_t dev_info; 14161 int64_t lun64 = 0; 14162 14163 mutex_enter(&mpt->m_mutex); 14164 target = ptgt->m_devhdl; 14165 sas_wwn = ptgt->m_sas_wwn; 14166 devinfo = ptgt->m_deviceinfo; 14167 phy = ptgt->m_phynum; 14168 mutex_exit(&mpt->m_mutex); 14169 14170 /* 14171 * generate compatible property with binding-set "mpt" 14172 */ 14173 scsi_hba_nodename_compatible_get(inq, NULL, inq->inq_dtype, NULL, 14174 &nodename, &compatible, &ncompatible); 14175 14176 /* 14177 * if nodename can't be determined then print a message and skip it 14178 */ 14179 if (nodename == NULL) { 14180 mptsas_log(mpt, CE_WARN, "mptsas found no compatible driver " 14181 "for target %d lun %d", target, lun); 14182 return (DDI_FAILURE); 14183 } 14184 14185 ndi_rtn = ndi_devi_alloc(pdip, nodename, 14186 DEVI_SID_NODEID, lun_dip); 14187 14188 /* 14189 * if lun alloc success, set props 14190 */ 14191 if (ndi_rtn == NDI_SUCCESS) { 14192 14193 if (ndi_prop_update_int(DDI_DEV_T_NONE, 14194 *lun_dip, LUN_PROP, lun) != 14195 DDI_PROP_SUCCESS) { 14196 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14197 "property for target %d lun %d (LUN_PROP)", 14198 target, lun); 14199 ndi_rtn = NDI_FAILURE; 14200 goto phys_create_done; 14201 } 14202 14203 lun64 = (int64_t)lun; 14204 if (ndi_prop_update_int64(DDI_DEV_T_NONE, 14205 *lun_dip, LUN64_PROP, lun64) != 14206 DDI_PROP_SUCCESS) { 14207 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14208 "property for target %d lun64 %d (LUN64_PROP)", 14209 target, lun); 14210 ndi_rtn = NDI_FAILURE; 14211 goto phys_create_done; 14212 } 14213 if (ndi_prop_update_string_array(DDI_DEV_T_NONE, 14214 *lun_dip, "compatible", compatible, ncompatible) 14215 != DDI_PROP_SUCCESS) { 14216 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14217 "property for target %d lun %d (COMPATIBLE)", 14218 target, lun); 14219 ndi_rtn = NDI_FAILURE; 14220 goto phys_create_done; 14221 } 14222 14223 /* 14224 * We need the SAS WWN for non-multipath devices, so 14225 * we'll use the same property as that multipathing 14226 * devices need to present for MPAPI. If we don't have 14227 * a WWN (e.g. parallel SCSI), don't create the prop. 14228 */ 14229 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP); 14230 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 14231 if (sas_wwn && ndi_prop_update_string(DDI_DEV_T_NONE, 14232 *lun_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) 14233 != DDI_PROP_SUCCESS) { 14234 mptsas_log(mpt, CE_WARN, "mptsas unable to " 14235 "create property for SAS target %d lun %d " 14236 "(target-port)", target, lun); 14237 ndi_rtn = NDI_FAILURE; 14238 goto phys_create_done; 14239 } 14240 14241 be_sas_wwn = BE_64(sas_wwn); 14242 if (sas_wwn && ndi_prop_update_byte_array( 14243 DDI_DEV_T_NONE, *lun_dip, "port-wwn", 14244 (uchar_t *)&be_sas_wwn, 8) != DDI_PROP_SUCCESS) { 14245 mptsas_log(mpt, CE_WARN, "mptsas unable to " 14246 "create property for SAS target %d lun %d " 14247 "(port-wwn)", target, lun); 14248 ndi_rtn = NDI_FAILURE; 14249 goto phys_create_done; 14250 } else if ((sas_wwn == 0) && (ndi_prop_update_int( 14251 DDI_DEV_T_NONE, *lun_dip, "sata-phy", phy) != 14252 DDI_PROP_SUCCESS)) { 14253 /* 14254 * Direct attached SATA device without DeviceName 14255 */ 14256 mptsas_log(mpt, CE_WARN, "mptsas unable to " 14257 "create property for SAS target %d lun %d " 14258 "(sata-phy)", target, lun); 14259 ndi_rtn = NDI_FAILURE; 14260 goto phys_create_done; 14261 } 14262 14263 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 14264 *lun_dip, SAS_PROP) != DDI_PROP_SUCCESS) { 14265 mptsas_log(mpt, CE_WARN, "mptsas unable to" 14266 "create property for SAS target %d lun %d" 14267 " (SAS_PROP)", target, lun); 14268 ndi_rtn = NDI_FAILURE; 14269 goto phys_create_done; 14270 } 14271 if (guid && (ndi_prop_update_string(DDI_DEV_T_NONE, 14272 *lun_dip, NDI_GUID, guid) != DDI_SUCCESS)) { 14273 mptsas_log(mpt, CE_WARN, "mptsas unable " 14274 "to create guid property for target %d " 14275 "lun %d", target, lun); 14276 ndi_rtn = NDI_FAILURE; 14277 goto phys_create_done; 14278 } 14279 14280 /* 14281 * The following code is to set properties for SM-HBA support, 14282 * it doesn't apply to RAID volumes 14283 */ 14284 if (ptgt->m_phymask == 0) 14285 goto phys_raid_lun; 14286 14287 mutex_enter(&mpt->m_mutex); 14288 14289 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14290 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14291 (uint32_t)ptgt->m_devhdl; 14292 rval = mptsas_get_sas_device_page0(mpt, page_address, 14293 &dev_hdl, &dev_sas_wwn, &dev_info, 14294 &physport, &phy_id, &pdev_hdl, 14295 &bay_num, &enclosure); 14296 if (rval != DDI_SUCCESS) { 14297 mutex_exit(&mpt->m_mutex); 14298 mptsas_log(mpt, CE_WARN, "mptsas unable to get" 14299 "parent device for handle %d.", page_address); 14300 ndi_rtn = NDI_FAILURE; 14301 goto phys_create_done; 14302 } 14303 14304 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14305 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl; 14306 rval = mptsas_get_sas_device_page0(mpt, page_address, 14307 &dev_hdl, &pdev_sas_wwn, &pdev_info, 14308 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure); 14309 if (rval != DDI_SUCCESS) { 14310 mutex_exit(&mpt->m_mutex); 14311 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14312 "device for handle %d.", page_address); 14313 ndi_rtn = NDI_FAILURE; 14314 goto phys_create_done; 14315 } 14316 14317 mutex_exit(&mpt->m_mutex); 14318 14319 /* 14320 * If this device direct attached to the controller 14321 * set the attached-port to the base wwid 14322 */ 14323 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 14324 != DEVINFO_DIRECT_ATTACHED) { 14325 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 14326 pdev_sas_wwn); 14327 } else { 14328 /* 14329 * Update the iport's attached-port to guid 14330 */ 14331 if (sas_wwn == 0) { 14332 (void) sprintf(wwn_str, "p%x", phy); 14333 } else { 14334 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 14335 } 14336 if (ddi_prop_update_string(DDI_DEV_T_NONE, 14337 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 14338 DDI_PROP_SUCCESS) { 14339 mptsas_log(mpt, CE_WARN, 14340 "mptsas unable to create " 14341 "property for iport target-port" 14342 " %s (sas_wwn)", 14343 wwn_str); 14344 ndi_rtn = NDI_FAILURE; 14345 goto phys_create_done; 14346 } 14347 14348 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 14349 mpt->un.m_base_wwid); 14350 } 14351 14352 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14353 *lun_dip, SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) != 14354 DDI_PROP_SUCCESS) { 14355 mptsas_log(mpt, CE_WARN, 14356 "mptsas unable to create " 14357 "property for iport attached-port %s (sas_wwn)", 14358 attached_wwn_str); 14359 ndi_rtn = NDI_FAILURE; 14360 goto phys_create_done; 14361 } 14362 14363 if (IS_SATA_DEVICE(dev_info)) { 14364 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14365 *lun_dip, MPTSAS_VARIANT, "sata") != 14366 DDI_PROP_SUCCESS) { 14367 mptsas_log(mpt, CE_WARN, 14368 "mptsas unable to create " 14369 "property for device variant "); 14370 ndi_rtn = NDI_FAILURE; 14371 goto phys_create_done; 14372 } 14373 } 14374 14375 if (IS_ATAPI_DEVICE(dev_info)) { 14376 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14377 *lun_dip, MPTSAS_VARIANT, "atapi") != 14378 DDI_PROP_SUCCESS) { 14379 mptsas_log(mpt, CE_WARN, 14380 "mptsas unable to create " 14381 "property for device variant "); 14382 ndi_rtn = NDI_FAILURE; 14383 goto phys_create_done; 14384 } 14385 } 14386 14387 phys_raid_lun: 14388 /* 14389 * if this is a SAS controller, and the target is a SATA 14390 * drive, set the 'pm-capable' property for sd and if on 14391 * an OPL platform, also check if this is an ATAPI 14392 * device. 14393 */ 14394 instance = ddi_get_instance(mpt->m_dip); 14395 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 14396 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 14397 NDBG2(("mptsas%d: creating pm-capable property, " 14398 "target %d", instance, target)); 14399 14400 if ((ndi_prop_update_int(DDI_DEV_T_NONE, 14401 *lun_dip, "pm-capable", 1)) != 14402 DDI_PROP_SUCCESS) { 14403 mptsas_log(mpt, CE_WARN, "mptsas " 14404 "failed to create pm-capable " 14405 "property, target %d", target); 14406 ndi_rtn = NDI_FAILURE; 14407 goto phys_create_done; 14408 } 14409 14410 } 14411 14412 if ((inq->inq_dtype == 0) || (inq->inq_dtype == 5)) { 14413 /* 14414 * add 'obp-path' properties for devinfo 14415 */ 14416 bzero(wwn_str, sizeof (wwn_str)); 14417 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn); 14418 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 14419 if (guid) { 14420 (void) snprintf(component, MAXPATHLEN, 14421 "disk@w%s,%x", wwn_str, lun); 14422 } else { 14423 (void) snprintf(component, MAXPATHLEN, 14424 "disk@p%x,%x", phy, lun); 14425 } 14426 if (ddi_pathname_obp_set(*lun_dip, component) 14427 != DDI_SUCCESS) { 14428 mptsas_log(mpt, CE_WARN, "mpt_sas driver " 14429 "unable to set obp-path for SAS " 14430 "object %s", component); 14431 ndi_rtn = NDI_FAILURE; 14432 goto phys_create_done; 14433 } 14434 } 14435 /* 14436 * Create the phy-num property for non-raid disk 14437 */ 14438 if (ptgt->m_phymask != 0) { 14439 if (ndi_prop_update_int(DDI_DEV_T_NONE, 14440 *lun_dip, "phy-num", ptgt->m_phynum) != 14441 DDI_PROP_SUCCESS) { 14442 mptsas_log(mpt, CE_WARN, "mptsas driver " 14443 "failed to create phy-num property for " 14444 "target %d", target); 14445 ndi_rtn = NDI_FAILURE; 14446 goto phys_create_done; 14447 } 14448 } 14449 phys_create_done: 14450 /* 14451 * If props were setup ok, online the lun 14452 */ 14453 if (ndi_rtn == NDI_SUCCESS) { 14454 /* 14455 * Try to online the new node 14456 */ 14457 ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH); 14458 } 14459 if (ndi_rtn == NDI_SUCCESS) { 14460 mutex_enter(&mpt->m_mutex); 14461 if (mptsas_set_led_status(mpt, ptgt, 0) != 14462 DDI_SUCCESS) { 14463 NDBG14(("mptsas: clear LED for tgt %x " 14464 "failed", ptgt->m_slot_num)); 14465 } 14466 mutex_exit(&mpt->m_mutex); 14467 } 14468 14469 /* 14470 * If success set rtn flag, else unwire alloc'd lun 14471 */ 14472 if (ndi_rtn != NDI_SUCCESS) { 14473 NDBG12(("mptsas driver unable to online " 14474 "target %d lun %d", target, lun)); 14475 ndi_prop_remove_all(*lun_dip); 14476 (void) ndi_devi_free(*lun_dip); 14477 *lun_dip = NULL; 14478 } 14479 } 14480 14481 scsi_hba_nodename_compatible_free(nodename, compatible); 14482 14483 if (wwn_str != NULL) { 14484 kmem_free(wwn_str, MPTSAS_WWN_STRLEN); 14485 } 14486 if (component != NULL) { 14487 kmem_free(component, MAXPATHLEN); 14488 } 14489 14490 14491 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 14492 } 14493 14494 static int 14495 mptsas_probe_smp(dev_info_t *pdip, uint64_t wwn) 14496 { 14497 mptsas_t *mpt = DIP2MPT(pdip); 14498 struct smp_device smp_sd; 14499 14500 /* XXX An HBA driver should not be allocating an smp_device. */ 14501 bzero(&smp_sd, sizeof (struct smp_device)); 14502 smp_sd.smp_sd_address.smp_a_hba_tran = mpt->m_smptran; 14503 bcopy(&wwn, smp_sd.smp_sd_address.smp_a_wwn, SAS_WWN_BYTE_SIZE); 14504 14505 if (smp_probe(&smp_sd) != DDI_PROBE_SUCCESS) 14506 return (NDI_FAILURE); 14507 return (NDI_SUCCESS); 14508 } 14509 14510 static int 14511 mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, dev_info_t **smp_dip) 14512 { 14513 mptsas_t *mpt = DIP2MPT(pdip); 14514 mptsas_smp_t *psmp = NULL; 14515 int rval; 14516 int phymask; 14517 14518 /* 14519 * Get the physical port associated to the iport 14520 * PHYMASK TODO 14521 */ 14522 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 14523 "phymask", 0); 14524 /* 14525 * Find the smp node in hash table with specified sas address and 14526 * physical port 14527 */ 14528 psmp = mptsas_wwid_to_psmp(mpt, phymask, sas_wwn); 14529 if (psmp == NULL) { 14530 return (DDI_FAILURE); 14531 } 14532 14533 rval = mptsas_online_smp(pdip, psmp, smp_dip); 14534 14535 return (rval); 14536 } 14537 14538 static int 14539 mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 14540 dev_info_t **smp_dip) 14541 { 14542 char wwn_str[MPTSAS_WWN_STRLEN]; 14543 char attached_wwn_str[MPTSAS_WWN_STRLEN]; 14544 int ndi_rtn = NDI_FAILURE; 14545 int rval = 0; 14546 mptsas_smp_t dev_info; 14547 uint32_t page_address; 14548 mptsas_t *mpt = DIP2MPT(pdip); 14549 uint16_t dev_hdl; 14550 uint64_t sas_wwn; 14551 uint64_t smp_sas_wwn; 14552 uint8_t physport; 14553 uint8_t phy_id; 14554 uint16_t pdev_hdl; 14555 uint8_t numphys = 0; 14556 uint16_t i = 0; 14557 char phymask[MPTSAS_MAX_PHYS]; 14558 char *iport = NULL; 14559 mptsas_phymask_t phy_mask = 0; 14560 uint16_t attached_devhdl; 14561 uint16_t bay_num, enclosure; 14562 14563 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr); 14564 14565 /* 14566 * Probe smp device, prevent the node of removed device from being 14567 * configured succesfully 14568 */ 14569 if (mptsas_probe_smp(pdip, smp_node->m_sasaddr) != NDI_SUCCESS) { 14570 return (DDI_FAILURE); 14571 } 14572 14573 if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) { 14574 return (DDI_SUCCESS); 14575 } 14576 14577 ndi_rtn = ndi_devi_alloc(pdip, "smp", DEVI_SID_NODEID, smp_dip); 14578 14579 /* 14580 * if lun alloc success, set props 14581 */ 14582 if (ndi_rtn == NDI_SUCCESS) { 14583 /* 14584 * Set the flavor of the child to be SMP flavored 14585 */ 14586 ndi_flavor_set(*smp_dip, SCSA_FLAVOR_SMP); 14587 14588 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14589 *smp_dip, SMP_WWN, wwn_str) != 14590 DDI_PROP_SUCCESS) { 14591 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14592 "property for smp device %s (sas_wwn)", 14593 wwn_str); 14594 ndi_rtn = NDI_FAILURE; 14595 goto smp_create_done; 14596 } 14597 (void) sprintf(wwn_str, "w%"PRIx64, smp_node->m_sasaddr); 14598 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14599 *smp_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != 14600 DDI_PROP_SUCCESS) { 14601 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14602 "property for iport target-port %s (sas_wwn)", 14603 wwn_str); 14604 ndi_rtn = NDI_FAILURE; 14605 goto smp_create_done; 14606 } 14607 14608 mutex_enter(&mpt->m_mutex); 14609 14610 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL & 14611 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | smp_node->m_devhdl; 14612 rval = mptsas_get_sas_expander_page0(mpt, page_address, 14613 &dev_info); 14614 if (rval != DDI_SUCCESS) { 14615 mutex_exit(&mpt->m_mutex); 14616 mptsas_log(mpt, CE_WARN, 14617 "mptsas unable to get expander " 14618 "parent device info for %x", page_address); 14619 ndi_rtn = NDI_FAILURE; 14620 goto smp_create_done; 14621 } 14622 14623 smp_node->m_pdevhdl = dev_info.m_pdevhdl; 14624 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14625 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14626 (uint32_t)dev_info.m_pdevhdl; 14627 rval = mptsas_get_sas_device_page0(mpt, page_address, 14628 &dev_hdl, &sas_wwn, &smp_node->m_pdevinfo, 14629 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure); 14630 if (rval != DDI_SUCCESS) { 14631 mutex_exit(&mpt->m_mutex); 14632 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 14633 "device info for %x", page_address); 14634 ndi_rtn = NDI_FAILURE; 14635 goto smp_create_done; 14636 } 14637 14638 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14639 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14640 (uint32_t)dev_info.m_devhdl; 14641 rval = mptsas_get_sas_device_page0(mpt, page_address, 14642 &dev_hdl, &smp_sas_wwn, &smp_node->m_deviceinfo, 14643 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure); 14644 if (rval != DDI_SUCCESS) { 14645 mutex_exit(&mpt->m_mutex); 14646 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 14647 "device info for %x", page_address); 14648 ndi_rtn = NDI_FAILURE; 14649 goto smp_create_done; 14650 } 14651 mutex_exit(&mpt->m_mutex); 14652 14653 /* 14654 * If this smp direct attached to the controller 14655 * set the attached-port to the base wwid 14656 */ 14657 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 14658 != DEVINFO_DIRECT_ATTACHED) { 14659 (void) sprintf(attached_wwn_str, "w%016"PRIx64, 14660 sas_wwn); 14661 } else { 14662 (void) sprintf(attached_wwn_str, "w%016"PRIx64, 14663 mpt->un.m_base_wwid); 14664 } 14665 14666 if (ndi_prop_update_string(DDI_DEV_T_NONE, 14667 *smp_dip, SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwn_str) != 14668 DDI_PROP_SUCCESS) { 14669 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14670 "property for smp attached-port %s (sas_wwn)", 14671 attached_wwn_str); 14672 ndi_rtn = NDI_FAILURE; 14673 goto smp_create_done; 14674 } 14675 14676 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 14677 *smp_dip, SMP_PROP) != DDI_PROP_SUCCESS) { 14678 mptsas_log(mpt, CE_WARN, "mptsas unable to " 14679 "create property for SMP %s (SMP_PROP) ", 14680 wwn_str); 14681 ndi_rtn = NDI_FAILURE; 14682 goto smp_create_done; 14683 } 14684 14685 /* 14686 * check the smp to see whether it direct 14687 * attached to the controller 14688 */ 14689 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 14690 != DEVINFO_DIRECT_ATTACHED) { 14691 goto smp_create_done; 14692 } 14693 numphys = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 14694 DDI_PROP_DONTPASS, MPTSAS_NUM_PHYS, -1); 14695 if (numphys > 0) { 14696 goto smp_create_done; 14697 } 14698 /* 14699 * this iport is an old iport, we need to 14700 * reconfig the props for it. 14701 */ 14702 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip, 14703 MPTSAS_VIRTUAL_PORT, 0) != 14704 DDI_PROP_SUCCESS) { 14705 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 14706 MPTSAS_VIRTUAL_PORT); 14707 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 14708 "prop update failed"); 14709 goto smp_create_done; 14710 } 14711 14712 mutex_enter(&mpt->m_mutex); 14713 numphys = 0; 14714 iport = ddi_get_name_addr(pdip); 14715 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 14716 bzero(phymask, sizeof (phymask)); 14717 (void) sprintf(phymask, 14718 "%x", mpt->m_phy_info[i].phy_mask); 14719 if (strcmp(phymask, iport) == 0) { 14720 phy_mask = mpt->m_phy_info[i].phy_mask; 14721 break; 14722 } 14723 } 14724 14725 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 14726 if ((phy_mask >> i) & 0x01) { 14727 numphys++; 14728 } 14729 } 14730 /* 14731 * Update PHY info for smhba 14732 */ 14733 if (mptsas_smhba_phy_init(mpt)) { 14734 mutex_exit(&mpt->m_mutex); 14735 mptsas_log(mpt, CE_WARN, "mptsas phy update " 14736 "failed"); 14737 goto smp_create_done; 14738 } 14739 mutex_exit(&mpt->m_mutex); 14740 14741 mptsas_smhba_set_phy_props(mpt, iport, pdip, 14742 numphys, &attached_devhdl); 14743 14744 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip, 14745 MPTSAS_NUM_PHYS, numphys) != 14746 DDI_PROP_SUCCESS) { 14747 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 14748 MPTSAS_NUM_PHYS); 14749 mptsas_log(mpt, CE_WARN, "mptsas update " 14750 "num phys props failed"); 14751 goto smp_create_done; 14752 } 14753 /* 14754 * Add parent's props for SMHBA support 14755 */ 14756 if (ddi_prop_update_string(DDI_DEV_T_NONE, pdip, 14757 SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 14758 DDI_PROP_SUCCESS) { 14759 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 14760 SCSI_ADDR_PROP_ATTACHED_PORT); 14761 mptsas_log(mpt, CE_WARN, "mptsas update iport" 14762 "attached-port failed"); 14763 goto smp_create_done; 14764 } 14765 14766 smp_create_done: 14767 /* 14768 * If props were setup ok, online the lun 14769 */ 14770 if (ndi_rtn == NDI_SUCCESS) { 14771 /* 14772 * Try to online the new node 14773 */ 14774 ndi_rtn = ndi_devi_online(*smp_dip, NDI_ONLINE_ATTACH); 14775 } 14776 14777 /* 14778 * If success set rtn flag, else unwire alloc'd lun 14779 */ 14780 if (ndi_rtn != NDI_SUCCESS) { 14781 NDBG12(("mptsas unable to online " 14782 "SMP target %s", wwn_str)); 14783 ndi_prop_remove_all(*smp_dip); 14784 (void) ndi_devi_free(*smp_dip); 14785 } 14786 } 14787 14788 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 14789 } 14790 14791 /* smp transport routine */ 14792 static int mptsas_smp_start(struct smp_pkt *smp_pkt) 14793 { 14794 uint64_t wwn; 14795 Mpi2SmpPassthroughRequest_t req; 14796 Mpi2SmpPassthroughReply_t rep; 14797 uint32_t direction = 0; 14798 mptsas_t *mpt; 14799 int ret; 14800 uint64_t tmp64; 14801 14802 mpt = (mptsas_t *)smp_pkt->smp_pkt_address-> 14803 smp_a_hba_tran->smp_tran_hba_private; 14804 14805 bcopy(smp_pkt->smp_pkt_address->smp_a_wwn, &wwn, SAS_WWN_BYTE_SIZE); 14806 /* 14807 * Need to compose a SMP request message 14808 * and call mptsas_do_passthru() function 14809 */ 14810 bzero(&req, sizeof (req)); 14811 bzero(&rep, sizeof (rep)); 14812 req.PassthroughFlags = 0; 14813 req.PhysicalPort = 0xff; 14814 req.ChainOffset = 0; 14815 req.Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 14816 14817 if ((smp_pkt->smp_pkt_reqsize & 0xffff0000ul) != 0) { 14818 smp_pkt->smp_pkt_reason = ERANGE; 14819 return (DDI_FAILURE); 14820 } 14821 req.RequestDataLength = LE_16((uint16_t)(smp_pkt->smp_pkt_reqsize - 4)); 14822 14823 req.MsgFlags = 0; 14824 tmp64 = LE_64(wwn); 14825 bcopy(&tmp64, &req.SASAddress, SAS_WWN_BYTE_SIZE); 14826 if (smp_pkt->smp_pkt_rspsize > 0) { 14827 direction |= MPTSAS_PASS_THRU_DIRECTION_READ; 14828 } 14829 if (smp_pkt->smp_pkt_reqsize > 0) { 14830 direction |= MPTSAS_PASS_THRU_DIRECTION_WRITE; 14831 } 14832 14833 mutex_enter(&mpt->m_mutex); 14834 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, 14835 (uint8_t *)smp_pkt->smp_pkt_rsp, 14836 offsetof(Mpi2SmpPassthroughRequest_t, SGL), sizeof (rep), 14837 smp_pkt->smp_pkt_rspsize - 4, direction, 14838 (uint8_t *)smp_pkt->smp_pkt_req, smp_pkt->smp_pkt_reqsize - 4, 14839 smp_pkt->smp_pkt_timeout, FKIOCTL); 14840 mutex_exit(&mpt->m_mutex); 14841 if (ret != 0) { 14842 cmn_err(CE_WARN, "smp_start do passthru error %d", ret); 14843 smp_pkt->smp_pkt_reason = (uchar_t)(ret); 14844 return (DDI_FAILURE); 14845 } 14846 /* do passthrough success, check the smp status */ 14847 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 14848 switch (LE_16(rep.IOCStatus)) { 14849 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 14850 smp_pkt->smp_pkt_reason = ENODEV; 14851 break; 14852 case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN: 14853 smp_pkt->smp_pkt_reason = EOVERFLOW; 14854 break; 14855 case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED: 14856 smp_pkt->smp_pkt_reason = EIO; 14857 break; 14858 default: 14859 mptsas_log(mpt, CE_NOTE, "smp_start: get unknown ioc" 14860 "status:%x", LE_16(rep.IOCStatus)); 14861 smp_pkt->smp_pkt_reason = EIO; 14862 break; 14863 } 14864 return (DDI_FAILURE); 14865 } 14866 if (rep.SASStatus != MPI2_SASSTATUS_SUCCESS) { 14867 mptsas_log(mpt, CE_NOTE, "smp_start: get error SAS status:%x", 14868 rep.SASStatus); 14869 smp_pkt->smp_pkt_reason = EIO; 14870 return (DDI_FAILURE); 14871 } 14872 14873 return (DDI_SUCCESS); 14874 } 14875 14876 /* 14877 * If we didn't get a match, we need to get sas page0 for each device, and 14878 * untill we get a match. If failed, return NULL 14879 */ 14880 static mptsas_target_t * 14881 mptsas_phy_to_tgt(mptsas_t *mpt, int phymask, uint8_t phy) 14882 { 14883 int i, j = 0; 14884 int rval = 0; 14885 uint16_t cur_handle; 14886 uint32_t page_address; 14887 mptsas_target_t *ptgt = NULL; 14888 14889 /* 14890 * PHY named device must be direct attached and attaches to 14891 * narrow port, if the iport is not parent of the device which 14892 * we are looking for. 14893 */ 14894 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 14895 if ((1 << i) & phymask) 14896 j++; 14897 } 14898 14899 if (j > 1) 14900 return (NULL); 14901 14902 /* 14903 * Must be a narrow port and single device attached to the narrow port 14904 * So the physical port num of device which is equal to the iport's 14905 * port num is the device what we are looking for. 14906 */ 14907 14908 if (mpt->m_phy_info[phy].phy_mask != phymask) 14909 return (NULL); 14910 14911 mutex_enter(&mpt->m_mutex); 14912 14913 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 14914 MPTSAS_HASH_FIRST); 14915 while (ptgt != NULL) { 14916 if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) { 14917 mutex_exit(&mpt->m_mutex); 14918 return (ptgt); 14919 } 14920 14921 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 14922 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 14923 } 14924 14925 if (mpt->m_done_traverse_dev) { 14926 mutex_exit(&mpt->m_mutex); 14927 return (NULL); 14928 } 14929 14930 /* If didn't get a match, come here */ 14931 cur_handle = mpt->m_dev_handle; 14932 for (; ; ) { 14933 ptgt = NULL; 14934 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 14935 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)cur_handle; 14936 rval = mptsas_get_target_device_info(mpt, page_address, 14937 &cur_handle, &ptgt); 14938 if ((rval == DEV_INFO_FAIL_PAGE0) || 14939 (rval == DEV_INFO_FAIL_ALLOC)) { 14940 break; 14941 } 14942 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) || 14943 (rval == DEV_INFO_PHYS_DISK)) { 14944 continue; 14945 } 14946 mpt->m_dev_handle = cur_handle; 14947 14948 if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) { 14949 break; 14950 } 14951 } 14952 14953 mutex_exit(&mpt->m_mutex); 14954 return (ptgt); 14955 } 14956 14957 /* 14958 * The ptgt->m_sas_wwn contains the wwid for each disk. 14959 * For Raid volumes, we need to check m_raidvol[x].m_raidwwid 14960 * If we didn't get a match, we need to get sas page0 for each device, and 14961 * untill we get a match 14962 * If failed, return NULL 14963 */ 14964 static mptsas_target_t * 14965 mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask, uint64_t wwid) 14966 { 14967 int rval = 0; 14968 uint16_t cur_handle; 14969 uint32_t page_address; 14970 mptsas_target_t *tmp_tgt = NULL; 14971 14972 mutex_enter(&mpt->m_mutex); 14973 tmp_tgt = (struct mptsas_target *)mptsas_hash_search( 14974 &mpt->m_active->m_tgttbl, wwid, phymask); 14975 if (tmp_tgt != NULL) { 14976 mutex_exit(&mpt->m_mutex); 14977 return (tmp_tgt); 14978 } 14979 14980 if (phymask == 0) { 14981 /* 14982 * It's IR volume 14983 */ 14984 rval = mptsas_get_raid_info(mpt); 14985 if (rval) { 14986 tmp_tgt = (struct mptsas_target *)mptsas_hash_search( 14987 &mpt->m_active->m_tgttbl, wwid, phymask); 14988 } 14989 mutex_exit(&mpt->m_mutex); 14990 return (tmp_tgt); 14991 } 14992 14993 if (mpt->m_done_traverse_dev) { 14994 mutex_exit(&mpt->m_mutex); 14995 return (NULL); 14996 } 14997 14998 /* If didn't get a match, come here */ 14999 cur_handle = mpt->m_dev_handle; 15000 for (; ; ) { 15001 tmp_tgt = NULL; 15002 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 15003 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle; 15004 rval = mptsas_get_target_device_info(mpt, page_address, 15005 &cur_handle, &tmp_tgt); 15006 if ((rval == DEV_INFO_FAIL_PAGE0) || 15007 (rval == DEV_INFO_FAIL_ALLOC)) { 15008 tmp_tgt = NULL; 15009 break; 15010 } 15011 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) || 15012 (rval == DEV_INFO_PHYS_DISK)) { 15013 continue; 15014 } 15015 mpt->m_dev_handle = cur_handle; 15016 if ((tmp_tgt->m_sas_wwn) && (tmp_tgt->m_sas_wwn == wwid) && 15017 (tmp_tgt->m_phymask == phymask)) { 15018 break; 15019 } 15020 } 15021 15022 mutex_exit(&mpt->m_mutex); 15023 return (tmp_tgt); 15024 } 15025 15026 static mptsas_smp_t * 15027 mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask, uint64_t wwid) 15028 { 15029 int rval = 0; 15030 uint16_t cur_handle; 15031 uint32_t page_address; 15032 mptsas_smp_t smp_node, *psmp = NULL; 15033 15034 mutex_enter(&mpt->m_mutex); 15035 psmp = (struct mptsas_smp *)mptsas_hash_search(&mpt->m_active->m_smptbl, 15036 wwid, phymask); 15037 if (psmp != NULL) { 15038 mutex_exit(&mpt->m_mutex); 15039 return (psmp); 15040 } 15041 15042 if (mpt->m_done_traverse_smp) { 15043 mutex_exit(&mpt->m_mutex); 15044 return (NULL); 15045 } 15046 15047 /* If didn't get a match, come here */ 15048 cur_handle = mpt->m_smp_devhdl; 15049 for (; ; ) { 15050 psmp = NULL; 15051 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL & 15052 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle; 15053 rval = mptsas_get_sas_expander_page0(mpt, page_address, 15054 &smp_node); 15055 if (rval != DDI_SUCCESS) { 15056 break; 15057 } 15058 mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl; 15059 psmp = mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node); 15060 ASSERT(psmp); 15061 if ((psmp->m_sasaddr) && (psmp->m_sasaddr == wwid) && 15062 (psmp->m_phymask == phymask)) { 15063 break; 15064 } 15065 } 15066 15067 mutex_exit(&mpt->m_mutex); 15068 return (psmp); 15069 } 15070 15071 /* helper functions using hash */ 15072 15073 /* 15074 * Can't have duplicate entries for same devhdl, 15075 * if there are invalid entries, the devhdl should be set to 0xffff 15076 */ 15077 static void * 15078 mptsas_search_by_devhdl(mptsas_hash_table_t *hashtab, uint16_t devhdl) 15079 { 15080 mptsas_hash_data_t *data; 15081 15082 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST); 15083 while (data != NULL) { 15084 if (data->devhdl == devhdl) { 15085 break; 15086 } 15087 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT); 15088 } 15089 return (data); 15090 } 15091 15092 mptsas_target_t * 15093 mptsas_tgt_alloc(mptsas_hash_table_t *hashtab, uint16_t devhdl, uint64_t wwid, 15094 uint32_t devinfo, mptsas_phymask_t phymask, uint8_t phynum) 15095 { 15096 mptsas_target_t *tmp_tgt = NULL; 15097 15098 tmp_tgt = mptsas_hash_search(hashtab, wwid, phymask); 15099 if (tmp_tgt != NULL) { 15100 NDBG20(("Hash item already exist")); 15101 tmp_tgt->m_deviceinfo = devinfo; 15102 tmp_tgt->m_devhdl = devhdl; 15103 return (tmp_tgt); 15104 } 15105 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP); 15106 if (tmp_tgt == NULL) { 15107 cmn_err(CE_WARN, "Fatal, allocated tgt failed"); 15108 return (NULL); 15109 } 15110 tmp_tgt->m_devhdl = devhdl; 15111 tmp_tgt->m_sas_wwn = wwid; 15112 tmp_tgt->m_deviceinfo = devinfo; 15113 tmp_tgt->m_phymask = phymask; 15114 tmp_tgt->m_phynum = phynum; 15115 /* Initialized the tgt structure */ 15116 tmp_tgt->m_qfull_retries = QFULL_RETRIES; 15117 tmp_tgt->m_qfull_retry_interval = 15118 drv_usectohz(QFULL_RETRY_INTERVAL * 1000); 15119 tmp_tgt->m_t_throttle = MAX_THROTTLE; 15120 15121 mptsas_hash_add(hashtab, tmp_tgt); 15122 15123 return (tmp_tgt); 15124 } 15125 15126 static void 15127 mptsas_tgt_free(mptsas_hash_table_t *hashtab, uint64_t wwid, 15128 mptsas_phymask_t phymask) 15129 { 15130 mptsas_target_t *tmp_tgt; 15131 tmp_tgt = mptsas_hash_rem(hashtab, wwid, phymask); 15132 if (tmp_tgt == NULL) { 15133 cmn_err(CE_WARN, "Tgt not found, nothing to free"); 15134 } else { 15135 kmem_free(tmp_tgt, sizeof (struct mptsas_target)); 15136 } 15137 } 15138 15139 /* 15140 * Return the entry in the hash table 15141 */ 15142 static mptsas_smp_t * 15143 mptsas_smp_alloc(mptsas_hash_table_t *hashtab, mptsas_smp_t *data) 15144 { 15145 uint64_t key1 = data->m_sasaddr; 15146 mptsas_phymask_t key2 = data->m_phymask; 15147 mptsas_smp_t *ret_data; 15148 15149 ret_data = mptsas_hash_search(hashtab, key1, key2); 15150 if (ret_data != NULL) { 15151 bcopy(data, ret_data, sizeof (mptsas_smp_t)); 15152 return (ret_data); 15153 } 15154 15155 ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP); 15156 bcopy(data, ret_data, sizeof (mptsas_smp_t)); 15157 mptsas_hash_add(hashtab, ret_data); 15158 return (ret_data); 15159 } 15160 15161 static void 15162 mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid, 15163 mptsas_phymask_t phymask) 15164 { 15165 mptsas_smp_t *tmp_smp; 15166 tmp_smp = mptsas_hash_rem(hashtab, wwid, phymask); 15167 if (tmp_smp == NULL) { 15168 cmn_err(CE_WARN, "Smp element not found, nothing to free"); 15169 } else { 15170 kmem_free(tmp_smp, sizeof (struct mptsas_smp)); 15171 } 15172 } 15173 15174 /* 15175 * Hash operation functions 15176 * key1 is the sas_wwn, key2 is the phymask 15177 */ 15178 static void 15179 mptsas_hash_init(mptsas_hash_table_t *hashtab) 15180 { 15181 if (hashtab == NULL) { 15182 return; 15183 } 15184 bzero(hashtab->head, sizeof (mptsas_hash_node_t) * 15185 MPTSAS_HASH_ARRAY_SIZE); 15186 hashtab->cur = NULL; 15187 hashtab->line = 0; 15188 } 15189 15190 static void 15191 mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen) 15192 { 15193 uint16_t line = 0; 15194 mptsas_hash_node_t *cur = NULL, *last = NULL; 15195 15196 if (hashtab == NULL) { 15197 return; 15198 } 15199 for (line = 0; line < MPTSAS_HASH_ARRAY_SIZE; line++) { 15200 cur = hashtab->head[line]; 15201 while (cur != NULL) { 15202 last = cur; 15203 cur = cur->next; 15204 kmem_free(last->data, datalen); 15205 kmem_free(last, sizeof (mptsas_hash_node_t)); 15206 } 15207 } 15208 } 15209 15210 /* 15211 * You must guarantee the element doesn't exist in the hash table 15212 * before you call mptsas_hash_add() 15213 */ 15214 static void 15215 mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data) 15216 { 15217 uint64_t key1 = ((mptsas_hash_data_t *)data)->key1; 15218 mptsas_phymask_t key2 = ((mptsas_hash_data_t *)data)->key2; 15219 mptsas_hash_node_t **head = NULL; 15220 mptsas_hash_node_t *node = NULL; 15221 15222 if (hashtab == NULL) { 15223 return; 15224 } 15225 ASSERT(mptsas_hash_search(hashtab, key1, key2) == NULL); 15226 node = kmem_zalloc(sizeof (mptsas_hash_node_t), KM_NOSLEEP); 15227 node->data = data; 15228 15229 head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]); 15230 if (*head == NULL) { 15231 *head = node; 15232 } else { 15233 node->next = *head; 15234 *head = node; 15235 } 15236 } 15237 15238 static void * 15239 mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1, 15240 mptsas_phymask_t key2) 15241 { 15242 mptsas_hash_node_t **head = NULL; 15243 mptsas_hash_node_t *last = NULL, *cur = NULL; 15244 mptsas_hash_data_t *data; 15245 if (hashtab == NULL) { 15246 return (NULL); 15247 } 15248 head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]); 15249 cur = *head; 15250 while (cur != NULL) { 15251 data = cur->data; 15252 if ((data->key1 == key1) && (data->key2 == key2)) { 15253 if (last == NULL) { 15254 (*head) = cur->next; 15255 } else { 15256 last->next = cur->next; 15257 } 15258 kmem_free(cur, sizeof (mptsas_hash_node_t)); 15259 return (data); 15260 } else { 15261 last = cur; 15262 cur = cur->next; 15263 } 15264 } 15265 return (NULL); 15266 } 15267 15268 static void * 15269 mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1, 15270 mptsas_phymask_t key2) 15271 { 15272 mptsas_hash_node_t *cur = NULL; 15273 mptsas_hash_data_t *data; 15274 if (hashtab == NULL) { 15275 return (NULL); 15276 } 15277 cur = hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]; 15278 while (cur != NULL) { 15279 data = cur->data; 15280 if ((data->key1 == key1) && (data->key2 == key2)) { 15281 return (data); 15282 } else { 15283 cur = cur->next; 15284 } 15285 } 15286 return (NULL); 15287 } 15288 15289 static void * 15290 mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos) 15291 { 15292 mptsas_hash_node_t *this = NULL; 15293 15294 if (hashtab == NULL) { 15295 return (NULL); 15296 } 15297 15298 if (pos == MPTSAS_HASH_FIRST) { 15299 hashtab->line = 0; 15300 hashtab->cur = NULL; 15301 this = hashtab->head[0]; 15302 } else { 15303 if (hashtab->cur == NULL) { 15304 return (NULL); 15305 } else { 15306 this = hashtab->cur->next; 15307 } 15308 } 15309 15310 while (this == NULL) { 15311 hashtab->line++; 15312 if (hashtab->line >= MPTSAS_HASH_ARRAY_SIZE) { 15313 /* the traverse reaches the end */ 15314 hashtab->cur = NULL; 15315 return (NULL); 15316 } else { 15317 this = hashtab->head[hashtab->line]; 15318 } 15319 } 15320 hashtab->cur = this; 15321 return (this->data); 15322 } 15323 15324 /* 15325 * Functions for SGPIO LED support 15326 */ 15327 static dev_info_t * 15328 mptsas_get_dip_from_dev(dev_t dev, mptsas_phymask_t *phymask) 15329 { 15330 dev_info_t *dip; 15331 int prop; 15332 dip = e_ddi_hold_devi_by_dev(dev, 0); 15333 if (dip == NULL) 15334 return (dip); 15335 prop = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 15336 "phymask", 0); 15337 *phymask = (mptsas_phymask_t)prop; 15338 ddi_release_devi(dip); 15339 return (dip); 15340 } 15341 static mptsas_target_t * 15342 mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask) 15343 { 15344 uint8_t phynum; 15345 uint64_t wwn; 15346 int lun; 15347 mptsas_target_t *ptgt = NULL; 15348 15349 if (mptsas_parse_address(addr, &wwn, &phynum, &lun) != DDI_SUCCESS) { 15350 return (NULL); 15351 } 15352 if (addr[0] == 'w') { 15353 ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn); 15354 } else { 15355 ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum); 15356 } 15357 return (ptgt); 15358 } 15359 15360 #ifdef MPTSAS_GET_LED 15361 static int 15362 mptsas_get_led_status(mptsas_t *mpt, mptsas_target_t *ptgt, 15363 uint32_t *slotstatus) 15364 { 15365 return (mptsas_send_sep(mpt, ptgt, slotstatus, 15366 MPI2_SEP_REQ_ACTION_READ_STATUS)); 15367 } 15368 #endif 15369 static int 15370 mptsas_set_led_status(mptsas_t *mpt, mptsas_target_t *ptgt, uint32_t slotstatus) 15371 { 15372 NDBG14(("mptsas_ioctl: set LED status %x for slot %x", 15373 slotstatus, ptgt->m_slot_num)); 15374 return (mptsas_send_sep(mpt, ptgt, &slotstatus, 15375 MPI2_SEP_REQ_ACTION_WRITE_STATUS)); 15376 } 15377 /* 15378 * send sep request, use enclosure/slot addressing 15379 */ 15380 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt, 15381 uint32_t *status, uint8_t act) 15382 { 15383 Mpi2SepRequest_t req; 15384 Mpi2SepReply_t rep; 15385 int ret; 15386 15387 ASSERT(mutex_owned(&mpt->m_mutex)); 15388 15389 bzero(&req, sizeof (req)); 15390 bzero(&rep, sizeof (rep)); 15391 15392 /* Do nothing for RAID volumes */ 15393 if (ptgt->m_phymask == 0) { 15394 NDBG14(("mptsas_send_sep: Skip RAID volumes")); 15395 return (DDI_FAILURE); 15396 } 15397 15398 req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; 15399 req.Action = act; 15400 req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS; 15401 req.EnclosureHandle = LE_16(ptgt->m_enclosure); 15402 req.Slot = LE_16(ptgt->m_slot_num); 15403 if (act == MPI2_SEP_REQ_ACTION_WRITE_STATUS) { 15404 req.SlotStatus = LE_32(*status); 15405 } 15406 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL, 15407 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL); 15408 if (ret != 0) { 15409 mptsas_log(mpt, CE_NOTE, "mptsas_send_sep: passthru SEP " 15410 "Processor Request message error %d", ret); 15411 return (DDI_FAILURE); 15412 } 15413 /* do passthrough success, check the ioc status */ 15414 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 15415 if ((LE_16(rep.IOCStatus) & MPI2_IOCSTATUS_MASK) == 15416 MPI2_IOCSTATUS_INVALID_FIELD) { 15417 mptsas_log(mpt, CE_NOTE, "send sep act %x: Not " 15418 "supported action, loginfo %x", act, 15419 LE_32(rep.IOCLogInfo)); 15420 return (DDI_FAILURE); 15421 } 15422 mptsas_log(mpt, CE_NOTE, "send_sep act %x: ioc " 15423 "status:%x", act, LE_16(rep.IOCStatus)); 15424 return (DDI_FAILURE); 15425 } 15426 if (act != MPI2_SEP_REQ_ACTION_WRITE_STATUS) { 15427 *status = LE_32(rep.SlotStatus); 15428 } 15429 15430 return (DDI_SUCCESS); 15431 } 15432 15433 int 15434 mptsas_dma_addr_create(mptsas_t *mpt, ddi_dma_attr_t dma_attr, 15435 ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp, caddr_t *dma_memp, 15436 uint32_t alloc_size, ddi_dma_cookie_t *cookiep) 15437 { 15438 ddi_dma_cookie_t new_cookie; 15439 size_t alloc_len; 15440 uint_t ncookie; 15441 15442 if (cookiep == NULL) 15443 cookiep = &new_cookie; 15444 15445 if (ddi_dma_alloc_handle(mpt->m_dip, &dma_attr, DDI_DMA_SLEEP, 15446 NULL, dma_hdp) != DDI_SUCCESS) { 15447 dma_hdp = NULL; 15448 return (FALSE); 15449 } 15450 15451 if (ddi_dma_mem_alloc(*dma_hdp, alloc_size, &mpt->m_dev_acc_attr, 15452 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, dma_memp, &alloc_len, 15453 acc_hdp) != DDI_SUCCESS) { 15454 ddi_dma_free_handle(dma_hdp); 15455 dma_hdp = NULL; 15456 return (FALSE); 15457 } 15458 15459 if (ddi_dma_addr_bind_handle(*dma_hdp, NULL, *dma_memp, alloc_len, 15460 (DDI_DMA_RDWR | DDI_DMA_CONSISTENT), DDI_DMA_SLEEP, NULL, 15461 cookiep, &ncookie) != DDI_DMA_MAPPED) { 15462 (void) ddi_dma_mem_free(acc_hdp); 15463 ddi_dma_free_handle(dma_hdp); 15464 dma_hdp = NULL; 15465 return (FALSE); 15466 } 15467 15468 return (TRUE); 15469 } 15470 15471 void 15472 mptsas_dma_addr_destroy(ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp) 15473 { 15474 if (*dma_hdp == NULL) 15475 return; 15476 15477 (void) ddi_dma_unbind_handle(*dma_hdp); 15478 (void) ddi_dma_mem_free(acc_hdp); 15479 ddi_dma_free_handle(dma_hdp); 15480 dma_hdp = NULL; 15481 } 15482