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 */ 25 26 /* 27 * Copyright (c) 2000 to 2010, LSI Corporation. 28 * All rights reserved. 29 * 30 * Redistribution and use in source and binary forms of all code within 31 * this file that is exclusively owned by LSI, with or without 32 * modification, is permitted provided that, in addition to the CDDL 1.0 33 * License requirements, the following conditions are met: 34 * 35 * Neither the name of the author nor the names of its contributors may be 36 * used to endorse or promote products derived from this software without 37 * specific prior written permission. 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 40 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 41 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 42 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 43 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 44 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 45 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 46 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 47 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 48 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 49 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 50 * DAMAGE. 51 */ 52 53 /* 54 * mptsas - This is a driver based on LSI Logic's MPT2.0 interface. 55 * 56 */ 57 58 #if defined(lint) || defined(DEBUG) 59 #define MPTSAS_DEBUG 60 #endif 61 62 /* 63 * standard header files. 64 */ 65 #include <sys/note.h> 66 #include <sys/scsi/scsi.h> 67 #include <sys/pci.h> 68 #include <sys/file.h> 69 #include <sys/cpuvar.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 98 #include <sys/raidioctl.h> 99 100 #include <sys/fs/dv_node.h> /* devfs_clean */ 101 102 /* 103 * FMA header files 104 */ 105 #include <sys/ddifm.h> 106 #include <sys/fm/protocol.h> 107 #include <sys/fm/util.h> 108 #include <sys/fm/io/ddi.h> 109 110 /* 111 * For anyone who would modify the code in mptsas_driver, it must be awared 112 * that from snv_145 where CR6910752(mpt_sas driver performance can be 113 * improved) is integrated, the per_instance mutex m_mutex is not hold 114 * in the key IO code path, including mptsas_scsi_start(), mptsas_intr() 115 * and all of the recursive functions called in them, so don't 116 * make it for granted that all operations are sync/exclude correctly. Before 117 * doing any modification in key code path, and even other code path such as 118 * DR, watchsubr, ioctl, passthrough etc, make sure the elements modified have 119 * no releationship to elements shown in the fastpath 120 * (function mptsas_handle_io_fastpath()) in ISR and its recursive functions. 121 * otherwise, you have to use the new introduced mutex to protect them. 122 * As to how to do correctly, refer to the comments in mptsas_intr(). 123 */ 124 125 /* 126 * autoconfiguration data and routines. 127 */ 128 static int mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 129 static int mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd); 130 static int mptsas_power(dev_info_t *dip, int component, int level); 131 132 /* 133 * cb_ops function 134 */ 135 static int mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, 136 cred_t *credp, int *rval); 137 #ifdef __sparc 138 static int mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd); 139 #else /* __sparc */ 140 static int mptsas_quiesce(dev_info_t *devi); 141 #endif /* __sparc */ 142 143 /* 144 * Resource initilaization for hardware 145 */ 146 static void mptsas_setup_cmd_reg(mptsas_t *mpt); 147 static void mptsas_disable_bus_master(mptsas_t *mpt); 148 static void mptsas_hba_fini(mptsas_t *mpt); 149 static void mptsas_cfg_fini(mptsas_t *mptsas_blkp); 150 static int mptsas_hba_setup(mptsas_t *mpt); 151 static void mptsas_hba_teardown(mptsas_t *mpt); 152 static int mptsas_config_space_init(mptsas_t *mpt); 153 static void mptsas_config_space_fini(mptsas_t *mpt); 154 static void mptsas_iport_register(mptsas_t *mpt); 155 static int mptsas_smp_setup(mptsas_t *mpt); 156 static void mptsas_smp_teardown(mptsas_t *mpt); 157 static int mptsas_cache_create(mptsas_t *mpt); 158 static void mptsas_cache_destroy(mptsas_t *mpt); 159 static int mptsas_alloc_request_frames(mptsas_t *mpt); 160 static int mptsas_alloc_reply_frames(mptsas_t *mpt); 161 static int mptsas_alloc_free_queue(mptsas_t *mpt); 162 static int mptsas_alloc_post_queue(mptsas_t *mpt); 163 static void mptsas_alloc_reply_args(mptsas_t *mpt); 164 static int mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd); 165 static void mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd); 166 static int mptsas_init_chip(mptsas_t *mpt, int first_time); 167 168 /* 169 * SCSA function prototypes 170 */ 171 static int mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt); 172 static int mptsas_scsi_reset(struct scsi_address *ap, int level); 173 static int mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt); 174 static int mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly); 175 static int mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, 176 int tgtonly); 177 static void mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt); 178 static struct scsi_pkt *mptsas_scsi_init_pkt(struct scsi_address *ap, 179 struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen, 180 int tgtlen, int flags, int (*callback)(), caddr_t arg); 181 static void mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt); 182 static void mptsas_scsi_destroy_pkt(struct scsi_address *ap, 183 struct scsi_pkt *pkt); 184 static int mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 185 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 186 static void mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 187 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 188 static int mptsas_scsi_reset_notify(struct scsi_address *ap, int flag, 189 void (*callback)(caddr_t), caddr_t arg); 190 static int mptsas_get_name(struct scsi_device *sd, char *name, int len); 191 static int mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len); 192 static int mptsas_scsi_quiesce(dev_info_t *dip); 193 static int mptsas_scsi_unquiesce(dev_info_t *dip); 194 static int mptsas_bus_config(dev_info_t *pdip, uint_t flags, 195 ddi_bus_config_op_t op, void *arg, dev_info_t **childp); 196 197 /* 198 * SMP functions 199 */ 200 static int mptsas_smp_start(struct smp_pkt *smp_pkt); 201 202 /* 203 * internal function prototypes. 204 */ 205 static void mptsas_list_add(mptsas_t *mpt); 206 static void mptsas_list_del(mptsas_t *mpt); 207 208 static int mptsas_quiesce_bus(mptsas_t *mpt); 209 static int mptsas_unquiesce_bus(mptsas_t *mpt); 210 211 static int mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size); 212 static void mptsas_free_handshake_msg(mptsas_t *mpt); 213 214 static void mptsas_ncmds_checkdrain(void *arg); 215 216 static int mptsas_prepare_pkt(mptsas_cmd_t *cmd); 217 static int mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *sp); 218 219 static int mptsas_do_detach(dev_info_t *dev); 220 static int mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl); 221 static int mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, 222 struct scsi_pkt *pkt); 223 static int mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp); 224 225 static void mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd); 226 static void mptsas_handle_event(void *args); 227 static int mptsas_handle_event_sync(void *args); 228 static void mptsas_handle_dr(void *args); 229 static void mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node, 230 dev_info_t *pdip); 231 232 static void mptsas_restart_cmd(void *); 233 234 static void mptsas_flush_hba(mptsas_t *mpt); 235 static void mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, 236 uint8_t tasktype); 237 static void mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, 238 uchar_t reason, uint_t stat); 239 240 static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2); 241 static void mptsas_process_intr(mptsas_t *mpt, 242 pMpi2ReplyDescriptorsUnion_t reply_desc_union); 243 static int mptsas_handle_io_fastpath(mptsas_t *mpt, uint16_t SMID); 244 static void mptsas_handle_scsi_io_success(mptsas_t *mpt, 245 pMpi2ReplyDescriptorsUnion_t reply_desc); 246 static void mptsas_handle_address_reply(mptsas_t *mpt, 247 pMpi2ReplyDescriptorsUnion_t reply_desc); 248 static int mptsas_wait_intr(mptsas_t *mpt, int polltime); 249 static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, 250 uint32_t *control, pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl); 251 252 static void mptsas_watch(void *arg); 253 static void mptsas_watchsubr(mptsas_t *mpt); 254 static void mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl); 255 256 static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd); 257 static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply, 258 uint8_t *data, uint32_t request_size, uint32_t reply_size, 259 uint32_t data_size, uint32_t direction, uint8_t *dataout, 260 uint32_t dataout_size, short timeout, int mode); 261 static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl); 262 263 static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, 264 uint32_t unique_id); 265 static void mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd); 266 static int mptsas_post_fw_diag_buffer(mptsas_t *mpt, 267 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code); 268 static int mptsas_release_fw_diag_buffer(mptsas_t *mpt, 269 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code, 270 uint32_t diag_type); 271 static int mptsas_diag_register(mptsas_t *mpt, 272 mptsas_fw_diag_register_t *diag_register, uint32_t *return_code); 273 static int mptsas_diag_unregister(mptsas_t *mpt, 274 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code); 275 static int mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query, 276 uint32_t *return_code); 277 static int mptsas_diag_read_buffer(mptsas_t *mpt, 278 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf, 279 uint32_t *return_code, int ioctl_mode); 280 static int mptsas_diag_release(mptsas_t *mpt, 281 mptsas_fw_diag_release_t *diag_release, uint32_t *return_code); 282 static int mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, 283 uint8_t *diag_action, uint32_t length, uint32_t *return_code, 284 int ioctl_mode); 285 static int mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *data, 286 int mode); 287 288 static int mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd, 289 int cmdlen, int tgtlen, int statuslen, int kf); 290 static void mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd); 291 292 static int mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags); 293 static void mptsas_kmem_cache_destructor(void *buf, void *cdrarg); 294 295 static int mptsas_cache_frames_constructor(void *buf, void *cdrarg, 296 int kmflags); 297 static void mptsas_cache_frames_destructor(void *buf, void *cdrarg); 298 299 static void mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, 300 mptsas_cmd_t *cmd); 301 static void mptsas_check_task_mgt(mptsas_t *mpt, 302 pMpi2SCSIManagementReply_t reply, mptsas_cmd_t *cmd); 303 static int mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap, 304 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp, 305 int *resid); 306 307 static int mptsas_alloc_active_slots(mptsas_t *mpt, int flag); 308 static void mptsas_free_active_slots(mptsas_t *mpt); 309 static int mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd); 310 static int mptsas_start_cmd0(mptsas_t *mpt, mptsas_cmd_t *cmd); 311 312 static void mptsas_restart_hba(mptsas_t *mpt); 313 314 static void mptsas_deliver_doneq_thread(mptsas_t *mpt); 315 static void mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd); 316 static inline void mptsas_doneq_add0(mptsas_t *mpt, mptsas_cmd_t *cmd); 317 static void mptsas_doneq_mv(mptsas_t *mpt, uint64_t t); 318 319 static mptsas_cmd_t *mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t); 320 static void mptsas_doneq_empty(mptsas_t *mpt); 321 static void mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg); 322 323 static mptsas_cmd_t *mptsas_waitq_rm(mptsas_t *mpt); 324 static void mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd); 325 326 static void mptsas_start_watch_reset_delay(); 327 static void mptsas_setup_bus_reset_delay(mptsas_t *mpt); 328 static void mptsas_watch_reset_delay(void *arg); 329 static int mptsas_watch_reset_delay_subr(mptsas_t *mpt); 330 331 static int mptsas_outstanding_cmds_n(mptsas_t *mpt); 332 /* 333 * helper functions 334 */ 335 static void mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd); 336 337 static dev_info_t *mptsas_find_child(dev_info_t *pdip, char *name); 338 static dev_info_t *mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy); 339 static dev_info_t *mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, 340 int lun); 341 static mdi_pathinfo_t *mptsas_find_path_addr(dev_info_t *pdip, uint64_t sasaddr, 342 int lun); 343 static mdi_pathinfo_t *mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy); 344 static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn); 345 346 static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, 347 int *lun); 348 static int mptsas_parse_smp_name(char *name, uint64_t *wwn); 349 350 static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt, int phymask, 351 uint8_t phy); 352 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask, 353 uint64_t wwid); 354 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask, 355 uint64_t wwid); 356 357 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, 358 uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd); 359 360 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address, 361 uint16_t *handle, mptsas_target_t **pptgt); 362 static void mptsas_update_phymask(mptsas_t *mpt); 363 static inline void mptsas_remove_cmd0(mptsas_t *mpt, mptsas_cmd_t *cmd); 364 365 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt, 366 uint32_t *status, uint8_t cmd); 367 static dev_info_t *mptsas_get_dip_from_dev(dev_t dev, 368 mptsas_phymask_t *phymask); 369 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, 370 mptsas_phymask_t phymask); 371 static int mptsas_set_led_status(mptsas_t *mpt, mptsas_target_t *ptgt, 372 uint32_t slotstatus); 373 374 375 /* 376 * Enumeration / DR functions 377 */ 378 static void mptsas_config_all(dev_info_t *pdip); 379 static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun, 380 dev_info_t **lundip); 381 static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun, 382 dev_info_t **lundip); 383 384 static int mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt); 385 static int mptsas_offline_target(dev_info_t *pdip, char *name); 386 387 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target, 388 dev_info_t **dip); 389 390 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt); 391 static int mptsas_probe_lun(dev_info_t *pdip, int lun, 392 dev_info_t **dip, mptsas_target_t *ptgt); 393 394 static int mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq, 395 dev_info_t **dip, mptsas_target_t *ptgt, int lun); 396 397 static int mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *sd, 398 char *guid, dev_info_t **dip, mptsas_target_t *ptgt, int lun); 399 static int mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *sd, 400 char *guid, dev_info_t **dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, 401 int lun); 402 403 static void mptsas_offline_missed_luns(dev_info_t *pdip, 404 uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt); 405 static int mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip, 406 mdi_pathinfo_t *rpip, uint_t flags); 407 408 static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, 409 dev_info_t **smp_dip); 410 static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 411 uint_t flags); 412 413 static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, 414 int mode, int *rval); 415 static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, 416 int mode, int *rval); 417 static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, 418 int mode, int *rval); 419 static void mptsas_record_event(void *args); 420 static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, 421 int mode); 422 423 static void mptsas_hash_init(mptsas_hash_table_t *hashtab); 424 static void mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen); 425 static void mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data); 426 static void * mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1, 427 mptsas_phymask_t key2); 428 static void * mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1, 429 mptsas_phymask_t key2); 430 static void * mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos); 431 432 mptsas_target_t *mptsas_tgt_alloc(mptsas_hash_table_t *, uint16_t, uint64_t, 433 uint32_t, mptsas_phymask_t, uint8_t, mptsas_t *); 434 static mptsas_smp_t *mptsas_smp_alloc(mptsas_hash_table_t *hashtab, 435 mptsas_smp_t *data); 436 static void mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid, 437 mptsas_phymask_t phymask); 438 static void mptsas_tgt_free(mptsas_hash_table_t *, uint64_t, mptsas_phymask_t); 439 static void * mptsas_search_by_devhdl(mptsas_hash_table_t *, uint16_t); 440 static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 441 dev_info_t **smp_dip); 442 443 /* 444 * Power management functions 445 */ 446 static int mptsas_get_pci_cap(mptsas_t *mpt); 447 static int mptsas_init_pm(mptsas_t *mpt); 448 449 /* 450 * MPT MSI tunable: 451 * 452 * By default MSI is enabled on all supported platforms. 453 */ 454 boolean_t mptsas_enable_msi = B_TRUE; 455 boolean_t mptsas_physical_bind_failed_page_83 = B_FALSE; 456 457 static int mptsas_register_intrs(mptsas_t *); 458 static void mptsas_unregister_intrs(mptsas_t *); 459 static int mptsas_add_intrs(mptsas_t *, int); 460 static void mptsas_rem_intrs(mptsas_t *); 461 462 /* 463 * FMA Prototypes 464 */ 465 static void mptsas_fm_init(mptsas_t *mpt); 466 static void mptsas_fm_fini(mptsas_t *mpt); 467 static int mptsas_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *); 468 469 extern pri_t minclsyspri, maxclsyspri; 470 471 /* 472 * This device is created by the SCSI pseudo nexus driver (SCSI vHCI). It is 473 * under this device that the paths to a physical device are created when 474 * MPxIO is used. 475 */ 476 extern dev_info_t *scsi_vhci_dip; 477 478 /* 479 * Tunable timeout value for Inquiry VPD page 0x83 480 * By default the value is 30 seconds. 481 */ 482 int mptsas_inq83_retry_timeout = 30; 483 484 /* 485 * This is used to allocate memory for message frame storage, not for 486 * data I/O DMA. All message frames must be stored in the first 4G of 487 * physical memory. 488 */ 489 ddi_dma_attr_t mptsas_dma_attrs = { 490 DMA_ATTR_V0, /* attribute layout version */ 491 0x0ull, /* address low - should be 0 (longlong) */ 492 0xffffffffull, /* address high - 32-bit max range */ 493 0x00ffffffull, /* count max - max DMA object size */ 494 4, /* allocation alignment requirements */ 495 0x78, /* burstsizes - binary encoded values */ 496 1, /* minxfer - gran. of DMA engine */ 497 0x00ffffffull, /* maxxfer - gran. of DMA engine */ 498 0xffffffffull, /* max segment size (DMA boundary) */ 499 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */ 500 512, /* granularity - device transfer size */ 501 0 /* flags, set to 0 */ 502 }; 503 504 /* 505 * This is used for data I/O DMA memory allocation. (full 64-bit DMA 506 * physical addresses are supported.) 507 */ 508 ddi_dma_attr_t mptsas_dma_attrs64 = { 509 DMA_ATTR_V0, /* attribute layout version */ 510 0x0ull, /* address low - should be 0 (longlong) */ 511 0xffffffffffffffffull, /* address high - 64-bit max */ 512 0x00ffffffull, /* count max - max DMA object size */ 513 4, /* allocation alignment requirements */ 514 0x78, /* burstsizes - binary encoded values */ 515 1, /* minxfer - gran. of DMA engine */ 516 0x00ffffffull, /* maxxfer - gran. of DMA engine */ 517 0xffffffffull, /* max segment size (DMA boundary) */ 518 MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length */ 519 512, /* granularity - device transfer size */ 520 DDI_DMA_RELAXED_ORDERING /* flags, enable relaxed ordering */ 521 }; 522 523 ddi_device_acc_attr_t mptsas_dev_attr = { 524 DDI_DEVICE_ATTR_V1, 525 DDI_STRUCTURE_LE_ACC, 526 DDI_STRICTORDER_ACC, 527 DDI_DEFAULT_ACC 528 }; 529 530 static struct cb_ops mptsas_cb_ops = { 531 scsi_hba_open, /* open */ 532 scsi_hba_close, /* close */ 533 nodev, /* strategy */ 534 nodev, /* print */ 535 nodev, /* dump */ 536 nodev, /* read */ 537 nodev, /* write */ 538 mptsas_ioctl, /* ioctl */ 539 nodev, /* devmap */ 540 nodev, /* mmap */ 541 nodev, /* segmap */ 542 nochpoll, /* chpoll */ 543 ddi_prop_op, /* cb_prop_op */ 544 NULL, /* streamtab */ 545 D_MP, /* cb_flag */ 546 CB_REV, /* rev */ 547 nodev, /* aread */ 548 nodev /* awrite */ 549 }; 550 551 static struct dev_ops mptsas_ops = { 552 DEVO_REV, /* devo_rev, */ 553 0, /* refcnt */ 554 ddi_no_info, /* info */ 555 nulldev, /* identify */ 556 nulldev, /* probe */ 557 mptsas_attach, /* attach */ 558 mptsas_detach, /* detach */ 559 #ifdef __sparc 560 mptsas_reset, 561 #else 562 nodev, /* reset */ 563 #endif /* __sparc */ 564 &mptsas_cb_ops, /* driver operations */ 565 NULL, /* bus operations */ 566 mptsas_power, /* power management */ 567 #ifdef __sparc 568 ddi_quiesce_not_needed 569 #else 570 mptsas_quiesce /* quiesce */ 571 #endif /* __sparc */ 572 }; 573 574 575 #define MPTSAS_MOD_STRING "MPTSAS HBA Driver 00.00.00.24" 576 577 static struct modldrv modldrv = { 578 &mod_driverops, /* Type of module. This one is a driver */ 579 MPTSAS_MOD_STRING, /* Name of the module. */ 580 &mptsas_ops, /* driver ops */ 581 }; 582 583 static struct modlinkage modlinkage = { 584 MODREV_1, &modldrv, NULL 585 }; 586 #define TARGET_PROP "target" 587 #define LUN_PROP "lun" 588 #define LUN64_PROP "lun64" 589 #define SAS_PROP "sas-mpt" 590 #define MDI_GUID "wwn" 591 #define NDI_GUID "guid" 592 #define MPTSAS_DEV_GONE "mptsas_dev_gone" 593 594 /* 595 * Local static data 596 */ 597 #if defined(MPTSAS_DEBUG) 598 uint32_t mptsas_debug_flags = 0; 599 #endif /* defined(MPTSAS_DEBUG) */ 600 uint32_t mptsas_debug_resets = 0; 601 602 static kmutex_t mptsas_global_mutex; 603 static void *mptsas_state; /* soft state ptr */ 604 static krwlock_t mptsas_global_rwlock; 605 606 static kmutex_t mptsas_log_mutex; 607 static char mptsas_log_buf[256]; 608 _NOTE(MUTEX_PROTECTS_DATA(mptsas_log_mutex, mptsas_log_buf)) 609 610 static mptsas_t *mptsas_head, *mptsas_tail; 611 static clock_t mptsas_scsi_watchdog_tick; 612 static clock_t mptsas_tick; 613 static timeout_id_t mptsas_reset_watch; 614 static timeout_id_t mptsas_timeout_id; 615 static int mptsas_timeouts_enabled = 0; 616 /* 617 * warlock directives 618 */ 619 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt \ 620 mptsas_cmd NcrTableIndirect buf scsi_cdb scsi_status)) 621 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", smp_pkt)) 622 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address)) 623 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", mptsas_tgt_private)) 624 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_hba_tran::tran_tgt_private)) 625 626 /* 627 * SM - HBA statics 628 */ 629 char *mptsas_driver_rev = MPTSAS_MOD_STRING; 630 631 #ifdef MPTSAS_DEBUG 632 void debug_enter(char *); 633 #endif 634 635 /* 636 * Notes: 637 * - scsi_hba_init(9F) initializes SCSI HBA modules 638 * - must call scsi_hba_fini(9F) if modload() fails 639 */ 640 int 641 _init(void) 642 { 643 int status; 644 /* CONSTCOND */ 645 ASSERT(NO_COMPETING_THREADS); 646 647 NDBG0(("_init")); 648 649 status = ddi_soft_state_init(&mptsas_state, MPTSAS_SIZE, 650 MPTSAS_INITIAL_SOFT_SPACE); 651 if (status != 0) { 652 return (status); 653 } 654 655 if ((status = scsi_hba_init(&modlinkage)) != 0) { 656 ddi_soft_state_fini(&mptsas_state); 657 return (status); 658 } 659 660 mutex_init(&mptsas_global_mutex, NULL, MUTEX_DRIVER, NULL); 661 rw_init(&mptsas_global_rwlock, NULL, RW_DRIVER, NULL); 662 mutex_init(&mptsas_log_mutex, NULL, MUTEX_DRIVER, NULL); 663 664 if ((status = mod_install(&modlinkage)) != 0) { 665 mutex_destroy(&mptsas_log_mutex); 666 rw_destroy(&mptsas_global_rwlock); 667 mutex_destroy(&mptsas_global_mutex); 668 ddi_soft_state_fini(&mptsas_state); 669 scsi_hba_fini(&modlinkage); 670 } 671 672 return (status); 673 } 674 675 /* 676 * Notes: 677 * - scsi_hba_fini(9F) uninitializes SCSI HBA modules 678 */ 679 int 680 _fini(void) 681 { 682 int status; 683 /* CONSTCOND */ 684 ASSERT(NO_COMPETING_THREADS); 685 686 NDBG0(("_fini")); 687 688 if ((status = mod_remove(&modlinkage)) == 0) { 689 ddi_soft_state_fini(&mptsas_state); 690 scsi_hba_fini(&modlinkage); 691 mutex_destroy(&mptsas_global_mutex); 692 rw_destroy(&mptsas_global_rwlock); 693 mutex_destroy(&mptsas_log_mutex); 694 } 695 return (status); 696 } 697 698 /* 699 * The loadable-module _info(9E) entry point 700 */ 701 int 702 _info(struct modinfo *modinfop) 703 { 704 /* CONSTCOND */ 705 ASSERT(NO_COMPETING_THREADS); 706 NDBG0(("mptsas _info")); 707 708 return (mod_info(&modlinkage, modinfop)); 709 } 710 711 712 static int 713 mptsas_iport_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 714 { 715 dev_info_t *pdip; 716 mptsas_t *mpt; 717 scsi_hba_tran_t *hba_tran; 718 char *iport = NULL; 719 char phymask[MPTSAS_MAX_PHYS]; 720 mptsas_phymask_t phy_mask = 0; 721 int dynamic_port = 0; 722 uint32_t page_address; 723 char initiator_wwnstr[MPTSAS_WWN_STRLEN]; 724 int rval = DDI_FAILURE; 725 int i = 0; 726 uint8_t numphys = 0; 727 uint8_t phy_id; 728 uint8_t phy_port = 0; 729 uint16_t attached_devhdl = 0; 730 uint32_t dev_info; 731 uint64_t attached_sas_wwn; 732 uint16_t dev_hdl; 733 uint16_t pdev_hdl; 734 uint16_t bay_num, enclosure; 735 char attached_wwnstr[MPTSAS_WWN_STRLEN]; 736 737 /* CONSTCOND */ 738 ASSERT(NO_COMPETING_THREADS); 739 740 switch (cmd) { 741 case DDI_ATTACH: 742 break; 743 744 case DDI_RESUME: 745 /* 746 * If this a scsi-iport node, nothing to do here. 747 */ 748 return (DDI_SUCCESS); 749 750 default: 751 return (DDI_FAILURE); 752 } 753 754 pdip = ddi_get_parent(dip); 755 756 if ((hba_tran = ndi_flavorv_get(pdip, SCSA_FLAVOR_SCSI_DEVICE)) == 757 NULL) { 758 cmn_err(CE_WARN, "Failed attach iport because fail to " 759 "get tran vector for the HBA node"); 760 return (DDI_FAILURE); 761 } 762 763 mpt = TRAN2MPT(hba_tran); 764 ASSERT(mpt != NULL); 765 if (mpt == NULL) 766 return (DDI_FAILURE); 767 768 if ((hba_tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == 769 NULL) { 770 mptsas_log(mpt, CE_WARN, "Failed attach iport because fail to " 771 "get tran vector for the iport node"); 772 return (DDI_FAILURE); 773 } 774 775 /* 776 * Overwrite parent's tran_hba_private to iport's tran vector 777 */ 778 hba_tran->tran_hba_private = mpt; 779 780 ddi_report_dev(dip); 781 782 /* 783 * Get SAS address for initiator port according dev_handle 784 */ 785 iport = ddi_get_name_addr(dip); 786 if (iport && strncmp(iport, "v0", 2) == 0) { 787 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 788 MPTSAS_VIRTUAL_PORT, 1) != 789 DDI_PROP_SUCCESS) { 790 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, 791 MPTSAS_VIRTUAL_PORT); 792 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 793 "prop update failed"); 794 return (DDI_FAILURE); 795 } 796 return (DDI_SUCCESS); 797 } 798 799 mutex_enter(&mpt->m_mutex); 800 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 801 bzero(phymask, sizeof (phymask)); 802 (void) sprintf(phymask, 803 "%x", mpt->m_phy_info[i].phy_mask); 804 if (strcmp(phymask, iport) == 0) { 805 break; 806 } 807 } 808 809 if (i == MPTSAS_MAX_PHYS) { 810 mptsas_log(mpt, CE_WARN, "Failed attach port %s because port" 811 "seems not exist", iport); 812 mutex_exit(&mpt->m_mutex); 813 return (DDI_FAILURE); 814 } 815 816 phy_mask = mpt->m_phy_info[i].phy_mask; 817 818 if (mpt->m_phy_info[i].port_flags & AUTO_PORT_CONFIGURATION) 819 dynamic_port = 1; 820 else 821 dynamic_port = 0; 822 823 /* 824 * Update PHY info for smhba 825 */ 826 if (mptsas_smhba_phy_init(mpt)) { 827 mutex_exit(&mpt->m_mutex); 828 mptsas_log(mpt, CE_WARN, "mptsas phy update " 829 "failed"); 830 return (DDI_FAILURE); 831 } 832 833 mutex_exit(&mpt->m_mutex); 834 835 numphys = 0; 836 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 837 if ((phy_mask >> i) & 0x01) { 838 numphys++; 839 } 840 } 841 842 bzero(initiator_wwnstr, sizeof (initiator_wwnstr)); 843 (void) sprintf(initiator_wwnstr, "w%016"PRIx64, 844 mpt->un.m_base_wwid); 845 846 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, 847 SCSI_ADDR_PROP_INITIATOR_PORT, initiator_wwnstr) != 848 DDI_PROP_SUCCESS) { 849 (void) ddi_prop_remove(DDI_DEV_T_NONE, 850 dip, SCSI_ADDR_PROP_INITIATOR_PORT); 851 mptsas_log(mpt, CE_WARN, "mptsas Initiator port " 852 "prop update failed"); 853 return (DDI_FAILURE); 854 } 855 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 856 MPTSAS_NUM_PHYS, numphys) != 857 DDI_PROP_SUCCESS) { 858 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, MPTSAS_NUM_PHYS); 859 return (DDI_FAILURE); 860 } 861 862 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 863 "phymask", phy_mask) != 864 DDI_PROP_SUCCESS) { 865 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "phymask"); 866 mptsas_log(mpt, CE_WARN, "mptsas phy mask " 867 "prop update failed"); 868 return (DDI_FAILURE); 869 } 870 871 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 872 "dynamic-port", dynamic_port) != 873 DDI_PROP_SUCCESS) { 874 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "dynamic-port"); 875 mptsas_log(mpt, CE_WARN, "mptsas dynamic port " 876 "prop update failed"); 877 return (DDI_FAILURE); 878 } 879 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 880 MPTSAS_VIRTUAL_PORT, 0) != 881 DDI_PROP_SUCCESS) { 882 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, 883 MPTSAS_VIRTUAL_PORT); 884 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 885 "prop update failed"); 886 return (DDI_FAILURE); 887 } 888 mptsas_smhba_set_phy_props(mpt, 889 iport, dip, numphys, &attached_devhdl); 890 891 mutex_enter(&mpt->m_mutex); 892 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 893 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)attached_devhdl; 894 rval = mptsas_get_sas_device_page0(mpt, page_address, &dev_hdl, 895 &attached_sas_wwn, &dev_info, &phy_port, &phy_id, 896 &pdev_hdl, &bay_num, &enclosure); 897 if (rval != DDI_SUCCESS) { 898 mptsas_log(mpt, CE_WARN, 899 "Failed to get device page0 for handle:%d", 900 attached_devhdl); 901 mutex_exit(&mpt->m_mutex); 902 return (DDI_FAILURE); 903 } 904 905 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 906 bzero(phymask, sizeof (phymask)); 907 (void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask); 908 if (strcmp(phymask, iport) == 0) { 909 (void) sprintf(&mpt->m_phy_info[i].smhba_info.path[0], 910 "%x", 911 mpt->m_phy_info[i].phy_mask); 912 } 913 } 914 mutex_exit(&mpt->m_mutex); 915 916 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 917 (void) sprintf(attached_wwnstr, "w%016"PRIx64, 918 attached_sas_wwn); 919 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, 920 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 921 DDI_PROP_SUCCESS) { 922 (void) ddi_prop_remove(DDI_DEV_T_NONE, 923 dip, SCSI_ADDR_PROP_ATTACHED_PORT); 924 return (DDI_FAILURE); 925 } 926 927 /* Create kstats for each phy on this iport */ 928 929 mptsas_create_phy_stats(mpt, iport, dip); 930 931 /* 932 * register sas hba iport with mdi (MPxIO/vhci) 933 */ 934 if (mdi_phci_register(MDI_HCI_CLASS_SCSI, 935 dip, 0) == MDI_SUCCESS) { 936 mpt->m_mpxio_enable = TRUE; 937 } 938 return (DDI_SUCCESS); 939 } 940 941 /* 942 * Notes: 943 * Set up all device state and allocate data structures, 944 * mutexes, condition variables, etc. for device operation. 945 * Add interrupts needed. 946 * Return DDI_SUCCESS if device is ready, else return DDI_FAILURE. 947 */ 948 static int 949 mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 950 { 951 mptsas_t *mpt = NULL; 952 int instance, i, j; 953 int doneq_thread_num; 954 char intr_added = 0; 955 char map_setup = 0; 956 char config_setup = 0; 957 char hba_attach_setup = 0; 958 char smp_attach_setup = 0; 959 char mutex_init_done = 0; 960 char event_taskq_create = 0; 961 char dr_taskq_create = 0; 962 char doneq_thread_create = 0; 963 scsi_hba_tran_t *hba_tran; 964 uint_t mem_bar = MEM_SPACE; 965 int rval = DDI_FAILURE; 966 967 /* CONSTCOND */ 968 ASSERT(NO_COMPETING_THREADS); 969 970 if (scsi_hba_iport_unit_address(dip)) { 971 return (mptsas_iport_attach(dip, cmd)); 972 } 973 974 switch (cmd) { 975 case DDI_ATTACH: 976 break; 977 978 case DDI_RESUME: 979 if ((hba_tran = ddi_get_driver_private(dip)) == NULL) 980 return (DDI_FAILURE); 981 982 mpt = TRAN2MPT(hba_tran); 983 984 if (!mpt) { 985 return (DDI_FAILURE); 986 } 987 988 /* 989 * Reset hardware and softc to "no outstanding commands" 990 * Note that a check condition can result on first command 991 * to a target. 992 */ 993 mutex_enter(&mpt->m_mutex); 994 995 /* 996 * raise power. 997 */ 998 if (mpt->m_options & MPTSAS_OPT_PM) { 999 mutex_exit(&mpt->m_mutex); 1000 (void) pm_busy_component(dip, 0); 1001 rval = pm_power_has_changed(dip, 0, PM_LEVEL_D0); 1002 if (rval == DDI_SUCCESS) { 1003 mutex_enter(&mpt->m_mutex); 1004 } else { 1005 /* 1006 * The pm_raise_power() call above failed, 1007 * and that can only occur if we were unable 1008 * to reset the hardware. This is probably 1009 * due to unhealty hardware, and because 1010 * important filesystems(such as the root 1011 * filesystem) could be on the attached disks, 1012 * it would not be a good idea to continue, 1013 * as we won't be entirely certain we are 1014 * writing correct data. So we panic() here 1015 * to not only prevent possible data corruption, 1016 * but to give developers or end users a hope 1017 * of identifying and correcting any problems. 1018 */ 1019 fm_panic("mptsas could not reset hardware " 1020 "during resume"); 1021 } 1022 } 1023 1024 mpt->m_suspended = 0; 1025 1026 /* 1027 * Reinitialize ioc 1028 */ 1029 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1030 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) { 1031 mutex_exit(&mpt->m_mutex); 1032 if (mpt->m_options & MPTSAS_OPT_PM) { 1033 (void) pm_idle_component(dip, 0); 1034 } 1035 fm_panic("mptsas init chip fail during resume"); 1036 } 1037 /* 1038 * mptsas_update_driver_data needs interrupts so enable them 1039 * first. 1040 */ 1041 MPTSAS_ENABLE_INTR(mpt); 1042 mptsas_update_driver_data(mpt); 1043 1044 /* start requests, if possible */ 1045 mptsas_restart_hba(mpt); 1046 1047 mutex_exit(&mpt->m_mutex); 1048 1049 /* 1050 * Restart watch thread 1051 */ 1052 mutex_enter(&mptsas_global_mutex); 1053 if (mptsas_timeout_id == 0) { 1054 mptsas_timeout_id = timeout(mptsas_watch, NULL, 1055 mptsas_tick); 1056 mptsas_timeouts_enabled = 1; 1057 } 1058 mutex_exit(&mptsas_global_mutex); 1059 1060 /* report idle status to pm framework */ 1061 if (mpt->m_options & MPTSAS_OPT_PM) { 1062 (void) pm_idle_component(dip, 0); 1063 } 1064 1065 return (DDI_SUCCESS); 1066 1067 default: 1068 return (DDI_FAILURE); 1069 1070 } 1071 1072 instance = ddi_get_instance(dip); 1073 1074 /* 1075 * Allocate softc information. 1076 */ 1077 if (ddi_soft_state_zalloc(mptsas_state, instance) != DDI_SUCCESS) { 1078 mptsas_log(NULL, CE_WARN, 1079 "mptsas%d: cannot allocate soft state", instance); 1080 goto fail; 1081 } 1082 1083 mpt = ddi_get_soft_state(mptsas_state, instance); 1084 1085 if (mpt == NULL) { 1086 mptsas_log(NULL, CE_WARN, 1087 "mptsas%d: cannot get soft state", instance); 1088 goto fail; 1089 } 1090 1091 /* Indicate that we are 'sizeof (scsi_*(9S))' clean. */ 1092 scsi_size_clean(dip); 1093 1094 mpt->m_dip = dip; 1095 mpt->m_instance = instance; 1096 1097 /* Make a per-instance copy of the structures */ 1098 mpt->m_io_dma_attr = mptsas_dma_attrs64; 1099 mpt->m_msg_dma_attr = mptsas_dma_attrs; 1100 mpt->m_reg_acc_attr = mptsas_dev_attr; 1101 mpt->m_dev_acc_attr = mptsas_dev_attr; 1102 1103 /* 1104 * Initialize FMA 1105 */ 1106 mpt->m_fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, mpt->m_dip, 1107 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable", 1108 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE | 1109 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE); 1110 1111 mptsas_fm_init(mpt); 1112 1113 if (mptsas_alloc_handshake_msg(mpt, 1114 sizeof (Mpi2SCSITaskManagementRequest_t)) == DDI_FAILURE) { 1115 mptsas_log(mpt, CE_WARN, "cannot initialize handshake msg."); 1116 goto fail; 1117 } 1118 1119 /* 1120 * Setup configuration space 1121 */ 1122 if (mptsas_config_space_init(mpt) == FALSE) { 1123 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init failed"); 1124 goto fail; 1125 } 1126 config_setup++; 1127 1128 if (ddi_regs_map_setup(dip, mem_bar, (caddr_t *)&mpt->m_reg, 1129 0, 0, &mpt->m_reg_acc_attr, &mpt->m_datap) != DDI_SUCCESS) { 1130 mptsas_log(mpt, CE_WARN, "map setup failed"); 1131 goto fail; 1132 } 1133 map_setup++; 1134 1135 /* 1136 * A taskq is created for dealing with the event handler 1137 */ 1138 if ((mpt->m_event_taskq = ddi_taskq_create(dip, "mptsas_event_taskq", 1139 1, TASKQ_DEFAULTPRI, 0)) == NULL) { 1140 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create failed"); 1141 goto fail; 1142 } 1143 event_taskq_create++; 1144 1145 /* 1146 * A taskq is created for dealing with dr events 1147 */ 1148 if ((mpt->m_dr_taskq = ddi_taskq_create(dip, 1149 "mptsas_dr_taskq", 1150 1, TASKQ_DEFAULTPRI, 0)) == NULL) { 1151 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create for discovery " 1152 "failed"); 1153 goto fail; 1154 } 1155 dr_taskq_create++; 1156 1157 mpt->m_doneq_thread_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1158 0, "mptsas_doneq_thread_threshold_prop", 10); 1159 mpt->m_doneq_length_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1160 0, "mptsas_doneq_length_threshold_prop", 8); 1161 mpt->m_doneq_thread_n = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1162 0, "mptsas_doneq_thread_n_prop", 8); 1163 1164 if (mpt->m_doneq_thread_n) { 1165 cv_init(&mpt->m_doneq_thread_cv, NULL, CV_DRIVER, NULL); 1166 mutex_init(&mpt->m_doneq_mutex, NULL, MUTEX_DRIVER, NULL); 1167 1168 mutex_enter(&mpt->m_doneq_mutex); 1169 mpt->m_doneq_thread_id = 1170 kmem_zalloc(sizeof (mptsas_doneq_thread_list_t) 1171 * mpt->m_doneq_thread_n, KM_SLEEP); 1172 1173 for (j = 0; j < mpt->m_doneq_thread_n; j++) { 1174 cv_init(&mpt->m_doneq_thread_id[j].cv, NULL, 1175 CV_DRIVER, NULL); 1176 mutex_init(&mpt->m_doneq_thread_id[j].mutex, NULL, 1177 MUTEX_DRIVER, NULL); 1178 mutex_enter(&mpt->m_doneq_thread_id[j].mutex); 1179 mpt->m_doneq_thread_id[j].flag |= 1180 MPTSAS_DONEQ_THREAD_ACTIVE; 1181 mpt->m_doneq_thread_id[j].arg.mpt = mpt; 1182 mpt->m_doneq_thread_id[j].arg.t = j; 1183 mpt->m_doneq_thread_id[j].threadp = 1184 thread_create(NULL, 0, mptsas_doneq_thread, 1185 &mpt->m_doneq_thread_id[j].arg, 1186 0, &p0, TS_RUN, minclsyspri); 1187 mpt->m_doneq_thread_id[j].donetail = 1188 &mpt->m_doneq_thread_id[j].doneq; 1189 mutex_exit(&mpt->m_doneq_thread_id[j].mutex); 1190 } 1191 mutex_exit(&mpt->m_doneq_mutex); 1192 doneq_thread_create++; 1193 } 1194 1195 /* Initialize mutex used in interrupt handler */ 1196 mutex_init(&mpt->m_mutex, NULL, MUTEX_DRIVER, 1197 DDI_INTR_PRI(mpt->m_intr_pri)); 1198 mutex_init(&mpt->m_passthru_mutex, NULL, MUTEX_DRIVER, NULL); 1199 mutex_init(&mpt->m_intr_mutex, NULL, MUTEX_DRIVER, 1200 DDI_INTR_PRI(mpt->m_intr_pri)); 1201 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1202 mutex_init(&mpt->m_phy_info[i].smhba_info.phy_mutex, 1203 NULL, MUTEX_DRIVER, 1204 DDI_INTR_PRI(mpt->m_intr_pri)); 1205 } 1206 1207 cv_init(&mpt->m_cv, NULL, CV_DRIVER, NULL); 1208 cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL); 1209 cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL); 1210 cv_init(&mpt->m_config_cv, NULL, CV_DRIVER, NULL); 1211 cv_init(&mpt->m_fw_diag_cv, NULL, CV_DRIVER, NULL); 1212 mutex_init_done++; 1213 1214 /* 1215 * Disable hardware interrupt since we're not ready to 1216 * handle it yet. 1217 */ 1218 MPTSAS_DISABLE_INTR(mpt); 1219 if (mptsas_register_intrs(mpt) == FALSE) 1220 goto fail; 1221 intr_added++; 1222 1223 mutex_enter(&mpt->m_mutex); 1224 /* 1225 * Initialize power management component 1226 */ 1227 if (mpt->m_options & MPTSAS_OPT_PM) { 1228 if (mptsas_init_pm(mpt)) { 1229 mutex_exit(&mpt->m_mutex); 1230 mptsas_log(mpt, CE_WARN, "mptsas pm initialization " 1231 "failed"); 1232 goto fail; 1233 } 1234 } 1235 1236 /* 1237 * Initialize chip using Message Unit Reset, if allowed 1238 */ 1239 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1240 if (mptsas_init_chip(mpt, TRUE) == DDI_FAILURE) { 1241 mutex_exit(&mpt->m_mutex); 1242 mptsas_log(mpt, CE_WARN, "mptsas chip initialization failed"); 1243 goto fail; 1244 } 1245 1246 /* 1247 * Fill in the phy_info structure and get the base WWID 1248 */ 1249 if (mptsas_get_manufacture_page5(mpt) == DDI_FAILURE) { 1250 mptsas_log(mpt, CE_WARN, 1251 "mptsas_get_manufacture_page5 failed!"); 1252 goto fail; 1253 } 1254 1255 if (mptsas_get_sas_io_unit_page_hndshk(mpt)) { 1256 mptsas_log(mpt, CE_WARN, 1257 "mptsas_get_sas_io_unit_page_hndshk failed!"); 1258 goto fail; 1259 } 1260 1261 if (mptsas_get_manufacture_page0(mpt) == DDI_FAILURE) { 1262 mptsas_log(mpt, CE_WARN, 1263 "mptsas_get_manufacture_page0 failed!"); 1264 goto fail; 1265 } 1266 1267 mutex_exit(&mpt->m_mutex); 1268 1269 /* 1270 * Register the iport for multiple port HBA 1271 */ 1272 mptsas_iport_register(mpt); 1273 1274 /* 1275 * initialize SCSI HBA transport structure 1276 */ 1277 if (mptsas_hba_setup(mpt) == FALSE) 1278 goto fail; 1279 hba_attach_setup++; 1280 1281 if (mptsas_smp_setup(mpt) == FALSE) 1282 goto fail; 1283 smp_attach_setup++; 1284 1285 if (mptsas_cache_create(mpt) == FALSE) 1286 goto fail; 1287 1288 mpt->m_scsi_reset_delay = ddi_prop_get_int(DDI_DEV_T_ANY, 1289 dip, 0, "scsi-reset-delay", SCSI_DEFAULT_RESET_DELAY); 1290 if (mpt->m_scsi_reset_delay == 0) { 1291 mptsas_log(mpt, CE_NOTE, 1292 "scsi_reset_delay of 0 is not recommended," 1293 " resetting to SCSI_DEFAULT_RESET_DELAY\n"); 1294 mpt->m_scsi_reset_delay = SCSI_DEFAULT_RESET_DELAY; 1295 } 1296 1297 /* 1298 * Initialize the wait and done FIFO queue 1299 */ 1300 mpt->m_donetail = &mpt->m_doneq; 1301 mpt->m_waitqtail = &mpt->m_waitq; 1302 1303 /* 1304 * ioc cmd queue initialize 1305 */ 1306 mpt->m_ioc_event_cmdtail = &mpt->m_ioc_event_cmdq; 1307 mpt->m_dev_handle = 0xFFFF; 1308 1309 MPTSAS_ENABLE_INTR(mpt); 1310 1311 /* 1312 * enable event notification 1313 */ 1314 mutex_enter(&mpt->m_mutex); 1315 if (mptsas_ioc_enable_event_notification(mpt)) { 1316 mutex_exit(&mpt->m_mutex); 1317 goto fail; 1318 } 1319 mutex_exit(&mpt->m_mutex); 1320 1321 /* 1322 * Initialize PHY info for smhba 1323 */ 1324 if (mptsas_smhba_setup(mpt)) { 1325 mptsas_log(mpt, CE_WARN, "mptsas phy initialization " 1326 "failed"); 1327 goto fail; 1328 } 1329 1330 /* Check all dma handles allocated in attach */ 1331 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) 1332 != DDI_SUCCESS) || 1333 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) 1334 != DDI_SUCCESS) || 1335 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) 1336 != DDI_SUCCESS) || 1337 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) 1338 != DDI_SUCCESS) || 1339 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) 1340 != DDI_SUCCESS)) { 1341 goto fail; 1342 } 1343 1344 /* Check all acc handles allocated in attach */ 1345 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) || 1346 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) 1347 != DDI_SUCCESS) || 1348 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) 1349 != DDI_SUCCESS) || 1350 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) 1351 != DDI_SUCCESS) || 1352 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) 1353 != DDI_SUCCESS) || 1354 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) 1355 != DDI_SUCCESS) || 1356 (mptsas_check_acc_handle(mpt->m_config_handle) 1357 != DDI_SUCCESS)) { 1358 goto fail; 1359 } 1360 1361 /* 1362 * After this point, we are not going to fail the attach. 1363 */ 1364 /* 1365 * used for mptsas_watch 1366 */ 1367 mptsas_list_add(mpt); 1368 1369 mutex_enter(&mptsas_global_mutex); 1370 if (mptsas_timeouts_enabled == 0) { 1371 mptsas_scsi_watchdog_tick = ddi_prop_get_int(DDI_DEV_T_ANY, 1372 dip, 0, "scsi-watchdog-tick", DEFAULT_WD_TICK); 1373 1374 mptsas_tick = mptsas_scsi_watchdog_tick * 1375 drv_usectohz((clock_t)1000000); 1376 1377 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick); 1378 mptsas_timeouts_enabled = 1; 1379 } 1380 mutex_exit(&mptsas_global_mutex); 1381 1382 /* Print message of HBA present */ 1383 ddi_report_dev(dip); 1384 1385 /* report idle status to pm framework */ 1386 if (mpt->m_options & MPTSAS_OPT_PM) { 1387 (void) pm_idle_component(dip, 0); 1388 } 1389 1390 return (DDI_SUCCESS); 1391 1392 fail: 1393 mptsas_log(mpt, CE_WARN, "attach failed"); 1394 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 1395 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 1396 if (mpt) { 1397 mutex_enter(&mptsas_global_mutex); 1398 1399 if (mptsas_timeout_id && (mptsas_head == NULL)) { 1400 timeout_id_t tid = mptsas_timeout_id; 1401 mptsas_timeouts_enabled = 0; 1402 mptsas_timeout_id = 0; 1403 mutex_exit(&mptsas_global_mutex); 1404 (void) untimeout(tid); 1405 mutex_enter(&mptsas_global_mutex); 1406 } 1407 mutex_exit(&mptsas_global_mutex); 1408 /* deallocate in reverse order */ 1409 mptsas_cache_destroy(mpt); 1410 1411 if (smp_attach_setup) { 1412 mptsas_smp_teardown(mpt); 1413 } 1414 if (hba_attach_setup) { 1415 mptsas_hba_teardown(mpt); 1416 } 1417 1418 if (mpt->m_active) { 1419 mptsas_hash_uninit(&mpt->m_active->m_smptbl, 1420 sizeof (mptsas_smp_t)); 1421 mptsas_hash_uninit(&mpt->m_active->m_tgttbl, 1422 sizeof (mptsas_target_t)); 1423 mptsas_free_active_slots(mpt); 1424 } 1425 if (intr_added) { 1426 mptsas_unregister_intrs(mpt); 1427 } 1428 1429 if (doneq_thread_create) { 1430 mutex_enter(&mpt->m_doneq_mutex); 1431 doneq_thread_num = mpt->m_doneq_thread_n; 1432 for (j = 0; j < mpt->m_doneq_thread_n; j++) { 1433 mutex_enter(&mpt->m_doneq_thread_id[j].mutex); 1434 mpt->m_doneq_thread_id[j].flag &= 1435 (~MPTSAS_DONEQ_THREAD_ACTIVE); 1436 cv_signal(&mpt->m_doneq_thread_id[j].cv); 1437 mutex_exit(&mpt->m_doneq_thread_id[j].mutex); 1438 } 1439 while (mpt->m_doneq_thread_n) { 1440 cv_wait(&mpt->m_doneq_thread_cv, 1441 &mpt->m_doneq_mutex); 1442 } 1443 for (j = 0; j < doneq_thread_num; j++) { 1444 cv_destroy(&mpt->m_doneq_thread_id[j].cv); 1445 mutex_destroy(&mpt->m_doneq_thread_id[j].mutex); 1446 } 1447 kmem_free(mpt->m_doneq_thread_id, 1448 sizeof (mptsas_doneq_thread_list_t) 1449 * doneq_thread_num); 1450 mutex_exit(&mpt->m_doneq_mutex); 1451 cv_destroy(&mpt->m_doneq_thread_cv); 1452 mutex_destroy(&mpt->m_doneq_mutex); 1453 } 1454 if (event_taskq_create) { 1455 ddi_taskq_destroy(mpt->m_event_taskq); 1456 } 1457 if (dr_taskq_create) { 1458 ddi_taskq_destroy(mpt->m_dr_taskq); 1459 } 1460 if (mutex_init_done) { 1461 mutex_destroy(&mpt->m_intr_mutex); 1462 mutex_destroy(&mpt->m_passthru_mutex); 1463 mutex_destroy(&mpt->m_mutex); 1464 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1465 mutex_destroy( 1466 &mpt->m_phy_info[i].smhba_info.phy_mutex); 1467 } 1468 cv_destroy(&mpt->m_cv); 1469 cv_destroy(&mpt->m_passthru_cv); 1470 cv_destroy(&mpt->m_fw_cv); 1471 cv_destroy(&mpt->m_config_cv); 1472 cv_destroy(&mpt->m_fw_diag_cv); 1473 } 1474 1475 if (map_setup) { 1476 mptsas_cfg_fini(mpt); 1477 } 1478 if (config_setup) { 1479 mptsas_config_space_fini(mpt); 1480 } 1481 mptsas_free_handshake_msg(mpt); 1482 mptsas_hba_fini(mpt); 1483 1484 mptsas_fm_fini(mpt); 1485 ddi_soft_state_free(mptsas_state, instance); 1486 ddi_prop_remove_all(dip); 1487 } 1488 return (DDI_FAILURE); 1489 } 1490 1491 static int 1492 mptsas_suspend(dev_info_t *devi) 1493 { 1494 mptsas_t *mpt, *g; 1495 scsi_hba_tran_t *tran; 1496 1497 if (scsi_hba_iport_unit_address(devi)) { 1498 return (DDI_SUCCESS); 1499 } 1500 1501 if ((tran = ddi_get_driver_private(devi)) == NULL) 1502 return (DDI_SUCCESS); 1503 1504 mpt = TRAN2MPT(tran); 1505 if (!mpt) { 1506 return (DDI_SUCCESS); 1507 } 1508 1509 mutex_enter(&mpt->m_mutex); 1510 1511 if (mpt->m_suspended++) { 1512 mutex_exit(&mpt->m_mutex); 1513 return (DDI_SUCCESS); 1514 } 1515 1516 /* 1517 * Cancel timeout threads for this mpt 1518 */ 1519 if (mpt->m_quiesce_timeid) { 1520 timeout_id_t tid = mpt->m_quiesce_timeid; 1521 mpt->m_quiesce_timeid = 0; 1522 mutex_exit(&mpt->m_mutex); 1523 (void) untimeout(tid); 1524 mutex_enter(&mpt->m_mutex); 1525 } 1526 1527 if (mpt->m_restart_cmd_timeid) { 1528 timeout_id_t tid = mpt->m_restart_cmd_timeid; 1529 mpt->m_restart_cmd_timeid = 0; 1530 mutex_exit(&mpt->m_mutex); 1531 (void) untimeout(tid); 1532 mutex_enter(&mpt->m_mutex); 1533 } 1534 1535 mutex_exit(&mpt->m_mutex); 1536 1537 (void) pm_idle_component(mpt->m_dip, 0); 1538 1539 /* 1540 * Cancel watch threads if all mpts suspended 1541 */ 1542 rw_enter(&mptsas_global_rwlock, RW_WRITER); 1543 for (g = mptsas_head; g != NULL; g = g->m_next) { 1544 if (!g->m_suspended) 1545 break; 1546 } 1547 rw_exit(&mptsas_global_rwlock); 1548 1549 mutex_enter(&mptsas_global_mutex); 1550 if (g == NULL) { 1551 timeout_id_t tid; 1552 1553 mptsas_timeouts_enabled = 0; 1554 if (mptsas_timeout_id) { 1555 tid = mptsas_timeout_id; 1556 mptsas_timeout_id = 0; 1557 mutex_exit(&mptsas_global_mutex); 1558 (void) untimeout(tid); 1559 mutex_enter(&mptsas_global_mutex); 1560 } 1561 if (mptsas_reset_watch) { 1562 tid = mptsas_reset_watch; 1563 mptsas_reset_watch = 0; 1564 mutex_exit(&mptsas_global_mutex); 1565 (void) untimeout(tid); 1566 mutex_enter(&mptsas_global_mutex); 1567 } 1568 } 1569 mutex_exit(&mptsas_global_mutex); 1570 1571 mutex_enter(&mpt->m_mutex); 1572 1573 /* 1574 * If this mpt is not in full power(PM_LEVEL_D0), just return. 1575 */ 1576 if ((mpt->m_options & MPTSAS_OPT_PM) && 1577 (mpt->m_power_level != PM_LEVEL_D0)) { 1578 mutex_exit(&mpt->m_mutex); 1579 return (DDI_SUCCESS); 1580 } 1581 1582 /* Disable HBA interrupts in hardware */ 1583 MPTSAS_DISABLE_INTR(mpt); 1584 /* 1585 * Send RAID action system shutdown to sync IR 1586 */ 1587 mptsas_raid_action_system_shutdown(mpt); 1588 1589 mutex_exit(&mpt->m_mutex); 1590 1591 /* drain the taskq */ 1592 ddi_taskq_wait(mpt->m_event_taskq); 1593 ddi_taskq_wait(mpt->m_dr_taskq); 1594 1595 return (DDI_SUCCESS); 1596 } 1597 1598 #ifdef __sparc 1599 /*ARGSUSED*/ 1600 static int 1601 mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd) 1602 { 1603 mptsas_t *mpt; 1604 scsi_hba_tran_t *tran; 1605 1606 /* 1607 * If this call is for iport, just return. 1608 */ 1609 if (scsi_hba_iport_unit_address(devi)) 1610 return (DDI_SUCCESS); 1611 1612 if ((tran = ddi_get_driver_private(devi)) == NULL) 1613 return (DDI_SUCCESS); 1614 1615 if ((mpt = TRAN2MPT(tran)) == NULL) 1616 return (DDI_SUCCESS); 1617 1618 /* 1619 * Send RAID action system shutdown to sync IR. Disable HBA 1620 * interrupts in hardware first. 1621 */ 1622 MPTSAS_DISABLE_INTR(mpt); 1623 mptsas_raid_action_system_shutdown(mpt); 1624 1625 return (DDI_SUCCESS); 1626 } 1627 #else /* __sparc */ 1628 /* 1629 * quiesce(9E) entry point. 1630 * 1631 * This function is called when the system is single-threaded at high 1632 * PIL with preemption disabled. Therefore, this function must not be 1633 * blocked. 1634 * 1635 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 1636 * DDI_FAILURE indicates an error condition and should almost never happen. 1637 */ 1638 static int 1639 mptsas_quiesce(dev_info_t *devi) 1640 { 1641 mptsas_t *mpt; 1642 scsi_hba_tran_t *tran; 1643 1644 /* 1645 * If this call is for iport, just return. 1646 */ 1647 if (scsi_hba_iport_unit_address(devi)) 1648 return (DDI_SUCCESS); 1649 1650 if ((tran = ddi_get_driver_private(devi)) == NULL) 1651 return (DDI_SUCCESS); 1652 1653 if ((mpt = TRAN2MPT(tran)) == NULL) 1654 return (DDI_SUCCESS); 1655 1656 /* Disable HBA interrupts in hardware */ 1657 MPTSAS_DISABLE_INTR(mpt); 1658 /* Send RAID action system shutdonw to sync IR */ 1659 mptsas_raid_action_system_shutdown(mpt); 1660 1661 return (DDI_SUCCESS); 1662 } 1663 #endif /* __sparc */ 1664 1665 /* 1666 * detach(9E). Remove all device allocations and system resources; 1667 * disable device interrupts. 1668 * Return DDI_SUCCESS if done; DDI_FAILURE if there's a problem. 1669 */ 1670 static int 1671 mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 1672 { 1673 /* CONSTCOND */ 1674 ASSERT(NO_COMPETING_THREADS); 1675 NDBG0(("mptsas_detach: dip=0x%p cmd=0x%p", (void *)devi, (void *)cmd)); 1676 1677 switch (cmd) { 1678 case DDI_DETACH: 1679 return (mptsas_do_detach(devi)); 1680 1681 case DDI_SUSPEND: 1682 return (mptsas_suspend(devi)); 1683 1684 default: 1685 return (DDI_FAILURE); 1686 } 1687 /* NOTREACHED */ 1688 } 1689 1690 static int 1691 mptsas_do_detach(dev_info_t *dip) 1692 { 1693 mptsas_t *mpt; 1694 scsi_hba_tran_t *tran; 1695 int circ = 0; 1696 int circ1 = 0; 1697 mdi_pathinfo_t *pip = NULL; 1698 int i; 1699 int doneq_thread_num = 0; 1700 1701 NDBG0(("mptsas_do_detach: dip=0x%p", (void *)dip)); 1702 1703 if ((tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == NULL) 1704 return (DDI_FAILURE); 1705 1706 mpt = TRAN2MPT(tran); 1707 if (!mpt) { 1708 return (DDI_FAILURE); 1709 } 1710 /* 1711 * Still have pathinfo child, should not detach mpt driver 1712 */ 1713 if (scsi_hba_iport_unit_address(dip)) { 1714 if (mpt->m_mpxio_enable) { 1715 /* 1716 * MPxIO enabled for the iport 1717 */ 1718 ndi_devi_enter(scsi_vhci_dip, &circ1); 1719 ndi_devi_enter(dip, &circ); 1720 while (pip = mdi_get_next_client_path(dip, NULL)) { 1721 if (mdi_pi_free(pip, 0) == MDI_SUCCESS) { 1722 continue; 1723 } 1724 ndi_devi_exit(dip, circ); 1725 ndi_devi_exit(scsi_vhci_dip, circ1); 1726 NDBG12(("detach failed because of " 1727 "outstanding path info")); 1728 return (DDI_FAILURE); 1729 } 1730 ndi_devi_exit(dip, circ); 1731 ndi_devi_exit(scsi_vhci_dip, circ1); 1732 (void) mdi_phci_unregister(dip, 0); 1733 } 1734 1735 ddi_prop_remove_all(dip); 1736 1737 return (DDI_SUCCESS); 1738 } 1739 1740 /* Make sure power level is D0 before accessing registers */ 1741 if (mpt->m_options & MPTSAS_OPT_PM) { 1742 (void) pm_busy_component(dip, 0); 1743 if (mpt->m_power_level != PM_LEVEL_D0) { 1744 if (pm_raise_power(dip, 0, PM_LEVEL_D0) != 1745 DDI_SUCCESS) { 1746 mptsas_log(mpt, CE_WARN, 1747 "mptsas%d: Raise power request failed.", 1748 mpt->m_instance); 1749 (void) pm_idle_component(dip, 0); 1750 return (DDI_FAILURE); 1751 } 1752 } 1753 } 1754 1755 /* 1756 * Send RAID action system shutdown to sync IR. After action, send a 1757 * Message Unit Reset. Since after that DMA resource will be freed, 1758 * set ioc to READY state will avoid HBA initiated DMA operation. 1759 */ 1760 mutex_enter(&mpt->m_mutex); 1761 MPTSAS_DISABLE_INTR(mpt); 1762 mptsas_raid_action_system_shutdown(mpt); 1763 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1764 (void) mptsas_ioc_reset(mpt); 1765 mutex_exit(&mpt->m_mutex); 1766 mptsas_rem_intrs(mpt); 1767 ddi_taskq_destroy(mpt->m_event_taskq); 1768 ddi_taskq_destroy(mpt->m_dr_taskq); 1769 1770 if (mpt->m_doneq_thread_n) { 1771 mutex_enter(&mpt->m_doneq_mutex); 1772 doneq_thread_num = mpt->m_doneq_thread_n; 1773 for (i = 0; i < mpt->m_doneq_thread_n; i++) { 1774 mutex_enter(&mpt->m_doneq_thread_id[i].mutex); 1775 mpt->m_doneq_thread_id[i].flag &= 1776 (~MPTSAS_DONEQ_THREAD_ACTIVE); 1777 cv_signal(&mpt->m_doneq_thread_id[i].cv); 1778 mutex_exit(&mpt->m_doneq_thread_id[i].mutex); 1779 } 1780 while (mpt->m_doneq_thread_n) { 1781 cv_wait(&mpt->m_doneq_thread_cv, 1782 &mpt->m_doneq_mutex); 1783 } 1784 for (i = 0; i < doneq_thread_num; i++) { 1785 cv_destroy(&mpt->m_doneq_thread_id[i].cv); 1786 mutex_destroy(&mpt->m_doneq_thread_id[i].mutex); 1787 } 1788 kmem_free(mpt->m_doneq_thread_id, 1789 sizeof (mptsas_doneq_thread_list_t) 1790 * doneq_thread_num); 1791 mutex_exit(&mpt->m_doneq_mutex); 1792 cv_destroy(&mpt->m_doneq_thread_cv); 1793 mutex_destroy(&mpt->m_doneq_mutex); 1794 } 1795 1796 scsi_hba_reset_notify_tear_down(mpt->m_reset_notify_listf); 1797 1798 mptsas_list_del(mpt); 1799 1800 /* 1801 * Cancel timeout threads for this mpt 1802 */ 1803 mutex_enter(&mpt->m_mutex); 1804 if (mpt->m_quiesce_timeid) { 1805 timeout_id_t tid = mpt->m_quiesce_timeid; 1806 mpt->m_quiesce_timeid = 0; 1807 mutex_exit(&mpt->m_mutex); 1808 (void) untimeout(tid); 1809 mutex_enter(&mpt->m_mutex); 1810 } 1811 1812 if (mpt->m_restart_cmd_timeid) { 1813 timeout_id_t tid = mpt->m_restart_cmd_timeid; 1814 mpt->m_restart_cmd_timeid = 0; 1815 mutex_exit(&mpt->m_mutex); 1816 (void) untimeout(tid); 1817 mutex_enter(&mpt->m_mutex); 1818 } 1819 1820 mutex_exit(&mpt->m_mutex); 1821 1822 /* 1823 * last mpt? ... if active, CANCEL watch threads. 1824 */ 1825 mutex_enter(&mptsas_global_mutex); 1826 if (mptsas_head == NULL) { 1827 timeout_id_t tid; 1828 /* 1829 * Clear mptsas_timeouts_enable so that the watch thread 1830 * gets restarted on DDI_ATTACH 1831 */ 1832 mptsas_timeouts_enabled = 0; 1833 if (mptsas_timeout_id) { 1834 tid = mptsas_timeout_id; 1835 mptsas_timeout_id = 0; 1836 mutex_exit(&mptsas_global_mutex); 1837 (void) untimeout(tid); 1838 mutex_enter(&mptsas_global_mutex); 1839 } 1840 if (mptsas_reset_watch) { 1841 tid = mptsas_reset_watch; 1842 mptsas_reset_watch = 0; 1843 mutex_exit(&mptsas_global_mutex); 1844 (void) untimeout(tid); 1845 mutex_enter(&mptsas_global_mutex); 1846 } 1847 } 1848 mutex_exit(&mptsas_global_mutex); 1849 1850 /* 1851 * Delete Phy stats 1852 */ 1853 mptsas_destroy_phy_stats(mpt); 1854 1855 /* 1856 * Delete nt_active. 1857 */ 1858 mutex_enter(&mpt->m_mutex); 1859 mptsas_hash_uninit(&mpt->m_active->m_tgttbl, sizeof (mptsas_target_t)); 1860 mptsas_hash_uninit(&mpt->m_active->m_smptbl, sizeof (mptsas_smp_t)); 1861 mptsas_free_active_slots(mpt); 1862 mutex_exit(&mpt->m_mutex); 1863 1864 /* deallocate everything that was allocated in mptsas_attach */ 1865 mptsas_cache_destroy(mpt); 1866 1867 mptsas_hba_fini(mpt); 1868 mptsas_cfg_fini(mpt); 1869 1870 /* Lower the power informing PM Framework */ 1871 if (mpt->m_options & MPTSAS_OPT_PM) { 1872 if (pm_lower_power(dip, 0, PM_LEVEL_D3) != DDI_SUCCESS) 1873 mptsas_log(mpt, CE_WARN, 1874 "!mptsas%d: Lower power request failed " 1875 "during detach, ignoring.", 1876 mpt->m_instance); 1877 } 1878 1879 mutex_destroy(&mpt->m_intr_mutex); 1880 mutex_destroy(&mpt->m_passthru_mutex); 1881 mutex_destroy(&mpt->m_mutex); 1882 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1883 mutex_destroy(&mpt->m_phy_info[i].smhba_info.phy_mutex); 1884 } 1885 cv_destroy(&mpt->m_cv); 1886 cv_destroy(&mpt->m_passthru_cv); 1887 cv_destroy(&mpt->m_fw_cv); 1888 cv_destroy(&mpt->m_config_cv); 1889 cv_destroy(&mpt->m_fw_diag_cv); 1890 1891 1892 mptsas_smp_teardown(mpt); 1893 mptsas_hba_teardown(mpt); 1894 1895 mptsas_config_space_fini(mpt); 1896 1897 mptsas_free_handshake_msg(mpt); 1898 1899 mptsas_fm_fini(mpt); 1900 ddi_soft_state_free(mptsas_state, ddi_get_instance(dip)); 1901 ddi_prop_remove_all(dip); 1902 1903 return (DDI_SUCCESS); 1904 } 1905 1906 static void 1907 mptsas_list_add(mptsas_t *mpt) 1908 { 1909 rw_enter(&mptsas_global_rwlock, RW_WRITER); 1910 1911 if (mptsas_head == NULL) { 1912 mptsas_head = mpt; 1913 } else { 1914 mptsas_tail->m_next = mpt; 1915 } 1916 mptsas_tail = mpt; 1917 rw_exit(&mptsas_global_rwlock); 1918 } 1919 1920 static void 1921 mptsas_list_del(mptsas_t *mpt) 1922 { 1923 mptsas_t *m; 1924 /* 1925 * Remove device instance from the global linked list 1926 */ 1927 rw_enter(&mptsas_global_rwlock, RW_WRITER); 1928 if (mptsas_head == mpt) { 1929 m = mptsas_head = mpt->m_next; 1930 } else { 1931 for (m = mptsas_head; m != NULL; m = m->m_next) { 1932 if (m->m_next == mpt) { 1933 m->m_next = mpt->m_next; 1934 break; 1935 } 1936 } 1937 if (m == NULL) { 1938 mptsas_log(mpt, CE_PANIC, "Not in softc list!"); 1939 } 1940 } 1941 1942 if (mptsas_tail == mpt) { 1943 mptsas_tail = m; 1944 } 1945 rw_exit(&mptsas_global_rwlock); 1946 } 1947 1948 static int 1949 mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size) 1950 { 1951 ddi_dma_attr_t task_dma_attrs; 1952 1953 task_dma_attrs = mpt->m_msg_dma_attr; 1954 task_dma_attrs.dma_attr_sgllen = 1; 1955 task_dma_attrs.dma_attr_granular = (uint32_t)(alloc_size); 1956 1957 /* allocate Task Management ddi_dma resources */ 1958 if (mptsas_dma_addr_create(mpt, task_dma_attrs, 1959 &mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl, &mpt->m_hshk_memp, 1960 alloc_size, NULL) == FALSE) { 1961 return (DDI_FAILURE); 1962 } 1963 mpt->m_hshk_dma_size = alloc_size; 1964 1965 return (DDI_SUCCESS); 1966 } 1967 1968 static void 1969 mptsas_free_handshake_msg(mptsas_t *mpt) 1970 { 1971 mptsas_dma_addr_destroy(&mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl); 1972 mpt->m_hshk_dma_size = 0; 1973 } 1974 1975 static int 1976 mptsas_hba_setup(mptsas_t *mpt) 1977 { 1978 scsi_hba_tran_t *hba_tran; 1979 int tran_flags; 1980 1981 /* Allocate a transport structure */ 1982 hba_tran = mpt->m_tran = scsi_hba_tran_alloc(mpt->m_dip, 1983 SCSI_HBA_CANSLEEP); 1984 ASSERT(mpt->m_tran != NULL); 1985 1986 hba_tran->tran_hba_private = mpt; 1987 hba_tran->tran_tgt_private = NULL; 1988 1989 hba_tran->tran_tgt_init = mptsas_scsi_tgt_init; 1990 hba_tran->tran_tgt_free = mptsas_scsi_tgt_free; 1991 1992 hba_tran->tran_start = mptsas_scsi_start; 1993 hba_tran->tran_reset = mptsas_scsi_reset; 1994 hba_tran->tran_abort = mptsas_scsi_abort; 1995 hba_tran->tran_getcap = mptsas_scsi_getcap; 1996 hba_tran->tran_setcap = mptsas_scsi_setcap; 1997 hba_tran->tran_init_pkt = mptsas_scsi_init_pkt; 1998 hba_tran->tran_destroy_pkt = mptsas_scsi_destroy_pkt; 1999 2000 hba_tran->tran_dmafree = mptsas_scsi_dmafree; 2001 hba_tran->tran_sync_pkt = mptsas_scsi_sync_pkt; 2002 hba_tran->tran_reset_notify = mptsas_scsi_reset_notify; 2003 2004 hba_tran->tran_get_bus_addr = mptsas_get_bus_addr; 2005 hba_tran->tran_get_name = mptsas_get_name; 2006 2007 hba_tran->tran_quiesce = mptsas_scsi_quiesce; 2008 hba_tran->tran_unquiesce = mptsas_scsi_unquiesce; 2009 hba_tran->tran_bus_reset = NULL; 2010 2011 hba_tran->tran_add_eventcall = NULL; 2012 hba_tran->tran_get_eventcookie = NULL; 2013 hba_tran->tran_post_event = NULL; 2014 hba_tran->tran_remove_eventcall = NULL; 2015 2016 hba_tran->tran_bus_config = mptsas_bus_config; 2017 2018 hba_tran->tran_interconnect_type = INTERCONNECT_SAS; 2019 2020 /* 2021 * All children of the HBA are iports. We need tran was cloned. 2022 * So we pass the flags to SCSA. SCSI_HBA_TRAN_CLONE will be 2023 * inherited to iport's tran vector. 2024 */ 2025 tran_flags = (SCSI_HBA_HBA | SCSI_HBA_TRAN_CLONE); 2026 2027 if (scsi_hba_attach_setup(mpt->m_dip, &mpt->m_msg_dma_attr, 2028 hba_tran, tran_flags) != DDI_SUCCESS) { 2029 mptsas_log(mpt, CE_WARN, "hba attach setup failed"); 2030 scsi_hba_tran_free(hba_tran); 2031 mpt->m_tran = NULL; 2032 return (FALSE); 2033 } 2034 return (TRUE); 2035 } 2036 2037 static void 2038 mptsas_hba_teardown(mptsas_t *mpt) 2039 { 2040 (void) scsi_hba_detach(mpt->m_dip); 2041 if (mpt->m_tran != NULL) { 2042 scsi_hba_tran_free(mpt->m_tran); 2043 mpt->m_tran = NULL; 2044 } 2045 } 2046 2047 static void 2048 mptsas_iport_register(mptsas_t *mpt) 2049 { 2050 int i, j; 2051 mptsas_phymask_t mask = 0x0; 2052 /* 2053 * initial value of mask is 0 2054 */ 2055 mutex_enter(&mpt->m_mutex); 2056 for (i = 0; i < mpt->m_num_phys; i++) { 2057 mptsas_phymask_t phy_mask = 0x0; 2058 char phy_mask_name[MPTSAS_MAX_PHYS]; 2059 uint8_t current_port; 2060 2061 if (mpt->m_phy_info[i].attached_devhdl == 0) 2062 continue; 2063 2064 bzero(phy_mask_name, sizeof (phy_mask_name)); 2065 2066 current_port = mpt->m_phy_info[i].port_num; 2067 2068 if ((mask & (1 << i)) != 0) 2069 continue; 2070 2071 for (j = 0; j < mpt->m_num_phys; j++) { 2072 if (mpt->m_phy_info[j].attached_devhdl && 2073 (mpt->m_phy_info[j].port_num == current_port)) { 2074 phy_mask |= (1 << j); 2075 } 2076 } 2077 mask = mask | phy_mask; 2078 2079 for (j = 0; j < mpt->m_num_phys; j++) { 2080 if ((phy_mask >> j) & 0x01) { 2081 mpt->m_phy_info[j].phy_mask = phy_mask; 2082 } 2083 } 2084 2085 (void) sprintf(phy_mask_name, "%x", phy_mask); 2086 2087 mutex_exit(&mpt->m_mutex); 2088 /* 2089 * register a iport 2090 */ 2091 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name); 2092 mutex_enter(&mpt->m_mutex); 2093 } 2094 mutex_exit(&mpt->m_mutex); 2095 /* 2096 * register a virtual port for RAID volume always 2097 */ 2098 (void) scsi_hba_iport_register(mpt->m_dip, "v0"); 2099 2100 } 2101 2102 static int 2103 mptsas_smp_setup(mptsas_t *mpt) 2104 { 2105 mpt->m_smptran = smp_hba_tran_alloc(mpt->m_dip); 2106 ASSERT(mpt->m_smptran != NULL); 2107 mpt->m_smptran->smp_tran_hba_private = mpt; 2108 mpt->m_smptran->smp_tran_start = mptsas_smp_start; 2109 if (smp_hba_attach_setup(mpt->m_dip, mpt->m_smptran) != DDI_SUCCESS) { 2110 mptsas_log(mpt, CE_WARN, "smp attach setup failed"); 2111 smp_hba_tran_free(mpt->m_smptran); 2112 mpt->m_smptran = NULL; 2113 return (FALSE); 2114 } 2115 /* 2116 * Initialize smp hash table 2117 */ 2118 mptsas_hash_init(&mpt->m_active->m_smptbl); 2119 mpt->m_smp_devhdl = 0xFFFF; 2120 2121 return (TRUE); 2122 } 2123 2124 static void 2125 mptsas_smp_teardown(mptsas_t *mpt) 2126 { 2127 (void) smp_hba_detach(mpt->m_dip); 2128 if (mpt->m_smptran != NULL) { 2129 smp_hba_tran_free(mpt->m_smptran); 2130 mpt->m_smptran = NULL; 2131 } 2132 mpt->m_smp_devhdl = 0; 2133 } 2134 2135 static int 2136 mptsas_cache_create(mptsas_t *mpt) 2137 { 2138 int instance = mpt->m_instance; 2139 char buf[64]; 2140 2141 /* 2142 * create kmem cache for packets 2143 */ 2144 (void) sprintf(buf, "mptsas%d_cache", instance); 2145 mpt->m_kmem_cache = kmem_cache_create(buf, 2146 sizeof (struct mptsas_cmd) + scsi_pkt_size(), 8, 2147 mptsas_kmem_cache_constructor, mptsas_kmem_cache_destructor, 2148 NULL, (void *)mpt, NULL, 0); 2149 2150 if (mpt->m_kmem_cache == NULL) { 2151 mptsas_log(mpt, CE_WARN, "creating kmem cache failed"); 2152 return (FALSE); 2153 } 2154 2155 /* 2156 * create kmem cache for extra SGL frames if SGL cannot 2157 * be accomodated into main request frame. 2158 */ 2159 (void) sprintf(buf, "mptsas%d_cache_frames", instance); 2160 mpt->m_cache_frames = kmem_cache_create(buf, 2161 sizeof (mptsas_cache_frames_t), 8, 2162 mptsas_cache_frames_constructor, mptsas_cache_frames_destructor, 2163 NULL, (void *)mpt, NULL, 0); 2164 2165 if (mpt->m_cache_frames == NULL) { 2166 mptsas_log(mpt, CE_WARN, "creating cache for frames failed"); 2167 return (FALSE); 2168 } 2169 2170 return (TRUE); 2171 } 2172 2173 static void 2174 mptsas_cache_destroy(mptsas_t *mpt) 2175 { 2176 /* deallocate in reverse order */ 2177 if (mpt->m_cache_frames) { 2178 kmem_cache_destroy(mpt->m_cache_frames); 2179 mpt->m_cache_frames = NULL; 2180 } 2181 if (mpt->m_kmem_cache) { 2182 kmem_cache_destroy(mpt->m_kmem_cache); 2183 mpt->m_kmem_cache = NULL; 2184 } 2185 } 2186 2187 static int 2188 mptsas_power(dev_info_t *dip, int component, int level) 2189 { 2190 #ifndef __lock_lint 2191 _NOTE(ARGUNUSED(component)) 2192 #endif 2193 mptsas_t *mpt; 2194 int rval = DDI_SUCCESS; 2195 int polls = 0; 2196 uint32_t ioc_status; 2197 2198 if (scsi_hba_iport_unit_address(dip) != 0) 2199 return (DDI_SUCCESS); 2200 2201 mpt = ddi_get_soft_state(mptsas_state, ddi_get_instance(dip)); 2202 if (mpt == NULL) { 2203 return (DDI_FAILURE); 2204 } 2205 2206 mutex_enter(&mpt->m_mutex); 2207 2208 /* 2209 * If the device is busy, don't lower its power level 2210 */ 2211 if (mpt->m_busy && (mpt->m_power_level > level)) { 2212 mutex_exit(&mpt->m_mutex); 2213 return (DDI_FAILURE); 2214 } 2215 switch (level) { 2216 case PM_LEVEL_D0: 2217 NDBG11(("mptsas%d: turning power ON.", mpt->m_instance)); 2218 MPTSAS_POWER_ON(mpt); 2219 /* 2220 * Wait up to 30 seconds for IOC to come out of reset. 2221 */ 2222 while (((ioc_status = ddi_get32(mpt->m_datap, 2223 &mpt->m_reg->Doorbell)) & 2224 MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_RESET) { 2225 if (polls++ > 3000) { 2226 break; 2227 } 2228 delay(drv_usectohz(10000)); 2229 } 2230 /* 2231 * If IOC is not in operational state, try to hard reset it. 2232 */ 2233 if ((ioc_status & MPI2_IOC_STATE_MASK) != 2234 MPI2_IOC_STATE_OPERATIONAL) { 2235 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 2236 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) { 2237 mptsas_log(mpt, CE_WARN, 2238 "mptsas_power: hard reset failed"); 2239 mutex_exit(&mpt->m_mutex); 2240 return (DDI_FAILURE); 2241 } 2242 } 2243 mutex_enter(&mpt->m_intr_mutex); 2244 mpt->m_power_level = PM_LEVEL_D0; 2245 mutex_exit(&mpt->m_intr_mutex); 2246 break; 2247 case PM_LEVEL_D3: 2248 NDBG11(("mptsas%d: turning power OFF.", mpt->m_instance)); 2249 MPTSAS_POWER_OFF(mpt); 2250 break; 2251 default: 2252 mptsas_log(mpt, CE_WARN, "mptsas%d: unknown power level <%x>.", 2253 mpt->m_instance, level); 2254 rval = DDI_FAILURE; 2255 break; 2256 } 2257 mutex_exit(&mpt->m_mutex); 2258 return (rval); 2259 } 2260 2261 /* 2262 * Initialize configuration space and figure out which 2263 * chip and revison of the chip the mpt driver is using. 2264 */ 2265 static int 2266 mptsas_config_space_init(mptsas_t *mpt) 2267 { 2268 NDBG0(("mptsas_config_space_init")); 2269 2270 if (mpt->m_config_handle != NULL) 2271 return (TRUE); 2272 2273 if (pci_config_setup(mpt->m_dip, 2274 &mpt->m_config_handle) != DDI_SUCCESS) { 2275 mptsas_log(mpt, CE_WARN, "cannot map configuration space."); 2276 return (FALSE); 2277 } 2278 2279 /* 2280 * This is a workaround for a XMITS ASIC bug which does not 2281 * drive the CBE upper bits. 2282 */ 2283 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) & 2284 PCI_STAT_PERROR) { 2285 pci_config_put16(mpt->m_config_handle, PCI_CONF_STAT, 2286 PCI_STAT_PERROR); 2287 } 2288 2289 mptsas_setup_cmd_reg(mpt); 2290 2291 /* 2292 * Get the chip device id: 2293 */ 2294 mpt->m_devid = pci_config_get16(mpt->m_config_handle, PCI_CONF_DEVID); 2295 2296 /* 2297 * Save the revision. 2298 */ 2299 mpt->m_revid = pci_config_get8(mpt->m_config_handle, PCI_CONF_REVID); 2300 2301 /* 2302 * Save the SubSystem Vendor and Device IDs 2303 */ 2304 mpt->m_svid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBVENID); 2305 mpt->m_ssid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBSYSID); 2306 2307 /* 2308 * Set the latency timer to 0x40 as specified by the upa -> pci 2309 * bridge chip design team. This may be done by the sparc pci 2310 * bus nexus driver, but the driver should make sure the latency 2311 * timer is correct for performance reasons. 2312 */ 2313 pci_config_put8(mpt->m_config_handle, PCI_CONF_LATENCY_TIMER, 2314 MPTSAS_LATENCY_TIMER); 2315 2316 (void) mptsas_get_pci_cap(mpt); 2317 return (TRUE); 2318 } 2319 2320 static void 2321 mptsas_config_space_fini(mptsas_t *mpt) 2322 { 2323 if (mpt->m_config_handle != NULL) { 2324 mptsas_disable_bus_master(mpt); 2325 pci_config_teardown(&mpt->m_config_handle); 2326 mpt->m_config_handle = NULL; 2327 } 2328 } 2329 2330 static void 2331 mptsas_setup_cmd_reg(mptsas_t *mpt) 2332 { 2333 ushort_t cmdreg; 2334 2335 /* 2336 * Set the command register to the needed values. 2337 */ 2338 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM); 2339 cmdreg |= (PCI_COMM_ME | PCI_COMM_SERR_ENABLE | 2340 PCI_COMM_PARITY_DETECT | PCI_COMM_MAE); 2341 cmdreg &= ~PCI_COMM_IO; 2342 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg); 2343 } 2344 2345 static void 2346 mptsas_disable_bus_master(mptsas_t *mpt) 2347 { 2348 ushort_t cmdreg; 2349 2350 /* 2351 * Clear the master enable bit in the PCI command register. 2352 * This prevents any bus mastering activity like DMA. 2353 */ 2354 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM); 2355 cmdreg &= ~PCI_COMM_ME; 2356 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg); 2357 } 2358 2359 int 2360 mptsas_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep) 2361 { 2362 ddi_dma_attr_t attrs; 2363 2364 attrs = mpt->m_io_dma_attr; 2365 attrs.dma_attr_sgllen = 1; 2366 2367 ASSERT(dma_statep != NULL); 2368 2369 if (mptsas_dma_addr_create(mpt, attrs, &dma_statep->handle, 2370 &dma_statep->accessp, &dma_statep->memp, dma_statep->size, 2371 &dma_statep->cookie) == FALSE) { 2372 return (DDI_FAILURE); 2373 } 2374 2375 return (DDI_SUCCESS); 2376 } 2377 2378 void 2379 mptsas_dma_free(mptsas_dma_alloc_state_t *dma_statep) 2380 { 2381 ASSERT(dma_statep != NULL); 2382 mptsas_dma_addr_destroy(&dma_statep->handle, &dma_statep->accessp); 2383 dma_statep->size = 0; 2384 } 2385 2386 int 2387 mptsas_do_dma(mptsas_t *mpt, uint32_t size, int var, int (*callback)()) 2388 { 2389 ddi_dma_attr_t attrs; 2390 ddi_dma_handle_t dma_handle; 2391 caddr_t memp; 2392 ddi_acc_handle_t accessp; 2393 int rval; 2394 2395 ASSERT(mutex_owned(&mpt->m_mutex)); 2396 2397 attrs = mpt->m_msg_dma_attr; 2398 attrs.dma_attr_sgllen = 1; 2399 attrs.dma_attr_granular = size; 2400 2401 if (mptsas_dma_addr_create(mpt, attrs, &dma_handle, 2402 &accessp, &memp, size, NULL) == FALSE) { 2403 return (DDI_FAILURE); 2404 } 2405 2406 rval = (*callback) (mpt, memp, var, accessp); 2407 2408 if ((mptsas_check_dma_handle(dma_handle) != DDI_SUCCESS) || 2409 (mptsas_check_acc_handle(accessp) != DDI_SUCCESS)) { 2410 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 2411 rval = DDI_FAILURE; 2412 } 2413 2414 mptsas_dma_addr_destroy(&dma_handle, &accessp); 2415 return (rval); 2416 2417 } 2418 2419 static int 2420 mptsas_alloc_request_frames(mptsas_t *mpt) 2421 { 2422 ddi_dma_attr_t frame_dma_attrs; 2423 caddr_t memp; 2424 ddi_dma_cookie_t cookie; 2425 size_t mem_size; 2426 2427 /* 2428 * re-alloc when it has already alloced 2429 */ 2430 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl, 2431 &mpt->m_acc_req_frame_hdl); 2432 2433 /* 2434 * The size of the request frame pool is: 2435 * Number of Request Frames * Request Frame Size 2436 */ 2437 mem_size = mpt->m_max_requests * mpt->m_req_frame_size; 2438 2439 /* 2440 * set the DMA attributes. System Request Message Frames must be 2441 * aligned on a 16-byte boundry. 2442 */ 2443 frame_dma_attrs = mpt->m_msg_dma_attr; 2444 frame_dma_attrs.dma_attr_align = 16; 2445 frame_dma_attrs.dma_attr_sgllen = 1; 2446 2447 /* 2448 * allocate the request frame pool. 2449 */ 2450 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2451 &mpt->m_dma_req_frame_hdl, &mpt->m_acc_req_frame_hdl, &memp, 2452 mem_size, &cookie) == FALSE) { 2453 return (DDI_FAILURE); 2454 } 2455 2456 /* 2457 * Store the request frame memory address. This chip uses this 2458 * address to dma to and from the driver's frame. The second 2459 * address is the address mpt uses to fill in the frame. 2460 */ 2461 mpt->m_req_frame_dma_addr = cookie.dmac_laddress; 2462 mpt->m_req_frame = memp; 2463 2464 /* 2465 * Clear the request frame pool. 2466 */ 2467 bzero(mpt->m_req_frame, mem_size); 2468 2469 return (DDI_SUCCESS); 2470 } 2471 2472 static int 2473 mptsas_alloc_reply_frames(mptsas_t *mpt) 2474 { 2475 ddi_dma_attr_t frame_dma_attrs; 2476 caddr_t memp; 2477 ddi_dma_cookie_t cookie; 2478 size_t mem_size; 2479 2480 /* 2481 * re-alloc when it has already alloced 2482 */ 2483 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl, 2484 &mpt->m_acc_reply_frame_hdl); 2485 2486 /* 2487 * The size of the reply frame pool is: 2488 * Number of Reply Frames * Reply Frame Size 2489 */ 2490 mem_size = mpt->m_max_replies * mpt->m_reply_frame_size; 2491 2492 /* 2493 * set the DMA attributes. System Reply Message Frames must be 2494 * aligned on a 4-byte boundry. This is the default. 2495 */ 2496 frame_dma_attrs = mpt->m_msg_dma_attr; 2497 frame_dma_attrs.dma_attr_sgllen = 1; 2498 2499 /* 2500 * allocate the reply frame pool 2501 */ 2502 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2503 &mpt->m_dma_reply_frame_hdl, &mpt->m_acc_reply_frame_hdl, &memp, 2504 mem_size, &cookie) == FALSE) { 2505 return (DDI_FAILURE); 2506 } 2507 2508 /* 2509 * Store the reply frame memory address. This chip uses this 2510 * address to dma to and from the driver's frame. The second 2511 * address is the address mpt uses to process the frame. 2512 */ 2513 mpt->m_reply_frame_dma_addr = cookie.dmac_laddress; 2514 mpt->m_reply_frame = memp; 2515 2516 /* 2517 * Clear the reply frame pool. 2518 */ 2519 bzero(mpt->m_reply_frame, mem_size); 2520 2521 return (DDI_SUCCESS); 2522 } 2523 2524 static int 2525 mptsas_alloc_free_queue(mptsas_t *mpt) 2526 { 2527 ddi_dma_attr_t frame_dma_attrs; 2528 caddr_t memp; 2529 ddi_dma_cookie_t cookie; 2530 size_t mem_size; 2531 2532 /* 2533 * re-alloc when it has already alloced 2534 */ 2535 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl, 2536 &mpt->m_acc_free_queue_hdl); 2537 2538 /* 2539 * The reply free queue size is: 2540 * Reply Free Queue Depth * 4 2541 * The "4" is the size of one 32 bit address (low part of 64-bit 2542 * address) 2543 */ 2544 mem_size = mpt->m_free_queue_depth * 4; 2545 2546 /* 2547 * set the DMA attributes The Reply Free Queue must be aligned on a 2548 * 16-byte boundry. 2549 */ 2550 frame_dma_attrs = mpt->m_msg_dma_attr; 2551 frame_dma_attrs.dma_attr_align = 16; 2552 frame_dma_attrs.dma_attr_sgllen = 1; 2553 2554 /* 2555 * allocate the reply free queue 2556 */ 2557 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2558 &mpt->m_dma_free_queue_hdl, &mpt->m_acc_free_queue_hdl, &memp, 2559 mem_size, &cookie) == FALSE) { 2560 return (DDI_FAILURE); 2561 } 2562 2563 /* 2564 * Store the reply free queue memory address. This chip uses this 2565 * address to read from the reply free queue. The second address 2566 * is the address mpt uses to manage the queue. 2567 */ 2568 mpt->m_free_queue_dma_addr = cookie.dmac_laddress; 2569 mpt->m_free_queue = memp; 2570 2571 /* 2572 * Clear the reply free queue memory. 2573 */ 2574 bzero(mpt->m_free_queue, mem_size); 2575 2576 return (DDI_SUCCESS); 2577 } 2578 2579 static int 2580 mptsas_alloc_post_queue(mptsas_t *mpt) 2581 { 2582 ddi_dma_attr_t frame_dma_attrs; 2583 caddr_t memp; 2584 ddi_dma_cookie_t cookie; 2585 size_t mem_size; 2586 2587 /* 2588 * re-alloc when it has already alloced 2589 */ 2590 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl, 2591 &mpt->m_acc_post_queue_hdl); 2592 2593 /* 2594 * The reply descriptor post queue size is: 2595 * Reply Descriptor Post Queue Depth * 8 2596 * The "8" is the size of each descriptor (8 bytes or 64 bits). 2597 */ 2598 mem_size = mpt->m_post_queue_depth * 8; 2599 2600 /* 2601 * set the DMA attributes. The Reply Descriptor Post Queue must be 2602 * aligned on a 16-byte boundry. 2603 */ 2604 frame_dma_attrs = mpt->m_msg_dma_attr; 2605 frame_dma_attrs.dma_attr_align = 16; 2606 frame_dma_attrs.dma_attr_sgllen = 1; 2607 2608 /* 2609 * allocate the reply post queue 2610 */ 2611 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2612 &mpt->m_dma_post_queue_hdl, &mpt->m_acc_post_queue_hdl, &memp, 2613 mem_size, &cookie) == FALSE) { 2614 return (DDI_FAILURE); 2615 } 2616 2617 /* 2618 * Store the reply descriptor post queue memory address. This chip 2619 * uses this address to write to the reply descriptor post queue. The 2620 * second address is the address mpt uses to manage the queue. 2621 */ 2622 mpt->m_post_queue_dma_addr = cookie.dmac_laddress; 2623 mpt->m_post_queue = memp; 2624 2625 /* 2626 * Clear the reply post queue memory. 2627 */ 2628 bzero(mpt->m_post_queue, mem_size); 2629 2630 return (DDI_SUCCESS); 2631 } 2632 2633 static void 2634 mptsas_alloc_reply_args(mptsas_t *mpt) 2635 { 2636 if (mpt->m_replyh_args != NULL) { 2637 kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t) 2638 * mpt->m_max_replies); 2639 mpt->m_replyh_args = NULL; 2640 } 2641 mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) * 2642 mpt->m_max_replies, KM_SLEEP); 2643 } 2644 2645 static int 2646 mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd) 2647 { 2648 mptsas_cache_frames_t *frames = NULL; 2649 if (cmd->cmd_extra_frames == NULL) { 2650 frames = kmem_cache_alloc(mpt->m_cache_frames, KM_NOSLEEP); 2651 if (frames == NULL) { 2652 return (DDI_FAILURE); 2653 } 2654 cmd->cmd_extra_frames = frames; 2655 } 2656 return (DDI_SUCCESS); 2657 } 2658 2659 static void 2660 mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd) 2661 { 2662 if (cmd->cmd_extra_frames) { 2663 kmem_cache_free(mpt->m_cache_frames, 2664 (void *)cmd->cmd_extra_frames); 2665 cmd->cmd_extra_frames = NULL; 2666 } 2667 } 2668 2669 static void 2670 mptsas_cfg_fini(mptsas_t *mpt) 2671 { 2672 NDBG0(("mptsas_cfg_fini")); 2673 ddi_regs_map_free(&mpt->m_datap); 2674 } 2675 2676 static void 2677 mptsas_hba_fini(mptsas_t *mpt) 2678 { 2679 NDBG0(("mptsas_hba_fini")); 2680 2681 /* 2682 * Free up any allocated memory 2683 */ 2684 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl, 2685 &mpt->m_acc_req_frame_hdl); 2686 2687 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl, 2688 &mpt->m_acc_reply_frame_hdl); 2689 2690 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl, 2691 &mpt->m_acc_free_queue_hdl); 2692 2693 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl, 2694 &mpt->m_acc_post_queue_hdl); 2695 2696 if (mpt->m_replyh_args != NULL) { 2697 kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t) 2698 * mpt->m_max_replies); 2699 } 2700 } 2701 2702 static int 2703 mptsas_name_child(dev_info_t *lun_dip, char *name, int len) 2704 { 2705 int lun = 0; 2706 char *sas_wwn = NULL; 2707 int phynum = -1; 2708 int reallen = 0; 2709 2710 /* Get the target num */ 2711 lun = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, DDI_PROP_DONTPASS, 2712 LUN_PROP, 0); 2713 2714 if ((phynum = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, 2715 DDI_PROP_DONTPASS, "sata-phy", -1)) != -1) { 2716 /* 2717 * Stick in the address of form "pPHY,LUN" 2718 */ 2719 reallen = snprintf(name, len, "p%x,%x", phynum, lun); 2720 } else if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lun_dip, 2721 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &sas_wwn) 2722 == DDI_PROP_SUCCESS) { 2723 /* 2724 * Stick in the address of the form "wWWN,LUN" 2725 */ 2726 reallen = snprintf(name, len, "%s,%x", sas_wwn, lun); 2727 ddi_prop_free(sas_wwn); 2728 } else { 2729 return (DDI_FAILURE); 2730 } 2731 2732 ASSERT(reallen < len); 2733 if (reallen >= len) { 2734 mptsas_log(0, CE_WARN, "!mptsas_get_name: name parameter " 2735 "length too small, it needs to be %d bytes", reallen + 1); 2736 } 2737 return (DDI_SUCCESS); 2738 } 2739 2740 /* 2741 * tran_tgt_init(9E) - target device instance initialization 2742 */ 2743 static int 2744 mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 2745 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 2746 { 2747 #ifndef __lock_lint 2748 _NOTE(ARGUNUSED(hba_tran)) 2749 #endif 2750 2751 /* 2752 * At this point, the scsi_device structure already exists 2753 * and has been initialized. 2754 * 2755 * Use this function to allocate target-private data structures, 2756 * if needed by this HBA. Add revised flow-control and queue 2757 * properties for child here, if desired and if you can tell they 2758 * support tagged queueing by now. 2759 */ 2760 mptsas_t *mpt; 2761 int lun = sd->sd_address.a_lun; 2762 mdi_pathinfo_t *pip = NULL; 2763 mptsas_tgt_private_t *tgt_private = NULL; 2764 mptsas_target_t *ptgt = NULL; 2765 char *psas_wwn = NULL; 2766 int phymask = 0; 2767 uint64_t sas_wwn = 0; 2768 mpt = SDEV2MPT(sd); 2769 2770 ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0); 2771 2772 NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d", 2773 (void *)hba_dip, (void *)tgt_dip, lun)); 2774 2775 if (ndi_dev_is_persistent_node(tgt_dip) == 0) { 2776 (void) ndi_merge_node(tgt_dip, mptsas_name_child); 2777 ddi_set_name_addr(tgt_dip, NULL); 2778 return (DDI_FAILURE); 2779 } 2780 /* 2781 * phymask is 0 means the virtual port for RAID 2782 */ 2783 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0, 2784 "phymask", 0); 2785 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) { 2786 if ((pip = (void *)(sd->sd_private)) == NULL) { 2787 /* 2788 * Very bad news if this occurs. Somehow scsi_vhci has 2789 * lost the pathinfo node for this target. 2790 */ 2791 return (DDI_NOT_WELL_FORMED); 2792 } 2793 2794 if (mdi_prop_lookup_int(pip, LUN_PROP, &lun) != 2795 DDI_PROP_SUCCESS) { 2796 mptsas_log(mpt, CE_WARN, "Get lun property failed\n"); 2797 return (DDI_FAILURE); 2798 } 2799 2800 if (mdi_prop_lookup_string(pip, SCSI_ADDR_PROP_TARGET_PORT, 2801 &psas_wwn) == MDI_SUCCESS) { 2802 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) { 2803 sas_wwn = 0; 2804 } 2805 (void) mdi_prop_free(psas_wwn); 2806 } 2807 } else { 2808 lun = ddi_prop_get_int(DDI_DEV_T_ANY, tgt_dip, 2809 DDI_PROP_DONTPASS, LUN_PROP, 0); 2810 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, tgt_dip, 2811 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &psas_wwn) == 2812 DDI_PROP_SUCCESS) { 2813 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) { 2814 sas_wwn = 0; 2815 } 2816 ddi_prop_free(psas_wwn); 2817 } else { 2818 sas_wwn = 0; 2819 } 2820 } 2821 ASSERT((sas_wwn != 0) || (phymask != 0)); 2822 mutex_enter(&mpt->m_mutex); 2823 ptgt = mptsas_hash_search(&mpt->m_active->m_tgttbl, sas_wwn, phymask); 2824 mutex_exit(&mpt->m_mutex); 2825 if (ptgt == NULL) { 2826 mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or " 2827 "gone already! phymask:%x, saswwn %"PRIx64, phymask, 2828 sas_wwn); 2829 return (DDI_FAILURE); 2830 } 2831 if (hba_tran->tran_tgt_private == NULL) { 2832 tgt_private = kmem_zalloc(sizeof (mptsas_tgt_private_t), 2833 KM_SLEEP); 2834 tgt_private->t_lun = lun; 2835 tgt_private->t_private = ptgt; 2836 hba_tran->tran_tgt_private = tgt_private; 2837 } 2838 2839 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) { 2840 return (DDI_SUCCESS); 2841 } 2842 mutex_enter(&mpt->m_mutex); 2843 2844 if (ptgt->m_deviceinfo & 2845 (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 2846 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 2847 uchar_t *inq89 = NULL; 2848 int inq89_len = 0x238; 2849 int reallen = 0; 2850 int rval = 0; 2851 struct sata_id *sid = NULL; 2852 char model[SATA_ID_MODEL_LEN + 1]; 2853 char fw[SATA_ID_FW_LEN + 1]; 2854 char *vid, *pid; 2855 int i; 2856 2857 mutex_exit(&mpt->m_mutex); 2858 /* 2859 * According SCSI/ATA Translation -2 (SAT-2) revision 01a 2860 * chapter 12.4.2 VPD page 89h includes 512 bytes ATA IDENTIFY 2861 * DEVICE data or ATA IDENTIFY PACKET DEVICE data. 2862 */ 2863 inq89 = kmem_zalloc(inq89_len, KM_SLEEP); 2864 rval = mptsas_inquiry(mpt, ptgt, 0, 0x89, 2865 inq89, inq89_len, &reallen, 1); 2866 2867 if (rval != 0) { 2868 if (inq89 != NULL) { 2869 kmem_free(inq89, inq89_len); 2870 } 2871 2872 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 2873 "0x89 for SATA target:%x failed!", ptgt->m_devhdl); 2874 return (DDI_SUCCESS); 2875 } 2876 sid = (void *)(&inq89[60]); 2877 2878 swab(sid->ai_model, model, SATA_ID_MODEL_LEN); 2879 swab(sid->ai_fw, fw, SATA_ID_FW_LEN); 2880 2881 model[SATA_ID_MODEL_LEN] = 0; 2882 fw[SATA_ID_FW_LEN] = 0; 2883 2884 /* 2885 * split model into into vid/pid 2886 */ 2887 for (i = 0, pid = model; i < SATA_ID_MODEL_LEN; i++, pid++) 2888 if ((*pid == ' ') || (*pid == '\t')) 2889 break; 2890 if (i < SATA_ID_MODEL_LEN) { 2891 vid = model; 2892 /* 2893 * terminate vid, establish pid 2894 */ 2895 *pid++ = 0; 2896 } else { 2897 /* 2898 * vid will stay "ATA ", the rule is same 2899 * as sata framework implementation. 2900 */ 2901 vid = NULL; 2902 /* 2903 * model is all pid 2904 */ 2905 pid = model; 2906 } 2907 2908 /* 2909 * override SCSA "inquiry-*" properties 2910 */ 2911 if (vid) 2912 (void) scsi_device_prop_update_inqstring(sd, 2913 INQUIRY_VENDOR_ID, vid, strlen(vid)); 2914 if (pid) 2915 (void) scsi_device_prop_update_inqstring(sd, 2916 INQUIRY_PRODUCT_ID, pid, strlen(pid)); 2917 (void) scsi_device_prop_update_inqstring(sd, 2918 INQUIRY_REVISION_ID, fw, strlen(fw)); 2919 2920 if (inq89 != NULL) { 2921 kmem_free(inq89, inq89_len); 2922 } 2923 } else { 2924 mutex_exit(&mpt->m_mutex); 2925 } 2926 2927 return (DDI_SUCCESS); 2928 } 2929 /* 2930 * tran_tgt_free(9E) - target device instance deallocation 2931 */ 2932 static void 2933 mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 2934 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 2935 { 2936 #ifndef __lock_lint 2937 _NOTE(ARGUNUSED(hba_dip, tgt_dip, hba_tran, sd)) 2938 #endif 2939 2940 mptsas_tgt_private_t *tgt_private = hba_tran->tran_tgt_private; 2941 2942 if (tgt_private != NULL) { 2943 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t)); 2944 hba_tran->tran_tgt_private = NULL; 2945 } 2946 } 2947 2948 /* 2949 * scsi_pkt handling 2950 * 2951 * Visible to the external world via the transport structure. 2952 */ 2953 2954 /* 2955 * Notes: 2956 * - transport the command to the addressed SCSI target/lun device 2957 * - normal operation is to schedule the command to be transported, 2958 * and return TRAN_ACCEPT if this is successful. 2959 * - if NO_INTR, tran_start must poll device for command completion 2960 */ 2961 static int 2962 mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt) 2963 { 2964 #ifndef __lock_lint 2965 _NOTE(ARGUNUSED(ap)) 2966 #endif 2967 mptsas_t *mpt = PKT2MPT(pkt); 2968 mptsas_cmd_t *cmd = PKT2CMD(pkt); 2969 int rval; 2970 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 2971 2972 NDBG1(("mptsas_scsi_start: pkt=0x%p", (void *)pkt)); 2973 ASSERT(ptgt); 2974 if (ptgt == NULL) 2975 return (TRAN_FATAL_ERROR); 2976 2977 /* 2978 * prepare the pkt before taking mutex. 2979 */ 2980 rval = mptsas_prepare_pkt(cmd); 2981 if (rval != TRAN_ACCEPT) { 2982 return (rval); 2983 } 2984 2985 /* 2986 * Send the command to target/lun, however your HBA requires it. 2987 * If busy, return TRAN_BUSY; if there's some other formatting error 2988 * in the packet, return TRAN_BADPKT; otherwise, fall through to the 2989 * return of TRAN_ACCEPT. 2990 * 2991 * Remember that access to shared resources, including the mptsas_t 2992 * data structure and the HBA hardware registers, must be protected 2993 * with mutexes, here and everywhere. 2994 * 2995 * Also remember that at interrupt time, you'll get an argument 2996 * to the interrupt handler which is a pointer to your mptsas_t 2997 * structure; you'll have to remember which commands are outstanding 2998 * and which scsi_pkt is the currently-running command so the 2999 * interrupt handler can refer to the pkt to set completion 3000 * status, call the target driver back through pkt_comp, etc. 3001 */ 3002 3003 mutex_enter(&ptgt->m_tgt_intr_mutex); 3004 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3005 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3006 /* 3007 * commands should be allowed to retry by 3008 * returning TRAN_BUSY to stall the I/O's 3009 * which come from scsi_vhci since the device/ 3010 * path is in unstable state now. 3011 */ 3012 mutex_exit(&ptgt->m_tgt_intr_mutex); 3013 return (TRAN_BUSY); 3014 } else { 3015 /* 3016 * The device is offline, just fail the 3017 * command by returning TRAN_FATAL_ERROR. 3018 */ 3019 mutex_exit(&ptgt->m_tgt_intr_mutex); 3020 return (TRAN_FATAL_ERROR); 3021 } 3022 } 3023 mutex_exit(&ptgt->m_tgt_intr_mutex); 3024 rval = mptsas_accept_pkt(mpt, cmd); 3025 3026 return (rval); 3027 } 3028 3029 static int 3030 mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd) 3031 { 3032 int rval = TRAN_ACCEPT; 3033 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3034 3035 NDBG1(("mptsas_accept_pkt: cmd=0x%p", (void *)cmd)); 3036 3037 if ((cmd->cmd_flags & CFLAG_PREPARED) == 0) { 3038 rval = mptsas_prepare_pkt(cmd); 3039 if (rval != TRAN_ACCEPT) { 3040 cmd->cmd_flags &= ~CFLAG_TRANFLAG; 3041 return (rval); 3042 } 3043 } 3044 3045 /* 3046 * reset the throttle if we were draining 3047 */ 3048 mutex_enter(&ptgt->m_tgt_intr_mutex); 3049 if ((ptgt->m_t_ncmds == 0) && 3050 (ptgt->m_t_throttle == DRAIN_THROTTLE)) { 3051 NDBG23(("reset throttle")); 3052 ASSERT(ptgt->m_reset_delay == 0); 3053 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 3054 } 3055 3056 /* 3057 * If device handle has already been invalidated, just 3058 * fail the command. In theory, command from scsi_vhci 3059 * client is impossible send down command with invalid 3060 * devhdl since devhdl is set after path offline, target 3061 * driver is not suppose to select a offlined path. 3062 */ 3063 if (ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) { 3064 NDBG20(("rejecting command, it might because invalid devhdl " 3065 "request.")); 3066 mutex_exit(&ptgt->m_tgt_intr_mutex); 3067 mutex_enter(&mpt->m_mutex); 3068 /* 3069 * If HBA is being reset, the DevHandles are being 3070 * re-initialized, which means that they could be invalid 3071 * even if the target is still attached. Check if being reset 3072 * and if DevHandle is being re-initialized. If this is the 3073 * case, return BUSY so the I/O can be retried later. 3074 */ 3075 if (mpt->m_in_reset) { 3076 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, 3077 STAT_BUS_RESET); 3078 if (cmd->cmd_flags & CFLAG_TXQ) { 3079 mptsas_doneq_add(mpt, cmd); 3080 mptsas_doneq_empty(mpt); 3081 mutex_exit(&mpt->m_mutex); 3082 return (rval); 3083 } else { 3084 mutex_exit(&mpt->m_mutex); 3085 return (TRAN_BUSY); 3086 } 3087 } 3088 mptsas_set_pkt_reason(mpt, cmd, CMD_DEV_GONE, STAT_TERMINATED); 3089 if (cmd->cmd_flags & CFLAG_TXQ) { 3090 mptsas_doneq_add(mpt, cmd); 3091 mptsas_doneq_empty(mpt); 3092 mutex_exit(&mpt->m_mutex); 3093 return (rval); 3094 } else { 3095 mutex_exit(&mpt->m_mutex); 3096 return (TRAN_FATAL_ERROR); 3097 } 3098 } 3099 mutex_exit(&ptgt->m_tgt_intr_mutex); 3100 /* 3101 * The first case is the normal case. mpt gets a command from the 3102 * target driver and starts it. 3103 * Since SMID 0 is reserved and the TM slot is reserved, the actual max 3104 * commands is m_max_requests - 2. 3105 */ 3106 mutex_enter(&ptgt->m_tgt_intr_mutex); 3107 if ((ptgt->m_t_throttle > HOLD_THROTTLE) && 3108 (ptgt->m_t_ncmds < ptgt->m_t_throttle) && 3109 (ptgt->m_reset_delay == 0) && 3110 (ptgt->m_t_nwait == 0) && 3111 ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0)) { 3112 mutex_exit(&ptgt->m_tgt_intr_mutex); 3113 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 3114 (void) mptsas_start_cmd0(mpt, cmd); 3115 } else { 3116 mutex_enter(&mpt->m_mutex); 3117 mptsas_waitq_add(mpt, cmd); 3118 mutex_exit(&mpt->m_mutex); 3119 } 3120 } else { 3121 /* 3122 * Add this pkt to the work queue 3123 */ 3124 mutex_exit(&ptgt->m_tgt_intr_mutex); 3125 mutex_enter(&mpt->m_mutex); 3126 mptsas_waitq_add(mpt, cmd); 3127 3128 if (cmd->cmd_pkt_flags & FLAG_NOINTR) { 3129 (void) mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME); 3130 3131 /* 3132 * Only flush the doneq if this is not a TM 3133 * cmd. For TM cmds the flushing of the 3134 * doneq will be done in those routines. 3135 */ 3136 if ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) { 3137 mptsas_doneq_empty(mpt); 3138 } 3139 } 3140 mutex_exit(&mpt->m_mutex); 3141 } 3142 return (rval); 3143 } 3144 3145 int 3146 mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 3147 { 3148 mptsas_slots_t *slots; 3149 int slot; 3150 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3151 mptsas_slot_free_e_t *pe; 3152 int qn, qn_first; 3153 3154 slots = mpt->m_active; 3155 3156 /* 3157 * Account for reserved TM request slot and reserved SMID of 0. 3158 */ 3159 ASSERT(slots->m_n_slots == (mpt->m_max_requests - 2)); 3160 3161 qn = qn_first = CPU->cpu_seqid & (mpt->m_slot_freeq_pair_n - 1); 3162 3163 qpair_retry: 3164 ASSERT(qn < mpt->m_slot_freeq_pair_n); 3165 mutex_enter(&mpt->m_slot_freeq_pairp[qn].m_slot_allocq.s.m_fq_mutex); 3166 pe = list_head(&mpt->m_slot_freeq_pairp[qn].m_slot_allocq. 3167 s.m_fq_list); 3168 if (!pe) { /* switch the allocq and releq */ 3169 mutex_enter(&mpt->m_slot_freeq_pairp[qn].m_slot_releq. 3170 s.m_fq_mutex); 3171 if (mpt->m_slot_freeq_pairp[qn].m_slot_releq.s.m_fq_n) { 3172 mpt->m_slot_freeq_pairp[qn]. 3173 m_slot_allocq.s.m_fq_n = 3174 mpt->m_slot_freeq_pairp[qn]. 3175 m_slot_releq.s.m_fq_n; 3176 mpt->m_slot_freeq_pairp[qn]. 3177 m_slot_allocq.s.m_fq_list.list_head.list_next = 3178 mpt->m_slot_freeq_pairp[qn]. 3179 m_slot_releq.s.m_fq_list.list_head.list_next; 3180 mpt->m_slot_freeq_pairp[qn]. 3181 m_slot_allocq.s.m_fq_list.list_head.list_prev = 3182 mpt->m_slot_freeq_pairp[qn]. 3183 m_slot_releq.s.m_fq_list.list_head.list_prev; 3184 mpt->m_slot_freeq_pairp[qn]. 3185 m_slot_releq.s.m_fq_list.list_head.list_prev-> 3186 list_next = 3187 &mpt->m_slot_freeq_pairp[qn]. 3188 m_slot_allocq.s.m_fq_list.list_head; 3189 mpt->m_slot_freeq_pairp[qn]. 3190 m_slot_releq.s.m_fq_list.list_head.list_next-> 3191 list_prev = 3192 &mpt->m_slot_freeq_pairp[qn]. 3193 m_slot_allocq.s.m_fq_list.list_head; 3194 3195 mpt->m_slot_freeq_pairp[qn]. 3196 m_slot_releq.s.m_fq_list.list_head.list_next = 3197 mpt->m_slot_freeq_pairp[qn]. 3198 m_slot_releq.s.m_fq_list.list_head.list_prev = 3199 &mpt->m_slot_freeq_pairp[qn]. 3200 m_slot_releq.s.m_fq_list.list_head; 3201 mpt->m_slot_freeq_pairp[qn]. 3202 m_slot_releq.s.m_fq_n = 0; 3203 } else { 3204 mutex_exit(&mpt->m_slot_freeq_pairp[qn]. 3205 m_slot_releq.s.m_fq_mutex); 3206 mutex_exit(&mpt->m_slot_freeq_pairp[qn]. 3207 m_slot_allocq.s.m_fq_mutex); 3208 qn = (qn + 1) & (mpt->m_slot_freeq_pair_n - 1); 3209 if (qn == qn_first) 3210 return (FALSE); 3211 else 3212 goto qpair_retry; 3213 } 3214 mutex_exit(&mpt->m_slot_freeq_pairp[qn]. 3215 m_slot_releq.s.m_fq_mutex); 3216 pe = list_head(&mpt->m_slot_freeq_pairp[qn]. 3217 m_slot_allocq.s.m_fq_list); 3218 ASSERT(pe); 3219 } 3220 list_remove(&mpt->m_slot_freeq_pairp[qn]. 3221 m_slot_allocq.s.m_fq_list, pe); 3222 slot = pe->slot; 3223 /* 3224 * Make sure SMID is not using reserved value of 0 3225 * and the TM request slot. 3226 */ 3227 ASSERT((slot > 0) && (slot <= slots->m_n_slots) && 3228 mpt->m_slot_freeq_pairp[qn].m_slot_allocq.s.m_fq_n > 0); 3229 cmd->cmd_slot = slot; 3230 mpt->m_slot_freeq_pairp[qn].m_slot_allocq.s.m_fq_n--; 3231 ASSERT(mpt->m_slot_freeq_pairp[qn].m_slot_allocq.s.m_fq_n >= 0); 3232 3233 mutex_exit(&mpt->m_slot_freeq_pairp[qn].m_slot_allocq.s.m_fq_mutex); 3234 /* 3235 * only increment per target ncmds if this is not a 3236 * command that has no target associated with it (i.e. a 3237 * event acknoledgment) 3238 */ 3239 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 3240 mutex_enter(&ptgt->m_tgt_intr_mutex); 3241 ptgt->m_t_ncmds++; 3242 mutex_exit(&ptgt->m_tgt_intr_mutex); 3243 } 3244 cmd->cmd_active_timeout = cmd->cmd_pkt->pkt_time; 3245 3246 /* 3247 * If initial timout is less than or equal to one tick, bump 3248 * the timeout by a tick so that command doesn't timeout before 3249 * its allotted time. 3250 */ 3251 if (cmd->cmd_active_timeout <= mptsas_scsi_watchdog_tick) { 3252 cmd->cmd_active_timeout += mptsas_scsi_watchdog_tick; 3253 } 3254 return (TRUE); 3255 } 3256 3257 /* 3258 * prepare the pkt: 3259 * the pkt may have been resubmitted or just reused so 3260 * initialize some fields and do some checks. 3261 */ 3262 static int 3263 mptsas_prepare_pkt(mptsas_cmd_t *cmd) 3264 { 3265 struct scsi_pkt *pkt = CMD2PKT(cmd); 3266 3267 NDBG1(("mptsas_prepare_pkt: cmd=0x%p", (void *)cmd)); 3268 3269 /* 3270 * Reinitialize some fields that need it; the packet may 3271 * have been resubmitted 3272 */ 3273 pkt->pkt_reason = CMD_CMPLT; 3274 pkt->pkt_state = 0; 3275 pkt->pkt_statistics = 0; 3276 pkt->pkt_resid = 0; 3277 cmd->cmd_age = 0; 3278 cmd->cmd_pkt_flags = pkt->pkt_flags; 3279 3280 /* 3281 * zero status byte. 3282 */ 3283 *(pkt->pkt_scbp) = 0; 3284 3285 if (cmd->cmd_flags & CFLAG_DMAVALID) { 3286 pkt->pkt_resid = cmd->cmd_dmacount; 3287 3288 /* 3289 * consistent packets need to be sync'ed first 3290 * (only for data going out) 3291 */ 3292 if ((cmd->cmd_flags & CFLAG_CMDIOPB) && 3293 (cmd->cmd_flags & CFLAG_DMASEND)) { 3294 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 3295 DDI_DMA_SYNC_FORDEV); 3296 } 3297 } 3298 3299 cmd->cmd_flags = 3300 (cmd->cmd_flags & ~(CFLAG_TRANFLAG)) | 3301 CFLAG_PREPARED | CFLAG_IN_TRANSPORT; 3302 3303 return (TRAN_ACCEPT); 3304 } 3305 3306 /* 3307 * tran_init_pkt(9E) - allocate scsi_pkt(9S) for command 3308 * 3309 * One of three possibilities: 3310 * - allocate scsi_pkt 3311 * - allocate scsi_pkt and DMA resources 3312 * - allocate DMA resources to an already-allocated pkt 3313 */ 3314 static struct scsi_pkt * 3315 mptsas_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt, 3316 struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags, 3317 int (*callback)(), caddr_t arg) 3318 { 3319 mptsas_cmd_t *cmd, *new_cmd; 3320 mptsas_t *mpt = ADDR2MPT(ap); 3321 int failure = 1; 3322 #ifndef __sparc 3323 uint_t oldcookiec; 3324 #endif /* __sparc */ 3325 mptsas_target_t *ptgt = NULL; 3326 int rval; 3327 mptsas_tgt_private_t *tgt_private; 3328 int kf; 3329 3330 kf = (callback == SLEEP_FUNC)? KM_SLEEP: KM_NOSLEEP; 3331 3332 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran-> 3333 tran_tgt_private; 3334 ASSERT(tgt_private != NULL); 3335 if (tgt_private == NULL) { 3336 return (NULL); 3337 } 3338 ptgt = tgt_private->t_private; 3339 ASSERT(ptgt != NULL); 3340 if (ptgt == NULL) 3341 return (NULL); 3342 ap->a_target = ptgt->m_devhdl; 3343 ap->a_lun = tgt_private->t_lun; 3344 3345 ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC); 3346 #ifdef MPTSAS_TEST_EXTRN_ALLOC 3347 statuslen *= 100; tgtlen *= 4; 3348 #endif 3349 NDBG3(("mptsas_scsi_init_pkt:\n" 3350 "\ttgt=%d in=0x%p bp=0x%p clen=%d slen=%d tlen=%d flags=%x", 3351 ap->a_target, (void *)pkt, (void *)bp, 3352 cmdlen, statuslen, tgtlen, flags)); 3353 3354 /* 3355 * Allocate the new packet. 3356 */ 3357 if (pkt == NULL) { 3358 ddi_dma_handle_t save_dma_handle; 3359 ddi_dma_handle_t save_arq_dma_handle; 3360 struct buf *save_arq_bp; 3361 ddi_dma_cookie_t save_arqcookie; 3362 #ifdef __sparc 3363 mptti_t *save_sg; 3364 #endif /* __sparc */ 3365 3366 cmd = kmem_cache_alloc(mpt->m_kmem_cache, kf); 3367 3368 if (cmd) { 3369 save_dma_handle = cmd->cmd_dmahandle; 3370 save_arq_dma_handle = cmd->cmd_arqhandle; 3371 save_arq_bp = cmd->cmd_arq_buf; 3372 save_arqcookie = cmd->cmd_arqcookie; 3373 #ifdef __sparc 3374 save_sg = cmd->cmd_sg; 3375 #endif /* __sparc */ 3376 bzero(cmd, sizeof (*cmd) + scsi_pkt_size()); 3377 cmd->cmd_dmahandle = save_dma_handle; 3378 cmd->cmd_arqhandle = save_arq_dma_handle; 3379 cmd->cmd_arq_buf = save_arq_bp; 3380 cmd->cmd_arqcookie = save_arqcookie; 3381 #ifdef __sparc 3382 cmd->cmd_sg = save_sg; 3383 #endif /* __sparc */ 3384 pkt = (void *)((uchar_t *)cmd + 3385 sizeof (struct mptsas_cmd)); 3386 pkt->pkt_ha_private = (opaque_t)cmd; 3387 pkt->pkt_address = *ap; 3388 pkt->pkt_private = (opaque_t)cmd->cmd_pkt_private; 3389 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; 3390 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb; 3391 cmd->cmd_pkt = (struct scsi_pkt *)pkt; 3392 cmd->cmd_cdblen = (uchar_t)cmdlen; 3393 cmd->cmd_scblen = statuslen; 3394 cmd->cmd_rqslen = SENSE_LENGTH; 3395 cmd->cmd_tgt_addr = ptgt; 3396 failure = 0; 3397 } 3398 3399 if (failure || (cmdlen > sizeof (cmd->cmd_cdb)) || 3400 (tgtlen > PKT_PRIV_LEN) || 3401 (statuslen > EXTCMDS_STATUS_SIZE)) { 3402 if (failure == 0) { 3403 /* 3404 * if extern alloc fails, all will be 3405 * deallocated, including cmd 3406 */ 3407 failure = mptsas_pkt_alloc_extern(mpt, cmd, 3408 cmdlen, tgtlen, statuslen, kf); 3409 } 3410 if (failure) { 3411 /* 3412 * if extern allocation fails, it will 3413 * deallocate the new pkt as well 3414 */ 3415 return (NULL); 3416 } 3417 } 3418 new_cmd = cmd; 3419 3420 } else { 3421 cmd = PKT2CMD(pkt); 3422 new_cmd = NULL; 3423 } 3424 3425 3426 #ifndef __sparc 3427 /* grab cmd->cmd_cookiec here as oldcookiec */ 3428 3429 oldcookiec = cmd->cmd_cookiec; 3430 #endif /* __sparc */ 3431 3432 /* 3433 * If the dma was broken up into PARTIAL transfers cmd_nwin will be 3434 * greater than 0 and we'll need to grab the next dma window 3435 */ 3436 /* 3437 * SLM-not doing extra command frame right now; may add later 3438 */ 3439 3440 if (cmd->cmd_nwin > 0) { 3441 3442 /* 3443 * Make sure we havn't gone past the the total number 3444 * of windows 3445 */ 3446 if (++cmd->cmd_winindex >= cmd->cmd_nwin) { 3447 return (NULL); 3448 } 3449 if (ddi_dma_getwin(cmd->cmd_dmahandle, cmd->cmd_winindex, 3450 &cmd->cmd_dma_offset, &cmd->cmd_dma_len, 3451 &cmd->cmd_cookie, &cmd->cmd_cookiec) == DDI_FAILURE) { 3452 return (NULL); 3453 } 3454 goto get_dma_cookies; 3455 } 3456 3457 3458 if (flags & PKT_XARQ) { 3459 cmd->cmd_flags |= CFLAG_XARQ; 3460 } 3461 3462 /* 3463 * DMA resource allocation. This version assumes your 3464 * HBA has some sort of bus-mastering or onboard DMA capability, with a 3465 * scatter-gather list of length MPTSAS_MAX_DMA_SEGS, as given in the 3466 * ddi_dma_attr_t structure and passed to scsi_impl_dmaget. 3467 */ 3468 if (bp && (bp->b_bcount != 0) && 3469 (cmd->cmd_flags & CFLAG_DMAVALID) == 0) { 3470 3471 int cnt, dma_flags; 3472 mptti_t *dmap; /* ptr to the S/G list */ 3473 3474 /* 3475 * Set up DMA memory and position to the next DMA segment. 3476 */ 3477 ASSERT(cmd->cmd_dmahandle != NULL); 3478 3479 if (bp->b_flags & B_READ) { 3480 dma_flags = DDI_DMA_READ; 3481 cmd->cmd_flags &= ~CFLAG_DMASEND; 3482 } else { 3483 dma_flags = DDI_DMA_WRITE; 3484 cmd->cmd_flags |= CFLAG_DMASEND; 3485 } 3486 if (flags & PKT_CONSISTENT) { 3487 cmd->cmd_flags |= CFLAG_CMDIOPB; 3488 dma_flags |= DDI_DMA_CONSISTENT; 3489 } 3490 3491 if (flags & PKT_DMA_PARTIAL) { 3492 dma_flags |= DDI_DMA_PARTIAL; 3493 } 3494 3495 /* 3496 * workaround for byte hole issue on psycho and 3497 * schizo pre 2.1 3498 */ 3499 if ((bp->b_flags & B_READ) && ((bp->b_flags & 3500 (B_PAGEIO|B_REMAPPED)) != B_PAGEIO) && 3501 ((uintptr_t)bp->b_un.b_addr & 0x7)) { 3502 dma_flags |= DDI_DMA_CONSISTENT; 3503 } 3504 3505 rval = ddi_dma_buf_bind_handle(cmd->cmd_dmahandle, bp, 3506 dma_flags, callback, arg, 3507 &cmd->cmd_cookie, &cmd->cmd_cookiec); 3508 if (rval == DDI_DMA_PARTIAL_MAP) { 3509 (void) ddi_dma_numwin(cmd->cmd_dmahandle, 3510 &cmd->cmd_nwin); 3511 cmd->cmd_winindex = 0; 3512 (void) ddi_dma_getwin(cmd->cmd_dmahandle, 3513 cmd->cmd_winindex, &cmd->cmd_dma_offset, 3514 &cmd->cmd_dma_len, &cmd->cmd_cookie, 3515 &cmd->cmd_cookiec); 3516 } else if (rval && (rval != DDI_DMA_MAPPED)) { 3517 switch (rval) { 3518 case DDI_DMA_NORESOURCES: 3519 bioerror(bp, 0); 3520 break; 3521 case DDI_DMA_BADATTR: 3522 case DDI_DMA_NOMAPPING: 3523 bioerror(bp, EFAULT); 3524 break; 3525 case DDI_DMA_TOOBIG: 3526 default: 3527 bioerror(bp, EINVAL); 3528 break; 3529 } 3530 cmd->cmd_flags &= ~CFLAG_DMAVALID; 3531 if (new_cmd) { 3532 mptsas_scsi_destroy_pkt(ap, pkt); 3533 } 3534 return ((struct scsi_pkt *)NULL); 3535 } 3536 3537 get_dma_cookies: 3538 cmd->cmd_flags |= CFLAG_DMAVALID; 3539 ASSERT(cmd->cmd_cookiec > 0); 3540 3541 if (cmd->cmd_cookiec > MPTSAS_MAX_CMD_SEGS) { 3542 mptsas_log(mpt, CE_NOTE, "large cookiec received %d\n", 3543 cmd->cmd_cookiec); 3544 bioerror(bp, EINVAL); 3545 if (new_cmd) { 3546 mptsas_scsi_destroy_pkt(ap, pkt); 3547 } 3548 return ((struct scsi_pkt *)NULL); 3549 } 3550 3551 /* 3552 * Allocate extra SGL buffer if needed. 3553 */ 3554 if ((cmd->cmd_cookiec > MPTSAS_MAX_FRAME_SGES64(mpt)) && 3555 (cmd->cmd_extra_frames == NULL)) { 3556 if (mptsas_alloc_extra_sgl_frame(mpt, cmd) == 3557 DDI_FAILURE) { 3558 mptsas_log(mpt, CE_WARN, "MPT SGL mem alloc " 3559 "failed"); 3560 bioerror(bp, ENOMEM); 3561 if (new_cmd) { 3562 mptsas_scsi_destroy_pkt(ap, pkt); 3563 } 3564 return ((struct scsi_pkt *)NULL); 3565 } 3566 } 3567 3568 /* 3569 * Always use scatter-gather transfer 3570 * Use the loop below to store physical addresses of 3571 * DMA segments, from the DMA cookies, into your HBA's 3572 * scatter-gather list. 3573 * We need to ensure we have enough kmem alloc'd 3574 * for the sg entries since we are no longer using an 3575 * array inside mptsas_cmd_t. 3576 * 3577 * We check cmd->cmd_cookiec against oldcookiec so 3578 * the scatter-gather list is correctly allocated 3579 */ 3580 #ifndef __sparc 3581 if (oldcookiec != cmd->cmd_cookiec) { 3582 if (cmd->cmd_sg != (mptti_t *)NULL) { 3583 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * 3584 oldcookiec); 3585 cmd->cmd_sg = NULL; 3586 } 3587 } 3588 3589 if (cmd->cmd_sg == (mptti_t *)NULL) { 3590 cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)* 3591 cmd->cmd_cookiec), kf); 3592 3593 if (cmd->cmd_sg == (mptti_t *)NULL) { 3594 mptsas_log(mpt, CE_WARN, 3595 "unable to kmem_alloc enough memory " 3596 "for scatter/gather list"); 3597 /* 3598 * if we have an ENOMEM condition we need to behave 3599 * the same way as the rest of this routine 3600 */ 3601 3602 bioerror(bp, ENOMEM); 3603 if (new_cmd) { 3604 mptsas_scsi_destroy_pkt(ap, pkt); 3605 } 3606 return ((struct scsi_pkt *)NULL); 3607 } 3608 } 3609 #endif /* __sparc */ 3610 dmap = cmd->cmd_sg; 3611 3612 ASSERT(cmd->cmd_cookie.dmac_size != 0); 3613 3614 /* 3615 * store the first segment into the S/G list 3616 */ 3617 dmap->count = cmd->cmd_cookie.dmac_size; 3618 dmap->addr.address64.Low = (uint32_t) 3619 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull); 3620 dmap->addr.address64.High = (uint32_t) 3621 (cmd->cmd_cookie.dmac_laddress >> 32); 3622 3623 /* 3624 * dmacount counts the size of the dma for this window 3625 * (if partial dma is being used). totaldmacount 3626 * keeps track of the total amount of dma we have 3627 * transferred for all the windows (needed to calculate 3628 * the resid value below). 3629 */ 3630 cmd->cmd_dmacount = cmd->cmd_cookie.dmac_size; 3631 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size; 3632 3633 /* 3634 * We already stored the first DMA scatter gather segment, 3635 * start at 1 if we need to store more. 3636 */ 3637 for (cnt = 1; cnt < cmd->cmd_cookiec; cnt++) { 3638 /* 3639 * Get next DMA cookie 3640 */ 3641 ddi_dma_nextcookie(cmd->cmd_dmahandle, 3642 &cmd->cmd_cookie); 3643 dmap++; 3644 3645 cmd->cmd_dmacount += cmd->cmd_cookie.dmac_size; 3646 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size; 3647 3648 /* 3649 * store the segment parms into the S/G list 3650 */ 3651 dmap->count = cmd->cmd_cookie.dmac_size; 3652 dmap->addr.address64.Low = (uint32_t) 3653 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull); 3654 dmap->addr.address64.High = (uint32_t) 3655 (cmd->cmd_cookie.dmac_laddress >> 32); 3656 } 3657 3658 /* 3659 * If this was partially allocated we set the resid 3660 * the amount of data NOT transferred in this window 3661 * If there is only one window, the resid will be 0 3662 */ 3663 pkt->pkt_resid = (bp->b_bcount - cmd->cmd_totaldmacount); 3664 NDBG16(("mptsas_dmaget: cmd_dmacount=%d.", cmd->cmd_dmacount)); 3665 } 3666 return (pkt); 3667 } 3668 3669 /* 3670 * tran_destroy_pkt(9E) - scsi_pkt(9s) deallocation 3671 * 3672 * Notes: 3673 * - also frees DMA resources if allocated 3674 * - implicit DMA synchonization 3675 */ 3676 static void 3677 mptsas_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 3678 { 3679 mptsas_cmd_t *cmd = PKT2CMD(pkt); 3680 mptsas_t *mpt = ADDR2MPT(ap); 3681 3682 NDBG3(("mptsas_scsi_destroy_pkt: target=%d pkt=0x%p", 3683 ap->a_target, (void *)pkt)); 3684 3685 if (cmd->cmd_flags & CFLAG_DMAVALID) { 3686 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle); 3687 cmd->cmd_flags &= ~CFLAG_DMAVALID; 3688 } 3689 #ifndef __sparc 3690 if (cmd->cmd_sg) { 3691 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * cmd->cmd_cookiec); 3692 cmd->cmd_sg = NULL; 3693 } 3694 #endif /* __sparc */ 3695 mptsas_free_extra_sgl_frame(mpt, cmd); 3696 3697 if ((cmd->cmd_flags & 3698 (CFLAG_FREE | CFLAG_CDBEXTERN | CFLAG_PRIVEXTERN | 3699 CFLAG_SCBEXTERN)) == 0) { 3700 cmd->cmd_flags = CFLAG_FREE; 3701 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd); 3702 } else { 3703 mptsas_pkt_destroy_extern(mpt, cmd); 3704 } 3705 } 3706 3707 /* 3708 * kmem cache constructor and destructor: 3709 * When constructing, we bzero the cmd and allocate the dma handle 3710 * When destructing, just free the dma handle 3711 */ 3712 static int 3713 mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags) 3714 { 3715 mptsas_cmd_t *cmd = buf; 3716 mptsas_t *mpt = cdrarg; 3717 struct scsi_address ap; 3718 uint_t cookiec; 3719 ddi_dma_attr_t arq_dma_attr; 3720 int (*callback)(caddr_t); 3721 3722 callback = (kmflags == KM_SLEEP)? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT; 3723 3724 NDBG4(("mptsas_kmem_cache_constructor")); 3725 3726 ap.a_hba_tran = mpt->m_tran; 3727 ap.a_target = 0; 3728 ap.a_lun = 0; 3729 3730 /* 3731 * allocate a dma handle 3732 */ 3733 if ((ddi_dma_alloc_handle(mpt->m_dip, &mpt->m_io_dma_attr, callback, 3734 NULL, &cmd->cmd_dmahandle)) != DDI_SUCCESS) { 3735 cmd->cmd_dmahandle = NULL; 3736 return (-1); 3737 } 3738 3739 cmd->cmd_arq_buf = scsi_alloc_consistent_buf(&ap, (struct buf *)NULL, 3740 SENSE_LENGTH, B_READ, callback, NULL); 3741 if (cmd->cmd_arq_buf == NULL) { 3742 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3743 cmd->cmd_dmahandle = NULL; 3744 return (-1); 3745 } 3746 3747 /* 3748 * allocate a arq handle 3749 */ 3750 arq_dma_attr = mpt->m_msg_dma_attr; 3751 arq_dma_attr.dma_attr_sgllen = 1; 3752 if ((ddi_dma_alloc_handle(mpt->m_dip, &arq_dma_attr, callback, 3753 NULL, &cmd->cmd_arqhandle)) != DDI_SUCCESS) { 3754 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3755 scsi_free_consistent_buf(cmd->cmd_arq_buf); 3756 cmd->cmd_dmahandle = NULL; 3757 cmd->cmd_arqhandle = NULL; 3758 return (-1); 3759 } 3760 3761 if (ddi_dma_buf_bind_handle(cmd->cmd_arqhandle, 3762 cmd->cmd_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT), 3763 callback, NULL, &cmd->cmd_arqcookie, &cookiec) != DDI_SUCCESS) { 3764 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3765 ddi_dma_free_handle(&cmd->cmd_arqhandle); 3766 scsi_free_consistent_buf(cmd->cmd_arq_buf); 3767 cmd->cmd_dmahandle = NULL; 3768 cmd->cmd_arqhandle = NULL; 3769 cmd->cmd_arq_buf = NULL; 3770 return (-1); 3771 } 3772 /* 3773 * In sparc, the sgl length in most of the cases would be 1, so we 3774 * pre-allocate it in cache. On x86, the max number would be 256, 3775 * pre-allocate a maximum would waste a lot of memory especially 3776 * when many cmds are put onto waitq. 3777 */ 3778 #ifdef __sparc 3779 cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)* 3780 MPTSAS_MAX_CMD_SEGS), KM_SLEEP); 3781 #endif /* __sparc */ 3782 3783 return (0); 3784 } 3785 3786 static void 3787 mptsas_kmem_cache_destructor(void *buf, void *cdrarg) 3788 { 3789 #ifndef __lock_lint 3790 _NOTE(ARGUNUSED(cdrarg)) 3791 #endif 3792 mptsas_cmd_t *cmd = buf; 3793 3794 NDBG4(("mptsas_kmem_cache_destructor")); 3795 3796 if (cmd->cmd_arqhandle) { 3797 (void) ddi_dma_unbind_handle(cmd->cmd_arqhandle); 3798 ddi_dma_free_handle(&cmd->cmd_arqhandle); 3799 cmd->cmd_arqhandle = NULL; 3800 } 3801 if (cmd->cmd_arq_buf) { 3802 scsi_free_consistent_buf(cmd->cmd_arq_buf); 3803 cmd->cmd_arq_buf = NULL; 3804 } 3805 if (cmd->cmd_dmahandle) { 3806 ddi_dma_free_handle(&cmd->cmd_dmahandle); 3807 cmd->cmd_dmahandle = NULL; 3808 } 3809 #ifdef __sparc 3810 if (cmd->cmd_sg) { 3811 kmem_free(cmd->cmd_sg, sizeof (mptti_t)* MPTSAS_MAX_CMD_SEGS); 3812 cmd->cmd_sg = NULL; 3813 } 3814 #endif /* __sparc */ 3815 } 3816 3817 static int 3818 mptsas_cache_frames_constructor(void *buf, void *cdrarg, int kmflags) 3819 { 3820 mptsas_cache_frames_t *p = buf; 3821 mptsas_t *mpt = cdrarg; 3822 ddi_dma_attr_t frame_dma_attr; 3823 size_t mem_size, alloc_len; 3824 ddi_dma_cookie_t cookie; 3825 uint_t ncookie; 3826 int (*callback)(caddr_t) = (kmflags == KM_SLEEP) 3827 ? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT; 3828 3829 frame_dma_attr = mpt->m_msg_dma_attr; 3830 frame_dma_attr.dma_attr_align = 0x10; 3831 frame_dma_attr.dma_attr_sgllen = 1; 3832 3833 if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attr, callback, NULL, 3834 &p->m_dma_hdl) != DDI_SUCCESS) { 3835 mptsas_log(mpt, CE_WARN, "Unable to allocate dma handle for" 3836 " extra SGL."); 3837 return (DDI_FAILURE); 3838 } 3839 3840 mem_size = (mpt->m_max_request_frames - 1) * mpt->m_req_frame_size; 3841 3842 if (ddi_dma_mem_alloc(p->m_dma_hdl, mem_size, &mpt->m_dev_acc_attr, 3843 DDI_DMA_CONSISTENT, callback, NULL, (caddr_t *)&p->m_frames_addr, 3844 &alloc_len, &p->m_acc_hdl) != DDI_SUCCESS) { 3845 ddi_dma_free_handle(&p->m_dma_hdl); 3846 p->m_dma_hdl = NULL; 3847 mptsas_log(mpt, CE_WARN, "Unable to allocate dma memory for" 3848 " extra SGL."); 3849 return (DDI_FAILURE); 3850 } 3851 3852 if (ddi_dma_addr_bind_handle(p->m_dma_hdl, NULL, p->m_frames_addr, 3853 alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, callback, NULL, 3854 &cookie, &ncookie) != DDI_DMA_MAPPED) { 3855 (void) ddi_dma_mem_free(&p->m_acc_hdl); 3856 ddi_dma_free_handle(&p->m_dma_hdl); 3857 p->m_dma_hdl = NULL; 3858 mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources for" 3859 " extra SGL"); 3860 return (DDI_FAILURE); 3861 } 3862 3863 /* 3864 * Store the SGL memory address. This chip uses this 3865 * address to dma to and from the driver. The second 3866 * address is the address mpt uses to fill in the SGL. 3867 */ 3868 p->m_phys_addr = cookie.dmac_address; 3869 3870 return (DDI_SUCCESS); 3871 } 3872 3873 static void 3874 mptsas_cache_frames_destructor(void *buf, void *cdrarg) 3875 { 3876 #ifndef __lock_lint 3877 _NOTE(ARGUNUSED(cdrarg)) 3878 #endif 3879 mptsas_cache_frames_t *p = buf; 3880 if (p->m_dma_hdl != NULL) { 3881 (void) ddi_dma_unbind_handle(p->m_dma_hdl); 3882 (void) ddi_dma_mem_free(&p->m_acc_hdl); 3883 ddi_dma_free_handle(&p->m_dma_hdl); 3884 p->m_phys_addr = NULL; 3885 p->m_frames_addr = NULL; 3886 p->m_dma_hdl = NULL; 3887 p->m_acc_hdl = NULL; 3888 } 3889 3890 } 3891 3892 /* 3893 * allocate and deallocate external pkt space (ie. not part of mptsas_cmd) 3894 * for non-standard length cdb, pkt_private, status areas 3895 * if allocation fails, then deallocate all external space and the pkt 3896 */ 3897 /* ARGSUSED */ 3898 static int 3899 mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd, 3900 int cmdlen, int tgtlen, int statuslen, int kf) 3901 { 3902 caddr_t cdbp, scbp, tgt; 3903 int (*callback)(caddr_t) = (kf == KM_SLEEP) ? 3904 DDI_DMA_SLEEP : DDI_DMA_DONTWAIT; 3905 struct scsi_address ap; 3906 size_t senselength; 3907 ddi_dma_attr_t ext_arq_dma_attr; 3908 uint_t cookiec; 3909 3910 NDBG3(("mptsas_pkt_alloc_extern: " 3911 "cmd=0x%p cmdlen=%d tgtlen=%d statuslen=%d kf=%x", 3912 (void *)cmd, cmdlen, tgtlen, statuslen, kf)); 3913 3914 tgt = cdbp = scbp = NULL; 3915 cmd->cmd_scblen = statuslen; 3916 cmd->cmd_privlen = (uchar_t)tgtlen; 3917 3918 if (cmdlen > sizeof (cmd->cmd_cdb)) { 3919 if ((cdbp = kmem_zalloc((size_t)cmdlen, kf)) == NULL) { 3920 goto fail; 3921 } 3922 cmd->cmd_pkt->pkt_cdbp = (opaque_t)cdbp; 3923 cmd->cmd_flags |= CFLAG_CDBEXTERN; 3924 } 3925 if (tgtlen > PKT_PRIV_LEN) { 3926 if ((tgt = kmem_zalloc((size_t)tgtlen, kf)) == NULL) { 3927 goto fail; 3928 } 3929 cmd->cmd_flags |= CFLAG_PRIVEXTERN; 3930 cmd->cmd_pkt->pkt_private = tgt; 3931 } 3932 if (statuslen > EXTCMDS_STATUS_SIZE) { 3933 if ((scbp = kmem_zalloc((size_t)statuslen, kf)) == NULL) { 3934 goto fail; 3935 } 3936 cmd->cmd_flags |= CFLAG_SCBEXTERN; 3937 cmd->cmd_pkt->pkt_scbp = (opaque_t)scbp; 3938 3939 /* allocate sense data buf for DMA */ 3940 3941 senselength = statuslen - MPTSAS_GET_ITEM_OFF( 3942 struct scsi_arq_status, sts_sensedata); 3943 cmd->cmd_rqslen = (uchar_t)senselength; 3944 3945 ap.a_hba_tran = mpt->m_tran; 3946 ap.a_target = 0; 3947 ap.a_lun = 0; 3948 3949 cmd->cmd_ext_arq_buf = scsi_alloc_consistent_buf(&ap, 3950 (struct buf *)NULL, senselength, B_READ, 3951 callback, NULL); 3952 3953 if (cmd->cmd_ext_arq_buf == NULL) { 3954 goto fail; 3955 } 3956 /* 3957 * allocate a extern arq handle and bind the buf 3958 */ 3959 ext_arq_dma_attr = mpt->m_msg_dma_attr; 3960 ext_arq_dma_attr.dma_attr_sgllen = 1; 3961 if ((ddi_dma_alloc_handle(mpt->m_dip, 3962 &ext_arq_dma_attr, callback, 3963 NULL, &cmd->cmd_ext_arqhandle)) != DDI_SUCCESS) { 3964 goto fail; 3965 } 3966 3967 if (ddi_dma_buf_bind_handle(cmd->cmd_ext_arqhandle, 3968 cmd->cmd_ext_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT), 3969 callback, NULL, &cmd->cmd_ext_arqcookie, 3970 &cookiec) 3971 != DDI_SUCCESS) { 3972 goto fail; 3973 } 3974 cmd->cmd_flags |= CFLAG_EXTARQBUFVALID; 3975 } 3976 return (0); 3977 fail: 3978 mptsas_pkt_destroy_extern(mpt, cmd); 3979 return (1); 3980 } 3981 3982 /* 3983 * deallocate external pkt space and deallocate the pkt 3984 */ 3985 static void 3986 mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd) 3987 { 3988 NDBG3(("mptsas_pkt_destroy_extern: cmd=0x%p", (void *)cmd)); 3989 3990 if (cmd->cmd_flags & CFLAG_FREE) { 3991 mptsas_log(mpt, CE_PANIC, 3992 "mptsas_pkt_destroy_extern: freeing free packet"); 3993 _NOTE(NOT_REACHED) 3994 /* NOTREACHED */ 3995 } 3996 if (cmd->cmd_flags & CFLAG_CDBEXTERN) { 3997 kmem_free(cmd->cmd_pkt->pkt_cdbp, (size_t)cmd->cmd_cdblen); 3998 } 3999 if (cmd->cmd_flags & CFLAG_SCBEXTERN) { 4000 kmem_free(cmd->cmd_pkt->pkt_scbp, (size_t)cmd->cmd_scblen); 4001 if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) { 4002 (void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle); 4003 } 4004 if (cmd->cmd_ext_arqhandle) { 4005 ddi_dma_free_handle(&cmd->cmd_ext_arqhandle); 4006 cmd->cmd_ext_arqhandle = NULL; 4007 } 4008 if (cmd->cmd_ext_arq_buf) 4009 scsi_free_consistent_buf(cmd->cmd_ext_arq_buf); 4010 } 4011 if (cmd->cmd_flags & CFLAG_PRIVEXTERN) { 4012 kmem_free(cmd->cmd_pkt->pkt_private, (size_t)cmd->cmd_privlen); 4013 } 4014 cmd->cmd_flags = CFLAG_FREE; 4015 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd); 4016 } 4017 4018 /* 4019 * tran_sync_pkt(9E) - explicit DMA synchronization 4020 */ 4021 /*ARGSUSED*/ 4022 static void 4023 mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 4024 { 4025 mptsas_cmd_t *cmd = PKT2CMD(pkt); 4026 4027 NDBG3(("mptsas_scsi_sync_pkt: target=%d, pkt=0x%p", 4028 ap->a_target, (void *)pkt)); 4029 4030 if (cmd->cmd_dmahandle) { 4031 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 4032 (cmd->cmd_flags & CFLAG_DMASEND) ? 4033 DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU); 4034 } 4035 } 4036 4037 /* 4038 * tran_dmafree(9E) - deallocate DMA resources allocated for command 4039 */ 4040 /*ARGSUSED*/ 4041 static void 4042 mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt) 4043 { 4044 mptsas_cmd_t *cmd = PKT2CMD(pkt); 4045 mptsas_t *mpt = ADDR2MPT(ap); 4046 4047 NDBG3(("mptsas_scsi_dmafree: target=%d pkt=0x%p", 4048 ap->a_target, (void *)pkt)); 4049 4050 if (cmd->cmd_flags & CFLAG_DMAVALID) { 4051 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle); 4052 cmd->cmd_flags &= ~CFLAG_DMAVALID; 4053 } 4054 4055 if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) { 4056 (void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle); 4057 cmd->cmd_flags &= ~CFLAG_EXTARQBUFVALID; 4058 } 4059 4060 mptsas_free_extra_sgl_frame(mpt, cmd); 4061 } 4062 4063 static void 4064 mptsas_pkt_comp(struct scsi_pkt *pkt, mptsas_cmd_t *cmd) 4065 { 4066 if ((cmd->cmd_flags & CFLAG_CMDIOPB) && 4067 (!(cmd->cmd_flags & CFLAG_DMASEND))) { 4068 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 4069 DDI_DMA_SYNC_FORCPU); 4070 } 4071 (*pkt->pkt_comp)(pkt); 4072 } 4073 4074 static void 4075 mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, uint32_t *control, 4076 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl) 4077 { 4078 uint_t cookiec; 4079 mptti_t *dmap; 4080 uint32_t flags; 4081 pMpi2SGESimple64_t sge; 4082 pMpi2SGEChain64_t sgechain; 4083 ASSERT(cmd->cmd_flags & CFLAG_DMAVALID); 4084 4085 /* 4086 * Save the number of entries in the DMA 4087 * Scatter/Gather list 4088 */ 4089 cookiec = cmd->cmd_cookiec; 4090 4091 NDBG1(("mptsas_sge_setup: cookiec=%d", cookiec)); 4092 4093 /* 4094 * Set read/write bit in control. 4095 */ 4096 if (cmd->cmd_flags & CFLAG_DMASEND) { 4097 *control |= MPI2_SCSIIO_CONTROL_WRITE; 4098 } else { 4099 *control |= MPI2_SCSIIO_CONTROL_READ; 4100 } 4101 4102 ddi_put32(acc_hdl, &frame->DataLength, cmd->cmd_dmacount); 4103 4104 /* 4105 * We have 2 cases here. First where we can fit all the 4106 * SG elements into the main frame, and the case 4107 * where we can't. 4108 * If we have more cookies than we can attach to a frame 4109 * we will need to use a chain element to point 4110 * a location of memory where the rest of the S/G 4111 * elements reside. 4112 */ 4113 if (cookiec <= MPTSAS_MAX_FRAME_SGES64(mpt)) { 4114 dmap = cmd->cmd_sg; 4115 sge = (pMpi2SGESimple64_t)(&frame->SGL); 4116 while (cookiec--) { 4117 ddi_put32(acc_hdl, 4118 &sge->Address.Low, dmap->addr.address64.Low); 4119 ddi_put32(acc_hdl, 4120 &sge->Address.High, dmap->addr.address64.High); 4121 ddi_put32(acc_hdl, &sge->FlagsLength, 4122 dmap->count); 4123 flags = ddi_get32(acc_hdl, &sge->FlagsLength); 4124 flags |= ((uint32_t) 4125 (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4126 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4127 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4128 MPI2_SGE_FLAGS_SHIFT); 4129 4130 /* 4131 * If this is the last cookie, we set the flags 4132 * to indicate so 4133 */ 4134 if (cookiec == 0) { 4135 flags |= 4136 ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT 4137 | MPI2_SGE_FLAGS_END_OF_BUFFER 4138 | MPI2_SGE_FLAGS_END_OF_LIST) << 4139 MPI2_SGE_FLAGS_SHIFT); 4140 } 4141 if (cmd->cmd_flags & CFLAG_DMASEND) { 4142 flags |= (MPI2_SGE_FLAGS_HOST_TO_IOC << 4143 MPI2_SGE_FLAGS_SHIFT); 4144 } else { 4145 flags |= (MPI2_SGE_FLAGS_IOC_TO_HOST << 4146 MPI2_SGE_FLAGS_SHIFT); 4147 } 4148 ddi_put32(acc_hdl, &sge->FlagsLength, flags); 4149 dmap++; 4150 sge++; 4151 } 4152 } else { 4153 /* 4154 * Hereby we start to deal with multiple frames. 4155 * The process is as follows: 4156 * 1. Determine how many frames are needed for SGL element 4157 * storage; Note that all frames are stored in contiguous 4158 * memory space and in 64-bit DMA mode each element is 4159 * 3 double-words (12 bytes) long. 4160 * 2. Fill up the main frame. We need to do this separately 4161 * since it contains the SCSI IO request header and needs 4162 * dedicated processing. Note that the last 4 double-words 4163 * of the SCSI IO header is for SGL element storage 4164 * (MPI2_SGE_IO_UNION). 4165 * 3. Fill the chain element in the main frame, so the DMA 4166 * engine can use the following frames. 4167 * 4. Enter a loop to fill the remaining frames. Note that the 4168 * last frame contains no chain element. The remaining 4169 * frames go into the mpt SGL buffer allocated on the fly, 4170 * not immediately following the main message frame, as in 4171 * Gen1. 4172 * Some restrictions: 4173 * 1. For 64-bit DMA, the simple element and chain element 4174 * are both of 3 double-words (12 bytes) in size, even 4175 * though all frames are stored in the first 4G of mem 4176 * range and the higher 32-bits of the address are always 0. 4177 * 2. On some controllers (like the 1064/1068), a frame can 4178 * hold SGL elements with the last 1 or 2 double-words 4179 * (4 or 8 bytes) un-used. On these controllers, we should 4180 * recognize that there's not enough room for another SGL 4181 * element and move the sge pointer to the next frame. 4182 */ 4183 int i, j, k, l, frames, sgemax; 4184 int temp; 4185 uint8_t chainflags; 4186 uint16_t chainlength; 4187 mptsas_cache_frames_t *p; 4188 4189 /* 4190 * Sgemax is the number of SGE's that will fit 4191 * each extra frame and frames is total 4192 * number of frames we'll need. 1 sge entry per 4193 * frame is reseverd for the chain element thus the -1 below. 4194 */ 4195 sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_SGE_SIMPLE64)) 4196 - 1); 4197 temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax; 4198 4199 /* 4200 * A little check to see if we need to round up the number 4201 * of frames we need 4202 */ 4203 if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp * 4204 sgemax) > 1) { 4205 frames = (temp + 1); 4206 } else { 4207 frames = temp; 4208 } 4209 dmap = cmd->cmd_sg; 4210 sge = (pMpi2SGESimple64_t)(&frame->SGL); 4211 4212 /* 4213 * First fill in the main frame 4214 */ 4215 for (j = 1; j < MPTSAS_MAX_FRAME_SGES64(mpt); j++) { 4216 ddi_put32(acc_hdl, &sge->Address.Low, 4217 dmap->addr.address64.Low); 4218 ddi_put32(acc_hdl, &sge->Address.High, 4219 dmap->addr.address64.High); 4220 ddi_put32(acc_hdl, &sge->FlagsLength, dmap->count); 4221 flags = ddi_get32(acc_hdl, &sge->FlagsLength); 4222 flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4223 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4224 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4225 MPI2_SGE_FLAGS_SHIFT); 4226 4227 /* 4228 * If this is the last SGE of this frame 4229 * we set the end of list flag 4230 */ 4231 if (j == (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) { 4232 flags |= ((uint32_t) 4233 (MPI2_SGE_FLAGS_LAST_ELEMENT) << 4234 MPI2_SGE_FLAGS_SHIFT); 4235 } 4236 if (cmd->cmd_flags & CFLAG_DMASEND) { 4237 flags |= 4238 (MPI2_SGE_FLAGS_HOST_TO_IOC << 4239 MPI2_SGE_FLAGS_SHIFT); 4240 } else { 4241 flags |= 4242 (MPI2_SGE_FLAGS_IOC_TO_HOST << 4243 MPI2_SGE_FLAGS_SHIFT); 4244 } 4245 ddi_put32(acc_hdl, &sge->FlagsLength, flags); 4246 dmap++; 4247 sge++; 4248 } 4249 4250 /* 4251 * Fill in the chain element in the main frame. 4252 * About calculation on ChainOffset: 4253 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes) 4254 * in the end reserved for SGL element storage 4255 * (MPI2_SGE_IO_UNION); we should count it in our 4256 * calculation. See its definition in the header file. 4257 * 2. Constant j is the counter of the current SGL element 4258 * that will be processed, and (j - 1) is the number of 4259 * SGL elements that have been processed (stored in the 4260 * main frame). 4261 * 3. ChainOffset value should be in units of double-words (4 4262 * bytes) so the last value should be divided by 4. 4263 */ 4264 ddi_put8(acc_hdl, &frame->ChainOffset, 4265 (sizeof (MPI2_SCSI_IO_REQUEST) - 4266 sizeof (MPI2_SGE_IO_UNION) + 4267 (j - 1) * sizeof (MPI2_SGE_SIMPLE64)) >> 2); 4268 sgechain = (pMpi2SGEChain64_t)sge; 4269 chainflags = (MPI2_SGE_FLAGS_CHAIN_ELEMENT | 4270 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4271 MPI2_SGE_FLAGS_64_BIT_ADDRESSING); 4272 ddi_put8(acc_hdl, &sgechain->Flags, chainflags); 4273 4274 /* 4275 * The size of the next frame is the accurate size of space 4276 * (in bytes) used to store the SGL elements. j is the counter 4277 * of SGL elements. (j - 1) is the number of SGL elements that 4278 * have been processed (stored in frames). 4279 */ 4280 if (frames >= 2) { 4281 chainlength = mpt->m_req_frame_size / 4282 sizeof (MPI2_SGE_SIMPLE64) * 4283 sizeof (MPI2_SGE_SIMPLE64); 4284 } else { 4285 chainlength = ((cookiec - (j - 1)) * 4286 sizeof (MPI2_SGE_SIMPLE64)); 4287 } 4288 4289 p = cmd->cmd_extra_frames; 4290 4291 ddi_put16(acc_hdl, &sgechain->Length, chainlength); 4292 ddi_put32(acc_hdl, &sgechain->Address.Low, 4293 p->m_phys_addr); 4294 /* SGL is allocated in the first 4G mem range */ 4295 ddi_put32(acc_hdl, &sgechain->Address.High, 0); 4296 4297 /* 4298 * If there are more than 2 frames left we have to 4299 * fill in the next chain offset to the location of 4300 * the chain element in the next frame. 4301 * sgemax is the number of simple elements in an extra 4302 * frame. Note that the value NextChainOffset should be 4303 * in double-words (4 bytes). 4304 */ 4305 if (frames >= 2) { 4306 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 4307 (sgemax * sizeof (MPI2_SGE_SIMPLE64)) >> 2); 4308 } else { 4309 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 0); 4310 } 4311 4312 /* 4313 * Jump to next frame; 4314 * Starting here, chain buffers go into the per command SGL. 4315 * This buffer is allocated when chain buffers are needed. 4316 */ 4317 sge = (pMpi2SGESimple64_t)p->m_frames_addr; 4318 i = cookiec; 4319 4320 /* 4321 * Start filling in frames with SGE's. If we 4322 * reach the end of frame and still have SGE's 4323 * to fill we need to add a chain element and 4324 * use another frame. j will be our counter 4325 * for what cookie we are at and i will be 4326 * the total cookiec. k is the current frame 4327 */ 4328 for (k = 1; k <= frames; k++) { 4329 for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) { 4330 4331 /* 4332 * If we have reached the end of frame 4333 * and we have more SGE's to fill in 4334 * we have to fill the final entry 4335 * with a chain element and then 4336 * continue to the next frame 4337 */ 4338 if ((l == (sgemax + 1)) && (k != frames)) { 4339 sgechain = (pMpi2SGEChain64_t)sge; 4340 j--; 4341 chainflags = ( 4342 MPI2_SGE_FLAGS_CHAIN_ELEMENT | 4343 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4344 MPI2_SGE_FLAGS_64_BIT_ADDRESSING); 4345 ddi_put8(p->m_acc_hdl, 4346 &sgechain->Flags, chainflags); 4347 /* 4348 * k is the frame counter and (k + 1) 4349 * is the number of the next frame. 4350 * Note that frames are in contiguous 4351 * memory space. 4352 */ 4353 ddi_put32(p->m_acc_hdl, 4354 &sgechain->Address.Low, 4355 (p->m_phys_addr + 4356 (mpt->m_req_frame_size * k))); 4357 ddi_put32(p->m_acc_hdl, 4358 &sgechain->Address.High, 0); 4359 4360 /* 4361 * If there are more than 2 frames left 4362 * we have to next chain offset to 4363 * the location of the chain element 4364 * in the next frame and fill in the 4365 * length of the next chain 4366 */ 4367 if ((frames - k) >= 2) { 4368 ddi_put8(p->m_acc_hdl, 4369 &sgechain->NextChainOffset, 4370 (sgemax * 4371 sizeof (MPI2_SGE_SIMPLE64)) 4372 >> 2); 4373 ddi_put16(p->m_acc_hdl, 4374 &sgechain->Length, 4375 mpt->m_req_frame_size / 4376 sizeof (MPI2_SGE_SIMPLE64) * 4377 sizeof (MPI2_SGE_SIMPLE64)); 4378 } else { 4379 /* 4380 * This is the last frame. Set 4381 * the NextChainOffset to 0 and 4382 * Length is the total size of 4383 * all remaining simple elements 4384 */ 4385 ddi_put8(p->m_acc_hdl, 4386 &sgechain->NextChainOffset, 4387 0); 4388 ddi_put16(p->m_acc_hdl, 4389 &sgechain->Length, 4390 (cookiec - j) * 4391 sizeof (MPI2_SGE_SIMPLE64)); 4392 } 4393 4394 /* Jump to the next frame */ 4395 sge = (pMpi2SGESimple64_t) 4396 ((char *)p->m_frames_addr + 4397 (int)mpt->m_req_frame_size * k); 4398 4399 continue; 4400 } 4401 4402 ddi_put32(p->m_acc_hdl, 4403 &sge->Address.Low, 4404 dmap->addr.address64.Low); 4405 ddi_put32(p->m_acc_hdl, 4406 &sge->Address.High, 4407 dmap->addr.address64.High); 4408 ddi_put32(p->m_acc_hdl, 4409 &sge->FlagsLength, dmap->count); 4410 flags = ddi_get32(p->m_acc_hdl, 4411 &sge->FlagsLength); 4412 flags |= ((uint32_t)( 4413 MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4414 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4415 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4416 MPI2_SGE_FLAGS_SHIFT); 4417 4418 /* 4419 * If we are at the end of the frame and 4420 * there is another frame to fill in 4421 * we set the last simple element as last 4422 * element 4423 */ 4424 if ((l == sgemax) && (k != frames)) { 4425 flags |= ((uint32_t) 4426 (MPI2_SGE_FLAGS_LAST_ELEMENT) << 4427 MPI2_SGE_FLAGS_SHIFT); 4428 } 4429 4430 /* 4431 * If this is the final cookie we 4432 * indicate it by setting the flags 4433 */ 4434 if (j == i) { 4435 flags |= ((uint32_t) 4436 (MPI2_SGE_FLAGS_LAST_ELEMENT | 4437 MPI2_SGE_FLAGS_END_OF_BUFFER | 4438 MPI2_SGE_FLAGS_END_OF_LIST) << 4439 MPI2_SGE_FLAGS_SHIFT); 4440 } 4441 if (cmd->cmd_flags & CFLAG_DMASEND) { 4442 flags |= 4443 (MPI2_SGE_FLAGS_HOST_TO_IOC << 4444 MPI2_SGE_FLAGS_SHIFT); 4445 } else { 4446 flags |= 4447 (MPI2_SGE_FLAGS_IOC_TO_HOST << 4448 MPI2_SGE_FLAGS_SHIFT); 4449 } 4450 ddi_put32(p->m_acc_hdl, 4451 &sge->FlagsLength, flags); 4452 dmap++; 4453 sge++; 4454 } 4455 } 4456 4457 /* 4458 * Sync DMA with the chain buffers that were just created 4459 */ 4460 (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 4461 } 4462 } 4463 4464 /* 4465 * Interrupt handling 4466 * Utility routine. Poll for status of a command sent to HBA 4467 * without interrupts (a FLAG_NOINTR command). 4468 */ 4469 int 4470 mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime) 4471 { 4472 int rval = TRUE; 4473 4474 NDBG5(("mptsas_poll: cmd=0x%p", (void *)poll_cmd)); 4475 4476 /* 4477 * In order to avoid using m_mutex in ISR(a new separate mutex 4478 * m_intr_mutex is introduced) and keep the same lock logic, 4479 * the m_intr_mutex should be used to protect the getting and 4480 * setting of the ReplyDescriptorIndex. 4481 * 4482 * Since the m_intr_mutex would be released during processing the poll 4483 * cmd, so we should set the poll flag earlier here to make sure the 4484 * polled cmd be handled in this thread/context. A side effect is other 4485 * cmds during the period between the flag set and reset are also 4486 * handled in this thread and not the ISR. Since the poll cmd is not 4487 * so common, so the performance degradation in this case is not a big 4488 * issue. 4489 */ 4490 mutex_enter(&mpt->m_intr_mutex); 4491 mpt->m_polled_intr = 1; 4492 mutex_exit(&mpt->m_intr_mutex); 4493 4494 if ((poll_cmd->cmd_flags & CFLAG_TM_CMD) == 0) { 4495 mptsas_restart_hba(mpt); 4496 } 4497 4498 /* 4499 * Wait, using drv_usecwait(), long enough for the command to 4500 * reasonably return from the target if the target isn't 4501 * "dead". A polled command may well be sent from scsi_poll, and 4502 * there are retries built in to scsi_poll if the transport 4503 * accepted the packet (TRAN_ACCEPT). scsi_poll waits 1 second 4504 * and retries the transport up to scsi_poll_busycnt times 4505 * (currently 60) if 4506 * 1. pkt_reason is CMD_INCOMPLETE and pkt_state is 0, or 4507 * 2. pkt_reason is CMD_CMPLT and *pkt_scbp has STATUS_BUSY 4508 * 4509 * limit the waiting to avoid a hang in the event that the 4510 * cmd never gets started but we are still receiving interrupts 4511 */ 4512 while (!(poll_cmd->cmd_flags & CFLAG_FINISHED)) { 4513 if (mptsas_wait_intr(mpt, polltime) == FALSE) { 4514 NDBG5(("mptsas_poll: command incomplete")); 4515 rval = FALSE; 4516 break; 4517 } 4518 } 4519 4520 mutex_enter(&mpt->m_intr_mutex); 4521 mpt->m_polled_intr = 0; 4522 mutex_exit(&mpt->m_intr_mutex); 4523 4524 if (rval == FALSE) { 4525 4526 /* 4527 * this isn't supposed to happen, the hba must be wedged 4528 * Mark this cmd as a timeout. 4529 */ 4530 mptsas_set_pkt_reason(mpt, poll_cmd, CMD_TIMEOUT, 4531 (STAT_TIMEOUT|STAT_ABORTED)); 4532 4533 if (poll_cmd->cmd_queued == FALSE) { 4534 4535 NDBG5(("mptsas_poll: not on waitq")); 4536 4537 poll_cmd->cmd_pkt->pkt_state |= 4538 (STATE_GOT_BUS|STATE_GOT_TARGET|STATE_SENT_CMD); 4539 } else { 4540 4541 /* find and remove it from the waitq */ 4542 NDBG5(("mptsas_poll: delete from waitq")); 4543 mptsas_waitq_delete(mpt, poll_cmd); 4544 } 4545 4546 } 4547 mptsas_fma_check(mpt, poll_cmd); 4548 NDBG5(("mptsas_poll: done")); 4549 return (rval); 4550 } 4551 4552 /* 4553 * Used for polling cmds and TM function 4554 */ 4555 static int 4556 mptsas_wait_intr(mptsas_t *mpt, int polltime) 4557 { 4558 int cnt; 4559 pMpi2ReplyDescriptorsUnion_t reply_desc_union; 4560 Mpi2ReplyDescriptorsUnion_t reply_desc_union_v; 4561 uint32_t int_mask; 4562 uint8_t reply_type; 4563 4564 NDBG5(("mptsas_wait_intr")); 4565 4566 4567 /* 4568 * Get the current interrupt mask and disable interrupts. When 4569 * re-enabling ints, set mask to saved value. 4570 */ 4571 int_mask = ddi_get32(mpt->m_datap, &mpt->m_reg->HostInterruptMask); 4572 MPTSAS_DISABLE_INTR(mpt); 4573 4574 /* 4575 * Keep polling for at least (polltime * 1000) seconds 4576 */ 4577 for (cnt = 0; cnt < polltime; cnt++) { 4578 mutex_enter(&mpt->m_intr_mutex); 4579 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 4580 DDI_DMA_SYNC_FORCPU); 4581 4582 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t) 4583 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index); 4584 4585 if (ddi_get32(mpt->m_acc_post_queue_hdl, 4586 &reply_desc_union->Words.Low) == 0xFFFFFFFF || 4587 ddi_get32(mpt->m_acc_post_queue_hdl, 4588 &reply_desc_union->Words.High) == 0xFFFFFFFF) { 4589 mutex_exit(&mpt->m_intr_mutex); 4590 drv_usecwait(1000); 4591 continue; 4592 } 4593 4594 reply_type = ddi_get8(mpt->m_acc_post_queue_hdl, 4595 &reply_desc_union->Default.ReplyFlags); 4596 reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; 4597 reply_desc_union_v.Default.ReplyFlags = reply_type; 4598 if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) { 4599 reply_desc_union_v.SCSIIOSuccess.SMID = 4600 ddi_get16(mpt->m_acc_post_queue_hdl, 4601 &reply_desc_union->SCSIIOSuccess.SMID); 4602 } else if (reply_type == 4603 MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { 4604 reply_desc_union_v.AddressReply.ReplyFrameAddress = 4605 ddi_get32(mpt->m_acc_post_queue_hdl, 4606 &reply_desc_union->AddressReply.ReplyFrameAddress); 4607 reply_desc_union_v.AddressReply.SMID = 4608 ddi_get16(mpt->m_acc_post_queue_hdl, 4609 &reply_desc_union->AddressReply.SMID); 4610 } 4611 /* 4612 * Clear the reply descriptor for re-use and increment 4613 * index. 4614 */ 4615 ddi_put64(mpt->m_acc_post_queue_hdl, 4616 &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index], 4617 0xFFFFFFFFFFFFFFFF); 4618 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 4619 DDI_DMA_SYNC_FORDEV); 4620 4621 if (++mpt->m_post_index == mpt->m_post_queue_depth) { 4622 mpt->m_post_index = 0; 4623 } 4624 4625 /* 4626 * Update the global reply index 4627 */ 4628 ddi_put32(mpt->m_datap, 4629 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); 4630 mutex_exit(&mpt->m_intr_mutex); 4631 4632 /* 4633 * The reply is valid, process it according to its 4634 * type. 4635 */ 4636 mptsas_process_intr(mpt, &reply_desc_union_v); 4637 4638 4639 /* 4640 * Re-enable interrupts and quit. 4641 */ 4642 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, 4643 int_mask); 4644 return (TRUE); 4645 4646 } 4647 4648 /* 4649 * Clear polling flag, re-enable interrupts and quit. 4650 */ 4651 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, int_mask); 4652 return (FALSE); 4653 } 4654 4655 /* 4656 * For fastpath, the m_intr_mutex should be held from the begining to the end, 4657 * so we only treat those cmds that need not release m_intr_mutex(even just for 4658 * a moment) as candidate for fast processing. otherwise, we don't handle them 4659 * and just return, then in ISR, those cmds would be handled later with m_mutex 4660 * held and m_intr_mutex not held. 4661 */ 4662 static int 4663 mptsas_handle_io_fastpath(mptsas_t *mpt, 4664 uint16_t SMID) 4665 { 4666 mptsas_slots_t *slots = mpt->m_active; 4667 mptsas_cmd_t *cmd = NULL; 4668 struct scsi_pkt *pkt; 4669 4670 /* 4671 * This is a success reply so just complete the IO. First, do a sanity 4672 * check on the SMID. The final slot is used for TM requests, which 4673 * would not come into this reply handler. 4674 */ 4675 if ((SMID == 0) || (SMID > slots->m_n_slots)) { 4676 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n", 4677 SMID); 4678 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 4679 return (TRUE); 4680 } 4681 4682 cmd = slots->m_slot[SMID]; 4683 4684 /* 4685 * print warning and return if the slot is empty 4686 */ 4687 if (cmd == NULL) { 4688 mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO " 4689 "in slot %d", SMID); 4690 return (TRUE); 4691 } 4692 4693 pkt = CMD2PKT(cmd); 4694 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD | 4695 STATE_GOT_STATUS); 4696 if (cmd->cmd_flags & CFLAG_DMAVALID) { 4697 pkt->pkt_state |= STATE_XFERRED_DATA; 4698 } 4699 pkt->pkt_resid = 0; 4700 4701 /* 4702 * If the cmd is a IOC, or a passthrough, then we don't process it in 4703 * fastpath, and later it would be handled by mptsas_process_intr() 4704 * with m_mutex protected. 4705 */ 4706 if (cmd->cmd_flags & (CFLAG_PASSTHRU | CFLAG_CMDIOC)) { 4707 return (FALSE); 4708 } else { 4709 mptsas_remove_cmd0(mpt, cmd); 4710 } 4711 4712 if (cmd->cmd_flags & CFLAG_RETRY) { 4713 /* 4714 * The target returned QFULL or busy, do not add tihs 4715 * pkt to the doneq since the hba will retry 4716 * this cmd. 4717 * 4718 * The pkt has already been resubmitted in 4719 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error(). 4720 * Remove this cmd_flag here. 4721 */ 4722 cmd->cmd_flags &= ~CFLAG_RETRY; 4723 } else { 4724 mptsas_doneq_add0(mpt, cmd); 4725 } 4726 4727 /* 4728 * In fastpath, the cmd should only be a context reply, so just check 4729 * the post queue of the reply descriptor and the dmahandle of the cmd 4730 * is enough. No sense data in this case and no need to check the dma 4731 * handle where sense data dma info is saved, the dma handle of the 4732 * reply frame, and the dma handle of the reply free queue. 4733 * For the dma handle of the request queue. Check fma here since we 4734 * are sure the request must have already been sent/DMAed correctly. 4735 * otherwise checking in mptsas_scsi_start() is not correct since 4736 * at that time the dma may not start. 4737 */ 4738 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 4739 DDI_SUCCESS) || 4740 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) != 4741 DDI_SUCCESS)) { 4742 ddi_fm_service_impact(mpt->m_dip, 4743 DDI_SERVICE_UNAFFECTED); 4744 pkt->pkt_reason = CMD_TRAN_ERR; 4745 pkt->pkt_statistics = 0; 4746 } 4747 if (cmd->cmd_dmahandle && 4748 (mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS)) { 4749 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 4750 pkt->pkt_reason = CMD_TRAN_ERR; 4751 pkt->pkt_statistics = 0; 4752 } 4753 if ((cmd->cmd_extra_frames && 4754 ((mptsas_check_dma_handle(cmd->cmd_extra_frames->m_dma_hdl) != 4755 DDI_SUCCESS) || 4756 (mptsas_check_acc_handle(cmd->cmd_extra_frames->m_acc_hdl) != 4757 DDI_SUCCESS)))) { 4758 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 4759 pkt->pkt_reason = CMD_TRAN_ERR; 4760 pkt->pkt_statistics = 0; 4761 } 4762 4763 return (TRUE); 4764 } 4765 4766 static void 4767 mptsas_handle_scsi_io_success(mptsas_t *mpt, 4768 pMpi2ReplyDescriptorsUnion_t reply_desc) 4769 { 4770 pMpi2SCSIIOSuccessReplyDescriptor_t scsi_io_success; 4771 uint16_t SMID; 4772 mptsas_slots_t *slots = mpt->m_active; 4773 mptsas_cmd_t *cmd = NULL; 4774 struct scsi_pkt *pkt; 4775 4776 scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc; 4777 SMID = scsi_io_success->SMID; 4778 4779 /* 4780 * This is a success reply so just complete the IO. First, do a sanity 4781 * check on the SMID. The final slot is used for TM requests, which 4782 * would not come into this reply handler. 4783 */ 4784 if ((SMID == 0) || (SMID > slots->m_n_slots)) { 4785 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n", 4786 SMID); 4787 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 4788 return; 4789 } 4790 4791 cmd = slots->m_slot[SMID]; 4792 4793 /* 4794 * print warning and return if the slot is empty 4795 */ 4796 if (cmd == NULL) { 4797 mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO " 4798 "in slot %d", SMID); 4799 return; 4800 } 4801 4802 pkt = CMD2PKT(cmd); 4803 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD | 4804 STATE_GOT_STATUS); 4805 if (cmd->cmd_flags & CFLAG_DMAVALID) { 4806 pkt->pkt_state |= STATE_XFERRED_DATA; 4807 } 4808 pkt->pkt_resid = 0; 4809 4810 if (cmd->cmd_flags & CFLAG_PASSTHRU) { 4811 cmd->cmd_flags |= CFLAG_FINISHED; 4812 cv_broadcast(&mpt->m_passthru_cv); 4813 return; 4814 } else { 4815 mptsas_remove_cmd(mpt, cmd); 4816 } 4817 4818 if (cmd->cmd_flags & CFLAG_RETRY) { 4819 /* 4820 * The target returned QFULL or busy, do not add tihs 4821 * pkt to the doneq since the hba will retry 4822 * this cmd. 4823 * 4824 * The pkt has already been resubmitted in 4825 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error(). 4826 * Remove this cmd_flag here. 4827 */ 4828 cmd->cmd_flags &= ~CFLAG_RETRY; 4829 } else { 4830 mptsas_doneq_add(mpt, cmd); 4831 } 4832 } 4833 4834 static void 4835 mptsas_handle_address_reply(mptsas_t *mpt, 4836 pMpi2ReplyDescriptorsUnion_t reply_desc) 4837 { 4838 pMpi2AddressReplyDescriptor_t address_reply; 4839 pMPI2DefaultReply_t reply; 4840 mptsas_fw_diagnostic_buffer_t *pBuffer; 4841 uint32_t reply_addr; 4842 uint16_t SMID, iocstatus; 4843 mptsas_slots_t *slots = mpt->m_active; 4844 mptsas_cmd_t *cmd = NULL; 4845 uint8_t function, buffer_type; 4846 m_replyh_arg_t *args; 4847 int reply_frame_no; 4848 4849 ASSERT(mutex_owned(&mpt->m_mutex)); 4850 4851 address_reply = (pMpi2AddressReplyDescriptor_t)reply_desc; 4852 4853 reply_addr = address_reply->ReplyFrameAddress; 4854 SMID = address_reply->SMID; 4855 /* 4856 * If reply frame is not in the proper range we should ignore this 4857 * message and exit the interrupt handler. 4858 */ 4859 if ((reply_addr < mpt->m_reply_frame_dma_addr) || 4860 (reply_addr >= (mpt->m_reply_frame_dma_addr + 4861 (mpt->m_reply_frame_size * mpt->m_max_replies))) || 4862 ((reply_addr - mpt->m_reply_frame_dma_addr) % 4863 mpt->m_reply_frame_size != 0)) { 4864 mptsas_log(mpt, CE_WARN, "?Received invalid reply frame " 4865 "address 0x%x\n", reply_addr); 4866 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 4867 return; 4868 } 4869 4870 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 4871 DDI_DMA_SYNC_FORCPU); 4872 reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame + (reply_addr - 4873 mpt->m_reply_frame_dma_addr)); 4874 function = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Function); 4875 4876 /* 4877 * don't get slot information and command for events since these values 4878 * don't exist 4879 */ 4880 if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) && 4881 (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) { 4882 /* 4883 * This could be a TM reply, which use the last allocated SMID, 4884 * so allow for that. 4885 */ 4886 if ((SMID == 0) || (SMID > (slots->m_n_slots + 1))) { 4887 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of " 4888 "%d\n", SMID); 4889 ddi_fm_service_impact(mpt->m_dip, 4890 DDI_SERVICE_UNAFFECTED); 4891 return; 4892 } 4893 4894 cmd = slots->m_slot[SMID]; 4895 4896 /* 4897 * print warning and return if the slot is empty 4898 */ 4899 if (cmd == NULL) { 4900 mptsas_log(mpt, CE_WARN, "?NULL command for address " 4901 "reply in slot %d", SMID); 4902 return; 4903 } 4904 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 4905 (cmd->cmd_flags & CFLAG_CONFIG) || 4906 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 4907 cmd->cmd_rfm = reply_addr; 4908 cmd->cmd_flags |= CFLAG_FINISHED; 4909 cv_broadcast(&mpt->m_passthru_cv); 4910 cv_broadcast(&mpt->m_config_cv); 4911 cv_broadcast(&mpt->m_fw_diag_cv); 4912 return; 4913 } else if (!(cmd->cmd_flags & CFLAG_FW_CMD)) { 4914 mptsas_remove_cmd(mpt, cmd); 4915 } 4916 NDBG31(("\t\tmptsas_process_intr: slot=%d", SMID)); 4917 } 4918 /* 4919 * Depending on the function, we need to handle 4920 * the reply frame (and cmd) differently. 4921 */ 4922 switch (function) { 4923 case MPI2_FUNCTION_SCSI_IO_REQUEST: 4924 mptsas_check_scsi_io_error(mpt, (pMpi2SCSIIOReply_t)reply, cmd); 4925 break; 4926 case MPI2_FUNCTION_SCSI_TASK_MGMT: 4927 cmd->cmd_rfm = reply_addr; 4928 mptsas_check_task_mgt(mpt, (pMpi2SCSIManagementReply_t)reply, 4929 cmd); 4930 break; 4931 case MPI2_FUNCTION_FW_DOWNLOAD: 4932 cmd->cmd_flags |= CFLAG_FINISHED; 4933 cv_signal(&mpt->m_fw_cv); 4934 break; 4935 case MPI2_FUNCTION_EVENT_NOTIFICATION: 4936 reply_frame_no = (reply_addr - mpt->m_reply_frame_dma_addr) / 4937 mpt->m_reply_frame_size; 4938 args = &mpt->m_replyh_args[reply_frame_no]; 4939 args->mpt = (void *)mpt; 4940 args->rfm = reply_addr; 4941 4942 /* 4943 * Record the event if its type is enabled in 4944 * this mpt instance by ioctl. 4945 */ 4946 mptsas_record_event(args); 4947 4948 /* 4949 * Handle time critical events 4950 * NOT_RESPONDING/ADDED only now 4951 */ 4952 if (mptsas_handle_event_sync(args) == DDI_SUCCESS) { 4953 /* 4954 * Would not return main process, 4955 * just let taskq resolve ack action 4956 * and ack would be sent in taskq thread 4957 */ 4958 NDBG20(("send mptsas_handle_event_sync success")); 4959 } 4960 if ((ddi_taskq_dispatch(mpt->m_event_taskq, mptsas_handle_event, 4961 (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) { 4962 mptsas_log(mpt, CE_WARN, "No memory available" 4963 "for dispatch taskq"); 4964 /* 4965 * Return the reply frame to the free queue. 4966 */ 4967 ddi_put32(mpt->m_acc_free_queue_hdl, 4968 &((uint32_t *)(void *) 4969 mpt->m_free_queue)[mpt->m_free_index], reply_addr); 4970 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 4971 DDI_DMA_SYNC_FORDEV); 4972 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 4973 mpt->m_free_index = 0; 4974 } 4975 4976 ddi_put32(mpt->m_datap, 4977 &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index); 4978 } 4979 return; 4980 case MPI2_FUNCTION_DIAG_BUFFER_POST: 4981 /* 4982 * If SMID is 0, this implies that the reply is due to a 4983 * release function with a status that the buffer has been 4984 * released. Set the buffer flags accordingly. 4985 */ 4986 if (SMID == 0) { 4987 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 4988 &reply->IOCStatus); 4989 buffer_type = ddi_get8(mpt->m_acc_reply_frame_hdl, 4990 &(((pMpi2DiagBufferPostReply_t)reply)->BufferType)); 4991 if (iocstatus == MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED) { 4992 pBuffer = 4993 &mpt->m_fw_diag_buffer_list[buffer_type]; 4994 pBuffer->valid_data = TRUE; 4995 pBuffer->owned_by_firmware = FALSE; 4996 pBuffer->immediate = FALSE; 4997 } 4998 } else { 4999 /* 5000 * Normal handling of diag post reply with SMID. 5001 */ 5002 cmd = slots->m_slot[SMID]; 5003 5004 /* 5005 * print warning and return if the slot is empty 5006 */ 5007 if (cmd == NULL) { 5008 mptsas_log(mpt, CE_WARN, "?NULL command for " 5009 "address reply in slot %d", SMID); 5010 return; 5011 } 5012 cmd->cmd_rfm = reply_addr; 5013 cmd->cmd_flags |= CFLAG_FINISHED; 5014 cv_broadcast(&mpt->m_fw_diag_cv); 5015 } 5016 return; 5017 default: 5018 mptsas_log(mpt, CE_WARN, "Unknown function 0x%x ", function); 5019 break; 5020 } 5021 5022 /* 5023 * Return the reply frame to the free queue. 5024 */ 5025 ddi_put32(mpt->m_acc_free_queue_hdl, 5026 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 5027 reply_addr); 5028 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 5029 DDI_DMA_SYNC_FORDEV); 5030 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 5031 mpt->m_free_index = 0; 5032 } 5033 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 5034 mpt->m_free_index); 5035 5036 if (cmd->cmd_flags & CFLAG_FW_CMD) 5037 return; 5038 5039 if (cmd->cmd_flags & CFLAG_RETRY) { 5040 /* 5041 * The target returned QFULL or busy, do not add tihs 5042 * pkt to the doneq since the hba will retry 5043 * this cmd. 5044 * 5045 * The pkt has already been resubmitted in 5046 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error(). 5047 * Remove this cmd_flag here. 5048 */ 5049 cmd->cmd_flags &= ~CFLAG_RETRY; 5050 } else { 5051 mptsas_doneq_add(mpt, cmd); 5052 } 5053 } 5054 5055 static void 5056 mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, 5057 mptsas_cmd_t *cmd) 5058 { 5059 uint8_t scsi_status, scsi_state; 5060 uint16_t ioc_status; 5061 uint32_t xferred, sensecount, responsedata, loginfo = 0; 5062 struct scsi_pkt *pkt; 5063 struct scsi_arq_status *arqstat; 5064 struct buf *bp; 5065 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 5066 uint8_t *sensedata = NULL; 5067 5068 if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) == 5069 (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) { 5070 bp = cmd->cmd_ext_arq_buf; 5071 } else { 5072 bp = cmd->cmd_arq_buf; 5073 } 5074 5075 scsi_status = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIStatus); 5076 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus); 5077 scsi_state = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIState); 5078 xferred = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->TransferCount); 5079 sensecount = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->SenseCount); 5080 responsedata = ddi_get32(mpt->m_acc_reply_frame_hdl, 5081 &reply->ResponseInfo); 5082 5083 if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 5084 loginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 5085 &reply->IOCLogInfo); 5086 mptsas_log(mpt, CE_NOTE, 5087 "?Log info 0x%x received for target %d.\n" 5088 "\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x", 5089 loginfo, Tgt(cmd), scsi_status, ioc_status, 5090 scsi_state); 5091 } 5092 5093 NDBG31(("\t\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x", 5094 scsi_status, ioc_status, scsi_state)); 5095 5096 pkt = CMD2PKT(cmd); 5097 *(pkt->pkt_scbp) = scsi_status; 5098 5099 if (loginfo == 0x31170000) { 5100 /* 5101 * if loginfo PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY 5102 * 0x31170000 comes, that means the device missing delay 5103 * is in progressing, the command need retry later. 5104 */ 5105 *(pkt->pkt_scbp) = STATUS_BUSY; 5106 return; 5107 } 5108 5109 if ((scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS) && 5110 ((ioc_status & MPI2_IOCSTATUS_MASK) == 5111 MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE)) { 5112 pkt->pkt_reason = CMD_INCOMPLETE; 5113 pkt->pkt_state |= STATE_GOT_BUS; 5114 mutex_enter(&ptgt->m_tgt_intr_mutex); 5115 if (ptgt->m_reset_delay == 0) { 5116 mptsas_set_throttle(mpt, ptgt, 5117 DRAIN_THROTTLE); 5118 } 5119 mutex_exit(&ptgt->m_tgt_intr_mutex); 5120 return; 5121 } 5122 5123 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) { 5124 responsedata &= 0x000000FF; 5125 if (responsedata & MPTSAS_SCSI_RESPONSE_CODE_TLR_OFF) { 5126 mptsas_log(mpt, CE_NOTE, "Do not support the TLR\n"); 5127 pkt->pkt_reason = CMD_TLR_OFF; 5128 return; 5129 } 5130 } 5131 5132 5133 switch (scsi_status) { 5134 case MPI2_SCSI_STATUS_CHECK_CONDITION: 5135 pkt->pkt_resid = (cmd->cmd_dmacount - xferred); 5136 arqstat = (void*)(pkt->pkt_scbp); 5137 arqstat->sts_rqpkt_status = *((struct scsi_status *) 5138 (pkt->pkt_scbp)); 5139 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 5140 STATE_SENT_CMD | STATE_GOT_STATUS | STATE_ARQ_DONE); 5141 if (cmd->cmd_flags & CFLAG_XARQ) { 5142 pkt->pkt_state |= STATE_XARQ_DONE; 5143 } 5144 if (pkt->pkt_resid != cmd->cmd_dmacount) { 5145 pkt->pkt_state |= STATE_XFERRED_DATA; 5146 } 5147 arqstat->sts_rqpkt_reason = pkt->pkt_reason; 5148 arqstat->sts_rqpkt_state = pkt->pkt_state; 5149 arqstat->sts_rqpkt_state |= STATE_XFERRED_DATA; 5150 arqstat->sts_rqpkt_statistics = pkt->pkt_statistics; 5151 sensedata = (uint8_t *)&arqstat->sts_sensedata; 5152 5153 bcopy((uchar_t *)bp->b_un.b_addr, sensedata, 5154 ((cmd->cmd_rqslen >= sensecount) ? sensecount : 5155 cmd->cmd_rqslen)); 5156 arqstat->sts_rqpkt_resid = (cmd->cmd_rqslen - sensecount); 5157 cmd->cmd_flags |= CFLAG_CMDARQ; 5158 /* 5159 * Set proper status for pkt if autosense was valid 5160 */ 5161 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) { 5162 struct scsi_status zero_status = { 0 }; 5163 arqstat->sts_rqpkt_status = zero_status; 5164 } 5165 5166 /* 5167 * ASC=0x47 is parity error 5168 * ASC=0x48 is initiator detected error received 5169 */ 5170 if ((scsi_sense_key(sensedata) == KEY_ABORTED_COMMAND) && 5171 ((scsi_sense_asc(sensedata) == 0x47) || 5172 (scsi_sense_asc(sensedata) == 0x48))) { 5173 mptsas_log(mpt, CE_NOTE, "Aborted_command!"); 5174 } 5175 5176 /* 5177 * ASC/ASCQ=0x3F/0x0E means report_luns data changed 5178 * ASC/ASCQ=0x25/0x00 means invalid lun 5179 */ 5180 if (((scsi_sense_key(sensedata) == KEY_UNIT_ATTENTION) && 5181 (scsi_sense_asc(sensedata) == 0x3F) && 5182 (scsi_sense_ascq(sensedata) == 0x0E)) || 5183 ((scsi_sense_key(sensedata) == KEY_ILLEGAL_REQUEST) && 5184 (scsi_sense_asc(sensedata) == 0x25) && 5185 (scsi_sense_ascq(sensedata) == 0x00))) { 5186 mptsas_topo_change_list_t *topo_node = NULL; 5187 5188 topo_node = kmem_zalloc( 5189 sizeof (mptsas_topo_change_list_t), 5190 KM_NOSLEEP); 5191 if (topo_node == NULL) { 5192 mptsas_log(mpt, CE_NOTE, "No memory" 5193 "resource for handle SAS dynamic" 5194 "reconfigure.\n"); 5195 break; 5196 } 5197 topo_node->mpt = mpt; 5198 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET; 5199 topo_node->un.phymask = ptgt->m_phymask; 5200 topo_node->devhdl = ptgt->m_devhdl; 5201 topo_node->object = (void *)ptgt; 5202 topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED; 5203 5204 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 5205 mptsas_handle_dr, 5206 (void *)topo_node, 5207 DDI_NOSLEEP)) != DDI_SUCCESS) { 5208 mptsas_log(mpt, CE_NOTE, "mptsas start taskq" 5209 "for handle SAS dynamic reconfigure" 5210 "failed. \n"); 5211 } 5212 } 5213 break; 5214 case MPI2_SCSI_STATUS_GOOD: 5215 switch (ioc_status & MPI2_IOCSTATUS_MASK) { 5216 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 5217 pkt->pkt_reason = CMD_DEV_GONE; 5218 pkt->pkt_state |= STATE_GOT_BUS; 5219 mutex_enter(&ptgt->m_tgt_intr_mutex); 5220 if (ptgt->m_reset_delay == 0) { 5221 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5222 } 5223 mutex_exit(&ptgt->m_tgt_intr_mutex); 5224 NDBG31(("lost disk for target%d, command:%x", 5225 Tgt(cmd), pkt->pkt_cdbp[0])); 5226 break; 5227 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN: 5228 NDBG31(("data overrun: xferred=%d", xferred)); 5229 NDBG31(("dmacount=%d", cmd->cmd_dmacount)); 5230 pkt->pkt_reason = CMD_DATA_OVR; 5231 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET 5232 | STATE_SENT_CMD | STATE_GOT_STATUS 5233 | STATE_XFERRED_DATA); 5234 pkt->pkt_resid = 0; 5235 break; 5236 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: 5237 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN: 5238 NDBG31(("data underrun: xferred=%d", xferred)); 5239 NDBG31(("dmacount=%d", cmd->cmd_dmacount)); 5240 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET 5241 | STATE_SENT_CMD | STATE_GOT_STATUS); 5242 pkt->pkt_resid = (cmd->cmd_dmacount - xferred); 5243 if (pkt->pkt_resid != cmd->cmd_dmacount) { 5244 pkt->pkt_state |= STATE_XFERRED_DATA; 5245 } 5246 break; 5247 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: 5248 mptsas_set_pkt_reason(mpt, 5249 cmd, CMD_RESET, STAT_BUS_RESET); 5250 break; 5251 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: 5252 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: 5253 mptsas_set_pkt_reason(mpt, 5254 cmd, CMD_RESET, STAT_DEV_RESET); 5255 break; 5256 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR: 5257 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR: 5258 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET); 5259 mptsas_set_pkt_reason(mpt, 5260 cmd, CMD_TERMINATED, STAT_TERMINATED); 5261 break; 5262 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: 5263 case MPI2_IOCSTATUS_BUSY: 5264 /* 5265 * set throttles to drain 5266 */ 5267 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 5268 &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST); 5269 while (ptgt != NULL) { 5270 mutex_enter(&ptgt->m_tgt_intr_mutex); 5271 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5272 mutex_exit(&ptgt->m_tgt_intr_mutex); 5273 5274 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 5275 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 5276 } 5277 5278 /* 5279 * retry command 5280 */ 5281 cmd->cmd_flags |= CFLAG_RETRY; 5282 cmd->cmd_pkt_flags |= FLAG_HEAD; 5283 5284 mutex_exit(&mpt->m_mutex); 5285 (void) mptsas_accept_pkt(mpt, cmd); 5286 mutex_enter(&mpt->m_mutex); 5287 break; 5288 default: 5289 mptsas_log(mpt, CE_WARN, 5290 "unknown ioc_status = %x\n", ioc_status); 5291 mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer " 5292 "count = %x, scsi_status = %x", scsi_state, 5293 xferred, scsi_status); 5294 break; 5295 } 5296 break; 5297 case MPI2_SCSI_STATUS_TASK_SET_FULL: 5298 mptsas_handle_qfull(mpt, cmd); 5299 break; 5300 case MPI2_SCSI_STATUS_BUSY: 5301 NDBG31(("scsi_status busy received")); 5302 break; 5303 case MPI2_SCSI_STATUS_RESERVATION_CONFLICT: 5304 NDBG31(("scsi_status reservation conflict received")); 5305 break; 5306 default: 5307 mptsas_log(mpt, CE_WARN, "scsi_status=%x, ioc_status=%x\n", 5308 scsi_status, ioc_status); 5309 mptsas_log(mpt, CE_WARN, 5310 "mptsas_process_intr: invalid scsi status\n"); 5311 break; 5312 } 5313 } 5314 5315 static void 5316 mptsas_check_task_mgt(mptsas_t *mpt, pMpi2SCSIManagementReply_t reply, 5317 mptsas_cmd_t *cmd) 5318 { 5319 uint8_t task_type; 5320 uint16_t ioc_status; 5321 uint32_t log_info; 5322 uint16_t dev_handle; 5323 struct scsi_pkt *pkt = CMD2PKT(cmd); 5324 5325 task_type = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->TaskType); 5326 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus); 5327 log_info = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo); 5328 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->DevHandle); 5329 5330 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 5331 mptsas_log(mpt, CE_WARN, "mptsas_check_task_mgt: Task 0x%x " 5332 "failed. IOCStatus=0x%x IOCLogInfo=0x%x target=%d\n", 5333 task_type, ioc_status, log_info, dev_handle); 5334 pkt->pkt_reason = CMD_INCOMPLETE; 5335 return; 5336 } 5337 5338 switch (task_type) { 5339 case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK: 5340 case MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET: 5341 case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK: 5342 case MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA: 5343 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET: 5344 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION: 5345 break; 5346 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 5347 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 5348 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 5349 /* 5350 * Check for invalid DevHandle of 0 in case application 5351 * sends bad command. DevHandle of 0 could cause problems. 5352 */ 5353 if (dev_handle == 0) { 5354 mptsas_log(mpt, CE_WARN, "!Can't flush target with" 5355 " DevHandle of 0."); 5356 } else { 5357 mptsas_flush_target(mpt, dev_handle, Lun(cmd), 5358 task_type); 5359 } 5360 break; 5361 default: 5362 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.", 5363 task_type); 5364 mptsas_log(mpt, CE_WARN, "ioc status = %x", ioc_status); 5365 break; 5366 } 5367 } 5368 5369 static void 5370 mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg) 5371 { 5372 mptsas_t *mpt = arg->mpt; 5373 uint64_t t = arg->t; 5374 mptsas_cmd_t *cmd; 5375 struct scsi_pkt *pkt; 5376 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 5377 5378 mutex_enter(&item->mutex); 5379 while (item->flag & MPTSAS_DONEQ_THREAD_ACTIVE) { 5380 if (!item->doneq) { 5381 cv_wait(&item->cv, &item->mutex); 5382 } 5383 pkt = NULL; 5384 if ((cmd = mptsas_doneq_thread_rm(mpt, t)) != NULL) { 5385 cmd->cmd_flags |= CFLAG_COMPLETED; 5386 pkt = CMD2PKT(cmd); 5387 } 5388 mutex_exit(&item->mutex); 5389 if (pkt) { 5390 mptsas_pkt_comp(pkt, cmd); 5391 } 5392 mutex_enter(&item->mutex); 5393 } 5394 mutex_exit(&item->mutex); 5395 mutex_enter(&mpt->m_doneq_mutex); 5396 mpt->m_doneq_thread_n--; 5397 cv_broadcast(&mpt->m_doneq_thread_cv); 5398 mutex_exit(&mpt->m_doneq_mutex); 5399 } 5400 5401 /* 5402 * mpt interrupt handler. 5403 */ 5404 static uint_t 5405 mptsas_intr(caddr_t arg1, caddr_t arg2) 5406 { 5407 mptsas_t *mpt = (void *)arg1; 5408 pMpi2ReplyDescriptorsUnion_t reply_desc_union; 5409 uchar_t did_reply = FALSE; 5410 int i = 0, j; 5411 uint8_t reply_type; 5412 uint16_t SMID; 5413 5414 NDBG1(("mptsas_intr: arg1 0x%p arg2 0x%p", (void *)arg1, (void *)arg2)); 5415 5416 /* 5417 * 1. 5418 * To avoid using m_mutex in the ISR(ISR referes not only mptsas_intr, 5419 * but all of the recursive called functions in it. the same below), 5420 * separate mutexs are introduced to protect the elements shown in ISR. 5421 * 3 type of mutex are involved here: 5422 * a)per instance mutex m_intr_mutex. 5423 * b)per target mutex m_tgt_intr_mutex. 5424 * c)mutex that protect the free slot. 5425 * 5426 * a)per instance mutex m_intr_mutex: 5427 * used to protect m_options, m_power, m_waitq, etc that would be 5428 * checked/modified in ISR; protect the getting and setting the reply 5429 * descriptor index; protect the m_slots[]; 5430 * 5431 * b)per target mutex m_tgt_intr_mutex: 5432 * used to protect per target element which has relationship to ISR. 5433 * contention for the new per target mutex is just as high as it in 5434 * sd(7d) driver. 5435 * 5436 * c)mutexs that protect the free slots: 5437 * those mutexs are introduced to minimize the mutex contentions 5438 * between the IO request threads where free slots are allocated 5439 * for sending cmds and ISR where slots holding outstanding cmds 5440 * are returned to the free pool. 5441 * the idea is like this: 5442 * 1) Partition all of the free slot into NCPU groups. For example, 5443 * In system where we have 15 slots, and 4 CPU, then slot s1,s5,s9,s13 5444 * are marked belonging to CPU1, s2,s6,s10,s14 to CPU2, s3,s7,s11,s15 5445 * to CPU3, and s4,s8,s12 to CPU4. 5446 * 2) In each of the group, an alloc/release queue pair is created, 5447 * and both the allocq and the releaseq have a dedicated mutex. 5448 * 3) When init, all of the slots in a CPU group are inserted into the 5449 * allocq of its CPU's pair. 5450 * 4) When doing IO, 5451 * mptsas_scsi_start() 5452 * { 5453 * cpuid = the cpu NO of the cpu where this thread is running on 5454 * retry: 5455 * mutex_enter(&allocq[cpuid]); 5456 * if (get free slot = success) { 5457 * remove the slot from the allocq 5458 * mutex_exit(&allocq[cpuid]); 5459 * return(success); 5460 * } else { // exchange allocq and releaseq and try again 5461 * mutex_enter(&releq[cpuid]); 5462 * exchange the allocq and releaseq of this pair; 5463 * mutex_exit(&releq[cpuid]); 5464 * if (try to get free slot again = success) { 5465 * remove the slot from the allocq 5466 * mutex_exit(&allocq[cpuid]); 5467 * return(success); 5468 * } else { 5469 * MOD(cpuid)++; 5470 * goto retry; 5471 * if (all CPU groups tried) 5472 * mutex_exit(&allocq[cpuid]); 5473 * return(failure); 5474 * } 5475 * } 5476 * } 5477 * ISR() 5478 * { 5479 * cpuid = the CPU group id where the slot sending the 5480 * cmd belongs; 5481 * mutex_enter(&releq[cpuid]); 5482 * remove the slot from the releaseq 5483 * mutex_exit(&releq[cpuid]); 5484 * } 5485 * This way, only when the queue pair doing exchange have mutex 5486 * contentions. 5487 * 5488 * For mutex m_intr_mutex and m_tgt_intr_mutex, there are 2 scenarios: 5489 * 5490 * a)If the elements are only checked but not modified in the ISR, then 5491 * only the places where those elements are modifed(outside of ISR) 5492 * need to be protected by the new introduced mutex. 5493 * For example, data A is only read/checked in ISR, then we need do 5494 * like this: 5495 * In ISR: 5496 * { 5497 * mutex_enter(&new_mutex); 5498 * read(A); 5499 * mutex_exit(&new_mutex); 5500 * //the new_mutex here is either the m_tgt_intr_mutex or 5501 * //the m_intr_mutex. 5502 * } 5503 * In non-ISR 5504 * { 5505 * mutex_enter(&m_mutex); //the stock driver already did this 5506 * mutex_enter(&new_mutex); 5507 * write(A); 5508 * mutex_exit(&new_mutex); 5509 * mutex_exit(&m_mutex); //the stock driver already did this 5510 * 5511 * read(A); 5512 * // read(A) in non-ISR is not required to be protected by new 5513 * // mutex since 'A' has already been protected by m_mutex 5514 * // outside of the ISR 5515 * } 5516 * 5517 * Those fields in mptsas_target_t/ptgt which are only read in ISR 5518 * fall into this catergory. So they, together with the fields which 5519 * are never read in ISR, are not necessary to be protected by 5520 * m_tgt_intr_mutex, don't bother. 5521 * checking of m_waitq also falls into this catergory. so all of the 5522 * place outside of ISR where the m_waitq is modified, such as in 5523 * mptsas_waitq_add(), mptsas_waitq_delete(), mptsas_waitq_rm(), 5524 * m_intr_mutex should be used. 5525 * 5526 * b)If the elements are modified in the ISR, then each place where 5527 * those elements are referred(outside of ISR) need to be protected 5528 * by the new introduced mutex. Of course, if those elements only 5529 * appear in the non-key code path, that is, they don't affect 5530 * performance, then the m_mutex can still be used as before. 5531 * For example, data B is modified in key code path in ISR, and data C 5532 * is modified in non-key code path in ISR, then we can do like this: 5533 * In ISR: 5534 * { 5535 * mutex_enter(&new_mutex); 5536 * wirte(B); 5537 * mutex_exit(&new_mutex); 5538 * if (seldom happen) { 5539 * mutex_enter(&m_mutex); 5540 * write(C); 5541 * mutex_exit(&m_mutex); 5542 * } 5543 * //the new_mutex here is either the m_tgt_intr_mutex or 5544 * //the m_intr_mutex. 5545 * } 5546 * In non-ISR 5547 * { 5548 * mutex_enter(&new_mutex); 5549 * write(B); 5550 * mutex_exit(&new_mutex); 5551 * 5552 * mutex_enter(&new_mutex); 5553 * read(B); 5554 * mutex_exit(&new_mutex); 5555 * // both write(B) and read(B) in non-ISR is required to be 5556 * // protected by new mutex outside of the ISR 5557 * 5558 * mutex_enter(&m_mutex); //the stock driver already did this 5559 * read(C); 5560 * write(C); 5561 * mutex_exit(&m_mutex); //the stock driver already did this 5562 * // both write(C) and read(C) in non-ISR have been already 5563 * // been protected by m_mutex outside of the ISR 5564 * } 5565 * 5566 * For example, ptgt->m_t_ncmds fall into 'B' of this catergory, and 5567 * elements shown in address reply, restart_hba, passthrough, IOC 5568 * fall into 'C' of this catergory. 5569 * 5570 * In any case where mutexs are nested, make sure in the following 5571 * order: 5572 * m_mutex -> m_intr_mutex -> m_tgt_intr_mutex 5573 * m_intr_mutex -> m_tgt_intr_mutex 5574 * m_mutex -> m_intr_mutex 5575 * m_mutex -> m_tgt_intr_mutex 5576 * 5577 * 2. 5578 * Make sure at any time, getting the ReplyDescriptor by m_post_index 5579 * and setting m_post_index to the ReplyDescriptorIndex register are 5580 * atomic. Since m_mutex is not used for this purpose in ISR, the new 5581 * mutex m_intr_mutex must play this role. So mptsas_poll(), where this 5582 * kind of getting/setting is also performed, must use m_intr_mutex. 5583 * Note, since context reply in ISR/process_intr is the only code path 5584 * which affect performance, a fast path is introduced to only handle 5585 * the read/write IO having context reply. For other IOs such as 5586 * passthrough and IOC with context reply and all address reply, we 5587 * use the as-is process_intr() to handle them. In order to keep the 5588 * same semantics in process_intr(), make sure any new mutex is not held 5589 * before enterring it. 5590 */ 5591 5592 mutex_enter(&mpt->m_intr_mutex); 5593 5594 /* 5595 * If interrupts are shared by two channels then check whether this 5596 * interrupt is genuinely for this channel by making sure first the 5597 * chip is in high power state. 5598 */ 5599 if ((mpt->m_options & MPTSAS_OPT_PM) && 5600 (mpt->m_power_level != PM_LEVEL_D0)) { 5601 mutex_exit(&mpt->m_intr_mutex); 5602 return (DDI_INTR_UNCLAIMED); 5603 } 5604 5605 /* 5606 * If polling, interrupt was triggered by some shared interrupt because 5607 * IOC interrupts are disabled during polling, so polling routine will 5608 * handle any replies. Considering this, if polling is happening, 5609 * return with interrupt unclaimed. 5610 */ 5611 if (mpt->m_polled_intr) { 5612 mutex_exit(&mpt->m_intr_mutex); 5613 mptsas_log(mpt, CE_WARN, "mpt_sas: Unclaimed interrupt"); 5614 return (DDI_INTR_UNCLAIMED); 5615 } 5616 5617 /* 5618 * Read the istat register. 5619 */ 5620 if ((INTPENDING(mpt)) != 0) { 5621 /* 5622 * read fifo until empty. 5623 */ 5624 #ifndef __lock_lint 5625 _NOTE(CONSTCOND) 5626 #endif 5627 while (TRUE) { 5628 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 5629 DDI_DMA_SYNC_FORCPU); 5630 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t) 5631 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index); 5632 5633 if (ddi_get32(mpt->m_acc_post_queue_hdl, 5634 &reply_desc_union->Words.Low) == 0xFFFFFFFF || 5635 ddi_get32(mpt->m_acc_post_queue_hdl, 5636 &reply_desc_union->Words.High) == 0xFFFFFFFF) { 5637 break; 5638 } 5639 5640 /* 5641 * The reply is valid, process it according to its 5642 * type. Also, set a flag for updating the reply index 5643 * after they've all been processed. 5644 */ 5645 did_reply = TRUE; 5646 5647 reply_type = ddi_get8(mpt->m_acc_post_queue_hdl, 5648 &reply_desc_union->Default.ReplyFlags); 5649 reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; 5650 mpt->m_reply[i].Default.ReplyFlags = reply_type; 5651 if (reply_type == 5652 MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) { 5653 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, 5654 &reply_desc_union->SCSIIOSuccess.SMID); 5655 if (mptsas_handle_io_fastpath(mpt, SMID) != 5656 TRUE) { 5657 mpt->m_reply[i].SCSIIOSuccess.SMID = 5658 SMID; 5659 i++; 5660 } 5661 } else if (reply_type == 5662 MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { 5663 mpt->m_reply[i].AddressReply.ReplyFrameAddress = 5664 ddi_get32(mpt->m_acc_post_queue_hdl, 5665 &reply_desc_union->AddressReply. 5666 ReplyFrameAddress); 5667 mpt->m_reply[i].AddressReply.SMID = 5668 ddi_get16(mpt->m_acc_post_queue_hdl, 5669 &reply_desc_union->AddressReply.SMID); 5670 i++; 5671 } 5672 /* 5673 * Clear the reply descriptor for re-use and increment 5674 * index. 5675 */ 5676 ddi_put64(mpt->m_acc_post_queue_hdl, 5677 &((uint64_t *)(void *)mpt->m_post_queue) 5678 [mpt->m_post_index], 0xFFFFFFFFFFFFFFFF); 5679 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 5680 DDI_DMA_SYNC_FORDEV); 5681 5682 /* 5683 * Increment post index and roll over if needed. 5684 */ 5685 if (++mpt->m_post_index == mpt->m_post_queue_depth) { 5686 mpt->m_post_index = 0; 5687 } 5688 if (i >= MPI_ADDRESS_COALSCE_MAX) 5689 break; 5690 } 5691 5692 /* 5693 * Update the global reply index if at least one reply was 5694 * processed. 5695 */ 5696 if (did_reply) { 5697 ddi_put32(mpt->m_datap, 5698 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); 5699 5700 /* 5701 * For fma, only check the PIO is required and enough 5702 * here. Those cases where fastpath is not hit, the 5703 * mptsas_fma_check() check all of the types of 5704 * fma. That is not necessary and sometimes not 5705 * correct. fma check should only be done after 5706 * the PIO and/or dma is performed. 5707 */ 5708 if ((mptsas_check_acc_handle(mpt->m_datap) != 5709 DDI_SUCCESS)) { 5710 ddi_fm_service_impact(mpt->m_dip, 5711 DDI_SERVICE_UNAFFECTED); 5712 } 5713 5714 } 5715 } else { 5716 mutex_exit(&mpt->m_intr_mutex); 5717 return (DDI_INTR_UNCLAIMED); 5718 } 5719 NDBG1(("mptsas_intr complete")); 5720 mutex_exit(&mpt->m_intr_mutex); 5721 5722 /* 5723 * Since most of the cmds(read and write IO with success return.) 5724 * have already been processed in fast path in which the m_mutex 5725 * is not held, handling here the address reply and other context reply 5726 * such as passthrough and IOC cmd with m_mutex held should be a big 5727 * issue for performance. 5728 * If holding m_mutex to process these cmds was still an obvious issue, 5729 * we can process them in a taskq. 5730 */ 5731 for (j = 0; j < i; j++) { 5732 mutex_enter(&mpt->m_mutex); 5733 mptsas_process_intr(mpt, &mpt->m_reply[j]); 5734 mutex_exit(&mpt->m_mutex); 5735 } 5736 5737 /* 5738 * If no helper threads are created, process the doneq in ISR. If 5739 * helpers are created, use the doneq length as a metric to measure the 5740 * load on the interrupt CPU. If it is long enough, which indicates the 5741 * load is heavy, then we deliver the IO completions to the helpers. 5742 * This measurement has some limitations, although it is simple and 5743 * straightforward and works well for most of the cases at present. 5744 */ 5745 if (!mpt->m_doneq_thread_n) { 5746 mptsas_doneq_empty(mpt); 5747 } else { 5748 int helper = 1; 5749 mutex_enter(&mpt->m_intr_mutex); 5750 if (mpt->m_doneq_len <= mpt->m_doneq_length_threshold) 5751 helper = 0; 5752 mutex_exit(&mpt->m_intr_mutex); 5753 if (helper) { 5754 mptsas_deliver_doneq_thread(mpt); 5755 } else { 5756 mptsas_doneq_empty(mpt); 5757 } 5758 } 5759 5760 /* 5761 * If there are queued cmd, start them now. 5762 */ 5763 mutex_enter(&mpt->m_intr_mutex); 5764 if (mpt->m_waitq != NULL) { 5765 mutex_exit(&mpt->m_intr_mutex); 5766 mutex_enter(&mpt->m_mutex); 5767 mptsas_restart_hba(mpt); 5768 mutex_exit(&mpt->m_mutex); 5769 return (DDI_INTR_CLAIMED); 5770 } 5771 mutex_exit(&mpt->m_intr_mutex); 5772 return (DDI_INTR_CLAIMED); 5773 } 5774 5775 /* 5776 * In ISR, the successfully completed read and write IO are processed in a 5777 * fast path. This function is only used to handle non-fastpath IO, including 5778 * all of the address reply, and the context reply for IOC cmd, passthrough, 5779 * etc. 5780 * This function is also used to process polled cmd. 5781 */ 5782 static void 5783 mptsas_process_intr(mptsas_t *mpt, 5784 pMpi2ReplyDescriptorsUnion_t reply_desc_union) 5785 { 5786 uint8_t reply_type; 5787 5788 /* 5789 * The reply is valid, process it according to its 5790 * type. Also, set a flag for updated the reply index 5791 * after they've all been processed. 5792 */ 5793 reply_type = reply_desc_union->Default.ReplyFlags; 5794 if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) { 5795 mptsas_handle_scsi_io_success(mpt, reply_desc_union); 5796 } else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { 5797 mptsas_handle_address_reply(mpt, reply_desc_union); 5798 } else { 5799 mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type); 5800 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 5801 } 5802 } 5803 5804 /* 5805 * handle qfull condition 5806 */ 5807 static void 5808 mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd) 5809 { 5810 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 5811 5812 if ((++cmd->cmd_qfull_retries > ptgt->m_qfull_retries) || 5813 (ptgt->m_qfull_retries == 0)) { 5814 /* 5815 * We have exhausted the retries on QFULL, or, 5816 * the target driver has indicated that it 5817 * wants to handle QFULL itself by setting 5818 * qfull-retries capability to 0. In either case 5819 * we want the target driver's QFULL handling 5820 * to kick in. We do this by having pkt_reason 5821 * as CMD_CMPLT and pkt_scbp as STATUS_QFULL. 5822 */ 5823 mutex_enter(&ptgt->m_tgt_intr_mutex); 5824 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5825 mutex_exit(&ptgt->m_tgt_intr_mutex); 5826 } else { 5827 mutex_enter(&ptgt->m_tgt_intr_mutex); 5828 if (ptgt->m_reset_delay == 0) { 5829 ptgt->m_t_throttle = 5830 max((ptgt->m_t_ncmds - 2), 0); 5831 } 5832 mutex_exit(&ptgt->m_tgt_intr_mutex); 5833 5834 cmd->cmd_pkt_flags |= FLAG_HEAD; 5835 cmd->cmd_flags &= ~(CFLAG_TRANFLAG); 5836 cmd->cmd_flags |= CFLAG_RETRY; 5837 5838 mutex_exit(&mpt->m_mutex); 5839 (void) mptsas_accept_pkt(mpt, cmd); 5840 mutex_enter(&mpt->m_mutex); 5841 5842 /* 5843 * when target gives queue full status with no commands 5844 * outstanding (m_t_ncmds == 0), throttle is set to 0 5845 * (HOLD_THROTTLE), and the queue full handling start 5846 * (see psarc/1994/313); if there are commands outstanding, 5847 * throttle is set to (m_t_ncmds - 2) 5848 */ 5849 mutex_enter(&ptgt->m_tgt_intr_mutex); 5850 if (ptgt->m_t_throttle == HOLD_THROTTLE) { 5851 /* 5852 * By setting throttle to QFULL_THROTTLE, we 5853 * avoid submitting new commands and in 5854 * mptsas_restart_cmd find out slots which need 5855 * their throttles to be cleared. 5856 */ 5857 mptsas_set_throttle(mpt, ptgt, QFULL_THROTTLE); 5858 if (mpt->m_restart_cmd_timeid == 0) { 5859 mpt->m_restart_cmd_timeid = 5860 timeout(mptsas_restart_cmd, mpt, 5861 ptgt->m_qfull_retry_interval); 5862 } 5863 } 5864 mutex_exit(&ptgt->m_tgt_intr_mutex); 5865 } 5866 } 5867 5868 mptsas_phymask_t 5869 mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport) 5870 { 5871 mptsas_phymask_t phy_mask = 0; 5872 uint8_t i = 0; 5873 5874 NDBG20(("mptsas%d physport_to_phymask enter", mpt->m_instance)); 5875 5876 ASSERT(mutex_owned(&mpt->m_mutex)); 5877 5878 /* 5879 * If physport is 0xFF, this is a RAID volume. Use phymask of 0. 5880 */ 5881 if (physport == 0xFF) { 5882 return (0); 5883 } 5884 5885 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 5886 if (mpt->m_phy_info[i].attached_devhdl && 5887 (mpt->m_phy_info[i].phy_mask != 0) && 5888 (mpt->m_phy_info[i].port_num == physport)) { 5889 phy_mask = mpt->m_phy_info[i].phy_mask; 5890 break; 5891 } 5892 } 5893 NDBG20(("mptsas%d physport_to_phymask:physport :%x phymask :%x, ", 5894 mpt->m_instance, physport, phy_mask)); 5895 return (phy_mask); 5896 } 5897 5898 /* 5899 * mpt free device handle after device gone, by use of passthrough 5900 */ 5901 static int 5902 mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl) 5903 { 5904 Mpi2SasIoUnitControlRequest_t req; 5905 Mpi2SasIoUnitControlReply_t rep; 5906 int ret; 5907 5908 ASSERT(mutex_owned(&mpt->m_mutex)); 5909 5910 /* 5911 * Need to compose a SAS IO Unit Control request message 5912 * and call mptsas_do_passthru() function 5913 */ 5914 bzero(&req, sizeof (req)); 5915 bzero(&rep, sizeof (rep)); 5916 5917 req.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 5918 req.Operation = MPI2_SAS_OP_REMOVE_DEVICE; 5919 req.DevHandle = LE_16(devhdl); 5920 5921 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL, 5922 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL); 5923 if (ret != 0) { 5924 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit " 5925 "Control error %d", ret); 5926 return (DDI_FAILURE); 5927 } 5928 5929 /* do passthrough success, check the ioc status */ 5930 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 5931 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit " 5932 "Control IOCStatus %d", LE_16(rep.IOCStatus)); 5933 return (DDI_FAILURE); 5934 } 5935 5936 return (DDI_SUCCESS); 5937 } 5938 5939 static void 5940 mptsas_update_phymask(mptsas_t *mpt) 5941 { 5942 mptsas_phymask_t mask = 0, phy_mask; 5943 char *phy_mask_name; 5944 uint8_t current_port; 5945 int i, j; 5946 5947 NDBG20(("mptsas%d update phymask ", mpt->m_instance)); 5948 5949 ASSERT(mutex_owned(&mpt->m_mutex)); 5950 5951 (void) mptsas_get_sas_io_unit_page(mpt); 5952 5953 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 5954 5955 for (i = 0; i < mpt->m_num_phys; i++) { 5956 phy_mask = 0x00; 5957 5958 if (mpt->m_phy_info[i].attached_devhdl == 0) 5959 continue; 5960 5961 bzero(phy_mask_name, sizeof (phy_mask_name)); 5962 5963 current_port = mpt->m_phy_info[i].port_num; 5964 5965 if ((mask & (1 << i)) != 0) 5966 continue; 5967 5968 for (j = 0; j < mpt->m_num_phys; j++) { 5969 if (mpt->m_phy_info[j].attached_devhdl && 5970 (mpt->m_phy_info[j].port_num == current_port)) { 5971 phy_mask |= (1 << j); 5972 } 5973 } 5974 mask = mask | phy_mask; 5975 5976 for (j = 0; j < mpt->m_num_phys; j++) { 5977 if ((phy_mask >> j) & 0x01) { 5978 mpt->m_phy_info[j].phy_mask = phy_mask; 5979 } 5980 } 5981 5982 (void) sprintf(phy_mask_name, "%x", phy_mask); 5983 5984 mutex_exit(&mpt->m_mutex); 5985 /* 5986 * register a iport, if the port has already been existed 5987 * SCSA will do nothing and just return. 5988 */ 5989 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name); 5990 mutex_enter(&mpt->m_mutex); 5991 } 5992 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 5993 NDBG20(("mptsas%d update phymask return", mpt->m_instance)); 5994 } 5995 5996 /* 5997 * mptsas_handle_dr is a task handler for DR, the DR action includes: 5998 * 1. Directly attched Device Added/Removed. 5999 * 2. Expander Device Added/Removed. 6000 * 3. Indirectly Attached Device Added/Expander. 6001 * 4. LUNs of a existing device status change. 6002 * 5. RAID volume created/deleted. 6003 * 6. Member of RAID volume is released because of RAID deletion. 6004 * 7. Physical disks are removed because of RAID creation. 6005 */ 6006 static void 6007 mptsas_handle_dr(void *args) { 6008 mptsas_topo_change_list_t *topo_node = NULL; 6009 mptsas_topo_change_list_t *save_node = NULL; 6010 mptsas_t *mpt; 6011 dev_info_t *parent = NULL; 6012 mptsas_phymask_t phymask = 0; 6013 char *phy_mask_name; 6014 uint8_t flags = 0, physport = 0xff; 6015 uint8_t port_update = 0; 6016 uint_t event; 6017 6018 topo_node = (mptsas_topo_change_list_t *)args; 6019 6020 mpt = topo_node->mpt; 6021 event = topo_node->event; 6022 flags = topo_node->flags; 6023 6024 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 6025 6026 NDBG20(("mptsas%d handle_dr enter", mpt->m_instance)); 6027 6028 switch (event) { 6029 case MPTSAS_DR_EVENT_RECONFIG_TARGET: 6030 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 6031 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE) || 6032 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) { 6033 /* 6034 * Direct attached or expander attached device added 6035 * into system or a Phys Disk that is being unhidden. 6036 */ 6037 port_update = 1; 6038 } 6039 break; 6040 case MPTSAS_DR_EVENT_RECONFIG_SMP: 6041 /* 6042 * New expander added into system, it must be the head 6043 * of topo_change_list_t 6044 */ 6045 port_update = 1; 6046 break; 6047 default: 6048 port_update = 0; 6049 break; 6050 } 6051 /* 6052 * All cases port_update == 1 may cause initiator port form change 6053 */ 6054 mutex_enter(&mpt->m_mutex); 6055 if (mpt->m_port_chng && port_update) { 6056 /* 6057 * mpt->m_port_chng flag indicates some PHYs of initiator 6058 * port have changed to online. So when expander added or 6059 * directly attached device online event come, we force to 6060 * update port information by issueing SAS IO Unit Page and 6061 * update PHYMASKs. 6062 */ 6063 (void) mptsas_update_phymask(mpt); 6064 mpt->m_port_chng = 0; 6065 6066 } 6067 mutex_exit(&mpt->m_mutex); 6068 while (topo_node) { 6069 phymask = 0; 6070 if (parent == NULL) { 6071 physport = topo_node->un.physport; 6072 event = topo_node->event; 6073 flags = topo_node->flags; 6074 if (event & (MPTSAS_DR_EVENT_OFFLINE_TARGET | 6075 MPTSAS_DR_EVENT_OFFLINE_SMP)) { 6076 /* 6077 * For all offline events, phymask is known 6078 */ 6079 phymask = topo_node->un.phymask; 6080 goto find_parent; 6081 } 6082 if (event & MPTSAS_TOPO_FLAG_REMOVE_HANDLE) { 6083 goto handle_topo_change; 6084 } 6085 if (flags & MPTSAS_TOPO_FLAG_LUN_ASSOCIATED) { 6086 phymask = topo_node->un.phymask; 6087 goto find_parent; 6088 } 6089 6090 if ((flags == 6091 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) && 6092 (event == MPTSAS_DR_EVENT_RECONFIG_TARGET)) { 6093 /* 6094 * There is no any field in IR_CONFIG_CHANGE 6095 * event indicate physport/phynum, let's get 6096 * parent after SAS Device Page0 request. 6097 */ 6098 goto handle_topo_change; 6099 } 6100 6101 mutex_enter(&mpt->m_mutex); 6102 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 6103 /* 6104 * If the direct attached device added or a 6105 * phys disk is being unhidden, argument 6106 * physport actually is PHY#, so we have to get 6107 * phymask according PHY#. 6108 */ 6109 physport = mpt->m_phy_info[physport].port_num; 6110 } 6111 6112 /* 6113 * Translate physport to phymask so that we can search 6114 * parent dip. 6115 */ 6116 phymask = mptsas_physport_to_phymask(mpt, 6117 physport); 6118 mutex_exit(&mpt->m_mutex); 6119 6120 find_parent: 6121 bzero(phy_mask_name, MPTSAS_MAX_PHYS); 6122 /* 6123 * For RAID topology change node, write the iport name 6124 * as v0. 6125 */ 6126 if (flags & MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 6127 (void) sprintf(phy_mask_name, "v0"); 6128 } else { 6129 /* 6130 * phymask can bo 0 if the drive has been 6131 * pulled by the time an add event is 6132 * processed. If phymask is 0, just skip this 6133 * event and continue. 6134 */ 6135 if (phymask == 0) { 6136 mutex_enter(&mpt->m_mutex); 6137 save_node = topo_node; 6138 topo_node = topo_node->next; 6139 ASSERT(save_node); 6140 kmem_free(save_node, 6141 sizeof (mptsas_topo_change_list_t)); 6142 mutex_exit(&mpt->m_mutex); 6143 6144 parent = NULL; 6145 continue; 6146 } 6147 (void) sprintf(phy_mask_name, "%x", phymask); 6148 } 6149 parent = scsi_hba_iport_find(mpt->m_dip, 6150 phy_mask_name); 6151 if (parent == NULL) { 6152 mptsas_log(mpt, CE_WARN, "Failed to find an " 6153 "iport, should not happen!"); 6154 goto out; 6155 } 6156 6157 } 6158 ASSERT(parent); 6159 handle_topo_change: 6160 6161 mutex_enter(&mpt->m_mutex); 6162 6163 mptsas_handle_topo_change(topo_node, parent); 6164 save_node = topo_node; 6165 topo_node = topo_node->next; 6166 ASSERT(save_node); 6167 kmem_free(save_node, sizeof (mptsas_topo_change_list_t)); 6168 mutex_exit(&mpt->m_mutex); 6169 6170 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 6171 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) || 6172 (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) { 6173 /* 6174 * If direct attached device associated, make sure 6175 * reset the parent before start the next one. But 6176 * all devices associated with expander shares the 6177 * parent. Also, reset parent if this is for RAID. 6178 */ 6179 parent = NULL; 6180 } 6181 } 6182 out: 6183 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 6184 } 6185 6186 static void 6187 mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node, 6188 dev_info_t *parent) 6189 { 6190 mptsas_target_t *ptgt = NULL; 6191 mptsas_smp_t *psmp = NULL; 6192 mptsas_t *mpt = (void *)topo_node->mpt; 6193 uint16_t devhdl; 6194 uint16_t attached_devhdl; 6195 uint64_t sas_wwn = 0; 6196 int rval = 0; 6197 uint32_t page_address; 6198 uint8_t phy, flags; 6199 char *addr = NULL; 6200 dev_info_t *lundip; 6201 int circ = 0, circ1 = 0; 6202 char attached_wwnstr[MPTSAS_WWN_STRLEN]; 6203 6204 NDBG20(("mptsas%d handle_topo_change enter", mpt->m_instance)); 6205 6206 ASSERT(mutex_owned(&mpt->m_mutex)); 6207 6208 switch (topo_node->event) { 6209 case MPTSAS_DR_EVENT_RECONFIG_TARGET: 6210 { 6211 char *phy_mask_name; 6212 mptsas_phymask_t phymask = 0; 6213 6214 if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 6215 /* 6216 * Get latest RAID info. 6217 */ 6218 (void) mptsas_get_raid_info(mpt); 6219 ptgt = mptsas_search_by_devhdl( 6220 &mpt->m_active->m_tgttbl, topo_node->devhdl); 6221 if (ptgt == NULL) 6222 break; 6223 } else { 6224 ptgt = (void *)topo_node->object; 6225 } 6226 6227 if (ptgt == NULL) { 6228 /* 6229 * If a Phys Disk was deleted, RAID info needs to be 6230 * updated to reflect the new topology. 6231 */ 6232 (void) mptsas_get_raid_info(mpt); 6233 6234 /* 6235 * Get sas device page 0 by DevHandle to make sure if 6236 * SSP/SATA end device exist. 6237 */ 6238 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 6239 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 6240 topo_node->devhdl; 6241 6242 rval = mptsas_get_target_device_info(mpt, page_address, 6243 &devhdl, &ptgt); 6244 if (rval == DEV_INFO_WRONG_DEVICE_TYPE) { 6245 mptsas_log(mpt, CE_NOTE, 6246 "mptsas_handle_topo_change: target %d is " 6247 "not a SAS/SATA device. \n", 6248 topo_node->devhdl); 6249 } else if (rval == DEV_INFO_FAIL_ALLOC) { 6250 mptsas_log(mpt, CE_NOTE, 6251 "mptsas_handle_topo_change: could not " 6252 "allocate memory. \n"); 6253 } 6254 /* 6255 * If rval is DEV_INFO_PHYS_DISK than there is nothing 6256 * else to do, just leave. 6257 */ 6258 if (rval != DEV_INFO_SUCCESS) { 6259 return; 6260 } 6261 } 6262 6263 ASSERT(ptgt->m_devhdl == topo_node->devhdl); 6264 6265 mutex_exit(&mpt->m_mutex); 6266 flags = topo_node->flags; 6267 6268 if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) { 6269 phymask = ptgt->m_phymask; 6270 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 6271 (void) sprintf(phy_mask_name, "%x", phymask); 6272 parent = scsi_hba_iport_find(mpt->m_dip, 6273 phy_mask_name); 6274 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 6275 if (parent == NULL) { 6276 mptsas_log(mpt, CE_WARN, "Failed to find a " 6277 "iport for PD, should not happen!"); 6278 mutex_enter(&mpt->m_mutex); 6279 break; 6280 } 6281 } 6282 6283 if (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 6284 ndi_devi_enter(parent, &circ1); 6285 (void) mptsas_config_raid(parent, topo_node->devhdl, 6286 &lundip); 6287 ndi_devi_exit(parent, circ1); 6288 } else { 6289 /* 6290 * hold nexus for bus configure 6291 */ 6292 ndi_devi_enter(scsi_vhci_dip, &circ); 6293 ndi_devi_enter(parent, &circ1); 6294 rval = mptsas_config_target(parent, ptgt); 6295 /* 6296 * release nexus for bus configure 6297 */ 6298 ndi_devi_exit(parent, circ1); 6299 ndi_devi_exit(scsi_vhci_dip, circ); 6300 6301 /* 6302 * Add parent's props for SMHBA support 6303 */ 6304 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 6305 bzero(attached_wwnstr, 6306 sizeof (attached_wwnstr)); 6307 (void) sprintf(attached_wwnstr, "w%016"PRIx64, 6308 ptgt->m_sas_wwn); 6309 if (ddi_prop_update_string(DDI_DEV_T_NONE, 6310 parent, 6311 SCSI_ADDR_PROP_ATTACHED_PORT, 6312 attached_wwnstr) 6313 != DDI_PROP_SUCCESS) { 6314 (void) ddi_prop_remove(DDI_DEV_T_NONE, 6315 parent, 6316 SCSI_ADDR_PROP_ATTACHED_PORT); 6317 mptsas_log(mpt, CE_WARN, "Failed to" 6318 "attached-port props"); 6319 return; 6320 } 6321 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6322 MPTSAS_NUM_PHYS, 1) != 6323 DDI_PROP_SUCCESS) { 6324 (void) ddi_prop_remove(DDI_DEV_T_NONE, 6325 parent, MPTSAS_NUM_PHYS); 6326 mptsas_log(mpt, CE_WARN, "Failed to" 6327 " create num-phys props"); 6328 return; 6329 } 6330 6331 /* 6332 * Update PHY info for smhba 6333 */ 6334 mutex_enter(&mpt->m_mutex); 6335 if (mptsas_smhba_phy_init(mpt)) { 6336 mutex_exit(&mpt->m_mutex); 6337 mptsas_log(mpt, CE_WARN, "mptsas phy" 6338 " update failed"); 6339 return; 6340 } 6341 mutex_exit(&mpt->m_mutex); 6342 mptsas_smhba_set_phy_props(mpt, 6343 ddi_get_name_addr(parent), parent, 6344 1, &attached_devhdl); 6345 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6346 MPTSAS_VIRTUAL_PORT, 0) != 6347 DDI_PROP_SUCCESS) { 6348 (void) ddi_prop_remove(DDI_DEV_T_NONE, 6349 parent, MPTSAS_VIRTUAL_PORT); 6350 mptsas_log(mpt, CE_WARN, 6351 "mptsas virtual-port" 6352 "port prop update failed"); 6353 return; 6354 } 6355 } 6356 } 6357 mutex_enter(&mpt->m_mutex); 6358 6359 NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, " 6360 "phymask:%x.", mpt->m_instance, ptgt->m_devhdl, 6361 ptgt->m_phymask)); 6362 break; 6363 } 6364 case MPTSAS_DR_EVENT_OFFLINE_TARGET: 6365 { 6366 mptsas_hash_table_t *tgttbl = &mpt->m_active->m_tgttbl; 6367 devhdl = topo_node->devhdl; 6368 ptgt = mptsas_search_by_devhdl(tgttbl, devhdl); 6369 if (ptgt == NULL) 6370 break; 6371 6372 sas_wwn = ptgt->m_sas_wwn; 6373 phy = ptgt->m_phynum; 6374 6375 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 6376 6377 if (sas_wwn) { 6378 (void) sprintf(addr, "w%016"PRIx64, sas_wwn); 6379 } else { 6380 (void) sprintf(addr, "p%x", phy); 6381 } 6382 ASSERT(ptgt->m_devhdl == devhdl); 6383 6384 if ((topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) || 6385 (topo_node->flags == 6386 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) { 6387 /* 6388 * Get latest RAID info if RAID volume status changes 6389 * or Phys Disk status changes 6390 */ 6391 (void) mptsas_get_raid_info(mpt); 6392 } 6393 /* 6394 * Abort all outstanding command on the device 6395 */ 6396 rval = mptsas_do_scsi_reset(mpt, devhdl); 6397 if (rval) { 6398 NDBG20(("mptsas%d handle_topo_change to reset target " 6399 "before offline devhdl:%x, phymask:%x, rval:%x", 6400 mpt->m_instance, ptgt->m_devhdl, ptgt->m_phymask, 6401 rval)); 6402 } 6403 6404 mutex_exit(&mpt->m_mutex); 6405 6406 ndi_devi_enter(scsi_vhci_dip, &circ); 6407 ndi_devi_enter(parent, &circ1); 6408 rval = mptsas_offline_target(parent, addr); 6409 ndi_devi_exit(parent, circ1); 6410 ndi_devi_exit(scsi_vhci_dip, circ); 6411 NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, " 6412 "phymask:%x, rval:%x", mpt->m_instance, 6413 ptgt->m_devhdl, ptgt->m_phymask, rval)); 6414 6415 kmem_free(addr, SCSI_MAXNAMELEN); 6416 6417 /* 6418 * Clear parent's props for SMHBA support 6419 */ 6420 flags = topo_node->flags; 6421 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 6422 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6423 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent, 6424 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 6425 DDI_PROP_SUCCESS) { 6426 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6427 SCSI_ADDR_PROP_ATTACHED_PORT); 6428 mptsas_log(mpt, CE_WARN, "mptsas attached port " 6429 "prop update failed"); 6430 break; 6431 } 6432 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6433 MPTSAS_NUM_PHYS, 0) != 6434 DDI_PROP_SUCCESS) { 6435 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6436 MPTSAS_NUM_PHYS); 6437 mptsas_log(mpt, CE_WARN, "mptsas num phys " 6438 "prop update failed"); 6439 break; 6440 } 6441 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6442 MPTSAS_VIRTUAL_PORT, 1) != 6443 DDI_PROP_SUCCESS) { 6444 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6445 MPTSAS_VIRTUAL_PORT); 6446 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 6447 "prop update failed"); 6448 break; 6449 } 6450 } 6451 6452 mutex_enter(&mpt->m_mutex); 6453 if (mptsas_set_led_status(mpt, ptgt, 0) != DDI_SUCCESS) { 6454 NDBG14(("mptsas: clear LED for tgt %x failed", 6455 ptgt->m_slot_num)); 6456 } 6457 if (rval == DDI_SUCCESS) { 6458 mptsas_tgt_free(&mpt->m_active->m_tgttbl, 6459 ptgt->m_sas_wwn, ptgt->m_phymask); 6460 ptgt = NULL; 6461 } else { 6462 /* 6463 * clean DR_INTRANSITION flag to allow I/O down to 6464 * PHCI driver since failover finished. 6465 * Invalidate the devhdl 6466 */ 6467 mutex_enter(&ptgt->m_tgt_intr_mutex); 6468 ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL; 6469 ptgt->m_tgt_unconfigured = 0; 6470 ptgt->m_dr_flag = MPTSAS_DR_INACTIVE; 6471 mutex_exit(&ptgt->m_tgt_intr_mutex); 6472 } 6473 6474 /* 6475 * Send SAS IO Unit Control to free the dev handle 6476 */ 6477 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 6478 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE)) { 6479 rval = mptsas_free_devhdl(mpt, devhdl); 6480 6481 NDBG20(("mptsas%d handle_topo_change to remove " 6482 "devhdl:%x, rval:%x", mpt->m_instance, devhdl, 6483 rval)); 6484 } 6485 6486 break; 6487 } 6488 case MPTSAS_TOPO_FLAG_REMOVE_HANDLE: 6489 { 6490 devhdl = topo_node->devhdl; 6491 /* 6492 * If this is the remove handle event, do a reset first. 6493 */ 6494 if (topo_node->event == MPTSAS_TOPO_FLAG_REMOVE_HANDLE) { 6495 rval = mptsas_do_scsi_reset(mpt, devhdl); 6496 if (rval) { 6497 NDBG20(("mpt%d reset target before remove " 6498 "devhdl:%x, rval:%x", mpt->m_instance, 6499 devhdl, rval)); 6500 } 6501 } 6502 6503 /* 6504 * Send SAS IO Unit Control to free the dev handle 6505 */ 6506 rval = mptsas_free_devhdl(mpt, devhdl); 6507 NDBG20(("mptsas%d handle_topo_change to remove " 6508 "devhdl:%x, rval:%x", mpt->m_instance, devhdl, 6509 rval)); 6510 break; 6511 } 6512 case MPTSAS_DR_EVENT_RECONFIG_SMP: 6513 { 6514 mptsas_smp_t smp; 6515 dev_info_t *smpdip; 6516 mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl; 6517 6518 devhdl = topo_node->devhdl; 6519 6520 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL & 6521 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl; 6522 rval = mptsas_get_sas_expander_page0(mpt, page_address, &smp); 6523 if (rval != DDI_SUCCESS) { 6524 mptsas_log(mpt, CE_WARN, "failed to online smp, " 6525 "handle %x", devhdl); 6526 return; 6527 } 6528 6529 psmp = mptsas_smp_alloc(smptbl, &smp); 6530 if (psmp == NULL) { 6531 return; 6532 } 6533 6534 mutex_exit(&mpt->m_mutex); 6535 ndi_devi_enter(parent, &circ1); 6536 (void) mptsas_online_smp(parent, psmp, &smpdip); 6537 ndi_devi_exit(parent, circ1); 6538 6539 mutex_enter(&mpt->m_mutex); 6540 break; 6541 } 6542 case MPTSAS_DR_EVENT_OFFLINE_SMP: 6543 { 6544 mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl; 6545 devhdl = topo_node->devhdl; 6546 uint32_t dev_info; 6547 6548 psmp = mptsas_search_by_devhdl(smptbl, devhdl); 6549 if (psmp == NULL) 6550 break; 6551 /* 6552 * The mptsas_smp_t data is released only if the dip is offlined 6553 * successfully. 6554 */ 6555 mutex_exit(&mpt->m_mutex); 6556 6557 ndi_devi_enter(parent, &circ1); 6558 rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE); 6559 ndi_devi_exit(parent, circ1); 6560 6561 dev_info = psmp->m_deviceinfo; 6562 if ((dev_info & DEVINFO_DIRECT_ATTACHED) == 6563 DEVINFO_DIRECT_ATTACHED) { 6564 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6565 MPTSAS_VIRTUAL_PORT, 1) != 6566 DDI_PROP_SUCCESS) { 6567 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6568 MPTSAS_VIRTUAL_PORT); 6569 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 6570 "prop update failed"); 6571 return; 6572 } 6573 /* 6574 * Check whether the smp connected to the iport, 6575 */ 6576 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6577 MPTSAS_NUM_PHYS, 0) != 6578 DDI_PROP_SUCCESS) { 6579 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6580 MPTSAS_NUM_PHYS); 6581 mptsas_log(mpt, CE_WARN, "mptsas num phys" 6582 "prop update failed"); 6583 return; 6584 } 6585 /* 6586 * Clear parent's attached-port props 6587 */ 6588 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6589 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent, 6590 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 6591 DDI_PROP_SUCCESS) { 6592 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6593 SCSI_ADDR_PROP_ATTACHED_PORT); 6594 mptsas_log(mpt, CE_WARN, "mptsas attached port " 6595 "prop update failed"); 6596 return; 6597 } 6598 } 6599 6600 mutex_enter(&mpt->m_mutex); 6601 NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, " 6602 "rval:%x", mpt->m_instance, psmp->m_devhdl, rval)); 6603 if (rval == DDI_SUCCESS) { 6604 mptsas_smp_free(smptbl, psmp->m_sasaddr, 6605 psmp->m_phymask); 6606 } else { 6607 psmp->m_devhdl = MPTSAS_INVALID_DEVHDL; 6608 } 6609 6610 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6611 6612 break; 6613 } 6614 default: 6615 return; 6616 } 6617 } 6618 6619 /* 6620 * Record the event if its type is enabled in mpt instance by ioctl. 6621 */ 6622 static void 6623 mptsas_record_event(void *args) 6624 { 6625 m_replyh_arg_t *replyh_arg; 6626 pMpi2EventNotificationReply_t eventreply; 6627 uint32_t event, rfm; 6628 mptsas_t *mpt; 6629 int i, j; 6630 uint16_t event_data_len; 6631 boolean_t sendAEN = FALSE; 6632 6633 replyh_arg = (m_replyh_arg_t *)args; 6634 rfm = replyh_arg->rfm; 6635 mpt = replyh_arg->mpt; 6636 6637 eventreply = (pMpi2EventNotificationReply_t) 6638 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr)); 6639 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 6640 6641 6642 /* 6643 * Generate a system event to let anyone who cares know that a 6644 * LOG_ENTRY_ADDED event has occurred. This is sent no matter what the 6645 * event mask is set to. 6646 */ 6647 if (event == MPI2_EVENT_LOG_ENTRY_ADDED) { 6648 sendAEN = TRUE; 6649 } 6650 6651 /* 6652 * Record the event only if it is not masked. Determine which dword 6653 * and bit of event mask to test. 6654 */ 6655 i = (uint8_t)(event / 32); 6656 j = (uint8_t)(event % 32); 6657 if ((i < 4) && ((1 << j) & mpt->m_event_mask[i])) { 6658 i = mpt->m_event_index; 6659 mpt->m_events[i].Type = event; 6660 mpt->m_events[i].Number = ++mpt->m_event_number; 6661 bzero(mpt->m_events[i].Data, MPTSAS_MAX_EVENT_DATA_LENGTH * 4); 6662 event_data_len = ddi_get16(mpt->m_acc_reply_frame_hdl, 6663 &eventreply->EventDataLength); 6664 6665 if (event_data_len > 0) { 6666 /* 6667 * Limit data to size in m_event entry 6668 */ 6669 if (event_data_len > MPTSAS_MAX_EVENT_DATA_LENGTH) { 6670 event_data_len = MPTSAS_MAX_EVENT_DATA_LENGTH; 6671 } 6672 for (j = 0; j < event_data_len; j++) { 6673 mpt->m_events[i].Data[j] = 6674 ddi_get32(mpt->m_acc_reply_frame_hdl, 6675 &(eventreply->EventData[j])); 6676 } 6677 6678 /* 6679 * check for index wrap-around 6680 */ 6681 if (++i == MPTSAS_EVENT_QUEUE_SIZE) { 6682 i = 0; 6683 } 6684 mpt->m_event_index = (uint8_t)i; 6685 6686 /* 6687 * Set flag to send the event. 6688 */ 6689 sendAEN = TRUE; 6690 } 6691 } 6692 6693 /* 6694 * Generate a system event if flag is set to let anyone who cares know 6695 * that an event has occurred. 6696 */ 6697 if (sendAEN) { 6698 (void) ddi_log_sysevent(mpt->m_dip, DDI_VENDOR_LSI, "MPT_SAS", 6699 "SAS", NULL, NULL, DDI_NOSLEEP); 6700 } 6701 } 6702 6703 #define SMP_RESET_IN_PROGRESS MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS 6704 /* 6705 * handle sync events from ioc in interrupt 6706 * return value: 6707 * DDI_SUCCESS: The event is handled by this func 6708 * DDI_FAILURE: Event is not handled 6709 */ 6710 static int 6711 mptsas_handle_event_sync(void *args) 6712 { 6713 m_replyh_arg_t *replyh_arg; 6714 pMpi2EventNotificationReply_t eventreply; 6715 uint32_t event, rfm; 6716 mptsas_t *mpt; 6717 uint_t iocstatus; 6718 6719 replyh_arg = (m_replyh_arg_t *)args; 6720 rfm = replyh_arg->rfm; 6721 mpt = replyh_arg->mpt; 6722 6723 ASSERT(mutex_owned(&mpt->m_mutex)); 6724 6725 eventreply = (pMpi2EventNotificationReply_t) 6726 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr)); 6727 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 6728 6729 if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 6730 &eventreply->IOCStatus)) { 6731 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 6732 mptsas_log(mpt, CE_WARN, 6733 "!mptsas_handle_event_sync: IOCStatus=0x%x, " 6734 "IOCLogInfo=0x%x", iocstatus, 6735 ddi_get32(mpt->m_acc_reply_frame_hdl, 6736 &eventreply->IOCLogInfo)); 6737 } else { 6738 mptsas_log(mpt, CE_WARN, 6739 "mptsas_handle_event_sync: IOCStatus=0x%x, " 6740 "IOCLogInfo=0x%x", iocstatus, 6741 ddi_get32(mpt->m_acc_reply_frame_hdl, 6742 &eventreply->IOCLogInfo)); 6743 } 6744 } 6745 6746 /* 6747 * figure out what kind of event we got and handle accordingly 6748 */ 6749 switch (event) { 6750 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 6751 { 6752 pMpi2EventDataSasTopologyChangeList_t sas_topo_change_list; 6753 uint8_t num_entries, expstatus, phy; 6754 uint8_t phystatus, physport, state, i; 6755 uint8_t start_phy_num, link_rate; 6756 uint16_t dev_handle, reason_code; 6757 uint16_t enc_handle, expd_handle; 6758 char string[80], curr[80], prev[80]; 6759 mptsas_topo_change_list_t *topo_head = NULL; 6760 mptsas_topo_change_list_t *topo_tail = NULL; 6761 mptsas_topo_change_list_t *topo_node = NULL; 6762 mptsas_target_t *ptgt; 6763 mptsas_smp_t *psmp; 6764 mptsas_hash_table_t *tgttbl, *smptbl; 6765 uint8_t flags = 0, exp_flag; 6766 smhba_info_t *pSmhba = NULL; 6767 6768 NDBG20(("mptsas_handle_event_sync: SAS topology change")); 6769 6770 tgttbl = &mpt->m_active->m_tgttbl; 6771 smptbl = &mpt->m_active->m_smptbl; 6772 6773 sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t) 6774 eventreply->EventData; 6775 6776 enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6777 &sas_topo_change_list->EnclosureHandle); 6778 expd_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6779 &sas_topo_change_list->ExpanderDevHandle); 6780 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl, 6781 &sas_topo_change_list->NumEntries); 6782 start_phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl, 6783 &sas_topo_change_list->StartPhyNum); 6784 expstatus = ddi_get8(mpt->m_acc_reply_frame_hdl, 6785 &sas_topo_change_list->ExpStatus); 6786 physport = ddi_get8(mpt->m_acc_reply_frame_hdl, 6787 &sas_topo_change_list->PhysicalPort); 6788 6789 string[0] = 0; 6790 if (expd_handle) { 6791 flags = MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED; 6792 switch (expstatus) { 6793 case MPI2_EVENT_SAS_TOPO_ES_ADDED: 6794 (void) sprintf(string, " added"); 6795 /* 6796 * New expander device added 6797 */ 6798 mpt->m_port_chng = 1; 6799 topo_node = kmem_zalloc( 6800 sizeof (mptsas_topo_change_list_t), 6801 KM_SLEEP); 6802 topo_node->mpt = mpt; 6803 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_SMP; 6804 topo_node->un.physport = physport; 6805 topo_node->devhdl = expd_handle; 6806 topo_node->flags = flags; 6807 topo_node->object = NULL; 6808 if (topo_head == NULL) { 6809 topo_head = topo_tail = topo_node; 6810 } else { 6811 topo_tail->next = topo_node; 6812 topo_tail = topo_node; 6813 } 6814 break; 6815 case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING: 6816 (void) sprintf(string, " not responding, " 6817 "removed"); 6818 psmp = mptsas_search_by_devhdl(smptbl, 6819 expd_handle); 6820 if (psmp == NULL) 6821 break; 6822 6823 topo_node = kmem_zalloc( 6824 sizeof (mptsas_topo_change_list_t), 6825 KM_SLEEP); 6826 topo_node->mpt = mpt; 6827 topo_node->un.phymask = psmp->m_phymask; 6828 topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP; 6829 topo_node->devhdl = expd_handle; 6830 topo_node->flags = flags; 6831 topo_node->object = NULL; 6832 if (topo_head == NULL) { 6833 topo_head = topo_tail = topo_node; 6834 } else { 6835 topo_tail->next = topo_node; 6836 topo_tail = topo_node; 6837 } 6838 break; 6839 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING: 6840 break; 6841 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING: 6842 (void) sprintf(string, " not responding, " 6843 "delaying removal"); 6844 break; 6845 default: 6846 break; 6847 } 6848 } else { 6849 flags = MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE; 6850 } 6851 6852 NDBG20(("SAS TOPOLOGY CHANGE for enclosure %x expander %x%s\n", 6853 enc_handle, expd_handle, string)); 6854 for (i = 0; i < num_entries; i++) { 6855 phy = i + start_phy_num; 6856 phystatus = ddi_get8(mpt->m_acc_reply_frame_hdl, 6857 &sas_topo_change_list->PHY[i].PhyStatus); 6858 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 6859 &sas_topo_change_list->PHY[i].AttachedDevHandle); 6860 reason_code = phystatus & MPI2_EVENT_SAS_TOPO_RC_MASK; 6861 /* 6862 * Filter out processing of Phy Vacant Status unless 6863 * the reason code is "Not Responding". Process all 6864 * other combinations of Phy Status and Reason Codes. 6865 */ 6866 if ((phystatus & 6867 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) && 6868 (reason_code != 6869 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) { 6870 continue; 6871 } 6872 curr[0] = 0; 6873 prev[0] = 0; 6874 string[0] = 0; 6875 switch (reason_code) { 6876 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 6877 { 6878 NDBG20(("mptsas%d phy %d physical_port %d " 6879 "dev_handle %d added", mpt->m_instance, phy, 6880 physport, dev_handle)); 6881 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl, 6882 &sas_topo_change_list->PHY[i].LinkRate); 6883 state = (link_rate & 6884 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >> 6885 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT; 6886 switch (state) { 6887 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 6888 (void) sprintf(curr, "is disabled"); 6889 break; 6890 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 6891 (void) sprintf(curr, "is offline, " 6892 "failed speed negotiation"); 6893 break; 6894 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 6895 (void) sprintf(curr, "SATA OOB " 6896 "complete"); 6897 break; 6898 case SMP_RESET_IN_PROGRESS: 6899 (void) sprintf(curr, "SMP reset in " 6900 "progress"); 6901 break; 6902 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 6903 (void) sprintf(curr, "is online at " 6904 "1.5 Gbps"); 6905 break; 6906 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 6907 (void) sprintf(curr, "is online at 3.0 " 6908 "Gbps"); 6909 break; 6910 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 6911 (void) sprintf(curr, "is online at 6.0 " 6912 "Gbps"); 6913 break; 6914 default: 6915 (void) sprintf(curr, "state is " 6916 "unknown"); 6917 break; 6918 } 6919 /* 6920 * New target device added into the system. 6921 * Set association flag according to if an 6922 * expander is used or not. 6923 */ 6924 exp_flag = 6925 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE; 6926 if (flags == 6927 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) { 6928 flags = exp_flag; 6929 } 6930 topo_node = kmem_zalloc( 6931 sizeof (mptsas_topo_change_list_t), 6932 KM_SLEEP); 6933 topo_node->mpt = mpt; 6934 topo_node->event = 6935 MPTSAS_DR_EVENT_RECONFIG_TARGET; 6936 if (expd_handle == 0) { 6937 /* 6938 * Per MPI 2, if expander dev handle 6939 * is 0, it's a directly attached 6940 * device. So driver use PHY to decide 6941 * which iport is associated 6942 */ 6943 physport = phy; 6944 mpt->m_port_chng = 1; 6945 } 6946 topo_node->un.physport = physport; 6947 topo_node->devhdl = dev_handle; 6948 topo_node->flags = flags; 6949 topo_node->object = NULL; 6950 if (topo_head == NULL) { 6951 topo_head = topo_tail = topo_node; 6952 } else { 6953 topo_tail->next = topo_node; 6954 topo_tail = topo_node; 6955 } 6956 break; 6957 } 6958 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 6959 { 6960 NDBG20(("mptsas%d phy %d physical_port %d " 6961 "dev_handle %d removed", mpt->m_instance, 6962 phy, physport, dev_handle)); 6963 /* 6964 * Set association flag according to if an 6965 * expander is used or not. 6966 */ 6967 exp_flag = 6968 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE; 6969 if (flags == 6970 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) { 6971 flags = exp_flag; 6972 } 6973 /* 6974 * Target device is removed from the system 6975 * Before the device is really offline from 6976 * from system. 6977 */ 6978 ptgt = mptsas_search_by_devhdl(tgttbl, 6979 dev_handle); 6980 /* 6981 * If ptgt is NULL here, it means that the 6982 * DevHandle is not in the hash table. This is 6983 * reasonable sometimes. For example, if a 6984 * disk was pulled, then added, then pulled 6985 * again, the disk will not have been put into 6986 * the hash table because the add event will 6987 * have an invalid phymask. BUT, this does not 6988 * mean that the DevHandle is invalid. The 6989 * controller will still have a valid DevHandle 6990 * that must be removed. To do this, use the 6991 * MPTSAS_TOPO_FLAG_REMOVE_HANDLE event. 6992 */ 6993 if (ptgt == NULL) { 6994 topo_node = kmem_zalloc( 6995 sizeof (mptsas_topo_change_list_t), 6996 KM_SLEEP); 6997 topo_node->mpt = mpt; 6998 topo_node->un.phymask = 0; 6999 topo_node->event = 7000 MPTSAS_TOPO_FLAG_REMOVE_HANDLE; 7001 topo_node->devhdl = dev_handle; 7002 topo_node->flags = flags; 7003 topo_node->object = NULL; 7004 if (topo_head == NULL) { 7005 topo_head = topo_tail = 7006 topo_node; 7007 } else { 7008 topo_tail->next = topo_node; 7009 topo_tail = topo_node; 7010 } 7011 break; 7012 } 7013 7014 /* 7015 * Update DR flag immediately avoid I/O failure 7016 * before failover finish. Pay attention to the 7017 * mutex protect, we need grab the per target 7018 * mutex during set m_dr_flag because the 7019 * m_mutex would not be held all the time in 7020 * mptsas_scsi_start(). 7021 */ 7022 mutex_enter(&ptgt->m_tgt_intr_mutex); 7023 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 7024 mutex_exit(&ptgt->m_tgt_intr_mutex); 7025 7026 topo_node = kmem_zalloc( 7027 sizeof (mptsas_topo_change_list_t), 7028 KM_SLEEP); 7029 topo_node->mpt = mpt; 7030 topo_node->un.phymask = ptgt->m_phymask; 7031 topo_node->event = 7032 MPTSAS_DR_EVENT_OFFLINE_TARGET; 7033 topo_node->devhdl = dev_handle; 7034 topo_node->flags = flags; 7035 topo_node->object = NULL; 7036 if (topo_head == NULL) { 7037 topo_head = topo_tail = topo_node; 7038 } else { 7039 topo_tail->next = topo_node; 7040 topo_tail = topo_node; 7041 } 7042 break; 7043 } 7044 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 7045 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl, 7046 &sas_topo_change_list->PHY[i].LinkRate); 7047 state = (link_rate & 7048 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >> 7049 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT; 7050 pSmhba = &mpt->m_phy_info[i].smhba_info; 7051 pSmhba->negotiated_link_rate = state; 7052 switch (state) { 7053 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 7054 (void) sprintf(curr, "is disabled"); 7055 mptsas_smhba_log_sysevent(mpt, 7056 ESC_SAS_PHY_EVENT, 7057 SAS_PHY_REMOVE, 7058 &mpt->m_phy_info[i].smhba_info); 7059 mpt->m_phy_info[i].smhba_info. 7060 negotiated_link_rate 7061 = 0x1; 7062 break; 7063 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 7064 (void) sprintf(curr, "is offline, " 7065 "failed speed negotiation"); 7066 mptsas_smhba_log_sysevent(mpt, 7067 ESC_SAS_PHY_EVENT, 7068 SAS_PHY_OFFLINE, 7069 &mpt->m_phy_info[i].smhba_info); 7070 break; 7071 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 7072 (void) sprintf(curr, "SATA OOB " 7073 "complete"); 7074 break; 7075 case SMP_RESET_IN_PROGRESS: 7076 (void) sprintf(curr, "SMP reset in " 7077 "progress"); 7078 break; 7079 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 7080 (void) sprintf(curr, "is online at " 7081 "1.5 Gbps"); 7082 if ((expd_handle == 0) && 7083 (enc_handle == 1)) { 7084 mpt->m_port_chng = 1; 7085 } 7086 mptsas_smhba_log_sysevent(mpt, 7087 ESC_SAS_PHY_EVENT, 7088 SAS_PHY_ONLINE, 7089 &mpt->m_phy_info[i].smhba_info); 7090 break; 7091 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 7092 (void) sprintf(curr, "is online at 3.0 " 7093 "Gbps"); 7094 if ((expd_handle == 0) && 7095 (enc_handle == 1)) { 7096 mpt->m_port_chng = 1; 7097 } 7098 mptsas_smhba_log_sysevent(mpt, 7099 ESC_SAS_PHY_EVENT, 7100 SAS_PHY_ONLINE, 7101 &mpt->m_phy_info[i].smhba_info); 7102 break; 7103 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 7104 (void) sprintf(curr, "is online at " 7105 "6.0 Gbps"); 7106 if ((expd_handle == 0) && 7107 (enc_handle == 1)) { 7108 mpt->m_port_chng = 1; 7109 } 7110 mptsas_smhba_log_sysevent(mpt, 7111 ESC_SAS_PHY_EVENT, 7112 SAS_PHY_ONLINE, 7113 &mpt->m_phy_info[i].smhba_info); 7114 break; 7115 default: 7116 (void) sprintf(curr, "state is " 7117 "unknown"); 7118 break; 7119 } 7120 7121 state = (link_rate & 7122 MPI2_EVENT_SAS_TOPO_LR_PREV_MASK) >> 7123 MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT; 7124 switch (state) { 7125 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 7126 (void) sprintf(prev, ", was disabled"); 7127 break; 7128 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 7129 (void) sprintf(prev, ", was offline, " 7130 "failed speed negotiation"); 7131 break; 7132 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 7133 (void) sprintf(prev, ", was SATA OOB " 7134 "complete"); 7135 break; 7136 case SMP_RESET_IN_PROGRESS: 7137 (void) sprintf(prev, ", was SMP reset " 7138 "in progress"); 7139 break; 7140 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 7141 (void) sprintf(prev, ", was online at " 7142 "1.5 Gbps"); 7143 break; 7144 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 7145 (void) sprintf(prev, ", was online at " 7146 "3.0 Gbps"); 7147 break; 7148 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 7149 (void) sprintf(prev, ", was online at " 7150 "6.0 Gbps"); 7151 break; 7152 default: 7153 break; 7154 } 7155 (void) sprintf(&string[strlen(string)], "link " 7156 "changed, "); 7157 break; 7158 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE: 7159 continue; 7160 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING: 7161 (void) sprintf(&string[strlen(string)], 7162 "target not responding, delaying " 7163 "removal"); 7164 break; 7165 } 7166 NDBG20(("mptsas%d phy %d DevHandle %x, %s%s%s\n", 7167 mpt->m_instance, phy, dev_handle, string, curr, 7168 prev)); 7169 } 7170 if (topo_head != NULL) { 7171 /* 7172 * Launch DR taskq to handle topology change 7173 */ 7174 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 7175 mptsas_handle_dr, (void *)topo_head, 7176 DDI_NOSLEEP)) != DDI_SUCCESS) { 7177 mptsas_log(mpt, CE_NOTE, "mptsas start taskq " 7178 "for handle SAS DR event failed. \n"); 7179 } 7180 } 7181 break; 7182 } 7183 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 7184 { 7185 Mpi2EventDataIrConfigChangeList_t *irChangeList; 7186 mptsas_topo_change_list_t *topo_head = NULL; 7187 mptsas_topo_change_list_t *topo_tail = NULL; 7188 mptsas_topo_change_list_t *topo_node = NULL; 7189 mptsas_target_t *ptgt; 7190 mptsas_hash_table_t *tgttbl; 7191 uint8_t num_entries, i, reason; 7192 uint16_t volhandle, diskhandle; 7193 7194 irChangeList = (pMpi2EventDataIrConfigChangeList_t) 7195 eventreply->EventData; 7196 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl, 7197 &irChangeList->NumElements); 7198 7199 tgttbl = &mpt->m_active->m_tgttbl; 7200 7201 NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received", 7202 mpt->m_instance)); 7203 7204 for (i = 0; i < num_entries; i++) { 7205 reason = ddi_get8(mpt->m_acc_reply_frame_hdl, 7206 &irChangeList->ConfigElement[i].ReasonCode); 7207 volhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7208 &irChangeList->ConfigElement[i].VolDevHandle); 7209 diskhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7210 &irChangeList->ConfigElement[i].PhysDiskDevHandle); 7211 7212 switch (reason) { 7213 case MPI2_EVENT_IR_CHANGE_RC_ADDED: 7214 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: 7215 { 7216 NDBG20(("mptsas %d volume added\n", 7217 mpt->m_instance)); 7218 7219 topo_node = kmem_zalloc( 7220 sizeof (mptsas_topo_change_list_t), 7221 KM_SLEEP); 7222 7223 topo_node->mpt = mpt; 7224 topo_node->event = 7225 MPTSAS_DR_EVENT_RECONFIG_TARGET; 7226 topo_node->un.physport = 0xff; 7227 topo_node->devhdl = volhandle; 7228 topo_node->flags = 7229 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED; 7230 topo_node->object = NULL; 7231 if (topo_head == NULL) { 7232 topo_head = topo_tail = topo_node; 7233 } else { 7234 topo_tail->next = topo_node; 7235 topo_tail = topo_node; 7236 } 7237 break; 7238 } 7239 case MPI2_EVENT_IR_CHANGE_RC_REMOVED: 7240 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: 7241 { 7242 NDBG20(("mptsas %d volume deleted\n", 7243 mpt->m_instance)); 7244 ptgt = mptsas_search_by_devhdl(tgttbl, 7245 volhandle); 7246 if (ptgt == NULL) 7247 break; 7248 7249 /* 7250 * Clear any flags related to volume 7251 */ 7252 (void) mptsas_delete_volume(mpt, volhandle); 7253 7254 /* 7255 * Update DR flag immediately avoid I/O failure 7256 */ 7257 mutex_enter(&ptgt->m_tgt_intr_mutex); 7258 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 7259 mutex_exit(&ptgt->m_tgt_intr_mutex); 7260 7261 topo_node = kmem_zalloc( 7262 sizeof (mptsas_topo_change_list_t), 7263 KM_SLEEP); 7264 topo_node->mpt = mpt; 7265 topo_node->un.phymask = ptgt->m_phymask; 7266 topo_node->event = 7267 MPTSAS_DR_EVENT_OFFLINE_TARGET; 7268 topo_node->devhdl = volhandle; 7269 topo_node->flags = 7270 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED; 7271 topo_node->object = (void *)ptgt; 7272 if (topo_head == NULL) { 7273 topo_head = topo_tail = topo_node; 7274 } else { 7275 topo_tail->next = topo_node; 7276 topo_tail = topo_node; 7277 } 7278 break; 7279 } 7280 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: 7281 case MPI2_EVENT_IR_CHANGE_RC_HIDE: 7282 { 7283 ptgt = mptsas_search_by_devhdl(tgttbl, 7284 diskhandle); 7285 if (ptgt == NULL) 7286 break; 7287 7288 /* 7289 * Update DR flag immediately avoid I/O failure 7290 */ 7291 mutex_enter(&ptgt->m_tgt_intr_mutex); 7292 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 7293 mutex_exit(&ptgt->m_tgt_intr_mutex); 7294 7295 topo_node = kmem_zalloc( 7296 sizeof (mptsas_topo_change_list_t), 7297 KM_SLEEP); 7298 topo_node->mpt = mpt; 7299 topo_node->un.phymask = ptgt->m_phymask; 7300 topo_node->event = 7301 MPTSAS_DR_EVENT_OFFLINE_TARGET; 7302 topo_node->devhdl = diskhandle; 7303 topo_node->flags = 7304 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED; 7305 topo_node->object = (void *)ptgt; 7306 if (topo_head == NULL) { 7307 topo_head = topo_tail = topo_node; 7308 } else { 7309 topo_tail->next = topo_node; 7310 topo_tail = topo_node; 7311 } 7312 break; 7313 } 7314 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: 7315 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: 7316 { 7317 /* 7318 * The physical drive is released by a IR 7319 * volume. But we cannot get the the physport 7320 * or phynum from the event data, so we only 7321 * can get the physport/phynum after SAS 7322 * Device Page0 request for the devhdl. 7323 */ 7324 topo_node = kmem_zalloc( 7325 sizeof (mptsas_topo_change_list_t), 7326 KM_SLEEP); 7327 topo_node->mpt = mpt; 7328 topo_node->un.phymask = 0; 7329 topo_node->event = 7330 MPTSAS_DR_EVENT_RECONFIG_TARGET; 7331 topo_node->devhdl = diskhandle; 7332 topo_node->flags = 7333 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED; 7334 topo_node->object = NULL; 7335 mpt->m_port_chng = 1; 7336 if (topo_head == NULL) { 7337 topo_head = topo_tail = topo_node; 7338 } else { 7339 topo_tail->next = topo_node; 7340 topo_tail = topo_node; 7341 } 7342 break; 7343 } 7344 default: 7345 break; 7346 } 7347 } 7348 7349 if (topo_head != NULL) { 7350 /* 7351 * Launch DR taskq to handle topology change 7352 */ 7353 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 7354 mptsas_handle_dr, (void *)topo_head, 7355 DDI_NOSLEEP)) != DDI_SUCCESS) { 7356 mptsas_log(mpt, CE_NOTE, "mptsas start taskq " 7357 "for handle SAS DR event failed. \n"); 7358 } 7359 } 7360 break; 7361 } 7362 default: 7363 return (DDI_FAILURE); 7364 } 7365 7366 return (DDI_SUCCESS); 7367 } 7368 7369 /* 7370 * handle events from ioc 7371 */ 7372 static void 7373 mptsas_handle_event(void *args) 7374 { 7375 m_replyh_arg_t *replyh_arg; 7376 pMpi2EventNotificationReply_t eventreply; 7377 uint32_t event, iocloginfo, rfm; 7378 uint32_t status; 7379 uint8_t port; 7380 mptsas_t *mpt; 7381 uint_t iocstatus; 7382 7383 replyh_arg = (m_replyh_arg_t *)args; 7384 rfm = replyh_arg->rfm; 7385 mpt = replyh_arg->mpt; 7386 7387 mutex_enter(&mpt->m_mutex); 7388 7389 eventreply = (pMpi2EventNotificationReply_t) 7390 (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr)); 7391 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 7392 7393 if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 7394 &eventreply->IOCStatus)) { 7395 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 7396 mptsas_log(mpt, CE_WARN, 7397 "!mptsas_handle_event: IOCStatus=0x%x, " 7398 "IOCLogInfo=0x%x", iocstatus, 7399 ddi_get32(mpt->m_acc_reply_frame_hdl, 7400 &eventreply->IOCLogInfo)); 7401 } else { 7402 mptsas_log(mpt, CE_WARN, 7403 "mptsas_handle_event: IOCStatus=0x%x, " 7404 "IOCLogInfo=0x%x", iocstatus, 7405 ddi_get32(mpt->m_acc_reply_frame_hdl, 7406 &eventreply->IOCLogInfo)); 7407 } 7408 } 7409 7410 /* 7411 * figure out what kind of event we got and handle accordingly 7412 */ 7413 switch (event) { 7414 case MPI2_EVENT_LOG_ENTRY_ADDED: 7415 break; 7416 case MPI2_EVENT_LOG_DATA: 7417 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 7418 &eventreply->IOCLogInfo); 7419 NDBG20(("mptsas %d log info %x received.\n", mpt->m_instance, 7420 iocloginfo)); 7421 break; 7422 case MPI2_EVENT_STATE_CHANGE: 7423 NDBG20(("mptsas%d state change.", mpt->m_instance)); 7424 break; 7425 case MPI2_EVENT_HARD_RESET_RECEIVED: 7426 NDBG20(("mptsas%d event change.", mpt->m_instance)); 7427 break; 7428 case MPI2_EVENT_SAS_DISCOVERY: 7429 { 7430 MPI2_EVENT_DATA_SAS_DISCOVERY *sasdiscovery; 7431 char string[80]; 7432 uint8_t rc; 7433 7434 sasdiscovery = 7435 (pMpi2EventDataSasDiscovery_t)eventreply->EventData; 7436 7437 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7438 &sasdiscovery->ReasonCode); 7439 port = ddi_get8(mpt->m_acc_reply_frame_hdl, 7440 &sasdiscovery->PhysicalPort); 7441 status = ddi_get32(mpt->m_acc_reply_frame_hdl, 7442 &sasdiscovery->DiscoveryStatus); 7443 7444 string[0] = 0; 7445 switch (rc) { 7446 case MPI2_EVENT_SAS_DISC_RC_STARTED: 7447 (void) sprintf(string, "STARTING"); 7448 break; 7449 case MPI2_EVENT_SAS_DISC_RC_COMPLETED: 7450 (void) sprintf(string, "COMPLETED"); 7451 break; 7452 default: 7453 (void) sprintf(string, "UNKNOWN"); 7454 break; 7455 } 7456 7457 NDBG20(("SAS DISCOVERY is %s for port %d, status %x", string, 7458 port, status)); 7459 7460 break; 7461 } 7462 case MPI2_EVENT_EVENT_CHANGE: 7463 NDBG20(("mptsas%d event change.", mpt->m_instance)); 7464 break; 7465 case MPI2_EVENT_TASK_SET_FULL: 7466 { 7467 pMpi2EventDataTaskSetFull_t taskfull; 7468 7469 taskfull = (pMpi2EventDataTaskSetFull_t)eventreply->EventData; 7470 7471 NDBG20(("TASK_SET_FULL received for mptsas%d, depth %d\n", 7472 mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl, 7473 &taskfull->CurrentDepth))); 7474 break; 7475 } 7476 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 7477 { 7478 /* 7479 * SAS TOPOLOGY CHANGE LIST Event has already been handled 7480 * in mptsas_handle_event_sync() of interrupt context 7481 */ 7482 break; 7483 } 7484 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: 7485 { 7486 pMpi2EventDataSasEnclDevStatusChange_t encstatus; 7487 uint8_t rc; 7488 char string[80]; 7489 7490 encstatus = (pMpi2EventDataSasEnclDevStatusChange_t) 7491 eventreply->EventData; 7492 7493 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7494 &encstatus->ReasonCode); 7495 switch (rc) { 7496 case MPI2_EVENT_SAS_ENCL_RC_ADDED: 7497 (void) sprintf(string, "added"); 7498 break; 7499 case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING: 7500 (void) sprintf(string, ", not responding"); 7501 break; 7502 default: 7503 break; 7504 } 7505 NDBG20(("mptsas%d ENCLOSURE STATUS CHANGE for enclosure %x%s\n", 7506 mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl, 7507 &encstatus->EnclosureHandle), string)); 7508 break; 7509 } 7510 7511 /* 7512 * MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE is handled by 7513 * mptsas_handle_event_sync,in here just send ack message. 7514 */ 7515 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: 7516 { 7517 pMpi2EventDataSasDeviceStatusChange_t statuschange; 7518 uint8_t rc; 7519 uint16_t devhdl; 7520 uint64_t wwn = 0; 7521 uint32_t wwn_lo, wwn_hi; 7522 7523 statuschange = (pMpi2EventDataSasDeviceStatusChange_t) 7524 eventreply->EventData; 7525 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7526 &statuschange->ReasonCode); 7527 wwn_lo = ddi_get32(mpt->m_acc_reply_frame_hdl, 7528 (uint32_t *)(void *)&statuschange->SASAddress); 7529 wwn_hi = ddi_get32(mpt->m_acc_reply_frame_hdl, 7530 (uint32_t *)(void *)&statuschange->SASAddress + 1); 7531 wwn = ((uint64_t)wwn_hi << 32) | wwn_lo; 7532 devhdl = ddi_get16(mpt->m_acc_reply_frame_hdl, 7533 &statuschange->DevHandle); 7534 7535 NDBG13(("MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE wwn is %"PRIx64, 7536 wwn)); 7537 7538 switch (rc) { 7539 case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA: 7540 NDBG20(("SMART data received, ASC/ASCQ = %02x/%02x", 7541 ddi_get8(mpt->m_acc_reply_frame_hdl, 7542 &statuschange->ASC), 7543 ddi_get8(mpt->m_acc_reply_frame_hdl, 7544 &statuschange->ASCQ))); 7545 break; 7546 7547 case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED: 7548 NDBG20(("Device not supported")); 7549 break; 7550 7551 case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: 7552 NDBG20(("IOC internally generated the Target Reset " 7553 "for devhdl:%x", devhdl)); 7554 break; 7555 7556 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET: 7557 NDBG20(("IOC's internally generated Target Reset " 7558 "completed for devhdl:%x", devhdl)); 7559 break; 7560 7561 case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: 7562 NDBG20(("IOC internally generated Abort Task")); 7563 break; 7564 7565 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL: 7566 NDBG20(("IOC's internally generated Abort Task " 7567 "completed")); 7568 break; 7569 7570 case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: 7571 NDBG20(("IOC internally generated Abort Task Set")); 7572 break; 7573 7574 case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: 7575 NDBG20(("IOC internally generated Clear Task Set")); 7576 break; 7577 7578 case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: 7579 NDBG20(("IOC internally generated Query Task")); 7580 break; 7581 7582 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION: 7583 NDBG20(("Device sent an Asynchronous Notification")); 7584 break; 7585 7586 default: 7587 break; 7588 } 7589 break; 7590 } 7591 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 7592 { 7593 /* 7594 * IR TOPOLOGY CHANGE LIST Event has already been handled 7595 * in mpt_handle_event_sync() of interrupt context 7596 */ 7597 break; 7598 } 7599 case MPI2_EVENT_IR_OPERATION_STATUS: 7600 { 7601 Mpi2EventDataIrOperationStatus_t *irOpStatus; 7602 char reason_str[80]; 7603 uint8_t rc, percent; 7604 uint16_t handle; 7605 7606 irOpStatus = (pMpi2EventDataIrOperationStatus_t) 7607 eventreply->EventData; 7608 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7609 &irOpStatus->RAIDOperation); 7610 percent = ddi_get8(mpt->m_acc_reply_frame_hdl, 7611 &irOpStatus->PercentComplete); 7612 handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7613 &irOpStatus->VolDevHandle); 7614 7615 switch (rc) { 7616 case MPI2_EVENT_IR_RAIDOP_RESYNC: 7617 (void) sprintf(reason_str, "resync"); 7618 break; 7619 case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION: 7620 (void) sprintf(reason_str, "online capacity " 7621 "expansion"); 7622 break; 7623 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK: 7624 (void) sprintf(reason_str, "consistency check"); 7625 break; 7626 default: 7627 (void) sprintf(reason_str, "unknown reason %x", 7628 rc); 7629 } 7630 7631 NDBG20(("mptsas%d raid operational status: (%s)" 7632 "\thandle(0x%04x), percent complete(%d)\n", 7633 mpt->m_instance, reason_str, handle, percent)); 7634 break; 7635 } 7636 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: 7637 { 7638 pMpi2EventDataSasBroadcastPrimitive_t sas_broadcast; 7639 uint8_t phy_num; 7640 uint8_t primitive; 7641 7642 sas_broadcast = (pMpi2EventDataSasBroadcastPrimitive_t) 7643 eventreply->EventData; 7644 7645 phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl, 7646 &sas_broadcast->PhyNum); 7647 primitive = ddi_get8(mpt->m_acc_reply_frame_hdl, 7648 &sas_broadcast->Primitive); 7649 7650 switch (primitive) { 7651 case MPI2_EVENT_PRIMITIVE_CHANGE: 7652 mptsas_smhba_log_sysevent(mpt, 7653 ESC_SAS_HBA_PORT_BROADCAST, 7654 SAS_PORT_BROADCAST_CHANGE, 7655 &mpt->m_phy_info[phy_num].smhba_info); 7656 break; 7657 case MPI2_EVENT_PRIMITIVE_SES: 7658 mptsas_smhba_log_sysevent(mpt, 7659 ESC_SAS_HBA_PORT_BROADCAST, 7660 SAS_PORT_BROADCAST_SES, 7661 &mpt->m_phy_info[phy_num].smhba_info); 7662 break; 7663 case MPI2_EVENT_PRIMITIVE_EXPANDER: 7664 mptsas_smhba_log_sysevent(mpt, 7665 ESC_SAS_HBA_PORT_BROADCAST, 7666 SAS_PORT_BROADCAST_D01_4, 7667 &mpt->m_phy_info[phy_num].smhba_info); 7668 break; 7669 case MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT: 7670 mptsas_smhba_log_sysevent(mpt, 7671 ESC_SAS_HBA_PORT_BROADCAST, 7672 SAS_PORT_BROADCAST_D04_7, 7673 &mpt->m_phy_info[phy_num].smhba_info); 7674 break; 7675 case MPI2_EVENT_PRIMITIVE_RESERVED3: 7676 mptsas_smhba_log_sysevent(mpt, 7677 ESC_SAS_HBA_PORT_BROADCAST, 7678 SAS_PORT_BROADCAST_D16_7, 7679 &mpt->m_phy_info[phy_num].smhba_info); 7680 break; 7681 case MPI2_EVENT_PRIMITIVE_RESERVED4: 7682 mptsas_smhba_log_sysevent(mpt, 7683 ESC_SAS_HBA_PORT_BROADCAST, 7684 SAS_PORT_BROADCAST_D29_7, 7685 &mpt->m_phy_info[phy_num].smhba_info); 7686 break; 7687 case MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED: 7688 mptsas_smhba_log_sysevent(mpt, 7689 ESC_SAS_HBA_PORT_BROADCAST, 7690 SAS_PORT_BROADCAST_D24_0, 7691 &mpt->m_phy_info[phy_num].smhba_info); 7692 break; 7693 case MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED: 7694 mptsas_smhba_log_sysevent(mpt, 7695 ESC_SAS_HBA_PORT_BROADCAST, 7696 SAS_PORT_BROADCAST_D27_4, 7697 &mpt->m_phy_info[phy_num].smhba_info); 7698 break; 7699 default: 7700 NDBG20(("mptsas%d: unknown BROADCAST PRIMITIVE" 7701 " %x received", 7702 mpt->m_instance, primitive)); 7703 break; 7704 } 7705 NDBG20(("mptsas%d sas broadcast primitive: " 7706 "\tprimitive(0x%04x), phy(%d) complete\n", 7707 mpt->m_instance, primitive, phy_num)); 7708 break; 7709 } 7710 case MPI2_EVENT_IR_VOLUME: 7711 { 7712 Mpi2EventDataIrVolume_t *irVolume; 7713 uint16_t devhandle; 7714 uint32_t state; 7715 int config, vol; 7716 mptsas_slots_t *slots = mpt->m_active; 7717 uint8_t found = FALSE; 7718 7719 irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData; 7720 state = ddi_get32(mpt->m_acc_reply_frame_hdl, 7721 &irVolume->NewValue); 7722 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7723 &irVolume->VolDevHandle); 7724 7725 NDBG20(("EVENT_IR_VOLUME event is received")); 7726 7727 /* 7728 * Get latest RAID info and then find the DevHandle for this 7729 * event in the configuration. If the DevHandle is not found 7730 * just exit the event. 7731 */ 7732 (void) mptsas_get_raid_info(mpt); 7733 for (config = 0; (config < slots->m_num_raid_configs) && 7734 (!found); config++) { 7735 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) { 7736 if (slots->m_raidconfig[config].m_raidvol[vol]. 7737 m_raidhandle == devhandle) { 7738 found = TRUE; 7739 break; 7740 } 7741 } 7742 } 7743 if (!found) { 7744 break; 7745 } 7746 7747 switch (irVolume->ReasonCode) { 7748 case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED: 7749 { 7750 uint32_t i; 7751 slots->m_raidconfig[config].m_raidvol[vol].m_settings = 7752 state; 7753 7754 i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING; 7755 mptsas_log(mpt, CE_NOTE, " Volume %d settings changed" 7756 ", auto-config of hot-swap drives is %s" 7757 ", write caching is %s" 7758 ", hot-spare pool mask is %02x\n", 7759 vol, state & 7760 MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE 7761 ? "disabled" : "enabled", 7762 i == MPI2_RAIDVOL0_SETTING_UNCHANGED 7763 ? "controlled by member disks" : 7764 i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING 7765 ? "disabled" : 7766 i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING 7767 ? "enabled" : 7768 "incorrectly set", 7769 (state >> 16) & 0xff); 7770 break; 7771 } 7772 case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED: 7773 { 7774 slots->m_raidconfig[config].m_raidvol[vol].m_state = 7775 (uint8_t)state; 7776 7777 mptsas_log(mpt, CE_NOTE, 7778 "Volume %d is now %s\n", vol, 7779 state == MPI2_RAID_VOL_STATE_OPTIMAL 7780 ? "optimal" : 7781 state == MPI2_RAID_VOL_STATE_DEGRADED 7782 ? "degraded" : 7783 state == MPI2_RAID_VOL_STATE_ONLINE 7784 ? "online" : 7785 state == MPI2_RAID_VOL_STATE_INITIALIZING 7786 ? "initializing" : 7787 state == MPI2_RAID_VOL_STATE_FAILED 7788 ? "failed" : 7789 state == MPI2_RAID_VOL_STATE_MISSING 7790 ? "missing" : 7791 "state unknown"); 7792 break; 7793 } 7794 case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED: 7795 { 7796 slots->m_raidconfig[config].m_raidvol[vol]. 7797 m_statusflags = state; 7798 7799 mptsas_log(mpt, CE_NOTE, 7800 " Volume %d is now %s%s%s%s%s%s%s%s%s\n", 7801 vol, 7802 state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED 7803 ? ", enabled" : ", disabled", 7804 state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED 7805 ? ", quiesced" : "", 7806 state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE 7807 ? ", inactive" : ", active", 7808 state & 7809 MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL 7810 ? ", bad block table is full" : "", 7811 state & 7812 MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS 7813 ? ", resync in progress" : "", 7814 state & MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT 7815 ? ", background initialization in progress" : "", 7816 state & 7817 MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION 7818 ? ", capacity expansion in progress" : "", 7819 state & 7820 MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK 7821 ? ", consistency check in progress" : "", 7822 state & MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB 7823 ? ", data scrub in progress" : ""); 7824 break; 7825 } 7826 default: 7827 break; 7828 } 7829 break; 7830 } 7831 case MPI2_EVENT_IR_PHYSICAL_DISK: 7832 { 7833 Mpi2EventDataIrPhysicalDisk_t *irPhysDisk; 7834 uint16_t devhandle, enchandle, slot; 7835 uint32_t status, state; 7836 uint8_t physdisknum, reason; 7837 7838 irPhysDisk = (Mpi2EventDataIrPhysicalDisk_t *) 7839 eventreply->EventData; 7840 physdisknum = ddi_get8(mpt->m_acc_reply_frame_hdl, 7841 &irPhysDisk->PhysDiskNum); 7842 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7843 &irPhysDisk->PhysDiskDevHandle); 7844 enchandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7845 &irPhysDisk->EnclosureHandle); 7846 slot = ddi_get16(mpt->m_acc_reply_frame_hdl, 7847 &irPhysDisk->Slot); 7848 state = ddi_get32(mpt->m_acc_reply_frame_hdl, 7849 &irPhysDisk->NewValue); 7850 reason = ddi_get8(mpt->m_acc_reply_frame_hdl, 7851 &irPhysDisk->ReasonCode); 7852 7853 NDBG20(("EVENT_IR_PHYSICAL_DISK event is received")); 7854 7855 switch (reason) { 7856 case MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED: 7857 mptsas_log(mpt, CE_NOTE, 7858 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 7859 "for enclosure with handle 0x%x is now in hot " 7860 "spare pool %d", 7861 physdisknum, devhandle, slot, enchandle, 7862 (state >> 16) & 0xff); 7863 break; 7864 7865 case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED: 7866 status = state; 7867 mptsas_log(mpt, CE_NOTE, 7868 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 7869 "for enclosure with handle 0x%x is now " 7870 "%s%s%s%s%s\n", physdisknum, devhandle, slot, 7871 enchandle, 7872 status & MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME 7873 ? ", inactive" : ", active", 7874 status & MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC 7875 ? ", out of sync" : "", 7876 status & MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED 7877 ? ", quiesced" : "", 7878 status & 7879 MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED 7880 ? ", write cache enabled" : "", 7881 status & MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET 7882 ? ", capacity expansion target" : ""); 7883 break; 7884 7885 case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED: 7886 mptsas_log(mpt, CE_NOTE, 7887 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 7888 "for enclosure with handle 0x%x is now %s\n", 7889 physdisknum, devhandle, slot, enchandle, 7890 state == MPI2_RAID_PD_STATE_OPTIMAL 7891 ? "optimal" : 7892 state == MPI2_RAID_PD_STATE_REBUILDING 7893 ? "rebuilding" : 7894 state == MPI2_RAID_PD_STATE_DEGRADED 7895 ? "degraded" : 7896 state == MPI2_RAID_PD_STATE_HOT_SPARE 7897 ? "a hot spare" : 7898 state == MPI2_RAID_PD_STATE_ONLINE 7899 ? "online" : 7900 state == MPI2_RAID_PD_STATE_OFFLINE 7901 ? "offline" : 7902 state == MPI2_RAID_PD_STATE_NOT_COMPATIBLE 7903 ? "not compatible" : 7904 state == MPI2_RAID_PD_STATE_NOT_CONFIGURED 7905 ? "not configured" : 7906 "state unknown"); 7907 break; 7908 } 7909 break; 7910 } 7911 default: 7912 NDBG20(("mptsas%d: unknown event %x received", 7913 mpt->m_instance, event)); 7914 break; 7915 } 7916 7917 /* 7918 * Return the reply frame to the free queue. 7919 */ 7920 ddi_put32(mpt->m_acc_free_queue_hdl, 7921 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], rfm); 7922 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 7923 DDI_DMA_SYNC_FORDEV); 7924 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 7925 mpt->m_free_index = 0; 7926 } 7927 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 7928 mpt->m_free_index); 7929 mutex_exit(&mpt->m_mutex); 7930 } 7931 7932 /* 7933 * invoked from timeout() to restart qfull cmds with throttle == 0 7934 */ 7935 static void 7936 mptsas_restart_cmd(void *arg) 7937 { 7938 mptsas_t *mpt = arg; 7939 mptsas_target_t *ptgt = NULL; 7940 7941 mutex_enter(&mpt->m_mutex); 7942 7943 mpt->m_restart_cmd_timeid = 0; 7944 7945 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 7946 MPTSAS_HASH_FIRST); 7947 while (ptgt != NULL) { 7948 mutex_enter(&ptgt->m_tgt_intr_mutex); 7949 if (ptgt->m_reset_delay == 0) { 7950 if (ptgt->m_t_throttle == QFULL_THROTTLE) { 7951 mptsas_set_throttle(mpt, ptgt, 7952 MAX_THROTTLE); 7953 } 7954 } 7955 mutex_exit(&ptgt->m_tgt_intr_mutex); 7956 7957 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 7958 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 7959 } 7960 mptsas_restart_hba(mpt); 7961 mutex_exit(&mpt->m_mutex); 7962 } 7963 7964 /* 7965 * mptsas_remove_cmd0 is similar to mptsas_remove_cmd except that it is called 7966 * where m_intr_mutex has already been held. 7967 */ 7968 void 7969 mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 7970 { 7971 ASSERT(mutex_owned(&mpt->m_mutex)); 7972 7973 /* 7974 * With new fine-grained lock mechanism, the outstanding cmd is only 7975 * linked to m_active before the dma is triggerred(MPTSAS_START_CMD) 7976 * to send it. that is, mptsas_save_cmd() doesn't link the outstanding 7977 * cmd now. So when mptsas_remove_cmd is called, a mptsas_save_cmd must 7978 * have been called, but the cmd may have not been linked. 7979 * For mptsas_remove_cmd0, the cmd must have been linked. 7980 * In order to keep the same semantic, we link the cmd to the 7981 * outstanding cmd list. 7982 */ 7983 mpt->m_active->m_slot[cmd->cmd_slot] = cmd; 7984 7985 mutex_enter(&mpt->m_intr_mutex); 7986 mptsas_remove_cmd0(mpt, cmd); 7987 mutex_exit(&mpt->m_intr_mutex); 7988 } 7989 7990 static inline void 7991 mptsas_remove_cmd0(mptsas_t *mpt, mptsas_cmd_t *cmd) 7992 { 7993 int slot; 7994 mptsas_slots_t *slots = mpt->m_active; 7995 int t; 7996 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 7997 mptsas_slot_free_e_t *pe; 7998 7999 ASSERT(cmd != NULL); 8000 ASSERT(cmd->cmd_queued == FALSE); 8001 8002 /* 8003 * Task Management cmds are removed in their own routines. Also, 8004 * we don't want to modify timeout based on TM cmds. 8005 */ 8006 if (cmd->cmd_flags & CFLAG_TM_CMD) { 8007 return; 8008 } 8009 8010 t = Tgt(cmd); 8011 slot = cmd->cmd_slot; 8012 pe = mpt->m_slot_free_ae + slot - 1; 8013 ASSERT(cmd == slots->m_slot[slot]); 8014 ASSERT((slot > 0) && slot < (mpt->m_max_requests - 1)); 8015 8016 /* 8017 * remove the cmd. 8018 */ 8019 mutex_enter(&mpt->m_slot_freeq_pairp[pe->cpuid]. 8020 m_slot_releq.s.m_fq_mutex); 8021 NDBG31(("mptsas_remove_cmd0: removing cmd=0x%p", (void *)cmd)); 8022 slots->m_slot[slot] = NULL; 8023 ASSERT(pe->slot == slot); 8024 list_insert_tail(&mpt->m_slot_freeq_pairp[pe->cpuid]. 8025 m_slot_releq.s.m_fq_list, pe); 8026 mpt->m_slot_freeq_pairp[pe->cpuid].m_slot_releq.s.m_fq_n++; 8027 ASSERT(mpt->m_slot_freeq_pairp[pe->cpuid]. 8028 m_slot_releq.s.m_fq_n <= mpt->m_max_requests - 2); 8029 mutex_exit(&mpt->m_slot_freeq_pairp[pe->cpuid]. 8030 m_slot_releq.s.m_fq_mutex); 8031 8032 /* 8033 * only decrement per target ncmds if command 8034 * has a target associated with it. 8035 */ 8036 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 8037 mutex_enter(&ptgt->m_tgt_intr_mutex); 8038 ptgt->m_t_ncmds--; 8039 /* 8040 * reset throttle if we just ran an untagged command 8041 * to a tagged target 8042 */ 8043 if ((ptgt->m_t_ncmds == 0) && 8044 ((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0)) { 8045 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 8046 } 8047 mutex_exit(&ptgt->m_tgt_intr_mutex); 8048 } 8049 8050 /* 8051 * This is all we need to do for ioc commands. 8052 * The ioc cmds would never be handled in fastpath in ISR, so we make 8053 * sure the mptsas_return_to_pool() would always be called with 8054 * m_mutex protected. 8055 */ 8056 if (cmd->cmd_flags & CFLAG_CMDIOC) { 8057 ASSERT(mutex_owned(&mpt->m_mutex)); 8058 mptsas_return_to_pool(mpt, cmd); 8059 return; 8060 } 8061 8062 /* 8063 * Figure out what to set tag Q timeout for... 8064 * 8065 * Optimize: If we have duplicate's of same timeout 8066 * we're using, then we'll use it again until we run 8067 * out of duplicates. This should be the normal case 8068 * for block and raw I/O. 8069 * If no duplicates, we have to scan through tag que and 8070 * find the longest timeout value and use it. This is 8071 * going to take a while... 8072 * Add 1 to m_n_slots to account for TM request. 8073 */ 8074 mutex_enter(&ptgt->m_tgt_intr_mutex); 8075 if (cmd->cmd_pkt->pkt_time == ptgt->m_timebase) { 8076 if (--(ptgt->m_dups) == 0) { 8077 if (ptgt->m_t_ncmds) { 8078 mptsas_cmd_t *ssp; 8079 uint_t n = 0; 8080 ushort_t nslots = (slots->m_n_slots + 1); 8081 ushort_t i; 8082 /* 8083 * This crude check assumes we don't do 8084 * this too often which seems reasonable 8085 * for block and raw I/O. 8086 */ 8087 for (i = 0; i < nslots; i++) { 8088 ssp = slots->m_slot[i]; 8089 if (ssp && (Tgt(ssp) == t) && 8090 (ssp->cmd_pkt->pkt_time > n)) { 8091 n = ssp->cmd_pkt->pkt_time; 8092 ptgt->m_dups = 1; 8093 } else if (ssp && (Tgt(ssp) == t) && 8094 (ssp->cmd_pkt->pkt_time == n)) { 8095 ptgt->m_dups++; 8096 } 8097 } 8098 ptgt->m_timebase = n; 8099 } else { 8100 ptgt->m_dups = 0; 8101 ptgt->m_timebase = 0; 8102 } 8103 } 8104 } 8105 ptgt->m_timeout = ptgt->m_timebase; 8106 8107 ASSERT(cmd != slots->m_slot[cmd->cmd_slot]); 8108 mutex_exit(&ptgt->m_tgt_intr_mutex); 8109 } 8110 8111 /* 8112 * start a fresh request from the top of the device queue. 8113 */ 8114 static void 8115 mptsas_restart_hba(mptsas_t *mpt) 8116 { 8117 mptsas_cmd_t *cmd, *next_cmd; 8118 mptsas_target_t *ptgt = NULL; 8119 8120 NDBG1(("mptsas_restart_hba: mpt=0x%p", (void *)mpt)); 8121 8122 ASSERT(mutex_owned(&mpt->m_mutex)); 8123 8124 /* 8125 * If there is a reset delay, don't start any cmds. Otherwise, start 8126 * as many cmds as possible. 8127 * Since SMID 0 is reserved and the TM slot is reserved, the actual max 8128 * commands is m_max_requests - 2. 8129 */ 8130 cmd = mpt->m_waitq; 8131 8132 while (cmd != NULL) { 8133 next_cmd = cmd->cmd_linkp; 8134 if (cmd->cmd_flags & CFLAG_PASSTHRU) { 8135 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 8136 /* 8137 * passthru command get slot need 8138 * set CFLAG_PREPARED. 8139 */ 8140 cmd->cmd_flags |= CFLAG_PREPARED; 8141 mptsas_waitq_delete(mpt, cmd); 8142 mptsas_start_passthru(mpt, cmd); 8143 } 8144 cmd = next_cmd; 8145 continue; 8146 } 8147 if (cmd->cmd_flags & CFLAG_CONFIG) { 8148 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 8149 /* 8150 * Send the config page request and delete it 8151 * from the waitq. 8152 */ 8153 cmd->cmd_flags |= CFLAG_PREPARED; 8154 mptsas_waitq_delete(mpt, cmd); 8155 mptsas_start_config_page_access(mpt, cmd); 8156 } 8157 cmd = next_cmd; 8158 continue; 8159 } 8160 if (cmd->cmd_flags & CFLAG_FW_DIAG) { 8161 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 8162 /* 8163 * Send the FW Diag request and delete if from 8164 * the waitq. 8165 */ 8166 cmd->cmd_flags |= CFLAG_PREPARED; 8167 mptsas_waitq_delete(mpt, cmd); 8168 mptsas_start_diag(mpt, cmd); 8169 } 8170 cmd = next_cmd; 8171 continue; 8172 } 8173 8174 ptgt = cmd->cmd_tgt_addr; 8175 if (ptgt) { 8176 mutex_enter(&mpt->m_intr_mutex); 8177 mutex_enter(&ptgt->m_tgt_intr_mutex); 8178 if ((ptgt->m_t_throttle == DRAIN_THROTTLE) && 8179 (ptgt->m_t_ncmds == 0)) { 8180 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 8181 } 8182 if ((ptgt->m_reset_delay == 0) && 8183 (ptgt->m_t_ncmds < ptgt->m_t_throttle)) { 8184 mutex_exit(&ptgt->m_tgt_intr_mutex); 8185 mutex_exit(&mpt->m_intr_mutex); 8186 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 8187 mptsas_waitq_delete(mpt, cmd); 8188 (void) mptsas_start_cmd(mpt, cmd); 8189 } 8190 goto out; 8191 } 8192 mutex_exit(&ptgt->m_tgt_intr_mutex); 8193 mutex_exit(&mpt->m_intr_mutex); 8194 } 8195 out: 8196 cmd = next_cmd; 8197 } 8198 } 8199 8200 /* 8201 * mpt tag type lookup 8202 */ 8203 static char mptsas_tag_lookup[] = 8204 {0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG}; 8205 8206 /* 8207 * mptsas_start_cmd0 is similar to mptsas_start_cmd, except that, it is called 8208 * without ANY mutex protected, while, mptsas_start_cmd is called with m_mutex 8209 * protected. 8210 * 8211 * the relevant field in ptgt should be protected by m_tgt_intr_mutex in both 8212 * functions. 8213 * 8214 * before the cmds are linked on the slot for monitor as outstanding cmds, they 8215 * are accessed as slab objects, so slab framework ensures the exclusive access, 8216 * and no other mutex is requireed. Linking for monitor and the trigger of dma 8217 * must be done exclusively. 8218 */ 8219 static int 8220 mptsas_start_cmd0(mptsas_t *mpt, mptsas_cmd_t *cmd) 8221 { 8222 struct scsi_pkt *pkt = CMD2PKT(cmd); 8223 uint32_t control = 0; 8224 int n; 8225 caddr_t mem; 8226 pMpi2SCSIIORequest_t io_request; 8227 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; 8228 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl; 8229 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8230 uint16_t SMID, io_flags = 0; 8231 uint32_t request_desc_low, request_desc_high; 8232 8233 NDBG1(("mptsas_start_cmd0: cmd=0x%p", (void *)cmd)); 8234 8235 /* 8236 * Set SMID and increment index. Rollover to 1 instead of 0 if index 8237 * is at the max. 0 is an invalid SMID, so we call the first index 1. 8238 */ 8239 SMID = cmd->cmd_slot; 8240 8241 /* 8242 * It is possible for back to back device reset to 8243 * happen before the reset delay has expired. That's 8244 * ok, just let the device reset go out on the bus. 8245 */ 8246 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 8247 ASSERT(ptgt->m_reset_delay == 0); 8248 } 8249 8250 /* 8251 * if a non-tagged cmd is submitted to an active tagged target 8252 * then drain before submitting this cmd; SCSI-2 allows RQSENSE 8253 * to be untagged 8254 */ 8255 mutex_enter(&ptgt->m_tgt_intr_mutex); 8256 if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) && 8257 (ptgt->m_t_ncmds > 1) && 8258 ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) && 8259 (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) { 8260 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 8261 NDBG23(("target=%d, untagged cmd, start draining\n", 8262 ptgt->m_devhdl)); 8263 8264 if (ptgt->m_reset_delay == 0) { 8265 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 8266 } 8267 mutex_exit(&ptgt->m_tgt_intr_mutex); 8268 8269 mutex_enter(&mpt->m_mutex); 8270 mptsas_remove_cmd(mpt, cmd); 8271 cmd->cmd_pkt_flags |= FLAG_HEAD; 8272 mptsas_waitq_add(mpt, cmd); 8273 mutex_exit(&mpt->m_mutex); 8274 return (DDI_FAILURE); 8275 } 8276 mutex_exit(&ptgt->m_tgt_intr_mutex); 8277 return (DDI_FAILURE); 8278 } 8279 mutex_exit(&ptgt->m_tgt_intr_mutex); 8280 8281 /* 8282 * Set correct tag bits. 8283 */ 8284 if (cmd->cmd_pkt_flags & FLAG_TAGMASK) { 8285 switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags & 8286 FLAG_TAGMASK) >> 12)]) { 8287 case MSG_SIMPLE_QTAG: 8288 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 8289 break; 8290 case MSG_HEAD_QTAG: 8291 control |= MPI2_SCSIIO_CONTROL_HEADOFQ; 8292 break; 8293 case MSG_ORDERED_QTAG: 8294 control |= MPI2_SCSIIO_CONTROL_ORDEREDQ; 8295 break; 8296 default: 8297 mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n"); 8298 break; 8299 } 8300 } else { 8301 if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) { 8302 ptgt->m_t_throttle = 1; 8303 } 8304 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 8305 } 8306 8307 if (cmd->cmd_pkt_flags & FLAG_TLR) { 8308 control |= MPI2_SCSIIO_CONTROL_TLR_ON; 8309 } 8310 8311 mem = mpt->m_req_frame + (mpt->m_req_frame_size * SMID); 8312 io_request = (pMpi2SCSIIORequest_t)mem; 8313 8314 bzero(io_request, sizeof (Mpi2SCSIIORequest_t)); 8315 ddi_put8(acc_hdl, &io_request->SGLOffset0, offsetof 8316 (MPI2_SCSI_IO_REQUEST, SGL) / 4); 8317 mptsas_init_std_hdr(acc_hdl, io_request, ptgt->m_devhdl, Lun(cmd), 0, 8318 MPI2_FUNCTION_SCSI_IO_REQUEST); 8319 8320 (void) ddi_rep_put8(acc_hdl, (uint8_t *)pkt->pkt_cdbp, 8321 io_request->CDB.CDB32, cmd->cmd_cdblen, DDI_DEV_AUTOINCR); 8322 8323 io_flags = cmd->cmd_cdblen; 8324 ddi_put16(acc_hdl, &io_request->IoFlags, io_flags); 8325 /* 8326 * setup the Scatter/Gather DMA list for this request 8327 */ 8328 if (cmd->cmd_cookiec > 0) { 8329 mptsas_sge_setup(mpt, cmd, &control, io_request, acc_hdl); 8330 } else { 8331 ddi_put32(acc_hdl, &io_request->SGL.MpiSimple.FlagsLength, 8332 ((uint32_t)MPI2_SGE_FLAGS_LAST_ELEMENT | 8333 MPI2_SGE_FLAGS_END_OF_BUFFER | 8334 MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 8335 MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); 8336 } 8337 8338 /* 8339 * save ARQ information 8340 */ 8341 ddi_put8(acc_hdl, &io_request->SenseBufferLength, cmd->cmd_rqslen); 8342 if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) == 8343 (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) { 8344 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, 8345 cmd->cmd_ext_arqcookie.dmac_address); 8346 } else { 8347 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, 8348 cmd->cmd_arqcookie.dmac_address); 8349 } 8350 8351 ddi_put32(acc_hdl, &io_request->Control, control); 8352 8353 NDBG31(("starting message=0x%p, with cmd=0x%p", 8354 (void *)(uintptr_t)mpt->m_req_frame_dma_addr, (void *)cmd)); 8355 8356 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 8357 8358 /* 8359 * Build request descriptor and write it to the request desc post reg. 8360 */ 8361 request_desc_low = (SMID << 16) + MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 8362 request_desc_high = ptgt->m_devhdl << 16; 8363 8364 mutex_enter(&mpt->m_mutex); 8365 mpt->m_active->m_slot[cmd->cmd_slot] = cmd; 8366 MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high); 8367 mutex_exit(&mpt->m_mutex); 8368 8369 /* 8370 * Start timeout. 8371 */ 8372 mutex_enter(&ptgt->m_tgt_intr_mutex); 8373 #ifdef MPTSAS_TEST 8374 /* 8375 * Temporarily set timebase = 0; needed for 8376 * timeout torture test. 8377 */ 8378 if (mptsas_test_timeouts) { 8379 ptgt->m_timebase = 0; 8380 } 8381 #endif 8382 n = pkt->pkt_time - ptgt->m_timebase; 8383 8384 if (n == 0) { 8385 (ptgt->m_dups)++; 8386 ptgt->m_timeout = ptgt->m_timebase; 8387 } else if (n > 0) { 8388 ptgt->m_timeout = 8389 ptgt->m_timebase = pkt->pkt_time; 8390 ptgt->m_dups = 1; 8391 } else if (n < 0) { 8392 ptgt->m_timeout = ptgt->m_timebase; 8393 } 8394 #ifdef MPTSAS_TEST 8395 /* 8396 * Set back to a number higher than 8397 * mptsas_scsi_watchdog_tick 8398 * so timeouts will happen in mptsas_watchsubr 8399 */ 8400 if (mptsas_test_timeouts) { 8401 ptgt->m_timebase = 60; 8402 } 8403 #endif 8404 mutex_exit(&ptgt->m_tgt_intr_mutex); 8405 8406 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || 8407 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { 8408 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8409 return (DDI_FAILURE); 8410 } 8411 return (DDI_SUCCESS); 8412 } 8413 8414 static int 8415 mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 8416 { 8417 struct scsi_pkt *pkt = CMD2PKT(cmd); 8418 uint32_t control = 0; 8419 int n; 8420 caddr_t mem; 8421 pMpi2SCSIIORequest_t io_request; 8422 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; 8423 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl; 8424 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8425 uint16_t SMID, io_flags = 0; 8426 uint32_t request_desc_low, request_desc_high; 8427 8428 NDBG1(("mptsas_start_cmd: cmd=0x%p", (void *)cmd)); 8429 8430 /* 8431 * Set SMID and increment index. Rollover to 1 instead of 0 if index 8432 * is at the max. 0 is an invalid SMID, so we call the first index 1. 8433 */ 8434 SMID = cmd->cmd_slot; 8435 8436 /* 8437 * It is possible for back to back device reset to 8438 * happen before the reset delay has expired. That's 8439 * ok, just let the device reset go out on the bus. 8440 */ 8441 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 8442 ASSERT(ptgt->m_reset_delay == 0); 8443 } 8444 8445 /* 8446 * if a non-tagged cmd is submitted to an active tagged target 8447 * then drain before submitting this cmd; SCSI-2 allows RQSENSE 8448 * to be untagged 8449 */ 8450 mutex_enter(&ptgt->m_tgt_intr_mutex); 8451 if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) && 8452 (ptgt->m_t_ncmds > 1) && 8453 ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) && 8454 (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) { 8455 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 8456 NDBG23(("target=%d, untagged cmd, start draining\n", 8457 ptgt->m_devhdl)); 8458 8459 if (ptgt->m_reset_delay == 0) { 8460 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 8461 } 8462 mutex_exit(&ptgt->m_tgt_intr_mutex); 8463 8464 mptsas_remove_cmd(mpt, cmd); 8465 cmd->cmd_pkt_flags |= FLAG_HEAD; 8466 mptsas_waitq_add(mpt, cmd); 8467 return (DDI_FAILURE); 8468 } 8469 mutex_exit(&ptgt->m_tgt_intr_mutex); 8470 return (DDI_FAILURE); 8471 } 8472 mutex_exit(&ptgt->m_tgt_intr_mutex); 8473 8474 /* 8475 * Set correct tag bits. 8476 */ 8477 if (cmd->cmd_pkt_flags & FLAG_TAGMASK) { 8478 switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags & 8479 FLAG_TAGMASK) >> 12)]) { 8480 case MSG_SIMPLE_QTAG: 8481 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 8482 break; 8483 case MSG_HEAD_QTAG: 8484 control |= MPI2_SCSIIO_CONTROL_HEADOFQ; 8485 break; 8486 case MSG_ORDERED_QTAG: 8487 control |= MPI2_SCSIIO_CONTROL_ORDEREDQ; 8488 break; 8489 default: 8490 mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n"); 8491 break; 8492 } 8493 } else { 8494 if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) { 8495 ptgt->m_t_throttle = 1; 8496 } 8497 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 8498 } 8499 8500 if (cmd->cmd_pkt_flags & FLAG_TLR) { 8501 control |= MPI2_SCSIIO_CONTROL_TLR_ON; 8502 } 8503 8504 mem = mpt->m_req_frame + (mpt->m_req_frame_size * SMID); 8505 io_request = (pMpi2SCSIIORequest_t)mem; 8506 8507 bzero(io_request, sizeof (Mpi2SCSIIORequest_t)); 8508 ddi_put8(acc_hdl, &io_request->SGLOffset0, offsetof 8509 (MPI2_SCSI_IO_REQUEST, SGL) / 4); 8510 mptsas_init_std_hdr(acc_hdl, io_request, ptgt->m_devhdl, Lun(cmd), 0, 8511 MPI2_FUNCTION_SCSI_IO_REQUEST); 8512 8513 (void) ddi_rep_put8(acc_hdl, (uint8_t *)pkt->pkt_cdbp, 8514 io_request->CDB.CDB32, cmd->cmd_cdblen, DDI_DEV_AUTOINCR); 8515 8516 io_flags = cmd->cmd_cdblen; 8517 ddi_put16(acc_hdl, &io_request->IoFlags, io_flags); 8518 /* 8519 * setup the Scatter/Gather DMA list for this request 8520 */ 8521 if (cmd->cmd_cookiec > 0) { 8522 mptsas_sge_setup(mpt, cmd, &control, io_request, acc_hdl); 8523 } else { 8524 ddi_put32(acc_hdl, &io_request->SGL.MpiSimple.FlagsLength, 8525 ((uint32_t)MPI2_SGE_FLAGS_LAST_ELEMENT | 8526 MPI2_SGE_FLAGS_END_OF_BUFFER | 8527 MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 8528 MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); 8529 } 8530 8531 /* 8532 * save ARQ information 8533 */ 8534 ddi_put8(acc_hdl, &io_request->SenseBufferLength, cmd->cmd_rqslen); 8535 if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) == 8536 (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) { 8537 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, 8538 cmd->cmd_ext_arqcookie.dmac_address); 8539 } else { 8540 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, 8541 cmd->cmd_arqcookie.dmac_address); 8542 } 8543 8544 ddi_put32(acc_hdl, &io_request->Control, control); 8545 8546 NDBG31(("starting message=0x%p, with cmd=0x%p", 8547 (void *)(uintptr_t)mpt->m_req_frame_dma_addr, (void *)cmd)); 8548 8549 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 8550 8551 /* 8552 * Build request descriptor and write it to the request desc post reg. 8553 */ 8554 request_desc_low = (SMID << 16) + MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 8555 request_desc_high = ptgt->m_devhdl << 16; 8556 8557 mpt->m_active->m_slot[cmd->cmd_slot] = cmd; 8558 MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high); 8559 8560 /* 8561 * Start timeout. 8562 */ 8563 mutex_enter(&ptgt->m_tgt_intr_mutex); 8564 #ifdef MPTSAS_TEST 8565 /* 8566 * Temporarily set timebase = 0; needed for 8567 * timeout torture test. 8568 */ 8569 if (mptsas_test_timeouts) { 8570 ptgt->m_timebase = 0; 8571 } 8572 #endif 8573 n = pkt->pkt_time - ptgt->m_timebase; 8574 8575 if (n == 0) { 8576 (ptgt->m_dups)++; 8577 ptgt->m_timeout = ptgt->m_timebase; 8578 } else if (n > 0) { 8579 ptgt->m_timeout = 8580 ptgt->m_timebase = pkt->pkt_time; 8581 ptgt->m_dups = 1; 8582 } else if (n < 0) { 8583 ptgt->m_timeout = ptgt->m_timebase; 8584 } 8585 #ifdef MPTSAS_TEST 8586 /* 8587 * Set back to a number higher than 8588 * mptsas_scsi_watchdog_tick 8589 * so timeouts will happen in mptsas_watchsubr 8590 */ 8591 if (mptsas_test_timeouts) { 8592 ptgt->m_timebase = 60; 8593 } 8594 #endif 8595 mutex_exit(&ptgt->m_tgt_intr_mutex); 8596 8597 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || 8598 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { 8599 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8600 return (DDI_FAILURE); 8601 } 8602 return (DDI_SUCCESS); 8603 } 8604 8605 /* 8606 * Select a helper thread to handle current doneq 8607 */ 8608 static void 8609 mptsas_deliver_doneq_thread(mptsas_t *mpt) 8610 { 8611 uint64_t t, i; 8612 uint32_t min = 0xffffffff; 8613 mptsas_doneq_thread_list_t *item; 8614 8615 for (i = 0; i < mpt->m_doneq_thread_n; i++) { 8616 item = &mpt->m_doneq_thread_id[i]; 8617 /* 8618 * If the completed command on help thread[i] less than 8619 * doneq_thread_threshold, then pick the thread[i]. Otherwise 8620 * pick a thread which has least completed command. 8621 */ 8622 8623 mutex_enter(&item->mutex); 8624 if (item->len < mpt->m_doneq_thread_threshold) { 8625 t = i; 8626 mutex_exit(&item->mutex); 8627 break; 8628 } 8629 if (item->len < min) { 8630 min = item->len; 8631 t = i; 8632 } 8633 mutex_exit(&item->mutex); 8634 } 8635 mutex_enter(&mpt->m_doneq_thread_id[t].mutex); 8636 mptsas_doneq_mv(mpt, t); 8637 cv_signal(&mpt->m_doneq_thread_id[t].cv); 8638 mutex_exit(&mpt->m_doneq_thread_id[t].mutex); 8639 } 8640 8641 /* 8642 * move the current global doneq to the doneq of thread[t] 8643 */ 8644 static void 8645 mptsas_doneq_mv(mptsas_t *mpt, uint64_t t) 8646 { 8647 mptsas_cmd_t *cmd; 8648 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 8649 8650 ASSERT(mutex_owned(&item->mutex)); 8651 mutex_enter(&mpt->m_intr_mutex); 8652 while ((cmd = mpt->m_doneq) != NULL) { 8653 if ((mpt->m_doneq = cmd->cmd_linkp) == NULL) { 8654 mpt->m_donetail = &mpt->m_doneq; 8655 } 8656 cmd->cmd_linkp = NULL; 8657 *item->donetail = cmd; 8658 item->donetail = &cmd->cmd_linkp; 8659 mpt->m_doneq_len--; 8660 item->len++; 8661 } 8662 mutex_exit(&mpt->m_intr_mutex); 8663 } 8664 8665 void 8666 mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd) 8667 { 8668 struct scsi_pkt *pkt = CMD2PKT(cmd); 8669 8670 /* Check all acc and dma handles */ 8671 if ((mptsas_check_acc_handle(mpt->m_datap) != 8672 DDI_SUCCESS) || 8673 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 8674 DDI_SUCCESS) || 8675 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) != 8676 DDI_SUCCESS) || 8677 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) != 8678 DDI_SUCCESS) || 8679 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) != 8680 DDI_SUCCESS) || 8681 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) != 8682 DDI_SUCCESS) || 8683 (mptsas_check_acc_handle(mpt->m_config_handle) != 8684 DDI_SUCCESS)) { 8685 ddi_fm_service_impact(mpt->m_dip, 8686 DDI_SERVICE_UNAFFECTED); 8687 ddi_fm_acc_err_clear(mpt->m_config_handle, 8688 DDI_FME_VER0); 8689 pkt->pkt_reason = CMD_TRAN_ERR; 8690 pkt->pkt_statistics = 0; 8691 } 8692 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 8693 DDI_SUCCESS) || 8694 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) != 8695 DDI_SUCCESS) || 8696 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) != 8697 DDI_SUCCESS) || 8698 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) != 8699 DDI_SUCCESS) || 8700 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) != 8701 DDI_SUCCESS)) { 8702 ddi_fm_service_impact(mpt->m_dip, 8703 DDI_SERVICE_UNAFFECTED); 8704 pkt->pkt_reason = CMD_TRAN_ERR; 8705 pkt->pkt_statistics = 0; 8706 } 8707 if (cmd->cmd_dmahandle && 8708 (mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS)) { 8709 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8710 pkt->pkt_reason = CMD_TRAN_ERR; 8711 pkt->pkt_statistics = 0; 8712 } 8713 if ((cmd->cmd_extra_frames && 8714 ((mptsas_check_dma_handle(cmd->cmd_extra_frames->m_dma_hdl) != 8715 DDI_SUCCESS) || 8716 (mptsas_check_acc_handle(cmd->cmd_extra_frames->m_acc_hdl) != 8717 DDI_SUCCESS)))) { 8718 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8719 pkt->pkt_reason = CMD_TRAN_ERR; 8720 pkt->pkt_statistics = 0; 8721 } 8722 if (cmd->cmd_arqhandle && 8723 (mptsas_check_dma_handle(cmd->cmd_arqhandle) != DDI_SUCCESS)) { 8724 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8725 pkt->pkt_reason = CMD_TRAN_ERR; 8726 pkt->pkt_statistics = 0; 8727 } 8728 if (cmd->cmd_ext_arqhandle && 8729 (mptsas_check_dma_handle(cmd->cmd_ext_arqhandle) != DDI_SUCCESS)) { 8730 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8731 pkt->pkt_reason = CMD_TRAN_ERR; 8732 pkt->pkt_statistics = 0; 8733 } 8734 } 8735 8736 /* 8737 * mptsas_doneq_add0 is similar to mptsas_doneq_add except that it is called 8738 * where m_intr_mutex has already been held. 8739 */ 8740 static inline void 8741 mptsas_doneq_add0(mptsas_t *mpt, mptsas_cmd_t *cmd) 8742 { 8743 struct scsi_pkt *pkt = CMD2PKT(cmd); 8744 8745 NDBG31(("mptsas_doneq_add0: cmd=0x%p", (void *)cmd)); 8746 8747 ASSERT((cmd->cmd_flags & CFLAG_COMPLETED) == 0); 8748 cmd->cmd_linkp = NULL; 8749 cmd->cmd_flags |= CFLAG_FINISHED; 8750 cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT; 8751 8752 /* 8753 * only add scsi pkts that have completion routines to 8754 * the doneq. no intr cmds do not have callbacks. 8755 */ 8756 if (pkt && (pkt->pkt_comp)) { 8757 *mpt->m_donetail = cmd; 8758 mpt->m_donetail = &cmd->cmd_linkp; 8759 mpt->m_doneq_len++; 8760 } 8761 } 8762 8763 /* 8764 * These routines manipulate the queue of commands that 8765 * are waiting for their completion routines to be called. 8766 * The queue is usually in FIFO order but on an MP system 8767 * it's possible for the completion routines to get out 8768 * of order. If that's a problem you need to add a global 8769 * mutex around the code that calls the completion routine 8770 * in the interrupt handler. 8771 */ 8772 static void 8773 mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd) 8774 { 8775 ASSERT(mutex_owned(&mpt->m_mutex)); 8776 8777 mptsas_fma_check(mpt, cmd); 8778 8779 mutex_enter(&mpt->m_intr_mutex); 8780 mptsas_doneq_add0(mpt, cmd); 8781 mutex_exit(&mpt->m_intr_mutex); 8782 } 8783 8784 static mptsas_cmd_t * 8785 mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t) 8786 { 8787 mptsas_cmd_t *cmd; 8788 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 8789 8790 /* pop one off the done queue */ 8791 if ((cmd = item->doneq) != NULL) { 8792 /* if the queue is now empty fix the tail pointer */ 8793 NDBG31(("mptsas_doneq_thread_rm: cmd=0x%p", (void *)cmd)); 8794 if ((item->doneq = cmd->cmd_linkp) == NULL) { 8795 item->donetail = &item->doneq; 8796 } 8797 cmd->cmd_linkp = NULL; 8798 item->len--; 8799 } 8800 return (cmd); 8801 } 8802 8803 static void 8804 mptsas_doneq_empty(mptsas_t *mpt) 8805 { 8806 mutex_enter(&mpt->m_intr_mutex); 8807 if (mpt->m_doneq && !mpt->m_in_callback) { 8808 mptsas_cmd_t *cmd, *next; 8809 struct scsi_pkt *pkt; 8810 8811 mpt->m_in_callback = 1; 8812 cmd = mpt->m_doneq; 8813 mpt->m_doneq = NULL; 8814 mpt->m_donetail = &mpt->m_doneq; 8815 mpt->m_doneq_len = 0; 8816 8817 mutex_exit(&mpt->m_intr_mutex); 8818 8819 /* 8820 * ONLY in ISR, is it called without m_mutex held, otherwise, 8821 * it is always called with m_mutex held. 8822 */ 8823 if ((curthread->t_flag & T_INTR_THREAD) == 0) 8824 mutex_exit(&mpt->m_mutex); 8825 /* 8826 * run the completion routines of all the 8827 * completed commands 8828 */ 8829 while (cmd != NULL) { 8830 next = cmd->cmd_linkp; 8831 cmd->cmd_linkp = NULL; 8832 /* run this command's completion routine */ 8833 cmd->cmd_flags |= CFLAG_COMPLETED; 8834 pkt = CMD2PKT(cmd); 8835 mptsas_pkt_comp(pkt, cmd); 8836 cmd = next; 8837 } 8838 if ((curthread->t_flag & T_INTR_THREAD) == 0) 8839 mutex_enter(&mpt->m_mutex); 8840 mpt->m_in_callback = 0; 8841 return; 8842 } 8843 mutex_exit(&mpt->m_intr_mutex); 8844 } 8845 8846 /* 8847 * These routines manipulate the target's queue of pending requests 8848 */ 8849 void 8850 mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd) 8851 { 8852 NDBG7(("mptsas_waitq_add: cmd=0x%p", (void *)cmd)); 8853 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8854 cmd->cmd_queued = TRUE; 8855 if (ptgt) 8856 ptgt->m_t_nwait++; 8857 if (cmd->cmd_pkt_flags & FLAG_HEAD) { 8858 mutex_enter(&mpt->m_intr_mutex); 8859 if ((cmd->cmd_linkp = mpt->m_waitq) == NULL) { 8860 mpt->m_waitqtail = &cmd->cmd_linkp; 8861 } 8862 mpt->m_waitq = cmd; 8863 mutex_exit(&mpt->m_intr_mutex); 8864 } else { 8865 cmd->cmd_linkp = NULL; 8866 *(mpt->m_waitqtail) = cmd; 8867 mpt->m_waitqtail = &cmd->cmd_linkp; 8868 } 8869 } 8870 8871 static mptsas_cmd_t * 8872 mptsas_waitq_rm(mptsas_t *mpt) 8873 { 8874 mptsas_cmd_t *cmd; 8875 mptsas_target_t *ptgt; 8876 NDBG7(("mptsas_waitq_rm")); 8877 8878 mutex_enter(&mpt->m_intr_mutex); 8879 MPTSAS_WAITQ_RM(mpt, cmd); 8880 mutex_exit(&mpt->m_intr_mutex); 8881 8882 NDBG7(("mptsas_waitq_rm: cmd=0x%p", (void *)cmd)); 8883 if (cmd) { 8884 ptgt = cmd->cmd_tgt_addr; 8885 if (ptgt) { 8886 ptgt->m_t_nwait--; 8887 ASSERT(ptgt->m_t_nwait >= 0); 8888 } 8889 } 8890 return (cmd); 8891 } 8892 8893 /* 8894 * remove specified cmd from the middle of the wait queue. 8895 */ 8896 static void 8897 mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd) 8898 { 8899 mptsas_cmd_t *prevp = mpt->m_waitq; 8900 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8901 8902 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8903 (void *)mpt, (void *)cmd)); 8904 if (ptgt) { 8905 ptgt->m_t_nwait--; 8906 ASSERT(ptgt->m_t_nwait >= 0); 8907 } 8908 8909 if (prevp == cmd) { 8910 mutex_enter(&mpt->m_intr_mutex); 8911 if ((mpt->m_waitq = cmd->cmd_linkp) == NULL) 8912 mpt->m_waitqtail = &mpt->m_waitq; 8913 mutex_exit(&mpt->m_intr_mutex); 8914 8915 cmd->cmd_linkp = NULL; 8916 cmd->cmd_queued = FALSE; 8917 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8918 (void *)mpt, (void *)cmd)); 8919 return; 8920 } 8921 8922 while (prevp != NULL) { 8923 if (prevp->cmd_linkp == cmd) { 8924 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL) 8925 mpt->m_waitqtail = &prevp->cmd_linkp; 8926 8927 cmd->cmd_linkp = NULL; 8928 cmd->cmd_queued = FALSE; 8929 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 8930 (void *)mpt, (void *)cmd)); 8931 return; 8932 } 8933 prevp = prevp->cmd_linkp; 8934 } 8935 cmn_err(CE_PANIC, "mpt: mptsas_waitq_delete: queue botch"); 8936 } 8937 8938 /* 8939 * device and bus reset handling 8940 * 8941 * Notes: 8942 * - RESET_ALL: reset the controller 8943 * - RESET_TARGET: reset the target specified in scsi_address 8944 */ 8945 static int 8946 mptsas_scsi_reset(struct scsi_address *ap, int level) 8947 { 8948 mptsas_t *mpt = ADDR2MPT(ap); 8949 int rval; 8950 mptsas_tgt_private_t *tgt_private; 8951 mptsas_target_t *ptgt = NULL; 8952 8953 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->tran_tgt_private; 8954 ptgt = tgt_private->t_private; 8955 if (ptgt == NULL) { 8956 return (FALSE); 8957 } 8958 NDBG22(("mptsas_scsi_reset: target=%d level=%d", ptgt->m_devhdl, 8959 level)); 8960 8961 mutex_enter(&mpt->m_mutex); 8962 /* 8963 * if we are not in panic set up a reset delay for this target 8964 */ 8965 if (!ddi_in_panic()) { 8966 mptsas_setup_bus_reset_delay(mpt); 8967 } else { 8968 drv_usecwait(mpt->m_scsi_reset_delay * 1000); 8969 } 8970 rval = mptsas_do_scsi_reset(mpt, ptgt->m_devhdl); 8971 mutex_exit(&mpt->m_mutex); 8972 8973 /* 8974 * The transport layer expect to only see TRUE and 8975 * FALSE. Therefore, we will adjust the return value 8976 * if mptsas_do_scsi_reset returns FAILED. 8977 */ 8978 if (rval == FAILED) 8979 rval = FALSE; 8980 return (rval); 8981 } 8982 8983 static int 8984 mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl) 8985 { 8986 int rval = FALSE; 8987 uint8_t config, disk; 8988 mptsas_slots_t *slots = mpt->m_active; 8989 8990 ASSERT(mutex_owned(&mpt->m_mutex)); 8991 8992 if (mptsas_debug_resets) { 8993 mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d", 8994 devhdl); 8995 } 8996 8997 /* 8998 * Issue a Target Reset message to the target specified but not to a 8999 * disk making up a raid volume. Just look through the RAID config 9000 * Phys Disk list of DevHandles. If the target's DevHandle is in this 9001 * list, then don't reset this target. 9002 */ 9003 for (config = 0; config < slots->m_num_raid_configs; config++) { 9004 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) { 9005 if (devhdl == slots->m_raidconfig[config]. 9006 m_physdisk_devhdl[disk]) { 9007 return (TRUE); 9008 } 9009 } 9010 } 9011 9012 rval = mptsas_ioc_task_management(mpt, 9013 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, devhdl, 0, NULL, 0, 0); 9014 9015 mptsas_doneq_empty(mpt); 9016 return (rval); 9017 } 9018 9019 static int 9020 mptsas_scsi_reset_notify(struct scsi_address *ap, int flag, 9021 void (*callback)(caddr_t), caddr_t arg) 9022 { 9023 mptsas_t *mpt = ADDR2MPT(ap); 9024 9025 NDBG22(("mptsas_scsi_reset_notify: tgt=%d", ap->a_target)); 9026 9027 return (scsi_hba_reset_notify_setup(ap, flag, callback, arg, 9028 &mpt->m_mutex, &mpt->m_reset_notify_listf)); 9029 } 9030 9031 static int 9032 mptsas_get_name(struct scsi_device *sd, char *name, int len) 9033 { 9034 dev_info_t *lun_dip = NULL; 9035 9036 ASSERT(sd != NULL); 9037 ASSERT(name != NULL); 9038 lun_dip = sd->sd_dev; 9039 ASSERT(lun_dip != NULL); 9040 9041 if (mptsas_name_child(lun_dip, name, len) == DDI_SUCCESS) { 9042 return (1); 9043 } else { 9044 return (0); 9045 } 9046 } 9047 9048 static int 9049 mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len) 9050 { 9051 return (mptsas_get_name(sd, name, len)); 9052 } 9053 9054 void 9055 mptsas_set_throttle(mptsas_t *mpt, mptsas_target_t *ptgt, int what) 9056 { 9057 9058 NDBG25(("mptsas_set_throttle: throttle=%x", what)); 9059 9060 /* 9061 * if the bus is draining/quiesced, no changes to the throttles 9062 * are allowed. Not allowing change of throttles during draining 9063 * limits error recovery but will reduce draining time 9064 * 9065 * all throttles should have been set to HOLD_THROTTLE 9066 */ 9067 if (mpt->m_softstate & (MPTSAS_SS_QUIESCED | MPTSAS_SS_DRAINING)) { 9068 return; 9069 } 9070 9071 if (what == HOLD_THROTTLE) { 9072 ptgt->m_t_throttle = HOLD_THROTTLE; 9073 } else if (ptgt->m_reset_delay == 0) { 9074 ptgt->m_t_throttle = what; 9075 } 9076 } 9077 9078 /* 9079 * Clean up from a device reset. 9080 * For the case of target reset, this function clears the waitq of all 9081 * commands for a particular target. For the case of abort task set, this 9082 * function clears the waitq of all commonds for a particular target/lun. 9083 */ 9084 static void 9085 mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype) 9086 { 9087 mptsas_slots_t *slots = mpt->m_active; 9088 mptsas_cmd_t *cmd, *next_cmd; 9089 int slot; 9090 uchar_t reason; 9091 uint_t stat; 9092 9093 NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun)); 9094 9095 /* 9096 * Make sure the I/O Controller has flushed all cmds 9097 * that are associated with this target for a target reset 9098 * and target/lun for abort task set. 9099 * Account for TM requests, which use the last SMID. 9100 */ 9101 mutex_enter(&mpt->m_intr_mutex); 9102 for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) { 9103 if ((cmd = slots->m_slot[slot]) == NULL) { 9104 continue; 9105 } 9106 reason = CMD_RESET; 9107 stat = STAT_DEV_RESET; 9108 switch (tasktype) { 9109 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 9110 if (Tgt(cmd) == target) { 9111 NDBG25(("mptsas_flush_target discovered non-" 9112 "NULL cmd in slot %d, tasktype 0x%x", slot, 9113 tasktype)); 9114 mptsas_dump_cmd(mpt, cmd); 9115 mptsas_remove_cmd0(mpt, cmd); 9116 mptsas_set_pkt_reason(mpt, cmd, reason, stat); 9117 mptsas_doneq_add0(mpt, cmd); 9118 } 9119 break; 9120 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 9121 reason = CMD_ABORTED; 9122 stat = STAT_ABORTED; 9123 /*FALLTHROUGH*/ 9124 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 9125 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 9126 9127 NDBG25(("mptsas_flush_target discovered non-" 9128 "NULL cmd in slot %d, tasktype 0x%x", slot, 9129 tasktype)); 9130 mptsas_dump_cmd(mpt, cmd); 9131 mptsas_remove_cmd0(mpt, cmd); 9132 mptsas_set_pkt_reason(mpt, cmd, reason, 9133 stat); 9134 mptsas_doneq_add0(mpt, cmd); 9135 } 9136 break; 9137 default: 9138 break; 9139 } 9140 } 9141 mutex_exit(&mpt->m_intr_mutex); 9142 9143 /* 9144 * Flush the waitq of this target's cmds 9145 */ 9146 cmd = mpt->m_waitq; 9147 9148 reason = CMD_RESET; 9149 stat = STAT_DEV_RESET; 9150 9151 switch (tasktype) { 9152 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 9153 while (cmd != NULL) { 9154 next_cmd = cmd->cmd_linkp; 9155 if (Tgt(cmd) == target) { 9156 mptsas_waitq_delete(mpt, cmd); 9157 mptsas_set_pkt_reason(mpt, cmd, 9158 reason, stat); 9159 mptsas_doneq_add(mpt, cmd); 9160 } 9161 cmd = next_cmd; 9162 } 9163 break; 9164 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 9165 reason = CMD_ABORTED; 9166 stat = STAT_ABORTED; 9167 /*FALLTHROUGH*/ 9168 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 9169 while (cmd != NULL) { 9170 next_cmd = cmd->cmd_linkp; 9171 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 9172 mptsas_waitq_delete(mpt, cmd); 9173 mptsas_set_pkt_reason(mpt, cmd, 9174 reason, stat); 9175 mptsas_doneq_add(mpt, cmd); 9176 } 9177 cmd = next_cmd; 9178 } 9179 break; 9180 default: 9181 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.", 9182 tasktype); 9183 break; 9184 } 9185 } 9186 9187 /* 9188 * Clean up hba state, abort all outstanding command and commands in waitq 9189 * reset timeout of all targets. 9190 */ 9191 static void 9192 mptsas_flush_hba(mptsas_t *mpt) 9193 { 9194 mptsas_slots_t *slots = mpt->m_active; 9195 mptsas_cmd_t *cmd; 9196 int slot; 9197 9198 NDBG25(("mptsas_flush_hba")); 9199 9200 /* 9201 * The I/O Controller should have already sent back 9202 * all commands via the scsi I/O reply frame. Make 9203 * sure all commands have been flushed. 9204 * Account for TM request, which use the last SMID. 9205 */ 9206 mutex_enter(&mpt->m_intr_mutex); 9207 for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) { 9208 if ((cmd = slots->m_slot[slot]) == NULL) { 9209 continue; 9210 } 9211 9212 if (cmd->cmd_flags & CFLAG_CMDIOC) { 9213 /* 9214 * Need to make sure to tell everyone that might be 9215 * waiting on this command that it's going to fail. If 9216 * we get here, this command will never timeout because 9217 * the active command table is going to be re-allocated, 9218 * so there will be nothing to check against a time out. 9219 * Instead, mark the command as failed due to reset. 9220 */ 9221 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, 9222 STAT_BUS_RESET); 9223 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 9224 (cmd->cmd_flags & CFLAG_CONFIG) || 9225 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 9226 cmd->cmd_flags |= CFLAG_FINISHED; 9227 cv_broadcast(&mpt->m_passthru_cv); 9228 cv_broadcast(&mpt->m_config_cv); 9229 cv_broadcast(&mpt->m_fw_diag_cv); 9230 } 9231 continue; 9232 } 9233 9234 NDBG25(("mptsas_flush_hba discovered non-NULL cmd in slot %d", 9235 slot)); 9236 mptsas_dump_cmd(mpt, cmd); 9237 9238 mptsas_remove_cmd0(mpt, cmd); 9239 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 9240 mptsas_doneq_add0(mpt, cmd); 9241 } 9242 mutex_exit(&mpt->m_intr_mutex); 9243 9244 /* 9245 * Flush the waitq. 9246 */ 9247 while ((cmd = mptsas_waitq_rm(mpt)) != NULL) { 9248 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 9249 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 9250 (cmd->cmd_flags & CFLAG_CONFIG) || 9251 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 9252 cmd->cmd_flags |= CFLAG_FINISHED; 9253 cv_broadcast(&mpt->m_passthru_cv); 9254 cv_broadcast(&mpt->m_config_cv); 9255 cv_broadcast(&mpt->m_fw_diag_cv); 9256 } else { 9257 mptsas_doneq_add(mpt, cmd); 9258 } 9259 } 9260 } 9261 9262 /* 9263 * set pkt_reason and OR in pkt_statistics flag 9264 */ 9265 static void 9266 mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, uchar_t reason, 9267 uint_t stat) 9268 { 9269 #ifndef __lock_lint 9270 _NOTE(ARGUNUSED(mpt)) 9271 #endif 9272 9273 NDBG25(("mptsas_set_pkt_reason: cmd=0x%p reason=%x stat=%x", 9274 (void *)cmd, reason, stat)); 9275 9276 if (cmd) { 9277 if (cmd->cmd_pkt->pkt_reason == CMD_CMPLT) { 9278 cmd->cmd_pkt->pkt_reason = reason; 9279 } 9280 cmd->cmd_pkt->pkt_statistics |= stat; 9281 } 9282 } 9283 9284 static void 9285 mptsas_start_watch_reset_delay() 9286 { 9287 NDBG22(("mptsas_start_watch_reset_delay")); 9288 9289 mutex_enter(&mptsas_global_mutex); 9290 if (mptsas_reset_watch == NULL && mptsas_timeouts_enabled) { 9291 mptsas_reset_watch = timeout(mptsas_watch_reset_delay, NULL, 9292 drv_usectohz((clock_t) 9293 MPTSAS_WATCH_RESET_DELAY_TICK * 1000)); 9294 ASSERT(mptsas_reset_watch != NULL); 9295 } 9296 mutex_exit(&mptsas_global_mutex); 9297 } 9298 9299 static void 9300 mptsas_setup_bus_reset_delay(mptsas_t *mpt) 9301 { 9302 mptsas_target_t *ptgt = NULL; 9303 9304 NDBG22(("mptsas_setup_bus_reset_delay")); 9305 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 9306 MPTSAS_HASH_FIRST); 9307 while (ptgt != NULL) { 9308 mutex_enter(&ptgt->m_tgt_intr_mutex); 9309 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 9310 ptgt->m_reset_delay = mpt->m_scsi_reset_delay; 9311 mutex_exit(&ptgt->m_tgt_intr_mutex); 9312 9313 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9314 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9315 } 9316 9317 mptsas_start_watch_reset_delay(); 9318 } 9319 9320 /* 9321 * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every 9322 * mpt instance for active reset delays 9323 */ 9324 static void 9325 mptsas_watch_reset_delay(void *arg) 9326 { 9327 #ifndef __lock_lint 9328 _NOTE(ARGUNUSED(arg)) 9329 #endif 9330 9331 mptsas_t *mpt; 9332 int not_done = 0; 9333 9334 NDBG22(("mptsas_watch_reset_delay")); 9335 9336 mutex_enter(&mptsas_global_mutex); 9337 mptsas_reset_watch = 0; 9338 mutex_exit(&mptsas_global_mutex); 9339 rw_enter(&mptsas_global_rwlock, RW_READER); 9340 for (mpt = mptsas_head; mpt != NULL; mpt = mpt->m_next) { 9341 if (mpt->m_tran == 0) { 9342 continue; 9343 } 9344 mutex_enter(&mpt->m_mutex); 9345 not_done += mptsas_watch_reset_delay_subr(mpt); 9346 mutex_exit(&mpt->m_mutex); 9347 } 9348 rw_exit(&mptsas_global_rwlock); 9349 9350 if (not_done) { 9351 mptsas_start_watch_reset_delay(); 9352 } 9353 } 9354 9355 static int 9356 mptsas_watch_reset_delay_subr(mptsas_t *mpt) 9357 { 9358 int done = 0; 9359 int restart = 0; 9360 mptsas_target_t *ptgt = NULL; 9361 9362 NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt)); 9363 9364 ASSERT(mutex_owned(&mpt->m_mutex)); 9365 9366 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 9367 MPTSAS_HASH_FIRST); 9368 while (ptgt != NULL) { 9369 mutex_enter(&ptgt->m_tgt_intr_mutex); 9370 if (ptgt->m_reset_delay != 0) { 9371 ptgt->m_reset_delay -= 9372 MPTSAS_WATCH_RESET_DELAY_TICK; 9373 if (ptgt->m_reset_delay <= 0) { 9374 ptgt->m_reset_delay = 0; 9375 mptsas_set_throttle(mpt, ptgt, 9376 MAX_THROTTLE); 9377 restart++; 9378 } else { 9379 done = -1; 9380 } 9381 } 9382 mutex_exit(&ptgt->m_tgt_intr_mutex); 9383 9384 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 9385 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 9386 } 9387 9388 if (restart > 0) { 9389 mptsas_restart_hba(mpt); 9390 } 9391 return (done); 9392 } 9393 9394 #ifdef MPTSAS_TEST 9395 static void 9396 mptsas_test_reset(mptsas_t *mpt, int target) 9397 { 9398 mptsas_target_t *ptgt = NULL; 9399 9400 if (mptsas_rtest == target) { 9401 if (mptsas_do_scsi_reset(mpt, target) == TRUE) { 9402 mptsas_rtest = -1; 9403 } 9404 if (mptsas_rtest == -1) { 9405 NDBG22(("mptsas_test_reset success")); 9406 } 9407 } 9408 } 9409 #endif 9410 9411 /* 9412 * abort handling: 9413 * 9414 * Notes: 9415 * - if pkt is not NULL, abort just that command 9416 * - if pkt is NULL, abort all outstanding commands for target 9417 */ 9418 static int 9419 mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt) 9420 { 9421 mptsas_t *mpt = ADDR2MPT(ap); 9422 int rval; 9423 mptsas_tgt_private_t *tgt_private; 9424 int target, lun; 9425 9426 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran-> 9427 tran_tgt_private; 9428 ASSERT(tgt_private != NULL); 9429 target = tgt_private->t_private->m_devhdl; 9430 lun = tgt_private->t_lun; 9431 9432 NDBG23(("mptsas_scsi_abort: target=%d.%d", target, lun)); 9433 9434 mutex_enter(&mpt->m_mutex); 9435 rval = mptsas_do_scsi_abort(mpt, target, lun, pkt); 9436 mutex_exit(&mpt->m_mutex); 9437 return (rval); 9438 } 9439 9440 static int 9441 mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, struct scsi_pkt *pkt) 9442 { 9443 mptsas_cmd_t *sp = NULL; 9444 mptsas_slots_t *slots = mpt->m_active; 9445 int rval = FALSE; 9446 9447 ASSERT(mutex_owned(&mpt->m_mutex)); 9448 9449 /* 9450 * Abort the command pkt on the target/lun in ap. If pkt is 9451 * NULL, abort all outstanding commands on that target/lun. 9452 * If you can abort them, return 1, else return 0. 9453 * Each packet that's aborted should be sent back to the target 9454 * driver through the callback routine, with pkt_reason set to 9455 * CMD_ABORTED. 9456 * 9457 * abort cmd pkt on HBA hardware; clean out of outstanding 9458 * command lists, etc. 9459 */ 9460 if (pkt != NULL) { 9461 /* abort the specified packet */ 9462 sp = PKT2CMD(pkt); 9463 9464 if (sp->cmd_queued) { 9465 NDBG23(("mptsas_do_scsi_abort: queued sp=0x%p aborted", 9466 (void *)sp)); 9467 mptsas_waitq_delete(mpt, sp); 9468 mptsas_set_pkt_reason(mpt, sp, CMD_ABORTED, 9469 STAT_ABORTED); 9470 mptsas_doneq_add(mpt, sp); 9471 rval = TRUE; 9472 goto done; 9473 } 9474 9475 /* 9476 * Have mpt firmware abort this command 9477 */ 9478 mutex_enter(&mpt->m_intr_mutex); 9479 if (slots->m_slot[sp->cmd_slot] != NULL) { 9480 mutex_exit(&mpt->m_intr_mutex); 9481 rval = mptsas_ioc_task_management(mpt, 9482 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, target, 9483 lun, NULL, 0, 0); 9484 9485 /* 9486 * The transport layer expects only TRUE and FALSE. 9487 * Therefore, if mptsas_ioc_task_management returns 9488 * FAILED we will return FALSE. 9489 */ 9490 if (rval == FAILED) 9491 rval = FALSE; 9492 goto done; 9493 } 9494 mutex_exit(&mpt->m_intr_mutex); 9495 } 9496 9497 /* 9498 * If pkt is NULL then abort task set 9499 */ 9500 rval = mptsas_ioc_task_management(mpt, 9501 MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, target, lun, NULL, 0, 0); 9502 9503 /* 9504 * The transport layer expects only TRUE and FALSE. 9505 * Therefore, if mptsas_ioc_task_management returns 9506 * FAILED we will return FALSE. 9507 */ 9508 if (rval == FAILED) 9509 rval = FALSE; 9510 9511 #ifdef MPTSAS_TEST 9512 if (rval && mptsas_test_stop) { 9513 debug_enter("mptsas_do_scsi_abort"); 9514 } 9515 #endif 9516 9517 done: 9518 mptsas_doneq_empty(mpt); 9519 return (rval); 9520 } 9521 9522 /* 9523 * capability handling: 9524 * (*tran_getcap). Get the capability named, and return its value. 9525 */ 9526 static int 9527 mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly) 9528 { 9529 mptsas_t *mpt = ADDR2MPT(ap); 9530 int ckey; 9531 int rval = FALSE; 9532 9533 NDBG24(("mptsas_scsi_getcap: target=%d, cap=%s tgtonly=%x", 9534 ap->a_target, cap, tgtonly)); 9535 9536 mutex_enter(&mpt->m_mutex); 9537 9538 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) { 9539 mutex_exit(&mpt->m_mutex); 9540 return (UNDEFINED); 9541 } 9542 9543 switch (ckey) { 9544 case SCSI_CAP_DMA_MAX: 9545 rval = (int)mpt->m_msg_dma_attr.dma_attr_maxxfer; 9546 break; 9547 case SCSI_CAP_ARQ: 9548 rval = TRUE; 9549 break; 9550 case SCSI_CAP_MSG_OUT: 9551 case SCSI_CAP_PARITY: 9552 case SCSI_CAP_UNTAGGED_QING: 9553 rval = TRUE; 9554 break; 9555 case SCSI_CAP_TAGGED_QING: 9556 rval = TRUE; 9557 break; 9558 case SCSI_CAP_RESET_NOTIFICATION: 9559 rval = TRUE; 9560 break; 9561 case SCSI_CAP_LINKED_CMDS: 9562 rval = FALSE; 9563 break; 9564 case SCSI_CAP_QFULL_RETRIES: 9565 rval = ((mptsas_tgt_private_t *)(ap->a_hba_tran-> 9566 tran_tgt_private))->t_private->m_qfull_retries; 9567 break; 9568 case SCSI_CAP_QFULL_RETRY_INTERVAL: 9569 rval = drv_hztousec(((mptsas_tgt_private_t *) 9570 (ap->a_hba_tran->tran_tgt_private))-> 9571 t_private->m_qfull_retry_interval) / 1000; 9572 break; 9573 case SCSI_CAP_CDB_LEN: 9574 rval = CDB_GROUP4; 9575 break; 9576 case SCSI_CAP_INTERCONNECT_TYPE: 9577 rval = INTERCONNECT_SAS; 9578 break; 9579 case SCSI_CAP_TRAN_LAYER_RETRIES: 9580 if (mpt->m_ioc_capabilities & 9581 MPI2_IOCFACTS_CAPABILITY_TLR) 9582 rval = TRUE; 9583 else 9584 rval = FALSE; 9585 break; 9586 default: 9587 rval = UNDEFINED; 9588 break; 9589 } 9590 9591 NDBG24(("mptsas_scsi_getcap: %s, rval=%x", cap, rval)); 9592 9593 mutex_exit(&mpt->m_mutex); 9594 return (rval); 9595 } 9596 9597 /* 9598 * (*tran_setcap). Set the capability named to the value given. 9599 */ 9600 static int 9601 mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, int tgtonly) 9602 { 9603 mptsas_t *mpt = ADDR2MPT(ap); 9604 int ckey; 9605 int rval = FALSE; 9606 mptsas_target_t *ptgt; 9607 9608 NDBG24(("mptsas_scsi_setcap: target=%d, cap=%s value=%x tgtonly=%x", 9609 ap->a_target, cap, value, tgtonly)); 9610 9611 if (!tgtonly) { 9612 return (rval); 9613 } 9614 9615 mutex_enter(&mpt->m_mutex); 9616 9617 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) { 9618 mutex_exit(&mpt->m_mutex); 9619 return (UNDEFINED); 9620 } 9621 9622 switch (ckey) { 9623 case SCSI_CAP_DMA_MAX: 9624 case SCSI_CAP_MSG_OUT: 9625 case SCSI_CAP_PARITY: 9626 case SCSI_CAP_INITIATOR_ID: 9627 case SCSI_CAP_LINKED_CMDS: 9628 case SCSI_CAP_UNTAGGED_QING: 9629 case SCSI_CAP_RESET_NOTIFICATION: 9630 /* 9631 * None of these are settable via 9632 * the capability interface. 9633 */ 9634 break; 9635 case SCSI_CAP_ARQ: 9636 /* 9637 * We cannot turn off arq so return false if asked to 9638 */ 9639 if (value) { 9640 rval = TRUE; 9641 } else { 9642 rval = FALSE; 9643 } 9644 break; 9645 case SCSI_CAP_TAGGED_QING: 9646 ptgt = ((mptsas_tgt_private_t *) 9647 (ap->a_hba_tran->tran_tgt_private))->t_private; 9648 mutex_enter(&ptgt->m_tgt_intr_mutex); 9649 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 9650 mutex_exit(&ptgt->m_tgt_intr_mutex); 9651 rval = TRUE; 9652 break; 9653 case SCSI_CAP_QFULL_RETRIES: 9654 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))-> 9655 t_private->m_qfull_retries = (uchar_t)value; 9656 rval = TRUE; 9657 break; 9658 case SCSI_CAP_QFULL_RETRY_INTERVAL: 9659 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))-> 9660 t_private->m_qfull_retry_interval = 9661 drv_usectohz(value * 1000); 9662 rval = TRUE; 9663 break; 9664 default: 9665 rval = UNDEFINED; 9666 break; 9667 } 9668 mutex_exit(&mpt->m_mutex); 9669 return (rval); 9670 } 9671 9672 /* 9673 * Utility routine for mptsas_ifsetcap/ifgetcap 9674 */ 9675 /*ARGSUSED*/ 9676 static int 9677 mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp) 9678 { 9679 NDBG24(("mptsas_scsi_capchk: cap=%s", cap)); 9680 9681 if (!cap) 9682 return (FALSE); 9683 9684 *cidxp = scsi_hba_lookup_capstr(cap); 9685 return (TRUE); 9686 } 9687 9688 static int 9689 mptsas_alloc_active_slots(mptsas_t *mpt, int flag) 9690 { 9691 mptsas_slots_t *old_active = mpt->m_active; 9692 mptsas_slots_t *new_active; 9693 size_t size; 9694 int rval = -1, nslot, i; 9695 mptsas_slot_free_e_t *pe; 9696 9697 if (mptsas_outstanding_cmds_n(mpt)) { 9698 NDBG9(("cannot change size of active slots array")); 9699 return (rval); 9700 } 9701 9702 size = MPTSAS_SLOTS_SIZE(mpt); 9703 new_active = kmem_zalloc(size, flag); 9704 if (new_active == NULL) { 9705 NDBG1(("new active alloc failed")); 9706 return (rval); 9707 } 9708 /* 9709 * Since SMID 0 is reserved and the TM slot is reserved, the 9710 * number of slots that can be used at any one time is 9711 * m_max_requests - 2. 9712 */ 9713 new_active->m_n_slots = nslot = (mpt->m_max_requests - 2); 9714 new_active->m_size = size; 9715 new_active->m_tags = 1; 9716 9717 if (old_active) { 9718 new_active->m_tgttbl = old_active->m_tgttbl; 9719 new_active->m_smptbl = old_active->m_smptbl; 9720 new_active->m_num_raid_configs = 9721 old_active->m_num_raid_configs; 9722 for (i = 0; i < new_active->m_num_raid_configs; i++) { 9723 new_active->m_raidconfig[i] = 9724 old_active->m_raidconfig[i]; 9725 } 9726 mptsas_free_active_slots(mpt); 9727 } 9728 9729 if (max_ncpus & (max_ncpus - 1)) { 9730 mpt->m_slot_freeq_pair_n = (1 << highbit(max_ncpus)); 9731 } else { 9732 mpt->m_slot_freeq_pair_n = max_ncpus; 9733 } 9734 mpt->m_slot_freeq_pairp = kmem_zalloc( 9735 mpt->m_slot_freeq_pair_n * 9736 sizeof (mptsas_slot_freeq_pair_t), KM_SLEEP); 9737 for (i = 0; i < mpt->m_slot_freeq_pair_n; i++) { 9738 list_create(&mpt->m_slot_freeq_pairp[i]. 9739 m_slot_allocq.s.m_fq_list, 9740 sizeof (mptsas_slot_free_e_t), 9741 offsetof(mptsas_slot_free_e_t, node)); 9742 list_create(&mpt->m_slot_freeq_pairp[i]. 9743 m_slot_releq.s.m_fq_list, 9744 sizeof (mptsas_slot_free_e_t), 9745 offsetof(mptsas_slot_free_e_t, node)); 9746 mpt->m_slot_freeq_pairp[i].m_slot_allocq.s.m_fq_n = 0; 9747 mpt->m_slot_freeq_pairp[i].m_slot_releq.s.m_fq_n = 0; 9748 mutex_init(&mpt->m_slot_freeq_pairp[i]. 9749 m_slot_allocq.s.m_fq_mutex, NULL, MUTEX_DRIVER, 9750 DDI_INTR_PRI(mpt->m_intr_pri)); 9751 mutex_init(&mpt->m_slot_freeq_pairp[i]. 9752 m_slot_releq.s.m_fq_mutex, NULL, MUTEX_DRIVER, 9753 DDI_INTR_PRI(mpt->m_intr_pri)); 9754 } 9755 pe = mpt->m_slot_free_ae = kmem_zalloc(nslot * 9756 sizeof (mptsas_slot_free_e_t), KM_SLEEP); 9757 /* 9758 * An array of Mpi2ReplyDescriptorsUnion_t is defined here. 9759 * We are trying to eliminate the m_mutex in the context 9760 * reply code path in the ISR. Since the read of the 9761 * ReplyDescriptor and update/write of the ReplyIndex must 9762 * be atomic (since the poll thread may also update them at 9763 * the same time) so we first read out of the ReplyDescriptor 9764 * into this array and update the ReplyIndex register with a 9765 * separate mutex m_intr_mutex protected, and then release the 9766 * mutex and process all of them. the length of the array is 9767 * defined as max as 128(128*64=8k), which is 9768 * assumed as the maxmium depth of the interrupt coalese. 9769 */ 9770 mpt->m_reply = kmem_zalloc(MPI_ADDRESS_COALSCE_MAX * 9771 sizeof (Mpi2ReplyDescriptorsUnion_t), KM_SLEEP); 9772 for (i = 0; i < nslot; i++, pe++) { 9773 pe->slot = i + 1; /* SMID 0 is reserved */ 9774 pe->cpuid = i % mpt->m_slot_freeq_pair_n; 9775 list_insert_tail(&mpt->m_slot_freeq_pairp 9776 [i % mpt->m_slot_freeq_pair_n] 9777 .m_slot_allocq.s.m_fq_list, pe); 9778 mpt->m_slot_freeq_pairp[i % mpt->m_slot_freeq_pair_n] 9779 .m_slot_allocq.s.m_fq_n++; 9780 mpt->m_slot_freeq_pairp[i % mpt->m_slot_freeq_pair_n] 9781 .m_slot_allocq.s.m_fq_n_init++; 9782 } 9783 9784 mpt->m_active = new_active; 9785 rval = 0; 9786 9787 return (rval); 9788 } 9789 9790 static void 9791 mptsas_free_active_slots(mptsas_t *mpt) 9792 { 9793 mptsas_slots_t *active = mpt->m_active; 9794 size_t size; 9795 mptsas_slot_free_e_t *pe; 9796 int i; 9797 9798 if (active == NULL) 9799 return; 9800 9801 if (mpt->m_slot_freeq_pairp) { 9802 for (i = 0; i < mpt->m_slot_freeq_pair_n; i++) { 9803 while ((pe = list_head(&mpt->m_slot_freeq_pairp 9804 [i].m_slot_allocq.s.m_fq_list)) != NULL) { 9805 list_remove(&mpt->m_slot_freeq_pairp[i] 9806 .m_slot_allocq.s.m_fq_list, pe); 9807 } 9808 list_destroy(&mpt->m_slot_freeq_pairp 9809 [i].m_slot_allocq.s.m_fq_list); 9810 while ((pe = list_head(&mpt->m_slot_freeq_pairp 9811 [i].m_slot_releq.s.m_fq_list)) != NULL) { 9812 list_remove(&mpt->m_slot_freeq_pairp[i] 9813 .m_slot_releq.s.m_fq_list, pe); 9814 } 9815 list_destroy(&mpt->m_slot_freeq_pairp 9816 [i].m_slot_releq.s.m_fq_list); 9817 mutex_destroy(&mpt->m_slot_freeq_pairp 9818 [i].m_slot_allocq.s.m_fq_mutex); 9819 mutex_destroy(&mpt->m_slot_freeq_pairp 9820 [i].m_slot_releq.s.m_fq_mutex); 9821 } 9822 kmem_free(mpt->m_slot_freeq_pairp, mpt->m_slot_freeq_pair_n * 9823 sizeof (mptsas_slot_freeq_pair_t)); 9824 } 9825 if (mpt->m_slot_free_ae) 9826 kmem_free(mpt->m_slot_free_ae, mpt->m_active->m_n_slots * 9827 sizeof (mptsas_slot_free_e_t)); 9828 9829 if (mpt->m_reply) 9830 kmem_free(mpt->m_reply, MPI_ADDRESS_COALSCE_MAX * 9831 sizeof (Mpi2ReplyDescriptorsUnion_t)); 9832 9833 size = active->m_size; 9834 kmem_free(active, size); 9835 mpt->m_active = NULL; 9836 } 9837 9838 /* 9839 * Error logging, printing, and debug print routines. 9840 */ 9841 static char *mptsas_label = "mpt_sas"; 9842 9843 /*PRINTFLIKE3*/ 9844 void 9845 mptsas_log(mptsas_t *mpt, int level, char *fmt, ...) 9846 { 9847 dev_info_t *dev; 9848 va_list ap; 9849 9850 if (mpt) { 9851 dev = mpt->m_dip; 9852 } else { 9853 dev = 0; 9854 } 9855 9856 mutex_enter(&mptsas_log_mutex); 9857 9858 va_start(ap, fmt); 9859 (void) vsprintf(mptsas_log_buf, fmt, ap); 9860 va_end(ap); 9861 9862 if (level == CE_CONT) { 9863 scsi_log(dev, mptsas_label, level, "%s\n", mptsas_log_buf); 9864 } else { 9865 scsi_log(dev, mptsas_label, level, "%s", mptsas_log_buf); 9866 } 9867 9868 mutex_exit(&mptsas_log_mutex); 9869 } 9870 9871 #ifdef MPTSAS_DEBUG 9872 /*PRINTFLIKE1*/ 9873 void 9874 mptsas_printf(char *fmt, ...) 9875 { 9876 dev_info_t *dev = 0; 9877 va_list ap; 9878 9879 mutex_enter(&mptsas_log_mutex); 9880 9881 va_start(ap, fmt); 9882 (void) vsprintf(mptsas_log_buf, fmt, ap); 9883 va_end(ap); 9884 9885 #ifdef PROM_PRINTF 9886 prom_printf("%s:\t%s\n", mptsas_label, mptsas_log_buf); 9887 #else 9888 scsi_log(dev, mptsas_label, SCSI_DEBUG, "%s\n", mptsas_log_buf); 9889 #endif 9890 mutex_exit(&mptsas_log_mutex); 9891 } 9892 #endif 9893 9894 /* 9895 * timeout handling 9896 */ 9897 static void 9898 mptsas_watch(void *arg) 9899 { 9900 #ifndef __lock_lint 9901 _NOTE(ARGUNUSED(arg)) 9902 #endif 9903 9904 mptsas_t *mpt; 9905 uint32_t doorbell; 9906 9907 NDBG30(("mptsas_watch")); 9908 9909 rw_enter(&mptsas_global_rwlock, RW_READER); 9910 for (mpt = mptsas_head; mpt != (mptsas_t *)NULL; mpt = mpt->m_next) { 9911 9912 mutex_enter(&mpt->m_mutex); 9913 9914 /* Skip device if not powered on */ 9915 if (mpt->m_options & MPTSAS_OPT_PM) { 9916 if (mpt->m_power_level == PM_LEVEL_D0) { 9917 (void) pm_busy_component(mpt->m_dip, 0); 9918 mpt->m_busy = 1; 9919 } else { 9920 mutex_exit(&mpt->m_mutex); 9921 continue; 9922 } 9923 } 9924 9925 /* 9926 * Check if controller is in a FAULT state. If so, reset it. 9927 */ 9928 doorbell = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell); 9929 if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { 9930 doorbell &= MPI2_DOORBELL_DATA_MASK; 9931 mptsas_log(mpt, CE_WARN, "MPT Firmware Fault, " 9932 "code: %04x", doorbell); 9933 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 9934 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 9935 mptsas_log(mpt, CE_WARN, "Reset failed" 9936 "after fault was detected"); 9937 } 9938 } 9939 9940 /* 9941 * For now, always call mptsas_watchsubr. 9942 */ 9943 mptsas_watchsubr(mpt); 9944 9945 if (mpt->m_options & MPTSAS_OPT_PM) { 9946 mpt->m_busy = 0; 9947 (void) pm_idle_component(mpt->m_dip, 0); 9948 } 9949 9950 mutex_exit(&mpt->m_mutex); 9951 } 9952 rw_exit(&mptsas_global_rwlock); 9953 9954 mutex_enter(&mptsas_global_mutex); 9955 if (mptsas_timeouts_enabled) 9956 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick); 9957 mutex_exit(&mptsas_global_mutex); 9958 } 9959 9960 static void 9961 mptsas_watchsubr(mptsas_t *mpt) 9962 { 9963 int i; 9964 mptsas_cmd_t *cmd; 9965 mptsas_target_t *ptgt = NULL; 9966 9967 NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt)); 9968 9969 #ifdef MPTSAS_TEST 9970 if (mptsas_enable_untagged) { 9971 mptsas_test_untagged++; 9972 } 9973 #endif 9974 9975 /* 9976 * Check for commands stuck in active slot 9977 * Account for TM requests, which use the last SMID. 9978 */ 9979 mutex_enter(&mpt->m_intr_mutex); 9980 for (i = 0; i <= mpt->m_active->m_n_slots; i++) { 9981 if ((cmd = mpt->m_active->m_slot[i]) != NULL) { 9982 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 9983 cmd->cmd_active_timeout -= 9984 mptsas_scsi_watchdog_tick; 9985 if (cmd->cmd_active_timeout <= 0) { 9986 /* 9987 * There seems to be a command stuck 9988 * in the active slot. Drain throttle. 9989 */ 9990 ptgt = cmd->cmd_tgt_addr; 9991 mutex_enter(&ptgt->m_tgt_intr_mutex); 9992 mptsas_set_throttle(mpt, ptgt, 9993 DRAIN_THROTTLE); 9994 mutex_exit(&ptgt->m_tgt_intr_mutex); 9995 } 9996 } 9997 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 9998 (cmd->cmd_flags & CFLAG_CONFIG) || 9999 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 10000 cmd->cmd_active_timeout -= 10001 mptsas_scsi_watchdog_tick; 10002 if (cmd->cmd_active_timeout <= 0) { 10003 /* 10004 * passthrough command timeout 10005 */ 10006 cmd->cmd_flags |= (CFLAG_FINISHED | 10007 CFLAG_TIMEOUT); 10008 cv_broadcast(&mpt->m_passthru_cv); 10009 cv_broadcast(&mpt->m_config_cv); 10010 cv_broadcast(&mpt->m_fw_diag_cv); 10011 } 10012 } 10013 } 10014 } 10015 mutex_exit(&mpt->m_intr_mutex); 10016 10017 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 10018 MPTSAS_HASH_FIRST); 10019 while (ptgt != NULL) { 10020 /* 10021 * In order to avoid using m_mutex in the key code path in ISR, 10022 * separate mutexs are introduced to protect those elements 10023 * shown in ISR. 10024 */ 10025 mutex_enter(&ptgt->m_tgt_intr_mutex); 10026 10027 /* 10028 * If we were draining due to a qfull condition, 10029 * go back to full throttle. 10030 */ 10031 if ((ptgt->m_t_throttle < MAX_THROTTLE) && 10032 (ptgt->m_t_throttle > HOLD_THROTTLE) && 10033 (ptgt->m_t_ncmds < ptgt->m_t_throttle)) { 10034 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 10035 mptsas_restart_hba(mpt); 10036 } 10037 10038 if ((ptgt->m_t_ncmds > 0) && 10039 (ptgt->m_timebase)) { 10040 10041 if (ptgt->m_timebase <= 10042 mptsas_scsi_watchdog_tick) { 10043 ptgt->m_timebase += 10044 mptsas_scsi_watchdog_tick; 10045 mutex_exit(&ptgt->m_tgt_intr_mutex); 10046 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10047 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 10048 continue; 10049 } 10050 10051 ptgt->m_timeout -= mptsas_scsi_watchdog_tick; 10052 10053 if (ptgt->m_timeout < 0) { 10054 mutex_exit(&ptgt->m_tgt_intr_mutex); 10055 mptsas_cmd_timeout(mpt, ptgt->m_devhdl); 10056 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10057 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 10058 continue; 10059 } 10060 10061 if ((ptgt->m_timeout) <= 10062 mptsas_scsi_watchdog_tick) { 10063 NDBG23(("pending timeout")); 10064 mptsas_set_throttle(mpt, ptgt, 10065 DRAIN_THROTTLE); 10066 } 10067 } 10068 mutex_exit(&ptgt->m_tgt_intr_mutex); 10069 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10070 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 10071 } 10072 } 10073 10074 /* 10075 * timeout recovery 10076 */ 10077 static void 10078 mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl) 10079 { 10080 10081 NDBG29(("mptsas_cmd_timeout: target=%d", devhdl)); 10082 mptsas_log(mpt, CE_WARN, "Disconnected command timeout for " 10083 "Target %d", devhdl); 10084 10085 /* 10086 * If the current target is not the target passed in, 10087 * try to reset that target. 10088 */ 10089 NDBG29(("mptsas_cmd_timeout: device reset")); 10090 if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) { 10091 mptsas_log(mpt, CE_WARN, "Target %d reset for command timeout " 10092 "recovery failed!", devhdl); 10093 } 10094 } 10095 10096 /* 10097 * Device / Hotplug control 10098 */ 10099 static int 10100 mptsas_scsi_quiesce(dev_info_t *dip) 10101 { 10102 mptsas_t *mpt; 10103 scsi_hba_tran_t *tran; 10104 10105 tran = ddi_get_driver_private(dip); 10106 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL) 10107 return (-1); 10108 10109 return (mptsas_quiesce_bus(mpt)); 10110 } 10111 10112 static int 10113 mptsas_scsi_unquiesce(dev_info_t *dip) 10114 { 10115 mptsas_t *mpt; 10116 scsi_hba_tran_t *tran; 10117 10118 tran = ddi_get_driver_private(dip); 10119 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL) 10120 return (-1); 10121 10122 return (mptsas_unquiesce_bus(mpt)); 10123 } 10124 10125 static int 10126 mptsas_quiesce_bus(mptsas_t *mpt) 10127 { 10128 mptsas_target_t *ptgt = NULL; 10129 10130 NDBG28(("mptsas_quiesce_bus")); 10131 mutex_enter(&mpt->m_mutex); 10132 10133 /* Set all the throttles to zero */ 10134 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 10135 MPTSAS_HASH_FIRST); 10136 while (ptgt != NULL) { 10137 mutex_enter(&ptgt->m_tgt_intr_mutex); 10138 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 10139 mutex_exit(&ptgt->m_tgt_intr_mutex); 10140 10141 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10142 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 10143 } 10144 10145 /* If there are any outstanding commands in the queue */ 10146 mutex_enter(&mpt->m_intr_mutex); 10147 if (mptsas_outstanding_cmds_n(mpt)) { 10148 mutex_exit(&mpt->m_intr_mutex); 10149 mpt->m_softstate |= MPTSAS_SS_DRAINING; 10150 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain, 10151 mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000))); 10152 if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) { 10153 /* 10154 * Quiesce has been interrupted 10155 */ 10156 mpt->m_softstate &= ~MPTSAS_SS_DRAINING; 10157 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10158 &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST); 10159 while (ptgt != NULL) { 10160 mutex_enter(&ptgt->m_tgt_intr_mutex); 10161 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 10162 mutex_exit(&ptgt->m_tgt_intr_mutex); 10163 10164 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10165 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 10166 } 10167 mptsas_restart_hba(mpt); 10168 if (mpt->m_quiesce_timeid != 0) { 10169 timeout_id_t tid = mpt->m_quiesce_timeid; 10170 mpt->m_quiesce_timeid = 0; 10171 mutex_exit(&mpt->m_mutex); 10172 (void) untimeout(tid); 10173 return (-1); 10174 } 10175 mutex_exit(&mpt->m_mutex); 10176 return (-1); 10177 } else { 10178 /* Bus has been quiesced */ 10179 ASSERT(mpt->m_quiesce_timeid == 0); 10180 mpt->m_softstate &= ~MPTSAS_SS_DRAINING; 10181 mpt->m_softstate |= MPTSAS_SS_QUIESCED; 10182 mutex_exit(&mpt->m_mutex); 10183 return (0); 10184 } 10185 } 10186 mutex_exit(&mpt->m_intr_mutex); 10187 /* Bus was not busy - QUIESCED */ 10188 mutex_exit(&mpt->m_mutex); 10189 10190 return (0); 10191 } 10192 10193 static int 10194 mptsas_unquiesce_bus(mptsas_t *mpt) 10195 { 10196 mptsas_target_t *ptgt = NULL; 10197 10198 NDBG28(("mptsas_unquiesce_bus")); 10199 mutex_enter(&mpt->m_mutex); 10200 mpt->m_softstate &= ~MPTSAS_SS_QUIESCED; 10201 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 10202 MPTSAS_HASH_FIRST); 10203 while (ptgt != NULL) { 10204 mutex_enter(&ptgt->m_tgt_intr_mutex); 10205 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 10206 mutex_exit(&ptgt->m_tgt_intr_mutex); 10207 10208 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10209 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 10210 } 10211 mptsas_restart_hba(mpt); 10212 mutex_exit(&mpt->m_mutex); 10213 return (0); 10214 } 10215 10216 static void 10217 mptsas_ncmds_checkdrain(void *arg) 10218 { 10219 mptsas_t *mpt = arg; 10220 mptsas_target_t *ptgt = NULL; 10221 10222 mutex_enter(&mpt->m_mutex); 10223 if (mpt->m_softstate & MPTSAS_SS_DRAINING) { 10224 mpt->m_quiesce_timeid = 0; 10225 mutex_enter(&mpt->m_intr_mutex); 10226 if (mptsas_outstanding_cmds_n(mpt)) { 10227 mutex_exit(&mpt->m_intr_mutex); 10228 /* 10229 * The throttle may have been reset because 10230 * of a SCSI bus reset 10231 */ 10232 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10233 &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST); 10234 while (ptgt != NULL) { 10235 mutex_enter(&ptgt->m_tgt_intr_mutex); 10236 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 10237 mutex_exit(&ptgt->m_tgt_intr_mutex); 10238 10239 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 10240 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 10241 } 10242 10243 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain, 10244 mpt, (MPTSAS_QUIESCE_TIMEOUT * 10245 drv_usectohz(1000000))); 10246 } else { 10247 mutex_exit(&mpt->m_intr_mutex); 10248 /* Command queue has been drained */ 10249 cv_signal(&mpt->m_cv); 10250 } 10251 } 10252 mutex_exit(&mpt->m_mutex); 10253 } 10254 10255 /*ARGSUSED*/ 10256 static void 10257 mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 10258 { 10259 int i; 10260 uint8_t *cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp; 10261 char buf[128]; 10262 10263 buf[0] = '\0'; 10264 NDBG25(("?Cmd (0x%p) dump for Target %d Lun %d:\n", (void *)cmd, 10265 Tgt(cmd), Lun(cmd))); 10266 (void) sprintf(&buf[0], "\tcdb=["); 10267 for (i = 0; i < (int)cmd->cmd_cdblen; i++) { 10268 (void) sprintf(&buf[strlen(buf)], " 0x%x", *cp++); 10269 } 10270 (void) sprintf(&buf[strlen(buf)], " ]"); 10271 NDBG25(("?%s\n", buf)); 10272 NDBG25(("?pkt_flags=0x%x pkt_statistics=0x%x pkt_state=0x%x\n", 10273 cmd->cmd_pkt->pkt_flags, cmd->cmd_pkt->pkt_statistics, 10274 cmd->cmd_pkt->pkt_state)); 10275 NDBG25(("?pkt_scbp=0x%x cmd_flags=0x%x\n", cmd->cmd_pkt->pkt_scbp ? 10276 *(cmd->cmd_pkt->pkt_scbp) : 0, cmd->cmd_flags)); 10277 } 10278 10279 static void 10280 mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd) 10281 { 10282 caddr_t memp; 10283 pMPI2RequestHeader_t request_hdrp; 10284 struct scsi_pkt *pkt = cmd->cmd_pkt; 10285 mptsas_pt_request_t *pt = pkt->pkt_ha_private; 10286 uint32_t request_size, data_size, dataout_size; 10287 uint32_t direction; 10288 ddi_dma_cookie_t data_cookie; 10289 ddi_dma_cookie_t dataout_cookie; 10290 uint32_t request_desc_low, request_desc_high = 0; 10291 uint32_t i, sense_bufp; 10292 uint8_t desc_type; 10293 uint8_t *request, function; 10294 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; 10295 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl; 10296 10297 desc_type = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 10298 10299 request = pt->request; 10300 direction = pt->direction; 10301 request_size = pt->request_size; 10302 data_size = pt->data_size; 10303 dataout_size = pt->dataout_size; 10304 data_cookie = pt->data_cookie; 10305 dataout_cookie = pt->dataout_cookie; 10306 10307 /* 10308 * Store the passthrough message in memory location 10309 * corresponding to our slot number 10310 */ 10311 memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot); 10312 request_hdrp = (pMPI2RequestHeader_t)memp; 10313 bzero(memp, mpt->m_req_frame_size); 10314 10315 for (i = 0; i < request_size; i++) { 10316 bcopy(request + i, memp + i, 1); 10317 } 10318 10319 if (data_size || dataout_size) { 10320 pMpi2SGESimple64_t sgep; 10321 uint32_t sge_flags; 10322 10323 sgep = (pMpi2SGESimple64_t)((uint8_t *)request_hdrp + 10324 request_size); 10325 if (dataout_size) { 10326 10327 sge_flags = dataout_size | 10328 ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 10329 MPI2_SGE_FLAGS_END_OF_BUFFER | 10330 MPI2_SGE_FLAGS_HOST_TO_IOC | 10331 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 10332 MPI2_SGE_FLAGS_SHIFT); 10333 ddi_put32(acc_hdl, &sgep->FlagsLength, sge_flags); 10334 ddi_put32(acc_hdl, &sgep->Address.Low, 10335 (uint32_t)(dataout_cookie.dmac_laddress & 10336 0xffffffffull)); 10337 ddi_put32(acc_hdl, &sgep->Address.High, 10338 (uint32_t)(dataout_cookie.dmac_laddress 10339 >> 32)); 10340 sgep++; 10341 } 10342 sge_flags = data_size; 10343 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 10344 MPI2_SGE_FLAGS_LAST_ELEMENT | 10345 MPI2_SGE_FLAGS_END_OF_BUFFER | 10346 MPI2_SGE_FLAGS_END_OF_LIST | 10347 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 10348 MPI2_SGE_FLAGS_SHIFT); 10349 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) { 10350 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_HOST_TO_IOC) << 10351 MPI2_SGE_FLAGS_SHIFT); 10352 } else { 10353 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_IOC_TO_HOST) << 10354 MPI2_SGE_FLAGS_SHIFT); 10355 } 10356 ddi_put32(acc_hdl, &sgep->FlagsLength, 10357 sge_flags); 10358 ddi_put32(acc_hdl, &sgep->Address.Low, 10359 (uint32_t)(data_cookie.dmac_laddress & 10360 0xffffffffull)); 10361 ddi_put32(acc_hdl, &sgep->Address.High, 10362 (uint32_t)(data_cookie.dmac_laddress >> 32)); 10363 } 10364 10365 function = request_hdrp->Function; 10366 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) || 10367 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 10368 pMpi2SCSIIORequest_t scsi_io_req; 10369 10370 scsi_io_req = (pMpi2SCSIIORequest_t)request_hdrp; 10371 /* 10372 * Put SGE for data and data_out buffer at the end of 10373 * scsi_io_request message header.(64 bytes in total) 10374 * Following above SGEs, the residual space will be 10375 * used by sense data. 10376 */ 10377 ddi_put8(acc_hdl, 10378 &scsi_io_req->SenseBufferLength, 10379 (uint8_t)(request_size - 64)); 10380 10381 sense_bufp = mpt->m_req_frame_dma_addr + 10382 (mpt->m_req_frame_size * cmd->cmd_slot); 10383 sense_bufp += 64; 10384 ddi_put32(acc_hdl, 10385 &scsi_io_req->SenseBufferLowAddress, sense_bufp); 10386 10387 /* 10388 * Set SGLOffset0 value 10389 */ 10390 ddi_put8(acc_hdl, &scsi_io_req->SGLOffset0, 10391 offsetof(MPI2_SCSI_IO_REQUEST, SGL) / 4); 10392 10393 /* 10394 * Setup descriptor info. RAID passthrough must use the 10395 * default request descriptor which is already set, so if this 10396 * is a SCSI IO request, change the descriptor to SCSI IO. 10397 */ 10398 if (function == MPI2_FUNCTION_SCSI_IO_REQUEST) { 10399 desc_type = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 10400 request_desc_high = (ddi_get16(acc_hdl, 10401 &scsi_io_req->DevHandle) << 16); 10402 } 10403 } 10404 10405 /* 10406 * We must wait till the message has been completed before 10407 * beginning the next message so we wait for this one to 10408 * finish. 10409 */ 10410 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 10411 request_desc_low = (cmd->cmd_slot << 16) + desc_type; 10412 cmd->cmd_rfm = NULL; 10413 mpt->m_active->m_slot[cmd->cmd_slot] = cmd; 10414 MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high); 10415 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || 10416 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { 10417 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 10418 } 10419 } 10420 10421 10422 10423 static int 10424 mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply, 10425 uint8_t *data, uint32_t request_size, uint32_t reply_size, 10426 uint32_t data_size, uint32_t direction, uint8_t *dataout, 10427 uint32_t dataout_size, short timeout, int mode) 10428 { 10429 mptsas_pt_request_t pt; 10430 mptsas_dma_alloc_state_t data_dma_state; 10431 mptsas_dma_alloc_state_t dataout_dma_state; 10432 caddr_t memp; 10433 mptsas_cmd_t *cmd = NULL; 10434 struct scsi_pkt *pkt; 10435 uint32_t reply_len = 0, sense_len = 0; 10436 pMPI2RequestHeader_t request_hdrp; 10437 pMPI2RequestHeader_t request_msg; 10438 pMPI2DefaultReply_t reply_msg; 10439 Mpi2SCSIIOReply_t rep_msg; 10440 int i, status = 0, pt_flags = 0, rv = 0; 10441 int rvalue; 10442 uint8_t function; 10443 10444 ASSERT(mutex_owned(&mpt->m_mutex)); 10445 10446 reply_msg = (pMPI2DefaultReply_t)(&rep_msg); 10447 bzero(reply_msg, sizeof (MPI2_DEFAULT_REPLY)); 10448 request_msg = kmem_zalloc(request_size, KM_SLEEP); 10449 10450 mutex_exit(&mpt->m_mutex); 10451 /* 10452 * copy in the request buffer since it could be used by 10453 * another thread when the pt request into waitq 10454 */ 10455 if (ddi_copyin(request, request_msg, request_size, mode)) { 10456 mutex_enter(&mpt->m_mutex); 10457 status = EFAULT; 10458 mptsas_log(mpt, CE_WARN, "failed to copy request data"); 10459 goto out; 10460 } 10461 mutex_enter(&mpt->m_mutex); 10462 10463 function = request_msg->Function; 10464 if (function == MPI2_FUNCTION_SCSI_TASK_MGMT) { 10465 pMpi2SCSITaskManagementRequest_t task; 10466 task = (pMpi2SCSITaskManagementRequest_t)request_msg; 10467 mptsas_setup_bus_reset_delay(mpt); 10468 rv = mptsas_ioc_task_management(mpt, task->TaskType, 10469 task->DevHandle, (int)task->LUN[1], reply, reply_size, 10470 mode); 10471 10472 if (rv != TRUE) { 10473 status = EIO; 10474 mptsas_log(mpt, CE_WARN, "task management failed"); 10475 } 10476 goto out; 10477 } 10478 10479 if (data_size != 0) { 10480 data_dma_state.size = data_size; 10481 if (mptsas_dma_alloc(mpt, &data_dma_state) != DDI_SUCCESS) { 10482 status = ENOMEM; 10483 mptsas_log(mpt, CE_WARN, "failed to alloc DMA " 10484 "resource"); 10485 goto out; 10486 } 10487 pt_flags |= MPTSAS_DATA_ALLOCATED; 10488 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) { 10489 mutex_exit(&mpt->m_mutex); 10490 for (i = 0; i < data_size; i++) { 10491 if (ddi_copyin(data + i, (uint8_t *) 10492 data_dma_state.memp + i, 1, mode)) { 10493 mutex_enter(&mpt->m_mutex); 10494 status = EFAULT; 10495 mptsas_log(mpt, CE_WARN, "failed to " 10496 "copy read data"); 10497 goto out; 10498 } 10499 } 10500 mutex_enter(&mpt->m_mutex); 10501 } 10502 } 10503 10504 if (dataout_size != 0) { 10505 dataout_dma_state.size = dataout_size; 10506 if (mptsas_dma_alloc(mpt, &dataout_dma_state) != DDI_SUCCESS) { 10507 status = ENOMEM; 10508 mptsas_log(mpt, CE_WARN, "failed to alloc DMA " 10509 "resource"); 10510 goto out; 10511 } 10512 pt_flags |= MPTSAS_DATAOUT_ALLOCATED; 10513 mutex_exit(&mpt->m_mutex); 10514 for (i = 0; i < dataout_size; i++) { 10515 if (ddi_copyin(dataout + i, (uint8_t *) 10516 dataout_dma_state.memp + i, 1, mode)) { 10517 mutex_enter(&mpt->m_mutex); 10518 mptsas_log(mpt, CE_WARN, "failed to copy out" 10519 " data"); 10520 status = EFAULT; 10521 goto out; 10522 } 10523 } 10524 mutex_enter(&mpt->m_mutex); 10525 } 10526 10527 if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 10528 status = EAGAIN; 10529 mptsas_log(mpt, CE_NOTE, "event ack command pool is full"); 10530 goto out; 10531 } 10532 pt_flags |= MPTSAS_REQUEST_POOL_CMD; 10533 10534 bzero((caddr_t)cmd, sizeof (*cmd)); 10535 bzero((caddr_t)pkt, scsi_pkt_size()); 10536 bzero((caddr_t)&pt, sizeof (pt)); 10537 10538 cmd->ioc_cmd_slot = (uint32_t)(rvalue); 10539 10540 pt.request = (uint8_t *)request_msg; 10541 pt.direction = direction; 10542 pt.request_size = request_size; 10543 pt.data_size = data_size; 10544 pt.dataout_size = dataout_size; 10545 pt.data_cookie = data_dma_state.cookie; 10546 pt.dataout_cookie = dataout_dma_state.cookie; 10547 10548 /* 10549 * Form a blank cmd/pkt to store the acknowledgement message 10550 */ 10551 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb[0]; 10552 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; 10553 pkt->pkt_ha_private = (opaque_t)&pt; 10554 pkt->pkt_flags = FLAG_HEAD; 10555 pkt->pkt_time = timeout; 10556 cmd->cmd_pkt = pkt; 10557 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_PASSTHRU; 10558 10559 /* 10560 * Save the command in a slot 10561 */ 10562 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 10563 /* 10564 * Once passthru command get slot, set cmd_flags 10565 * CFLAG_PREPARED. 10566 */ 10567 cmd->cmd_flags |= CFLAG_PREPARED; 10568 mptsas_start_passthru(mpt, cmd); 10569 } else { 10570 mptsas_waitq_add(mpt, cmd); 10571 } 10572 10573 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 10574 cv_wait(&mpt->m_passthru_cv, &mpt->m_mutex); 10575 } 10576 10577 if (cmd->cmd_flags & CFLAG_PREPARED) { 10578 memp = mpt->m_req_frame + (mpt->m_req_frame_size * 10579 cmd->cmd_slot); 10580 request_hdrp = (pMPI2RequestHeader_t)memp; 10581 } 10582 10583 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 10584 status = ETIMEDOUT; 10585 mptsas_log(mpt, CE_WARN, "passthrough command timeout"); 10586 pt_flags |= MPTSAS_CMD_TIMEOUT; 10587 goto out; 10588 } 10589 10590 if (cmd->cmd_rfm) { 10591 /* 10592 * cmd_rfm is zero means the command reply is a CONTEXT 10593 * reply and no PCI Write to post the free reply SMFA 10594 * because no reply message frame is used. 10595 * cmd_rfm is non-zero means the reply is a ADDRESS 10596 * reply and reply message frame is used. 10597 */ 10598 pt_flags |= MPTSAS_ADDRESS_REPLY; 10599 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 10600 DDI_DMA_SYNC_FORCPU); 10601 reply_msg = (pMPI2DefaultReply_t) 10602 (mpt->m_reply_frame + (cmd->cmd_rfm - 10603 mpt->m_reply_frame_dma_addr)); 10604 } 10605 10606 mptsas_fma_check(mpt, cmd); 10607 if (pkt->pkt_reason == CMD_TRAN_ERR) { 10608 status = EAGAIN; 10609 mptsas_log(mpt, CE_WARN, "passthru fma error"); 10610 goto out; 10611 } 10612 if (pkt->pkt_reason == CMD_RESET) { 10613 status = EAGAIN; 10614 mptsas_log(mpt, CE_WARN, "ioc reset abort passthru"); 10615 goto out; 10616 } 10617 10618 if (pkt->pkt_reason == CMD_INCOMPLETE) { 10619 status = EIO; 10620 mptsas_log(mpt, CE_WARN, "passthrough command incomplete"); 10621 goto out; 10622 } 10623 10624 mutex_exit(&mpt->m_mutex); 10625 if (cmd->cmd_flags & CFLAG_PREPARED) { 10626 function = request_hdrp->Function; 10627 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) || 10628 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 10629 reply_len = sizeof (MPI2_SCSI_IO_REPLY); 10630 sense_len = reply_size - reply_len; 10631 } else { 10632 reply_len = reply_size; 10633 sense_len = 0; 10634 } 10635 10636 for (i = 0; i < reply_len; i++) { 10637 if (ddi_copyout((uint8_t *)reply_msg + i, reply + i, 1, 10638 mode)) { 10639 mutex_enter(&mpt->m_mutex); 10640 status = EFAULT; 10641 mptsas_log(mpt, CE_WARN, "failed to copy out " 10642 "reply data"); 10643 goto out; 10644 } 10645 } 10646 for (i = 0; i < sense_len; i++) { 10647 if (ddi_copyout((uint8_t *)request_hdrp + 64 + i, 10648 reply + reply_len + i, 1, mode)) { 10649 mutex_enter(&mpt->m_mutex); 10650 status = EFAULT; 10651 mptsas_log(mpt, CE_WARN, "failed to copy out " 10652 "sense data"); 10653 goto out; 10654 } 10655 } 10656 } 10657 10658 if (data_size) { 10659 if (direction != MPTSAS_PASS_THRU_DIRECTION_WRITE) { 10660 (void) ddi_dma_sync(data_dma_state.handle, 0, 0, 10661 DDI_DMA_SYNC_FORCPU); 10662 for (i = 0; i < data_size; i++) { 10663 if (ddi_copyout((uint8_t *)( 10664 data_dma_state.memp + i), data + i, 1, 10665 mode)) { 10666 mutex_enter(&mpt->m_mutex); 10667 status = EFAULT; 10668 mptsas_log(mpt, CE_WARN, "failed to " 10669 "copy out the reply data"); 10670 goto out; 10671 } 10672 } 10673 } 10674 } 10675 mutex_enter(&mpt->m_mutex); 10676 out: 10677 /* 10678 * Put the reply frame back on the free queue, increment the free 10679 * index, and write the new index to the free index register. But only 10680 * if this reply is an ADDRESS reply. 10681 */ 10682 if (pt_flags & MPTSAS_ADDRESS_REPLY) { 10683 ddi_put32(mpt->m_acc_free_queue_hdl, 10684 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 10685 cmd->cmd_rfm); 10686 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 10687 DDI_DMA_SYNC_FORDEV); 10688 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 10689 mpt->m_free_index = 0; 10690 } 10691 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 10692 mpt->m_free_index); 10693 } 10694 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 10695 mptsas_remove_cmd(mpt, cmd); 10696 pt_flags &= (~MPTSAS_REQUEST_POOL_CMD); 10697 } 10698 if (pt_flags & MPTSAS_REQUEST_POOL_CMD) 10699 mptsas_return_to_pool(mpt, cmd); 10700 if (pt_flags & MPTSAS_DATA_ALLOCATED) { 10701 if (mptsas_check_dma_handle(data_dma_state.handle) != 10702 DDI_SUCCESS) { 10703 ddi_fm_service_impact(mpt->m_dip, 10704 DDI_SERVICE_UNAFFECTED); 10705 status = EFAULT; 10706 } 10707 mptsas_dma_free(&data_dma_state); 10708 } 10709 if (pt_flags & MPTSAS_DATAOUT_ALLOCATED) { 10710 if (mptsas_check_dma_handle(dataout_dma_state.handle) != 10711 DDI_SUCCESS) { 10712 ddi_fm_service_impact(mpt->m_dip, 10713 DDI_SERVICE_UNAFFECTED); 10714 status = EFAULT; 10715 } 10716 mptsas_dma_free(&dataout_dma_state); 10717 } 10718 if (pt_flags & MPTSAS_CMD_TIMEOUT) { 10719 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 10720 mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed"); 10721 } 10722 } 10723 if (request_msg) 10724 kmem_free(request_msg, request_size); 10725 10726 return (status); 10727 } 10728 10729 static int 10730 mptsas_pass_thru(mptsas_t *mpt, mptsas_pass_thru_t *data, int mode) 10731 { 10732 /* 10733 * If timeout is 0, set timeout to default of 60 seconds. 10734 */ 10735 if (data->Timeout == 0) { 10736 data->Timeout = MPTSAS_PASS_THRU_TIME_DEFAULT; 10737 } 10738 10739 if (((data->DataSize == 0) && 10740 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_NONE)) || 10741 ((data->DataSize != 0) && 10742 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_READ) || 10743 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_WRITE) || 10744 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) && 10745 (data->DataOutSize != 0))))) { 10746 if (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) { 10747 data->DataDirection = MPTSAS_PASS_THRU_DIRECTION_READ; 10748 } else { 10749 data->DataOutSize = 0; 10750 } 10751 /* 10752 * Send passthru request messages 10753 */ 10754 return (mptsas_do_passthru(mpt, 10755 (uint8_t *)((uintptr_t)data->PtrRequest), 10756 (uint8_t *)((uintptr_t)data->PtrReply), 10757 (uint8_t *)((uintptr_t)data->PtrData), 10758 data->RequestSize, data->ReplySize, 10759 data->DataSize, data->DataDirection, 10760 (uint8_t *)((uintptr_t)data->PtrDataOut), 10761 data->DataOutSize, data->Timeout, mode)); 10762 } else { 10763 return (EINVAL); 10764 } 10765 } 10766 10767 static uint8_t 10768 mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, uint32_t unique_id) 10769 { 10770 uint8_t index; 10771 10772 for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) { 10773 if (mpt->m_fw_diag_buffer_list[index].unique_id == unique_id) { 10774 return (index); 10775 } 10776 } 10777 10778 return (MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND); 10779 } 10780 10781 static void 10782 mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd) 10783 { 10784 pMpi2DiagBufferPostRequest_t pDiag_post_msg; 10785 pMpi2DiagReleaseRequest_t pDiag_release_msg; 10786 struct scsi_pkt *pkt = cmd->cmd_pkt; 10787 mptsas_diag_request_t *diag = pkt->pkt_ha_private; 10788 uint32_t request_desc_low, i; 10789 10790 ASSERT(mutex_owned(&mpt->m_mutex)); 10791 10792 /* 10793 * Form the diag message depending on the post or release function. 10794 */ 10795 if (diag->function == MPI2_FUNCTION_DIAG_BUFFER_POST) { 10796 pDiag_post_msg = (pMpi2DiagBufferPostRequest_t) 10797 (mpt->m_req_frame + (mpt->m_req_frame_size * 10798 cmd->cmd_slot)); 10799 bzero(pDiag_post_msg, mpt->m_req_frame_size); 10800 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->Function, 10801 diag->function); 10802 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->BufferType, 10803 diag->pBuffer->buffer_type); 10804 ddi_put8(mpt->m_acc_req_frame_hdl, 10805 &pDiag_post_msg->ExtendedType, 10806 diag->pBuffer->extended_type); 10807 ddi_put32(mpt->m_acc_req_frame_hdl, 10808 &pDiag_post_msg->BufferLength, 10809 diag->pBuffer->buffer_data.size); 10810 for (i = 0; i < (sizeof (pDiag_post_msg->ProductSpecific) / 4); 10811 i++) { 10812 ddi_put32(mpt->m_acc_req_frame_hdl, 10813 &pDiag_post_msg->ProductSpecific[i], 10814 diag->pBuffer->product_specific[i]); 10815 } 10816 ddi_put32(mpt->m_acc_req_frame_hdl, 10817 &pDiag_post_msg->BufferAddress.Low, 10818 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress 10819 & 0xffffffffull)); 10820 ddi_put32(mpt->m_acc_req_frame_hdl, 10821 &pDiag_post_msg->BufferAddress.High, 10822 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress 10823 >> 32)); 10824 } else { 10825 pDiag_release_msg = (pMpi2DiagReleaseRequest_t) 10826 (mpt->m_req_frame + (mpt->m_req_frame_size * 10827 cmd->cmd_slot)); 10828 bzero(pDiag_release_msg, mpt->m_req_frame_size); 10829 ddi_put8(mpt->m_acc_req_frame_hdl, 10830 &pDiag_release_msg->Function, diag->function); 10831 ddi_put8(mpt->m_acc_req_frame_hdl, 10832 &pDiag_release_msg->BufferType, 10833 diag->pBuffer->buffer_type); 10834 } 10835 10836 /* 10837 * Send the message 10838 */ 10839 (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0, 10840 DDI_DMA_SYNC_FORDEV); 10841 request_desc_low = (cmd->cmd_slot << 16) + 10842 MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 10843 cmd->cmd_rfm = NULL; 10844 mpt->m_active->m_slot[cmd->cmd_slot] = cmd; 10845 MPTSAS_START_CMD(mpt, request_desc_low, 0); 10846 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 10847 DDI_SUCCESS) || 10848 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 10849 DDI_SUCCESS)) { 10850 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 10851 } 10852 } 10853 10854 static int 10855 mptsas_post_fw_diag_buffer(mptsas_t *mpt, 10856 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code) 10857 { 10858 mptsas_diag_request_t diag; 10859 int status, slot_num, post_flags = 0; 10860 mptsas_cmd_t *cmd = NULL; 10861 struct scsi_pkt *pkt; 10862 pMpi2DiagBufferPostReply_t reply; 10863 uint16_t iocstatus; 10864 uint32_t iocloginfo, transfer_length; 10865 10866 /* 10867 * If buffer is not enabled, just leave. 10868 */ 10869 *return_code = MPTSAS_FW_DIAG_ERROR_POST_FAILED; 10870 if (!pBuffer->enabled) { 10871 status = DDI_FAILURE; 10872 goto out; 10873 } 10874 10875 /* 10876 * Clear some flags initially. 10877 */ 10878 pBuffer->force_release = FALSE; 10879 pBuffer->valid_data = FALSE; 10880 pBuffer->owned_by_firmware = FALSE; 10881 10882 /* 10883 * Get a cmd buffer from the cmd buffer pool 10884 */ 10885 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 10886 status = DDI_FAILURE; 10887 mptsas_log(mpt, CE_NOTE, "command pool is full: Post FW Diag"); 10888 goto out; 10889 } 10890 post_flags |= MPTSAS_REQUEST_POOL_CMD; 10891 10892 bzero((caddr_t)cmd, sizeof (*cmd)); 10893 bzero((caddr_t)pkt, scsi_pkt_size()); 10894 10895 cmd->ioc_cmd_slot = (uint32_t)(slot_num); 10896 10897 diag.pBuffer = pBuffer; 10898 diag.function = MPI2_FUNCTION_DIAG_BUFFER_POST; 10899 10900 /* 10901 * Form a blank cmd/pkt to store the acknowledgement message 10902 */ 10903 pkt->pkt_ha_private = (opaque_t)&diag; 10904 pkt->pkt_flags = FLAG_HEAD; 10905 pkt->pkt_time = 60; 10906 cmd->cmd_pkt = pkt; 10907 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG; 10908 10909 /* 10910 * Save the command in a slot 10911 */ 10912 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 10913 /* 10914 * Once passthru command get slot, set cmd_flags 10915 * CFLAG_PREPARED. 10916 */ 10917 cmd->cmd_flags |= CFLAG_PREPARED; 10918 mptsas_start_diag(mpt, cmd); 10919 } else { 10920 mptsas_waitq_add(mpt, cmd); 10921 } 10922 10923 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 10924 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex); 10925 } 10926 10927 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 10928 status = DDI_FAILURE; 10929 mptsas_log(mpt, CE_WARN, "Post FW Diag command timeout"); 10930 goto out; 10931 } 10932 10933 /* 10934 * cmd_rfm points to the reply message if a reply was given. Check the 10935 * IOCStatus to make sure everything went OK with the FW diag request 10936 * and set buffer flags. 10937 */ 10938 if (cmd->cmd_rfm) { 10939 post_flags |= MPTSAS_ADDRESS_REPLY; 10940 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 10941 DDI_DMA_SYNC_FORCPU); 10942 reply = (pMpi2DiagBufferPostReply_t)(mpt->m_reply_frame + 10943 (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr)); 10944 10945 /* 10946 * Get the reply message data 10947 */ 10948 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 10949 &reply->IOCStatus); 10950 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 10951 &reply->IOCLogInfo); 10952 transfer_length = ddi_get32(mpt->m_acc_reply_frame_hdl, 10953 &reply->TransferLength); 10954 10955 /* 10956 * If post failed quit. 10957 */ 10958 if (iocstatus != MPI2_IOCSTATUS_SUCCESS) { 10959 status = DDI_FAILURE; 10960 NDBG13(("post FW Diag Buffer failed: IOCStatus=0x%x, " 10961 "IOCLogInfo=0x%x, TransferLength=0x%x", iocstatus, 10962 iocloginfo, transfer_length)); 10963 goto out; 10964 } 10965 10966 /* 10967 * Post was successful. 10968 */ 10969 pBuffer->valid_data = TRUE; 10970 pBuffer->owned_by_firmware = TRUE; 10971 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 10972 status = DDI_SUCCESS; 10973 } 10974 10975 out: 10976 /* 10977 * Put the reply frame back on the free queue, increment the free 10978 * index, and write the new index to the free index register. But only 10979 * if this reply is an ADDRESS reply. 10980 */ 10981 if (post_flags & MPTSAS_ADDRESS_REPLY) { 10982 ddi_put32(mpt->m_acc_free_queue_hdl, 10983 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 10984 cmd->cmd_rfm); 10985 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 10986 DDI_DMA_SYNC_FORDEV); 10987 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 10988 mpt->m_free_index = 0; 10989 } 10990 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 10991 mpt->m_free_index); 10992 } 10993 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 10994 mptsas_remove_cmd(mpt, cmd); 10995 post_flags &= (~MPTSAS_REQUEST_POOL_CMD); 10996 } 10997 if (post_flags & MPTSAS_REQUEST_POOL_CMD) { 10998 mptsas_return_to_pool(mpt, cmd); 10999 } 11000 11001 return (status); 11002 } 11003 11004 static int 11005 mptsas_release_fw_diag_buffer(mptsas_t *mpt, 11006 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code, 11007 uint32_t diag_type) 11008 { 11009 mptsas_diag_request_t diag; 11010 int status, slot_num, rel_flags = 0; 11011 mptsas_cmd_t *cmd = NULL; 11012 struct scsi_pkt *pkt; 11013 pMpi2DiagReleaseReply_t reply; 11014 uint16_t iocstatus; 11015 uint32_t iocloginfo; 11016 11017 /* 11018 * If buffer is not enabled, just leave. 11019 */ 11020 *return_code = MPTSAS_FW_DIAG_ERROR_RELEASE_FAILED; 11021 if (!pBuffer->enabled) { 11022 mptsas_log(mpt, CE_NOTE, "This buffer type is not supported " 11023 "by the IOC"); 11024 status = DDI_FAILURE; 11025 goto out; 11026 } 11027 11028 /* 11029 * Clear some flags initially. 11030 */ 11031 pBuffer->force_release = FALSE; 11032 pBuffer->valid_data = FALSE; 11033 pBuffer->owned_by_firmware = FALSE; 11034 11035 /* 11036 * Get a cmd buffer from the cmd buffer pool 11037 */ 11038 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 11039 status = DDI_FAILURE; 11040 mptsas_log(mpt, CE_NOTE, "command pool is full: Release FW " 11041 "Diag"); 11042 goto out; 11043 } 11044 rel_flags |= MPTSAS_REQUEST_POOL_CMD; 11045 11046 bzero((caddr_t)cmd, sizeof (*cmd)); 11047 bzero((caddr_t)pkt, scsi_pkt_size()); 11048 11049 cmd->ioc_cmd_slot = (uint32_t)(slot_num); 11050 11051 diag.pBuffer = pBuffer; 11052 diag.function = MPI2_FUNCTION_DIAG_RELEASE; 11053 11054 /* 11055 * Form a blank cmd/pkt to store the acknowledgement message 11056 */ 11057 pkt->pkt_ha_private = (opaque_t)&diag; 11058 pkt->pkt_flags = FLAG_HEAD; 11059 pkt->pkt_time = 60; 11060 cmd->cmd_pkt = pkt; 11061 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG; 11062 11063 /* 11064 * Save the command in a slot 11065 */ 11066 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 11067 /* 11068 * Once passthru command get slot, set cmd_flags 11069 * CFLAG_PREPARED. 11070 */ 11071 cmd->cmd_flags |= CFLAG_PREPARED; 11072 mptsas_start_diag(mpt, cmd); 11073 } else { 11074 mptsas_waitq_add(mpt, cmd); 11075 } 11076 11077 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 11078 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex); 11079 } 11080 11081 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 11082 status = DDI_FAILURE; 11083 mptsas_log(mpt, CE_WARN, "Release FW Diag command timeout"); 11084 goto out; 11085 } 11086 11087 /* 11088 * cmd_rfm points to the reply message if a reply was given. Check the 11089 * IOCStatus to make sure everything went OK with the FW diag request 11090 * and set buffer flags. 11091 */ 11092 if (cmd->cmd_rfm) { 11093 rel_flags |= MPTSAS_ADDRESS_REPLY; 11094 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 11095 DDI_DMA_SYNC_FORCPU); 11096 reply = (pMpi2DiagReleaseReply_t)(mpt->m_reply_frame + 11097 (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr)); 11098 11099 /* 11100 * Get the reply message data 11101 */ 11102 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 11103 &reply->IOCStatus); 11104 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 11105 &reply->IOCLogInfo); 11106 11107 /* 11108 * If release failed quit. 11109 */ 11110 if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) || 11111 pBuffer->owned_by_firmware) { 11112 status = DDI_FAILURE; 11113 NDBG13(("release FW Diag Buffer failed: " 11114 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus, 11115 iocloginfo)); 11116 goto out; 11117 } 11118 11119 /* 11120 * Release was successful. 11121 */ 11122 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 11123 status = DDI_SUCCESS; 11124 11125 /* 11126 * If this was for an UNREGISTER diag type command, clear the 11127 * unique ID. 11128 */ 11129 if (diag_type == MPTSAS_FW_DIAG_TYPE_UNREGISTER) { 11130 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID; 11131 } 11132 } 11133 11134 out: 11135 /* 11136 * Put the reply frame back on the free queue, increment the free 11137 * index, and write the new index to the free index register. But only 11138 * if this reply is an ADDRESS reply. 11139 */ 11140 if (rel_flags & MPTSAS_ADDRESS_REPLY) { 11141 ddi_put32(mpt->m_acc_free_queue_hdl, 11142 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 11143 cmd->cmd_rfm); 11144 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 11145 DDI_DMA_SYNC_FORDEV); 11146 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 11147 mpt->m_free_index = 0; 11148 } 11149 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 11150 mpt->m_free_index); 11151 } 11152 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 11153 mptsas_remove_cmd(mpt, cmd); 11154 rel_flags &= (~MPTSAS_REQUEST_POOL_CMD); 11155 } 11156 if (rel_flags & MPTSAS_REQUEST_POOL_CMD) { 11157 mptsas_return_to_pool(mpt, cmd); 11158 } 11159 11160 return (status); 11161 } 11162 11163 static int 11164 mptsas_diag_register(mptsas_t *mpt, mptsas_fw_diag_register_t *diag_register, 11165 uint32_t *return_code) 11166 { 11167 mptsas_fw_diagnostic_buffer_t *pBuffer; 11168 uint8_t extended_type, buffer_type, i; 11169 uint32_t buffer_size; 11170 uint32_t unique_id; 11171 int status; 11172 11173 ASSERT(mutex_owned(&mpt->m_mutex)); 11174 11175 extended_type = diag_register->ExtendedType; 11176 buffer_type = diag_register->BufferType; 11177 buffer_size = diag_register->RequestedBufferSize; 11178 unique_id = diag_register->UniqueId; 11179 11180 /* 11181 * Check for valid buffer type 11182 */ 11183 if (buffer_type >= MPI2_DIAG_BUF_TYPE_COUNT) { 11184 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11185 return (DDI_FAILURE); 11186 } 11187 11188 /* 11189 * Get the current buffer and look up the unique ID. The unique ID 11190 * should not be found. If it is, the ID is already in use. 11191 */ 11192 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 11193 pBuffer = &mpt->m_fw_diag_buffer_list[buffer_type]; 11194 if (i != MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 11195 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11196 return (DDI_FAILURE); 11197 } 11198 11199 /* 11200 * The buffer's unique ID should not be registered yet, and the given 11201 * unique ID cannot be 0. 11202 */ 11203 if ((pBuffer->unique_id != MPTSAS_FW_DIAG_INVALID_UID) || 11204 (unique_id == MPTSAS_FW_DIAG_INVALID_UID)) { 11205 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11206 return (DDI_FAILURE); 11207 } 11208 11209 /* 11210 * If this buffer is already posted as immediate, just change owner. 11211 */ 11212 if (pBuffer->immediate && pBuffer->owned_by_firmware && 11213 (pBuffer->unique_id == MPTSAS_FW_DIAG_INVALID_UID)) { 11214 pBuffer->immediate = FALSE; 11215 pBuffer->unique_id = unique_id; 11216 return (DDI_SUCCESS); 11217 } 11218 11219 /* 11220 * Post a new buffer after checking if it's enabled. The DMA buffer 11221 * that is allocated will be contiguous (sgl_len = 1). 11222 */ 11223 if (!pBuffer->enabled) { 11224 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER; 11225 return (DDI_FAILURE); 11226 } 11227 bzero(&pBuffer->buffer_data, sizeof (mptsas_dma_alloc_state_t)); 11228 pBuffer->buffer_data.size = buffer_size; 11229 if (mptsas_dma_alloc(mpt, &pBuffer->buffer_data) != DDI_SUCCESS) { 11230 mptsas_log(mpt, CE_WARN, "failed to alloc DMA resource for " 11231 "diag buffer: size = %d bytes", buffer_size); 11232 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER; 11233 return (DDI_FAILURE); 11234 } 11235 11236 /* 11237 * Copy the given info to the diag buffer and post the buffer. 11238 */ 11239 pBuffer->buffer_type = buffer_type; 11240 pBuffer->immediate = FALSE; 11241 if (buffer_type == MPI2_DIAG_BUF_TYPE_TRACE) { 11242 for (i = 0; i < (sizeof (pBuffer->product_specific) / 4); 11243 i++) { 11244 pBuffer->product_specific[i] = 11245 diag_register->ProductSpecific[i]; 11246 } 11247 } 11248 pBuffer->extended_type = extended_type; 11249 pBuffer->unique_id = unique_id; 11250 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, return_code); 11251 11252 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) != 11253 DDI_SUCCESS) { 11254 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed in " 11255 "mptsas_diag_register."); 11256 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 11257 status = DDI_FAILURE; 11258 } 11259 11260 /* 11261 * In case there was a failure, free the DMA buffer. 11262 */ 11263 if (status == DDI_FAILURE) { 11264 mptsas_dma_free(&pBuffer->buffer_data); 11265 } 11266 11267 return (status); 11268 } 11269 11270 static int 11271 mptsas_diag_unregister(mptsas_t *mpt, 11272 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code) 11273 { 11274 mptsas_fw_diagnostic_buffer_t *pBuffer; 11275 uint8_t i; 11276 uint32_t unique_id; 11277 int status; 11278 11279 ASSERT(mutex_owned(&mpt->m_mutex)); 11280 11281 unique_id = diag_unregister->UniqueId; 11282 11283 /* 11284 * Get the current buffer and look up the unique ID. The unique ID 11285 * should be there. 11286 */ 11287 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 11288 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 11289 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11290 return (DDI_FAILURE); 11291 } 11292 11293 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 11294 11295 /* 11296 * Try to release the buffer from FW before freeing it. If release 11297 * fails, don't free the DMA buffer in case FW tries to access it 11298 * later. If buffer is not owned by firmware, can't release it. 11299 */ 11300 if (!pBuffer->owned_by_firmware) { 11301 status = DDI_SUCCESS; 11302 } else { 11303 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, 11304 return_code, MPTSAS_FW_DIAG_TYPE_UNREGISTER); 11305 } 11306 11307 /* 11308 * At this point, return the current status no matter what happens with 11309 * the DMA buffer. 11310 */ 11311 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID; 11312 if (status == DDI_SUCCESS) { 11313 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) != 11314 DDI_SUCCESS) { 11315 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed " 11316 "in mptsas_diag_unregister."); 11317 ddi_fm_service_impact(mpt->m_dip, 11318 DDI_SERVICE_UNAFFECTED); 11319 } 11320 mptsas_dma_free(&pBuffer->buffer_data); 11321 } 11322 11323 return (status); 11324 } 11325 11326 static int 11327 mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query, 11328 uint32_t *return_code) 11329 { 11330 mptsas_fw_diagnostic_buffer_t *pBuffer; 11331 uint8_t i; 11332 uint32_t unique_id; 11333 11334 ASSERT(mutex_owned(&mpt->m_mutex)); 11335 11336 unique_id = diag_query->UniqueId; 11337 11338 /* 11339 * If ID is valid, query on ID. 11340 * If ID is invalid, query on buffer type. 11341 */ 11342 if (unique_id == MPTSAS_FW_DIAG_INVALID_UID) { 11343 i = diag_query->BufferType; 11344 if (i >= MPI2_DIAG_BUF_TYPE_COUNT) { 11345 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11346 return (DDI_FAILURE); 11347 } 11348 } else { 11349 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 11350 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 11351 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11352 return (DDI_FAILURE); 11353 } 11354 } 11355 11356 /* 11357 * Fill query structure with the diag buffer info. 11358 */ 11359 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 11360 diag_query->BufferType = pBuffer->buffer_type; 11361 diag_query->ExtendedType = pBuffer->extended_type; 11362 if (diag_query->BufferType == MPI2_DIAG_BUF_TYPE_TRACE) { 11363 for (i = 0; i < (sizeof (diag_query->ProductSpecific) / 4); 11364 i++) { 11365 diag_query->ProductSpecific[i] = 11366 pBuffer->product_specific[i]; 11367 } 11368 } 11369 diag_query->TotalBufferSize = pBuffer->buffer_data.size; 11370 diag_query->DriverAddedBufferSize = 0; 11371 diag_query->UniqueId = pBuffer->unique_id; 11372 diag_query->ApplicationFlags = 0; 11373 diag_query->DiagnosticFlags = 0; 11374 11375 /* 11376 * Set/Clear application flags 11377 */ 11378 if (pBuffer->immediate) { 11379 diag_query->ApplicationFlags &= ~MPTSAS_FW_DIAG_FLAG_APP_OWNED; 11380 } else { 11381 diag_query->ApplicationFlags |= MPTSAS_FW_DIAG_FLAG_APP_OWNED; 11382 } 11383 if (pBuffer->valid_data || pBuffer->owned_by_firmware) { 11384 diag_query->ApplicationFlags |= 11385 MPTSAS_FW_DIAG_FLAG_BUFFER_VALID; 11386 } else { 11387 diag_query->ApplicationFlags &= 11388 ~MPTSAS_FW_DIAG_FLAG_BUFFER_VALID; 11389 } 11390 if (pBuffer->owned_by_firmware) { 11391 diag_query->ApplicationFlags |= 11392 MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS; 11393 } else { 11394 diag_query->ApplicationFlags &= 11395 ~MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS; 11396 } 11397 11398 return (DDI_SUCCESS); 11399 } 11400 11401 static int 11402 mptsas_diag_read_buffer(mptsas_t *mpt, 11403 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf, 11404 uint32_t *return_code, int ioctl_mode) 11405 { 11406 mptsas_fw_diagnostic_buffer_t *pBuffer; 11407 uint8_t i, *pData; 11408 uint32_t unique_id, byte; 11409 int status; 11410 11411 ASSERT(mutex_owned(&mpt->m_mutex)); 11412 11413 unique_id = diag_read_buffer->UniqueId; 11414 11415 /* 11416 * Get the current buffer and look up the unique ID. The unique ID 11417 * should be there. 11418 */ 11419 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 11420 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 11421 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11422 return (DDI_FAILURE); 11423 } 11424 11425 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 11426 11427 /* 11428 * Make sure requested read is within limits 11429 */ 11430 if (diag_read_buffer->StartingOffset + diag_read_buffer->BytesToRead > 11431 pBuffer->buffer_data.size) { 11432 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11433 return (DDI_FAILURE); 11434 } 11435 11436 /* 11437 * Copy the requested data from DMA to the diag_read_buffer. The DMA 11438 * buffer that was allocated is one contiguous buffer. 11439 */ 11440 pData = (uint8_t *)(pBuffer->buffer_data.memp + 11441 diag_read_buffer->StartingOffset); 11442 (void) ddi_dma_sync(pBuffer->buffer_data.handle, 0, 0, 11443 DDI_DMA_SYNC_FORCPU); 11444 for (byte = 0; byte < diag_read_buffer->BytesToRead; byte++) { 11445 if (ddi_copyout(pData + byte, ioctl_buf + byte, 1, ioctl_mode) 11446 != 0) { 11447 return (DDI_FAILURE); 11448 } 11449 } 11450 diag_read_buffer->Status = 0; 11451 11452 /* 11453 * Set or clear the Force Release flag. 11454 */ 11455 if (pBuffer->force_release) { 11456 diag_read_buffer->Flags |= MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE; 11457 } else { 11458 diag_read_buffer->Flags &= ~MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE; 11459 } 11460 11461 /* 11462 * If buffer is to be reregistered, make sure it's not already owned by 11463 * firmware first. 11464 */ 11465 status = DDI_SUCCESS; 11466 if (!pBuffer->owned_by_firmware) { 11467 if (diag_read_buffer->Flags & MPTSAS_FW_DIAG_FLAG_REREGISTER) { 11468 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, 11469 return_code); 11470 } 11471 } 11472 11473 return (status); 11474 } 11475 11476 static int 11477 mptsas_diag_release(mptsas_t *mpt, mptsas_fw_diag_release_t *diag_release, 11478 uint32_t *return_code) 11479 { 11480 mptsas_fw_diagnostic_buffer_t *pBuffer; 11481 uint8_t i; 11482 uint32_t unique_id; 11483 int status; 11484 11485 ASSERT(mutex_owned(&mpt->m_mutex)); 11486 11487 unique_id = diag_release->UniqueId; 11488 11489 /* 11490 * Get the current buffer and look up the unique ID. The unique ID 11491 * should be there. 11492 */ 11493 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 11494 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 11495 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11496 return (DDI_FAILURE); 11497 } 11498 11499 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 11500 11501 /* 11502 * If buffer is not owned by firmware, it's already been released. 11503 */ 11504 if (!pBuffer->owned_by_firmware) { 11505 *return_code = MPTSAS_FW_DIAG_ERROR_ALREADY_RELEASED; 11506 return (DDI_FAILURE); 11507 } 11508 11509 /* 11510 * Release the buffer. 11511 */ 11512 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, return_code, 11513 MPTSAS_FW_DIAG_TYPE_RELEASE); 11514 return (status); 11515 } 11516 11517 static int 11518 mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, uint8_t *diag_action, 11519 uint32_t length, uint32_t *return_code, int ioctl_mode) 11520 { 11521 mptsas_fw_diag_register_t diag_register; 11522 mptsas_fw_diag_unregister_t diag_unregister; 11523 mptsas_fw_diag_query_t diag_query; 11524 mptsas_diag_read_buffer_t diag_read_buffer; 11525 mptsas_fw_diag_release_t diag_release; 11526 int status = DDI_SUCCESS; 11527 uint32_t original_return_code, read_buf_len; 11528 11529 ASSERT(mutex_owned(&mpt->m_mutex)); 11530 11531 original_return_code = *return_code; 11532 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 11533 11534 switch (action) { 11535 case MPTSAS_FW_DIAG_TYPE_REGISTER: 11536 if (!length) { 11537 *return_code = 11538 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11539 status = DDI_FAILURE; 11540 break; 11541 } 11542 if (ddi_copyin(diag_action, &diag_register, 11543 sizeof (diag_register), ioctl_mode) != 0) { 11544 return (DDI_FAILURE); 11545 } 11546 status = mptsas_diag_register(mpt, &diag_register, 11547 return_code); 11548 break; 11549 11550 case MPTSAS_FW_DIAG_TYPE_UNREGISTER: 11551 if (length < sizeof (diag_unregister)) { 11552 *return_code = 11553 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11554 status = DDI_FAILURE; 11555 break; 11556 } 11557 if (ddi_copyin(diag_action, &diag_unregister, 11558 sizeof (diag_unregister), ioctl_mode) != 0) { 11559 return (DDI_FAILURE); 11560 } 11561 status = mptsas_diag_unregister(mpt, &diag_unregister, 11562 return_code); 11563 break; 11564 11565 case MPTSAS_FW_DIAG_TYPE_QUERY: 11566 if (length < sizeof (diag_query)) { 11567 *return_code = 11568 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11569 status = DDI_FAILURE; 11570 break; 11571 } 11572 if (ddi_copyin(diag_action, &diag_query, 11573 sizeof (diag_query), ioctl_mode) != 0) { 11574 return (DDI_FAILURE); 11575 } 11576 status = mptsas_diag_query(mpt, &diag_query, 11577 return_code); 11578 if (status == DDI_SUCCESS) { 11579 if (ddi_copyout(&diag_query, diag_action, 11580 sizeof (diag_query), ioctl_mode) != 0) { 11581 return (DDI_FAILURE); 11582 } 11583 } 11584 break; 11585 11586 case MPTSAS_FW_DIAG_TYPE_READ_BUFFER: 11587 if (ddi_copyin(diag_action, &diag_read_buffer, 11588 sizeof (diag_read_buffer) - 4, ioctl_mode) != 0) { 11589 return (DDI_FAILURE); 11590 } 11591 read_buf_len = sizeof (diag_read_buffer) - 11592 sizeof (diag_read_buffer.DataBuffer) + 11593 diag_read_buffer.BytesToRead; 11594 if (length < read_buf_len) { 11595 *return_code = 11596 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11597 status = DDI_FAILURE; 11598 break; 11599 } 11600 status = mptsas_diag_read_buffer(mpt, 11601 &diag_read_buffer, diag_action + 11602 sizeof (diag_read_buffer) - 4, return_code, 11603 ioctl_mode); 11604 if (status == DDI_SUCCESS) { 11605 if (ddi_copyout(&diag_read_buffer, diag_action, 11606 sizeof (diag_read_buffer) - 4, ioctl_mode) 11607 != 0) { 11608 return (DDI_FAILURE); 11609 } 11610 } 11611 break; 11612 11613 case MPTSAS_FW_DIAG_TYPE_RELEASE: 11614 if (length < sizeof (diag_release)) { 11615 *return_code = 11616 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11617 status = DDI_FAILURE; 11618 break; 11619 } 11620 if (ddi_copyin(diag_action, &diag_release, 11621 sizeof (diag_release), ioctl_mode) != 0) { 11622 return (DDI_FAILURE); 11623 } 11624 status = mptsas_diag_release(mpt, &diag_release, 11625 return_code); 11626 break; 11627 11628 default: 11629 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11630 status = DDI_FAILURE; 11631 break; 11632 } 11633 11634 if ((status == DDI_FAILURE) && 11635 (original_return_code == MPTSAS_FW_DIAG_NEW) && 11636 (*return_code != MPTSAS_FW_DIAG_ERROR_SUCCESS)) { 11637 status = DDI_SUCCESS; 11638 } 11639 11640 return (status); 11641 } 11642 11643 static int 11644 mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *user_data, int mode) 11645 { 11646 int status; 11647 mptsas_diag_action_t driver_data; 11648 11649 ASSERT(mutex_owned(&mpt->m_mutex)); 11650 11651 /* 11652 * Copy the user data to a driver data buffer. 11653 */ 11654 if (ddi_copyin(user_data, &driver_data, sizeof (mptsas_diag_action_t), 11655 mode) == 0) { 11656 /* 11657 * Send diag action request if Action is valid 11658 */ 11659 if (driver_data.Action == MPTSAS_FW_DIAG_TYPE_REGISTER || 11660 driver_data.Action == MPTSAS_FW_DIAG_TYPE_UNREGISTER || 11661 driver_data.Action == MPTSAS_FW_DIAG_TYPE_QUERY || 11662 driver_data.Action == MPTSAS_FW_DIAG_TYPE_READ_BUFFER || 11663 driver_data.Action == MPTSAS_FW_DIAG_TYPE_RELEASE) { 11664 status = mptsas_do_diag_action(mpt, driver_data.Action, 11665 (void *)(uintptr_t)driver_data.PtrDiagAction, 11666 driver_data.Length, &driver_data.ReturnCode, 11667 mode); 11668 if (status == DDI_SUCCESS) { 11669 if (ddi_copyout(&driver_data.ReturnCode, 11670 &user_data->ReturnCode, 11671 sizeof (user_data->ReturnCode), mode) 11672 != 0) { 11673 status = EFAULT; 11674 } else { 11675 status = 0; 11676 } 11677 } else { 11678 status = EIO; 11679 } 11680 } else { 11681 status = EINVAL; 11682 } 11683 } else { 11684 status = EFAULT; 11685 } 11686 11687 return (status); 11688 } 11689 11690 /* 11691 * This routine handles the "event query" ioctl. 11692 */ 11693 static int 11694 mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, int mode, 11695 int *rval) 11696 { 11697 int status; 11698 mptsas_event_query_t driverdata; 11699 uint8_t i; 11700 11701 driverdata.Entries = MPTSAS_EVENT_QUEUE_SIZE; 11702 11703 mutex_enter(&mpt->m_mutex); 11704 for (i = 0; i < 4; i++) { 11705 driverdata.Types[i] = mpt->m_event_mask[i]; 11706 } 11707 mutex_exit(&mpt->m_mutex); 11708 11709 if (ddi_copyout(&driverdata, data, sizeof (driverdata), mode) != 0) { 11710 status = EFAULT; 11711 } else { 11712 *rval = MPTIOCTL_STATUS_GOOD; 11713 status = 0; 11714 } 11715 11716 return (status); 11717 } 11718 11719 /* 11720 * This routine handles the "event enable" ioctl. 11721 */ 11722 static int 11723 mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, int mode, 11724 int *rval) 11725 { 11726 int status; 11727 mptsas_event_enable_t driverdata; 11728 uint8_t i; 11729 11730 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) { 11731 mutex_enter(&mpt->m_mutex); 11732 for (i = 0; i < 4; i++) { 11733 mpt->m_event_mask[i] = driverdata.Types[i]; 11734 } 11735 mutex_exit(&mpt->m_mutex); 11736 11737 *rval = MPTIOCTL_STATUS_GOOD; 11738 status = 0; 11739 } else { 11740 status = EFAULT; 11741 } 11742 return (status); 11743 } 11744 11745 /* 11746 * This routine handles the "event report" ioctl. 11747 */ 11748 static int 11749 mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, int mode, 11750 int *rval) 11751 { 11752 int status; 11753 mptsas_event_report_t driverdata; 11754 11755 mutex_enter(&mpt->m_mutex); 11756 11757 if (ddi_copyin(&data->Size, &driverdata.Size, sizeof (driverdata.Size), 11758 mode) == 0) { 11759 if (driverdata.Size >= sizeof (mpt->m_events)) { 11760 if (ddi_copyout(mpt->m_events, data->Events, 11761 sizeof (mpt->m_events), mode) != 0) { 11762 status = EFAULT; 11763 } else { 11764 if (driverdata.Size > sizeof (mpt->m_events)) { 11765 driverdata.Size = 11766 sizeof (mpt->m_events); 11767 if (ddi_copyout(&driverdata.Size, 11768 &data->Size, 11769 sizeof (driverdata.Size), 11770 mode) != 0) { 11771 status = EFAULT; 11772 } else { 11773 *rval = MPTIOCTL_STATUS_GOOD; 11774 status = 0; 11775 } 11776 } else { 11777 *rval = MPTIOCTL_STATUS_GOOD; 11778 status = 0; 11779 } 11780 } 11781 } else { 11782 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT; 11783 status = 0; 11784 } 11785 } else { 11786 status = EFAULT; 11787 } 11788 11789 mutex_exit(&mpt->m_mutex); 11790 return (status); 11791 } 11792 11793 static void 11794 mptsas_lookup_pci_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data) 11795 { 11796 int *reg_data; 11797 uint_t reglen; 11798 11799 /* 11800 * Lookup the 'reg' property and extract the other data 11801 */ 11802 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip, 11803 DDI_PROP_DONTPASS, "reg", ®_data, ®len) == 11804 DDI_PROP_SUCCESS) { 11805 /* 11806 * Extract the PCI data from the 'reg' property first DWORD. 11807 * The entry looks like the following: 11808 * First DWORD: 11809 * Bits 0 - 7 8-bit Register number 11810 * Bits 8 - 10 3-bit Function number 11811 * Bits 11 - 15 5-bit Device number 11812 * Bits 16 - 23 8-bit Bus number 11813 * Bits 24 - 25 2-bit Address Space type identifier 11814 * 11815 */ 11816 adapter_data->PciInformation.u.bits.BusNumber = 11817 (reg_data[0] & 0x00FF0000) >> 16; 11818 adapter_data->PciInformation.u.bits.DeviceNumber = 11819 (reg_data[0] & 0x0000F800) >> 11; 11820 adapter_data->PciInformation.u.bits.FunctionNumber = 11821 (reg_data[0] & 0x00000700) >> 8; 11822 ddi_prop_free((void *)reg_data); 11823 } else { 11824 /* 11825 * If we can't determine the PCI data then we fill in FF's for 11826 * the data to indicate this. 11827 */ 11828 adapter_data->PCIDeviceHwId = 0xFFFFFFFF; 11829 adapter_data->MpiPortNumber = 0xFFFFFFFF; 11830 adapter_data->PciInformation.u.AsDWORD = 0xFFFFFFFF; 11831 } 11832 11833 /* 11834 * Saved in the mpt->m_fwversion 11835 */ 11836 adapter_data->MpiFirmwareVersion = mpt->m_fwversion; 11837 } 11838 11839 static void 11840 mptsas_read_adapter_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data) 11841 { 11842 char *driver_verstr = MPTSAS_MOD_STRING; 11843 11844 mptsas_lookup_pci_data(mpt, adapter_data); 11845 adapter_data->AdapterType = MPTIOCTL_ADAPTER_TYPE_SAS2; 11846 adapter_data->PCIDeviceHwId = (uint32_t)mpt->m_devid; 11847 adapter_data->PCIDeviceHwRev = (uint32_t)mpt->m_revid; 11848 adapter_data->SubSystemId = (uint32_t)mpt->m_ssid; 11849 adapter_data->SubsystemVendorId = (uint32_t)mpt->m_svid; 11850 (void) strcpy((char *)&adapter_data->DriverVersion[0], driver_verstr); 11851 adapter_data->BiosVersion = 0; 11852 (void) mptsas_get_bios_page3(mpt, &adapter_data->BiosVersion); 11853 } 11854 11855 static void 11856 mptsas_read_pci_info(mptsas_t *mpt, mptsas_pci_info_t *pci_info) 11857 { 11858 int *reg_data, i; 11859 uint_t reglen; 11860 11861 /* 11862 * Lookup the 'reg' property and extract the other data 11863 */ 11864 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip, 11865 DDI_PROP_DONTPASS, "reg", ®_data, ®len) == 11866 DDI_PROP_SUCCESS) { 11867 /* 11868 * Extract the PCI data from the 'reg' property first DWORD. 11869 * The entry looks like the following: 11870 * First DWORD: 11871 * Bits 8 - 10 3-bit Function number 11872 * Bits 11 - 15 5-bit Device number 11873 * Bits 16 - 23 8-bit Bus number 11874 */ 11875 pci_info->BusNumber = (reg_data[0] & 0x00FF0000) >> 16; 11876 pci_info->DeviceNumber = (reg_data[0] & 0x0000F800) >> 11; 11877 pci_info->FunctionNumber = (reg_data[0] & 0x00000700) >> 8; 11878 ddi_prop_free((void *)reg_data); 11879 } else { 11880 /* 11881 * If we can't determine the PCI info then we fill in FF's for 11882 * the data to indicate this. 11883 */ 11884 pci_info->BusNumber = 0xFFFFFFFF; 11885 pci_info->DeviceNumber = 0xFF; 11886 pci_info->FunctionNumber = 0xFF; 11887 } 11888 11889 /* 11890 * Now get the interrupt vector and the pci header. The vector can 11891 * only be 0 right now. The header is the first 256 bytes of config 11892 * space. 11893 */ 11894 pci_info->InterruptVector = 0; 11895 for (i = 0; i < sizeof (pci_info->PciHeader); i++) { 11896 pci_info->PciHeader[i] = pci_config_get8(mpt->m_config_handle, 11897 i); 11898 } 11899 } 11900 11901 static int 11902 mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, int mode) 11903 { 11904 int status = 0; 11905 mptsas_reg_access_t driverdata; 11906 11907 mutex_enter(&mpt->m_mutex); 11908 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) { 11909 switch (driverdata.Command) { 11910 /* 11911 * IO access is not supported. 11912 */ 11913 case REG_IO_READ: 11914 case REG_IO_WRITE: 11915 mptsas_log(mpt, CE_WARN, "IO access is not " 11916 "supported. Use memory access."); 11917 status = EINVAL; 11918 break; 11919 11920 case REG_MEM_READ: 11921 driverdata.RegData = ddi_get32(mpt->m_datap, 11922 (uint32_t *)(void *)mpt->m_reg + 11923 driverdata.RegOffset); 11924 if (ddi_copyout(&driverdata.RegData, 11925 &data->RegData, 11926 sizeof (driverdata.RegData), mode) != 0) { 11927 mptsas_log(mpt, CE_WARN, "Register " 11928 "Read Failed"); 11929 status = EFAULT; 11930 } 11931 break; 11932 11933 case REG_MEM_WRITE: 11934 ddi_put32(mpt->m_datap, 11935 (uint32_t *)(void *)mpt->m_reg + 11936 driverdata.RegOffset, 11937 driverdata.RegData); 11938 break; 11939 11940 default: 11941 status = EINVAL; 11942 break; 11943 } 11944 } else { 11945 status = EFAULT; 11946 } 11947 11948 mutex_exit(&mpt->m_mutex); 11949 return (status); 11950 } 11951 11952 static int 11953 mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp, 11954 int *rval) 11955 { 11956 int status = 0; 11957 mptsas_t *mpt; 11958 mptsas_update_flash_t flashdata; 11959 mptsas_pass_thru_t passthru_data; 11960 mptsas_adapter_data_t adapter_data; 11961 mptsas_pci_info_t pci_info; 11962 int copylen; 11963 11964 int iport_flag = 0; 11965 dev_info_t *dip = NULL; 11966 mptsas_phymask_t phymask = 0; 11967 struct devctl_iocdata *dcp = NULL; 11968 uint32_t slotstatus = 0; 11969 char *addr = NULL; 11970 mptsas_target_t *ptgt = NULL; 11971 11972 *rval = MPTIOCTL_STATUS_GOOD; 11973 if (secpolicy_sys_config(credp, B_FALSE) != 0) { 11974 return (EPERM); 11975 } 11976 11977 mpt = ddi_get_soft_state(mptsas_state, MINOR2INST(getminor(dev))); 11978 if (mpt == NULL) { 11979 /* 11980 * Called from iport node, get the states 11981 */ 11982 iport_flag = 1; 11983 dip = mptsas_get_dip_from_dev(dev, &phymask); 11984 if (dip == NULL) { 11985 return (ENXIO); 11986 } 11987 mpt = DIP2MPT(dip); 11988 } 11989 /* Make sure power level is D0 before accessing registers */ 11990 mutex_enter(&mpt->m_mutex); 11991 if (mpt->m_options & MPTSAS_OPT_PM) { 11992 (void) pm_busy_component(mpt->m_dip, 0); 11993 if (mpt->m_power_level != PM_LEVEL_D0) { 11994 mutex_exit(&mpt->m_mutex); 11995 if (pm_raise_power(mpt->m_dip, 0, PM_LEVEL_D0) != 11996 DDI_SUCCESS) { 11997 mptsas_log(mpt, CE_WARN, 11998 "mptsas%d: mptsas_ioctl: Raise power " 11999 "request failed.", mpt->m_instance); 12000 (void) pm_idle_component(mpt->m_dip, 0); 12001 return (ENXIO); 12002 } 12003 } else { 12004 mutex_exit(&mpt->m_mutex); 12005 } 12006 } else { 12007 mutex_exit(&mpt->m_mutex); 12008 } 12009 12010 if (iport_flag) { 12011 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, rval); 12012 if (status != 0) { 12013 goto out; 12014 } 12015 /* 12016 * The following code control the OK2RM LED, it doesn't affect 12017 * the ioctl return status. 12018 */ 12019 if ((cmd == DEVCTL_DEVICE_ONLINE) || 12020 (cmd == DEVCTL_DEVICE_OFFLINE)) { 12021 if (ndi_dc_allochdl((void *)data, &dcp) != 12022 NDI_SUCCESS) { 12023 goto out; 12024 } 12025 addr = ndi_dc_getaddr(dcp); 12026 ptgt = mptsas_addr_to_ptgt(mpt, addr, phymask); 12027 if (ptgt == NULL) { 12028 NDBG14(("mptsas_ioctl led control: tgt %s not " 12029 "found", addr)); 12030 ndi_dc_freehdl(dcp); 12031 goto out; 12032 } 12033 mutex_enter(&mpt->m_mutex); 12034 if (cmd == DEVCTL_DEVICE_ONLINE) { 12035 ptgt->m_tgt_unconfigured = 0; 12036 } else if (cmd == DEVCTL_DEVICE_OFFLINE) { 12037 ptgt->m_tgt_unconfigured = 1; 12038 } 12039 slotstatus = 0; 12040 #ifdef MPTSAS_GET_LED 12041 /* 12042 * The get led status can't get a valid/reasonable 12043 * state, so ignore the get led status, and write the 12044 * required value directly 12045 */ 12046 if (mptsas_get_led_status(mpt, ptgt, &slotstatus) != 12047 DDI_SUCCESS) { 12048 NDBG14(("mptsas_ioctl: get LED for tgt %s " 12049 "failed %x", addr, slotstatus)); 12050 slotstatus = 0; 12051 } 12052 NDBG14(("mptsas_ioctl: LED status %x for %s", 12053 slotstatus, addr)); 12054 #endif 12055 if (cmd == DEVCTL_DEVICE_OFFLINE) { 12056 slotstatus |= 12057 MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE; 12058 } else { 12059 slotstatus &= 12060 ~MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE; 12061 } 12062 if (mptsas_set_led_status(mpt, ptgt, slotstatus) != 12063 DDI_SUCCESS) { 12064 NDBG14(("mptsas_ioctl: set LED for tgt %s " 12065 "failed %x", addr, slotstatus)); 12066 } 12067 mutex_exit(&mpt->m_mutex); 12068 ndi_dc_freehdl(dcp); 12069 } 12070 goto out; 12071 } 12072 switch (cmd) { 12073 case MPTIOCTL_UPDATE_FLASH: 12074 if (ddi_copyin((void *)data, &flashdata, 12075 sizeof (struct mptsas_update_flash), mode)) { 12076 status = EFAULT; 12077 break; 12078 } 12079 12080 mutex_enter(&mpt->m_mutex); 12081 if (mptsas_update_flash(mpt, 12082 (caddr_t)(long)flashdata.PtrBuffer, 12083 flashdata.ImageSize, flashdata.ImageType, mode)) { 12084 status = EFAULT; 12085 } 12086 12087 /* 12088 * Reset the chip to start using the new 12089 * firmware. Reset if failed also. 12090 */ 12091 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 12092 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) { 12093 status = EFAULT; 12094 } 12095 mutex_exit(&mpt->m_mutex); 12096 break; 12097 case MPTIOCTL_PASS_THRU: 12098 /* 12099 * The user has requested to pass through a command to 12100 * be executed by the MPT firmware. Call our routine 12101 * which does this. Only allow one passthru IOCTL at 12102 * one time. Other threads will block on 12103 * m_passthru_mutex, which is of adaptive variant. 12104 */ 12105 if (ddi_copyin((void *)data, &passthru_data, 12106 sizeof (mptsas_pass_thru_t), mode)) { 12107 status = EFAULT; 12108 break; 12109 } 12110 mutex_enter(&mpt->m_passthru_mutex); 12111 mutex_enter(&mpt->m_mutex); 12112 status = mptsas_pass_thru(mpt, &passthru_data, mode); 12113 mutex_exit(&mpt->m_mutex); 12114 mutex_exit(&mpt->m_passthru_mutex); 12115 12116 break; 12117 case MPTIOCTL_GET_ADAPTER_DATA: 12118 /* 12119 * The user has requested to read adapter data. Call 12120 * our routine which does this. 12121 */ 12122 bzero(&adapter_data, sizeof (mptsas_adapter_data_t)); 12123 if (ddi_copyin((void *)data, (void *)&adapter_data, 12124 sizeof (mptsas_adapter_data_t), mode)) { 12125 status = EFAULT; 12126 break; 12127 } 12128 if (adapter_data.StructureLength >= 12129 sizeof (mptsas_adapter_data_t)) { 12130 adapter_data.StructureLength = (uint32_t) 12131 sizeof (mptsas_adapter_data_t); 12132 copylen = sizeof (mptsas_adapter_data_t); 12133 mutex_enter(&mpt->m_mutex); 12134 mptsas_read_adapter_data(mpt, &adapter_data); 12135 mutex_exit(&mpt->m_mutex); 12136 } else { 12137 adapter_data.StructureLength = (uint32_t) 12138 sizeof (mptsas_adapter_data_t); 12139 copylen = sizeof (adapter_data.StructureLength); 12140 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT; 12141 } 12142 if (ddi_copyout((void *)(&adapter_data), (void *)data, 12143 copylen, mode) != 0) { 12144 status = EFAULT; 12145 } 12146 break; 12147 case MPTIOCTL_GET_PCI_INFO: 12148 /* 12149 * The user has requested to read pci info. Call 12150 * our routine which does this. 12151 */ 12152 bzero(&pci_info, sizeof (mptsas_pci_info_t)); 12153 mutex_enter(&mpt->m_mutex); 12154 mptsas_read_pci_info(mpt, &pci_info); 12155 mutex_exit(&mpt->m_mutex); 12156 if (ddi_copyout((void *)(&pci_info), (void *)data, 12157 sizeof (mptsas_pci_info_t), mode) != 0) { 12158 status = EFAULT; 12159 } 12160 break; 12161 case MPTIOCTL_RESET_ADAPTER: 12162 mutex_enter(&mpt->m_mutex); 12163 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 12164 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 12165 mptsas_log(mpt, CE_WARN, "reset adapter IOCTL " 12166 "failed"); 12167 status = EFAULT; 12168 } 12169 mutex_exit(&mpt->m_mutex); 12170 break; 12171 case MPTIOCTL_DIAG_ACTION: 12172 /* 12173 * The user has done a diag buffer action. Call our 12174 * routine which does this. Only allow one diag action 12175 * at one time. 12176 */ 12177 mutex_enter(&mpt->m_mutex); 12178 if (mpt->m_diag_action_in_progress) { 12179 mutex_exit(&mpt->m_mutex); 12180 return (EBUSY); 12181 } 12182 mpt->m_diag_action_in_progress = 1; 12183 status = mptsas_diag_action(mpt, 12184 (mptsas_diag_action_t *)data, mode); 12185 mpt->m_diag_action_in_progress = 0; 12186 mutex_exit(&mpt->m_mutex); 12187 break; 12188 case MPTIOCTL_EVENT_QUERY: 12189 /* 12190 * The user has done an event query. Call our routine 12191 * which does this. 12192 */ 12193 status = mptsas_event_query(mpt, 12194 (mptsas_event_query_t *)data, mode, rval); 12195 break; 12196 case MPTIOCTL_EVENT_ENABLE: 12197 /* 12198 * The user has done an event enable. Call our routine 12199 * which does this. 12200 */ 12201 status = mptsas_event_enable(mpt, 12202 (mptsas_event_enable_t *)data, mode, rval); 12203 break; 12204 case MPTIOCTL_EVENT_REPORT: 12205 /* 12206 * The user has done an event report. Call our routine 12207 * which does this. 12208 */ 12209 status = mptsas_event_report(mpt, 12210 (mptsas_event_report_t *)data, mode, rval); 12211 break; 12212 case MPTIOCTL_REG_ACCESS: 12213 /* 12214 * The user has requested register access. Call our 12215 * routine which does this. 12216 */ 12217 status = mptsas_reg_access(mpt, 12218 (mptsas_reg_access_t *)data, mode); 12219 break; 12220 default: 12221 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, 12222 rval); 12223 break; 12224 } 12225 12226 out: 12227 if (mpt->m_options & MPTSAS_OPT_PM) 12228 (void) pm_idle_component(mpt->m_dip, 0); 12229 return (status); 12230 } 12231 12232 int 12233 mptsas_restart_ioc(mptsas_t *mpt) 12234 { 12235 int rval = DDI_SUCCESS; 12236 mptsas_target_t *ptgt = NULL; 12237 12238 ASSERT(mutex_owned(&mpt->m_mutex)); 12239 12240 /* 12241 * Set a flag telling I/O path that we're processing a reset. This is 12242 * needed because after the reset is complete, the hash table still 12243 * needs to be rebuilt. If I/Os are started before the hash table is 12244 * rebuilt, I/O errors will occur. This flag allows I/Os to be marked 12245 * so that they can be retried. 12246 */ 12247 mpt->m_in_reset = TRUE; 12248 12249 /* 12250 * Set all throttles to HOLD 12251 */ 12252 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 12253 MPTSAS_HASH_FIRST); 12254 while (ptgt != NULL) { 12255 mutex_enter(&ptgt->m_tgt_intr_mutex); 12256 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 12257 mutex_exit(&ptgt->m_tgt_intr_mutex); 12258 12259 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 12260 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 12261 } 12262 12263 /* 12264 * Disable interrupts 12265 */ 12266 MPTSAS_DISABLE_INTR(mpt); 12267 12268 /* 12269 * Abort all commands: outstanding commands, commands in waitq 12270 */ 12271 mptsas_flush_hba(mpt); 12272 12273 /* 12274 * Reinitialize the chip. 12275 */ 12276 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) { 12277 rval = DDI_FAILURE; 12278 } 12279 12280 /* 12281 * Enable interrupts again 12282 */ 12283 MPTSAS_ENABLE_INTR(mpt); 12284 12285 /* 12286 * If mptsas_init_chip was successful, update the driver data. 12287 */ 12288 if (rval == DDI_SUCCESS) { 12289 mptsas_update_driver_data(mpt); 12290 } 12291 12292 /* 12293 * Reset the throttles 12294 */ 12295 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 12296 MPTSAS_HASH_FIRST); 12297 while (ptgt != NULL) { 12298 mutex_enter(&ptgt->m_tgt_intr_mutex); 12299 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 12300 mutex_exit(&ptgt->m_tgt_intr_mutex); 12301 12302 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 12303 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 12304 } 12305 12306 mptsas_doneq_empty(mpt); 12307 mptsas_restart_hba(mpt); 12308 12309 if (rval != DDI_SUCCESS) { 12310 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 12311 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 12312 } 12313 12314 /* 12315 * Clear the reset flag so that I/Os can continue. 12316 */ 12317 mpt->m_in_reset = FALSE; 12318 12319 return (rval); 12320 } 12321 12322 static int 12323 mptsas_init_chip(mptsas_t *mpt, int first_time) 12324 { 12325 ddi_dma_cookie_t cookie; 12326 uint32_t i; 12327 int rval; 12328 12329 /* 12330 * Check to see if the firmware image is valid 12331 */ 12332 if (ddi_get32(mpt->m_datap, &mpt->m_reg->HostDiagnostic) & 12333 MPI2_DIAG_FLASH_BAD_SIG) { 12334 mptsas_log(mpt, CE_WARN, "mptsas bad flash signature!"); 12335 goto fail; 12336 } 12337 12338 /* 12339 * Reset the chip 12340 */ 12341 rval = mptsas_ioc_reset(mpt); 12342 if (rval == MPTSAS_RESET_FAIL) { 12343 mptsas_log(mpt, CE_WARN, "hard reset failed!"); 12344 goto fail; 12345 } 12346 12347 if ((rval == MPTSAS_SUCCESS_MUR) && (!first_time)) { 12348 goto mur; 12349 } 12350 /* 12351 * Setup configuration space 12352 */ 12353 if (mptsas_config_space_init(mpt) == FALSE) { 12354 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init " 12355 "failed!"); 12356 goto fail; 12357 } 12358 12359 /* 12360 * IOC facts can change after a diag reset so all buffers that are 12361 * based on these numbers must be de-allocated and re-allocated. Get 12362 * new IOC facts each time chip is initialized. 12363 */ 12364 if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) { 12365 mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed"); 12366 goto fail; 12367 } 12368 12369 if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) { 12370 goto fail; 12371 } 12372 /* 12373 * Allocate request message frames, reply free queue, reply descriptor 12374 * post queue, and reply message frames using latest IOC facts. 12375 */ 12376 if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) { 12377 mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed"); 12378 goto fail; 12379 } 12380 if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) { 12381 mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue failed!"); 12382 goto fail; 12383 } 12384 if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) { 12385 mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue failed!"); 12386 goto fail; 12387 } 12388 if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) { 12389 mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames failed!"); 12390 goto fail; 12391 } 12392 12393 mur: 12394 /* 12395 * Re-Initialize ioc to operational state 12396 */ 12397 if (mptsas_ioc_init(mpt) == DDI_FAILURE) { 12398 mptsas_log(mpt, CE_WARN, "mptsas_ioc_init failed"); 12399 goto fail; 12400 } 12401 12402 mptsas_alloc_reply_args(mpt); 12403 12404 /* 12405 * Initialize reply post index. Reply free index is initialized after 12406 * the next loop. 12407 */ 12408 mpt->m_post_index = 0; 12409 12410 /* 12411 * Initialize the Reply Free Queue with the physical addresses of our 12412 * reply frames. 12413 */ 12414 cookie.dmac_address = mpt->m_reply_frame_dma_addr; 12415 for (i = 0; i < mpt->m_max_replies; i++) { 12416 ddi_put32(mpt->m_acc_free_queue_hdl, 12417 &((uint32_t *)(void *)mpt->m_free_queue)[i], 12418 cookie.dmac_address); 12419 cookie.dmac_address += mpt->m_reply_frame_size; 12420 } 12421 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 12422 DDI_DMA_SYNC_FORDEV); 12423 12424 /* 12425 * Initialize the reply free index to one past the last frame on the 12426 * queue. This will signify that the queue is empty to start with. 12427 */ 12428 mpt->m_free_index = i; 12429 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, i); 12430 12431 /* 12432 * Initialize the reply post queue to 0xFFFFFFFF,0xFFFFFFFF's. 12433 */ 12434 for (i = 0; i < mpt->m_post_queue_depth; i++) { 12435 ddi_put64(mpt->m_acc_post_queue_hdl, 12436 &((uint64_t *)(void *)mpt->m_post_queue)[i], 12437 0xFFFFFFFFFFFFFFFF); 12438 } 12439 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 12440 DDI_DMA_SYNC_FORDEV); 12441 12442 /* 12443 * Enable ports 12444 */ 12445 if (mptsas_ioc_enable_port(mpt) == DDI_FAILURE) { 12446 mptsas_log(mpt, CE_WARN, "mptsas_ioc_enable_port failed"); 12447 goto fail; 12448 } 12449 12450 /* 12451 * enable events 12452 */ 12453 if (mptsas_ioc_enable_event_notification(mpt)) { 12454 goto fail; 12455 } 12456 12457 /* 12458 * We need checks in attach and these. 12459 * chip_init is called in mult. places 12460 */ 12461 12462 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 12463 DDI_SUCCESS) || 12464 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) != 12465 DDI_SUCCESS) || 12466 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) != 12467 DDI_SUCCESS) || 12468 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) != 12469 DDI_SUCCESS) || 12470 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) != 12471 DDI_SUCCESS)) { 12472 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 12473 goto fail; 12474 } 12475 12476 /* Check all acc handles */ 12477 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) || 12478 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 12479 DDI_SUCCESS) || 12480 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) != 12481 DDI_SUCCESS) || 12482 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) != 12483 DDI_SUCCESS) || 12484 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) != 12485 DDI_SUCCESS) || 12486 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) != 12487 DDI_SUCCESS) || 12488 (mptsas_check_acc_handle(mpt->m_config_handle) != 12489 DDI_SUCCESS)) { 12490 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 12491 goto fail; 12492 } 12493 12494 return (DDI_SUCCESS); 12495 12496 fail: 12497 return (DDI_FAILURE); 12498 } 12499 12500 static int 12501 mptsas_get_pci_cap(mptsas_t *mpt) 12502 { 12503 ushort_t caps_ptr, cap, cap_count; 12504 12505 if (mpt->m_config_handle == NULL) 12506 return (FALSE); 12507 /* 12508 * Check if capabilities list is supported and if so, 12509 * get initial capabilities pointer and clear bits 0,1. 12510 */ 12511 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) 12512 & PCI_STAT_CAP) { 12513 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle, 12514 PCI_CONF_CAP_PTR), 4); 12515 } else { 12516 caps_ptr = PCI_CAP_NEXT_PTR_NULL; 12517 } 12518 12519 /* 12520 * Walk capabilities if supported. 12521 */ 12522 for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) { 12523 12524 /* 12525 * Check that we haven't exceeded the maximum number of 12526 * capabilities and that the pointer is in a valid range. 12527 */ 12528 if (++cap_count > 48) { 12529 mptsas_log(mpt, CE_WARN, 12530 "too many device capabilities.\n"); 12531 break; 12532 } 12533 if (caps_ptr < 64) { 12534 mptsas_log(mpt, CE_WARN, 12535 "capabilities pointer 0x%x out of range.\n", 12536 caps_ptr); 12537 break; 12538 } 12539 12540 /* 12541 * Get next capability and check that it is valid. 12542 * For now, we only support power management. 12543 */ 12544 cap = pci_config_get8(mpt->m_config_handle, caps_ptr); 12545 switch (cap) { 12546 case PCI_CAP_ID_PM: 12547 mptsas_log(mpt, CE_NOTE, 12548 "?mptsas%d supports power management.\n", 12549 mpt->m_instance); 12550 mpt->m_options |= MPTSAS_OPT_PM; 12551 12552 /* Save PMCSR offset */ 12553 mpt->m_pmcsr_offset = caps_ptr + PCI_PMCSR; 12554 break; 12555 /* 12556 * The following capabilities are valid. Any others 12557 * will cause a message to be logged. 12558 */ 12559 case PCI_CAP_ID_VPD: 12560 case PCI_CAP_ID_MSI: 12561 case PCI_CAP_ID_PCIX: 12562 case PCI_CAP_ID_PCI_E: 12563 case PCI_CAP_ID_MSI_X: 12564 break; 12565 default: 12566 mptsas_log(mpt, CE_NOTE, 12567 "?mptsas%d unrecognized capability " 12568 "0x%x.\n", mpt->m_instance, cap); 12569 break; 12570 } 12571 12572 /* 12573 * Get next capabilities pointer and clear bits 0,1. 12574 */ 12575 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle, 12576 (caps_ptr + PCI_CAP_NEXT_PTR)), 4); 12577 } 12578 return (TRUE); 12579 } 12580 12581 static int 12582 mptsas_init_pm(mptsas_t *mpt) 12583 { 12584 char pmc_name[16]; 12585 char *pmc[] = { 12586 NULL, 12587 "0=Off (PCI D3 State)", 12588 "3=On (PCI D0 State)", 12589 NULL 12590 }; 12591 uint16_t pmcsr_stat; 12592 12593 if (mptsas_get_pci_cap(mpt) == FALSE) { 12594 return (DDI_FAILURE); 12595 } 12596 /* 12597 * If PCI's capability does not support PM, then don't need 12598 * to registe the pm-components 12599 */ 12600 if (!(mpt->m_options & MPTSAS_OPT_PM)) 12601 return (DDI_SUCCESS); 12602 /* 12603 * If power management is supported by this chip, create 12604 * pm-components property for the power management framework 12605 */ 12606 (void) sprintf(pmc_name, "NAME=mptsas%d", mpt->m_instance); 12607 pmc[0] = pmc_name; 12608 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, mpt->m_dip, 12609 "pm-components", pmc, 3) != DDI_PROP_SUCCESS) { 12610 mutex_enter(&mpt->m_intr_mutex); 12611 mpt->m_options &= ~MPTSAS_OPT_PM; 12612 mutex_exit(&mpt->m_intr_mutex); 12613 mptsas_log(mpt, CE_WARN, 12614 "mptsas%d: pm-component property creation failed.", 12615 mpt->m_instance); 12616 return (DDI_FAILURE); 12617 } 12618 12619 /* 12620 * Power on device. 12621 */ 12622 (void) pm_busy_component(mpt->m_dip, 0); 12623 pmcsr_stat = pci_config_get16(mpt->m_config_handle, 12624 mpt->m_pmcsr_offset); 12625 if ((pmcsr_stat & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_D0) { 12626 mptsas_log(mpt, CE_WARN, "mptsas%d: Power up the device", 12627 mpt->m_instance); 12628 pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset, 12629 PCI_PMCSR_D0); 12630 } 12631 if (pm_power_has_changed(mpt->m_dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) { 12632 mptsas_log(mpt, CE_WARN, "pm_power_has_changed failed"); 12633 return (DDI_FAILURE); 12634 } 12635 mutex_enter(&mpt->m_intr_mutex); 12636 mpt->m_power_level = PM_LEVEL_D0; 12637 mutex_exit(&mpt->m_intr_mutex); 12638 /* 12639 * Set pm idle delay. 12640 */ 12641 mpt->m_pm_idle_delay = ddi_prop_get_int(DDI_DEV_T_ANY, 12642 mpt->m_dip, 0, "mptsas-pm-idle-delay", MPTSAS_PM_IDLE_TIMEOUT); 12643 12644 return (DDI_SUCCESS); 12645 } 12646 12647 static int 12648 mptsas_register_intrs(mptsas_t *mpt) 12649 { 12650 dev_info_t *dip; 12651 int intr_types; 12652 12653 dip = mpt->m_dip; 12654 12655 /* Get supported interrupt types */ 12656 if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) { 12657 mptsas_log(mpt, CE_WARN, "ddi_intr_get_supported_types " 12658 "failed\n"); 12659 return (FALSE); 12660 } 12661 12662 NDBG6(("ddi_intr_get_supported_types() returned: 0x%x", intr_types)); 12663 12664 /* 12665 * Try MSI, but fall back to FIXED 12666 */ 12667 if (mptsas_enable_msi && (intr_types & DDI_INTR_TYPE_MSI)) { 12668 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_MSI) == DDI_SUCCESS) { 12669 NDBG0(("Using MSI interrupt type")); 12670 mpt->m_intr_type = DDI_INTR_TYPE_MSI; 12671 return (TRUE); 12672 } 12673 } 12674 if (intr_types & DDI_INTR_TYPE_FIXED) { 12675 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_FIXED) == DDI_SUCCESS) { 12676 NDBG0(("Using FIXED interrupt type")); 12677 mpt->m_intr_type = DDI_INTR_TYPE_FIXED; 12678 return (TRUE); 12679 } else { 12680 NDBG0(("FIXED interrupt registration failed")); 12681 return (FALSE); 12682 } 12683 } 12684 12685 return (FALSE); 12686 } 12687 12688 static void 12689 mptsas_unregister_intrs(mptsas_t *mpt) 12690 { 12691 mptsas_rem_intrs(mpt); 12692 } 12693 12694 /* 12695 * mptsas_add_intrs: 12696 * 12697 * Register FIXED or MSI interrupts. 12698 */ 12699 static int 12700 mptsas_add_intrs(mptsas_t *mpt, int intr_type) 12701 { 12702 dev_info_t *dip = mpt->m_dip; 12703 int avail, actual, count = 0; 12704 int i, flag, ret; 12705 12706 NDBG6(("mptsas_add_intrs:interrupt type 0x%x", intr_type)); 12707 12708 /* Get number of interrupts */ 12709 ret = ddi_intr_get_nintrs(dip, intr_type, &count); 12710 if ((ret != DDI_SUCCESS) || (count <= 0)) { 12711 mptsas_log(mpt, CE_WARN, "ddi_intr_get_nintrs() failed, " 12712 "ret %d count %d\n", ret, count); 12713 12714 return (DDI_FAILURE); 12715 } 12716 12717 /* Get number of available interrupts */ 12718 ret = ddi_intr_get_navail(dip, intr_type, &avail); 12719 if ((ret != DDI_SUCCESS) || (avail == 0)) { 12720 mptsas_log(mpt, CE_WARN, "ddi_intr_get_navail() failed, " 12721 "ret %d avail %d\n", ret, avail); 12722 12723 return (DDI_FAILURE); 12724 } 12725 12726 if (avail < count) { 12727 mptsas_log(mpt, CE_NOTE, "ddi_intr_get_nvail returned %d, " 12728 "navail() returned %d", count, avail); 12729 } 12730 12731 /* Mpt only have one interrupt routine */ 12732 if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) { 12733 count = 1; 12734 } 12735 12736 /* Allocate an array of interrupt handles */ 12737 mpt->m_intr_size = count * sizeof (ddi_intr_handle_t); 12738 mpt->m_htable = kmem_alloc(mpt->m_intr_size, KM_SLEEP); 12739 12740 flag = DDI_INTR_ALLOC_NORMAL; 12741 12742 /* call ddi_intr_alloc() */ 12743 ret = ddi_intr_alloc(dip, mpt->m_htable, intr_type, 0, 12744 count, &actual, flag); 12745 12746 if ((ret != DDI_SUCCESS) || (actual == 0)) { 12747 mptsas_log(mpt, CE_WARN, "ddi_intr_alloc() failed, ret %d\n", 12748 ret); 12749 kmem_free(mpt->m_htable, mpt->m_intr_size); 12750 return (DDI_FAILURE); 12751 } 12752 12753 /* use interrupt count returned or abort? */ 12754 if (actual < count) { 12755 mptsas_log(mpt, CE_NOTE, "Requested: %d, Received: %d\n", 12756 count, actual); 12757 } 12758 12759 mpt->m_intr_cnt = actual; 12760 12761 /* 12762 * Get priority for first msi, assume remaining are all the same 12763 */ 12764 if ((ret = ddi_intr_get_pri(mpt->m_htable[0], 12765 &mpt->m_intr_pri)) != DDI_SUCCESS) { 12766 mptsas_log(mpt, CE_WARN, "ddi_intr_get_pri() failed %d\n", ret); 12767 12768 /* Free already allocated intr */ 12769 for (i = 0; i < actual; i++) { 12770 (void) ddi_intr_free(mpt->m_htable[i]); 12771 } 12772 12773 kmem_free(mpt->m_htable, mpt->m_intr_size); 12774 return (DDI_FAILURE); 12775 } 12776 12777 /* Test for high level mutex */ 12778 if (mpt->m_intr_pri >= ddi_intr_get_hilevel_pri()) { 12779 mptsas_log(mpt, CE_WARN, "mptsas_add_intrs: " 12780 "Hi level interrupt not supported\n"); 12781 12782 /* Free already allocated intr */ 12783 for (i = 0; i < actual; i++) { 12784 (void) ddi_intr_free(mpt->m_htable[i]); 12785 } 12786 12787 kmem_free(mpt->m_htable, mpt->m_intr_size); 12788 return (DDI_FAILURE); 12789 } 12790 12791 /* Call ddi_intr_add_handler() */ 12792 for (i = 0; i < actual; i++) { 12793 if ((ret = ddi_intr_add_handler(mpt->m_htable[i], mptsas_intr, 12794 (caddr_t)mpt, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) { 12795 mptsas_log(mpt, CE_WARN, "ddi_intr_add_handler() " 12796 "failed %d\n", ret); 12797 12798 /* Free already allocated intr */ 12799 for (i = 0; i < actual; i++) { 12800 (void) ddi_intr_free(mpt->m_htable[i]); 12801 } 12802 12803 kmem_free(mpt->m_htable, mpt->m_intr_size); 12804 return (DDI_FAILURE); 12805 } 12806 } 12807 12808 if ((ret = ddi_intr_get_cap(mpt->m_htable[0], &mpt->m_intr_cap)) 12809 != DDI_SUCCESS) { 12810 mptsas_log(mpt, CE_WARN, "ddi_intr_get_cap() failed %d\n", ret); 12811 12812 /* Free already allocated intr */ 12813 for (i = 0; i < actual; i++) { 12814 (void) ddi_intr_free(mpt->m_htable[i]); 12815 } 12816 12817 kmem_free(mpt->m_htable, mpt->m_intr_size); 12818 return (DDI_FAILURE); 12819 } 12820 12821 /* 12822 * Enable interrupts 12823 */ 12824 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) { 12825 /* Call ddi_intr_block_enable() for MSI interrupts */ 12826 (void) ddi_intr_block_enable(mpt->m_htable, mpt->m_intr_cnt); 12827 } else { 12828 /* Call ddi_intr_enable for MSI or FIXED interrupts */ 12829 for (i = 0; i < mpt->m_intr_cnt; i++) { 12830 (void) ddi_intr_enable(mpt->m_htable[i]); 12831 } 12832 } 12833 return (DDI_SUCCESS); 12834 } 12835 12836 /* 12837 * mptsas_rem_intrs: 12838 * 12839 * Unregister FIXED or MSI interrupts 12840 */ 12841 static void 12842 mptsas_rem_intrs(mptsas_t *mpt) 12843 { 12844 int i; 12845 12846 NDBG6(("mptsas_rem_intrs")); 12847 12848 /* Disable all interrupts */ 12849 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) { 12850 /* Call ddi_intr_block_disable() */ 12851 (void) ddi_intr_block_disable(mpt->m_htable, mpt->m_intr_cnt); 12852 } else { 12853 for (i = 0; i < mpt->m_intr_cnt; i++) { 12854 (void) ddi_intr_disable(mpt->m_htable[i]); 12855 } 12856 } 12857 12858 /* Call ddi_intr_remove_handler() */ 12859 for (i = 0; i < mpt->m_intr_cnt; i++) { 12860 (void) ddi_intr_remove_handler(mpt->m_htable[i]); 12861 (void) ddi_intr_free(mpt->m_htable[i]); 12862 } 12863 12864 kmem_free(mpt->m_htable, mpt->m_intr_size); 12865 } 12866 12867 /* 12868 * The IO fault service error handling callback function 12869 */ 12870 /*ARGSUSED*/ 12871 static int 12872 mptsas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data) 12873 { 12874 /* 12875 * as the driver can always deal with an error in any dma or 12876 * access handle, we can just return the fme_status value. 12877 */ 12878 pci_ereport_post(dip, err, NULL); 12879 return (err->fme_status); 12880 } 12881 12882 /* 12883 * mptsas_fm_init - initialize fma capabilities and register with IO 12884 * fault services. 12885 */ 12886 static void 12887 mptsas_fm_init(mptsas_t *mpt) 12888 { 12889 /* 12890 * Need to change iblock to priority for new MSI intr 12891 */ 12892 ddi_iblock_cookie_t fm_ibc; 12893 12894 /* Only register with IO Fault Services if we have some capability */ 12895 if (mpt->m_fm_capabilities) { 12896 /* Adjust access and dma attributes for FMA */ 12897 mpt->m_reg_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC; 12898 mpt->m_msg_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 12899 mpt->m_io_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 12900 12901 /* 12902 * Register capabilities with IO Fault Services. 12903 * mpt->m_fm_capabilities will be updated to indicate 12904 * capabilities actually supported (not requested.) 12905 */ 12906 ddi_fm_init(mpt->m_dip, &mpt->m_fm_capabilities, &fm_ibc); 12907 12908 /* 12909 * Initialize pci ereport capabilities if ereport 12910 * capable (should always be.) 12911 */ 12912 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) || 12913 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 12914 pci_ereport_setup(mpt->m_dip); 12915 } 12916 12917 /* 12918 * Register error callback if error callback capable. 12919 */ 12920 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 12921 ddi_fm_handler_register(mpt->m_dip, 12922 mptsas_fm_error_cb, (void *) mpt); 12923 } 12924 } 12925 } 12926 12927 /* 12928 * mptsas_fm_fini - Releases fma capabilities and un-registers with IO 12929 * fault services. 12930 * 12931 */ 12932 static void 12933 mptsas_fm_fini(mptsas_t *mpt) 12934 { 12935 /* Only unregister FMA capabilities if registered */ 12936 if (mpt->m_fm_capabilities) { 12937 12938 /* 12939 * Un-register error callback if error callback capable. 12940 */ 12941 12942 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 12943 ddi_fm_handler_unregister(mpt->m_dip); 12944 } 12945 12946 /* 12947 * Release any resources allocated by pci_ereport_setup() 12948 */ 12949 12950 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) || 12951 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 12952 pci_ereport_teardown(mpt->m_dip); 12953 } 12954 12955 /* Unregister from IO Fault Services */ 12956 ddi_fm_fini(mpt->m_dip); 12957 12958 /* Adjust access and dma attributes for FMA */ 12959 mpt->m_reg_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC; 12960 mpt->m_msg_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 12961 mpt->m_io_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 12962 12963 } 12964 } 12965 12966 int 12967 mptsas_check_acc_handle(ddi_acc_handle_t handle) 12968 { 12969 ddi_fm_error_t de; 12970 12971 if (handle == NULL) 12972 return (DDI_FAILURE); 12973 ddi_fm_acc_err_get(handle, &de, DDI_FME_VER0); 12974 return (de.fme_status); 12975 } 12976 12977 int 12978 mptsas_check_dma_handle(ddi_dma_handle_t handle) 12979 { 12980 ddi_fm_error_t de; 12981 12982 if (handle == NULL) 12983 return (DDI_FAILURE); 12984 ddi_fm_dma_err_get(handle, &de, DDI_FME_VER0); 12985 return (de.fme_status); 12986 } 12987 12988 void 12989 mptsas_fm_ereport(mptsas_t *mpt, char *detail) 12990 { 12991 uint64_t ena; 12992 char buf[FM_MAX_CLASS]; 12993 12994 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail); 12995 ena = fm_ena_generate(0, FM_ENA_FMT1); 12996 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities)) { 12997 ddi_fm_ereport_post(mpt->m_dip, buf, ena, DDI_NOSLEEP, 12998 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL); 12999 } 13000 } 13001 13002 static int 13003 mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address, 13004 uint16_t *dev_handle, mptsas_target_t **pptgt) 13005 { 13006 int rval; 13007 uint32_t dev_info; 13008 uint64_t sas_wwn; 13009 mptsas_phymask_t phymask; 13010 uint8_t physport, phynum, config, disk; 13011 mptsas_slots_t *slots = mpt->m_active; 13012 uint64_t devicename; 13013 uint16_t pdev_hdl; 13014 mptsas_target_t *tmp_tgt = NULL; 13015 uint16_t bay_num, enclosure; 13016 13017 ASSERT(*pptgt == NULL); 13018 13019 rval = mptsas_get_sas_device_page0(mpt, page_address, dev_handle, 13020 &sas_wwn, &dev_info, &physport, &phynum, &pdev_hdl, 13021 &bay_num, &enclosure); 13022 if (rval != DDI_SUCCESS) { 13023 rval = DEV_INFO_FAIL_PAGE0; 13024 return (rval); 13025 } 13026 13027 if ((dev_info & (MPI2_SAS_DEVICE_INFO_SSP_TARGET | 13028 MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 13029 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) == NULL) { 13030 rval = DEV_INFO_WRONG_DEVICE_TYPE; 13031 return (rval); 13032 } 13033 13034 /* 13035 * Check if the dev handle is for a Phys Disk. If so, set return value 13036 * and exit. Don't add Phys Disks to hash. 13037 */ 13038 for (config = 0; config < slots->m_num_raid_configs; config++) { 13039 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) { 13040 if (*dev_handle == slots->m_raidconfig[config]. 13041 m_physdisk_devhdl[disk]) { 13042 rval = DEV_INFO_PHYS_DISK; 13043 return (rval); 13044 } 13045 } 13046 } 13047 13048 /* 13049 * Get SATA Device Name from SAS device page0 for 13050 * sata device, if device name doesn't exist, set m_sas_wwn to 13051 * 0 for direct attached SATA. For the device behind the expander 13052 * we still can use STP address assigned by expander. 13053 */ 13054 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 13055 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 13056 mutex_exit(&mpt->m_mutex); 13057 /* alloc a tmp_tgt to send the cmd */ 13058 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), 13059 KM_SLEEP); 13060 tmp_tgt->m_devhdl = *dev_handle; 13061 tmp_tgt->m_deviceinfo = dev_info; 13062 tmp_tgt->m_qfull_retries = QFULL_RETRIES; 13063 tmp_tgt->m_qfull_retry_interval = 13064 drv_usectohz(QFULL_RETRY_INTERVAL * 1000); 13065 tmp_tgt->m_t_throttle = MAX_THROTTLE; 13066 devicename = mptsas_get_sata_guid(mpt, tmp_tgt, 0); 13067 kmem_free(tmp_tgt, sizeof (struct mptsas_target)); 13068 mutex_enter(&mpt->m_mutex); 13069 if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) { 13070 sas_wwn = devicename; 13071 } else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) { 13072 sas_wwn = 0; 13073 } 13074 } 13075 13076 phymask = mptsas_physport_to_phymask(mpt, physport); 13077 *pptgt = mptsas_tgt_alloc(&slots->m_tgttbl, *dev_handle, sas_wwn, 13078 dev_info, phymask, phynum, mpt); 13079 if (*pptgt == NULL) { 13080 mptsas_log(mpt, CE_WARN, "Failed to allocated target" 13081 "structure!"); 13082 rval = DEV_INFO_FAIL_ALLOC; 13083 return (rval); 13084 } 13085 (*pptgt)->m_enclosure = enclosure; 13086 (*pptgt)->m_slot_num = bay_num; 13087 return (DEV_INFO_SUCCESS); 13088 } 13089 13090 uint64_t 13091 mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun) 13092 { 13093 uint64_t sata_guid = 0, *pwwn = NULL; 13094 int target = ptgt->m_devhdl; 13095 uchar_t *inq83 = NULL; 13096 int inq83_len = 0xFF; 13097 uchar_t *dblk = NULL; 13098 int inq83_retry = 3; 13099 int rval = DDI_FAILURE; 13100 13101 inq83 = kmem_zalloc(inq83_len, KM_SLEEP); 13102 13103 inq83_retry: 13104 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83, 13105 inq83_len, NULL, 1); 13106 if (rval != DDI_SUCCESS) { 13107 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 13108 "0x83 for target:%x, lun:%x failed!", target, lun); 13109 goto out; 13110 } 13111 /* According to SAT2, the first descriptor is logic unit name */ 13112 dblk = &inq83[4]; 13113 if ((dblk[1] & 0x30) != 0) { 13114 mptsas_log(mpt, CE_WARN, "!Descriptor is not lun associated."); 13115 goto out; 13116 } 13117 pwwn = (uint64_t *)(void *)(&dblk[4]); 13118 if ((dblk[4] & 0xf0) == 0x50) { 13119 sata_guid = BE_64(*pwwn); 13120 goto out; 13121 } else if (dblk[4] == 'A') { 13122 NDBG20(("SATA drive has no NAA format GUID.")); 13123 goto out; 13124 } else { 13125 /* The data is not ready, wait and retry */ 13126 inq83_retry--; 13127 if (inq83_retry <= 0) { 13128 goto out; 13129 } 13130 NDBG20(("The GUID is not ready, retry...")); 13131 delay(1 * drv_usectohz(1000000)); 13132 goto inq83_retry; 13133 } 13134 out: 13135 kmem_free(inq83, inq83_len); 13136 return (sata_guid); 13137 } 13138 13139 static int 13140 mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, uchar_t page, 13141 unsigned char *buf, int len, int *reallen, uchar_t evpd) 13142 { 13143 uchar_t cdb[CDB_GROUP0]; 13144 struct scsi_address ap; 13145 struct buf *data_bp = NULL; 13146 int resid = 0; 13147 int ret = DDI_FAILURE; 13148 13149 ASSERT(len <= 0xffff); 13150 13151 ap.a_target = MPTSAS_INVALID_DEVHDL; 13152 ap.a_lun = (uchar_t)(lun); 13153 ap.a_hba_tran = mpt->m_tran; 13154 13155 data_bp = scsi_alloc_consistent_buf(&ap, 13156 (struct buf *)NULL, len, B_READ, NULL_FUNC, NULL); 13157 if (data_bp == NULL) { 13158 return (ret); 13159 } 13160 bzero(cdb, CDB_GROUP0); 13161 cdb[0] = SCMD_INQUIRY; 13162 cdb[1] = evpd; 13163 cdb[2] = page; 13164 cdb[3] = (len & 0xff00) >> 8; 13165 cdb[4] = (len & 0x00ff); 13166 cdb[5] = 0; 13167 13168 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP0, data_bp, 13169 &resid); 13170 if (ret == DDI_SUCCESS) { 13171 if (reallen) { 13172 *reallen = len - resid; 13173 } 13174 bcopy((caddr_t)data_bp->b_un.b_addr, buf, len); 13175 } 13176 if (data_bp) { 13177 scsi_free_consistent_buf(data_bp); 13178 } 13179 return (ret); 13180 } 13181 13182 static int 13183 mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap, 13184 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp, 13185 int *resid) 13186 { 13187 struct scsi_pkt *pktp = NULL; 13188 scsi_hba_tran_t *tran_clone = NULL; 13189 mptsas_tgt_private_t *tgt_private = NULL; 13190 int ret = DDI_FAILURE; 13191 13192 /* 13193 * scsi_hba_tran_t->tran_tgt_private is used to pass the address 13194 * information to scsi_init_pkt, allocate a scsi_hba_tran structure 13195 * to simulate the cmds from sd 13196 */ 13197 tran_clone = kmem_alloc( 13198 sizeof (scsi_hba_tran_t), KM_SLEEP); 13199 if (tran_clone == NULL) { 13200 goto out; 13201 } 13202 bcopy((caddr_t)mpt->m_tran, 13203 (caddr_t)tran_clone, sizeof (scsi_hba_tran_t)); 13204 tgt_private = kmem_alloc( 13205 sizeof (mptsas_tgt_private_t), KM_SLEEP); 13206 if (tgt_private == NULL) { 13207 goto out; 13208 } 13209 tgt_private->t_lun = ap->a_lun; 13210 tgt_private->t_private = ptgt; 13211 tran_clone->tran_tgt_private = tgt_private; 13212 ap->a_hba_tran = tran_clone; 13213 13214 pktp = scsi_init_pkt(ap, (struct scsi_pkt *)NULL, 13215 data_bp, cdblen, sizeof (struct scsi_arq_status), 13216 0, PKT_CONSISTENT, NULL, NULL); 13217 if (pktp == NULL) { 13218 goto out; 13219 } 13220 bcopy(cdb, pktp->pkt_cdbp, cdblen); 13221 pktp->pkt_flags = FLAG_NOPARITY; 13222 if (scsi_poll(pktp) < 0) { 13223 goto out; 13224 } 13225 if (((struct scsi_status *)pktp->pkt_scbp)->sts_chk) { 13226 goto out; 13227 } 13228 if (resid != NULL) { 13229 *resid = pktp->pkt_resid; 13230 } 13231 13232 ret = DDI_SUCCESS; 13233 out: 13234 if (pktp) { 13235 scsi_destroy_pkt(pktp); 13236 } 13237 if (tran_clone) { 13238 kmem_free(tran_clone, sizeof (scsi_hba_tran_t)); 13239 } 13240 if (tgt_private) { 13241 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t)); 13242 } 13243 return (ret); 13244 } 13245 static int 13246 mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, int *lun) 13247 { 13248 char *cp = NULL; 13249 char *ptr = NULL; 13250 size_t s = 0; 13251 char *wwid_str = NULL; 13252 char *lun_str = NULL; 13253 long lunnum; 13254 long phyid = -1; 13255 int rc = DDI_FAILURE; 13256 13257 ptr = name; 13258 ASSERT(ptr[0] == 'w' || ptr[0] == 'p'); 13259 ptr++; 13260 if ((cp = strchr(ptr, ',')) == NULL) { 13261 return (DDI_FAILURE); 13262 } 13263 13264 wwid_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13265 s = (uintptr_t)cp - (uintptr_t)ptr; 13266 13267 bcopy(ptr, wwid_str, s); 13268 wwid_str[s] = '\0'; 13269 13270 ptr = ++cp; 13271 13272 if ((cp = strchr(ptr, '\0')) == NULL) { 13273 goto out; 13274 } 13275 lun_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13276 s = (uintptr_t)cp - (uintptr_t)ptr; 13277 13278 bcopy(ptr, lun_str, s); 13279 lun_str[s] = '\0'; 13280 13281 if (name[0] == 'p') { 13282 rc = ddi_strtol(wwid_str, NULL, 0x10, &phyid); 13283 } else { 13284 rc = scsi_wwnstr_to_wwn(wwid_str, wwid); 13285 } 13286 if (rc != DDI_SUCCESS) 13287 goto out; 13288 13289 if (phyid != -1) { 13290 ASSERT(phyid < MPTSAS_MAX_PHYS); 13291 *phy = (uint8_t)phyid; 13292 } 13293 rc = ddi_strtol(lun_str, NULL, 0x10, &lunnum); 13294 if (rc != 0) 13295 goto out; 13296 13297 *lun = (int)lunnum; 13298 rc = DDI_SUCCESS; 13299 out: 13300 if (wwid_str) 13301 kmem_free(wwid_str, SCSI_MAXNAMELEN); 13302 if (lun_str) 13303 kmem_free(lun_str, SCSI_MAXNAMELEN); 13304 13305 return (rc); 13306 } 13307 13308 /* 13309 * mptsas_parse_smp_name() is to parse sas wwn string 13310 * which format is "wWWN" 13311 */ 13312 static int 13313 mptsas_parse_smp_name(char *name, uint64_t *wwn) 13314 { 13315 char *ptr = name; 13316 13317 if (*ptr != 'w') { 13318 return (DDI_FAILURE); 13319 } 13320 13321 ptr++; 13322 if (scsi_wwnstr_to_wwn(ptr, wwn)) { 13323 return (DDI_FAILURE); 13324 } 13325 return (DDI_SUCCESS); 13326 } 13327 13328 static int 13329 mptsas_bus_config(dev_info_t *pdip, uint_t flag, 13330 ddi_bus_config_op_t op, void *arg, dev_info_t **childp) 13331 { 13332 int ret = NDI_FAILURE; 13333 int circ = 0; 13334 int circ1 = 0; 13335 mptsas_t *mpt; 13336 char *ptr = NULL; 13337 char *devnm = NULL; 13338 uint64_t wwid = 0; 13339 uint8_t phy = 0xFF; 13340 int lun = 0; 13341 uint_t mflags = flag; 13342 int bconfig = TRUE; 13343 13344 if (scsi_hba_iport_unit_address(pdip) == 0) { 13345 return (DDI_FAILURE); 13346 } 13347 13348 mpt = DIP2MPT(pdip); 13349 if (!mpt) { 13350 return (DDI_FAILURE); 13351 } 13352 /* 13353 * Hold the nexus across the bus_config 13354 */ 13355 ndi_devi_enter(scsi_vhci_dip, &circ); 13356 ndi_devi_enter(pdip, &circ1); 13357 switch (op) { 13358 case BUS_CONFIG_ONE: 13359 /* parse wwid/target name out of name given */ 13360 if ((ptr = strchr((char *)arg, '@')) == NULL) { 13361 ret = NDI_FAILURE; 13362 break; 13363 } 13364 ptr++; 13365 if (strncmp((char *)arg, "smp", 3) == 0) { 13366 /* 13367 * This is a SMP target device 13368 */ 13369 ret = mptsas_parse_smp_name(ptr, &wwid); 13370 if (ret != DDI_SUCCESS) { 13371 ret = NDI_FAILURE; 13372 break; 13373 } 13374 ret = mptsas_config_smp(pdip, wwid, childp); 13375 } else if ((ptr[0] == 'w') || (ptr[0] == 'p')) { 13376 /* 13377 * OBP could pass down a non-canonical form 13378 * bootpath without LUN part when LUN is 0. 13379 * So driver need adjust the string. 13380 */ 13381 if (strchr(ptr, ',') == NULL) { 13382 devnm = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 13383 (void) sprintf(devnm, "%s,0", (char *)arg); 13384 ptr = strchr(devnm, '@'); 13385 ptr++; 13386 } 13387 13388 /* 13389 * The device path is wWWID format and the device 13390 * is not SMP target device. 13391 */ 13392 ret = mptsas_parse_address(ptr, &wwid, &phy, &lun); 13393 if (ret != DDI_SUCCESS) { 13394 ret = NDI_FAILURE; 13395 break; 13396 } 13397 *childp = NULL; 13398 if (ptr[0] == 'w') { 13399 ret = mptsas_config_one_addr(pdip, wwid, 13400 lun, childp); 13401 } else if (ptr[0] == 'p') { 13402 ret = mptsas_config_one_phy(pdip, phy, lun, 13403 childp); 13404 } 13405 13406 /* 13407 * If this is CD/DVD device in OBP path, the 13408 * ndi_busop_bus_config can be skipped as config one 13409 * operation is done above. 13410 */ 13411 if ((ret == NDI_SUCCESS) && (*childp != NULL) && 13412 (strcmp(ddi_node_name(*childp), "cdrom") == 0) && 13413 (strncmp((char *)arg, "disk", 4) == 0)) { 13414 bconfig = FALSE; 13415 ndi_hold_devi(*childp); 13416 } 13417 } else { 13418 ret = NDI_FAILURE; 13419 break; 13420 } 13421 13422 /* 13423 * DDI group instructed us to use this flag. 13424 */ 13425 mflags |= NDI_MDI_FALLBACK; 13426 break; 13427 case BUS_CONFIG_DRIVER: 13428 case BUS_CONFIG_ALL: 13429 mptsas_config_all(pdip); 13430 ret = NDI_SUCCESS; 13431 break; 13432 } 13433 13434 if ((ret == NDI_SUCCESS) && bconfig) { 13435 ret = ndi_busop_bus_config(pdip, mflags, op, 13436 (devnm == NULL) ? arg : devnm, childp, 0); 13437 } 13438 13439 ndi_devi_exit(pdip, circ1); 13440 ndi_devi_exit(scsi_vhci_dip, circ); 13441 if (devnm != NULL) 13442 kmem_free(devnm, SCSI_MAXNAMELEN); 13443 return (ret); 13444 } 13445 13446 static int 13447 mptsas_probe_lun(dev_info_t *pdip, int lun, dev_info_t **dip, 13448 mptsas_target_t *ptgt) 13449 { 13450 int rval = DDI_FAILURE; 13451 struct scsi_inquiry *sd_inq = NULL; 13452 mptsas_t *mpt = DIP2MPT(pdip); 13453 13454 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP); 13455 13456 rval = mptsas_inquiry(mpt, ptgt, lun, 0, (uchar_t *)sd_inq, 13457 SUN_INQSIZE, 0, (uchar_t)0); 13458 13459 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) { 13460 rval = mptsas_create_lun(pdip, sd_inq, dip, ptgt, lun); 13461 } else { 13462 rval = DDI_FAILURE; 13463 } 13464 13465 kmem_free(sd_inq, SUN_INQSIZE); 13466 return (rval); 13467 } 13468 13469 static int 13470 mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun, 13471 dev_info_t **lundip) 13472 { 13473 int rval; 13474 mptsas_t *mpt = DIP2MPT(pdip); 13475 int phymask; 13476 mptsas_target_t *ptgt = NULL; 13477 13478 /* 13479 * Get the physical port associated to the iport 13480 */ 13481 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 13482 "phymask", 0); 13483 13484 ptgt = mptsas_wwid_to_ptgt(mpt, phymask, sasaddr); 13485 if (ptgt == NULL) { 13486 /* 13487 * didn't match any device by searching 13488 */ 13489 return (DDI_FAILURE); 13490 } 13491 /* 13492 * If the LUN already exists and the status is online, 13493 * we just return the pointer to dev_info_t directly. 13494 * For the mdi_pathinfo node, we'll handle it in 13495 * mptsas_create_virt_lun() 13496 * TODO should be also in mptsas_handle_dr 13497 */ 13498 13499 *lundip = mptsas_find_child_addr(pdip, sasaddr, lun); 13500 if (*lundip != NULL) { 13501 /* 13502 * TODO Another senario is, we hotplug the same disk 13503 * on the same slot, the devhdl changed, is this 13504 * possible? 13505 * tgt_private->t_private != ptgt 13506 */ 13507 if (sasaddr != ptgt->m_sas_wwn) { 13508 /* 13509 * The device has changed although the devhdl is the 13510 * same (Enclosure mapping mode, change drive on the 13511 * same slot) 13512 */ 13513 return (DDI_FAILURE); 13514 } 13515 return (DDI_SUCCESS); 13516 } 13517 13518 if (phymask == 0) { 13519 /* 13520 * Configure IR volume 13521 */ 13522 rval = mptsas_config_raid(pdip, ptgt->m_devhdl, lundip); 13523 return (rval); 13524 } 13525 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt); 13526 13527 return (rval); 13528 } 13529 13530 static int 13531 mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun, 13532 dev_info_t **lundip) 13533 { 13534 int rval; 13535 mptsas_t *mpt = DIP2MPT(pdip); 13536 int phymask; 13537 mptsas_target_t *ptgt = NULL; 13538 13539 /* 13540 * Get the physical port associated to the iport 13541 */ 13542 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 13543 "phymask", 0); 13544 13545 ptgt = mptsas_phy_to_tgt(mpt, phymask, phy); 13546 if (ptgt == NULL) { 13547 /* 13548 * didn't match any device by searching 13549 */ 13550 return (DDI_FAILURE); 13551 } 13552 13553 /* 13554 * If the LUN already exists and the status is online, 13555 * we just return the pointer to dev_info_t directly. 13556 * For the mdi_pathinfo node, we'll handle it in 13557 * mptsas_create_virt_lun(). 13558 */ 13559 13560 *lundip = mptsas_find_child_phy(pdip, phy); 13561 if (*lundip != NULL) { 13562 return (DDI_SUCCESS); 13563 } 13564 13565 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt); 13566 13567 return (rval); 13568 } 13569 13570 static int 13571 mptsas_retrieve_lundata(int lun_cnt, uint8_t *buf, uint16_t *lun_num, 13572 uint8_t *lun_addr_type) 13573 { 13574 uint32_t lun_idx = 0; 13575 13576 ASSERT(lun_num != NULL); 13577 ASSERT(lun_addr_type != NULL); 13578 13579 lun_idx = (lun_cnt + 1) * MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE; 13580 /* determine report luns addressing type */ 13581 switch (buf[lun_idx] & MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) { 13582 /* 13583 * Vendors in the field have been found to be concatenating 13584 * bus/target/lun to equal the complete lun value instead 13585 * of switching to flat space addressing 13586 */ 13587 /* 00b - peripheral device addressing method */ 13588 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_PERIPHERAL: 13589 /* FALLTHRU */ 13590 /* 10b - logical unit addressing method */ 13591 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT: 13592 /* FALLTHRU */ 13593 /* 01b - flat space addressing method */ 13594 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE: 13595 /* byte0 bit0-5=msb lun byte1 bit0-7=lsb lun */ 13596 *lun_addr_type = (buf[lun_idx] & 13597 MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) >> 6; 13598 *lun_num = (buf[lun_idx] & 0x3F) << 8; 13599 *lun_num |= buf[lun_idx + 1]; 13600 return (DDI_SUCCESS); 13601 default: 13602 return (DDI_FAILURE); 13603 } 13604 } 13605 13606 static int 13607 mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt) 13608 { 13609 struct buf *repluns_bp = NULL; 13610 struct scsi_address ap; 13611 uchar_t cdb[CDB_GROUP5]; 13612 int ret = DDI_FAILURE; 13613 int retry = 0; 13614 int lun_list_len = 0; 13615 uint16_t lun_num = 0; 13616 uint8_t lun_addr_type = 0; 13617 uint32_t lun_cnt = 0; 13618 uint32_t lun_total = 0; 13619 dev_info_t *cdip = NULL; 13620 uint16_t *saved_repluns = NULL; 13621 char *buffer = NULL; 13622 int buf_len = 128; 13623 mptsas_t *mpt = DIP2MPT(pdip); 13624 uint64_t sas_wwn = 0; 13625 uint8_t phy = 0xFF; 13626 uint32_t dev_info = 0; 13627 13628 mutex_enter(&mpt->m_mutex); 13629 sas_wwn = ptgt->m_sas_wwn; 13630 phy = ptgt->m_phynum; 13631 dev_info = ptgt->m_deviceinfo; 13632 mutex_exit(&mpt->m_mutex); 13633 13634 if (sas_wwn == 0) { 13635 /* 13636 * It's a SATA without Device Name 13637 * So don't try multi-LUNs 13638 */ 13639 if (mptsas_find_child_phy(pdip, phy)) { 13640 return (DDI_SUCCESS); 13641 } else { 13642 /* 13643 * need configure and create node 13644 */ 13645 return (DDI_FAILURE); 13646 } 13647 } 13648 13649 /* 13650 * WWN (SAS address or Device Name exist) 13651 */ 13652 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 13653 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 13654 /* 13655 * SATA device with Device Name 13656 * So don't try multi-LUNs 13657 */ 13658 if (mptsas_find_child_addr(pdip, sas_wwn, 0)) { 13659 return (DDI_SUCCESS); 13660 } else { 13661 return (DDI_FAILURE); 13662 } 13663 } 13664 13665 do { 13666 ap.a_target = MPTSAS_INVALID_DEVHDL; 13667 ap.a_lun = 0; 13668 ap.a_hba_tran = mpt->m_tran; 13669 repluns_bp = scsi_alloc_consistent_buf(&ap, 13670 (struct buf *)NULL, buf_len, B_READ, NULL_FUNC, NULL); 13671 if (repluns_bp == NULL) { 13672 retry++; 13673 continue; 13674 } 13675 bzero(cdb, CDB_GROUP5); 13676 cdb[0] = SCMD_REPORT_LUNS; 13677 cdb[6] = (buf_len & 0xff000000) >> 24; 13678 cdb[7] = (buf_len & 0x00ff0000) >> 16; 13679 cdb[8] = (buf_len & 0x0000ff00) >> 8; 13680 cdb[9] = (buf_len & 0x000000ff); 13681 13682 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP5, 13683 repluns_bp, NULL); 13684 if (ret != DDI_SUCCESS) { 13685 scsi_free_consistent_buf(repluns_bp); 13686 retry++; 13687 continue; 13688 } 13689 lun_list_len = BE_32(*(int *)((void *)( 13690 repluns_bp->b_un.b_addr))); 13691 if (buf_len >= lun_list_len + 8) { 13692 ret = DDI_SUCCESS; 13693 break; 13694 } 13695 scsi_free_consistent_buf(repluns_bp); 13696 buf_len = lun_list_len + 8; 13697 13698 } while (retry < 3); 13699 13700 if (ret != DDI_SUCCESS) 13701 return (ret); 13702 buffer = (char *)repluns_bp->b_un.b_addr; 13703 /* 13704 * find out the number of luns returned by the SCSI ReportLun call 13705 * and allocate buffer space 13706 */ 13707 lun_total = lun_list_len / MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE; 13708 saved_repluns = kmem_zalloc(sizeof (uint16_t) * lun_total, KM_SLEEP); 13709 if (saved_repluns == NULL) { 13710 scsi_free_consistent_buf(repluns_bp); 13711 return (DDI_FAILURE); 13712 } 13713 for (lun_cnt = 0; lun_cnt < lun_total; lun_cnt++) { 13714 if (mptsas_retrieve_lundata(lun_cnt, (uint8_t *)(buffer), 13715 &lun_num, &lun_addr_type) != DDI_SUCCESS) { 13716 continue; 13717 } 13718 saved_repluns[lun_cnt] = lun_num; 13719 if (cdip = mptsas_find_child_addr(pdip, sas_wwn, lun_num)) 13720 ret = DDI_SUCCESS; 13721 else 13722 ret = mptsas_probe_lun(pdip, lun_num, &cdip, 13723 ptgt); 13724 if ((ret == DDI_SUCCESS) && (cdip != NULL)) { 13725 (void) ndi_prop_remove(DDI_DEV_T_NONE, cdip, 13726 MPTSAS_DEV_GONE); 13727 } 13728 } 13729 mptsas_offline_missed_luns(pdip, saved_repluns, lun_total, ptgt); 13730 kmem_free(saved_repluns, sizeof (uint16_t) * lun_total); 13731 scsi_free_consistent_buf(repluns_bp); 13732 return (DDI_SUCCESS); 13733 } 13734 13735 static int 13736 mptsas_config_raid(dev_info_t *pdip, uint16_t target, dev_info_t **dip) 13737 { 13738 int rval = DDI_FAILURE; 13739 struct scsi_inquiry *sd_inq = NULL; 13740 mptsas_t *mpt = DIP2MPT(pdip); 13741 mptsas_target_t *ptgt = NULL; 13742 13743 mutex_enter(&mpt->m_mutex); 13744 ptgt = mptsas_search_by_devhdl(&mpt->m_active->m_tgttbl, target); 13745 mutex_exit(&mpt->m_mutex); 13746 if (ptgt == NULL) { 13747 mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x " 13748 "not found.", target); 13749 return (rval); 13750 } 13751 13752 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP); 13753 rval = mptsas_inquiry(mpt, ptgt, 0, 0, (uchar_t *)sd_inq, 13754 SUN_INQSIZE, 0, (uchar_t)0); 13755 13756 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) { 13757 rval = mptsas_create_phys_lun(pdip, sd_inq, NULL, dip, ptgt, 13758 0); 13759 } else { 13760 rval = DDI_FAILURE; 13761 } 13762 13763 kmem_free(sd_inq, SUN_INQSIZE); 13764 return (rval); 13765 } 13766 13767 /* 13768 * configure all RAID volumes for virtual iport 13769 */ 13770 static void 13771 mptsas_config_all_viport(dev_info_t *pdip) 13772 { 13773 mptsas_t *mpt = DIP2MPT(pdip); 13774 int config, vol; 13775 int target; 13776 dev_info_t *lundip = NULL; 13777 mptsas_slots_t *slots = mpt->m_active; 13778 13779 /* 13780 * Get latest RAID info and search for any Volume DevHandles. If any 13781 * are found, configure the volume. 13782 */ 13783 mutex_enter(&mpt->m_mutex); 13784 for (config = 0; config < slots->m_num_raid_configs; config++) { 13785 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) { 13786 if (slots->m_raidconfig[config].m_raidvol[vol].m_israid 13787 == 1) { 13788 target = slots->m_raidconfig[config]. 13789 m_raidvol[vol].m_raidhandle; 13790 mutex_exit(&mpt->m_mutex); 13791 (void) mptsas_config_raid(pdip, target, 13792 &lundip); 13793 mutex_enter(&mpt->m_mutex); 13794 } 13795 } 13796 } 13797 mutex_exit(&mpt->m_mutex); 13798 } 13799 13800 static void 13801 mptsas_offline_missed_luns(dev_info_t *pdip, uint16_t *repluns, 13802 int lun_cnt, mptsas_target_t *ptgt) 13803 { 13804 dev_info_t *child = NULL, *savechild = NULL; 13805 mdi_pathinfo_t *pip = NULL, *savepip = NULL; 13806 uint64_t sas_wwn, wwid; 13807 uint8_t phy; 13808 int lun; 13809 int i; 13810 int find; 13811 char *addr; 13812 char *nodename; 13813 mptsas_t *mpt = DIP2MPT(pdip); 13814 13815 mutex_enter(&mpt->m_mutex); 13816 wwid = ptgt->m_sas_wwn; 13817 mutex_exit(&mpt->m_mutex); 13818 13819 child = ddi_get_child(pdip); 13820 while (child) { 13821 find = 0; 13822 savechild = child; 13823 child = ddi_get_next_sibling(child); 13824 13825 nodename = ddi_node_name(savechild); 13826 if (strcmp(nodename, "smp") == 0) { 13827 continue; 13828 } 13829 13830 addr = ddi_get_name_addr(savechild); 13831 if (addr == NULL) { 13832 continue; 13833 } 13834 13835 if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) != 13836 DDI_SUCCESS) { 13837 continue; 13838 } 13839 13840 if (wwid == sas_wwn) { 13841 for (i = 0; i < lun_cnt; i++) { 13842 if (repluns[i] == lun) { 13843 find = 1; 13844 break; 13845 } 13846 } 13847 } else { 13848 continue; 13849 } 13850 if (find == 0) { 13851 /* 13852 * The lun has not been there already 13853 */ 13854 (void) mptsas_offline_lun(pdip, savechild, NULL, 13855 NDI_DEVI_REMOVE); 13856 } 13857 } 13858 13859 pip = mdi_get_next_client_path(pdip, NULL); 13860 while (pip) { 13861 find = 0; 13862 savepip = pip; 13863 addr = MDI_PI(pip)->pi_addr; 13864 13865 pip = mdi_get_next_client_path(pdip, pip); 13866 13867 if (addr == NULL) { 13868 continue; 13869 } 13870 13871 if (mptsas_parse_address(addr, &sas_wwn, &phy, 13872 &lun) != DDI_SUCCESS) { 13873 continue; 13874 } 13875 13876 if (sas_wwn == wwid) { 13877 for (i = 0; i < lun_cnt; i++) { 13878 if (repluns[i] == lun) { 13879 find = 1; 13880 break; 13881 } 13882 } 13883 } else { 13884 continue; 13885 } 13886 13887 if (find == 0) { 13888 /* 13889 * The lun has not been there already 13890 */ 13891 (void) mptsas_offline_lun(pdip, NULL, savepip, 13892 NDI_DEVI_REMOVE); 13893 } 13894 } 13895 } 13896 13897 void 13898 mptsas_update_hashtab(struct mptsas *mpt) 13899 { 13900 uint32_t page_address; 13901 int rval = 0; 13902 uint16_t dev_handle; 13903 mptsas_target_t *ptgt = NULL; 13904 mptsas_smp_t smp_node; 13905 13906 /* 13907 * Get latest RAID info. 13908 */ 13909 (void) mptsas_get_raid_info(mpt); 13910 13911 dev_handle = mpt->m_smp_devhdl; 13912 for (; mpt->m_done_traverse_smp == 0; ) { 13913 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL & 13914 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)dev_handle; 13915 if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node) 13916 != DDI_SUCCESS) { 13917 break; 13918 } 13919 mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl; 13920 (void) mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node); 13921 } 13922 13923 /* 13924 * Config target devices 13925 */ 13926 dev_handle = mpt->m_dev_handle; 13927 13928 /* 13929 * Do loop to get sas device page 0 by GetNextHandle till the 13930 * the last handle. If the sas device is a SATA/SSP target, 13931 * we try to config it. 13932 */ 13933 for (; mpt->m_done_traverse_dev == 0; ) { 13934 ptgt = NULL; 13935 page_address = 13936 (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 13937 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 13938 (uint32_t)dev_handle; 13939 rval = mptsas_get_target_device_info(mpt, page_address, 13940 &dev_handle, &ptgt); 13941 if ((rval == DEV_INFO_FAIL_PAGE0) || 13942 (rval == DEV_INFO_FAIL_ALLOC)) { 13943 break; 13944 } 13945 13946 mpt->m_dev_handle = dev_handle; 13947 } 13948 13949 } 13950 13951 void 13952 mptsas_invalid_hashtab(mptsas_hash_table_t *hashtab) 13953 { 13954 mptsas_hash_data_t *data; 13955 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST); 13956 while (data != NULL) { 13957 data->devhdl = MPTSAS_INVALID_DEVHDL; 13958 data->device_info = 0; 13959 /* 13960 * For tgttbl, clear dr_flag. 13961 */ 13962 data->dr_flag = MPTSAS_DR_INACTIVE; 13963 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT); 13964 } 13965 } 13966 13967 void 13968 mptsas_update_driver_data(struct mptsas *mpt) 13969 { 13970 /* 13971 * TODO after hard reset, update the driver data structures 13972 * 1. update port/phymask mapping table mpt->m_phy_info 13973 * 2. invalid all the entries in hash table 13974 * m_devhdl = 0xffff and m_deviceinfo = 0 13975 * 3. call sas_device_page/expander_page to update hash table 13976 */ 13977 mptsas_update_phymask(mpt); 13978 /* 13979 * Invalid the existing entries 13980 */ 13981 mptsas_invalid_hashtab(&mpt->m_active->m_tgttbl); 13982 mptsas_invalid_hashtab(&mpt->m_active->m_smptbl); 13983 mpt->m_done_traverse_dev = 0; 13984 mpt->m_done_traverse_smp = 0; 13985 mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL; 13986 mptsas_update_hashtab(mpt); 13987 } 13988 13989 static void 13990 mptsas_config_all(dev_info_t *pdip) 13991 { 13992 dev_info_t *smpdip = NULL; 13993 mptsas_t *mpt = DIP2MPT(pdip); 13994 int phymask = 0; 13995 mptsas_phymask_t phy_mask; 13996 mptsas_target_t *ptgt = NULL; 13997 mptsas_smp_t *psmp; 13998 13999 /* 14000 * Get the phymask associated to the iport 14001 */ 14002 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 14003 "phymask", 0); 14004 14005 /* 14006 * Enumerate RAID volumes here (phymask == 0). 14007 */ 14008 if (phymask == 0) { 14009 mptsas_config_all_viport(pdip); 14010 return; 14011 } 14012 14013 mutex_enter(&mpt->m_mutex); 14014 14015 if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp) { 14016 mptsas_update_hashtab(mpt); 14017 } 14018 14019 psmp = (mptsas_smp_t *)mptsas_hash_traverse(&mpt->m_active->m_smptbl, 14020 MPTSAS_HASH_FIRST); 14021 while (psmp != NULL) { 14022 phy_mask = psmp->m_phymask; 14023 if (phy_mask == phymask) { 14024 smpdip = NULL; 14025 mutex_exit(&mpt->m_mutex); 14026 (void) mptsas_online_smp(pdip, psmp, &smpdip); 14027 mutex_enter(&mpt->m_mutex); 14028 } 14029 psmp = (mptsas_smp_t *)mptsas_hash_traverse( 14030 &mpt->m_active->m_smptbl, MPTSAS_HASH_NEXT); 14031 } 14032 14033 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 14034 MPTSAS_HASH_FIRST); 14035 while (ptgt != NULL) { 14036 phy_mask = ptgt->m_phymask; 14037 if (phy_mask == phymask) { 14038 mutex_exit(&mpt->m_mutex); 14039 (void) mptsas_config_target(pdip, ptgt); 14040 mutex_enter(&mpt->m_mutex); 14041 } 14042 14043 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 14044 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 14045 } 14046 mutex_exit(&mpt->m_mutex); 14047 } 14048 14049 static int 14050 mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt) 14051 { 14052 int rval = DDI_FAILURE; 14053 dev_info_t *tdip; 14054 14055 rval = mptsas_config_luns(pdip, ptgt); 14056 if (rval != DDI_SUCCESS) { 14057 /* 14058 * The return value means the SCMD_REPORT_LUNS 14059 * did not execute successfully. The target maybe 14060 * doesn't support such command. 14061 */ 14062 rval = mptsas_probe_lun(pdip, 0, &tdip, ptgt); 14063 } 14064 return (rval); 14065 } 14066 14067 /* 14068 * Return fail if not all the childs/paths are freed. 14069 * if there is any path under the HBA, the return value will be always fail 14070 * because we didn't call mdi_pi_free for path 14071 */ 14072 static int 14073 mptsas_offline_target(dev_info_t *pdip, char *name) 14074 { 14075 dev_info_t *child = NULL, *prechild = NULL; 14076 mdi_pathinfo_t *pip = NULL, *savepip = NULL; 14077 int tmp_rval, rval = DDI_SUCCESS; 14078 char *addr, *cp; 14079 size_t s; 14080 mptsas_t *mpt = DIP2MPT(pdip); 14081 14082 child = ddi_get_child(pdip); 14083 while (child) { 14084 addr = ddi_get_name_addr(child); 14085 prechild = child; 14086 child = ddi_get_next_sibling(child); 14087 14088 if (addr == NULL) { 14089 continue; 14090 } 14091 if ((cp = strchr(addr, ',')) == NULL) { 14092 continue; 14093 } 14094 14095 s = (uintptr_t)cp - (uintptr_t)addr; 14096 14097 if (strncmp(addr, name, s) != 0) { 14098 continue; 14099 } 14100 14101 tmp_rval = mptsas_offline_lun(pdip, prechild, NULL, 14102 NDI_DEVI_REMOVE); 14103 if (tmp_rval != DDI_SUCCESS) { 14104 rval = DDI_FAILURE; 14105 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 14106 prechild, MPTSAS_DEV_GONE) != 14107 DDI_PROP_SUCCESS) { 14108 mptsas_log(mpt, CE_WARN, "mptsas driver " 14109 "unable to create property for " 14110 "SAS %s (MPTSAS_DEV_GONE)", addr); 14111 } 14112 } 14113 } 14114 14115 pip = mdi_get_next_client_path(pdip, NULL); 14116 while (pip) { 14117 addr = MDI_PI(pip)->pi_addr; 14118 savepip = pip; 14119 pip = mdi_get_next_client_path(pdip, pip); 14120 if (addr == NULL) { 14121 continue; 14122 } 14123 14124 if ((cp = strchr(addr, ',')) == NULL) { 14125 continue; 14126 } 14127 14128 s = (uintptr_t)cp - (uintptr_t)addr; 14129 14130 if (strncmp(addr, name, s) != 0) { 14131 continue; 14132 } 14133 14134 (void) mptsas_offline_lun(pdip, NULL, savepip, 14135 NDI_DEVI_REMOVE); 14136 /* 14137 * driver will not invoke mdi_pi_free, so path will not 14138 * be freed forever, return DDI_FAILURE. 14139 */ 14140 rval = DDI_FAILURE; 14141 } 14142 return (rval); 14143 } 14144 14145 static int 14146 mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip, 14147 mdi_pathinfo_t *rpip, uint_t flags) 14148 { 14149 int rval = DDI_FAILURE; 14150 char *devname; 14151 dev_info_t *cdip, *parent; 14152 14153 if (rpip != NULL) { 14154 parent = scsi_vhci_dip; 14155 cdip = mdi_pi_get_client(rpip); 14156 } else if (rdip != NULL) { 14157 parent = pdip; 14158 cdip = rdip; 14159 } else { 14160 return (DDI_FAILURE); 14161 } 14162 14163 /* 14164 * Make sure node is attached otherwise 14165 * it won't have related cache nodes to 14166 * clean up. i_ddi_devi_attached is 14167 * similiar to i_ddi_node_state(cdip) >= 14168 * DS_ATTACHED. 14169 */ 14170 if (i_ddi_devi_attached(cdip)) { 14171 14172 /* Get full devname */ 14173 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 14174 (void) ddi_deviname(cdip, devname); 14175 /* Clean cache */ 14176 (void) devfs_clean(parent, devname + 1, 14177 DV_CLEAN_FORCE); 14178 kmem_free(devname, MAXNAMELEN + 1); 14179 } 14180 if (rpip != NULL) { 14181 if (MDI_PI_IS_OFFLINE(rpip)) { 14182 rval = DDI_SUCCESS; 14183 } else { 14184 rval = mdi_pi_offline(rpip, 0); 14185 } 14186 } else { 14187 rval = ndi_devi_offline(cdip, flags); 14188 } 14189 14190 return (rval); 14191 } 14192 14193 static dev_info_t * 14194 mptsas_find_smp_child(dev_info_t *parent, char *str_wwn) 14195 { 14196 dev_info_t *child = NULL; 14197 char *smp_wwn = NULL; 14198 14199 child = ddi_get_child(parent); 14200 while (child) { 14201 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child, 14202 DDI_PROP_DONTPASS, SMP_WWN, &smp_wwn) 14203 != DDI_SUCCESS) { 14204 child = ddi_get_next_sibling(child); 14205 continue; 14206 } 14207 14208 if (strcmp(smp_wwn, str_wwn) == 0) { 14209 ddi_prop_free(smp_wwn); 14210 break; 14211 } 14212 child = ddi_get_next_sibling(child); 14213 ddi_prop_free(smp_wwn); 14214 } 14215 return (child); 14216 } 14217 14218 static int 14219 mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags) 14220 { 14221 int rval = DDI_FAILURE; 14222 char *devname; 14223 char wwn_str[MPTSAS_WWN_STRLEN]; 14224 dev_info_t *cdip; 14225 14226 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr); 14227 14228 cdip = mptsas_find_smp_child(pdip, wwn_str); 14229 14230 if (cdip == NULL) 14231 return (DDI_SUCCESS); 14232 14233 /* 14234 * Make sure node is attached otherwise 14235 * it won't have related cache nodes to 14236 * clean up. i_ddi_devi_attached is 14237 * similiar to i_ddi_node_state(cdip) >= 14238 * DS_ATTACHED. 14239 */ 14240 if (i_ddi_devi_attached(cdip)) { 14241 14242 /* Get full devname */ 14243 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 14244 (void) ddi_deviname(cdip, devname); 14245 /* Clean cache */ 14246 (void) devfs_clean(pdip, devname + 1, 14247 DV_CLEAN_FORCE); 14248 kmem_free(devname, MAXNAMELEN + 1); 14249 } 14250 14251 rval = ndi_devi_offline(cdip, flags); 14252 14253 return (rval); 14254 } 14255 14256 static dev_info_t * 14257 mptsas_find_child(dev_info_t *pdip, char *name) 14258 { 14259 dev_info_t *child = NULL; 14260 char *rname = NULL; 14261 int rval = DDI_FAILURE; 14262 14263 rname = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14264 14265 child = ddi_get_child(pdip); 14266 while (child) { 14267 rval = mptsas_name_child(child, rname, SCSI_MAXNAMELEN); 14268 if (rval != DDI_SUCCESS) { 14269 child = ddi_get_next_sibling(child); 14270 bzero(rname, SCSI_MAXNAMELEN); 14271 continue; 14272 } 14273 14274 if (strcmp(rname, name) == 0) { 14275 break; 14276 } 14277 child = ddi_get_next_sibling(child); 14278 bzero(rname, SCSI_MAXNAMELEN); 14279 } 14280 14281 kmem_free(rname, SCSI_MAXNAMELEN); 14282 14283 return (child); 14284 } 14285 14286 14287 static dev_info_t * 14288 mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, int lun) 14289 { 14290 dev_info_t *child = NULL; 14291 char *name = NULL; 14292 char *addr = NULL; 14293 14294 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14295 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14296 (void) sprintf(name, "%016"PRIx64, sasaddr); 14297 (void) sprintf(addr, "w%s,%x", name, lun); 14298 child = mptsas_find_child(pdip, addr); 14299 kmem_free(name, SCSI_MAXNAMELEN); 14300 kmem_free(addr, SCSI_MAXNAMELEN); 14301 return (child); 14302 } 14303 14304 static dev_info_t * 14305 mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy) 14306 { 14307 dev_info_t *child; 14308 char *addr; 14309 14310 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14311 (void) sprintf(addr, "p%x,0", phy); 14312 child = mptsas_find_child(pdip, addr); 14313 kmem_free(addr, SCSI_MAXNAMELEN); 14314 return (child); 14315 } 14316 14317 static mdi_pathinfo_t * 14318 mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy) 14319 { 14320 mdi_pathinfo_t *path; 14321 char *addr = NULL; 14322 14323 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14324 (void) sprintf(addr, "p%x,0", phy); 14325 path = mdi_pi_find(pdip, NULL, addr); 14326 kmem_free(addr, SCSI_MAXNAMELEN); 14327 return (path); 14328 } 14329 14330 static mdi_pathinfo_t * 14331 mptsas_find_path_addr(dev_info_t *parent, uint64_t sasaddr, int lun) 14332 { 14333 mdi_pathinfo_t *path; 14334 char *name = NULL; 14335 char *addr = NULL; 14336 14337 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14338 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14339 (void) sprintf(name, "%016"PRIx64, sasaddr); 14340 (void) sprintf(addr, "w%s,%x", name, lun); 14341 path = mdi_pi_find(parent, NULL, addr); 14342 kmem_free(name, SCSI_MAXNAMELEN); 14343 kmem_free(addr, SCSI_MAXNAMELEN); 14344 14345 return (path); 14346 } 14347 14348 static int 14349 mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq, 14350 dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun) 14351 { 14352 int i = 0; 14353 uchar_t *inq83 = NULL; 14354 int inq83_len1 = 0xFF; 14355 int inq83_len = 0; 14356 int rval = DDI_FAILURE; 14357 ddi_devid_t devid; 14358 char *guid = NULL; 14359 int target = ptgt->m_devhdl; 14360 mdi_pathinfo_t *pip = NULL; 14361 mptsas_t *mpt = DIP2MPT(pdip); 14362 14363 /* 14364 * For DVD/CD ROM and tape devices and optical 14365 * devices, we won't try to enumerate them under 14366 * scsi_vhci, so no need to try page83 14367 */ 14368 if (sd_inq && (sd_inq->inq_dtype == DTYPE_RODIRECT || 14369 sd_inq->inq_dtype == DTYPE_OPTICAL || 14370 sd_inq->inq_dtype == DTYPE_ESI)) 14371 goto create_lun; 14372 14373 /* 14374 * The LCA returns good SCSI status, but corrupt page 83 data the first 14375 * time it is queried. The solution is to keep trying to request page83 14376 * and verify the GUID is not (DDI_NOT_WELL_FORMED) in 14377 * mptsas_inq83_retry_timeout seconds. If the timeout expires, driver 14378 * give up to get VPD page at this stage and fail the enumeration. 14379 */ 14380 14381 inq83 = kmem_zalloc(inq83_len1, KM_SLEEP); 14382 14383 for (i = 0; i < mptsas_inq83_retry_timeout; i++) { 14384 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83, 14385 inq83_len1, &inq83_len, 1); 14386 if (rval != 0) { 14387 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 14388 "0x83 for target:%x, lun:%x failed!", target, lun); 14389 if (mptsas_physical_bind_failed_page_83 != B_FALSE) 14390 goto create_lun; 14391 goto out; 14392 } 14393 /* 14394 * create DEVID from inquiry data 14395 */ 14396 if ((rval = ddi_devid_scsi_encode( 14397 DEVID_SCSI_ENCODE_VERSION_LATEST, NULL, (uchar_t *)sd_inq, 14398 sizeof (struct scsi_inquiry), NULL, 0, inq83, 14399 (size_t)inq83_len, &devid)) == DDI_SUCCESS) { 14400 /* 14401 * extract GUID from DEVID 14402 */ 14403 guid = ddi_devid_to_guid(devid); 14404 14405 /* 14406 * Do not enable MPXIO if the strlen(guid) is greater 14407 * than MPTSAS_MAX_GUID_LEN, this constrain would be 14408 * handled by framework later. 14409 */ 14410 if (guid && (strlen(guid) > MPTSAS_MAX_GUID_LEN)) { 14411 ddi_devid_free_guid(guid); 14412 guid = NULL; 14413 if (mpt->m_mpxio_enable == TRUE) { 14414 mptsas_log(mpt, CE_NOTE, "!Target:%x, " 14415 "lun:%x doesn't have a valid GUID, " 14416 "multipathing for this drive is " 14417 "not enabled", target, lun); 14418 } 14419 } 14420 14421 /* 14422 * devid no longer needed 14423 */ 14424 ddi_devid_free(devid); 14425 break; 14426 } else if (rval == DDI_NOT_WELL_FORMED) { 14427 /* 14428 * return value of ddi_devid_scsi_encode equal to 14429 * DDI_NOT_WELL_FORMED means DEVID_RETRY, it worth 14430 * to retry inquiry page 0x83 and get GUID. 14431 */ 14432 NDBG20(("Not well formed devid, retry...")); 14433 delay(1 * drv_usectohz(1000000)); 14434 continue; 14435 } else { 14436 mptsas_log(mpt, CE_WARN, "!Encode devid failed for " 14437 "path target:%x, lun:%x", target, lun); 14438 rval = DDI_FAILURE; 14439 goto create_lun; 14440 } 14441 } 14442 14443 if (i == mptsas_inq83_retry_timeout) { 14444 mptsas_log(mpt, CE_WARN, "!Repeated page83 requests timeout " 14445 "for path target:%x, lun:%x", target, lun); 14446 } 14447 14448 rval = DDI_FAILURE; 14449 14450 create_lun: 14451 if ((guid != NULL) && (mpt->m_mpxio_enable == TRUE)) { 14452 rval = mptsas_create_virt_lun(pdip, sd_inq, guid, lun_dip, &pip, 14453 ptgt, lun); 14454 } 14455 if (rval != DDI_SUCCESS) { 14456 rval = mptsas_create_phys_lun(pdip, sd_inq, guid, lun_dip, 14457 ptgt, lun); 14458 14459 } 14460 out: 14461 if (guid != NULL) { 14462 /* 14463 * guid no longer needed 14464 */ 14465 ddi_devid_free_guid(guid); 14466 } 14467 if (inq83 != NULL) 14468 kmem_free(inq83, inq83_len1); 14469 return (rval); 14470 } 14471 14472 static int 14473 mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *inq, char *guid, 14474 dev_info_t **lun_dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, int lun) 14475 { 14476 int target; 14477 char *nodename = NULL; 14478 char **compatible = NULL; 14479 int ncompatible = 0; 14480 int mdi_rtn = MDI_FAILURE; 14481 int rval = DDI_FAILURE; 14482 char *old_guid = NULL; 14483 mptsas_t *mpt = DIP2MPT(pdip); 14484 char *lun_addr = NULL; 14485 char *wwn_str = NULL; 14486 char *attached_wwn_str = NULL; 14487 char *component = NULL; 14488 uint8_t phy = 0xFF; 14489 uint64_t sas_wwn; 14490 int64_t lun64 = 0; 14491 uint32_t devinfo; 14492 uint16_t dev_hdl; 14493 uint16_t pdev_hdl; 14494 uint64_t dev_sas_wwn; 14495 uint64_t pdev_sas_wwn; 14496 uint32_t pdev_info; 14497 uint8_t physport; 14498 uint8_t phy_id; 14499 uint32_t page_address; 14500 uint16_t bay_num, enclosure; 14501 char pdev_wwn_str[MPTSAS_WWN_STRLEN]; 14502 uint32_t dev_info; 14503 14504 mutex_enter(&mpt->m_mutex); 14505 target = ptgt->m_devhdl; 14506 sas_wwn = ptgt->m_sas_wwn; 14507 devinfo = ptgt->m_deviceinfo; 14508 phy = ptgt->m_phynum; 14509 mutex_exit(&mpt->m_mutex); 14510 14511 if (sas_wwn) { 14512 *pip = mptsas_find_path_addr(pdip, sas_wwn, lun); 14513 } else { 14514 *pip = mptsas_find_path_phy(pdip, phy); 14515 } 14516 14517 if (*pip != NULL) { 14518 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip; 14519 ASSERT(*lun_dip != NULL); 14520 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip, 14521 (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM), 14522 MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) { 14523 if (strncmp(guid, old_guid, strlen(guid)) == 0) { 14524 /* 14525 * Same path back online again. 14526 */ 14527 (void) ddi_prop_free(old_guid); 14528 if ((!MDI_PI_IS_ONLINE(*pip)) && 14529 (!MDI_PI_IS_STANDBY(*pip)) && 14530 (ptgt->m_tgt_unconfigured == 0)) { 14531 rval = mdi_pi_online(*pip, 0); 14532 mutex_enter(&mpt->m_mutex); 14533 (void) mptsas_set_led_status(mpt, ptgt, 14534 0); 14535 mutex_exit(&mpt->m_mutex); 14536 } else { 14537 rval = DDI_SUCCESS; 14538 } 14539 if (rval != DDI_SUCCESS) { 14540 mptsas_log(mpt, CE_WARN, "path:target: " 14541 "%x, lun:%x online failed!", target, 14542 lun); 14543 *pip = NULL; 14544 *lun_dip = NULL; 14545 } 14546 return (rval); 14547 } else { 14548 /* 14549 * The GUID of the LUN has changed which maybe 14550 * because customer mapped another volume to the 14551 * same LUN. 14552 */ 14553 mptsas_log(mpt, CE_WARN, "The GUID of the " 14554 "target:%x, lun:%x was changed, maybe " 14555 "because someone mapped another volume " 14556 "to the same LUN", target, lun); 14557 (void) ddi_prop_free(old_guid); 14558 if (!MDI_PI_IS_OFFLINE(*pip)) { 14559 rval = mdi_pi_offline(*pip, 0); 14560 if (rval != MDI_SUCCESS) { 14561 mptsas_log(mpt, CE_WARN, "path:" 14562 "target:%x, lun:%x offline " 14563 "failed!", target, lun); 14564 *pip = NULL; 14565 *lun_dip = NULL; 14566 return (DDI_FAILURE); 14567 } 14568 } 14569 if (mdi_pi_free(*pip, 0) != MDI_SUCCESS) { 14570 mptsas_log(mpt, CE_WARN, "path:target:" 14571 "%x, lun:%x free failed!", target, 14572 lun); 14573 *pip = NULL; 14574 *lun_dip = NULL; 14575 return (DDI_FAILURE); 14576 } 14577 } 14578 } else { 14579 mptsas_log(mpt, CE_WARN, "Can't get client-guid " 14580 "property for path:target:%x, lun:%x", target, lun); 14581 *pip = NULL; 14582 *lun_dip = NULL; 14583 return (DDI_FAILURE); 14584 } 14585 } 14586 scsi_hba_nodename_compatible_get(inq, NULL, 14587 inq->inq_dtype, NULL, &nodename, &compatible, &ncompatible); 14588 14589 /* 14590 * if nodename can't be determined then print a message and skip it 14591 */ 14592 if (nodename == NULL) { 14593 mptsas_log(mpt, CE_WARN, "mptsas driver found no compatible " 14594 "driver for target%d lun %d dtype:0x%02x", target, lun, 14595 inq->inq_dtype); 14596 return (DDI_FAILURE); 14597 } 14598 14599 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP); 14600 /* The property is needed by MPAPI */ 14601 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn); 14602 14603 lun_addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14604 if (guid) { 14605 (void) sprintf(lun_addr, "w%s,%x", wwn_str, lun); 14606 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 14607 } else { 14608 (void) sprintf(lun_addr, "p%x,%x", phy, lun); 14609 (void) sprintf(wwn_str, "p%x", phy); 14610 } 14611 14612 mdi_rtn = mdi_pi_alloc_compatible(pdip, nodename, 14613 guid, lun_addr, compatible, ncompatible, 14614 0, pip); 14615 if (mdi_rtn == MDI_SUCCESS) { 14616 14617 if (mdi_prop_update_string(*pip, MDI_GUID, 14618 guid) != DDI_SUCCESS) { 14619 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14620 "create prop for target %d lun %d (MDI_GUID)", 14621 target, lun); 14622 mdi_rtn = MDI_FAILURE; 14623 goto virt_create_done; 14624 } 14625 14626 if (mdi_prop_update_int(*pip, LUN_PROP, 14627 lun) != DDI_SUCCESS) { 14628 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14629 "create prop for target %d lun %d (LUN_PROP)", 14630 target, lun); 14631 mdi_rtn = MDI_FAILURE; 14632 goto virt_create_done; 14633 } 14634 lun64 = (int64_t)lun; 14635 if (mdi_prop_update_int64(*pip, LUN64_PROP, 14636 lun64) != DDI_SUCCESS) { 14637 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14638 "create prop for target %d (LUN64_PROP)", 14639 target); 14640 mdi_rtn = MDI_FAILURE; 14641 goto virt_create_done; 14642 } 14643 if (mdi_prop_update_string_array(*pip, "compatible", 14644 compatible, ncompatible) != 14645 DDI_PROP_SUCCESS) { 14646 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14647 "create prop for target %d lun %d (COMPATIBLE)", 14648 target, lun); 14649 mdi_rtn = MDI_FAILURE; 14650 goto virt_create_done; 14651 } 14652 if (sas_wwn && (mdi_prop_update_string(*pip, 14653 SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != DDI_PROP_SUCCESS)) { 14654 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14655 "create prop for target %d lun %d " 14656 "(target-port)", target, lun); 14657 mdi_rtn = MDI_FAILURE; 14658 goto virt_create_done; 14659 } else if ((sas_wwn == 0) && (mdi_prop_update_int(*pip, 14660 "sata-phy", phy) != DDI_PROP_SUCCESS)) { 14661 /* 14662 * Direct attached SATA device without DeviceName 14663 */ 14664 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14665 "create prop for SAS target %d lun %d " 14666 "(sata-phy)", target, lun); 14667 mdi_rtn = MDI_FAILURE; 14668 goto virt_create_done; 14669 } 14670 mutex_enter(&mpt->m_mutex); 14671 14672 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14673 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14674 (uint32_t)ptgt->m_devhdl; 14675 rval = mptsas_get_sas_device_page0(mpt, page_address, 14676 &dev_hdl, &dev_sas_wwn, &dev_info, &physport, 14677 &phy_id, &pdev_hdl, &bay_num, &enclosure); 14678 if (rval != DDI_SUCCESS) { 14679 mutex_exit(&mpt->m_mutex); 14680 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 14681 "parent device for handle %d", page_address); 14682 mdi_rtn = MDI_FAILURE; 14683 goto virt_create_done; 14684 } 14685 14686 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14687 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl; 14688 rval = mptsas_get_sas_device_page0(mpt, page_address, 14689 &dev_hdl, &pdev_sas_wwn, &pdev_info, &physport, 14690 &phy_id, &pdev_hdl, &bay_num, &enclosure); 14691 if (rval != DDI_SUCCESS) { 14692 mutex_exit(&mpt->m_mutex); 14693 mptsas_log(mpt, CE_WARN, "mptsas unable to get" 14694 "device info for handle %d", page_address); 14695 mdi_rtn = MDI_FAILURE; 14696 goto virt_create_done; 14697 } 14698 14699 mutex_exit(&mpt->m_mutex); 14700 14701 /* 14702 * If this device direct attached to the controller 14703 * set the attached-port to the base wwid 14704 */ 14705 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 14706 != DEVINFO_DIRECT_ATTACHED) { 14707 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 14708 pdev_sas_wwn); 14709 } else { 14710 /* 14711 * Update the iport's attached-port to guid 14712 */ 14713 if (sas_wwn == 0) { 14714 (void) sprintf(wwn_str, "p%x", phy); 14715 } else { 14716 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 14717 } 14718 if (ddi_prop_update_string(DDI_DEV_T_NONE, 14719 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 14720 DDI_PROP_SUCCESS) { 14721 mptsas_log(mpt, CE_WARN, 14722 "mptsas unable to create " 14723 "property for iport target-port" 14724 " %s (sas_wwn)", 14725 wwn_str); 14726 mdi_rtn = MDI_FAILURE; 14727 goto virt_create_done; 14728 } 14729 14730 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 14731 mpt->un.m_base_wwid); 14732 } 14733 14734 if (mdi_prop_update_string(*pip, 14735 SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) != 14736 DDI_PROP_SUCCESS) { 14737 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14738 "property for iport attached-port %s (sas_wwn)", 14739 attached_wwn_str); 14740 mdi_rtn = MDI_FAILURE; 14741 goto virt_create_done; 14742 } 14743 14744 14745 if (inq->inq_dtype == 0) { 14746 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 14747 /* 14748 * set obp path for pathinfo 14749 */ 14750 (void) snprintf(component, MAXPATHLEN, 14751 "disk@%s", lun_addr); 14752 14753 if (mdi_pi_pathname_obp_set(*pip, component) != 14754 DDI_SUCCESS) { 14755 mptsas_log(mpt, CE_WARN, "mpt_sas driver " 14756 "unable to set obp-path for object %s", 14757 component); 14758 mdi_rtn = MDI_FAILURE; 14759 goto virt_create_done; 14760 } 14761 } 14762 14763 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip; 14764 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 14765 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 14766 if ((ndi_prop_update_int(DDI_DEV_T_NONE, *lun_dip, 14767 "pm-capable", 1)) != 14768 DDI_PROP_SUCCESS) { 14769 mptsas_log(mpt, CE_WARN, "mptsas driver" 14770 "failed to create pm-capable " 14771 "property, target %d", target); 14772 mdi_rtn = MDI_FAILURE; 14773 goto virt_create_done; 14774 } 14775 } 14776 /* 14777 * Create the phy-num property 14778 */ 14779 if (mdi_prop_update_int(*pip, "phy-num", 14780 ptgt->m_phynum) != DDI_SUCCESS) { 14781 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 14782 "create phy-num property for target %d lun %d", 14783 target, lun); 14784 mdi_rtn = MDI_FAILURE; 14785 goto virt_create_done; 14786 } 14787 NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr)); 14788 mdi_rtn = mdi_pi_online(*pip, 0); 14789 if (mdi_rtn == MDI_SUCCESS) { 14790 mutex_enter(&mpt->m_mutex); 14791 if (mptsas_set_led_status(mpt, ptgt, 0) != 14792 DDI_SUCCESS) { 14793 NDBG14(("mptsas: clear LED for slot %x " 14794 "failed", ptgt->m_slot_num)); 14795 } 14796 mutex_exit(&mpt->m_mutex); 14797 } 14798 if (mdi_rtn == MDI_NOT_SUPPORTED) { 14799 mdi_rtn = MDI_FAILURE; 14800 } 14801 virt_create_done: 14802 if (*pip && mdi_rtn != MDI_SUCCESS) { 14803 (void) mdi_pi_free(*pip, 0); 14804 *pip = NULL; 14805 *lun_dip = NULL; 14806 } 14807 } 14808 14809 scsi_hba_nodename_compatible_free(nodename, compatible); 14810 if (lun_addr != NULL) { 14811 kmem_free(lun_addr, SCSI_MAXNAMELEN); 14812 } 14813 if (wwn_str != NULL) { 14814 kmem_free(wwn_str, MPTSAS_WWN_STRLEN); 14815 } 14816 if (component != NULL) { 14817 kmem_free(component, MAXPATHLEN); 14818 } 14819 14820 return ((mdi_rtn == MDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 14821 } 14822 14823 static int 14824 mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *inq, 14825 char *guid, dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun) 14826 { 14827 int target; 14828 int rval; 14829 int ndi_rtn = NDI_FAILURE; 14830 uint64_t be_sas_wwn; 14831 char *nodename = NULL; 14832 char **compatible = NULL; 14833 int ncompatible = 0; 14834 int instance = 0; 14835 mptsas_t *mpt = DIP2MPT(pdip); 14836 char *wwn_str = NULL; 14837 char *component = NULL; 14838 char *attached_wwn_str = NULL; 14839 uint8_t phy = 0xFF; 14840 uint64_t sas_wwn; 14841 uint32_t devinfo; 14842 uint16_t dev_hdl; 14843 uint16_t pdev_hdl; 14844 uint64_t pdev_sas_wwn; 14845 uint64_t dev_sas_wwn; 14846 uint32_t pdev_info; 14847 uint8_t physport; 14848 uint8_t phy_id; 14849 uint32_t page_address; 14850 uint16_t bay_num, enclosure; 14851 char pdev_wwn_str[MPTSAS_WWN_STRLEN]; 14852 uint32_t dev_info; 14853 int64_t lun64 = 0; 14854 14855 mutex_enter(&mpt->m_mutex); 14856 target = ptgt->m_devhdl; 14857 sas_wwn = ptgt->m_sas_wwn; 14858 devinfo = ptgt->m_deviceinfo; 14859 phy = ptgt->m_phynum; 14860 mutex_exit(&mpt->m_mutex); 14861 14862 /* 14863 * generate compatible property with binding-set "mpt" 14864 */ 14865 scsi_hba_nodename_compatible_get(inq, NULL, inq->inq_dtype, NULL, 14866 &nodename, &compatible, &ncompatible); 14867 14868 /* 14869 * if nodename can't be determined then print a message and skip it 14870 */ 14871 if (nodename == NULL) { 14872 mptsas_log(mpt, CE_WARN, "mptsas found no compatible driver " 14873 "for target %d lun %d", target, lun); 14874 return (DDI_FAILURE); 14875 } 14876 14877 ndi_rtn = ndi_devi_alloc(pdip, nodename, 14878 DEVI_SID_NODEID, lun_dip); 14879 14880 /* 14881 * if lun alloc success, set props 14882 */ 14883 if (ndi_rtn == NDI_SUCCESS) { 14884 14885 if (ndi_prop_update_int(DDI_DEV_T_NONE, 14886 *lun_dip, LUN_PROP, lun) != 14887 DDI_PROP_SUCCESS) { 14888 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14889 "property for target %d lun %d (LUN_PROP)", 14890 target, lun); 14891 ndi_rtn = NDI_FAILURE; 14892 goto phys_create_done; 14893 } 14894 14895 lun64 = (int64_t)lun; 14896 if (ndi_prop_update_int64(DDI_DEV_T_NONE, 14897 *lun_dip, LUN64_PROP, lun64) != 14898 DDI_PROP_SUCCESS) { 14899 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14900 "property for target %d lun64 %d (LUN64_PROP)", 14901 target, lun); 14902 ndi_rtn = NDI_FAILURE; 14903 goto phys_create_done; 14904 } 14905 if (ndi_prop_update_string_array(DDI_DEV_T_NONE, 14906 *lun_dip, "compatible", compatible, ncompatible) 14907 != DDI_PROP_SUCCESS) { 14908 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 14909 "property for target %d lun %d (COMPATIBLE)", 14910 target, lun); 14911 ndi_rtn = NDI_FAILURE; 14912 goto phys_create_done; 14913 } 14914 14915 /* 14916 * We need the SAS WWN for non-multipath devices, so 14917 * we'll use the same property as that multipathing 14918 * devices need to present for MPAPI. If we don't have 14919 * a WWN (e.g. parallel SCSI), don't create the prop. 14920 */ 14921 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP); 14922 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 14923 if (sas_wwn && ndi_prop_update_string(DDI_DEV_T_NONE, 14924 *lun_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) 14925 != DDI_PROP_SUCCESS) { 14926 mptsas_log(mpt, CE_WARN, "mptsas unable to " 14927 "create property for SAS target %d lun %d " 14928 "(target-port)", target, lun); 14929 ndi_rtn = NDI_FAILURE; 14930 goto phys_create_done; 14931 } 14932 14933 be_sas_wwn = BE_64(sas_wwn); 14934 if (sas_wwn && ndi_prop_update_byte_array( 14935 DDI_DEV_T_NONE, *lun_dip, "port-wwn", 14936 (uchar_t *)&be_sas_wwn, 8) != DDI_PROP_SUCCESS) { 14937 mptsas_log(mpt, CE_WARN, "mptsas unable to " 14938 "create property for SAS target %d lun %d " 14939 "(port-wwn)", target, lun); 14940 ndi_rtn = NDI_FAILURE; 14941 goto phys_create_done; 14942 } else if ((sas_wwn == 0) && (ndi_prop_update_int( 14943 DDI_DEV_T_NONE, *lun_dip, "sata-phy", phy) != 14944 DDI_PROP_SUCCESS)) { 14945 /* 14946 * Direct attached SATA device without DeviceName 14947 */ 14948 mptsas_log(mpt, CE_WARN, "mptsas unable to " 14949 "create property for SAS target %d lun %d " 14950 "(sata-phy)", target, lun); 14951 ndi_rtn = NDI_FAILURE; 14952 goto phys_create_done; 14953 } 14954 14955 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 14956 *lun_dip, SAS_PROP) != DDI_PROP_SUCCESS) { 14957 mptsas_log(mpt, CE_WARN, "mptsas unable to" 14958 "create property for SAS target %d lun %d" 14959 " (SAS_PROP)", target, lun); 14960 ndi_rtn = NDI_FAILURE; 14961 goto phys_create_done; 14962 } 14963 if (guid && (ndi_prop_update_string(DDI_DEV_T_NONE, 14964 *lun_dip, NDI_GUID, guid) != DDI_SUCCESS)) { 14965 mptsas_log(mpt, CE_WARN, "mptsas unable " 14966 "to create guid property for target %d " 14967 "lun %d", target, lun); 14968 ndi_rtn = NDI_FAILURE; 14969 goto phys_create_done; 14970 } 14971 14972 /* 14973 * The following code is to set properties for SM-HBA support, 14974 * it doesn't apply to RAID volumes 14975 */ 14976 if (ptgt->m_phymask == 0) 14977 goto phys_raid_lun; 14978 14979 mutex_enter(&mpt->m_mutex); 14980 14981 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14982 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14983 (uint32_t)ptgt->m_devhdl; 14984 rval = mptsas_get_sas_device_page0(mpt, page_address, 14985 &dev_hdl, &dev_sas_wwn, &dev_info, 14986 &physport, &phy_id, &pdev_hdl, 14987 &bay_num, &enclosure); 14988 if (rval != DDI_SUCCESS) { 14989 mutex_exit(&mpt->m_mutex); 14990 mptsas_log(mpt, CE_WARN, "mptsas unable to get" 14991 "parent device for handle %d.", page_address); 14992 ndi_rtn = NDI_FAILURE; 14993 goto phys_create_done; 14994 } 14995 14996 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 14997 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl; 14998 rval = mptsas_get_sas_device_page0(mpt, page_address, 14999 &dev_hdl, &pdev_sas_wwn, &pdev_info, 15000 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure); 15001 if (rval != DDI_SUCCESS) { 15002 mutex_exit(&mpt->m_mutex); 15003 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15004 "device for handle %d.", page_address); 15005 ndi_rtn = NDI_FAILURE; 15006 goto phys_create_done; 15007 } 15008 15009 mutex_exit(&mpt->m_mutex); 15010 15011 /* 15012 * If this device direct attached to the controller 15013 * set the attached-port to the base wwid 15014 */ 15015 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 15016 != DEVINFO_DIRECT_ATTACHED) { 15017 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 15018 pdev_sas_wwn); 15019 } else { 15020 /* 15021 * Update the iport's attached-port to guid 15022 */ 15023 if (sas_wwn == 0) { 15024 (void) sprintf(wwn_str, "p%x", phy); 15025 } else { 15026 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 15027 } 15028 if (ddi_prop_update_string(DDI_DEV_T_NONE, 15029 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 15030 DDI_PROP_SUCCESS) { 15031 mptsas_log(mpt, CE_WARN, 15032 "mptsas unable to create " 15033 "property for iport target-port" 15034 " %s (sas_wwn)", 15035 wwn_str); 15036 ndi_rtn = NDI_FAILURE; 15037 goto phys_create_done; 15038 } 15039 15040 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 15041 mpt->un.m_base_wwid); 15042 } 15043 15044 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15045 *lun_dip, SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) != 15046 DDI_PROP_SUCCESS) { 15047 mptsas_log(mpt, CE_WARN, 15048 "mptsas unable to create " 15049 "property for iport attached-port %s (sas_wwn)", 15050 attached_wwn_str); 15051 ndi_rtn = NDI_FAILURE; 15052 goto phys_create_done; 15053 } 15054 15055 if (IS_ATAPI_DEVICE(dev_info)) { 15056 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15057 *lun_dip, MPTSAS_VARIANT, "atapi") != 15058 DDI_PROP_SUCCESS) { 15059 mptsas_log(mpt, CE_WARN, 15060 "mptsas unable to create " 15061 "property for device variant "); 15062 ndi_rtn = NDI_FAILURE; 15063 goto phys_create_done; 15064 } 15065 } 15066 15067 if (IS_SATA_DEVICE(dev_info)) { 15068 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15069 *lun_dip, MPTSAS_VARIANT, "sata") != 15070 DDI_PROP_SUCCESS) { 15071 mptsas_log(mpt, CE_WARN, 15072 "mptsas unable to create " 15073 "property for device variant "); 15074 ndi_rtn = NDI_FAILURE; 15075 goto phys_create_done; 15076 } 15077 } 15078 phys_raid_lun: 15079 /* 15080 * if this is a SAS controller, and the target is a SATA 15081 * drive, set the 'pm-capable' property for sd and if on 15082 * an OPL platform, also check if this is an ATAPI 15083 * device. 15084 */ 15085 instance = ddi_get_instance(mpt->m_dip); 15086 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 15087 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 15088 NDBG2(("mptsas%d: creating pm-capable property, " 15089 "target %d", instance, target)); 15090 15091 if ((ndi_prop_update_int(DDI_DEV_T_NONE, 15092 *lun_dip, "pm-capable", 1)) != 15093 DDI_PROP_SUCCESS) { 15094 mptsas_log(mpt, CE_WARN, "mptsas " 15095 "failed to create pm-capable " 15096 "property, target %d", target); 15097 ndi_rtn = NDI_FAILURE; 15098 goto phys_create_done; 15099 } 15100 15101 } 15102 15103 if ((inq->inq_dtype == 0) || (inq->inq_dtype == 5)) { 15104 /* 15105 * add 'obp-path' properties for devinfo 15106 */ 15107 bzero(wwn_str, sizeof (wwn_str)); 15108 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn); 15109 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 15110 if (guid) { 15111 (void) snprintf(component, MAXPATHLEN, 15112 "disk@w%s,%x", wwn_str, lun); 15113 } else { 15114 (void) snprintf(component, MAXPATHLEN, 15115 "disk@p%x,%x", phy, lun); 15116 } 15117 if (ddi_pathname_obp_set(*lun_dip, component) 15118 != DDI_SUCCESS) { 15119 mptsas_log(mpt, CE_WARN, "mpt_sas driver " 15120 "unable to set obp-path for SAS " 15121 "object %s", component); 15122 ndi_rtn = NDI_FAILURE; 15123 goto phys_create_done; 15124 } 15125 } 15126 /* 15127 * Create the phy-num property for non-raid disk 15128 */ 15129 if (ptgt->m_phymask != 0) { 15130 if (ndi_prop_update_int(DDI_DEV_T_NONE, 15131 *lun_dip, "phy-num", ptgt->m_phynum) != 15132 DDI_PROP_SUCCESS) { 15133 mptsas_log(mpt, CE_WARN, "mptsas driver " 15134 "failed to create phy-num property for " 15135 "target %d", target); 15136 ndi_rtn = NDI_FAILURE; 15137 goto phys_create_done; 15138 } 15139 } 15140 phys_create_done: 15141 /* 15142 * If props were setup ok, online the lun 15143 */ 15144 if (ndi_rtn == NDI_SUCCESS) { 15145 /* 15146 * Try to online the new node 15147 */ 15148 ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH); 15149 } 15150 if (ndi_rtn == NDI_SUCCESS) { 15151 mutex_enter(&mpt->m_mutex); 15152 if (mptsas_set_led_status(mpt, ptgt, 0) != 15153 DDI_SUCCESS) { 15154 NDBG14(("mptsas: clear LED for tgt %x " 15155 "failed", ptgt->m_slot_num)); 15156 } 15157 mutex_exit(&mpt->m_mutex); 15158 } 15159 15160 /* 15161 * If success set rtn flag, else unwire alloc'd lun 15162 */ 15163 if (ndi_rtn != NDI_SUCCESS) { 15164 NDBG12(("mptsas driver unable to online " 15165 "target %d lun %d", target, lun)); 15166 ndi_prop_remove_all(*lun_dip); 15167 (void) ndi_devi_free(*lun_dip); 15168 *lun_dip = NULL; 15169 } 15170 } 15171 15172 scsi_hba_nodename_compatible_free(nodename, compatible); 15173 15174 if (wwn_str != NULL) { 15175 kmem_free(wwn_str, MPTSAS_WWN_STRLEN); 15176 } 15177 if (component != NULL) { 15178 kmem_free(component, MAXPATHLEN); 15179 } 15180 15181 15182 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 15183 } 15184 15185 static int 15186 mptsas_probe_smp(dev_info_t *pdip, uint64_t wwn) 15187 { 15188 mptsas_t *mpt = DIP2MPT(pdip); 15189 struct smp_device smp_sd; 15190 15191 /* XXX An HBA driver should not be allocating an smp_device. */ 15192 bzero(&smp_sd, sizeof (struct smp_device)); 15193 smp_sd.smp_sd_address.smp_a_hba_tran = mpt->m_smptran; 15194 bcopy(&wwn, smp_sd.smp_sd_address.smp_a_wwn, SAS_WWN_BYTE_SIZE); 15195 15196 if (smp_probe(&smp_sd) != DDI_PROBE_SUCCESS) 15197 return (NDI_FAILURE); 15198 return (NDI_SUCCESS); 15199 } 15200 15201 static int 15202 mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, dev_info_t **smp_dip) 15203 { 15204 mptsas_t *mpt = DIP2MPT(pdip); 15205 mptsas_smp_t *psmp = NULL; 15206 int rval; 15207 int phymask; 15208 15209 /* 15210 * Get the physical port associated to the iport 15211 * PHYMASK TODO 15212 */ 15213 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 15214 "phymask", 0); 15215 /* 15216 * Find the smp node in hash table with specified sas address and 15217 * physical port 15218 */ 15219 psmp = mptsas_wwid_to_psmp(mpt, phymask, sas_wwn); 15220 if (psmp == NULL) { 15221 return (DDI_FAILURE); 15222 } 15223 15224 rval = mptsas_online_smp(pdip, psmp, smp_dip); 15225 15226 return (rval); 15227 } 15228 15229 static int 15230 mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 15231 dev_info_t **smp_dip) 15232 { 15233 char wwn_str[MPTSAS_WWN_STRLEN]; 15234 char attached_wwn_str[MPTSAS_WWN_STRLEN]; 15235 int ndi_rtn = NDI_FAILURE; 15236 int rval = 0; 15237 mptsas_smp_t dev_info; 15238 uint32_t page_address; 15239 mptsas_t *mpt = DIP2MPT(pdip); 15240 uint16_t dev_hdl; 15241 uint64_t sas_wwn; 15242 uint64_t smp_sas_wwn; 15243 uint8_t physport; 15244 uint8_t phy_id; 15245 uint16_t pdev_hdl; 15246 uint8_t numphys = 0; 15247 uint16_t i = 0; 15248 char phymask[MPTSAS_MAX_PHYS]; 15249 char *iport = NULL; 15250 mptsas_phymask_t phy_mask = 0; 15251 uint16_t attached_devhdl; 15252 uint16_t bay_num, enclosure; 15253 15254 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr); 15255 15256 /* 15257 * Probe smp device, prevent the node of removed device from being 15258 * configured succesfully 15259 */ 15260 if (mptsas_probe_smp(pdip, smp_node->m_sasaddr) != NDI_SUCCESS) { 15261 return (DDI_FAILURE); 15262 } 15263 15264 if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) { 15265 return (DDI_SUCCESS); 15266 } 15267 15268 ndi_rtn = ndi_devi_alloc(pdip, "smp", DEVI_SID_NODEID, smp_dip); 15269 15270 /* 15271 * if lun alloc success, set props 15272 */ 15273 if (ndi_rtn == NDI_SUCCESS) { 15274 /* 15275 * Set the flavor of the child to be SMP flavored 15276 */ 15277 ndi_flavor_set(*smp_dip, SCSA_FLAVOR_SMP); 15278 15279 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15280 *smp_dip, SMP_WWN, wwn_str) != 15281 DDI_PROP_SUCCESS) { 15282 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15283 "property for smp device %s (sas_wwn)", 15284 wwn_str); 15285 ndi_rtn = NDI_FAILURE; 15286 goto smp_create_done; 15287 } 15288 (void) sprintf(wwn_str, "w%"PRIx64, smp_node->m_sasaddr); 15289 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15290 *smp_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != 15291 DDI_PROP_SUCCESS) { 15292 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15293 "property for iport target-port %s (sas_wwn)", 15294 wwn_str); 15295 ndi_rtn = NDI_FAILURE; 15296 goto smp_create_done; 15297 } 15298 15299 mutex_enter(&mpt->m_mutex); 15300 15301 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL & 15302 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | smp_node->m_devhdl; 15303 rval = mptsas_get_sas_expander_page0(mpt, page_address, 15304 &dev_info); 15305 if (rval != DDI_SUCCESS) { 15306 mutex_exit(&mpt->m_mutex); 15307 mptsas_log(mpt, CE_WARN, 15308 "mptsas unable to get expander " 15309 "parent device info for %x", page_address); 15310 ndi_rtn = NDI_FAILURE; 15311 goto smp_create_done; 15312 } 15313 15314 smp_node->m_pdevhdl = dev_info.m_pdevhdl; 15315 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 15316 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 15317 (uint32_t)dev_info.m_pdevhdl; 15318 rval = mptsas_get_sas_device_page0(mpt, page_address, 15319 &dev_hdl, &sas_wwn, &smp_node->m_pdevinfo, 15320 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure); 15321 if (rval != DDI_SUCCESS) { 15322 mutex_exit(&mpt->m_mutex); 15323 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 15324 "device info for %x", page_address); 15325 ndi_rtn = NDI_FAILURE; 15326 goto smp_create_done; 15327 } 15328 15329 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 15330 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 15331 (uint32_t)dev_info.m_devhdl; 15332 rval = mptsas_get_sas_device_page0(mpt, page_address, 15333 &dev_hdl, &smp_sas_wwn, &smp_node->m_deviceinfo, 15334 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure); 15335 if (rval != DDI_SUCCESS) { 15336 mutex_exit(&mpt->m_mutex); 15337 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 15338 "device info for %x", page_address); 15339 ndi_rtn = NDI_FAILURE; 15340 goto smp_create_done; 15341 } 15342 mutex_exit(&mpt->m_mutex); 15343 15344 /* 15345 * If this smp direct attached to the controller 15346 * set the attached-port to the base wwid 15347 */ 15348 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 15349 != DEVINFO_DIRECT_ATTACHED) { 15350 (void) sprintf(attached_wwn_str, "w%016"PRIx64, 15351 sas_wwn); 15352 } else { 15353 (void) sprintf(attached_wwn_str, "w%016"PRIx64, 15354 mpt->un.m_base_wwid); 15355 } 15356 15357 if (ndi_prop_update_string(DDI_DEV_T_NONE, 15358 *smp_dip, SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwn_str) != 15359 DDI_PROP_SUCCESS) { 15360 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15361 "property for smp attached-port %s (sas_wwn)", 15362 attached_wwn_str); 15363 ndi_rtn = NDI_FAILURE; 15364 goto smp_create_done; 15365 } 15366 15367 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 15368 *smp_dip, SMP_PROP) != DDI_PROP_SUCCESS) { 15369 mptsas_log(mpt, CE_WARN, "mptsas unable to " 15370 "create property for SMP %s (SMP_PROP) ", 15371 wwn_str); 15372 ndi_rtn = NDI_FAILURE; 15373 goto smp_create_done; 15374 } 15375 15376 /* 15377 * check the smp to see whether it direct 15378 * attached to the controller 15379 */ 15380 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 15381 != DEVINFO_DIRECT_ATTACHED) { 15382 goto smp_create_done; 15383 } 15384 numphys = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 15385 DDI_PROP_DONTPASS, MPTSAS_NUM_PHYS, -1); 15386 if (numphys > 0) { 15387 goto smp_create_done; 15388 } 15389 /* 15390 * this iport is an old iport, we need to 15391 * reconfig the props for it. 15392 */ 15393 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip, 15394 MPTSAS_VIRTUAL_PORT, 0) != 15395 DDI_PROP_SUCCESS) { 15396 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 15397 MPTSAS_VIRTUAL_PORT); 15398 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 15399 "prop update failed"); 15400 goto smp_create_done; 15401 } 15402 15403 mutex_enter(&mpt->m_mutex); 15404 numphys = 0; 15405 iport = ddi_get_name_addr(pdip); 15406 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 15407 bzero(phymask, sizeof (phymask)); 15408 (void) sprintf(phymask, 15409 "%x", mpt->m_phy_info[i].phy_mask); 15410 if (strcmp(phymask, iport) == 0) { 15411 phy_mask = mpt->m_phy_info[i].phy_mask; 15412 break; 15413 } 15414 } 15415 15416 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 15417 if ((phy_mask >> i) & 0x01) { 15418 numphys++; 15419 } 15420 } 15421 /* 15422 * Update PHY info for smhba 15423 */ 15424 if (mptsas_smhba_phy_init(mpt)) { 15425 mutex_exit(&mpt->m_mutex); 15426 mptsas_log(mpt, CE_WARN, "mptsas phy update " 15427 "failed"); 15428 goto smp_create_done; 15429 } 15430 mutex_exit(&mpt->m_mutex); 15431 15432 mptsas_smhba_set_phy_props(mpt, iport, pdip, 15433 numphys, &attached_devhdl); 15434 15435 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip, 15436 MPTSAS_NUM_PHYS, numphys) != 15437 DDI_PROP_SUCCESS) { 15438 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 15439 MPTSAS_NUM_PHYS); 15440 mptsas_log(mpt, CE_WARN, "mptsas update " 15441 "num phys props failed"); 15442 goto smp_create_done; 15443 } 15444 /* 15445 * Add parent's props for SMHBA support 15446 */ 15447 if (ddi_prop_update_string(DDI_DEV_T_NONE, pdip, 15448 SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 15449 DDI_PROP_SUCCESS) { 15450 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 15451 SCSI_ADDR_PROP_ATTACHED_PORT); 15452 mptsas_log(mpt, CE_WARN, "mptsas update iport" 15453 "attached-port failed"); 15454 goto smp_create_done; 15455 } 15456 15457 smp_create_done: 15458 /* 15459 * If props were setup ok, online the lun 15460 */ 15461 if (ndi_rtn == NDI_SUCCESS) { 15462 /* 15463 * Try to online the new node 15464 */ 15465 ndi_rtn = ndi_devi_online(*smp_dip, NDI_ONLINE_ATTACH); 15466 } 15467 15468 /* 15469 * If success set rtn flag, else unwire alloc'd lun 15470 */ 15471 if (ndi_rtn != NDI_SUCCESS) { 15472 NDBG12(("mptsas unable to online " 15473 "SMP target %s", wwn_str)); 15474 ndi_prop_remove_all(*smp_dip); 15475 (void) ndi_devi_free(*smp_dip); 15476 } 15477 } 15478 15479 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 15480 } 15481 15482 /* smp transport routine */ 15483 static int mptsas_smp_start(struct smp_pkt *smp_pkt) 15484 { 15485 uint64_t wwn; 15486 Mpi2SmpPassthroughRequest_t req; 15487 Mpi2SmpPassthroughReply_t rep; 15488 uint32_t direction = 0; 15489 mptsas_t *mpt; 15490 int ret; 15491 uint64_t tmp64; 15492 15493 mpt = (mptsas_t *)smp_pkt->smp_pkt_address-> 15494 smp_a_hba_tran->smp_tran_hba_private; 15495 15496 bcopy(smp_pkt->smp_pkt_address->smp_a_wwn, &wwn, SAS_WWN_BYTE_SIZE); 15497 /* 15498 * Need to compose a SMP request message 15499 * and call mptsas_do_passthru() function 15500 */ 15501 bzero(&req, sizeof (req)); 15502 bzero(&rep, sizeof (rep)); 15503 req.PassthroughFlags = 0; 15504 req.PhysicalPort = 0xff; 15505 req.ChainOffset = 0; 15506 req.Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 15507 15508 if ((smp_pkt->smp_pkt_reqsize & 0xffff0000ul) != 0) { 15509 smp_pkt->smp_pkt_reason = ERANGE; 15510 return (DDI_FAILURE); 15511 } 15512 req.RequestDataLength = LE_16((uint16_t)(smp_pkt->smp_pkt_reqsize - 4)); 15513 15514 req.MsgFlags = 0; 15515 tmp64 = LE_64(wwn); 15516 bcopy(&tmp64, &req.SASAddress, SAS_WWN_BYTE_SIZE); 15517 if (smp_pkt->smp_pkt_rspsize > 0) { 15518 direction |= MPTSAS_PASS_THRU_DIRECTION_READ; 15519 } 15520 if (smp_pkt->smp_pkt_reqsize > 0) { 15521 direction |= MPTSAS_PASS_THRU_DIRECTION_WRITE; 15522 } 15523 15524 mutex_enter(&mpt->m_mutex); 15525 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, 15526 (uint8_t *)smp_pkt->smp_pkt_rsp, 15527 offsetof(Mpi2SmpPassthroughRequest_t, SGL), sizeof (rep), 15528 smp_pkt->smp_pkt_rspsize - 4, direction, 15529 (uint8_t *)smp_pkt->smp_pkt_req, smp_pkt->smp_pkt_reqsize - 4, 15530 smp_pkt->smp_pkt_timeout, FKIOCTL); 15531 mutex_exit(&mpt->m_mutex); 15532 if (ret != 0) { 15533 cmn_err(CE_WARN, "smp_start do passthru error %d", ret); 15534 smp_pkt->smp_pkt_reason = (uchar_t)(ret); 15535 return (DDI_FAILURE); 15536 } 15537 /* do passthrough success, check the smp status */ 15538 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 15539 switch (LE_16(rep.IOCStatus)) { 15540 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 15541 smp_pkt->smp_pkt_reason = ENODEV; 15542 break; 15543 case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN: 15544 smp_pkt->smp_pkt_reason = EOVERFLOW; 15545 break; 15546 case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED: 15547 smp_pkt->smp_pkt_reason = EIO; 15548 break; 15549 default: 15550 mptsas_log(mpt, CE_NOTE, "smp_start: get unknown ioc" 15551 "status:%x", LE_16(rep.IOCStatus)); 15552 smp_pkt->smp_pkt_reason = EIO; 15553 break; 15554 } 15555 return (DDI_FAILURE); 15556 } 15557 if (rep.SASStatus != MPI2_SASSTATUS_SUCCESS) { 15558 mptsas_log(mpt, CE_NOTE, "smp_start: get error SAS status:%x", 15559 rep.SASStatus); 15560 smp_pkt->smp_pkt_reason = EIO; 15561 return (DDI_FAILURE); 15562 } 15563 15564 return (DDI_SUCCESS); 15565 } 15566 15567 /* 15568 * If we didn't get a match, we need to get sas page0 for each device, and 15569 * untill we get a match. If failed, return NULL 15570 */ 15571 static mptsas_target_t * 15572 mptsas_phy_to_tgt(mptsas_t *mpt, int phymask, uint8_t phy) 15573 { 15574 int i, j = 0; 15575 int rval = 0; 15576 uint16_t cur_handle; 15577 uint32_t page_address; 15578 mptsas_target_t *ptgt = NULL; 15579 15580 /* 15581 * PHY named device must be direct attached and attaches to 15582 * narrow port, if the iport is not parent of the device which 15583 * we are looking for. 15584 */ 15585 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 15586 if ((1 << i) & phymask) 15587 j++; 15588 } 15589 15590 if (j > 1) 15591 return (NULL); 15592 15593 /* 15594 * Must be a narrow port and single device attached to the narrow port 15595 * So the physical port num of device which is equal to the iport's 15596 * port num is the device what we are looking for. 15597 */ 15598 15599 if (mpt->m_phy_info[phy].phy_mask != phymask) 15600 return (NULL); 15601 15602 mutex_enter(&mpt->m_mutex); 15603 15604 ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl, 15605 MPTSAS_HASH_FIRST); 15606 while (ptgt != NULL) { 15607 if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) { 15608 mutex_exit(&mpt->m_mutex); 15609 return (ptgt); 15610 } 15611 15612 ptgt = (mptsas_target_t *)mptsas_hash_traverse( 15613 &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT); 15614 } 15615 15616 if (mpt->m_done_traverse_dev) { 15617 mutex_exit(&mpt->m_mutex); 15618 return (NULL); 15619 } 15620 15621 /* If didn't get a match, come here */ 15622 cur_handle = mpt->m_dev_handle; 15623 for (; ; ) { 15624 ptgt = NULL; 15625 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 15626 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)cur_handle; 15627 rval = mptsas_get_target_device_info(mpt, page_address, 15628 &cur_handle, &ptgt); 15629 if ((rval == DEV_INFO_FAIL_PAGE0) || 15630 (rval == DEV_INFO_FAIL_ALLOC)) { 15631 break; 15632 } 15633 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) || 15634 (rval == DEV_INFO_PHYS_DISK)) { 15635 continue; 15636 } 15637 mpt->m_dev_handle = cur_handle; 15638 15639 if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) { 15640 break; 15641 } 15642 } 15643 15644 mutex_exit(&mpt->m_mutex); 15645 return (ptgt); 15646 } 15647 15648 /* 15649 * The ptgt->m_sas_wwn contains the wwid for each disk. 15650 * For Raid volumes, we need to check m_raidvol[x].m_raidwwid 15651 * If we didn't get a match, we need to get sas page0 for each device, and 15652 * untill we get a match 15653 * If failed, return NULL 15654 */ 15655 static mptsas_target_t * 15656 mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask, uint64_t wwid) 15657 { 15658 int rval = 0; 15659 uint16_t cur_handle; 15660 uint32_t page_address; 15661 mptsas_target_t *tmp_tgt = NULL; 15662 15663 mutex_enter(&mpt->m_mutex); 15664 tmp_tgt = (struct mptsas_target *)mptsas_hash_search( 15665 &mpt->m_active->m_tgttbl, wwid, phymask); 15666 if (tmp_tgt != NULL) { 15667 mutex_exit(&mpt->m_mutex); 15668 return (tmp_tgt); 15669 } 15670 15671 if (phymask == 0) { 15672 /* 15673 * It's IR volume 15674 */ 15675 rval = mptsas_get_raid_info(mpt); 15676 if (rval) { 15677 tmp_tgt = (struct mptsas_target *)mptsas_hash_search( 15678 &mpt->m_active->m_tgttbl, wwid, phymask); 15679 } 15680 mutex_exit(&mpt->m_mutex); 15681 return (tmp_tgt); 15682 } 15683 15684 if (mpt->m_done_traverse_dev) { 15685 mutex_exit(&mpt->m_mutex); 15686 return (NULL); 15687 } 15688 15689 /* If didn't get a match, come here */ 15690 cur_handle = mpt->m_dev_handle; 15691 for (; ; ) { 15692 tmp_tgt = NULL; 15693 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 15694 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle; 15695 rval = mptsas_get_target_device_info(mpt, page_address, 15696 &cur_handle, &tmp_tgt); 15697 if ((rval == DEV_INFO_FAIL_PAGE0) || 15698 (rval == DEV_INFO_FAIL_ALLOC)) { 15699 tmp_tgt = NULL; 15700 break; 15701 } 15702 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) || 15703 (rval == DEV_INFO_PHYS_DISK)) { 15704 continue; 15705 } 15706 mpt->m_dev_handle = cur_handle; 15707 if ((tmp_tgt->m_sas_wwn) && (tmp_tgt->m_sas_wwn == wwid) && 15708 (tmp_tgt->m_phymask == phymask)) { 15709 break; 15710 } 15711 } 15712 15713 mutex_exit(&mpt->m_mutex); 15714 return (tmp_tgt); 15715 } 15716 15717 static mptsas_smp_t * 15718 mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask, uint64_t wwid) 15719 { 15720 int rval = 0; 15721 uint16_t cur_handle; 15722 uint32_t page_address; 15723 mptsas_smp_t smp_node, *psmp = NULL; 15724 15725 mutex_enter(&mpt->m_mutex); 15726 psmp = (struct mptsas_smp *)mptsas_hash_search(&mpt->m_active->m_smptbl, 15727 wwid, phymask); 15728 if (psmp != NULL) { 15729 mutex_exit(&mpt->m_mutex); 15730 return (psmp); 15731 } 15732 15733 if (mpt->m_done_traverse_smp) { 15734 mutex_exit(&mpt->m_mutex); 15735 return (NULL); 15736 } 15737 15738 /* If didn't get a match, come here */ 15739 cur_handle = mpt->m_smp_devhdl; 15740 for (; ; ) { 15741 psmp = NULL; 15742 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL & 15743 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle; 15744 rval = mptsas_get_sas_expander_page0(mpt, page_address, 15745 &smp_node); 15746 if (rval != DDI_SUCCESS) { 15747 break; 15748 } 15749 mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl; 15750 psmp = mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node); 15751 ASSERT(psmp); 15752 if ((psmp->m_sasaddr) && (psmp->m_sasaddr == wwid) && 15753 (psmp->m_phymask == phymask)) { 15754 break; 15755 } 15756 } 15757 15758 mutex_exit(&mpt->m_mutex); 15759 return (psmp); 15760 } 15761 15762 /* helper functions using hash */ 15763 15764 /* 15765 * Can't have duplicate entries for same devhdl, 15766 * if there are invalid entries, the devhdl should be set to 0xffff 15767 */ 15768 static void * 15769 mptsas_search_by_devhdl(mptsas_hash_table_t *hashtab, uint16_t devhdl) 15770 { 15771 mptsas_hash_data_t *data; 15772 15773 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST); 15774 while (data != NULL) { 15775 if (data->devhdl == devhdl) { 15776 break; 15777 } 15778 data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT); 15779 } 15780 return (data); 15781 } 15782 15783 mptsas_target_t * 15784 mptsas_tgt_alloc(mptsas_hash_table_t *hashtab, uint16_t devhdl, uint64_t wwid, 15785 uint32_t devinfo, mptsas_phymask_t phymask, uint8_t phynum, mptsas_t *mpt) 15786 { 15787 mptsas_target_t *tmp_tgt = NULL; 15788 15789 tmp_tgt = mptsas_hash_search(hashtab, wwid, phymask); 15790 if (tmp_tgt != NULL) { 15791 NDBG20(("Hash item already exist")); 15792 tmp_tgt->m_deviceinfo = devinfo; 15793 tmp_tgt->m_devhdl = devhdl; 15794 return (tmp_tgt); 15795 } 15796 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP); 15797 if (tmp_tgt == NULL) { 15798 cmn_err(CE_WARN, "Fatal, allocated tgt failed"); 15799 return (NULL); 15800 } 15801 tmp_tgt->m_devhdl = devhdl; 15802 tmp_tgt->m_sas_wwn = wwid; 15803 tmp_tgt->m_deviceinfo = devinfo; 15804 tmp_tgt->m_phymask = phymask; 15805 tmp_tgt->m_phynum = phynum; 15806 /* Initialized the tgt structure */ 15807 tmp_tgt->m_qfull_retries = QFULL_RETRIES; 15808 tmp_tgt->m_qfull_retry_interval = 15809 drv_usectohz(QFULL_RETRY_INTERVAL * 1000); 15810 tmp_tgt->m_t_throttle = MAX_THROTTLE; 15811 mutex_init(&tmp_tgt->m_tgt_intr_mutex, NULL, MUTEX_DRIVER, 15812 DDI_INTR_PRI(mpt->m_intr_pri)); 15813 15814 mptsas_hash_add(hashtab, tmp_tgt); 15815 15816 return (tmp_tgt); 15817 } 15818 15819 static void 15820 mptsas_tgt_free(mptsas_hash_table_t *hashtab, uint64_t wwid, 15821 mptsas_phymask_t phymask) 15822 { 15823 mptsas_target_t *tmp_tgt; 15824 tmp_tgt = mptsas_hash_rem(hashtab, wwid, phymask); 15825 if (tmp_tgt == NULL) { 15826 cmn_err(CE_WARN, "Tgt not found, nothing to free"); 15827 } else { 15828 mutex_destroy(&tmp_tgt->m_tgt_intr_mutex); 15829 kmem_free(tmp_tgt, sizeof (struct mptsas_target)); 15830 } 15831 } 15832 15833 /* 15834 * Return the entry in the hash table 15835 */ 15836 static mptsas_smp_t * 15837 mptsas_smp_alloc(mptsas_hash_table_t *hashtab, mptsas_smp_t *data) 15838 { 15839 uint64_t key1 = data->m_sasaddr; 15840 mptsas_phymask_t key2 = data->m_phymask; 15841 mptsas_smp_t *ret_data; 15842 15843 ret_data = mptsas_hash_search(hashtab, key1, key2); 15844 if (ret_data != NULL) { 15845 bcopy(data, ret_data, sizeof (mptsas_smp_t)); 15846 return (ret_data); 15847 } 15848 15849 ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP); 15850 bcopy(data, ret_data, sizeof (mptsas_smp_t)); 15851 mptsas_hash_add(hashtab, ret_data); 15852 return (ret_data); 15853 } 15854 15855 static void 15856 mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid, 15857 mptsas_phymask_t phymask) 15858 { 15859 mptsas_smp_t *tmp_smp; 15860 tmp_smp = mptsas_hash_rem(hashtab, wwid, phymask); 15861 if (tmp_smp == NULL) { 15862 cmn_err(CE_WARN, "Smp element not found, nothing to free"); 15863 } else { 15864 kmem_free(tmp_smp, sizeof (struct mptsas_smp)); 15865 } 15866 } 15867 15868 /* 15869 * Hash operation functions 15870 * key1 is the sas_wwn, key2 is the phymask 15871 */ 15872 static void 15873 mptsas_hash_init(mptsas_hash_table_t *hashtab) 15874 { 15875 if (hashtab == NULL) { 15876 return; 15877 } 15878 bzero(hashtab->head, sizeof (mptsas_hash_node_t) * 15879 MPTSAS_HASH_ARRAY_SIZE); 15880 hashtab->cur = NULL; 15881 hashtab->line = 0; 15882 } 15883 15884 static void 15885 mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen) 15886 { 15887 uint16_t line = 0; 15888 mptsas_hash_node_t *cur = NULL, *last = NULL; 15889 15890 if (hashtab == NULL) { 15891 return; 15892 } 15893 for (line = 0; line < MPTSAS_HASH_ARRAY_SIZE; line++) { 15894 cur = hashtab->head[line]; 15895 while (cur != NULL) { 15896 last = cur; 15897 cur = cur->next; 15898 kmem_free(last->data, datalen); 15899 kmem_free(last, sizeof (mptsas_hash_node_t)); 15900 } 15901 } 15902 } 15903 15904 /* 15905 * You must guarantee the element doesn't exist in the hash table 15906 * before you call mptsas_hash_add() 15907 */ 15908 static void 15909 mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data) 15910 { 15911 uint64_t key1 = ((mptsas_hash_data_t *)data)->key1; 15912 mptsas_phymask_t key2 = ((mptsas_hash_data_t *)data)->key2; 15913 mptsas_hash_node_t **head = NULL; 15914 mptsas_hash_node_t *node = NULL; 15915 15916 if (hashtab == NULL) { 15917 return; 15918 } 15919 ASSERT(mptsas_hash_search(hashtab, key1, key2) == NULL); 15920 node = kmem_zalloc(sizeof (mptsas_hash_node_t), KM_NOSLEEP); 15921 node->data = data; 15922 15923 head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]); 15924 if (*head == NULL) { 15925 *head = node; 15926 } else { 15927 node->next = *head; 15928 *head = node; 15929 } 15930 } 15931 15932 static void * 15933 mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1, 15934 mptsas_phymask_t key2) 15935 { 15936 mptsas_hash_node_t **head = NULL; 15937 mptsas_hash_node_t *last = NULL, *cur = NULL; 15938 mptsas_hash_data_t *data; 15939 if (hashtab == NULL) { 15940 return (NULL); 15941 } 15942 head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]); 15943 cur = *head; 15944 while (cur != NULL) { 15945 data = cur->data; 15946 if ((data->key1 == key1) && (data->key2 == key2)) { 15947 if (last == NULL) { 15948 (*head) = cur->next; 15949 } else { 15950 last->next = cur->next; 15951 } 15952 kmem_free(cur, sizeof (mptsas_hash_node_t)); 15953 return (data); 15954 } else { 15955 last = cur; 15956 cur = cur->next; 15957 } 15958 } 15959 return (NULL); 15960 } 15961 15962 static void * 15963 mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1, 15964 mptsas_phymask_t key2) 15965 { 15966 mptsas_hash_node_t *cur = NULL; 15967 mptsas_hash_data_t *data; 15968 if (hashtab == NULL) { 15969 return (NULL); 15970 } 15971 cur = hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]; 15972 while (cur != NULL) { 15973 data = cur->data; 15974 if ((data->key1 == key1) && (data->key2 == key2)) { 15975 return (data); 15976 } else { 15977 cur = cur->next; 15978 } 15979 } 15980 return (NULL); 15981 } 15982 15983 static void * 15984 mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos) 15985 { 15986 mptsas_hash_node_t *this = NULL; 15987 15988 if (hashtab == NULL) { 15989 return (NULL); 15990 } 15991 15992 if (pos == MPTSAS_HASH_FIRST) { 15993 hashtab->line = 0; 15994 hashtab->cur = NULL; 15995 this = hashtab->head[0]; 15996 } else { 15997 if (hashtab->cur == NULL) { 15998 return (NULL); 15999 } else { 16000 this = hashtab->cur->next; 16001 } 16002 } 16003 16004 while (this == NULL) { 16005 hashtab->line++; 16006 if (hashtab->line >= MPTSAS_HASH_ARRAY_SIZE) { 16007 /* the traverse reaches the end */ 16008 hashtab->cur = NULL; 16009 return (NULL); 16010 } else { 16011 this = hashtab->head[hashtab->line]; 16012 } 16013 } 16014 hashtab->cur = this; 16015 return (this->data); 16016 } 16017 16018 /* 16019 * Functions for SGPIO LED support 16020 */ 16021 static dev_info_t * 16022 mptsas_get_dip_from_dev(dev_t dev, mptsas_phymask_t *phymask) 16023 { 16024 dev_info_t *dip; 16025 int prop; 16026 dip = e_ddi_hold_devi_by_dev(dev, 0); 16027 if (dip == NULL) 16028 return (dip); 16029 prop = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 16030 "phymask", 0); 16031 *phymask = (mptsas_phymask_t)prop; 16032 ddi_release_devi(dip); 16033 return (dip); 16034 } 16035 static mptsas_target_t * 16036 mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask) 16037 { 16038 uint8_t phynum; 16039 uint64_t wwn; 16040 int lun; 16041 mptsas_target_t *ptgt = NULL; 16042 16043 if (mptsas_parse_address(addr, &wwn, &phynum, &lun) != DDI_SUCCESS) { 16044 return (NULL); 16045 } 16046 if (addr[0] == 'w') { 16047 ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn); 16048 } else { 16049 ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum); 16050 } 16051 return (ptgt); 16052 } 16053 16054 #ifdef MPTSAS_GET_LED 16055 static int 16056 mptsas_get_led_status(mptsas_t *mpt, mptsas_target_t *ptgt, 16057 uint32_t *slotstatus) 16058 { 16059 return (mptsas_send_sep(mpt, ptgt, slotstatus, 16060 MPI2_SEP_REQ_ACTION_READ_STATUS)); 16061 } 16062 #endif 16063 static int 16064 mptsas_set_led_status(mptsas_t *mpt, mptsas_target_t *ptgt, uint32_t slotstatus) 16065 { 16066 NDBG14(("mptsas_ioctl: set LED status %x for slot %x", 16067 slotstatus, ptgt->m_slot_num)); 16068 return (mptsas_send_sep(mpt, ptgt, &slotstatus, 16069 MPI2_SEP_REQ_ACTION_WRITE_STATUS)); 16070 } 16071 /* 16072 * send sep request, use enclosure/slot addressing 16073 */ 16074 static int mptsas_send_sep(mptsas_t *mpt, mptsas_target_t *ptgt, 16075 uint32_t *status, uint8_t act) 16076 { 16077 Mpi2SepRequest_t req; 16078 Mpi2SepReply_t rep; 16079 int ret; 16080 16081 ASSERT(mutex_owned(&mpt->m_mutex)); 16082 16083 bzero(&req, sizeof (req)); 16084 bzero(&rep, sizeof (rep)); 16085 16086 /* Do nothing for RAID volumes */ 16087 if (ptgt->m_phymask == 0) { 16088 NDBG14(("mptsas_send_sep: Skip RAID volumes")); 16089 return (DDI_FAILURE); 16090 } 16091 16092 req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; 16093 req.Action = act; 16094 req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS; 16095 req.EnclosureHandle = LE_16(ptgt->m_enclosure); 16096 req.Slot = LE_16(ptgt->m_slot_num); 16097 if (act == MPI2_SEP_REQ_ACTION_WRITE_STATUS) { 16098 req.SlotStatus = LE_32(*status); 16099 } 16100 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL, 16101 sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL); 16102 if (ret != 0) { 16103 mptsas_log(mpt, CE_NOTE, "mptsas_send_sep: passthru SEP " 16104 "Processor Request message error %d", ret); 16105 return (DDI_FAILURE); 16106 } 16107 /* do passthrough success, check the ioc status */ 16108 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 16109 if ((LE_16(rep.IOCStatus) & MPI2_IOCSTATUS_MASK) == 16110 MPI2_IOCSTATUS_INVALID_FIELD) { 16111 mptsas_log(mpt, CE_NOTE, "send sep act %x: Not " 16112 "supported action, loginfo %x", act, 16113 LE_32(rep.IOCLogInfo)); 16114 return (DDI_FAILURE); 16115 } 16116 mptsas_log(mpt, CE_NOTE, "send_sep act %x: ioc " 16117 "status:%x", act, LE_16(rep.IOCStatus)); 16118 return (DDI_FAILURE); 16119 } 16120 if (act != MPI2_SEP_REQ_ACTION_WRITE_STATUS) { 16121 *status = LE_32(rep.SlotStatus); 16122 } 16123 16124 return (DDI_SUCCESS); 16125 } 16126 16127 int 16128 mptsas_dma_addr_create(mptsas_t *mpt, ddi_dma_attr_t dma_attr, 16129 ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp, caddr_t *dma_memp, 16130 uint32_t alloc_size, ddi_dma_cookie_t *cookiep) 16131 { 16132 ddi_dma_cookie_t new_cookie; 16133 size_t alloc_len; 16134 uint_t ncookie; 16135 16136 if (cookiep == NULL) 16137 cookiep = &new_cookie; 16138 16139 if (ddi_dma_alloc_handle(mpt->m_dip, &dma_attr, DDI_DMA_SLEEP, 16140 NULL, dma_hdp) != DDI_SUCCESS) { 16141 dma_hdp = NULL; 16142 return (FALSE); 16143 } 16144 16145 if (ddi_dma_mem_alloc(*dma_hdp, alloc_size, &mpt->m_dev_acc_attr, 16146 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, dma_memp, &alloc_len, 16147 acc_hdp) != DDI_SUCCESS) { 16148 ddi_dma_free_handle(dma_hdp); 16149 dma_hdp = NULL; 16150 return (FALSE); 16151 } 16152 16153 if (ddi_dma_addr_bind_handle(*dma_hdp, NULL, *dma_memp, alloc_len, 16154 (DDI_DMA_RDWR | DDI_DMA_CONSISTENT), DDI_DMA_SLEEP, NULL, 16155 cookiep, &ncookie) != DDI_DMA_MAPPED) { 16156 (void) ddi_dma_mem_free(acc_hdp); 16157 ddi_dma_free_handle(dma_hdp); 16158 dma_hdp = NULL; 16159 return (FALSE); 16160 } 16161 16162 return (TRUE); 16163 } 16164 16165 void 16166 mptsas_dma_addr_destroy(ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp) 16167 { 16168 if (*dma_hdp == NULL) 16169 return; 16170 16171 (void) ddi_dma_unbind_handle(*dma_hdp); 16172 (void) ddi_dma_mem_free(acc_hdp); 16173 ddi_dma_free_handle(dma_hdp); 16174 dma_hdp = NULL; 16175 } 16176 16177 static int 16178 mptsas_outstanding_cmds_n(mptsas_t *mpt) 16179 { 16180 int n = 0, i; 16181 for (i = 0; i < mpt->m_slot_freeq_pair_n; i++) { 16182 mutex_enter(&mpt->m_slot_freeq_pairp[i]. 16183 m_slot_allocq.s.m_fq_mutex); 16184 mutex_enter(&mpt->m_slot_freeq_pairp[i]. 16185 m_slot_releq.s.m_fq_mutex); 16186 n += (mpt->m_slot_freeq_pairp[i].m_slot_allocq.s.m_fq_n_init - 16187 mpt->m_slot_freeq_pairp[i].m_slot_allocq.s.m_fq_n - 16188 mpt->m_slot_freeq_pairp[i].m_slot_releq.s.m_fq_n); 16189 mutex_exit(&mpt->m_slot_freeq_pairp[i]. 16190 m_slot_releq.s.m_fq_mutex); 16191 mutex_exit(&mpt->m_slot_freeq_pairp[i]. 16192 m_slot_allocq.s.m_fq_mutex); 16193 } 16194 if (mpt->m_max_requests - 2 < n) 16195 panic("mptsas: free slot allocq and releq crazy"); 16196 return (n); 16197 } 16198