1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2016 Nexenta Systems, Inc. All rights reserved. 25 * Copyright 2019 Joyent, Inc. 26 * Copyright 2014 OmniTI Computer Consulting, Inc. All rights reserved. 27 * Copyright (c) 2014, Tegile Systems Inc. All rights reserved. 28 * Copyright 2023 Oxide Computer Company 29 * Copyright 2023 Racktop Systems, Inc. 30 */ 31 32 /* 33 * Copyright (c) 2000 to 2010, LSI Corporation. 34 * All rights reserved. 35 * 36 * Redistribution and use in source and binary forms of all code within 37 * this file that is exclusively owned by LSI, with or without 38 * modification, is permitted provided that, in addition to the CDDL 1.0 39 * License requirements, the following conditions are met: 40 * 41 * Neither the name of the author nor the names of its contributors may be 42 * used to endorse or promote products derived from this software without 43 * specific prior written permission. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 46 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 47 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 48 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 49 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 50 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 51 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 52 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 53 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 54 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 55 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 56 * DAMAGE. 57 */ 58 59 /* 60 * mptsas - This is a driver based on LSI Logic's MPT2.0/2.5 interface. 61 * 62 */ 63 64 #if defined(lint) || defined(DEBUG) 65 #define MPTSAS_DEBUG 66 #endif 67 68 /* 69 * standard header files. 70 */ 71 #include <sys/note.h> 72 #include <sys/scsi/scsi.h> 73 #include <sys/pci.h> 74 #include <sys/file.h> 75 #include <sys/policy.h> 76 #include <sys/model.h> 77 #include <sys/refhash.h> 78 #include <sys/sysevent.h> 79 #include <sys/sysevent/eventdefs.h> 80 #include <sys/sysevent/dr.h> 81 #include <sys/sata/sata_defs.h> 82 #include <sys/sata/sata_hba.h> 83 #include <sys/scsi/generic/sas.h> 84 #include <sys/scsi/impl/scsi_sas.h> 85 86 #pragma pack(1) 87 #include <sys/scsi/adapters/mpi/mpi2_type.h> 88 #include <sys/scsi/adapters/mpi/mpi2.h> 89 #include <sys/scsi/adapters/mpi/mpi2_cnfg.h> 90 #include <sys/scsi/adapters/mpi/mpi2_init.h> 91 #include <sys/scsi/adapters/mpi/mpi2_ioc.h> 92 #include <sys/scsi/adapters/mpi/mpi2_sas.h> 93 #include <sys/scsi/adapters/mpi/mpi2_tool.h> 94 #include <sys/scsi/adapters/mpi/mpi2_raid.h> 95 #pragma pack() 96 97 /* 98 * private header files. 99 * 100 */ 101 #include <sys/scsi/impl/scsi_reset_notify.h> 102 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h> 103 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h> 104 #include <sys/scsi/adapters/mpt_sas/mptsas_smhba.h> 105 #include <sys/raidioctl.h> 106 107 #include <sys/fs/dv_node.h> /* devfs_clean */ 108 109 /* 110 * FMA header files 111 */ 112 #include <sys/ddifm.h> 113 #include <sys/fm/protocol.h> 114 #include <sys/fm/util.h> 115 #include <sys/fm/io/ddi.h> 116 117 /* 118 * autoconfiguration data and routines. 119 */ 120 static int mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 121 static int mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd); 122 static int mptsas_power(dev_info_t *dip, int component, int level); 123 124 /* 125 * cb_ops function 126 */ 127 static int mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, 128 cred_t *credp, int *rval); 129 #ifdef __sparc 130 static int mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd); 131 #else /* __sparc */ 132 static int mptsas_quiesce(dev_info_t *devi); 133 #endif /* __sparc */ 134 135 /* 136 * ddi_ufm_ops 137 */ 138 static int mptsas_ufm_fill_image(ddi_ufm_handle_t *ufmh, void *arg, 139 uint_t imgno, ddi_ufm_image_t *img); 140 static int mptsas_ufm_fill_slot(ddi_ufm_handle_t *ufmh, void *arg, 141 uint_t imgno, uint_t slotno, ddi_ufm_slot_t *slot); 142 static int mptsas_ufm_getcaps(ddi_ufm_handle_t *ufmh, void *arg, 143 ddi_ufm_cap_t *caps); 144 145 /* 146 * Resource initialization for hardware 147 */ 148 static void mptsas_setup_cmd_reg(mptsas_t *mpt); 149 static void mptsas_disable_bus_master(mptsas_t *mpt); 150 static void mptsas_hba_fini(mptsas_t *mpt); 151 static void mptsas_cfg_fini(mptsas_t *mptsas_blkp); 152 static int mptsas_hba_setup(mptsas_t *mpt); 153 static void mptsas_hba_teardown(mptsas_t *mpt); 154 static int mptsas_config_space_init(mptsas_t *mpt); 155 static void mptsas_config_space_fini(mptsas_t *mpt); 156 static void mptsas_iport_register(mptsas_t *mpt); 157 static int mptsas_smp_setup(mptsas_t *mpt); 158 static void mptsas_smp_teardown(mptsas_t *mpt); 159 static int mptsas_enc_setup(mptsas_t *mpt); 160 static void mptsas_enc_teardown(mptsas_t *mpt); 161 static int mptsas_cache_create(mptsas_t *mpt); 162 static void mptsas_cache_destroy(mptsas_t *mpt); 163 static int mptsas_alloc_request_frames(mptsas_t *mpt); 164 static int mptsas_alloc_sense_bufs(mptsas_t *mpt); 165 static int mptsas_alloc_reply_frames(mptsas_t *mpt); 166 static int mptsas_alloc_free_queue(mptsas_t *mpt); 167 static int mptsas_alloc_post_queue(mptsas_t *mpt); 168 static void mptsas_alloc_reply_args(mptsas_t *mpt); 169 static int mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd); 170 static void mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd); 171 static int mptsas_init_chip(mptsas_t *mpt, int first_time); 172 static void mptsas_update_hashtab(mptsas_t *mpt); 173 174 /* 175 * SCSA function prototypes 176 */ 177 static int mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt); 178 static int mptsas_scsi_reset(struct scsi_address *ap, int level); 179 static int mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt); 180 static int mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly); 181 static int mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, 182 int tgtonly); 183 static void mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt); 184 static struct scsi_pkt *mptsas_scsi_init_pkt(struct scsi_address *ap, 185 struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen, 186 int tgtlen, int flags, int (*callback)(), caddr_t arg); 187 static void mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt); 188 static void mptsas_scsi_destroy_pkt(struct scsi_address *ap, 189 struct scsi_pkt *pkt); 190 static int mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 191 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 192 static void mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 193 scsi_hba_tran_t *hba_tran, struct scsi_device *sd); 194 static int mptsas_scsi_reset_notify(struct scsi_address *ap, int flag, 195 void (*callback)(caddr_t), caddr_t arg); 196 static int mptsas_get_name(struct scsi_device *sd, char *name, int len); 197 static int mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len); 198 static int mptsas_scsi_quiesce(dev_info_t *dip); 199 static int mptsas_scsi_unquiesce(dev_info_t *dip); 200 static int mptsas_bus_config(dev_info_t *pdip, uint_t flags, 201 ddi_bus_config_op_t op, void *arg, dev_info_t **childp); 202 203 /* 204 * SMP functions 205 */ 206 static int mptsas_smp_start(struct smp_pkt *smp_pkt); 207 208 /* 209 * internal function prototypes. 210 */ 211 static void mptsas_list_add(mptsas_t *mpt); 212 static void mptsas_list_del(mptsas_t *mpt); 213 214 static int mptsas_quiesce_bus(mptsas_t *mpt); 215 static int mptsas_unquiesce_bus(mptsas_t *mpt); 216 217 static int mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size); 218 static void mptsas_free_handshake_msg(mptsas_t *mpt); 219 220 static void mptsas_ncmds_checkdrain(void *arg); 221 222 static int mptsas_prepare_pkt(mptsas_cmd_t *cmd); 223 static int mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *sp); 224 static int mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *sp); 225 static void mptsas_accept_tx_waitq(mptsas_t *mpt); 226 227 static int mptsas_do_detach(dev_info_t *dev); 228 static int mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl); 229 static int mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, 230 struct scsi_pkt *pkt); 231 static int mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp); 232 233 static void mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd); 234 static void mptsas_handle_event(void *args); 235 static int mptsas_handle_event_sync(void *args); 236 static void mptsas_handle_dr(void *args); 237 static void mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node, 238 dev_info_t *pdip); 239 240 static void mptsas_restart_cmd(void *); 241 242 static void mptsas_flush_hba(mptsas_t *mpt); 243 static void mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, 244 uint8_t tasktype); 245 static void mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, 246 uchar_t reason, uint_t stat); 247 248 static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2); 249 static void mptsas_process_intr(mptsas_t *mpt, 250 pMpi2ReplyDescriptorsUnion_t reply_desc_union); 251 static void mptsas_handle_scsi_io_success(mptsas_t *mpt, 252 pMpi2ReplyDescriptorsUnion_t reply_desc); 253 static void mptsas_handle_address_reply(mptsas_t *mpt, 254 pMpi2ReplyDescriptorsUnion_t reply_desc); 255 static int mptsas_wait_intr(mptsas_t *mpt, int polltime); 256 static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, 257 uint32_t *control, pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl); 258 259 static void mptsas_watch(void *arg); 260 static void mptsas_watchsubr(mptsas_t *mpt); 261 static void mptsas_cmd_timeout(mptsas_t *mpt, mptsas_target_t *ptgt); 262 263 static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd); 264 static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply, 265 uint8_t *data, uint32_t request_size, uint32_t reply_size, 266 uint32_t data_size, uint32_t direction, uint8_t *dataout, 267 uint32_t dataout_size, short timeout, int mode); 268 static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl); 269 270 static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, 271 uint32_t unique_id); 272 static void mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd); 273 static int mptsas_post_fw_diag_buffer(mptsas_t *mpt, 274 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code); 275 static int mptsas_release_fw_diag_buffer(mptsas_t *mpt, 276 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code, 277 uint32_t diag_type); 278 static int mptsas_diag_register(mptsas_t *mpt, 279 mptsas_fw_diag_register_t *diag_register, uint32_t *return_code); 280 static int mptsas_diag_unregister(mptsas_t *mpt, 281 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code); 282 static int mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query, 283 uint32_t *return_code); 284 static int mptsas_diag_read_buffer(mptsas_t *mpt, 285 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf, 286 uint32_t *return_code, int ioctl_mode); 287 static int mptsas_diag_release(mptsas_t *mpt, 288 mptsas_fw_diag_release_t *diag_release, uint32_t *return_code); 289 static int mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, 290 uint8_t *diag_action, uint32_t length, uint32_t *return_code, 291 int ioctl_mode); 292 static int mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *data, 293 int mode); 294 295 static int mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd, 296 int cmdlen, int tgtlen, int statuslen, int kf); 297 static void mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd); 298 299 static int mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags); 300 static void mptsas_kmem_cache_destructor(void *buf, void *cdrarg); 301 302 static int mptsas_cache_frames_constructor(void *buf, void *cdrarg, 303 int kmflags); 304 static void mptsas_cache_frames_destructor(void *buf, void *cdrarg); 305 306 static void mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, 307 mptsas_cmd_t *cmd); 308 static void mptsas_check_task_mgt(mptsas_t *mpt, 309 pMpi2SCSIManagementReply_t reply, mptsas_cmd_t *cmd); 310 static int mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap, 311 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp, 312 int *resid); 313 314 static int mptsas_alloc_active_slots(mptsas_t *mpt, int flag); 315 static void mptsas_free_active_slots(mptsas_t *mpt); 316 static int mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd); 317 318 static void mptsas_restart_hba(mptsas_t *mpt); 319 static void mptsas_restart_waitq(mptsas_t *mpt); 320 321 static void mptsas_deliver_doneq_thread(mptsas_t *mpt); 322 static void mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd); 323 static void mptsas_doneq_mv(mptsas_t *mpt, uint64_t t); 324 325 static mptsas_cmd_t *mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t); 326 static void mptsas_doneq_empty(mptsas_t *mpt); 327 static void mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg); 328 329 static mptsas_cmd_t *mptsas_waitq_rm(mptsas_t *mpt); 330 static void mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd); 331 static mptsas_cmd_t *mptsas_tx_waitq_rm(mptsas_t *mpt); 332 static void mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd); 333 334 335 static void mptsas_start_watch_reset_delay(); 336 static void mptsas_setup_bus_reset_delay(mptsas_t *mpt); 337 static void mptsas_watch_reset_delay(void *arg); 338 static int mptsas_watch_reset_delay_subr(mptsas_t *mpt); 339 340 /* 341 * helper functions 342 */ 343 static void mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd); 344 345 static dev_info_t *mptsas_find_child(dev_info_t *pdip, char *name); 346 static dev_info_t *mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy); 347 static dev_info_t *mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, 348 int lun); 349 static mdi_pathinfo_t *mptsas_find_path_addr(dev_info_t *pdip, uint64_t sasaddr, 350 int lun); 351 static mdi_pathinfo_t *mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy); 352 static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn); 353 354 static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, 355 int *lun); 356 static int mptsas_parse_smp_name(char *name, uint64_t *wwn); 357 358 static mptsas_target_t *mptsas_phy_to_tgt(mptsas_t *mpt, 359 mptsas_phymask_t phymask, uint8_t phy); 360 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt, 361 mptsas_phymask_t phymask, uint64_t wwid); 362 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, 363 mptsas_phymask_t phymask, uint64_t wwid); 364 365 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, 366 uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd); 367 368 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address, 369 uint16_t *handle, mptsas_target_t **pptgt); 370 static void mptsas_update_phymask(mptsas_t *mpt); 371 372 static int mptsas_flush_led_status(mptsas_t *mpt, mptsas_enclosure_t *mep, 373 uint16_t idx); 374 static int mptsas_send_sep(mptsas_t *mpt, mptsas_enclosure_t *mep, uint16_t idx, 375 uint32_t *status, uint8_t cmd); 376 static dev_info_t *mptsas_get_dip_from_dev(dev_t dev, 377 mptsas_phymask_t *phymask); 378 static mptsas_target_t *mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, 379 mptsas_phymask_t phymask); 380 381 382 /* 383 * Enumeration / DR functions 384 */ 385 static void mptsas_config_all(dev_info_t *pdip); 386 static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun, 387 dev_info_t **lundip); 388 static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun, 389 dev_info_t **lundip); 390 391 static int mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt); 392 static int mptsas_offline_target(dev_info_t *pdip, char *name); 393 394 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target, 395 dev_info_t **dip); 396 397 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt); 398 static int mptsas_probe_lun(dev_info_t *pdip, int lun, 399 dev_info_t **dip, mptsas_target_t *ptgt); 400 401 static int mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq, 402 dev_info_t **dip, mptsas_target_t *ptgt, int lun); 403 404 static int mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *sd, 405 char *guid, dev_info_t **dip, mptsas_target_t *ptgt, int lun); 406 static int mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *sd, 407 char *guid, dev_info_t **dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, 408 int lun); 409 410 static void mptsas_offline_missed_luns(dev_info_t *pdip, 411 uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt); 412 static int mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip, 413 mdi_pathinfo_t *rpip, uint_t flags); 414 415 static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, 416 dev_info_t **smp_dip); 417 static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 418 uint_t flags); 419 420 static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, 421 int mode, int *rval); 422 static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, 423 int mode, int *rval); 424 static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, 425 int mode, int *rval); 426 static void mptsas_record_event(void *args); 427 static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, 428 int mode); 429 430 mptsas_target_t *mptsas_tgt_alloc(refhash_t *, uint16_t, uint64_t, 431 uint32_t, mptsas_phymask_t, uint8_t); 432 static mptsas_smp_t *mptsas_smp_alloc(mptsas_t *, mptsas_smp_t *); 433 static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 434 dev_info_t **smp_dip); 435 436 /* 437 * Power management functions 438 */ 439 static int mptsas_get_pci_cap(mptsas_t *mpt); 440 static int mptsas_init_pm(mptsas_t *mpt); 441 442 /* 443 * MPT MSI tunable: 444 * 445 * By default MSI is enabled on all supported platforms. 446 */ 447 boolean_t mptsas_enable_msi = B_TRUE; 448 boolean_t mptsas_physical_bind_failed_page_83 = B_FALSE; 449 450 /* 451 * Global switch for use of MPI2.5 FAST PATH. 452 * We don't really know what FAST PATH actually does, so if it is suspected 453 * to cause problems it can be turned off by setting this variable to B_FALSE. 454 */ 455 boolean_t mptsas_use_fastpath = B_TRUE; 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 0 /* flags, set to 0 */ 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 static ddi_ufm_ops_t mptsas_ufm_ops = { 575 NULL, 576 mptsas_ufm_fill_image, 577 mptsas_ufm_fill_slot, 578 mptsas_ufm_getcaps 579 }; 580 581 #define MPTSAS_MOD_STRING "MPTSAS HBA Driver 00.00.00.24" 582 583 static struct modldrv modldrv = { 584 &mod_driverops, /* Type of module. This one is a driver */ 585 MPTSAS_MOD_STRING, /* Name of the module. */ 586 &mptsas_ops, /* driver ops */ 587 }; 588 589 static struct modlinkage modlinkage = { 590 MODREV_1, &modldrv, NULL 591 }; 592 #define TARGET_PROP "target" 593 #define LUN_PROP "lun" 594 #define LUN64_PROP "lun64" 595 #define SAS_PROP "sas-mpt" 596 #define MDI_GUID "wwn" 597 #define NDI_GUID "guid" 598 #define MPTSAS_DEV_GONE "mptsas_dev_gone" 599 600 /* 601 * Local static data 602 */ 603 #if defined(MPTSAS_DEBUG) 604 /* 605 * Flags to indicate which debug messages are to be printed and which go to the 606 * debug log ring buffer. Default is to not print anything, and to log 607 * everything except the watchsubr() output which normally happens every second. 608 */ 609 uint32_t mptsas_debugprt_flags = 0x0; 610 uint32_t mptsas_debuglog_flags = ~(1U << 30); 611 #endif /* defined(MPTSAS_DEBUG) */ 612 uint32_t mptsas_debug_resets = 0; 613 614 static kmutex_t mptsas_global_mutex; 615 static void *mptsas_state; /* soft state ptr */ 616 static krwlock_t mptsas_global_rwlock; 617 618 static kmutex_t mptsas_log_mutex; 619 static char mptsas_log_buf[256]; 620 _NOTE(MUTEX_PROTECTS_DATA(mptsas_log_mutex, mptsas_log_buf)) 621 622 static mptsas_t *mptsas_head, *mptsas_tail; 623 static clock_t mptsas_scsi_watchdog_tick; 624 static clock_t mptsas_tick; 625 static timeout_id_t mptsas_reset_watch; 626 static timeout_id_t mptsas_timeout_id; 627 static int mptsas_timeouts_enabled = 0; 628 629 /* 630 * Default length for extended auto request sense buffers. 631 * All sense buffers need to be under the same alloc because there 632 * is only one common top 32bits (of 64bits) address register. 633 * Most requests only require 32 bytes, but some request >256. 634 * We use rmalloc()/rmfree() on this additional memory to manage the 635 * "extended" requests. 636 */ 637 int mptsas_extreq_sense_bufsize = 256*64; 638 639 /* 640 * We believe that all software resrictions of having to run with DMA 641 * attributes to limit allocation to the first 4G are removed. 642 * However, this flag remains to enable quick switchback should suspicious 643 * problems emerge. 644 * Note that scsi_alloc_consistent_buf() does still adhere to allocating 645 * 32 bit addressable memory, but we can cope if that is changed now. 646 */ 647 int mptsas_use_64bit_msgaddr = 1; 648 649 /* 650 * warlock directives 651 */ 652 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt \ 653 mptsas_cmd NcrTableIndirect buf scsi_cdb scsi_status)) 654 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", smp_pkt)) 655 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address)) 656 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", mptsas_tgt_private)) 657 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_hba_tran::tran_tgt_private)) 658 659 /* 660 * SM - HBA statics 661 */ 662 char *mptsas_driver_rev = MPTSAS_MOD_STRING; 663 664 #ifdef MPTSAS_DEBUG 665 void debug_enter(char *); 666 #endif 667 668 /* 669 * Notes: 670 * - scsi_hba_init(9F) initializes SCSI HBA modules 671 * - must call scsi_hba_fini(9F) if modload() fails 672 */ 673 int 674 _init(void) 675 { 676 int status; 677 /* CONSTCOND */ 678 ASSERT(NO_COMPETING_THREADS); 679 680 NDBG0(("_init")); 681 682 status = ddi_soft_state_init(&mptsas_state, MPTSAS_SIZE, 683 MPTSAS_INITIAL_SOFT_SPACE); 684 if (status != 0) { 685 return (status); 686 } 687 688 if ((status = scsi_hba_init(&modlinkage)) != 0) { 689 ddi_soft_state_fini(&mptsas_state); 690 return (status); 691 } 692 693 mutex_init(&mptsas_global_mutex, NULL, MUTEX_DRIVER, NULL); 694 rw_init(&mptsas_global_rwlock, NULL, RW_DRIVER, NULL); 695 mutex_init(&mptsas_log_mutex, NULL, MUTEX_DRIVER, NULL); 696 697 if ((status = mod_install(&modlinkage)) != 0) { 698 mutex_destroy(&mptsas_log_mutex); 699 rw_destroy(&mptsas_global_rwlock); 700 mutex_destroy(&mptsas_global_mutex); 701 ddi_soft_state_fini(&mptsas_state); 702 scsi_hba_fini(&modlinkage); 703 } 704 705 return (status); 706 } 707 708 /* 709 * Notes: 710 * - scsi_hba_fini(9F) uninitializes SCSI HBA modules 711 */ 712 int 713 _fini(void) 714 { 715 int status; 716 /* CONSTCOND */ 717 ASSERT(NO_COMPETING_THREADS); 718 719 NDBG0(("_fini")); 720 721 if ((status = mod_remove(&modlinkage)) == 0) { 722 ddi_soft_state_fini(&mptsas_state); 723 scsi_hba_fini(&modlinkage); 724 mutex_destroy(&mptsas_global_mutex); 725 rw_destroy(&mptsas_global_rwlock); 726 mutex_destroy(&mptsas_log_mutex); 727 } 728 return (status); 729 } 730 731 /* 732 * The loadable-module _info(9E) entry point 733 */ 734 int 735 _info(struct modinfo *modinfop) 736 { 737 /* CONSTCOND */ 738 ASSERT(NO_COMPETING_THREADS); 739 NDBG0(("mptsas _info")); 740 741 return (mod_info(&modlinkage, modinfop)); 742 } 743 744 static int 745 mptsas_target_eval_devhdl(const void *op, void *arg) 746 { 747 uint16_t dh = *(uint16_t *)arg; 748 const mptsas_target_t *tp = op; 749 750 return ((int)tp->m_devhdl - (int)dh); 751 } 752 753 static int 754 mptsas_target_eval_nowwn(const void *op, void *arg) 755 { 756 uint8_t phy = *(uint8_t *)arg; 757 const mptsas_target_t *tp = op; 758 759 if (tp->m_addr.mta_wwn != 0) 760 return (-1); 761 762 return ((int)tp->m_phynum - (int)phy); 763 } 764 765 static int 766 mptsas_smp_eval_devhdl(const void *op, void *arg) 767 { 768 uint16_t dh = *(uint16_t *)arg; 769 const mptsas_smp_t *sp = op; 770 771 return ((int)sp->m_devhdl - (int)dh); 772 } 773 774 static uint64_t 775 mptsas_target_addr_hash(const void *tp) 776 { 777 const mptsas_target_addr_t *tap = tp; 778 779 return ((tap->mta_wwn & 0xffffffffffffULL) | 780 ((uint64_t)tap->mta_phymask << 48)); 781 } 782 783 static int 784 mptsas_target_addr_cmp(const void *a, const void *b) 785 { 786 const mptsas_target_addr_t *aap = a; 787 const mptsas_target_addr_t *bap = b; 788 789 if (aap->mta_wwn < bap->mta_wwn) 790 return (-1); 791 if (aap->mta_wwn > bap->mta_wwn) 792 return (1); 793 return ((int)bap->mta_phymask - (int)aap->mta_phymask); 794 } 795 796 static uint64_t 797 mptsas_tmp_target_hash(const void *tp) 798 { 799 return ((uint64_t)(uintptr_t)tp); 800 } 801 802 static int 803 mptsas_tmp_target_cmp(const void *a, const void *b) 804 { 805 if (a > b) 806 return (1); 807 if (b < a) 808 return (-1); 809 810 return (0); 811 } 812 813 static void 814 mptsas_target_free(void *op) 815 { 816 kmem_free(op, sizeof (mptsas_target_t)); 817 } 818 819 static void 820 mptsas_smp_free(void *op) 821 { 822 kmem_free(op, sizeof (mptsas_smp_t)); 823 } 824 825 static void 826 mptsas_destroy_hashes(mptsas_t *mpt) 827 { 828 mptsas_target_t *tp; 829 mptsas_smp_t *sp; 830 831 for (tp = refhash_first(mpt->m_targets); tp != NULL; 832 tp = refhash_next(mpt->m_targets, tp)) { 833 refhash_remove(mpt->m_targets, tp); 834 } 835 for (sp = refhash_first(mpt->m_smp_targets); sp != NULL; 836 sp = refhash_next(mpt->m_smp_targets, sp)) { 837 refhash_remove(mpt->m_smp_targets, sp); 838 } 839 refhash_destroy(mpt->m_tmp_targets); 840 refhash_destroy(mpt->m_targets); 841 refhash_destroy(mpt->m_smp_targets); 842 mpt->m_targets = NULL; 843 mpt->m_smp_targets = NULL; 844 } 845 846 static int 847 mptsas_iport_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 848 { 849 dev_info_t *pdip; 850 mptsas_t *mpt; 851 scsi_hba_tran_t *hba_tran; 852 char *iport = NULL; 853 char phymask[MPTSAS_MAX_PHYS]; 854 mptsas_phymask_t phy_mask = 0; 855 int dynamic_port = 0; 856 uint32_t page_address; 857 char initiator_wwnstr[MPTSAS_WWN_STRLEN]; 858 int rval = DDI_FAILURE; 859 int i = 0; 860 uint8_t numphys = 0; 861 uint8_t phy_id; 862 uint8_t phy_port = 0; 863 uint16_t attached_devhdl = 0; 864 uint32_t dev_info; 865 uint64_t attached_sas_wwn; 866 uint16_t dev_hdl; 867 uint16_t pdev_hdl; 868 uint16_t bay_num, enclosure, io_flags; 869 char attached_wwnstr[MPTSAS_WWN_STRLEN]; 870 871 /* CONSTCOND */ 872 ASSERT(NO_COMPETING_THREADS); 873 874 switch (cmd) { 875 case DDI_ATTACH: 876 break; 877 878 case DDI_RESUME: 879 /* 880 * If this a scsi-iport node, nothing to do here. 881 */ 882 return (DDI_SUCCESS); 883 884 default: 885 return (DDI_FAILURE); 886 } 887 888 pdip = ddi_get_parent(dip); 889 890 if ((hba_tran = ndi_flavorv_get(pdip, SCSA_FLAVOR_SCSI_DEVICE)) == 891 NULL) { 892 cmn_err(CE_WARN, "Failed attach iport because fail to " 893 "get tran vector for the HBA node"); 894 return (DDI_FAILURE); 895 } 896 897 mpt = TRAN2MPT(hba_tran); 898 ASSERT(mpt != NULL); 899 if (mpt == NULL) 900 return (DDI_FAILURE); 901 902 if ((hba_tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == 903 NULL) { 904 mptsas_log(mpt, CE_WARN, "Failed attach iport because fail to " 905 "get tran vector for the iport node"); 906 return (DDI_FAILURE); 907 } 908 909 /* 910 * Overwrite parent's tran_hba_private to iport's tran vector 911 */ 912 hba_tran->tran_hba_private = mpt; 913 914 ddi_report_dev(dip); 915 916 /* 917 * Get SAS address for initiator port according dev_handle 918 */ 919 iport = ddi_get_name_addr(dip); 920 if (iport && strncmp(iport, "v0", 2) == 0) { 921 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 922 MPTSAS_VIRTUAL_PORT, 1) != 923 DDI_PROP_SUCCESS) { 924 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, 925 MPTSAS_VIRTUAL_PORT); 926 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 927 "prop update failed"); 928 return (DDI_FAILURE); 929 } 930 return (DDI_SUCCESS); 931 } 932 933 mutex_enter(&mpt->m_mutex); 934 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 935 bzero(phymask, sizeof (phymask)); 936 (void) sprintf(phymask, 937 "%x", mpt->m_phy_info[i].phy_mask); 938 if (strcmp(phymask, iport) == 0) { 939 break; 940 } 941 } 942 943 if (i == MPTSAS_MAX_PHYS) { 944 mptsas_log(mpt, CE_WARN, "Failed attach port %s because port" 945 "seems not exist", iport); 946 mutex_exit(&mpt->m_mutex); 947 return (DDI_FAILURE); 948 } 949 950 phy_mask = mpt->m_phy_info[i].phy_mask; 951 952 if (mpt->m_phy_info[i].port_flags & AUTO_PORT_CONFIGURATION) 953 dynamic_port = 1; 954 else 955 dynamic_port = 0; 956 957 /* 958 * Update PHY info for smhba 959 */ 960 if (mptsas_smhba_phy_init(mpt)) { 961 mutex_exit(&mpt->m_mutex); 962 mptsas_log(mpt, CE_WARN, "mptsas phy update " 963 "failed"); 964 return (DDI_FAILURE); 965 } 966 967 mutex_exit(&mpt->m_mutex); 968 969 numphys = 0; 970 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 971 if ((phy_mask >> i) & 0x01) { 972 numphys++; 973 } 974 } 975 976 bzero(initiator_wwnstr, sizeof (initiator_wwnstr)); 977 (void) sprintf(initiator_wwnstr, "w%016"PRIx64, 978 mpt->un.m_base_wwid); 979 980 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, 981 SCSI_ADDR_PROP_INITIATOR_PORT, initiator_wwnstr) != 982 DDI_PROP_SUCCESS) { 983 (void) ddi_prop_remove(DDI_DEV_T_NONE, 984 dip, SCSI_ADDR_PROP_INITIATOR_PORT); 985 mptsas_log(mpt, CE_WARN, "mptsas Initiator port " 986 "prop update failed"); 987 return (DDI_FAILURE); 988 } 989 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 990 MPTSAS_NUM_PHYS, numphys) != 991 DDI_PROP_SUCCESS) { 992 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, MPTSAS_NUM_PHYS); 993 return (DDI_FAILURE); 994 } 995 996 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 997 "phymask", phy_mask) != 998 DDI_PROP_SUCCESS) { 999 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "phymask"); 1000 mptsas_log(mpt, CE_WARN, "mptsas phy mask " 1001 "prop update failed"); 1002 return (DDI_FAILURE); 1003 } 1004 1005 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 1006 "dynamic-port", dynamic_port) != 1007 DDI_PROP_SUCCESS) { 1008 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "dynamic-port"); 1009 mptsas_log(mpt, CE_WARN, "mptsas dynamic port " 1010 "prop update failed"); 1011 return (DDI_FAILURE); 1012 } 1013 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, 1014 MPTSAS_VIRTUAL_PORT, 0) != 1015 DDI_PROP_SUCCESS) { 1016 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, 1017 MPTSAS_VIRTUAL_PORT); 1018 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 1019 "prop update failed"); 1020 return (DDI_FAILURE); 1021 } 1022 mptsas_smhba_set_all_phy_props(mpt, dip, numphys, phy_mask, 1023 &attached_devhdl); 1024 1025 mutex_enter(&mpt->m_mutex); 1026 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 1027 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)attached_devhdl; 1028 rval = mptsas_get_sas_device_page0(mpt, page_address, &dev_hdl, 1029 &attached_sas_wwn, &dev_info, &phy_port, &phy_id, 1030 &pdev_hdl, &bay_num, &enclosure, &io_flags); 1031 if (rval != DDI_SUCCESS) { 1032 mptsas_log(mpt, CE_WARN, 1033 "Failed to get device page0 for handle:%d", 1034 attached_devhdl); 1035 mutex_exit(&mpt->m_mutex); 1036 return (DDI_FAILURE); 1037 } 1038 1039 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1040 bzero(phymask, sizeof (phymask)); 1041 (void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask); 1042 if (strcmp(phymask, iport) == 0) { 1043 (void) sprintf(&mpt->m_phy_info[i].smhba_info.path[0], 1044 "%x", 1045 mpt->m_phy_info[i].phy_mask); 1046 } 1047 } 1048 mutex_exit(&mpt->m_mutex); 1049 1050 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 1051 (void) sprintf(attached_wwnstr, "w%016"PRIx64, 1052 attached_sas_wwn); 1053 if (ddi_prop_update_string(DDI_DEV_T_NONE, dip, 1054 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 1055 DDI_PROP_SUCCESS) { 1056 (void) ddi_prop_remove(DDI_DEV_T_NONE, 1057 dip, SCSI_ADDR_PROP_ATTACHED_PORT); 1058 return (DDI_FAILURE); 1059 } 1060 1061 /* Create kstats for each phy on this iport */ 1062 1063 mptsas_create_phy_stats(mpt, iport, dip); 1064 1065 /* 1066 * register sas hba iport with mdi (MPxIO/vhci) 1067 */ 1068 if (mdi_phci_register(MDI_HCI_CLASS_SCSI, 1069 dip, 0) == MDI_SUCCESS) { 1070 mpt->m_mpxio_enable = TRUE; 1071 } 1072 return (DDI_SUCCESS); 1073 } 1074 1075 /* 1076 * Notes: 1077 * Set up all device state and allocate data structures, 1078 * mutexes, condition variables, etc. for device operation. 1079 * Add interrupts needed. 1080 * Return DDI_SUCCESS if device is ready, else return DDI_FAILURE. 1081 */ 1082 static int 1083 mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1084 { 1085 mptsas_t *mpt = NULL; 1086 int instance, i, j; 1087 int doneq_thread_num; 1088 char intr_added = 0; 1089 char map_setup = 0; 1090 char config_setup = 0; 1091 char hba_attach_setup = 0; 1092 char smp_attach_setup = 0; 1093 char enc_attach_setup = 0; 1094 char mutex_init_done = 0; 1095 char event_taskq_create = 0; 1096 char dr_taskq_create = 0; 1097 char doneq_thread_create = 0; 1098 char added_watchdog = 0; 1099 scsi_hba_tran_t *hba_tran; 1100 uint_t mem_bar; 1101 int rval = DDI_FAILURE; 1102 1103 /* CONSTCOND */ 1104 ASSERT(NO_COMPETING_THREADS); 1105 1106 if (scsi_hba_iport_unit_address(dip)) { 1107 return (mptsas_iport_attach(dip, cmd)); 1108 } 1109 1110 switch (cmd) { 1111 case DDI_ATTACH: 1112 break; 1113 1114 case DDI_RESUME: 1115 if ((hba_tran = ddi_get_driver_private(dip)) == NULL) 1116 return (DDI_FAILURE); 1117 1118 mpt = TRAN2MPT(hba_tran); 1119 1120 if (!mpt) { 1121 return (DDI_FAILURE); 1122 } 1123 1124 /* 1125 * Reset hardware and softc to "no outstanding commands" 1126 * Note that a check condition can result on first command 1127 * to a target. 1128 */ 1129 mutex_enter(&mpt->m_mutex); 1130 1131 /* 1132 * raise power. 1133 */ 1134 if (mpt->m_options & MPTSAS_OPT_PM) { 1135 mutex_exit(&mpt->m_mutex); 1136 (void) pm_busy_component(dip, 0); 1137 rval = pm_power_has_changed(dip, 0, PM_LEVEL_D0); 1138 if (rval == DDI_SUCCESS) { 1139 mutex_enter(&mpt->m_mutex); 1140 } else { 1141 /* 1142 * The pm_raise_power() call above failed, 1143 * and that can only occur if we were unable 1144 * to reset the hardware. This is probably 1145 * due to unhealty hardware, and because 1146 * important filesystems(such as the root 1147 * filesystem) could be on the attached disks, 1148 * it would not be a good idea to continue, 1149 * as we won't be entirely certain we are 1150 * writing correct data. So we panic() here 1151 * to not only prevent possible data corruption, 1152 * but to give developers or end users a hope 1153 * of identifying and correcting any problems. 1154 */ 1155 fm_panic("mptsas could not reset hardware " 1156 "during resume"); 1157 } 1158 } 1159 1160 mpt->m_suspended = 0; 1161 1162 /* 1163 * Reinitialize ioc 1164 */ 1165 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1166 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) { 1167 mutex_exit(&mpt->m_mutex); 1168 if (mpt->m_options & MPTSAS_OPT_PM) { 1169 (void) pm_idle_component(dip, 0); 1170 } 1171 fm_panic("mptsas init chip fail during resume"); 1172 } 1173 /* 1174 * mptsas_update_driver_data needs interrupts so enable them 1175 * first. 1176 */ 1177 MPTSAS_ENABLE_INTR(mpt); 1178 mptsas_update_driver_data(mpt); 1179 1180 /* start requests, if possible */ 1181 mptsas_restart_hba(mpt); 1182 1183 mutex_exit(&mpt->m_mutex); 1184 1185 /* 1186 * Restart watch thread 1187 */ 1188 mutex_enter(&mptsas_global_mutex); 1189 if (mptsas_timeout_id == 0) { 1190 mptsas_timeout_id = timeout(mptsas_watch, NULL, 1191 mptsas_tick); 1192 mptsas_timeouts_enabled = 1; 1193 } 1194 mutex_exit(&mptsas_global_mutex); 1195 1196 /* report idle status to pm framework */ 1197 if (mpt->m_options & MPTSAS_OPT_PM) { 1198 (void) pm_idle_component(dip, 0); 1199 } 1200 1201 return (DDI_SUCCESS); 1202 1203 default: 1204 return (DDI_FAILURE); 1205 1206 } 1207 1208 instance = ddi_get_instance(dip); 1209 1210 /* 1211 * Allocate softc information. 1212 */ 1213 if (ddi_soft_state_zalloc(mptsas_state, instance) != DDI_SUCCESS) { 1214 mptsas_log(NULL, CE_WARN, 1215 "mptsas%d: cannot allocate soft state", instance); 1216 goto fail; 1217 } 1218 1219 mpt = ddi_get_soft_state(mptsas_state, instance); 1220 1221 if (mpt == NULL) { 1222 mptsas_log(NULL, CE_WARN, 1223 "mptsas%d: cannot get soft state", instance); 1224 goto fail; 1225 } 1226 1227 /* Indicate that we are 'sizeof (scsi_*(9S))' clean. */ 1228 scsi_size_clean(dip); 1229 1230 mpt->m_dip = dip; 1231 mpt->m_instance = instance; 1232 1233 /* Make a per-instance copy of the structures */ 1234 mpt->m_io_dma_attr = mptsas_dma_attrs64; 1235 if (mptsas_use_64bit_msgaddr) { 1236 mpt->m_msg_dma_attr = mptsas_dma_attrs64; 1237 } else { 1238 mpt->m_msg_dma_attr = mptsas_dma_attrs; 1239 } 1240 mpt->m_reg_acc_attr = mptsas_dev_attr; 1241 mpt->m_dev_acc_attr = mptsas_dev_attr; 1242 1243 /* 1244 * Size of individual request sense buffer 1245 */ 1246 mpt->m_req_sense_size = EXTCMDS_STATUS_SIZE; 1247 1248 /* 1249 * Initialize FMA 1250 */ 1251 mpt->m_fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, mpt->m_dip, 1252 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable", 1253 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE | 1254 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE); 1255 1256 mptsas_fm_init(mpt); 1257 1258 /* 1259 * Initialize us with the UFM subsystem 1260 */ 1261 if (ddi_ufm_init(dip, DDI_UFM_CURRENT_VERSION, &mptsas_ufm_ops, 1262 &mpt->m_ufmh, mpt) != 0) { 1263 mptsas_log(mpt, CE_WARN, "failed to initialize UFM subsystem"); 1264 goto fail; 1265 } 1266 1267 if (mptsas_alloc_handshake_msg(mpt, 1268 sizeof (Mpi2SCSITaskManagementRequest_t)) == DDI_FAILURE) { 1269 mptsas_log(mpt, CE_WARN, "cannot initialize handshake msg."); 1270 goto fail; 1271 } 1272 1273 /* 1274 * Setup configuration space 1275 */ 1276 if (mptsas_config_space_init(mpt) == FALSE) { 1277 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init failed"); 1278 goto fail; 1279 } 1280 config_setup++; 1281 1282 mem_bar = mpt->m_mem_bar; 1283 if (ddi_regs_map_setup(dip, mem_bar, (caddr_t *)&mpt->m_reg, 1284 0, 0, &mpt->m_reg_acc_attr, &mpt->m_datap) != DDI_SUCCESS) { 1285 mptsas_log(mpt, CE_WARN, "map setup failed"); 1286 goto fail; 1287 } 1288 map_setup++; 1289 1290 /* 1291 * A taskq is created for dealing with the event handler 1292 */ 1293 if ((mpt->m_event_taskq = ddi_taskq_create(dip, "mptsas_event_taskq", 1294 1, TASKQ_DEFAULTPRI, 0)) == NULL) { 1295 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create failed"); 1296 goto fail; 1297 } 1298 event_taskq_create++; 1299 1300 /* 1301 * A taskq is created for dealing with dr events 1302 */ 1303 if ((mpt->m_dr_taskq = ddi_taskq_create(dip, 1304 "mptsas_dr_taskq", 1305 1, TASKQ_DEFAULTPRI, 0)) == NULL) { 1306 mptsas_log(mpt, CE_NOTE, "ddi_taskq_create for discovery " 1307 "failed"); 1308 goto fail; 1309 } 1310 dr_taskq_create++; 1311 1312 mpt->m_doneq_thread_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1313 0, "mptsas_doneq_thread_threshold_prop", 10); 1314 mpt->m_doneq_length_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1315 0, "mptsas_doneq_length_threshold_prop", 8); 1316 mpt->m_doneq_thread_n = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1317 0, "mptsas_doneq_thread_n_prop", 8); 1318 1319 if (mpt->m_doneq_thread_n) { 1320 cv_init(&mpt->m_doneq_thread_cv, NULL, CV_DRIVER, NULL); 1321 mutex_init(&mpt->m_doneq_mutex, NULL, MUTEX_DRIVER, NULL); 1322 1323 mutex_enter(&mpt->m_doneq_mutex); 1324 mpt->m_doneq_thread_id = 1325 kmem_zalloc(sizeof (mptsas_doneq_thread_list_t) 1326 * mpt->m_doneq_thread_n, KM_SLEEP); 1327 1328 for (j = 0; j < mpt->m_doneq_thread_n; j++) { 1329 cv_init(&mpt->m_doneq_thread_id[j].cv, NULL, 1330 CV_DRIVER, NULL); 1331 mutex_init(&mpt->m_doneq_thread_id[j].mutex, NULL, 1332 MUTEX_DRIVER, NULL); 1333 mutex_enter(&mpt->m_doneq_thread_id[j].mutex); 1334 mpt->m_doneq_thread_id[j].flag |= 1335 MPTSAS_DONEQ_THREAD_ACTIVE; 1336 mpt->m_doneq_thread_id[j].arg.mpt = mpt; 1337 mpt->m_doneq_thread_id[j].arg.t = j; 1338 mpt->m_doneq_thread_id[j].threadp = 1339 thread_create(NULL, 0, mptsas_doneq_thread, 1340 &mpt->m_doneq_thread_id[j].arg, 1341 0, &p0, TS_RUN, minclsyspri); 1342 mpt->m_doneq_thread_id[j].donetail = 1343 &mpt->m_doneq_thread_id[j].doneq; 1344 mutex_exit(&mpt->m_doneq_thread_id[j].mutex); 1345 } 1346 mutex_exit(&mpt->m_doneq_mutex); 1347 doneq_thread_create++; 1348 } 1349 1350 /* 1351 * Disable hardware interrupt since we're not ready to 1352 * handle it yet. 1353 */ 1354 MPTSAS_DISABLE_INTR(mpt); 1355 if (mptsas_register_intrs(mpt) == FALSE) 1356 goto fail; 1357 intr_added++; 1358 1359 /* Initialize mutex used in interrupt handler */ 1360 mutex_init(&mpt->m_mutex, NULL, MUTEX_DRIVER, 1361 DDI_INTR_PRI(mpt->m_intr_pri)); 1362 mutex_init(&mpt->m_passthru_mutex, NULL, MUTEX_DRIVER, NULL); 1363 mutex_init(&mpt->m_tx_waitq_mutex, NULL, MUTEX_DRIVER, 1364 DDI_INTR_PRI(mpt->m_intr_pri)); 1365 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1366 mutex_init(&mpt->m_phy_info[i].smhba_info.phy_mutex, 1367 NULL, MUTEX_DRIVER, 1368 DDI_INTR_PRI(mpt->m_intr_pri)); 1369 } 1370 1371 cv_init(&mpt->m_cv, NULL, CV_DRIVER, NULL); 1372 cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL); 1373 cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL); 1374 cv_init(&mpt->m_config_cv, NULL, CV_DRIVER, NULL); 1375 cv_init(&mpt->m_fw_diag_cv, NULL, CV_DRIVER, NULL); 1376 cv_init(&mpt->m_extreq_sense_refcount_cv, NULL, CV_DRIVER, NULL); 1377 mutex_init_done++; 1378 1379 mutex_enter(&mpt->m_mutex); 1380 /* 1381 * Initialize power management component 1382 */ 1383 if (mpt->m_options & MPTSAS_OPT_PM) { 1384 if (mptsas_init_pm(mpt)) { 1385 mutex_exit(&mpt->m_mutex); 1386 mptsas_log(mpt, CE_WARN, "mptsas pm initialization " 1387 "failed"); 1388 goto fail; 1389 } 1390 } 1391 1392 /* 1393 * Initialize chip using Message Unit Reset, if allowed 1394 */ 1395 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1396 if (mptsas_init_chip(mpt, TRUE) == DDI_FAILURE) { 1397 mutex_exit(&mpt->m_mutex); 1398 mptsas_log(mpt, CE_WARN, "mptsas chip initialization failed"); 1399 goto fail; 1400 } 1401 1402 mpt->m_targets = refhash_create(MPTSAS_TARGET_BUCKET_COUNT, 1403 mptsas_target_addr_hash, mptsas_target_addr_cmp, 1404 mptsas_target_free, sizeof (mptsas_target_t), 1405 offsetof(mptsas_target_t, m_link), 1406 offsetof(mptsas_target_t, m_addr), KM_SLEEP); 1407 1408 /* 1409 * The refhash for temporary targets uses the address of the target 1410 * struct itself as tag, so the tag offset is 0. See the implementation 1411 * of mptsas_tmp_target_hash() and mptsas_tmp_target_cmp(). 1412 */ 1413 mpt->m_tmp_targets = refhash_create(MPTSAS_TMP_TARGET_BUCKET_COUNT, 1414 mptsas_tmp_target_hash, mptsas_tmp_target_cmp, 1415 mptsas_target_free, sizeof (mptsas_target_t), 1416 offsetof(mptsas_target_t, m_link), 0, KM_SLEEP); 1417 1418 /* 1419 * Fill in the phy_info structure and get the base WWID 1420 */ 1421 if (mptsas_get_manufacture_page5(mpt) == DDI_FAILURE) { 1422 mptsas_log(mpt, CE_WARN, 1423 "mptsas_get_manufacture_page5 failed!"); 1424 goto fail; 1425 } 1426 1427 if (mptsas_get_sas_io_unit_page_hndshk(mpt)) { 1428 mptsas_log(mpt, CE_WARN, 1429 "mptsas_get_sas_io_unit_page_hndshk failed!"); 1430 goto fail; 1431 } 1432 1433 if (mptsas_get_manufacture_page0(mpt) == DDI_FAILURE) { 1434 mptsas_log(mpt, CE_WARN, 1435 "mptsas_get_manufacture_page0 failed!"); 1436 goto fail; 1437 } 1438 1439 mutex_exit(&mpt->m_mutex); 1440 1441 /* 1442 * Register the iport for multiple port HBA 1443 */ 1444 mptsas_iport_register(mpt); 1445 1446 /* 1447 * initialize SCSI HBA transport structure 1448 */ 1449 if (mptsas_hba_setup(mpt) == FALSE) 1450 goto fail; 1451 hba_attach_setup++; 1452 1453 if (mptsas_smp_setup(mpt) == FALSE) 1454 goto fail; 1455 smp_attach_setup++; 1456 1457 if (mptsas_enc_setup(mpt) == FALSE) 1458 goto fail; 1459 enc_attach_setup++; 1460 1461 if (mptsas_cache_create(mpt) == FALSE) 1462 goto fail; 1463 1464 mpt->m_scsi_reset_delay = ddi_prop_get_int(DDI_DEV_T_ANY, 1465 dip, 0, "scsi-reset-delay", SCSI_DEFAULT_RESET_DELAY); 1466 if (mpt->m_scsi_reset_delay == 0) { 1467 mptsas_log(mpt, CE_NOTE, 1468 "scsi_reset_delay of 0 is not recommended," 1469 " resetting to SCSI_DEFAULT_RESET_DELAY\n"); 1470 mpt->m_scsi_reset_delay = SCSI_DEFAULT_RESET_DELAY; 1471 } 1472 1473 /* 1474 * Initialize the wait and done FIFO queue 1475 */ 1476 mpt->m_donetail = &mpt->m_doneq; 1477 mpt->m_waitqtail = &mpt->m_waitq; 1478 mpt->m_tx_waitqtail = &mpt->m_tx_waitq; 1479 mpt->m_tx_draining = 0; 1480 1481 /* 1482 * ioc cmd queue initialize 1483 */ 1484 mpt->m_ioc_event_cmdtail = &mpt->m_ioc_event_cmdq; 1485 mpt->m_dev_handle = 0xFFFF; 1486 1487 MPTSAS_ENABLE_INTR(mpt); 1488 1489 /* 1490 * enable event notification 1491 */ 1492 mutex_enter(&mpt->m_mutex); 1493 if (mptsas_ioc_enable_event_notification(mpt)) { 1494 mutex_exit(&mpt->m_mutex); 1495 goto fail; 1496 } 1497 mutex_exit(&mpt->m_mutex); 1498 1499 /* 1500 * used for mptsas_watch 1501 */ 1502 mptsas_list_add(mpt); 1503 1504 mutex_enter(&mptsas_global_mutex); 1505 if (mptsas_timeouts_enabled == 0) { 1506 mptsas_scsi_watchdog_tick = ddi_prop_get_int(DDI_DEV_T_ANY, 1507 dip, 0, "scsi-watchdog-tick", DEFAULT_WD_TICK); 1508 1509 mptsas_tick = mptsas_scsi_watchdog_tick * 1510 drv_usectohz((clock_t)1000000); 1511 1512 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick); 1513 mptsas_timeouts_enabled = 1; 1514 } 1515 mutex_exit(&mptsas_global_mutex); 1516 added_watchdog++; 1517 1518 /* 1519 * Initialize PHY info for smhba. 1520 * This requires watchdog to be enabled otherwise if interrupts 1521 * don't work the system will hang. 1522 */ 1523 if (mptsas_smhba_setup(mpt)) { 1524 mptsas_log(mpt, CE_WARN, "mptsas phy initialization " 1525 "failed"); 1526 goto fail; 1527 } 1528 1529 /* Check all dma handles allocated in attach */ 1530 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) 1531 != DDI_SUCCESS) || 1532 (mptsas_check_dma_handle(mpt->m_dma_req_sense_hdl) 1533 != DDI_SUCCESS) || 1534 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) 1535 != DDI_SUCCESS) || 1536 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) 1537 != DDI_SUCCESS) || 1538 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) 1539 != DDI_SUCCESS) || 1540 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) 1541 != DDI_SUCCESS)) { 1542 goto fail; 1543 } 1544 1545 /* Check all acc handles allocated in attach */ 1546 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) || 1547 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) 1548 != DDI_SUCCESS) || 1549 (mptsas_check_acc_handle(mpt->m_acc_req_sense_hdl) 1550 != DDI_SUCCESS) || 1551 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) 1552 != DDI_SUCCESS) || 1553 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) 1554 != DDI_SUCCESS) || 1555 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) 1556 != DDI_SUCCESS) || 1557 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) 1558 != DDI_SUCCESS) || 1559 (mptsas_check_acc_handle(mpt->m_config_handle) 1560 != DDI_SUCCESS)) { 1561 goto fail; 1562 } 1563 1564 /* 1565 * After this point, we are not going to fail the attach. 1566 */ 1567 1568 /* Let the UFM susbsystem know we're ready to receive callbacks */ 1569 ddi_ufm_update(mpt->m_ufmh); 1570 1571 /* Print message of HBA present */ 1572 ddi_report_dev(dip); 1573 1574 /* report idle status to pm framework */ 1575 if (mpt->m_options & MPTSAS_OPT_PM) { 1576 (void) pm_idle_component(dip, 0); 1577 } 1578 1579 return (DDI_SUCCESS); 1580 1581 fail: 1582 mptsas_log(mpt, CE_WARN, "attach failed"); 1583 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 1584 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 1585 if (mpt) { 1586 /* deallocate in reverse order */ 1587 if (added_watchdog) { 1588 mptsas_list_del(mpt); 1589 mutex_enter(&mptsas_global_mutex); 1590 1591 if (mptsas_timeout_id && (mptsas_head == NULL)) { 1592 timeout_id_t tid = mptsas_timeout_id; 1593 mptsas_timeouts_enabled = 0; 1594 mptsas_timeout_id = 0; 1595 mutex_exit(&mptsas_global_mutex); 1596 (void) untimeout(tid); 1597 mutex_enter(&mptsas_global_mutex); 1598 } 1599 mutex_exit(&mptsas_global_mutex); 1600 } 1601 1602 mptsas_cache_destroy(mpt); 1603 1604 if (smp_attach_setup) { 1605 mptsas_smp_teardown(mpt); 1606 } 1607 if (enc_attach_setup) { 1608 mptsas_enc_teardown(mpt); 1609 } 1610 if (hba_attach_setup) { 1611 mptsas_hba_teardown(mpt); 1612 } 1613 1614 if (mpt->m_tmp_targets) 1615 refhash_destroy(mpt->m_tmp_targets); 1616 if (mpt->m_targets) 1617 refhash_destroy(mpt->m_targets); 1618 if (mpt->m_smp_targets) 1619 refhash_destroy(mpt->m_smp_targets); 1620 1621 if (mpt->m_active) { 1622 mptsas_free_active_slots(mpt); 1623 } 1624 if (intr_added) { 1625 mptsas_unregister_intrs(mpt); 1626 } 1627 1628 if (doneq_thread_create) { 1629 mutex_enter(&mpt->m_doneq_mutex); 1630 doneq_thread_num = mpt->m_doneq_thread_n; 1631 for (j = 0; j < mpt->m_doneq_thread_n; j++) { 1632 mutex_enter(&mpt->m_doneq_thread_id[j].mutex); 1633 mpt->m_doneq_thread_id[j].flag &= 1634 (~MPTSAS_DONEQ_THREAD_ACTIVE); 1635 cv_signal(&mpt->m_doneq_thread_id[j].cv); 1636 mutex_exit(&mpt->m_doneq_thread_id[j].mutex); 1637 } 1638 while (mpt->m_doneq_thread_n) { 1639 cv_wait(&mpt->m_doneq_thread_cv, 1640 &mpt->m_doneq_mutex); 1641 } 1642 for (j = 0; j < doneq_thread_num; j++) { 1643 cv_destroy(&mpt->m_doneq_thread_id[j].cv); 1644 mutex_destroy(&mpt->m_doneq_thread_id[j].mutex); 1645 } 1646 kmem_free(mpt->m_doneq_thread_id, 1647 sizeof (mptsas_doneq_thread_list_t) 1648 * doneq_thread_num); 1649 mutex_exit(&mpt->m_doneq_mutex); 1650 cv_destroy(&mpt->m_doneq_thread_cv); 1651 mutex_destroy(&mpt->m_doneq_mutex); 1652 } 1653 if (event_taskq_create) { 1654 ddi_taskq_destroy(mpt->m_event_taskq); 1655 } 1656 if (dr_taskq_create) { 1657 ddi_taskq_destroy(mpt->m_dr_taskq); 1658 } 1659 if (mutex_init_done) { 1660 mutex_destroy(&mpt->m_tx_waitq_mutex); 1661 mutex_destroy(&mpt->m_passthru_mutex); 1662 mutex_destroy(&mpt->m_mutex); 1663 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 1664 mutex_destroy( 1665 &mpt->m_phy_info[i].smhba_info.phy_mutex); 1666 } 1667 cv_destroy(&mpt->m_cv); 1668 cv_destroy(&mpt->m_passthru_cv); 1669 cv_destroy(&mpt->m_fw_cv); 1670 cv_destroy(&mpt->m_config_cv); 1671 cv_destroy(&mpt->m_fw_diag_cv); 1672 cv_destroy(&mpt->m_extreq_sense_refcount_cv); 1673 } 1674 1675 if (map_setup) { 1676 mptsas_cfg_fini(mpt); 1677 } 1678 if (config_setup) { 1679 mptsas_config_space_fini(mpt); 1680 } 1681 mptsas_free_handshake_msg(mpt); 1682 mptsas_hba_fini(mpt); 1683 1684 mptsas_fm_fini(mpt); 1685 ddi_soft_state_free(mptsas_state, instance); 1686 ddi_prop_remove_all(dip); 1687 } 1688 return (DDI_FAILURE); 1689 } 1690 1691 static int 1692 mptsas_suspend(dev_info_t *devi) 1693 { 1694 mptsas_t *mpt, *g; 1695 scsi_hba_tran_t *tran; 1696 1697 if (scsi_hba_iport_unit_address(devi)) { 1698 return (DDI_SUCCESS); 1699 } 1700 1701 if ((tran = ddi_get_driver_private(devi)) == NULL) 1702 return (DDI_SUCCESS); 1703 1704 mpt = TRAN2MPT(tran); 1705 if (!mpt) { 1706 return (DDI_SUCCESS); 1707 } 1708 1709 mutex_enter(&mpt->m_mutex); 1710 1711 if (mpt->m_suspended++) { 1712 mutex_exit(&mpt->m_mutex); 1713 return (DDI_SUCCESS); 1714 } 1715 1716 /* 1717 * Cancel timeout threads for this mpt 1718 */ 1719 if (mpt->m_quiesce_timeid) { 1720 timeout_id_t tid = mpt->m_quiesce_timeid; 1721 mpt->m_quiesce_timeid = 0; 1722 mutex_exit(&mpt->m_mutex); 1723 (void) untimeout(tid); 1724 mutex_enter(&mpt->m_mutex); 1725 } 1726 1727 if (mpt->m_restart_cmd_timeid) { 1728 timeout_id_t tid = mpt->m_restart_cmd_timeid; 1729 mpt->m_restart_cmd_timeid = 0; 1730 mutex_exit(&mpt->m_mutex); 1731 (void) untimeout(tid); 1732 mutex_enter(&mpt->m_mutex); 1733 } 1734 1735 mutex_exit(&mpt->m_mutex); 1736 1737 (void) pm_idle_component(mpt->m_dip, 0); 1738 1739 /* 1740 * Cancel watch threads if all mpts suspended 1741 */ 1742 rw_enter(&mptsas_global_rwlock, RW_WRITER); 1743 for (g = mptsas_head; g != NULL; g = g->m_next) { 1744 if (!g->m_suspended) 1745 break; 1746 } 1747 rw_exit(&mptsas_global_rwlock); 1748 1749 mutex_enter(&mptsas_global_mutex); 1750 if (g == NULL) { 1751 timeout_id_t tid; 1752 1753 mptsas_timeouts_enabled = 0; 1754 if (mptsas_timeout_id) { 1755 tid = mptsas_timeout_id; 1756 mptsas_timeout_id = 0; 1757 mutex_exit(&mptsas_global_mutex); 1758 (void) untimeout(tid); 1759 mutex_enter(&mptsas_global_mutex); 1760 } 1761 if (mptsas_reset_watch) { 1762 tid = mptsas_reset_watch; 1763 mptsas_reset_watch = 0; 1764 mutex_exit(&mptsas_global_mutex); 1765 (void) untimeout(tid); 1766 mutex_enter(&mptsas_global_mutex); 1767 } 1768 } 1769 mutex_exit(&mptsas_global_mutex); 1770 1771 mutex_enter(&mpt->m_mutex); 1772 1773 /* 1774 * If this mpt is not in full power(PM_LEVEL_D0), just return. 1775 */ 1776 if ((mpt->m_options & MPTSAS_OPT_PM) && 1777 (mpt->m_power_level != PM_LEVEL_D0)) { 1778 mutex_exit(&mpt->m_mutex); 1779 return (DDI_SUCCESS); 1780 } 1781 1782 /* Disable HBA interrupts in hardware */ 1783 MPTSAS_DISABLE_INTR(mpt); 1784 /* 1785 * Send RAID action system shutdown to sync IR 1786 */ 1787 mptsas_raid_action_system_shutdown(mpt); 1788 1789 mutex_exit(&mpt->m_mutex); 1790 1791 /* drain the taskq */ 1792 ddi_taskq_wait(mpt->m_event_taskq); 1793 ddi_taskq_wait(mpt->m_dr_taskq); 1794 1795 return (DDI_SUCCESS); 1796 } 1797 1798 #ifdef __sparc 1799 /*ARGSUSED*/ 1800 static int 1801 mptsas_reset(dev_info_t *devi, ddi_reset_cmd_t cmd) 1802 { 1803 mptsas_t *mpt; 1804 scsi_hba_tran_t *tran; 1805 1806 /* 1807 * If this call is for iport, just return. 1808 */ 1809 if (scsi_hba_iport_unit_address(devi)) 1810 return (DDI_SUCCESS); 1811 1812 if ((tran = ddi_get_driver_private(devi)) == NULL) 1813 return (DDI_SUCCESS); 1814 1815 if ((mpt = TRAN2MPT(tran)) == NULL) 1816 return (DDI_SUCCESS); 1817 1818 /* 1819 * Send RAID action system shutdown to sync IR. Disable HBA 1820 * interrupts in hardware first. 1821 */ 1822 MPTSAS_DISABLE_INTR(mpt); 1823 mptsas_raid_action_system_shutdown(mpt); 1824 1825 return (DDI_SUCCESS); 1826 } 1827 #else /* __sparc */ 1828 /* 1829 * quiesce(9E) entry point. 1830 * 1831 * This function is called when the system is single-threaded at high 1832 * PIL with preemption disabled. Therefore, this function must not be 1833 * blocked. 1834 * 1835 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 1836 * DDI_FAILURE indicates an error condition and should almost never happen. 1837 */ 1838 static int 1839 mptsas_quiesce(dev_info_t *devi) 1840 { 1841 mptsas_t *mpt; 1842 scsi_hba_tran_t *tran; 1843 1844 /* 1845 * If this call is for iport, just return. 1846 */ 1847 if (scsi_hba_iport_unit_address(devi)) 1848 return (DDI_SUCCESS); 1849 1850 if ((tran = ddi_get_driver_private(devi)) == NULL) 1851 return (DDI_SUCCESS); 1852 1853 if ((mpt = TRAN2MPT(tran)) == NULL) 1854 return (DDI_SUCCESS); 1855 1856 /* Disable HBA interrupts in hardware */ 1857 MPTSAS_DISABLE_INTR(mpt); 1858 /* Send RAID action system shutdonw to sync IR */ 1859 mptsas_raid_action_system_shutdown(mpt); 1860 1861 return (DDI_SUCCESS); 1862 } 1863 #endif /* __sparc */ 1864 1865 /* 1866 * detach(9E). Remove all device allocations and system resources; 1867 * disable device interrupts. 1868 * Return DDI_SUCCESS if done; DDI_FAILURE if there's a problem. 1869 */ 1870 static int 1871 mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 1872 { 1873 /* CONSTCOND */ 1874 ASSERT(NO_COMPETING_THREADS); 1875 NDBG0(("mptsas_detach: dip=0x%p cmd=0x%p", (void *)devi, (void *)cmd)); 1876 1877 switch (cmd) { 1878 case DDI_DETACH: 1879 return (mptsas_do_detach(devi)); 1880 1881 case DDI_SUSPEND: 1882 return (mptsas_suspend(devi)); 1883 1884 default: 1885 return (DDI_FAILURE); 1886 } 1887 /* NOTREACHED */ 1888 } 1889 1890 static int 1891 mptsas_do_detach(dev_info_t *dip) 1892 { 1893 mptsas_t *mpt; 1894 scsi_hba_tran_t *tran; 1895 mdi_pathinfo_t *pip = NULL; 1896 int i; 1897 int doneq_thread_num = 0; 1898 1899 NDBG0(("mptsas_do_detach: dip=0x%p", (void *)dip)); 1900 1901 if ((tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == NULL) 1902 return (DDI_FAILURE); 1903 1904 mpt = TRAN2MPT(tran); 1905 if (!mpt) { 1906 return (DDI_FAILURE); 1907 } 1908 1909 ddi_ufm_fini(mpt->m_ufmh); 1910 1911 /* 1912 * Still have pathinfo child, should not detach mpt driver 1913 */ 1914 if (scsi_hba_iport_unit_address(dip)) { 1915 if (mpt->m_mpxio_enable) { 1916 /* 1917 * MPxIO enabled for the iport 1918 */ 1919 ndi_devi_enter(scsi_vhci_dip); 1920 ndi_devi_enter(dip); 1921 while ((pip = mdi_get_next_client_path(dip, NULL)) != 1922 NULL) { 1923 if (mdi_pi_free(pip, 0) == MDI_SUCCESS) { 1924 continue; 1925 } 1926 ndi_devi_exit(dip); 1927 ndi_devi_exit(scsi_vhci_dip); 1928 NDBG12(("detach failed because of " 1929 "outstanding path info")); 1930 return (DDI_FAILURE); 1931 } 1932 ndi_devi_exit(dip); 1933 ndi_devi_exit(scsi_vhci_dip); 1934 (void) mdi_phci_unregister(dip, 0); 1935 } 1936 1937 ddi_prop_remove_all(dip); 1938 1939 return (DDI_SUCCESS); 1940 } 1941 1942 /* Make sure power level is D0 before accessing registers */ 1943 if (mpt->m_options & MPTSAS_OPT_PM) { 1944 (void) pm_busy_component(dip, 0); 1945 if (mpt->m_power_level != PM_LEVEL_D0) { 1946 if (pm_raise_power(dip, 0, PM_LEVEL_D0) != 1947 DDI_SUCCESS) { 1948 mptsas_log(mpt, CE_WARN, 1949 "mptsas%d: Raise power request failed.", 1950 mpt->m_instance); 1951 (void) pm_idle_component(dip, 0); 1952 return (DDI_FAILURE); 1953 } 1954 } 1955 } 1956 1957 /* 1958 * Send RAID action system shutdown to sync IR. After action, send a 1959 * Message Unit Reset. Since after that DMA resource will be freed, 1960 * set ioc to READY state will avoid HBA initiated DMA operation. 1961 */ 1962 mutex_enter(&mpt->m_mutex); 1963 MPTSAS_DISABLE_INTR(mpt); 1964 mptsas_raid_action_system_shutdown(mpt); 1965 mpt->m_softstate |= MPTSAS_SS_MSG_UNIT_RESET; 1966 (void) mptsas_ioc_reset(mpt, FALSE); 1967 mutex_exit(&mpt->m_mutex); 1968 mptsas_rem_intrs(mpt); 1969 ddi_taskq_destroy(mpt->m_event_taskq); 1970 ddi_taskq_destroy(mpt->m_dr_taskq); 1971 1972 if (mpt->m_doneq_thread_n) { 1973 mutex_enter(&mpt->m_doneq_mutex); 1974 doneq_thread_num = mpt->m_doneq_thread_n; 1975 for (i = 0; i < mpt->m_doneq_thread_n; i++) { 1976 mutex_enter(&mpt->m_doneq_thread_id[i].mutex); 1977 mpt->m_doneq_thread_id[i].flag &= 1978 (~MPTSAS_DONEQ_THREAD_ACTIVE); 1979 cv_signal(&mpt->m_doneq_thread_id[i].cv); 1980 mutex_exit(&mpt->m_doneq_thread_id[i].mutex); 1981 } 1982 while (mpt->m_doneq_thread_n) { 1983 cv_wait(&mpt->m_doneq_thread_cv, 1984 &mpt->m_doneq_mutex); 1985 } 1986 for (i = 0; i < doneq_thread_num; i++) { 1987 cv_destroy(&mpt->m_doneq_thread_id[i].cv); 1988 mutex_destroy(&mpt->m_doneq_thread_id[i].mutex); 1989 } 1990 kmem_free(mpt->m_doneq_thread_id, 1991 sizeof (mptsas_doneq_thread_list_t) 1992 * doneq_thread_num); 1993 mutex_exit(&mpt->m_doneq_mutex); 1994 cv_destroy(&mpt->m_doneq_thread_cv); 1995 mutex_destroy(&mpt->m_doneq_mutex); 1996 } 1997 1998 scsi_hba_reset_notify_tear_down(mpt->m_reset_notify_listf); 1999 2000 mptsas_list_del(mpt); 2001 2002 /* 2003 * Cancel timeout threads for this mpt 2004 */ 2005 mutex_enter(&mpt->m_mutex); 2006 if (mpt->m_quiesce_timeid) { 2007 timeout_id_t tid = mpt->m_quiesce_timeid; 2008 mpt->m_quiesce_timeid = 0; 2009 mutex_exit(&mpt->m_mutex); 2010 (void) untimeout(tid); 2011 mutex_enter(&mpt->m_mutex); 2012 } 2013 2014 if (mpt->m_restart_cmd_timeid) { 2015 timeout_id_t tid = mpt->m_restart_cmd_timeid; 2016 mpt->m_restart_cmd_timeid = 0; 2017 mutex_exit(&mpt->m_mutex); 2018 (void) untimeout(tid); 2019 mutex_enter(&mpt->m_mutex); 2020 } 2021 2022 mutex_exit(&mpt->m_mutex); 2023 2024 /* 2025 * last mpt? ... if active, CANCEL watch threads. 2026 */ 2027 mutex_enter(&mptsas_global_mutex); 2028 if (mptsas_head == NULL) { 2029 timeout_id_t tid; 2030 /* 2031 * Clear mptsas_timeouts_enable so that the watch thread 2032 * gets restarted on DDI_ATTACH 2033 */ 2034 mptsas_timeouts_enabled = 0; 2035 if (mptsas_timeout_id) { 2036 tid = mptsas_timeout_id; 2037 mptsas_timeout_id = 0; 2038 mutex_exit(&mptsas_global_mutex); 2039 (void) untimeout(tid); 2040 mutex_enter(&mptsas_global_mutex); 2041 } 2042 if (mptsas_reset_watch) { 2043 tid = mptsas_reset_watch; 2044 mptsas_reset_watch = 0; 2045 mutex_exit(&mptsas_global_mutex); 2046 (void) untimeout(tid); 2047 mutex_enter(&mptsas_global_mutex); 2048 } 2049 } 2050 mutex_exit(&mptsas_global_mutex); 2051 2052 /* 2053 * Delete Phy stats 2054 */ 2055 mptsas_destroy_phy_stats(mpt); 2056 2057 mptsas_destroy_hashes(mpt); 2058 2059 /* 2060 * Delete nt_active. 2061 */ 2062 mutex_enter(&mpt->m_mutex); 2063 mptsas_free_active_slots(mpt); 2064 mutex_exit(&mpt->m_mutex); 2065 2066 /* deallocate everything that was allocated in mptsas_attach */ 2067 mptsas_cache_destroy(mpt); 2068 2069 mptsas_hba_fini(mpt); 2070 mptsas_cfg_fini(mpt); 2071 2072 /* Lower the power informing PM Framework */ 2073 if (mpt->m_options & MPTSAS_OPT_PM) { 2074 if (pm_lower_power(dip, 0, PM_LEVEL_D3) != DDI_SUCCESS) 2075 mptsas_log(mpt, CE_WARN, 2076 "!mptsas%d: Lower power request failed " 2077 "during detach, ignoring.", 2078 mpt->m_instance); 2079 } 2080 2081 mutex_destroy(&mpt->m_tx_waitq_mutex); 2082 mutex_destroy(&mpt->m_passthru_mutex); 2083 mutex_destroy(&mpt->m_mutex); 2084 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 2085 mutex_destroy(&mpt->m_phy_info[i].smhba_info.phy_mutex); 2086 } 2087 cv_destroy(&mpt->m_cv); 2088 cv_destroy(&mpt->m_passthru_cv); 2089 cv_destroy(&mpt->m_fw_cv); 2090 cv_destroy(&mpt->m_config_cv); 2091 cv_destroy(&mpt->m_fw_diag_cv); 2092 cv_destroy(&mpt->m_extreq_sense_refcount_cv); 2093 2094 mptsas_smp_teardown(mpt); 2095 mptsas_enc_teardown(mpt); 2096 mptsas_hba_teardown(mpt); 2097 2098 mptsas_config_space_fini(mpt); 2099 2100 mptsas_free_handshake_msg(mpt); 2101 2102 mptsas_fm_fini(mpt); 2103 ddi_soft_state_free(mptsas_state, ddi_get_instance(dip)); 2104 ddi_prop_remove_all(dip); 2105 2106 return (DDI_SUCCESS); 2107 } 2108 2109 static void 2110 mptsas_list_add(mptsas_t *mpt) 2111 { 2112 rw_enter(&mptsas_global_rwlock, RW_WRITER); 2113 2114 if (mptsas_head == NULL) { 2115 mptsas_head = mpt; 2116 } else { 2117 mptsas_tail->m_next = mpt; 2118 } 2119 mptsas_tail = mpt; 2120 rw_exit(&mptsas_global_rwlock); 2121 } 2122 2123 static void 2124 mptsas_list_del(mptsas_t *mpt) 2125 { 2126 mptsas_t *m; 2127 /* 2128 * Remove device instance from the global linked list 2129 */ 2130 rw_enter(&mptsas_global_rwlock, RW_WRITER); 2131 if (mptsas_head == mpt) { 2132 m = mptsas_head = mpt->m_next; 2133 } else { 2134 for (m = mptsas_head; m != NULL; m = m->m_next) { 2135 if (m->m_next == mpt) { 2136 m->m_next = mpt->m_next; 2137 break; 2138 } 2139 } 2140 if (m == NULL) { 2141 mptsas_log(mpt, CE_PANIC, "Not in softc list!"); 2142 } 2143 } 2144 2145 if (mptsas_tail == mpt) { 2146 mptsas_tail = m; 2147 } 2148 rw_exit(&mptsas_global_rwlock); 2149 } 2150 2151 static int 2152 mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size) 2153 { 2154 ddi_dma_attr_t task_dma_attrs; 2155 2156 mpt->m_hshk_dma_size = 0; 2157 task_dma_attrs = mpt->m_msg_dma_attr; 2158 task_dma_attrs.dma_attr_sgllen = 1; 2159 task_dma_attrs.dma_attr_granular = (uint32_t)(alloc_size); 2160 2161 /* allocate Task Management ddi_dma resources */ 2162 if (mptsas_dma_addr_create(mpt, task_dma_attrs, 2163 &mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl, &mpt->m_hshk_memp, 2164 alloc_size, NULL) == FALSE) { 2165 return (DDI_FAILURE); 2166 } 2167 mpt->m_hshk_dma_size = alloc_size; 2168 2169 return (DDI_SUCCESS); 2170 } 2171 2172 static void 2173 mptsas_free_handshake_msg(mptsas_t *mpt) 2174 { 2175 if (mpt->m_hshk_dma_size == 0) 2176 return; 2177 mptsas_dma_addr_destroy(&mpt->m_hshk_dma_hdl, &mpt->m_hshk_acc_hdl); 2178 mpt->m_hshk_dma_size = 0; 2179 } 2180 2181 static int 2182 mptsas_hba_setup(mptsas_t *mpt) 2183 { 2184 scsi_hba_tran_t *hba_tran; 2185 int tran_flags; 2186 2187 /* Allocate a transport structure */ 2188 hba_tran = mpt->m_tran = scsi_hba_tran_alloc(mpt->m_dip, 2189 SCSI_HBA_CANSLEEP); 2190 ASSERT(mpt->m_tran != NULL); 2191 2192 hba_tran->tran_hba_private = mpt; 2193 hba_tran->tran_tgt_private = NULL; 2194 2195 hba_tran->tran_tgt_init = mptsas_scsi_tgt_init; 2196 hba_tran->tran_tgt_free = mptsas_scsi_tgt_free; 2197 2198 hba_tran->tran_start = mptsas_scsi_start; 2199 hba_tran->tran_reset = mptsas_scsi_reset; 2200 hba_tran->tran_abort = mptsas_scsi_abort; 2201 hba_tran->tran_getcap = mptsas_scsi_getcap; 2202 hba_tran->tran_setcap = mptsas_scsi_setcap; 2203 hba_tran->tran_init_pkt = mptsas_scsi_init_pkt; 2204 hba_tran->tran_destroy_pkt = mptsas_scsi_destroy_pkt; 2205 2206 hba_tran->tran_dmafree = mptsas_scsi_dmafree; 2207 hba_tran->tran_sync_pkt = mptsas_scsi_sync_pkt; 2208 hba_tran->tran_reset_notify = mptsas_scsi_reset_notify; 2209 2210 hba_tran->tran_get_bus_addr = mptsas_get_bus_addr; 2211 hba_tran->tran_get_name = mptsas_get_name; 2212 2213 hba_tran->tran_quiesce = mptsas_scsi_quiesce; 2214 hba_tran->tran_unquiesce = mptsas_scsi_unquiesce; 2215 hba_tran->tran_bus_reset = NULL; 2216 2217 hba_tran->tran_add_eventcall = NULL; 2218 hba_tran->tran_get_eventcookie = NULL; 2219 hba_tran->tran_post_event = NULL; 2220 hba_tran->tran_remove_eventcall = NULL; 2221 2222 hba_tran->tran_bus_config = mptsas_bus_config; 2223 2224 hba_tran->tran_interconnect_type = INTERCONNECT_SAS; 2225 2226 /* 2227 * All children of the HBA are iports. We need tran was cloned. 2228 * So we pass the flags to SCSA. SCSI_HBA_TRAN_CLONE will be 2229 * inherited to iport's tran vector. 2230 */ 2231 tran_flags = (SCSI_HBA_HBA | SCSI_HBA_TRAN_CLONE); 2232 2233 if (scsi_hba_attach_setup(mpt->m_dip, &mpt->m_msg_dma_attr, 2234 hba_tran, tran_flags) != DDI_SUCCESS) { 2235 mptsas_log(mpt, CE_WARN, "hba attach setup failed"); 2236 scsi_hba_tran_free(hba_tran); 2237 mpt->m_tran = NULL; 2238 return (FALSE); 2239 } 2240 return (TRUE); 2241 } 2242 2243 static void 2244 mptsas_hba_teardown(mptsas_t *mpt) 2245 { 2246 (void) scsi_hba_detach(mpt->m_dip); 2247 if (mpt->m_tran != NULL) { 2248 scsi_hba_tran_free(mpt->m_tran); 2249 mpt->m_tran = NULL; 2250 } 2251 } 2252 2253 static void 2254 mptsas_iport_register(mptsas_t *mpt) 2255 { 2256 int i, j; 2257 mptsas_phymask_t mask = 0x0; 2258 /* 2259 * initial value of mask is 0 2260 */ 2261 mutex_enter(&mpt->m_mutex); 2262 for (i = 0; i < mpt->m_num_phys; i++) { 2263 mptsas_phymask_t phy_mask = 0x0; 2264 char phy_mask_name[MPTSAS_MAX_PHYS]; 2265 uint8_t current_port; 2266 2267 if (mpt->m_phy_info[i].attached_devhdl == 0) 2268 continue; 2269 2270 bzero(phy_mask_name, sizeof (phy_mask_name)); 2271 2272 current_port = mpt->m_phy_info[i].port_num; 2273 2274 if ((mask & (1 << i)) != 0) 2275 continue; 2276 2277 for (j = 0; j < mpt->m_num_phys; j++) { 2278 if (mpt->m_phy_info[j].attached_devhdl && 2279 (mpt->m_phy_info[j].port_num == current_port)) { 2280 phy_mask |= (1 << j); 2281 } 2282 } 2283 mask = mask | phy_mask; 2284 2285 for (j = 0; j < mpt->m_num_phys; j++) { 2286 if ((phy_mask >> j) & 0x01) { 2287 mpt->m_phy_info[j].phy_mask = phy_mask; 2288 } 2289 } 2290 2291 (void) sprintf(phy_mask_name, "%x", phy_mask); 2292 2293 mutex_exit(&mpt->m_mutex); 2294 /* 2295 * register a iport 2296 */ 2297 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name); 2298 mutex_enter(&mpt->m_mutex); 2299 } 2300 mutex_exit(&mpt->m_mutex); 2301 /* 2302 * register a virtual port for RAID volume always 2303 */ 2304 (void) scsi_hba_iport_register(mpt->m_dip, "v0"); 2305 2306 } 2307 2308 static int 2309 mptsas_smp_setup(mptsas_t *mpt) 2310 { 2311 mpt->m_smptran = smp_hba_tran_alloc(mpt->m_dip); 2312 ASSERT(mpt->m_smptran != NULL); 2313 mpt->m_smptran->smp_tran_hba_private = mpt; 2314 mpt->m_smptran->smp_tran_start = mptsas_smp_start; 2315 if (smp_hba_attach_setup(mpt->m_dip, mpt->m_smptran) != DDI_SUCCESS) { 2316 mptsas_log(mpt, CE_WARN, "smp attach setup failed"); 2317 smp_hba_tran_free(mpt->m_smptran); 2318 mpt->m_smptran = NULL; 2319 return (FALSE); 2320 } 2321 /* 2322 * Initialize smp hash table 2323 */ 2324 mpt->m_smp_targets = refhash_create(MPTSAS_SMP_BUCKET_COUNT, 2325 mptsas_target_addr_hash, mptsas_target_addr_cmp, 2326 mptsas_smp_free, sizeof (mptsas_smp_t), 2327 offsetof(mptsas_smp_t, m_link), offsetof(mptsas_smp_t, m_addr), 2328 KM_SLEEP); 2329 mpt->m_smp_devhdl = 0xFFFF; 2330 2331 return (TRUE); 2332 } 2333 2334 static void 2335 mptsas_smp_teardown(mptsas_t *mpt) 2336 { 2337 (void) smp_hba_detach(mpt->m_dip); 2338 if (mpt->m_smptran != NULL) { 2339 smp_hba_tran_free(mpt->m_smptran); 2340 mpt->m_smptran = NULL; 2341 } 2342 mpt->m_smp_devhdl = 0; 2343 } 2344 2345 static int 2346 mptsas_enc_setup(mptsas_t *mpt) 2347 { 2348 list_create(&mpt->m_enclosures, sizeof (mptsas_enclosure_t), 2349 offsetof(mptsas_enclosure_t, me_link)); 2350 return (TRUE); 2351 } 2352 2353 static void 2354 mptsas_enc_free(mptsas_enclosure_t *mep) 2355 { 2356 if (mep == NULL) 2357 return; 2358 if (mep->me_slotleds != NULL) { 2359 VERIFY3U(mep->me_nslots, >, 0); 2360 kmem_free(mep->me_slotleds, sizeof (uint8_t) * mep->me_nslots); 2361 } 2362 kmem_free(mep, sizeof (mptsas_enclosure_t)); 2363 } 2364 2365 static void 2366 mptsas_enc_teardown(mptsas_t *mpt) 2367 { 2368 mptsas_enclosure_t *mep; 2369 2370 while ((mep = list_remove_head(&mpt->m_enclosures)) != NULL) { 2371 mptsas_enc_free(mep); 2372 } 2373 list_destroy(&mpt->m_enclosures); 2374 } 2375 2376 static mptsas_enclosure_t * 2377 mptsas_enc_lookup(mptsas_t *mpt, uint16_t hdl) 2378 { 2379 mptsas_enclosure_t *mep; 2380 2381 ASSERT(MUTEX_HELD(&mpt->m_mutex)); 2382 2383 for (mep = list_head(&mpt->m_enclosures); mep != NULL; 2384 mep = list_next(&mpt->m_enclosures, mep)) { 2385 if (hdl == mep->me_enchdl) { 2386 return (mep); 2387 } 2388 } 2389 2390 return (NULL); 2391 } 2392 2393 static int 2394 mptsas_cache_create(mptsas_t *mpt) 2395 { 2396 int instance = mpt->m_instance; 2397 char buf[64]; 2398 2399 /* 2400 * create kmem cache for packets 2401 */ 2402 (void) sprintf(buf, "mptsas%d_cache", instance); 2403 mpt->m_kmem_cache = kmem_cache_create(buf, 2404 sizeof (struct mptsas_cmd) + scsi_pkt_size(), 8, 2405 mptsas_kmem_cache_constructor, mptsas_kmem_cache_destructor, 2406 NULL, (void *)mpt, NULL, 0); 2407 2408 if (mpt->m_kmem_cache == NULL) { 2409 mptsas_log(mpt, CE_WARN, "creating kmem cache failed"); 2410 return (FALSE); 2411 } 2412 2413 /* 2414 * create kmem cache for extra SGL frames if SGL cannot 2415 * be accomodated into main request frame. 2416 */ 2417 (void) sprintf(buf, "mptsas%d_cache_frames", instance); 2418 mpt->m_cache_frames = kmem_cache_create(buf, 2419 sizeof (mptsas_cache_frames_t), 8, 2420 mptsas_cache_frames_constructor, mptsas_cache_frames_destructor, 2421 NULL, (void *)mpt, NULL, 0); 2422 2423 if (mpt->m_cache_frames == NULL) { 2424 mptsas_log(mpt, CE_WARN, "creating cache for frames failed"); 2425 return (FALSE); 2426 } 2427 2428 return (TRUE); 2429 } 2430 2431 static void 2432 mptsas_cache_destroy(mptsas_t *mpt) 2433 { 2434 /* deallocate in reverse order */ 2435 if (mpt->m_cache_frames) { 2436 kmem_cache_destroy(mpt->m_cache_frames); 2437 mpt->m_cache_frames = NULL; 2438 } 2439 if (mpt->m_kmem_cache) { 2440 kmem_cache_destroy(mpt->m_kmem_cache); 2441 mpt->m_kmem_cache = NULL; 2442 } 2443 } 2444 2445 static int 2446 mptsas_power(dev_info_t *dip, int component, int level) 2447 { 2448 #ifndef __lock_lint 2449 _NOTE(ARGUNUSED(component)) 2450 #endif 2451 mptsas_t *mpt; 2452 int rval = DDI_SUCCESS; 2453 int polls = 0; 2454 uint32_t ioc_status; 2455 2456 if (scsi_hba_iport_unit_address(dip) != 0) 2457 return (DDI_SUCCESS); 2458 2459 mpt = ddi_get_soft_state(mptsas_state, ddi_get_instance(dip)); 2460 if (mpt == NULL) { 2461 return (DDI_FAILURE); 2462 } 2463 2464 mutex_enter(&mpt->m_mutex); 2465 2466 /* 2467 * If the device is busy, don't lower its power level 2468 */ 2469 if (mpt->m_busy && (mpt->m_power_level > level)) { 2470 mutex_exit(&mpt->m_mutex); 2471 return (DDI_FAILURE); 2472 } 2473 switch (level) { 2474 case PM_LEVEL_D0: 2475 NDBG11(("mptsas%d: turning power ON.", mpt->m_instance)); 2476 MPTSAS_POWER_ON(mpt); 2477 /* 2478 * Wait up to 30 seconds for IOC to come out of reset. 2479 */ 2480 while (((ioc_status = mptsas_hirrd(mpt, 2481 &mpt->m_reg->Doorbell)) & 2482 MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_RESET) { 2483 if (polls++ > 3000) { 2484 break; 2485 } 2486 delay(drv_usectohz(10000)); 2487 } 2488 /* 2489 * If IOC is not in operational state, try to hard reset it. 2490 */ 2491 if ((ioc_status & MPI2_IOC_STATE_MASK) != 2492 MPI2_IOC_STATE_OPERATIONAL) { 2493 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 2494 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) { 2495 mptsas_log(mpt, CE_WARN, 2496 "mptsas_power: hard reset failed"); 2497 mutex_exit(&mpt->m_mutex); 2498 return (DDI_FAILURE); 2499 } 2500 } 2501 mpt->m_power_level = PM_LEVEL_D0; 2502 break; 2503 case PM_LEVEL_D3: 2504 NDBG11(("mptsas%d: turning power OFF.", mpt->m_instance)); 2505 MPTSAS_POWER_OFF(mpt); 2506 break; 2507 default: 2508 mptsas_log(mpt, CE_WARN, "mptsas%d: unknown power level <%x>.", 2509 mpt->m_instance, level); 2510 rval = DDI_FAILURE; 2511 break; 2512 } 2513 mutex_exit(&mpt->m_mutex); 2514 return (rval); 2515 } 2516 2517 /* 2518 * Check for newer v2.6 SAS chips. 2519 */ 2520 static void 2521 mptsas_ioc_check_rev(mptsas_t *mpt) 2522 { 2523 switch (mpt->m_devid) { 2524 case MPI26_MFGPAGE_DEVID_SAS3816: 2525 case MPI26_MFGPAGE_DEVID_SAS3816_1: 2526 mpt->m_is_sea_ioc = 1; 2527 mptsas_log(mpt, CE_NOTE, "!mptsas3%d: SAS3816 IOC Detected", 2528 mpt->m_instance); 2529 /* fallthrough */ 2530 case MPI26_MFGPAGE_DEVID_SAS3616: 2531 case MPI26_MFGPAGE_DEVID_SAS3708: 2532 case MPI26_MFGPAGE_DEVID_SAS3716: 2533 mptsas_log(mpt, CE_NOTE, "!mptsas3%d: gen3.5 IOC Detected", 2534 mpt->m_instance); 2535 mpt->m_is_gen35_ioc = 1; 2536 break; 2537 default: 2538 break; 2539 } 2540 } 2541 2542 /* 2543 * Search through the reg property for the first memory BAR. 2544 */ 2545 static void 2546 mptsas_find_mem_bar(mptsas_t *mpt) 2547 { 2548 int i, rcount; 2549 pci_regspec_t *reg_data; 2550 int reglen; 2551 2552 mpt->m_mem_bar = MEM_SPACE; /* old default */ 2553 /* 2554 * Lookup the 'reg' property. 2555 */ 2556 if (ddi_getlongprop(DDI_DEV_T_ANY, mpt->m_dip, 2557 DDI_PROP_DONTPASS, "reg", (caddr_t)®_data, ®len) == 2558 DDI_PROP_SUCCESS) { 2559 rcount = reglen / sizeof (pci_regspec_t); 2560 for (i = 0; i < rcount; i++) { 2561 if (PCI_REG_ADDR_G(reg_data[i].pci_phys_hi) == 2562 PCI_REG_ADDR_G(PCI_ADDR_MEM64)) { 2563 mpt->m_mem_bar = i; 2564 break; 2565 } 2566 } 2567 } 2568 } 2569 2570 2571 /* 2572 * Initialize configuration space and figure out which 2573 * chip and revison of the chip the mpt driver is using. 2574 */ 2575 static int 2576 mptsas_config_space_init(mptsas_t *mpt) 2577 { 2578 NDBG0(("mptsas_config_space_init")); 2579 2580 if (mpt->m_config_handle != NULL) 2581 return (TRUE); 2582 2583 if (pci_config_setup(mpt->m_dip, 2584 &mpt->m_config_handle) != DDI_SUCCESS) { 2585 mptsas_log(mpt, CE_WARN, "cannot map configuration space."); 2586 return (FALSE); 2587 } 2588 2589 /* 2590 * This is a workaround for a XMITS ASIC bug which does not 2591 * drive the CBE upper bits. 2592 */ 2593 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) & 2594 PCI_STAT_PERROR) { 2595 pci_config_put16(mpt->m_config_handle, PCI_CONF_STAT, 2596 PCI_STAT_PERROR); 2597 } 2598 2599 mptsas_setup_cmd_reg(mpt); 2600 2601 /* 2602 * Get the chip device id: 2603 */ 2604 mpt->m_devid = pci_config_get16(mpt->m_config_handle, PCI_CONF_DEVID); 2605 2606 /* 2607 * Save the revision. 2608 */ 2609 mpt->m_revid = pci_config_get8(mpt->m_config_handle, PCI_CONF_REVID); 2610 2611 /* 2612 * Save the SubSystem Vendor and Device IDs 2613 */ 2614 mpt->m_svid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBVENID); 2615 mpt->m_ssid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBSYSID); 2616 2617 /* 2618 * Set the latency timer to 0x40 as specified by the upa -> pci 2619 * bridge chip design team. This may be done by the sparc pci 2620 * bus nexus driver, but the driver should make sure the latency 2621 * timer is correct for performance reasons. 2622 */ 2623 pci_config_put8(mpt->m_config_handle, PCI_CONF_LATENCY_TIMER, 2624 MPTSAS_LATENCY_TIMER); 2625 2626 mptsas_ioc_check_rev(mpt); 2627 mptsas_find_mem_bar(mpt); 2628 (void) mptsas_get_pci_cap(mpt); 2629 return (TRUE); 2630 } 2631 2632 static void 2633 mptsas_config_space_fini(mptsas_t *mpt) 2634 { 2635 if (mpt->m_config_handle != NULL) { 2636 mptsas_disable_bus_master(mpt); 2637 pci_config_teardown(&mpt->m_config_handle); 2638 mpt->m_config_handle = NULL; 2639 } 2640 } 2641 2642 static void 2643 mptsas_setup_cmd_reg(mptsas_t *mpt) 2644 { 2645 ushort_t cmdreg; 2646 2647 /* 2648 * Set the command register to the needed values. 2649 */ 2650 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM); 2651 cmdreg |= (PCI_COMM_ME | PCI_COMM_SERR_ENABLE | 2652 PCI_COMM_PARITY_DETECT | PCI_COMM_MAE); 2653 cmdreg &= ~PCI_COMM_IO; 2654 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg); 2655 } 2656 2657 static void 2658 mptsas_disable_bus_master(mptsas_t *mpt) 2659 { 2660 ushort_t cmdreg; 2661 2662 /* 2663 * Clear the master enable bit in the PCI command register. 2664 * This prevents any bus mastering activity like DMA. 2665 */ 2666 cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM); 2667 cmdreg &= ~PCI_COMM_ME; 2668 pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg); 2669 } 2670 2671 int 2672 mptsas_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep) 2673 { 2674 ddi_dma_attr_t attrs; 2675 2676 attrs = mpt->m_io_dma_attr; 2677 attrs.dma_attr_sgllen = 1; 2678 2679 ASSERT(dma_statep != NULL); 2680 2681 if (mptsas_dma_addr_create(mpt, attrs, &dma_statep->handle, 2682 &dma_statep->accessp, &dma_statep->memp, dma_statep->size, 2683 &dma_statep->cookie) == FALSE) { 2684 return (DDI_FAILURE); 2685 } 2686 2687 return (DDI_SUCCESS); 2688 } 2689 2690 void 2691 mptsas_dma_free(mptsas_dma_alloc_state_t *dma_statep) 2692 { 2693 ASSERT(dma_statep != NULL); 2694 mptsas_dma_addr_destroy(&dma_statep->handle, &dma_statep->accessp); 2695 dma_statep->size = 0; 2696 } 2697 2698 int 2699 mptsas_do_dma(mptsas_t *mpt, uint32_t size, int var, int (*callback)()) 2700 { 2701 ddi_dma_attr_t attrs; 2702 ddi_dma_handle_t dma_handle; 2703 caddr_t memp; 2704 ddi_acc_handle_t accessp; 2705 int rval; 2706 2707 ASSERT(mutex_owned(&mpt->m_mutex)); 2708 2709 attrs = mpt->m_msg_dma_attr; 2710 attrs.dma_attr_sgllen = 1; 2711 attrs.dma_attr_granular = size; 2712 2713 if (mptsas_dma_addr_create(mpt, attrs, &dma_handle, 2714 &accessp, &memp, size, NULL) == FALSE) { 2715 return (DDI_FAILURE); 2716 } 2717 2718 rval = (*callback) (mpt, memp, var, accessp); 2719 2720 if ((mptsas_check_dma_handle(dma_handle) != DDI_SUCCESS) || 2721 (mptsas_check_acc_handle(accessp) != DDI_SUCCESS)) { 2722 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 2723 rval = DDI_FAILURE; 2724 } 2725 2726 mptsas_dma_addr_destroy(&dma_handle, &accessp); 2727 return (rval); 2728 2729 } 2730 2731 static int 2732 mptsas_alloc_request_frames(mptsas_t *mpt) 2733 { 2734 ddi_dma_attr_t frame_dma_attrs; 2735 caddr_t memp; 2736 ddi_dma_cookie_t cookie; 2737 size_t mem_size; 2738 2739 /* 2740 * re-alloc when it has already alloced 2741 */ 2742 if (mpt->m_dma_req_frame_hdl) 2743 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl, 2744 &mpt->m_acc_req_frame_hdl); 2745 2746 /* 2747 * The size of the request frame pool is: 2748 * Number of Request Frames * Request Frame Size 2749 */ 2750 mem_size = mpt->m_max_requests * mpt->m_req_frame_size; 2751 2752 /* 2753 * set the DMA attributes. System Request Message Frames must be 2754 * aligned on a 16-byte boundry. 2755 */ 2756 frame_dma_attrs = mpt->m_msg_dma_attr; 2757 frame_dma_attrs.dma_attr_align = 16; 2758 frame_dma_attrs.dma_attr_sgllen = 1; 2759 2760 /* 2761 * allocate the request frame pool. 2762 */ 2763 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2764 &mpt->m_dma_req_frame_hdl, &mpt->m_acc_req_frame_hdl, &memp, 2765 mem_size, &cookie) == FALSE) { 2766 return (DDI_FAILURE); 2767 } 2768 2769 /* 2770 * Store the request frame memory address. This chip uses this 2771 * address to dma to and from the driver's frame. The second 2772 * address is the address mpt uses to fill in the frame. 2773 */ 2774 mpt->m_req_frame_dma_addr = cookie.dmac_laddress; 2775 mpt->m_req_frame = memp; 2776 2777 /* 2778 * Clear the request frame pool. 2779 */ 2780 bzero(mpt->m_req_frame, mem_size); 2781 2782 return (DDI_SUCCESS); 2783 } 2784 2785 static int 2786 mptsas_alloc_sense_bufs(mptsas_t *mpt) 2787 { 2788 ddi_dma_attr_t sense_dma_attrs; 2789 caddr_t memp; 2790 ddi_dma_cookie_t cookie; 2791 size_t mem_size; 2792 int num_extrqsense_bufs; 2793 2794 ASSERT(mpt->m_extreq_sense_refcount == 0); 2795 2796 /* 2797 * re-alloc when it has already alloced 2798 */ 2799 if (mpt->m_dma_req_sense_hdl) { 2800 rmfreemap(mpt->m_erqsense_map); 2801 mptsas_dma_addr_destroy(&mpt->m_dma_req_sense_hdl, 2802 &mpt->m_acc_req_sense_hdl); 2803 } 2804 2805 /* 2806 * The size of the request sense pool is: 2807 * (Number of Request Frames - 2 ) * Request Sense Size + 2808 * extra memory for extended sense requests. 2809 */ 2810 mem_size = ((mpt->m_max_requests - 2) * mpt->m_req_sense_size) + 2811 mptsas_extreq_sense_bufsize; 2812 2813 /* 2814 * set the DMA attributes. ARQ buffers 2815 * aligned on a 16-byte boundry. 2816 */ 2817 sense_dma_attrs = mpt->m_msg_dma_attr; 2818 sense_dma_attrs.dma_attr_align = 16; 2819 sense_dma_attrs.dma_attr_sgllen = 1; 2820 2821 /* 2822 * allocate the request sense buffer pool. 2823 */ 2824 if (mptsas_dma_addr_create(mpt, sense_dma_attrs, 2825 &mpt->m_dma_req_sense_hdl, &mpt->m_acc_req_sense_hdl, &memp, 2826 mem_size, &cookie) == FALSE) { 2827 return (DDI_FAILURE); 2828 } 2829 2830 /* 2831 * Store the request sense base memory address. This chip uses this 2832 * address to dma the request sense data. The second 2833 * address is the address mpt uses to access the data. 2834 * The third is the base for the extended rqsense buffers. 2835 */ 2836 mpt->m_req_sense_dma_addr = cookie.dmac_laddress; 2837 mpt->m_req_sense = memp; 2838 memp += (mpt->m_max_requests - 2) * mpt->m_req_sense_size; 2839 mpt->m_extreq_sense = memp; 2840 2841 /* 2842 * The extra memory is divided up into multiples of the base 2843 * buffer size in order to allocate via rmalloc(). 2844 * Note that the rmallocmap cannot start at zero! 2845 */ 2846 num_extrqsense_bufs = mptsas_extreq_sense_bufsize / 2847 mpt->m_req_sense_size; 2848 mpt->m_erqsense_map = rmallocmap_wait(num_extrqsense_bufs); 2849 rmfree(mpt->m_erqsense_map, num_extrqsense_bufs, 1); 2850 2851 /* 2852 * Clear the pool. 2853 */ 2854 bzero(mpt->m_req_sense, mem_size); 2855 2856 return (DDI_SUCCESS); 2857 } 2858 2859 static int 2860 mptsas_alloc_reply_frames(mptsas_t *mpt) 2861 { 2862 ddi_dma_attr_t frame_dma_attrs; 2863 caddr_t memp; 2864 ddi_dma_cookie_t cookie; 2865 size_t mem_size; 2866 2867 /* 2868 * re-alloc when it has already alloced 2869 */ 2870 if (mpt->m_dma_reply_frame_hdl) { 2871 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl, 2872 &mpt->m_acc_reply_frame_hdl); 2873 } 2874 2875 /* 2876 * The size of the reply frame pool is: 2877 * Number of Reply Frames * Reply Frame Size 2878 */ 2879 mem_size = mpt->m_max_replies * mpt->m_reply_frame_size; 2880 2881 /* 2882 * set the DMA attributes. System Reply Message Frames must be 2883 * aligned on a 4-byte boundry. This is the default. 2884 */ 2885 frame_dma_attrs = mpt->m_msg_dma_attr; 2886 frame_dma_attrs.dma_attr_sgllen = 1; 2887 2888 /* 2889 * allocate the reply frame pool 2890 */ 2891 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2892 &mpt->m_dma_reply_frame_hdl, &mpt->m_acc_reply_frame_hdl, &memp, 2893 mem_size, &cookie) == FALSE) { 2894 return (DDI_FAILURE); 2895 } 2896 2897 /* 2898 * Store the reply frame memory address. This chip uses this 2899 * address to dma to and from the driver's frame. The second 2900 * address is the address mpt uses to process the frame. 2901 */ 2902 mpt->m_reply_frame_dma_addr = cookie.dmac_laddress; 2903 mpt->m_reply_frame = memp; 2904 2905 /* 2906 * Clear the reply frame pool. 2907 */ 2908 bzero(mpt->m_reply_frame, mem_size); 2909 2910 return (DDI_SUCCESS); 2911 } 2912 2913 static int 2914 mptsas_alloc_free_queue(mptsas_t *mpt) 2915 { 2916 ddi_dma_attr_t frame_dma_attrs; 2917 caddr_t memp; 2918 ddi_dma_cookie_t cookie; 2919 size_t mem_size; 2920 2921 /* 2922 * re-alloc when it has already alloced 2923 */ 2924 if (mpt->m_dma_free_queue_hdl) { 2925 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl, 2926 &mpt->m_acc_free_queue_hdl); 2927 } 2928 2929 /* 2930 * The reply free queue size is: 2931 * Reply Free Queue Depth * 4 2932 * The "4" is the size of one 32 bit address (low part of 64-bit 2933 * address) 2934 */ 2935 mem_size = mpt->m_free_queue_depth * 4; 2936 2937 /* 2938 * set the DMA attributes The Reply Free Queue must be aligned on a 2939 * 16-byte boundry. 2940 */ 2941 frame_dma_attrs = mpt->m_msg_dma_attr; 2942 frame_dma_attrs.dma_attr_align = 16; 2943 frame_dma_attrs.dma_attr_sgllen = 1; 2944 2945 /* 2946 * allocate the reply free queue 2947 */ 2948 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 2949 &mpt->m_dma_free_queue_hdl, &mpt->m_acc_free_queue_hdl, &memp, 2950 mem_size, &cookie) == FALSE) { 2951 return (DDI_FAILURE); 2952 } 2953 2954 /* 2955 * Store the reply free queue memory address. This chip uses this 2956 * address to read from the reply free queue. The second address 2957 * is the address mpt uses to manage the queue. 2958 */ 2959 mpt->m_free_queue_dma_addr = cookie.dmac_laddress; 2960 mpt->m_free_queue = memp; 2961 2962 /* 2963 * Clear the reply free queue memory. 2964 */ 2965 bzero(mpt->m_free_queue, mem_size); 2966 2967 return (DDI_SUCCESS); 2968 } 2969 2970 static int 2971 mptsas_alloc_post_queue(mptsas_t *mpt) 2972 { 2973 ddi_dma_attr_t frame_dma_attrs; 2974 caddr_t memp; 2975 ddi_dma_cookie_t cookie; 2976 size_t mem_size; 2977 2978 /* 2979 * re-alloc when it has already alloced 2980 */ 2981 if (mpt->m_dma_post_queue_hdl) { 2982 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl, 2983 &mpt->m_acc_post_queue_hdl); 2984 } 2985 2986 /* 2987 * The reply descriptor post queue size is: 2988 * Reply Descriptor Post Queue Depth * 8 2989 * The "8" is the size of each descriptor (8 bytes or 64 bits). 2990 */ 2991 mem_size = mpt->m_post_queue_depth * 8; 2992 2993 /* 2994 * set the DMA attributes. The Reply Descriptor Post Queue must be 2995 * aligned on a 16-byte boundry. 2996 */ 2997 frame_dma_attrs = mpt->m_msg_dma_attr; 2998 frame_dma_attrs.dma_attr_align = 16; 2999 frame_dma_attrs.dma_attr_sgllen = 1; 3000 3001 /* 3002 * allocate the reply post queue 3003 */ 3004 if (mptsas_dma_addr_create(mpt, frame_dma_attrs, 3005 &mpt->m_dma_post_queue_hdl, &mpt->m_acc_post_queue_hdl, &memp, 3006 mem_size, &cookie) == FALSE) { 3007 return (DDI_FAILURE); 3008 } 3009 3010 /* 3011 * Store the reply descriptor post queue memory address. This chip 3012 * uses this address to write to the reply descriptor post queue. The 3013 * second address is the address mpt uses to manage the queue. 3014 */ 3015 mpt->m_post_queue_dma_addr = cookie.dmac_laddress; 3016 mpt->m_post_queue = memp; 3017 3018 /* 3019 * Clear the reply post queue memory. 3020 */ 3021 bzero(mpt->m_post_queue, mem_size); 3022 3023 return (DDI_SUCCESS); 3024 } 3025 3026 static void 3027 mptsas_alloc_reply_args(mptsas_t *mpt) 3028 { 3029 if (mpt->m_replyh_args == NULL) { 3030 mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) * 3031 mpt->m_max_replies, KM_SLEEP); 3032 } 3033 } 3034 3035 static int 3036 mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd) 3037 { 3038 mptsas_cache_frames_t *frames = NULL; 3039 if (cmd->cmd_extra_frames == NULL) { 3040 frames = kmem_cache_alloc(mpt->m_cache_frames, KM_NOSLEEP); 3041 if (frames == NULL) { 3042 return (DDI_FAILURE); 3043 } 3044 cmd->cmd_extra_frames = frames; 3045 } 3046 return (DDI_SUCCESS); 3047 } 3048 3049 static void 3050 mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd) 3051 { 3052 if (cmd->cmd_extra_frames) { 3053 kmem_cache_free(mpt->m_cache_frames, 3054 (void *)cmd->cmd_extra_frames); 3055 cmd->cmd_extra_frames = NULL; 3056 } 3057 } 3058 3059 static void 3060 mptsas_cfg_fini(mptsas_t *mpt) 3061 { 3062 NDBG0(("mptsas_cfg_fini")); 3063 ddi_regs_map_free(&mpt->m_datap); 3064 } 3065 3066 static void 3067 mptsas_hba_fini(mptsas_t *mpt) 3068 { 3069 NDBG0(("mptsas_hba_fini")); 3070 3071 /* 3072 * Free up any allocated memory 3073 */ 3074 if (mpt->m_dma_req_frame_hdl) { 3075 mptsas_dma_addr_destroy(&mpt->m_dma_req_frame_hdl, 3076 &mpt->m_acc_req_frame_hdl); 3077 } 3078 3079 if (mpt->m_dma_req_sense_hdl) { 3080 rmfreemap(mpt->m_erqsense_map); 3081 mptsas_dma_addr_destroy(&mpt->m_dma_req_sense_hdl, 3082 &mpt->m_acc_req_sense_hdl); 3083 } 3084 3085 if (mpt->m_dma_reply_frame_hdl) { 3086 mptsas_dma_addr_destroy(&mpt->m_dma_reply_frame_hdl, 3087 &mpt->m_acc_reply_frame_hdl); 3088 } 3089 3090 if (mpt->m_dma_free_queue_hdl) { 3091 mptsas_dma_addr_destroy(&mpt->m_dma_free_queue_hdl, 3092 &mpt->m_acc_free_queue_hdl); 3093 } 3094 3095 if (mpt->m_dma_post_queue_hdl) { 3096 mptsas_dma_addr_destroy(&mpt->m_dma_post_queue_hdl, 3097 &mpt->m_acc_post_queue_hdl); 3098 } 3099 3100 if (mpt->m_replyh_args != NULL) { 3101 kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t) 3102 * mpt->m_max_replies); 3103 } 3104 } 3105 3106 static int 3107 mptsas_name_child(dev_info_t *lun_dip, char *name, int len) 3108 { 3109 int lun = 0; 3110 char *sas_wwn = NULL; 3111 int phynum = -1; 3112 int reallen = 0; 3113 3114 /* Get the target num */ 3115 lun = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, DDI_PROP_DONTPASS, 3116 LUN_PROP, 0); 3117 3118 if ((phynum = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, 3119 DDI_PROP_DONTPASS, "sata-phy", -1)) != -1) { 3120 /* 3121 * Stick in the address of form "pPHY,LUN" 3122 */ 3123 reallen = snprintf(name, len, "p%x,%x", phynum, lun); 3124 } else if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lun_dip, 3125 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &sas_wwn) 3126 == DDI_PROP_SUCCESS) { 3127 /* 3128 * Stick in the address of the form "wWWN,LUN" 3129 */ 3130 reallen = snprintf(name, len, "%s,%x", sas_wwn, lun); 3131 ddi_prop_free(sas_wwn); 3132 } else { 3133 return (DDI_FAILURE); 3134 } 3135 3136 ASSERT(reallen < len); 3137 if (reallen >= len) { 3138 mptsas_log(0, CE_WARN, "!mptsas_get_name: name parameter " 3139 "length too small, it needs to be %d bytes", reallen + 1); 3140 } 3141 return (DDI_SUCCESS); 3142 } 3143 3144 /* 3145 * tran_tgt_init(9E) - target device instance initialization 3146 */ 3147 static int 3148 mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip, 3149 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 3150 { 3151 #ifndef __lock_lint 3152 _NOTE(ARGUNUSED(hba_tran)) 3153 #endif 3154 3155 /* 3156 * At this point, the scsi_device structure already exists 3157 * and has been initialized. 3158 * 3159 * Use this function to allocate target-private data structures, 3160 * if needed by this HBA. Add revised flow-control and queue 3161 * properties for child here, if desired and if you can tell they 3162 * support tagged queueing by now. 3163 */ 3164 mptsas_t *mpt; 3165 int lun = sd->sd_address.a_lun; 3166 mdi_pathinfo_t *pip = NULL; 3167 mptsas_tgt_private_t *tgt_private = NULL; 3168 mptsas_target_t *ptgt = NULL; 3169 char *psas_wwn = NULL; 3170 mptsas_phymask_t phymask = 0; 3171 uint64_t sas_wwn = 0; 3172 mptsas_target_addr_t addr; 3173 mpt = SDEV2MPT(sd); 3174 3175 ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0); 3176 3177 NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d", 3178 (void *)hba_dip, (void *)tgt_dip, lun)); 3179 3180 if (ndi_dev_is_persistent_node(tgt_dip) == 0) { 3181 (void) ndi_merge_node(tgt_dip, mptsas_name_child); 3182 ddi_set_name_addr(tgt_dip, NULL); 3183 return (DDI_FAILURE); 3184 } 3185 /* 3186 * phymask is 0 means the virtual port for RAID 3187 */ 3188 phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0, 3189 "phymask", 0); 3190 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) { 3191 if ((pip = (void *)(sd->sd_private)) == NULL) { 3192 /* 3193 * Very bad news if this occurs. Somehow scsi_vhci has 3194 * lost the pathinfo node for this target. 3195 */ 3196 return (DDI_NOT_WELL_FORMED); 3197 } 3198 3199 if (mdi_prop_lookup_int(pip, LUN_PROP, &lun) != 3200 DDI_PROP_SUCCESS) { 3201 mptsas_log(mpt, CE_WARN, "Get lun property failed\n"); 3202 return (DDI_FAILURE); 3203 } 3204 3205 if (mdi_prop_lookup_string(pip, SCSI_ADDR_PROP_TARGET_PORT, 3206 &psas_wwn) == MDI_SUCCESS) { 3207 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) { 3208 sas_wwn = 0; 3209 } 3210 (void) mdi_prop_free(psas_wwn); 3211 } 3212 } else { 3213 lun = ddi_prop_get_int(DDI_DEV_T_ANY, tgt_dip, 3214 DDI_PROP_DONTPASS, LUN_PROP, 0); 3215 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, tgt_dip, 3216 DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &psas_wwn) == 3217 DDI_PROP_SUCCESS) { 3218 if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) { 3219 sas_wwn = 0; 3220 } 3221 ddi_prop_free(psas_wwn); 3222 } else { 3223 sas_wwn = 0; 3224 } 3225 } 3226 3227 ASSERT((sas_wwn != 0) || (phymask != 0)); 3228 addr.mta_wwn = sas_wwn; 3229 addr.mta_phymask = phymask; 3230 mutex_enter(&mpt->m_mutex); 3231 ptgt = refhash_lookup(mpt->m_targets, &addr); 3232 mutex_exit(&mpt->m_mutex); 3233 if (ptgt == NULL) { 3234 mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or " 3235 "gone already! phymask:%x, saswwn %"PRIx64, phymask, 3236 sas_wwn); 3237 return (DDI_FAILURE); 3238 } 3239 if (hba_tran->tran_tgt_private == NULL) { 3240 tgt_private = kmem_zalloc(sizeof (mptsas_tgt_private_t), 3241 KM_SLEEP); 3242 tgt_private->t_lun = lun; 3243 tgt_private->t_private = ptgt; 3244 hba_tran->tran_tgt_private = tgt_private; 3245 } 3246 3247 if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) { 3248 return (DDI_SUCCESS); 3249 } 3250 mutex_enter(&mpt->m_mutex); 3251 3252 if (ptgt->m_deviceinfo & 3253 (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 3254 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 3255 uchar_t *inq89 = NULL; 3256 int inq89_len = 0x238; 3257 int reallen = 0; 3258 int rval = 0; 3259 struct sata_id *sid = NULL; 3260 char model[SATA_ID_MODEL_LEN + 1]; 3261 char fw[SATA_ID_FW_LEN + 1]; 3262 char *vid, *pid; 3263 3264 mutex_exit(&mpt->m_mutex); 3265 /* 3266 * According SCSI/ATA Translation -2 (SAT-2) revision 01a 3267 * chapter 12.4.2 VPD page 89h includes 512 bytes ATA IDENTIFY 3268 * DEVICE data or ATA IDENTIFY PACKET DEVICE data. 3269 */ 3270 inq89 = kmem_zalloc(inq89_len, KM_SLEEP); 3271 rval = mptsas_inquiry(mpt, ptgt, 0, 0x89, 3272 inq89, inq89_len, &reallen, 1); 3273 3274 if (rval != 0) { 3275 if (inq89 != NULL) { 3276 kmem_free(inq89, inq89_len); 3277 } 3278 3279 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 3280 "0x89 for SATA target:%x failed!", ptgt->m_devhdl); 3281 return (DDI_SUCCESS); 3282 } 3283 sid = (void *)(&inq89[60]); 3284 3285 swab(sid->ai_model, model, SATA_ID_MODEL_LEN); 3286 swab(sid->ai_fw, fw, SATA_ID_FW_LEN); 3287 3288 model[SATA_ID_MODEL_LEN] = 0; 3289 fw[SATA_ID_FW_LEN] = 0; 3290 3291 sata_split_model(model, &vid, &pid); 3292 3293 /* 3294 * override SCSA "inquiry-*" properties 3295 */ 3296 if (vid) 3297 (void) scsi_device_prop_update_inqstring(sd, 3298 INQUIRY_VENDOR_ID, vid, strlen(vid)); 3299 if (pid) 3300 (void) scsi_device_prop_update_inqstring(sd, 3301 INQUIRY_PRODUCT_ID, pid, strlen(pid)); 3302 (void) scsi_device_prop_update_inqstring(sd, 3303 INQUIRY_REVISION_ID, fw, strlen(fw)); 3304 3305 if (inq89 != NULL) { 3306 kmem_free(inq89, inq89_len); 3307 } 3308 } else { 3309 mutex_exit(&mpt->m_mutex); 3310 } 3311 3312 return (DDI_SUCCESS); 3313 } 3314 /* 3315 * tran_tgt_free(9E) - target device instance deallocation 3316 */ 3317 static void 3318 mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip, 3319 scsi_hba_tran_t *hba_tran, struct scsi_device *sd) 3320 { 3321 #ifndef __lock_lint 3322 _NOTE(ARGUNUSED(hba_dip, tgt_dip, hba_tran, sd)) 3323 #endif 3324 3325 mptsas_tgt_private_t *tgt_private = hba_tran->tran_tgt_private; 3326 3327 if (tgt_private != NULL) { 3328 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t)); 3329 hba_tran->tran_tgt_private = NULL; 3330 } 3331 } 3332 3333 /* 3334 * scsi_pkt handling 3335 * 3336 * Visible to the external world via the transport structure. 3337 */ 3338 3339 /* 3340 * Notes: 3341 * - transport the command to the addressed SCSI target/lun device 3342 * - normal operation is to schedule the command to be transported, 3343 * and return TRAN_ACCEPT if this is successful. 3344 * - if NO_INTR, tran_start must poll device for command completion 3345 */ 3346 static int 3347 mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt) 3348 { 3349 #ifndef __lock_lint 3350 _NOTE(ARGUNUSED(ap)) 3351 #endif 3352 mptsas_t *mpt = PKT2MPT(pkt); 3353 mptsas_cmd_t *cmd = PKT2CMD(pkt); 3354 int rval; 3355 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3356 3357 NDBG1(("mptsas_scsi_start: pkt=0x%p", (void *)pkt)); 3358 ASSERT(ptgt); 3359 if (ptgt == NULL) 3360 return (TRAN_FATAL_ERROR); 3361 3362 /* 3363 * prepare the pkt before taking mutex. 3364 */ 3365 rval = mptsas_prepare_pkt(cmd); 3366 if (rval != TRAN_ACCEPT) { 3367 return (rval); 3368 } 3369 3370 /* 3371 * Send the command to target/lun, however your HBA requires it. 3372 * If busy, return TRAN_BUSY; if there's some other formatting error 3373 * in the packet, return TRAN_BADPKT; otherwise, fall through to the 3374 * return of TRAN_ACCEPT. 3375 * 3376 * Remember that access to shared resources, including the mptsas_t 3377 * data structure and the HBA hardware registers, must be protected 3378 * with mutexes, here and everywhere. 3379 * 3380 * Also remember that at interrupt time, you'll get an argument 3381 * to the interrupt handler which is a pointer to your mptsas_t 3382 * structure; you'll have to remember which commands are outstanding 3383 * and which scsi_pkt is the currently-running command so the 3384 * interrupt handler can refer to the pkt to set completion 3385 * status, call the target driver back through pkt_comp, etc. 3386 * 3387 * If the instance lock is held by other thread, don't spin to wait 3388 * for it. Instead, queue the cmd and next time when the instance lock 3389 * is not held, accept all the queued cmd. A extra tx_waitq is 3390 * introduced to protect the queue. 3391 * 3392 * The polled cmd will not be queud and accepted as usual. 3393 * 3394 * Under the tx_waitq mutex, record whether a thread is draining 3395 * the tx_waitq. An IO requesting thread that finds the instance 3396 * mutex contended appends to the tx_waitq and while holding the 3397 * tx_wait mutex, if the draining flag is not set, sets it and then 3398 * proceeds to spin for the instance mutex. This scheme ensures that 3399 * the last cmd in a burst be processed. 3400 * 3401 * we enable this feature only when the helper threads are enabled, 3402 * at which we think the loads are heavy. 3403 * 3404 * per instance mutex m_tx_waitq_mutex is introduced to protect the 3405 * m_tx_waitqtail, m_tx_waitq, m_tx_draining. 3406 */ 3407 3408 if (mpt->m_doneq_thread_n) { 3409 if (mutex_tryenter(&mpt->m_mutex) != 0) { 3410 rval = mptsas_accept_txwq_and_pkt(mpt, cmd); 3411 mutex_exit(&mpt->m_mutex); 3412 } else if (cmd->cmd_pkt_flags & FLAG_NOINTR) { 3413 mutex_enter(&mpt->m_mutex); 3414 rval = mptsas_accept_txwq_and_pkt(mpt, cmd); 3415 mutex_exit(&mpt->m_mutex); 3416 } else { 3417 mutex_enter(&mpt->m_tx_waitq_mutex); 3418 /* 3419 * ptgt->m_dr_flag is protected by m_mutex or 3420 * m_tx_waitq_mutex. In this case, m_tx_waitq_mutex 3421 * is acquired. 3422 */ 3423 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3424 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3425 /* 3426 * The command should be allowed to 3427 * retry by returning TRAN_BUSY to 3428 * to stall the I/O's which come from 3429 * scsi_vhci since the device/path is 3430 * in unstable state now. 3431 */ 3432 mutex_exit(&mpt->m_tx_waitq_mutex); 3433 return (TRAN_BUSY); 3434 } else { 3435 /* 3436 * The device is offline, just fail the 3437 * command by returning 3438 * TRAN_FATAL_ERROR. 3439 */ 3440 mutex_exit(&mpt->m_tx_waitq_mutex); 3441 return (TRAN_FATAL_ERROR); 3442 } 3443 } 3444 if (mpt->m_tx_draining) { 3445 cmd->cmd_flags |= CFLAG_TXQ; 3446 *mpt->m_tx_waitqtail = cmd; 3447 mpt->m_tx_waitqtail = &cmd->cmd_linkp; 3448 mutex_exit(&mpt->m_tx_waitq_mutex); 3449 } else { /* drain the queue */ 3450 mpt->m_tx_draining = 1; 3451 mutex_exit(&mpt->m_tx_waitq_mutex); 3452 mutex_enter(&mpt->m_mutex); 3453 rval = mptsas_accept_txwq_and_pkt(mpt, cmd); 3454 mutex_exit(&mpt->m_mutex); 3455 } 3456 } 3457 } else { 3458 mutex_enter(&mpt->m_mutex); 3459 /* 3460 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex 3461 * in this case, m_mutex is acquired. 3462 */ 3463 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3464 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3465 /* 3466 * commands should be allowed to retry by 3467 * returning TRAN_BUSY to stall the I/O's 3468 * which come from scsi_vhci since the device/ 3469 * path is in unstable state now. 3470 */ 3471 mutex_exit(&mpt->m_mutex); 3472 return (TRAN_BUSY); 3473 } else { 3474 /* 3475 * The device is offline, just fail the 3476 * command by returning TRAN_FATAL_ERROR. 3477 */ 3478 mutex_exit(&mpt->m_mutex); 3479 return (TRAN_FATAL_ERROR); 3480 } 3481 } 3482 rval = mptsas_accept_pkt(mpt, cmd); 3483 mutex_exit(&mpt->m_mutex); 3484 } 3485 3486 return (rval); 3487 } 3488 3489 /* 3490 * Accept all the queued cmds(if any) before accept the current one. 3491 */ 3492 static int 3493 mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd) 3494 { 3495 int rval; 3496 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3497 3498 ASSERT(mutex_owned(&mpt->m_mutex)); 3499 /* 3500 * The call to mptsas_accept_tx_waitq() must always be performed 3501 * because that is where mpt->m_tx_draining is cleared. 3502 */ 3503 mutex_enter(&mpt->m_tx_waitq_mutex); 3504 mptsas_accept_tx_waitq(mpt); 3505 mutex_exit(&mpt->m_tx_waitq_mutex); 3506 /* 3507 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex 3508 * in this case, m_mutex is acquired. 3509 */ 3510 if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) { 3511 if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) { 3512 /* 3513 * The command should be allowed to retry by returning 3514 * TRAN_BUSY to stall the I/O's which come from 3515 * scsi_vhci since the device/path is in unstable state 3516 * now. 3517 */ 3518 return (TRAN_BUSY); 3519 } else { 3520 /* 3521 * The device is offline, just fail the command by 3522 * return TRAN_FATAL_ERROR. 3523 */ 3524 return (TRAN_FATAL_ERROR); 3525 } 3526 } 3527 rval = mptsas_accept_pkt(mpt, cmd); 3528 3529 return (rval); 3530 } 3531 3532 static int 3533 mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd) 3534 { 3535 int rval = TRAN_ACCEPT; 3536 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3537 3538 NDBG1(("mptsas_accept_pkt: cmd=0x%p", (void *)cmd)); 3539 3540 ASSERT(mutex_owned(&mpt->m_mutex)); 3541 3542 if ((cmd->cmd_flags & CFLAG_PREPARED) == 0) { 3543 rval = mptsas_prepare_pkt(cmd); 3544 if (rval != TRAN_ACCEPT) { 3545 cmd->cmd_flags &= ~CFLAG_TRANFLAG; 3546 return (rval); 3547 } 3548 } 3549 3550 /* 3551 * reset the throttle if we were draining 3552 */ 3553 if ((ptgt->m_t_ncmds == 0) && 3554 (ptgt->m_t_throttle == DRAIN_THROTTLE)) { 3555 NDBG23(("reset throttle")); 3556 ASSERT(ptgt->m_reset_delay == 0); 3557 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 3558 } 3559 3560 /* 3561 * If HBA is being reset, the DevHandles are being re-initialized, 3562 * which means that they could be invalid even if the target is still 3563 * attached. Check if being reset and if DevHandle is being 3564 * re-initialized. If this is the case, return BUSY so the I/O can be 3565 * retried later. 3566 */ 3567 if ((ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) && mpt->m_in_reset) { 3568 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 3569 if (cmd->cmd_flags & CFLAG_TXQ) { 3570 mptsas_doneq_add(mpt, cmd); 3571 mptsas_doneq_empty(mpt); 3572 return (rval); 3573 } else { 3574 return (TRAN_BUSY); 3575 } 3576 } 3577 3578 /* 3579 * If device handle has already been invalidated, just 3580 * fail the command. In theory, command from scsi_vhci 3581 * client is impossible send down command with invalid 3582 * devhdl since devhdl is set after path offline, target 3583 * driver is not suppose to select a offlined path. 3584 */ 3585 if (ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) { 3586 NDBG3(("rejecting command, it might because invalid devhdl " 3587 "request.")); 3588 mptsas_set_pkt_reason(mpt, cmd, CMD_DEV_GONE, STAT_TERMINATED); 3589 if (cmd->cmd_flags & CFLAG_TXQ) { 3590 mptsas_doneq_add(mpt, cmd); 3591 mptsas_doneq_empty(mpt); 3592 return (rval); 3593 } else { 3594 return (TRAN_FATAL_ERROR); 3595 } 3596 } 3597 /* 3598 * The first case is the normal case. mpt gets a command from the 3599 * target driver and starts it. 3600 * Since SMID 0 is reserved and the TM slot is reserved, the actual max 3601 * commands is m_max_requests - 2. 3602 */ 3603 if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) && 3604 (ptgt->m_t_throttle > HOLD_THROTTLE) && 3605 (ptgt->m_t_ncmds < ptgt->m_t_throttle) && 3606 (ptgt->m_reset_delay == 0) && 3607 (ptgt->m_t_nwait == 0) && 3608 ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0)) { 3609 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 3610 (void) mptsas_start_cmd(mpt, cmd); 3611 } else { 3612 mptsas_waitq_add(mpt, cmd); 3613 } 3614 } else { 3615 /* 3616 * Add this pkt to the work queue 3617 */ 3618 mptsas_waitq_add(mpt, cmd); 3619 3620 if (cmd->cmd_pkt_flags & FLAG_NOINTR) { 3621 (void) mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME); 3622 3623 /* 3624 * Only flush the doneq if this is not a TM 3625 * cmd. For TM cmds the flushing of the 3626 * doneq will be done in those routines. 3627 */ 3628 if ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) { 3629 mptsas_doneq_empty(mpt); 3630 } 3631 } 3632 } 3633 return (rval); 3634 } 3635 3636 int 3637 mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 3638 { 3639 mptsas_slots_t *slots = mpt->m_active; 3640 uint_t slot, start_rotor; 3641 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 3642 3643 ASSERT(MUTEX_HELD(&mpt->m_mutex)); 3644 3645 /* 3646 * Account for reserved TM request slot and reserved SMID of 0. 3647 */ 3648 ASSERT(slots->m_n_normal == (mpt->m_max_requests - 2)); 3649 3650 /* 3651 * Find the next available slot, beginning at m_rotor. If no slot is 3652 * available, we'll return FALSE to indicate that. This mechanism 3653 * considers only the normal slots, not the reserved slot 0 nor the 3654 * task management slot m_n_normal + 1. The rotor is left to point to 3655 * the normal slot after the one we select, unless we select the last 3656 * normal slot in which case it returns to slot 1. 3657 */ 3658 start_rotor = slots->m_rotor; 3659 do { 3660 slot = slots->m_rotor++; 3661 if (slots->m_rotor > slots->m_n_normal) 3662 slots->m_rotor = 1; 3663 3664 if (slots->m_rotor == start_rotor) 3665 break; 3666 } while (slots->m_slot[slot] != NULL); 3667 3668 if (slots->m_slot[slot] != NULL) 3669 return (FALSE); 3670 3671 ASSERT(slot != 0 && slot <= slots->m_n_normal); 3672 3673 cmd->cmd_slot = slot; 3674 slots->m_slot[slot] = cmd; 3675 mpt->m_ncmds++; 3676 3677 /* 3678 * only increment per target ncmds if this is not a 3679 * command that has no target associated with it (i.e. a 3680 * event acknoledgment) 3681 */ 3682 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 3683 /* 3684 * Expiration time is set in mptsas_start_cmd 3685 */ 3686 ptgt->m_t_ncmds++; 3687 cmd->cmd_active_expiration = 0; 3688 } else { 3689 /* 3690 * Initialize expiration time for passthrough commands, 3691 */ 3692 cmd->cmd_active_expiration = gethrtime() + 3693 (hrtime_t)cmd->cmd_pkt->pkt_time * NANOSEC; 3694 } 3695 return (TRUE); 3696 } 3697 3698 /* 3699 * prepare the pkt: 3700 * the pkt may have been resubmitted or just reused so 3701 * initialize some fields and do some checks. 3702 */ 3703 static int 3704 mptsas_prepare_pkt(mptsas_cmd_t *cmd) 3705 { 3706 struct scsi_pkt *pkt = CMD2PKT(cmd); 3707 3708 NDBG1(("mptsas_prepare_pkt: cmd=0x%p", (void *)cmd)); 3709 3710 /* 3711 * Reinitialize some fields that need it; the packet may 3712 * have been resubmitted 3713 */ 3714 pkt->pkt_reason = CMD_CMPLT; 3715 pkt->pkt_state = 0; 3716 pkt->pkt_statistics = 0; 3717 pkt->pkt_resid = 0; 3718 cmd->cmd_age = 0; 3719 cmd->cmd_pkt_flags = pkt->pkt_flags; 3720 3721 /* 3722 * zero status byte. 3723 */ 3724 *(pkt->pkt_scbp) = 0; 3725 3726 if (cmd->cmd_flags & CFLAG_DMAVALID) { 3727 pkt->pkt_resid = cmd->cmd_dmacount; 3728 3729 /* 3730 * consistent packets need to be sync'ed first 3731 * (only for data going out) 3732 */ 3733 if ((cmd->cmd_flags & CFLAG_CMDIOPB) && 3734 (cmd->cmd_flags & CFLAG_DMASEND)) { 3735 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 3736 DDI_DMA_SYNC_FORDEV); 3737 } 3738 } 3739 3740 cmd->cmd_flags = 3741 (cmd->cmd_flags & ~(CFLAG_TRANFLAG)) | 3742 CFLAG_PREPARED | CFLAG_IN_TRANSPORT; 3743 3744 return (TRAN_ACCEPT); 3745 } 3746 3747 /* 3748 * tran_init_pkt(9E) - allocate scsi_pkt(9S) for command 3749 * 3750 * One of three possibilities: 3751 * - allocate scsi_pkt 3752 * - allocate scsi_pkt and DMA resources 3753 * - allocate DMA resources to an already-allocated pkt 3754 */ 3755 static struct scsi_pkt * 3756 mptsas_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt, 3757 struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags, 3758 int (*callback)(), caddr_t arg) 3759 { 3760 mptsas_cmd_t *cmd, *new_cmd; 3761 mptsas_t *mpt = ADDR2MPT(ap); 3762 uint_t oldcookiec; 3763 mptsas_target_t *ptgt = NULL; 3764 int rval; 3765 mptsas_tgt_private_t *tgt_private; 3766 int kf; 3767 3768 kf = (callback == SLEEP_FUNC)? KM_SLEEP: KM_NOSLEEP; 3769 3770 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran-> 3771 tran_tgt_private; 3772 ASSERT(tgt_private != NULL); 3773 if (tgt_private == NULL) { 3774 return (NULL); 3775 } 3776 ptgt = tgt_private->t_private; 3777 ASSERT(ptgt != NULL); 3778 if (ptgt == NULL) 3779 return (NULL); 3780 ap->a_target = ptgt->m_devhdl; 3781 ap->a_lun = tgt_private->t_lun; 3782 3783 ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC); 3784 #ifdef MPTSAS_TEST_EXTRN_ALLOC 3785 statuslen *= 100; tgtlen *= 4; 3786 #endif 3787 NDBG3(("mptsas_scsi_init_pkt:\n" 3788 "\ttgt=%d in=0x%p bp=0x%p clen=%d slen=%d tlen=%d flags=%x", 3789 ap->a_target, (void *)pkt, (void *)bp, 3790 cmdlen, statuslen, tgtlen, flags)); 3791 3792 /* 3793 * Allocate the new packet. 3794 */ 3795 if (pkt == NULL) { 3796 ddi_dma_handle_t save_dma_handle; 3797 3798 cmd = kmem_cache_alloc(mpt->m_kmem_cache, kf); 3799 if (cmd == NULL) 3800 return (NULL); 3801 3802 save_dma_handle = cmd->cmd_dmahandle; 3803 bzero(cmd, sizeof (*cmd) + scsi_pkt_size()); 3804 cmd->cmd_dmahandle = save_dma_handle; 3805 3806 pkt = (void *)((uchar_t *)cmd + 3807 sizeof (struct mptsas_cmd)); 3808 pkt->pkt_ha_private = (opaque_t)cmd; 3809 pkt->pkt_address = *ap; 3810 pkt->pkt_private = (opaque_t)cmd->cmd_pkt_private; 3811 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; 3812 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb; 3813 cmd->cmd_pkt = (struct scsi_pkt *)pkt; 3814 cmd->cmd_cdblen = (uchar_t)cmdlen; 3815 cmd->cmd_scblen = statuslen; 3816 cmd->cmd_rqslen = SENSE_LENGTH; 3817 cmd->cmd_tgt_addr = ptgt; 3818 3819 if ((cmdlen > sizeof (cmd->cmd_cdb)) || 3820 (tgtlen > PKT_PRIV_LEN) || 3821 (statuslen > EXTCMDS_STATUS_SIZE)) { 3822 int failure; 3823 3824 /* 3825 * We are going to allocate external packet space which 3826 * might include the sense data buffer for DMA so we 3827 * need to increase the reference counter here. In a 3828 * case the HBA is in reset we just simply free the 3829 * allocated packet and bail out. 3830 */ 3831 mutex_enter(&mpt->m_mutex); 3832 if (mpt->m_in_reset) { 3833 mutex_exit(&mpt->m_mutex); 3834 3835 cmd->cmd_flags = CFLAG_FREE; 3836 kmem_cache_free(mpt->m_kmem_cache, cmd); 3837 return (NULL); 3838 } 3839 mpt->m_extreq_sense_refcount++; 3840 ASSERT(mpt->m_extreq_sense_refcount > 0); 3841 mutex_exit(&mpt->m_mutex); 3842 3843 /* 3844 * if extern alloc fails, all will be 3845 * deallocated, including cmd 3846 */ 3847 failure = mptsas_pkt_alloc_extern(mpt, cmd, 3848 cmdlen, tgtlen, statuslen, kf); 3849 3850 if (failure != 0 || cmd->cmd_extrqslen == 0) { 3851 /* 3852 * If the external packet space allocation 3853 * failed, or we didn't allocate the sense 3854 * data buffer for DMA we need to decrease the 3855 * reference counter. 3856 */ 3857 mutex_enter(&mpt->m_mutex); 3858 ASSERT(mpt->m_extreq_sense_refcount > 0); 3859 mpt->m_extreq_sense_refcount--; 3860 if (mpt->m_extreq_sense_refcount == 0) 3861 cv_broadcast( 3862 &mpt->m_extreq_sense_refcount_cv); 3863 mutex_exit(&mpt->m_mutex); 3864 3865 if (failure != 0) { 3866 /* 3867 * if extern allocation fails, it will 3868 * deallocate the new pkt as well 3869 */ 3870 return (NULL); 3871 } 3872 } 3873 } 3874 new_cmd = cmd; 3875 3876 } else { 3877 cmd = PKT2CMD(pkt); 3878 new_cmd = NULL; 3879 } 3880 3881 3882 /* grab cmd->cmd_cookiec here as oldcookiec */ 3883 3884 oldcookiec = cmd->cmd_cookiec; 3885 3886 /* 3887 * If the dma was broken up into PARTIAL transfers cmd_nwin will be 3888 * greater than 0 and we'll need to grab the next dma window 3889 */ 3890 /* 3891 * SLM-not doing extra command frame right now; may add later 3892 */ 3893 3894 if (cmd->cmd_nwin > 0) { 3895 3896 /* 3897 * Make sure we havn't gone past the the total number 3898 * of windows 3899 */ 3900 if (++cmd->cmd_winindex >= cmd->cmd_nwin) { 3901 return (NULL); 3902 } 3903 if (ddi_dma_getwin(cmd->cmd_dmahandle, cmd->cmd_winindex, 3904 &cmd->cmd_dma_offset, &cmd->cmd_dma_len, 3905 &cmd->cmd_cookie, &cmd->cmd_cookiec) == DDI_FAILURE) { 3906 return (NULL); 3907 } 3908 goto get_dma_cookies; 3909 } 3910 3911 3912 if (flags & PKT_XARQ) { 3913 cmd->cmd_flags |= CFLAG_XARQ; 3914 } 3915 3916 /* 3917 * DMA resource allocation. This version assumes your 3918 * HBA has some sort of bus-mastering or onboard DMA capability, with a 3919 * scatter-gather list of length MPTSAS_MAX_DMA_SEGS, as given in the 3920 * ddi_dma_attr_t structure and passed to scsi_impl_dmaget. 3921 */ 3922 if (bp && (bp->b_bcount != 0) && 3923 (cmd->cmd_flags & CFLAG_DMAVALID) == 0) { 3924 3925 int cnt, dma_flags; 3926 mptti_t *dmap; /* ptr to the S/G list */ 3927 3928 /* 3929 * Set up DMA memory and position to the next DMA segment. 3930 */ 3931 ASSERT(cmd->cmd_dmahandle != NULL); 3932 3933 if (bp->b_flags & B_READ) { 3934 dma_flags = DDI_DMA_READ; 3935 cmd->cmd_flags &= ~CFLAG_DMASEND; 3936 } else { 3937 dma_flags = DDI_DMA_WRITE; 3938 cmd->cmd_flags |= CFLAG_DMASEND; 3939 } 3940 if (flags & PKT_CONSISTENT) { 3941 cmd->cmd_flags |= CFLAG_CMDIOPB; 3942 dma_flags |= DDI_DMA_CONSISTENT; 3943 } 3944 3945 if (flags & PKT_DMA_PARTIAL) { 3946 dma_flags |= DDI_DMA_PARTIAL; 3947 } 3948 3949 /* 3950 * workaround for byte hole issue on psycho and 3951 * schizo pre 2.1 3952 */ 3953 if ((bp->b_flags & B_READ) && ((bp->b_flags & 3954 (B_PAGEIO|B_REMAPPED)) != B_PAGEIO) && 3955 ((uintptr_t)bp->b_un.b_addr & 0x7)) { 3956 dma_flags |= DDI_DMA_CONSISTENT; 3957 } 3958 3959 rval = ddi_dma_buf_bind_handle(cmd->cmd_dmahandle, bp, 3960 dma_flags, callback, arg, 3961 &cmd->cmd_cookie, &cmd->cmd_cookiec); 3962 if (rval == DDI_DMA_PARTIAL_MAP) { 3963 (void) ddi_dma_numwin(cmd->cmd_dmahandle, 3964 &cmd->cmd_nwin); 3965 cmd->cmd_winindex = 0; 3966 (void) ddi_dma_getwin(cmd->cmd_dmahandle, 3967 cmd->cmd_winindex, &cmd->cmd_dma_offset, 3968 &cmd->cmd_dma_len, &cmd->cmd_cookie, 3969 &cmd->cmd_cookiec); 3970 } else if (rval && (rval != DDI_DMA_MAPPED)) { 3971 switch (rval) { 3972 case DDI_DMA_NORESOURCES: 3973 bioerror(bp, 0); 3974 break; 3975 case DDI_DMA_BADATTR: 3976 case DDI_DMA_NOMAPPING: 3977 bioerror(bp, EFAULT); 3978 break; 3979 case DDI_DMA_TOOBIG: 3980 default: 3981 bioerror(bp, EINVAL); 3982 break; 3983 } 3984 cmd->cmd_flags &= ~CFLAG_DMAVALID; 3985 if (new_cmd) { 3986 mptsas_scsi_destroy_pkt(ap, pkt); 3987 } 3988 return ((struct scsi_pkt *)NULL); 3989 } 3990 3991 get_dma_cookies: 3992 cmd->cmd_flags |= CFLAG_DMAVALID; 3993 ASSERT(cmd->cmd_cookiec > 0); 3994 3995 if (cmd->cmd_cookiec > MPTSAS_MAX_CMD_SEGS) { 3996 mptsas_log(mpt, CE_NOTE, "large cookiec received %d\n", 3997 cmd->cmd_cookiec); 3998 bioerror(bp, EINVAL); 3999 if (new_cmd) { 4000 mptsas_scsi_destroy_pkt(ap, pkt); 4001 } 4002 return ((struct scsi_pkt *)NULL); 4003 } 4004 4005 /* 4006 * Allocate extra SGL buffer if needed. 4007 */ 4008 if ((cmd->cmd_cookiec > MPTSAS_MAX_FRAME_SGES64(mpt)) && 4009 (cmd->cmd_extra_frames == NULL)) { 4010 if (mptsas_alloc_extra_sgl_frame(mpt, cmd) == 4011 DDI_FAILURE) { 4012 mptsas_log(mpt, CE_WARN, "MPT SGL mem alloc " 4013 "failed"); 4014 bioerror(bp, ENOMEM); 4015 if (new_cmd) { 4016 mptsas_scsi_destroy_pkt(ap, pkt); 4017 } 4018 return ((struct scsi_pkt *)NULL); 4019 } 4020 } 4021 4022 /* 4023 * Always use scatter-gather transfer 4024 * Use the loop below to store physical addresses of 4025 * DMA segments, from the DMA cookies, into your HBA's 4026 * scatter-gather list. 4027 * We need to ensure we have enough kmem alloc'd 4028 * for the sg entries since we are no longer using an 4029 * array inside mptsas_cmd_t. 4030 * 4031 * We check cmd->cmd_cookiec against oldcookiec so 4032 * the scatter-gather list is correctly allocated 4033 */ 4034 4035 if (oldcookiec != cmd->cmd_cookiec) { 4036 if (cmd->cmd_sg != (mptti_t *)NULL) { 4037 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * 4038 oldcookiec); 4039 cmd->cmd_sg = NULL; 4040 } 4041 } 4042 4043 if (cmd->cmd_sg == (mptti_t *)NULL) { 4044 cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)* 4045 cmd->cmd_cookiec), kf); 4046 4047 if (cmd->cmd_sg == (mptti_t *)NULL) { 4048 mptsas_log(mpt, CE_WARN, 4049 "unable to kmem_alloc enough memory " 4050 "for scatter/gather list"); 4051 /* 4052 * if we have an ENOMEM condition we need to behave 4053 * the same way as the rest of this routine 4054 */ 4055 4056 bioerror(bp, ENOMEM); 4057 if (new_cmd) { 4058 mptsas_scsi_destroy_pkt(ap, pkt); 4059 } 4060 return ((struct scsi_pkt *)NULL); 4061 } 4062 } 4063 4064 dmap = cmd->cmd_sg; 4065 4066 ASSERT(cmd->cmd_cookie.dmac_size != 0); 4067 4068 /* 4069 * store the first segment into the S/G list 4070 */ 4071 dmap->count = cmd->cmd_cookie.dmac_size; 4072 dmap->addr.address64.Low = (uint32_t) 4073 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull); 4074 dmap->addr.address64.High = (uint32_t) 4075 (cmd->cmd_cookie.dmac_laddress >> 32); 4076 4077 /* 4078 * dmacount counts the size of the dma for this window 4079 * (if partial dma is being used). totaldmacount 4080 * keeps track of the total amount of dma we have 4081 * transferred for all the windows (needed to calculate 4082 * the resid value below). 4083 */ 4084 cmd->cmd_dmacount = cmd->cmd_cookie.dmac_size; 4085 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size; 4086 4087 /* 4088 * We already stored the first DMA scatter gather segment, 4089 * start at 1 if we need to store more. 4090 */ 4091 for (cnt = 1; cnt < cmd->cmd_cookiec; cnt++) { 4092 /* 4093 * Get next DMA cookie 4094 */ 4095 ddi_dma_nextcookie(cmd->cmd_dmahandle, 4096 &cmd->cmd_cookie); 4097 dmap++; 4098 4099 cmd->cmd_dmacount += cmd->cmd_cookie.dmac_size; 4100 cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size; 4101 4102 /* 4103 * store the segment parms into the S/G list 4104 */ 4105 dmap->count = cmd->cmd_cookie.dmac_size; 4106 dmap->addr.address64.Low = (uint32_t) 4107 (cmd->cmd_cookie.dmac_laddress & 0xffffffffull); 4108 dmap->addr.address64.High = (uint32_t) 4109 (cmd->cmd_cookie.dmac_laddress >> 32); 4110 } 4111 4112 /* 4113 * If this was partially allocated we set the resid 4114 * the amount of data NOT transferred in this window 4115 * If there is only one window, the resid will be 0 4116 */ 4117 pkt->pkt_resid = (bp->b_bcount - cmd->cmd_totaldmacount); 4118 NDBG3(("mptsas_scsi_init_pkt: cmd_dmacount=%d.", 4119 cmd->cmd_dmacount)); 4120 } 4121 return (pkt); 4122 } 4123 4124 /* 4125 * tran_destroy_pkt(9E) - scsi_pkt(9s) deallocation 4126 * 4127 * Notes: 4128 * - also frees DMA resources if allocated 4129 * - implicit DMA synchonization 4130 */ 4131 static void 4132 mptsas_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 4133 { 4134 mptsas_cmd_t *cmd = PKT2CMD(pkt); 4135 mptsas_t *mpt = ADDR2MPT(ap); 4136 4137 NDBG3(("mptsas_scsi_destroy_pkt: target=%d pkt=0x%p", 4138 ap->a_target, (void *)pkt)); 4139 4140 if (cmd->cmd_flags & CFLAG_DMAVALID) { 4141 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle); 4142 cmd->cmd_flags &= ~CFLAG_DMAVALID; 4143 } 4144 4145 if (cmd->cmd_sg) { 4146 kmem_free(cmd->cmd_sg, sizeof (mptti_t) * cmd->cmd_cookiec); 4147 cmd->cmd_sg = NULL; 4148 } 4149 4150 mptsas_free_extra_sgl_frame(mpt, cmd); 4151 4152 if ((cmd->cmd_flags & 4153 (CFLAG_FREE | CFLAG_CDBEXTERN | CFLAG_PRIVEXTERN | 4154 CFLAG_SCBEXTERN)) == 0) { 4155 cmd->cmd_flags = CFLAG_FREE; 4156 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd); 4157 } else { 4158 boolean_t extrqslen = cmd->cmd_extrqslen != 0; 4159 4160 mptsas_pkt_destroy_extern(mpt, cmd); 4161 4162 /* 4163 * If the packet had the sense data buffer for DMA allocated we 4164 * need to decrease the reference counter. 4165 */ 4166 if (extrqslen) { 4167 mutex_enter(&mpt->m_mutex); 4168 ASSERT(mpt->m_extreq_sense_refcount > 0); 4169 mpt->m_extreq_sense_refcount--; 4170 if (mpt->m_extreq_sense_refcount == 0) 4171 cv_broadcast(&mpt->m_extreq_sense_refcount_cv); 4172 mutex_exit(&mpt->m_mutex); 4173 } 4174 } 4175 } 4176 4177 /* 4178 * kmem cache constructor and destructor: 4179 * When constructing, we bzero the cmd and allocate the dma handle 4180 * When destructing, just free the dma handle 4181 */ 4182 static int 4183 mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags) 4184 { 4185 mptsas_cmd_t *cmd = buf; 4186 mptsas_t *mpt = cdrarg; 4187 int (*callback)(caddr_t); 4188 4189 callback = (kmflags == KM_SLEEP)? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT; 4190 4191 NDBG4(("mptsas_kmem_cache_constructor")); 4192 4193 /* 4194 * allocate a dma handle 4195 */ 4196 if ((ddi_dma_alloc_handle(mpt->m_dip, &mpt->m_io_dma_attr, callback, 4197 NULL, &cmd->cmd_dmahandle)) != DDI_SUCCESS) { 4198 cmd->cmd_dmahandle = NULL; 4199 return (-1); 4200 } 4201 return (0); 4202 } 4203 4204 static void 4205 mptsas_kmem_cache_destructor(void *buf, void *cdrarg) 4206 { 4207 #ifndef __lock_lint 4208 _NOTE(ARGUNUSED(cdrarg)) 4209 #endif 4210 mptsas_cmd_t *cmd = buf; 4211 4212 NDBG4(("mptsas_kmem_cache_destructor")); 4213 4214 if (cmd->cmd_dmahandle) { 4215 ddi_dma_free_handle(&cmd->cmd_dmahandle); 4216 cmd->cmd_dmahandle = NULL; 4217 } 4218 } 4219 4220 static int 4221 mptsas_cache_frames_constructor(void *buf, void *cdrarg, int kmflags) 4222 { 4223 mptsas_cache_frames_t *p = buf; 4224 mptsas_t *mpt = cdrarg; 4225 ddi_dma_attr_t frame_dma_attr; 4226 size_t mem_size, alloc_len; 4227 ddi_dma_cookie_t cookie; 4228 uint_t ncookie; 4229 int (*callback)(caddr_t) = (kmflags == KM_SLEEP) 4230 ? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT; 4231 4232 frame_dma_attr = mpt->m_msg_dma_attr; 4233 frame_dma_attr.dma_attr_align = 0x10; 4234 frame_dma_attr.dma_attr_sgllen = 1; 4235 4236 if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attr, callback, NULL, 4237 &p->m_dma_hdl) != DDI_SUCCESS) { 4238 mptsas_log(mpt, CE_WARN, "Unable to allocate dma handle for" 4239 " extra SGL."); 4240 return (DDI_FAILURE); 4241 } 4242 4243 mem_size = (mpt->m_max_request_frames - 1) * mpt->m_req_frame_size; 4244 4245 if (ddi_dma_mem_alloc(p->m_dma_hdl, mem_size, &mpt->m_dev_acc_attr, 4246 DDI_DMA_CONSISTENT, callback, NULL, (caddr_t *)&p->m_frames_addr, 4247 &alloc_len, &p->m_acc_hdl) != DDI_SUCCESS) { 4248 ddi_dma_free_handle(&p->m_dma_hdl); 4249 p->m_dma_hdl = NULL; 4250 mptsas_log(mpt, CE_WARN, "Unable to allocate dma memory for" 4251 " extra SGL."); 4252 return (DDI_FAILURE); 4253 } 4254 4255 if (ddi_dma_addr_bind_handle(p->m_dma_hdl, NULL, p->m_frames_addr, 4256 alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, callback, NULL, 4257 &cookie, &ncookie) != DDI_DMA_MAPPED) { 4258 (void) ddi_dma_mem_free(&p->m_acc_hdl); 4259 ddi_dma_free_handle(&p->m_dma_hdl); 4260 p->m_dma_hdl = NULL; 4261 mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources for" 4262 " extra SGL"); 4263 return (DDI_FAILURE); 4264 } 4265 4266 /* 4267 * Store the SGL memory address. This chip uses this 4268 * address to dma to and from the driver. The second 4269 * address is the address mpt uses to fill in the SGL. 4270 */ 4271 p->m_phys_addr = cookie.dmac_laddress; 4272 4273 return (DDI_SUCCESS); 4274 } 4275 4276 static void 4277 mptsas_cache_frames_destructor(void *buf, void *cdrarg) 4278 { 4279 #ifndef __lock_lint 4280 _NOTE(ARGUNUSED(cdrarg)) 4281 #endif 4282 mptsas_cache_frames_t *p = buf; 4283 if (p->m_dma_hdl != NULL) { 4284 (void) ddi_dma_unbind_handle(p->m_dma_hdl); 4285 (void) ddi_dma_mem_free(&p->m_acc_hdl); 4286 ddi_dma_free_handle(&p->m_dma_hdl); 4287 p->m_phys_addr = 0; 4288 p->m_frames_addr = NULL; 4289 p->m_dma_hdl = NULL; 4290 p->m_acc_hdl = NULL; 4291 } 4292 4293 } 4294 4295 /* 4296 * Figure out if we need to use a different method for the request 4297 * sense buffer and allocate from the map if necessary. 4298 */ 4299 static boolean_t 4300 mptsas_cmdarqsize(mptsas_t *mpt, mptsas_cmd_t *cmd, size_t senselength, int kf) 4301 { 4302 if (senselength > mpt->m_req_sense_size) { 4303 unsigned long i; 4304 4305 /* Sense length is limited to an 8 bit value in MPI Spec. */ 4306 if (senselength > 255) 4307 senselength = 255; 4308 cmd->cmd_extrqschunks = (senselength + 4309 (mpt->m_req_sense_size - 1))/mpt->m_req_sense_size; 4310 i = (kf == KM_SLEEP ? rmalloc_wait : rmalloc) 4311 (mpt->m_erqsense_map, cmd->cmd_extrqschunks); 4312 4313 if (i == 0) 4314 return (B_FALSE); 4315 4316 cmd->cmd_extrqslen = (uint16_t)senselength; 4317 cmd->cmd_extrqsidx = i - 1; 4318 cmd->cmd_arq_buf = mpt->m_extreq_sense + 4319 (cmd->cmd_extrqsidx * mpt->m_req_sense_size); 4320 } else { 4321 cmd->cmd_rqslen = (uchar_t)senselength; 4322 } 4323 4324 return (B_TRUE); 4325 } 4326 4327 /* 4328 * allocate and deallocate external pkt space (ie. not part of mptsas_cmd) 4329 * for non-standard length cdb, pkt_private, status areas 4330 * if allocation fails, then deallocate all external space and the pkt 4331 */ 4332 /* ARGSUSED */ 4333 static int 4334 mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd, 4335 int cmdlen, int tgtlen, int statuslen, int kf) 4336 { 4337 caddr_t cdbp, scbp, tgt; 4338 4339 NDBG3(("mptsas_pkt_alloc_extern: " 4340 "cmd=0x%p cmdlen=%d tgtlen=%d statuslen=%d kf=%x", 4341 (void *)cmd, cmdlen, tgtlen, statuslen, kf)); 4342 4343 tgt = cdbp = scbp = NULL; 4344 cmd->cmd_scblen = statuslen; 4345 cmd->cmd_privlen = (uchar_t)tgtlen; 4346 4347 if (cmdlen > sizeof (cmd->cmd_cdb)) { 4348 if ((cdbp = kmem_zalloc((size_t)cmdlen, kf)) == NULL) { 4349 goto fail; 4350 } 4351 cmd->cmd_pkt->pkt_cdbp = (opaque_t)cdbp; 4352 cmd->cmd_flags |= CFLAG_CDBEXTERN; 4353 } 4354 if (tgtlen > PKT_PRIV_LEN) { 4355 if ((tgt = kmem_zalloc((size_t)tgtlen, kf)) == NULL) { 4356 goto fail; 4357 } 4358 cmd->cmd_flags |= CFLAG_PRIVEXTERN; 4359 cmd->cmd_pkt->pkt_private = tgt; 4360 } 4361 if (statuslen > EXTCMDS_STATUS_SIZE) { 4362 if ((scbp = kmem_zalloc((size_t)statuslen, kf)) == NULL) { 4363 goto fail; 4364 } 4365 cmd->cmd_flags |= CFLAG_SCBEXTERN; 4366 cmd->cmd_pkt->pkt_scbp = (opaque_t)scbp; 4367 4368 /* allocate sense data buf for DMA */ 4369 if (mptsas_cmdarqsize(mpt, cmd, statuslen - 4370 MPTSAS_GET_ITEM_OFF(struct scsi_arq_status, sts_sensedata), 4371 kf) == B_FALSE) 4372 goto fail; 4373 } 4374 return (0); 4375 fail: 4376 mptsas_pkt_destroy_extern(mpt, cmd); 4377 return (1); 4378 } 4379 4380 /* 4381 * deallocate external pkt space and deallocate the pkt 4382 */ 4383 static void 4384 mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd) 4385 { 4386 NDBG3(("mptsas_pkt_destroy_extern: cmd=0x%p", (void *)cmd)); 4387 4388 if (cmd->cmd_flags & CFLAG_FREE) { 4389 mptsas_log(mpt, CE_PANIC, 4390 "mptsas_pkt_destroy_extern: freeing free packet"); 4391 _NOTE(NOT_REACHED) 4392 /* NOTREACHED */ 4393 } 4394 if (cmd->cmd_extrqslen != 0) { 4395 rmfree(mpt->m_erqsense_map, cmd->cmd_extrqschunks, 4396 cmd->cmd_extrqsidx + 1); 4397 } 4398 if (cmd->cmd_flags & CFLAG_CDBEXTERN) { 4399 kmem_free(cmd->cmd_pkt->pkt_cdbp, (size_t)cmd->cmd_cdblen); 4400 } 4401 if (cmd->cmd_flags & CFLAG_SCBEXTERN) { 4402 kmem_free(cmd->cmd_pkt->pkt_scbp, (size_t)cmd->cmd_scblen); 4403 } 4404 if (cmd->cmd_flags & CFLAG_PRIVEXTERN) { 4405 kmem_free(cmd->cmd_pkt->pkt_private, (size_t)cmd->cmd_privlen); 4406 } 4407 cmd->cmd_flags = CFLAG_FREE; 4408 kmem_cache_free(mpt->m_kmem_cache, (void *)cmd); 4409 } 4410 4411 /* 4412 * tran_sync_pkt(9E) - explicit DMA synchronization 4413 */ 4414 /*ARGSUSED*/ 4415 static void 4416 mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt) 4417 { 4418 mptsas_cmd_t *cmd = PKT2CMD(pkt); 4419 4420 NDBG3(("mptsas_scsi_sync_pkt: target=%d, pkt=0x%p", 4421 ap->a_target, (void *)pkt)); 4422 4423 if (cmd->cmd_dmahandle) { 4424 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 4425 (cmd->cmd_flags & CFLAG_DMASEND) ? 4426 DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU); 4427 } 4428 } 4429 4430 /* 4431 * tran_dmafree(9E) - deallocate DMA resources allocated for command 4432 */ 4433 /*ARGSUSED*/ 4434 static void 4435 mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt) 4436 { 4437 mptsas_cmd_t *cmd = PKT2CMD(pkt); 4438 mptsas_t *mpt = ADDR2MPT(ap); 4439 4440 NDBG3(("mptsas_scsi_dmafree: target=%d pkt=0x%p", 4441 ap->a_target, (void *)pkt)); 4442 4443 if (cmd->cmd_flags & CFLAG_DMAVALID) { 4444 (void) ddi_dma_unbind_handle(cmd->cmd_dmahandle); 4445 cmd->cmd_flags &= ~CFLAG_DMAVALID; 4446 } 4447 4448 mptsas_free_extra_sgl_frame(mpt, cmd); 4449 } 4450 4451 static void 4452 mptsas_pkt_comp(struct scsi_pkt *pkt, mptsas_cmd_t *cmd) 4453 { 4454 if ((cmd->cmd_flags & CFLAG_CMDIOPB) && 4455 (!(cmd->cmd_flags & CFLAG_DMASEND))) { 4456 (void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0, 4457 DDI_DMA_SYNC_FORCPU); 4458 } 4459 (*pkt->pkt_comp)(pkt); 4460 } 4461 4462 static void 4463 mptsas_sge_mainframe(mptsas_cmd_t *cmd, pMpi2SCSIIORequest_t frame, 4464 ddi_acc_handle_t acc_hdl, uint_t cookiec, uint32_t end_flags) 4465 { 4466 pMpi2SGESimple64_t sge; 4467 mptti_t *dmap; 4468 uint32_t flags; 4469 4470 dmap = cmd->cmd_sg; 4471 4472 sge = (pMpi2SGESimple64_t)(&frame->SGL); 4473 while (cookiec--) { 4474 ddi_put32(acc_hdl, 4475 &sge->Address.Low, dmap->addr.address64.Low); 4476 ddi_put32(acc_hdl, 4477 &sge->Address.High, dmap->addr.address64.High); 4478 ddi_put32(acc_hdl, &sge->FlagsLength, 4479 dmap->count); 4480 flags = ddi_get32(acc_hdl, &sge->FlagsLength); 4481 flags |= ((uint32_t) 4482 (MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4483 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4484 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4485 MPI2_SGE_FLAGS_SHIFT); 4486 4487 /* 4488 * If this is the last cookie, we set the flags 4489 * to indicate so 4490 */ 4491 if (cookiec == 0) { 4492 flags |= end_flags; 4493 } 4494 if (cmd->cmd_flags & CFLAG_DMASEND) { 4495 flags |= (MPI2_SGE_FLAGS_HOST_TO_IOC << 4496 MPI2_SGE_FLAGS_SHIFT); 4497 } else { 4498 flags |= (MPI2_SGE_FLAGS_IOC_TO_HOST << 4499 MPI2_SGE_FLAGS_SHIFT); 4500 } 4501 ddi_put32(acc_hdl, &sge->FlagsLength, flags); 4502 dmap++; 4503 sge++; 4504 } 4505 } 4506 4507 static void 4508 mptsas_sge_chain(mptsas_t *mpt, mptsas_cmd_t *cmd, 4509 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl) 4510 { 4511 pMpi2SGESimple64_t sge; 4512 pMpi2SGEChain64_t sgechain; 4513 uint64_t nframe_phys_addr; 4514 uint_t cookiec; 4515 mptti_t *dmap; 4516 uint32_t flags; 4517 4518 /* 4519 * Save the number of entries in the DMA 4520 * Scatter/Gather list 4521 */ 4522 cookiec = cmd->cmd_cookiec; 4523 4524 /* 4525 * Hereby we start to deal with multiple frames. 4526 * The process is as follows: 4527 * 1. Determine how many frames are needed for SGL element 4528 * storage; Note that all frames are stored in contiguous 4529 * memory space and in 64-bit DMA mode each element is 4530 * 3 double-words (12 bytes) long. 4531 * 2. Fill up the main frame. We need to do this separately 4532 * since it contains the SCSI IO request header and needs 4533 * dedicated processing. Note that the last 4 double-words 4534 * of the SCSI IO header is for SGL element storage 4535 * (MPI2_SGE_IO_UNION). 4536 * 3. Fill the chain element in the main frame, so the DMA 4537 * engine can use the following frames. 4538 * 4. Enter a loop to fill the remaining frames. Note that the 4539 * last frame contains no chain element. The remaining 4540 * frames go into the mpt SGL buffer allocated on the fly, 4541 * not immediately following the main message frame, as in 4542 * Gen1. 4543 * Some restrictions: 4544 * 1. For 64-bit DMA, the simple element and chain element 4545 * are both of 3 double-words (12 bytes) in size, even 4546 * though all frames are stored in the first 4G of mem 4547 * range and the higher 32-bits of the address are always 0. 4548 * 2. On some controllers (like the 1064/1068), a frame can 4549 * hold SGL elements with the last 1 or 2 double-words 4550 * (4 or 8 bytes) un-used. On these controllers, we should 4551 * recognize that there's not enough room for another SGL 4552 * element and move the sge pointer to the next frame. 4553 */ 4554 int i, j, k, l, frames, sgemax; 4555 int temp; 4556 uint8_t chainflags; 4557 uint16_t chainlength; 4558 mptsas_cache_frames_t *p; 4559 4560 /* 4561 * Sgemax is the number of SGE's that will fit 4562 * each extra frame and frames is total 4563 * number of frames we'll need. 1 sge entry per 4564 * frame is reseverd for the chain element thus the -1 below. 4565 */ 4566 sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_SGE_SIMPLE64)) 4567 - 1); 4568 temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax; 4569 4570 /* 4571 * A little check to see if we need to round up the number 4572 * of frames we need 4573 */ 4574 if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp * 4575 sgemax) > 1) { 4576 frames = (temp + 1); 4577 } else { 4578 frames = temp; 4579 } 4580 dmap = cmd->cmd_sg; 4581 sge = (pMpi2SGESimple64_t)(&frame->SGL); 4582 4583 /* 4584 * First fill in the main frame 4585 */ 4586 j = MPTSAS_MAX_FRAME_SGES64(mpt) - 1; 4587 mptsas_sge_mainframe(cmd, frame, acc_hdl, j, 4588 ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT) << 4589 MPI2_SGE_FLAGS_SHIFT)); 4590 dmap += j; 4591 sge += j; 4592 j++; 4593 4594 /* 4595 * Fill in the chain element in the main frame. 4596 * About calculation on ChainOffset: 4597 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes) 4598 * in the end reserved for SGL element storage 4599 * (MPI2_SGE_IO_UNION); we should count it in our 4600 * calculation. See its definition in the header file. 4601 * 2. Constant j is the counter of the current SGL element 4602 * that will be processed, and (j - 1) is the number of 4603 * SGL elements that have been processed (stored in the 4604 * main frame). 4605 * 3. ChainOffset value should be in units of double-words (4 4606 * bytes) so the last value should be divided by 4. 4607 */ 4608 ddi_put8(acc_hdl, &frame->ChainOffset, 4609 (sizeof (MPI2_SCSI_IO_REQUEST) - 4610 sizeof (MPI2_SGE_IO_UNION) + 4611 (j - 1) * sizeof (MPI2_SGE_SIMPLE64)) >> 2); 4612 sgechain = (pMpi2SGEChain64_t)sge; 4613 chainflags = (MPI2_SGE_FLAGS_CHAIN_ELEMENT | 4614 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4615 MPI2_SGE_FLAGS_64_BIT_ADDRESSING); 4616 ddi_put8(acc_hdl, &sgechain->Flags, chainflags); 4617 4618 /* 4619 * The size of the next frame is the accurate size of space 4620 * (in bytes) used to store the SGL elements. j is the counter 4621 * of SGL elements. (j - 1) is the number of SGL elements that 4622 * have been processed (stored in frames). 4623 */ 4624 if (frames >= 2) { 4625 ASSERT(mpt->m_req_frame_size >= sizeof (MPI2_SGE_SIMPLE64)); 4626 chainlength = mpt->m_req_frame_size / 4627 sizeof (MPI2_SGE_SIMPLE64) * 4628 sizeof (MPI2_SGE_SIMPLE64); 4629 } else { 4630 chainlength = ((cookiec - (j - 1)) * 4631 sizeof (MPI2_SGE_SIMPLE64)); 4632 } 4633 4634 p = cmd->cmd_extra_frames; 4635 4636 ddi_put16(acc_hdl, &sgechain->Length, chainlength); 4637 ddi_put32(acc_hdl, &sgechain->Address.Low, p->m_phys_addr); 4638 ddi_put32(acc_hdl, &sgechain->Address.High, p->m_phys_addr >> 32); 4639 4640 /* 4641 * If there are more than 2 frames left we have to 4642 * fill in the next chain offset to the location of 4643 * the chain element in the next frame. 4644 * sgemax is the number of simple elements in an extra 4645 * frame. Note that the value NextChainOffset should be 4646 * in double-words (4 bytes). 4647 */ 4648 if (frames >= 2) { 4649 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 4650 (sgemax * sizeof (MPI2_SGE_SIMPLE64)) >> 2); 4651 } else { 4652 ddi_put8(acc_hdl, &sgechain->NextChainOffset, 0); 4653 } 4654 4655 /* 4656 * Jump to next frame; 4657 * Starting here, chain buffers go into the per command SGL. 4658 * This buffer is allocated when chain buffers are needed. 4659 */ 4660 sge = (pMpi2SGESimple64_t)p->m_frames_addr; 4661 i = cookiec; 4662 4663 /* 4664 * Start filling in frames with SGE's. If we 4665 * reach the end of frame and still have SGE's 4666 * to fill we need to add a chain element and 4667 * use another frame. j will be our counter 4668 * for what cookie we are at and i will be 4669 * the total cookiec. k is the current frame 4670 */ 4671 for (k = 1; k <= frames; k++) { 4672 for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) { 4673 4674 /* 4675 * If we have reached the end of frame 4676 * and we have more SGE's to fill in 4677 * we have to fill the final entry 4678 * with a chain element and then 4679 * continue to the next frame 4680 */ 4681 if ((l == (sgemax + 1)) && (k != frames)) { 4682 sgechain = (pMpi2SGEChain64_t)sge; 4683 j--; 4684 chainflags = ( 4685 MPI2_SGE_FLAGS_CHAIN_ELEMENT | 4686 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4687 MPI2_SGE_FLAGS_64_BIT_ADDRESSING); 4688 ddi_put8(p->m_acc_hdl, 4689 &sgechain->Flags, chainflags); 4690 /* 4691 * k is the frame counter and (k + 1) 4692 * is the number of the next frame. 4693 * Note that frames are in contiguous 4694 * memory space. 4695 */ 4696 nframe_phys_addr = p->m_phys_addr + 4697 (mpt->m_req_frame_size * k); 4698 ddi_put32(p->m_acc_hdl, 4699 &sgechain->Address.Low, 4700 nframe_phys_addr); 4701 ddi_put32(p->m_acc_hdl, 4702 &sgechain->Address.High, 4703 nframe_phys_addr >> 32); 4704 4705 /* 4706 * If there are more than 2 frames left 4707 * we have to next chain offset to 4708 * the location of the chain element 4709 * in the next frame and fill in the 4710 * length of the next chain 4711 */ 4712 if ((frames - k) >= 2) { 4713 ddi_put8(p->m_acc_hdl, 4714 &sgechain->NextChainOffset, 4715 (sgemax * 4716 sizeof (MPI2_SGE_SIMPLE64)) 4717 >> 2); 4718 ddi_put16(p->m_acc_hdl, 4719 &sgechain->Length, 4720 mpt->m_req_frame_size / 4721 sizeof (MPI2_SGE_SIMPLE64) * 4722 sizeof (MPI2_SGE_SIMPLE64)); 4723 } else { 4724 /* 4725 * This is the last frame. Set 4726 * the NextChainOffset to 0 and 4727 * Length is the total size of 4728 * all remaining simple elements 4729 */ 4730 ddi_put8(p->m_acc_hdl, 4731 &sgechain->NextChainOffset, 4732 0); 4733 ddi_put16(p->m_acc_hdl, 4734 &sgechain->Length, 4735 (cookiec - j) * 4736 sizeof (MPI2_SGE_SIMPLE64)); 4737 } 4738 4739 /* Jump to the next frame */ 4740 sge = (pMpi2SGESimple64_t) 4741 ((char *)p->m_frames_addr + 4742 (int)mpt->m_req_frame_size * k); 4743 4744 continue; 4745 } 4746 4747 ddi_put32(p->m_acc_hdl, 4748 &sge->Address.Low, 4749 dmap->addr.address64.Low); 4750 ddi_put32(p->m_acc_hdl, 4751 &sge->Address.High, 4752 dmap->addr.address64.High); 4753 ddi_put32(p->m_acc_hdl, 4754 &sge->FlagsLength, dmap->count); 4755 flags = ddi_get32(p->m_acc_hdl, 4756 &sge->FlagsLength); 4757 flags |= ((uint32_t)( 4758 MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 4759 MPI2_SGE_FLAGS_SYSTEM_ADDRESS | 4760 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 4761 MPI2_SGE_FLAGS_SHIFT); 4762 4763 /* 4764 * If we are at the end of the frame and 4765 * there is another frame to fill in 4766 * we set the last simple element as last 4767 * element 4768 */ 4769 if ((l == sgemax) && (k != frames)) { 4770 flags |= ((uint32_t) 4771 (MPI2_SGE_FLAGS_LAST_ELEMENT) << 4772 MPI2_SGE_FLAGS_SHIFT); 4773 } 4774 4775 /* 4776 * If this is the final cookie we 4777 * indicate it by setting the flags 4778 */ 4779 if (j == i) { 4780 flags |= ((uint32_t) 4781 (MPI2_SGE_FLAGS_LAST_ELEMENT | 4782 MPI2_SGE_FLAGS_END_OF_BUFFER | 4783 MPI2_SGE_FLAGS_END_OF_LIST) << 4784 MPI2_SGE_FLAGS_SHIFT); 4785 } 4786 if (cmd->cmd_flags & CFLAG_DMASEND) { 4787 flags |= 4788 (MPI2_SGE_FLAGS_HOST_TO_IOC << 4789 MPI2_SGE_FLAGS_SHIFT); 4790 } else { 4791 flags |= 4792 (MPI2_SGE_FLAGS_IOC_TO_HOST << 4793 MPI2_SGE_FLAGS_SHIFT); 4794 } 4795 ddi_put32(p->m_acc_hdl, 4796 &sge->FlagsLength, flags); 4797 dmap++; 4798 sge++; 4799 } 4800 } 4801 4802 /* 4803 * Sync DMA with the chain buffers that were just created 4804 */ 4805 (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 4806 } 4807 4808 static void 4809 mptsas_ieee_sge_mainframe(mptsas_cmd_t *cmd, pMpi2SCSIIORequest_t frame, 4810 ddi_acc_handle_t acc_hdl, uint_t cookiec, uint8_t end_flag) 4811 { 4812 pMpi2IeeeSgeSimple64_t ieeesge; 4813 mptti_t *dmap; 4814 uint8_t flags; 4815 4816 dmap = cmd->cmd_sg; 4817 4818 NDBG1(("mptsas_ieee_sge_mainframe: cookiec=%d, %s", cookiec, 4819 cmd->cmd_flags & CFLAG_DMASEND?"Out":"In")); 4820 4821 ieeesge = (pMpi2IeeeSgeSimple64_t)(&frame->SGL); 4822 while (cookiec--) { 4823 ddi_put32(acc_hdl, 4824 &ieeesge->Address.Low, dmap->addr.address64.Low); 4825 ddi_put32(acc_hdl, 4826 &ieeesge->Address.High, dmap->addr.address64.High); 4827 ddi_put32(acc_hdl, &ieeesge->Length, 4828 dmap->count); 4829 NDBG1(("mptsas_ieee_sge_mainframe: len=%d", dmap->count)); 4830 flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | 4831 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR); 4832 4833 /* 4834 * If this is the last cookie, we set the flags 4835 * to indicate so 4836 */ 4837 if (cookiec == 0) { 4838 flags |= end_flag; 4839 } 4840 4841 ddi_put8(acc_hdl, &ieeesge->Flags, flags); 4842 dmap++; 4843 ieeesge++; 4844 } 4845 } 4846 4847 static void 4848 mptsas_ieee_sge_chain(mptsas_t *mpt, mptsas_cmd_t *cmd, 4849 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl) 4850 { 4851 pMpi2IeeeSgeSimple64_t ieeesge; 4852 pMpi25IeeeSgeChain64_t ieeesgechain; 4853 uint64_t nframe_phys_addr; 4854 uint_t cookiec; 4855 mptti_t *dmap; 4856 uint8_t flags; 4857 4858 /* 4859 * Save the number of entries in the DMA 4860 * Scatter/Gather list 4861 */ 4862 cookiec = cmd->cmd_cookiec; 4863 4864 NDBG1(("mptsas_ieee_sge_chain: cookiec=%d", cookiec)); 4865 4866 /* 4867 * Hereby we start to deal with multiple frames. 4868 * The process is as follows: 4869 * 1. Determine how many frames are needed for SGL element 4870 * storage; Note that all frames are stored in contiguous 4871 * memory space and in 64-bit DMA mode each element is 4872 * 4 double-words (16 bytes) long. 4873 * 2. Fill up the main frame. We need to do this separately 4874 * since it contains the SCSI IO request header and needs 4875 * dedicated processing. Note that the last 4 double-words 4876 * of the SCSI IO header is for SGL element storage 4877 * (MPI2_SGE_IO_UNION). 4878 * 3. Fill the chain element in the main frame, so the DMA 4879 * engine can use the following frames. 4880 * 4. Enter a loop to fill the remaining frames. Note that the 4881 * last frame contains no chain element. The remaining 4882 * frames go into the mpt SGL buffer allocated on the fly, 4883 * not immediately following the main message frame, as in 4884 * Gen1. 4885 * Restrictions: 4886 * For 64-bit DMA, the simple element and chain element 4887 * are both of 4 double-words (16 bytes) in size, even 4888 * though all frames are stored in the first 4G of mem 4889 * range and the higher 32-bits of the address are always 0. 4890 */ 4891 int i, j, k, l, frames, sgemax; 4892 int temp; 4893 uint8_t chainflags; 4894 uint32_t chainlength; 4895 mptsas_cache_frames_t *p; 4896 4897 /* 4898 * Sgemax is the number of SGE's that will fit 4899 * each extra frame and frames is total 4900 * number of frames we'll need. 1 sge entry per 4901 * frame is reseverd for the chain element thus the -1 below. 4902 */ 4903 sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_IEEE_SGE_SIMPLE64)) 4904 - 1); 4905 temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax; 4906 4907 /* 4908 * A little check to see if we need to round up the number 4909 * of frames we need 4910 */ 4911 if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp * 4912 sgemax) > 1) { 4913 frames = (temp + 1); 4914 } else { 4915 frames = temp; 4916 } 4917 NDBG1(("mptsas_ieee_sge_chain: temp=%d, frames=%d", temp, frames)); 4918 dmap = cmd->cmd_sg; 4919 ieeesge = (pMpi2IeeeSgeSimple64_t)(&frame->SGL); 4920 4921 /* 4922 * First fill in the main frame 4923 */ 4924 j = MPTSAS_MAX_FRAME_SGES64(mpt) - 1; 4925 mptsas_ieee_sge_mainframe(cmd, frame, acc_hdl, j, 0); 4926 dmap += j; 4927 ieeesge += j; 4928 j++; 4929 4930 /* 4931 * Fill in the chain element in the main frame. 4932 * About calculation on ChainOffset: 4933 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes) 4934 * in the end reserved for SGL element storage 4935 * (MPI2_SGE_IO_UNION); we should count it in our 4936 * calculation. See its definition in the header file. 4937 * 2. Constant j is the counter of the current SGL element 4938 * that will be processed, and (j - 1) is the number of 4939 * SGL elements that have been processed (stored in the 4940 * main frame). 4941 * 3. ChainOffset value should be in units of quad-words (16 4942 * bytes) so the last value should be divided by 16. 4943 */ 4944 ddi_put8(acc_hdl, &frame->ChainOffset, 4945 (sizeof (MPI2_SCSI_IO_REQUEST) - 4946 sizeof (MPI2_SGE_IO_UNION) + 4947 (j - 1) * sizeof (MPI2_IEEE_SGE_SIMPLE64)) >> 4); 4948 ieeesgechain = (pMpi25IeeeSgeChain64_t)ieeesge; 4949 chainflags = (MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT | 4950 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR); 4951 ddi_put8(acc_hdl, &ieeesgechain->Flags, chainflags); 4952 4953 /* 4954 * The size of the next frame is the accurate size of space 4955 * (in bytes) used to store the SGL elements. j is the counter 4956 * of SGL elements. (j - 1) is the number of SGL elements that 4957 * have been processed (stored in frames). 4958 */ 4959 if (frames >= 2) { 4960 ASSERT(mpt->m_req_frame_size >= 4961 sizeof (MPI2_IEEE_SGE_SIMPLE64)); 4962 chainlength = mpt->m_req_frame_size / 4963 sizeof (MPI2_IEEE_SGE_SIMPLE64) * 4964 sizeof (MPI2_IEEE_SGE_SIMPLE64); 4965 } else { 4966 chainlength = ((cookiec - (j - 1)) * 4967 sizeof (MPI2_IEEE_SGE_SIMPLE64)); 4968 } 4969 4970 p = cmd->cmd_extra_frames; 4971 4972 ddi_put32(acc_hdl, &ieeesgechain->Length, chainlength); 4973 ddi_put32(acc_hdl, &ieeesgechain->Address.Low, p->m_phys_addr); 4974 ddi_put32(acc_hdl, &ieeesgechain->Address.High, p->m_phys_addr >> 32); 4975 4976 /* 4977 * If there are more than 2 frames left we have to 4978 * fill in the next chain offset to the location of 4979 * the chain element in the next frame. 4980 * sgemax is the number of simple elements in an extra 4981 * frame. Note that the value NextChainOffset should be 4982 * in double-words (4 bytes). 4983 */ 4984 if (frames >= 2) { 4985 ddi_put8(acc_hdl, &ieeesgechain->NextChainOffset, 4986 (sgemax * sizeof (MPI2_IEEE_SGE_SIMPLE64)) >> 4); 4987 } else { 4988 ddi_put8(acc_hdl, &ieeesgechain->NextChainOffset, 0); 4989 } 4990 4991 /* 4992 * Jump to next frame; 4993 * Starting here, chain buffers go into the per command SGL. 4994 * This buffer is allocated when chain buffers are needed. 4995 */ 4996 ieeesge = (pMpi2IeeeSgeSimple64_t)p->m_frames_addr; 4997 i = cookiec; 4998 4999 /* 5000 * Start filling in frames with SGE's. If we 5001 * reach the end of frame and still have SGE's 5002 * to fill we need to add a chain element and 5003 * use another frame. j will be our counter 5004 * for what cookie we are at and i will be 5005 * the total cookiec. k is the current frame 5006 */ 5007 for (k = 1; k <= frames; k++) { 5008 for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) { 5009 5010 /* 5011 * If we have reached the end of frame 5012 * and we have more SGE's to fill in 5013 * we have to fill the final entry 5014 * with a chain element and then 5015 * continue to the next frame 5016 */ 5017 if ((l == (sgemax + 1)) && (k != frames)) { 5018 ieeesgechain = (pMpi25IeeeSgeChain64_t)ieeesge; 5019 j--; 5020 chainflags = 5021 MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT | 5022 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR; 5023 ddi_put8(p->m_acc_hdl, 5024 &ieeesgechain->Flags, chainflags); 5025 /* 5026 * k is the frame counter and (k + 1) 5027 * is the number of the next frame. 5028 * Note that frames are in contiguous 5029 * memory space. 5030 */ 5031 nframe_phys_addr = p->m_phys_addr + 5032 (mpt->m_req_frame_size * k); 5033 ddi_put32(p->m_acc_hdl, 5034 &ieeesgechain->Address.Low, 5035 nframe_phys_addr); 5036 ddi_put32(p->m_acc_hdl, 5037 &ieeesgechain->Address.High, 5038 nframe_phys_addr >> 32); 5039 5040 /* 5041 * If there are more than 2 frames left 5042 * we have to next chain offset to 5043 * the location of the chain element 5044 * in the next frame and fill in the 5045 * length of the next chain 5046 */ 5047 if ((frames - k) >= 2) { 5048 ddi_put8(p->m_acc_hdl, 5049 &ieeesgechain->NextChainOffset, 5050 (sgemax * 5051 sizeof (MPI2_IEEE_SGE_SIMPLE64)) 5052 >> 4); 5053 ASSERT(mpt->m_req_frame_size >= 5054 sizeof (MPI2_IEEE_SGE_SIMPLE64)); 5055 ddi_put32(p->m_acc_hdl, 5056 &ieeesgechain->Length, 5057 mpt->m_req_frame_size / 5058 sizeof (MPI2_IEEE_SGE_SIMPLE64) * 5059 sizeof (MPI2_IEEE_SGE_SIMPLE64)); 5060 } else { 5061 /* 5062 * This is the last frame. Set 5063 * the NextChainOffset to 0 and 5064 * Length is the total size of 5065 * all remaining simple elements 5066 */ 5067 ddi_put8(p->m_acc_hdl, 5068 &ieeesgechain->NextChainOffset, 5069 0); 5070 ddi_put32(p->m_acc_hdl, 5071 &ieeesgechain->Length, 5072 (cookiec - j) * 5073 sizeof (MPI2_IEEE_SGE_SIMPLE64)); 5074 } 5075 5076 /* Jump to the next frame */ 5077 ieeesge = (pMpi2IeeeSgeSimple64_t) 5078 ((char *)p->m_frames_addr + 5079 (int)mpt->m_req_frame_size * k); 5080 5081 continue; 5082 } 5083 5084 ddi_put32(p->m_acc_hdl, 5085 &ieeesge->Address.Low, 5086 dmap->addr.address64.Low); 5087 ddi_put32(p->m_acc_hdl, 5088 &ieeesge->Address.High, 5089 dmap->addr.address64.High); 5090 ddi_put32(p->m_acc_hdl, 5091 &ieeesge->Length, dmap->count); 5092 flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | 5093 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR); 5094 5095 /* 5096 * If we are at the end of the frame and 5097 * there is another frame to fill in 5098 * do we need to do anything? 5099 * if ((l == sgemax) && (k != frames)) { 5100 * } 5101 */ 5102 5103 /* 5104 * If this is the final cookie set end of list. 5105 */ 5106 if (j == i) { 5107 flags |= MPI25_IEEE_SGE_FLAGS_END_OF_LIST; 5108 } 5109 5110 ddi_put8(p->m_acc_hdl, &ieeesge->Flags, flags); 5111 dmap++; 5112 ieeesge++; 5113 } 5114 } 5115 5116 /* 5117 * Sync DMA with the chain buffers that were just created 5118 */ 5119 (void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 5120 } 5121 5122 static void 5123 mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, uint32_t *control, 5124 pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl) 5125 { 5126 ASSERT(cmd->cmd_flags & CFLAG_DMAVALID); 5127 5128 NDBG1(("mptsas_sge_setup: cookiec=%d", cmd->cmd_cookiec)); 5129 5130 /* 5131 * Set read/write bit in control. 5132 */ 5133 if (cmd->cmd_flags & CFLAG_DMASEND) { 5134 *control |= MPI2_SCSIIO_CONTROL_WRITE; 5135 } else { 5136 *control |= MPI2_SCSIIO_CONTROL_READ; 5137 } 5138 5139 ddi_put32(acc_hdl, &frame->DataLength, cmd->cmd_dmacount); 5140 5141 /* 5142 * We have 4 cases here. First where we can fit all the 5143 * SG elements into the main frame, and the case 5144 * where we can't. The SG element is also different when using 5145 * MPI2.5 interface. 5146 * If we have more cookies than we can attach to a frame 5147 * we will need to use a chain element to point 5148 * a location of memory where the rest of the S/G 5149 * elements reside. 5150 */ 5151 if (cmd->cmd_cookiec <= MPTSAS_MAX_FRAME_SGES64(mpt)) { 5152 if (mpt->m_MPI25) { 5153 mptsas_ieee_sge_mainframe(cmd, frame, acc_hdl, 5154 cmd->cmd_cookiec, 5155 MPI25_IEEE_SGE_FLAGS_END_OF_LIST); 5156 } else { 5157 mptsas_sge_mainframe(cmd, frame, acc_hdl, 5158 cmd->cmd_cookiec, 5159 ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT 5160 | MPI2_SGE_FLAGS_END_OF_BUFFER 5161 | MPI2_SGE_FLAGS_END_OF_LIST) << 5162 MPI2_SGE_FLAGS_SHIFT)); 5163 } 5164 } else { 5165 if (mpt->m_MPI25) { 5166 mptsas_ieee_sge_chain(mpt, cmd, frame, acc_hdl); 5167 } else { 5168 mptsas_sge_chain(mpt, cmd, frame, acc_hdl); 5169 } 5170 } 5171 } 5172 5173 /* 5174 * Interrupt handling 5175 * Utility routine. Poll for status of a command sent to HBA 5176 * without interrupts (a FLAG_NOINTR command). 5177 */ 5178 int 5179 mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime) 5180 { 5181 int rval = TRUE; 5182 5183 NDBG5(("mptsas_poll: cmd=0x%p", (void *)poll_cmd)); 5184 5185 if ((poll_cmd->cmd_flags & CFLAG_TM_CMD) == 0) { 5186 mptsas_restart_hba(mpt); 5187 } 5188 5189 /* 5190 * Wait, using drv_usecwait(), long enough for the command to 5191 * reasonably return from the target if the target isn't 5192 * "dead". A polled command may well be sent from scsi_poll, and 5193 * there are retries built in to scsi_poll if the transport 5194 * accepted the packet (TRAN_ACCEPT). scsi_poll waits 1 second 5195 * and retries the transport up to scsi_poll_busycnt times 5196 * (currently 60) if 5197 * 1. pkt_reason is CMD_INCOMPLETE and pkt_state is 0, or 5198 * 2. pkt_reason is CMD_CMPLT and *pkt_scbp has STATUS_BUSY 5199 * 5200 * limit the waiting to avoid a hang in the event that the 5201 * cmd never gets started but we are still receiving interrupts 5202 */ 5203 while (!(poll_cmd->cmd_flags & CFLAG_FINISHED)) { 5204 if (mptsas_wait_intr(mpt, polltime) == FALSE) { 5205 NDBG5(("mptsas_poll: command incomplete")); 5206 rval = FALSE; 5207 break; 5208 } 5209 } 5210 5211 if (rval == FALSE) { 5212 5213 /* 5214 * this isn't supposed to happen, the hba must be wedged 5215 * Mark this cmd as a timeout. 5216 */ 5217 mptsas_set_pkt_reason(mpt, poll_cmd, CMD_TIMEOUT, 5218 (STAT_TIMEOUT|STAT_ABORTED)); 5219 5220 if (poll_cmd->cmd_queued == FALSE) { 5221 5222 NDBG5(("mptsas_poll: not on waitq")); 5223 5224 poll_cmd->cmd_pkt->pkt_state |= 5225 (STATE_GOT_BUS|STATE_GOT_TARGET|STATE_SENT_CMD); 5226 } else { 5227 5228 /* find and remove it from the waitq */ 5229 NDBG5(("mptsas_poll: delete from waitq")); 5230 mptsas_waitq_delete(mpt, poll_cmd); 5231 } 5232 5233 } 5234 mptsas_fma_check(mpt, poll_cmd); 5235 NDBG5(("mptsas_poll: done")); 5236 return (rval); 5237 } 5238 5239 /* 5240 * Used for polling cmds and TM function 5241 */ 5242 static int 5243 mptsas_wait_intr(mptsas_t *mpt, int polltime) 5244 { 5245 int cnt; 5246 pMpi2ReplyDescriptorsUnion_t reply_desc_union; 5247 uint32_t int_mask; 5248 5249 NDBG5(("mptsas_wait_intr")); 5250 5251 mpt->m_polled_intr = 1; 5252 5253 /* 5254 * Get the current interrupt mask and disable interrupts. When 5255 * re-enabling ints, set mask to saved value. 5256 */ 5257 int_mask = mptsas_hirrd(mpt, &mpt->m_reg->HostInterruptMask); 5258 MPTSAS_DISABLE_INTR(mpt); 5259 5260 /* 5261 * Keep polling for at least (polltime * 1000) seconds 5262 */ 5263 for (cnt = 0; cnt < polltime; cnt++) { 5264 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 5265 DDI_DMA_SYNC_FORCPU); 5266 5267 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t) 5268 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index); 5269 5270 if (ddi_get32(mpt->m_acc_post_queue_hdl, 5271 &reply_desc_union->Words.Low) == 0xFFFFFFFF || 5272 ddi_get32(mpt->m_acc_post_queue_hdl, 5273 &reply_desc_union->Words.High) == 0xFFFFFFFF) { 5274 drv_usecwait(1000); 5275 continue; 5276 } 5277 5278 /* 5279 * The reply is valid, process it according to its 5280 * type. 5281 */ 5282 mptsas_process_intr(mpt, reply_desc_union); 5283 5284 if (++mpt->m_post_index == mpt->m_post_queue_depth) { 5285 mpt->m_post_index = 0; 5286 } 5287 5288 /* 5289 * Update the global reply index 5290 */ 5291 ddi_put32(mpt->m_datap, 5292 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); 5293 mpt->m_polled_intr = 0; 5294 5295 /* 5296 * Re-enable interrupts and quit. 5297 */ 5298 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, 5299 int_mask); 5300 return (TRUE); 5301 5302 } 5303 5304 /* 5305 * Clear polling flag, re-enable interrupts and quit. 5306 */ 5307 mpt->m_polled_intr = 0; 5308 ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, int_mask); 5309 return (FALSE); 5310 } 5311 5312 static void 5313 mptsas_handle_scsi_io_success(mptsas_t *mpt, 5314 pMpi2ReplyDescriptorsUnion_t reply_desc) 5315 { 5316 pMpi2SCSIIOSuccessReplyDescriptor_t scsi_io_success; 5317 uint16_t SMID; 5318 mptsas_slots_t *slots = mpt->m_active; 5319 mptsas_cmd_t *cmd = NULL; 5320 struct scsi_pkt *pkt; 5321 5322 ASSERT(mutex_owned(&mpt->m_mutex)); 5323 5324 scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc; 5325 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &scsi_io_success->SMID); 5326 5327 /* 5328 * This is a success reply so just complete the IO. First, do a sanity 5329 * check on the SMID. The final slot is used for TM requests, which 5330 * would not come into this reply handler. 5331 */ 5332 if ((SMID == 0) || (SMID > slots->m_n_normal)) { 5333 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n", 5334 SMID); 5335 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 5336 return; 5337 } 5338 5339 cmd = slots->m_slot[SMID]; 5340 5341 /* 5342 * print warning and return if the slot is empty 5343 */ 5344 if (cmd == NULL) { 5345 mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO " 5346 "in slot %d", SMID); 5347 return; 5348 } 5349 5350 pkt = CMD2PKT(cmd); 5351 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD | 5352 STATE_GOT_STATUS); 5353 if (cmd->cmd_flags & CFLAG_DMAVALID) { 5354 pkt->pkt_state |= STATE_XFERRED_DATA; 5355 } 5356 pkt->pkt_resid = 0; 5357 5358 if (cmd->cmd_flags & CFLAG_PASSTHRU) { 5359 cmd->cmd_flags |= CFLAG_FINISHED; 5360 cv_broadcast(&mpt->m_passthru_cv); 5361 return; 5362 } else { 5363 mptsas_remove_cmd(mpt, cmd); 5364 } 5365 5366 if (cmd->cmd_flags & CFLAG_RETRY) { 5367 /* 5368 * The target returned QFULL or busy, do not add tihs 5369 * pkt to the doneq since the hba will retry 5370 * this cmd. 5371 * 5372 * The pkt has already been resubmitted in 5373 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error(). 5374 * Remove this cmd_flag here. 5375 */ 5376 cmd->cmd_flags &= ~CFLAG_RETRY; 5377 } else { 5378 mptsas_doneq_add(mpt, cmd); 5379 } 5380 } 5381 5382 static void 5383 mptsas_handle_address_reply(mptsas_t *mpt, 5384 pMpi2ReplyDescriptorsUnion_t reply_desc) 5385 { 5386 pMpi2AddressReplyDescriptor_t address_reply; 5387 pMPI2DefaultReply_t reply; 5388 mptsas_fw_diagnostic_buffer_t *pBuffer; 5389 uint32_t reply_addr, reply_frame_dma_baseaddr; 5390 uint16_t SMID, iocstatus; 5391 mptsas_slots_t *slots = mpt->m_active; 5392 mptsas_cmd_t *cmd = NULL; 5393 uint8_t function, buffer_type; 5394 m_replyh_arg_t *args; 5395 int reply_frame_no; 5396 5397 ASSERT(mutex_owned(&mpt->m_mutex)); 5398 5399 address_reply = (pMpi2AddressReplyDescriptor_t)reply_desc; 5400 reply_addr = ddi_get32(mpt->m_acc_post_queue_hdl, 5401 &address_reply->ReplyFrameAddress); 5402 SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &address_reply->SMID); 5403 5404 /* 5405 * If reply frame is not in the proper range we should ignore this 5406 * message and exit the interrupt handler. 5407 */ 5408 reply_frame_dma_baseaddr = mpt->m_reply_frame_dma_addr & 0xffffffffu; 5409 if ((reply_addr < reply_frame_dma_baseaddr) || 5410 (reply_addr >= (reply_frame_dma_baseaddr + 5411 (mpt->m_reply_frame_size * mpt->m_max_replies))) || 5412 ((reply_addr - reply_frame_dma_baseaddr) % 5413 mpt->m_reply_frame_size != 0)) { 5414 mptsas_log(mpt, CE_WARN, "?Received invalid reply frame " 5415 "address 0x%x\n", reply_addr); 5416 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 5417 return; 5418 } 5419 5420 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 5421 DDI_DMA_SYNC_FORCPU); 5422 reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame + (reply_addr - 5423 reply_frame_dma_baseaddr)); 5424 function = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Function); 5425 5426 NDBG31(("mptsas_handle_address_reply: function 0x%x, reply_addr=0x%x", 5427 function, reply_addr)); 5428 5429 /* 5430 * don't get slot information and command for events since these values 5431 * don't exist 5432 */ 5433 if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) && 5434 (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) { 5435 /* 5436 * This could be a TM reply, which use the last allocated SMID, 5437 * so allow for that. 5438 */ 5439 if ((SMID == 0) || (SMID > (slots->m_n_normal + 1))) { 5440 mptsas_log(mpt, CE_WARN, "?Received invalid SMID of " 5441 "%d\n", SMID); 5442 ddi_fm_service_impact(mpt->m_dip, 5443 DDI_SERVICE_UNAFFECTED); 5444 return; 5445 } 5446 5447 cmd = slots->m_slot[SMID]; 5448 5449 /* 5450 * print warning and return if the slot is empty 5451 */ 5452 if (cmd == NULL) { 5453 mptsas_log(mpt, CE_WARN, "?NULL command for address " 5454 "reply in slot %d", SMID); 5455 return; 5456 } 5457 if ((cmd->cmd_flags & 5458 (CFLAG_PASSTHRU | CFLAG_CONFIG | CFLAG_FW_DIAG))) { 5459 cmd->cmd_rfm = reply_addr; 5460 cmd->cmd_flags |= CFLAG_FINISHED; 5461 cv_broadcast(&mpt->m_passthru_cv); 5462 cv_broadcast(&mpt->m_config_cv); 5463 cv_broadcast(&mpt->m_fw_diag_cv); 5464 return; 5465 } else if (!(cmd->cmd_flags & CFLAG_FW_CMD)) { 5466 mptsas_remove_cmd(mpt, cmd); 5467 } 5468 NDBG31(("\t\tmptsas_process_intr: slot=%d", SMID)); 5469 } 5470 /* 5471 * Depending on the function, we need to handle 5472 * the reply frame (and cmd) differently. 5473 */ 5474 switch (function) { 5475 case MPI2_FUNCTION_SCSI_IO_REQUEST: 5476 mptsas_check_scsi_io_error(mpt, (pMpi2SCSIIOReply_t)reply, cmd); 5477 break; 5478 case MPI2_FUNCTION_SCSI_TASK_MGMT: 5479 cmd->cmd_rfm = reply_addr; 5480 mptsas_check_task_mgt(mpt, (pMpi2SCSIManagementReply_t)reply, 5481 cmd); 5482 break; 5483 case MPI2_FUNCTION_FW_DOWNLOAD: 5484 cmd->cmd_flags |= CFLAG_FINISHED; 5485 cv_signal(&mpt->m_fw_cv); 5486 break; 5487 case MPI2_FUNCTION_EVENT_NOTIFICATION: 5488 reply_frame_no = (reply_addr - reply_frame_dma_baseaddr) / 5489 mpt->m_reply_frame_size; 5490 args = &mpt->m_replyh_args[reply_frame_no]; 5491 args->mpt = (void *)mpt; 5492 args->rfm = reply_addr; 5493 5494 /* 5495 * Record the event if its type is enabled in 5496 * this mpt instance by ioctl. 5497 */ 5498 mptsas_record_event(args); 5499 5500 /* 5501 * Handle time critical events 5502 * NOT_RESPONDING/ADDED only now 5503 */ 5504 if (mptsas_handle_event_sync(args) == DDI_SUCCESS) { 5505 /* 5506 * Would not return main process, 5507 * just let taskq resolve ack action 5508 * and ack would be sent in taskq thread 5509 */ 5510 NDBG20(("send mptsas_handle_event_sync success")); 5511 } 5512 5513 if (mpt->m_in_reset) { 5514 NDBG20(("dropping event received during reset")); 5515 return; 5516 } 5517 5518 if ((ddi_taskq_dispatch(mpt->m_event_taskq, mptsas_handle_event, 5519 (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) { 5520 mptsas_log(mpt, CE_WARN, "No memory available" 5521 "for dispatch taskq"); 5522 /* 5523 * Return the reply frame to the free queue. 5524 */ 5525 ddi_put32(mpt->m_acc_free_queue_hdl, 5526 &((uint32_t *)(void *) 5527 mpt->m_free_queue)[mpt->m_free_index], reply_addr); 5528 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 5529 DDI_DMA_SYNC_FORDEV); 5530 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 5531 mpt->m_free_index = 0; 5532 } 5533 5534 ddi_put32(mpt->m_datap, 5535 &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index); 5536 } 5537 return; 5538 case MPI2_FUNCTION_DIAG_BUFFER_POST: 5539 /* 5540 * If SMID is 0, this implies that the reply is due to a 5541 * release function with a status that the buffer has been 5542 * released. Set the buffer flags accordingly. 5543 */ 5544 if (SMID == 0) { 5545 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 5546 &reply->IOCStatus); 5547 buffer_type = ddi_get8(mpt->m_acc_reply_frame_hdl, 5548 &(((pMpi2DiagBufferPostReply_t)reply)->BufferType)); 5549 if (iocstatus == MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED) { 5550 pBuffer = 5551 &mpt->m_fw_diag_buffer_list[buffer_type]; 5552 pBuffer->valid_data = TRUE; 5553 pBuffer->owned_by_firmware = FALSE; 5554 pBuffer->immediate = FALSE; 5555 } 5556 } else { 5557 /* 5558 * Normal handling of diag post reply with SMID. 5559 */ 5560 cmd = slots->m_slot[SMID]; 5561 5562 /* 5563 * print warning and return if the slot is empty 5564 */ 5565 if (cmd == NULL) { 5566 mptsas_log(mpt, CE_WARN, "?NULL command for " 5567 "address reply in slot %d", SMID); 5568 return; 5569 } 5570 cmd->cmd_rfm = reply_addr; 5571 cmd->cmd_flags |= CFLAG_FINISHED; 5572 cv_broadcast(&mpt->m_fw_diag_cv); 5573 } 5574 return; 5575 default: 5576 mptsas_log(mpt, CE_WARN, "Unknown function 0x%x ", function); 5577 break; 5578 } 5579 5580 /* 5581 * Return the reply frame to the free queue. 5582 */ 5583 ddi_put32(mpt->m_acc_free_queue_hdl, 5584 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 5585 reply_addr); 5586 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 5587 DDI_DMA_SYNC_FORDEV); 5588 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 5589 mpt->m_free_index = 0; 5590 } 5591 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 5592 mpt->m_free_index); 5593 5594 if (cmd->cmd_flags & CFLAG_FW_CMD) 5595 return; 5596 5597 if (cmd->cmd_flags & CFLAG_RETRY) { 5598 /* 5599 * The target returned QFULL or busy, do not add this 5600 * pkt to the doneq since the hba will retry 5601 * this cmd. 5602 * 5603 * The pkt has already been resubmitted in 5604 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error(). 5605 * Remove this cmd_flag here. 5606 */ 5607 cmd->cmd_flags &= ~CFLAG_RETRY; 5608 } else { 5609 mptsas_doneq_add(mpt, cmd); 5610 } 5611 } 5612 5613 #ifdef MPTSAS_DEBUG 5614 static uint8_t mptsas_last_sense[256]; 5615 #endif 5616 5617 static void 5618 mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply, 5619 mptsas_cmd_t *cmd) 5620 { 5621 uint8_t scsi_status, scsi_state; 5622 uint16_t ioc_status, cmd_rqs_len; 5623 uint32_t xferred, sensecount, responsedata, loginfo = 0; 5624 struct scsi_pkt *pkt; 5625 struct scsi_arq_status *arqstat; 5626 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 5627 uint8_t *sensedata = NULL; 5628 uint64_t sas_wwn; 5629 uint8_t phy; 5630 char wwn_str[MPTSAS_WWN_STRLEN]; 5631 5632 scsi_status = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIStatus); 5633 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus); 5634 scsi_state = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIState); 5635 xferred = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->TransferCount); 5636 sensecount = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->SenseCount); 5637 responsedata = ddi_get32(mpt->m_acc_reply_frame_hdl, 5638 &reply->ResponseInfo); 5639 5640 if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 5641 sas_wwn = ptgt->m_addr.mta_wwn; 5642 phy = ptgt->m_phynum; 5643 if (sas_wwn == 0) { 5644 (void) sprintf(wwn_str, "p%x", phy); 5645 } else { 5646 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 5647 } 5648 loginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 5649 &reply->IOCLogInfo); 5650 mptsas_log(mpt, CE_NOTE, 5651 "?Log info 0x%x received for target %d %s.\n" 5652 "\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x", 5653 loginfo, Tgt(cmd), wwn_str, scsi_status, ioc_status, 5654 scsi_state); 5655 } 5656 5657 NDBG31(("\t\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x", 5658 scsi_status, ioc_status, scsi_state)); 5659 5660 pkt = CMD2PKT(cmd); 5661 *(pkt->pkt_scbp) = scsi_status; 5662 5663 if (loginfo == 0x31170000) { 5664 /* 5665 * if loginfo PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY 5666 * 0x31170000 comes, that means the device missing delay 5667 * is in progressing, the command need retry later. 5668 */ 5669 *(pkt->pkt_scbp) = STATUS_BUSY; 5670 return; 5671 } 5672 5673 if ((scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS) && 5674 ((ioc_status & MPI2_IOCSTATUS_MASK) == 5675 MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE)) { 5676 pkt->pkt_reason = CMD_INCOMPLETE; 5677 pkt->pkt_state |= STATE_GOT_BUS; 5678 if (ptgt->m_reset_delay == 0) { 5679 mptsas_set_throttle(mpt, ptgt, 5680 DRAIN_THROTTLE); 5681 } 5682 return; 5683 } 5684 5685 if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) { 5686 responsedata &= 0x000000FF; 5687 if (responsedata & MPTSAS_SCSI_RESPONSE_CODE_TLR_OFF) { 5688 mptsas_log(mpt, CE_NOTE, "Do not support the TLR\n"); 5689 pkt->pkt_reason = CMD_TLR_OFF; 5690 return; 5691 } 5692 } 5693 5694 5695 switch (scsi_status) { 5696 case MPI2_SCSI_STATUS_CHECK_CONDITION: 5697 pkt->pkt_resid = (cmd->cmd_dmacount - xferred); 5698 arqstat = (void*)(pkt->pkt_scbp); 5699 arqstat->sts_rqpkt_status = *((struct scsi_status *) 5700 (pkt->pkt_scbp)); 5701 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | 5702 STATE_SENT_CMD | STATE_GOT_STATUS | STATE_ARQ_DONE); 5703 if (cmd->cmd_flags & CFLAG_XARQ) { 5704 pkt->pkt_state |= STATE_XARQ_DONE; 5705 } 5706 if (pkt->pkt_resid != cmd->cmd_dmacount) { 5707 pkt->pkt_state |= STATE_XFERRED_DATA; 5708 } 5709 arqstat->sts_rqpkt_reason = pkt->pkt_reason; 5710 arqstat->sts_rqpkt_state = pkt->pkt_state; 5711 arqstat->sts_rqpkt_state |= STATE_XFERRED_DATA; 5712 arqstat->sts_rqpkt_statistics = pkt->pkt_statistics; 5713 sensedata = (uint8_t *)&arqstat->sts_sensedata; 5714 cmd_rqs_len = cmd->cmd_extrqslen ? 5715 cmd->cmd_extrqslen : cmd->cmd_rqslen; 5716 (void) ddi_dma_sync(mpt->m_dma_req_sense_hdl, 0, 0, 5717 DDI_DMA_SYNC_FORKERNEL); 5718 #ifdef MPTSAS_DEBUG 5719 bcopy(cmd->cmd_arq_buf, mptsas_last_sense, 5720 ((cmd_rqs_len >= sizeof (mptsas_last_sense)) ? 5721 sizeof (mptsas_last_sense):cmd_rqs_len)); 5722 #endif 5723 bcopy((uchar_t *)cmd->cmd_arq_buf, sensedata, 5724 ((cmd_rqs_len >= sensecount) ? sensecount : 5725 cmd_rqs_len)); 5726 arqstat->sts_rqpkt_resid = (cmd_rqs_len - sensecount); 5727 cmd->cmd_flags |= CFLAG_CMDARQ; 5728 /* 5729 * Set proper status for pkt if autosense was valid 5730 */ 5731 if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) { 5732 struct scsi_status zero_status = { 0 }; 5733 arqstat->sts_rqpkt_status = zero_status; 5734 } 5735 5736 /* 5737 * ASC=0x47 is parity error 5738 * ASC=0x48 is initiator detected error received 5739 */ 5740 if ((scsi_sense_key(sensedata) == KEY_ABORTED_COMMAND) && 5741 ((scsi_sense_asc(sensedata) == 0x47) || 5742 (scsi_sense_asc(sensedata) == 0x48))) { 5743 mptsas_log(mpt, CE_NOTE, "Aborted_command!"); 5744 } 5745 5746 /* 5747 * ASC/ASCQ=0x3F/0x0E means report_luns data changed 5748 * ASC/ASCQ=0x25/0x00 means invalid lun 5749 */ 5750 if (((scsi_sense_key(sensedata) == KEY_UNIT_ATTENTION) && 5751 (scsi_sense_asc(sensedata) == 0x3F) && 5752 (scsi_sense_ascq(sensedata) == 0x0E)) || 5753 ((scsi_sense_key(sensedata) == KEY_ILLEGAL_REQUEST) && 5754 (scsi_sense_asc(sensedata) == 0x25) && 5755 (scsi_sense_ascq(sensedata) == 0x00))) { 5756 mptsas_topo_change_list_t *topo_node = NULL; 5757 5758 topo_node = kmem_zalloc( 5759 sizeof (mptsas_topo_change_list_t), 5760 KM_NOSLEEP); 5761 if (topo_node == NULL) { 5762 mptsas_log(mpt, CE_NOTE, "No memory" 5763 "resource for handle SAS dynamic" 5764 "reconfigure.\n"); 5765 break; 5766 } 5767 topo_node->mpt = mpt; 5768 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET; 5769 topo_node->un.phymask = ptgt->m_addr.mta_phymask; 5770 topo_node->devhdl = ptgt->m_devhdl; 5771 topo_node->object = (void *)ptgt; 5772 topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED; 5773 5774 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 5775 mptsas_handle_dr, 5776 (void *)topo_node, 5777 DDI_NOSLEEP)) != DDI_SUCCESS) { 5778 kmem_free(topo_node, 5779 sizeof (mptsas_topo_change_list_t)); 5780 mptsas_log(mpt, CE_NOTE, "mptsas start taskq" 5781 "for handle SAS dynamic reconfigure" 5782 "failed. \n"); 5783 } 5784 } 5785 break; 5786 case MPI2_SCSI_STATUS_GOOD: 5787 switch (ioc_status & MPI2_IOCSTATUS_MASK) { 5788 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 5789 pkt->pkt_reason = CMD_DEV_GONE; 5790 pkt->pkt_state |= STATE_GOT_BUS; 5791 if (ptgt->m_reset_delay == 0) { 5792 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5793 } 5794 NDBG31(("lost disk for target%d, command:%x", 5795 Tgt(cmd), pkt->pkt_cdbp[0])); 5796 break; 5797 case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN: 5798 NDBG31(("data overrun: xferred=%d", xferred)); 5799 NDBG31(("dmacount=%d", cmd->cmd_dmacount)); 5800 pkt->pkt_reason = CMD_DATA_OVR; 5801 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET 5802 | STATE_SENT_CMD | STATE_GOT_STATUS 5803 | STATE_XFERRED_DATA); 5804 pkt->pkt_resid = 0; 5805 break; 5806 case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: 5807 case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN: 5808 NDBG31(("data underrun: xferred=%d", xferred)); 5809 NDBG31(("dmacount=%d", cmd->cmd_dmacount)); 5810 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET 5811 | STATE_SENT_CMD | STATE_GOT_STATUS); 5812 pkt->pkt_resid = (cmd->cmd_dmacount - xferred); 5813 if (pkt->pkt_resid != cmd->cmd_dmacount) { 5814 pkt->pkt_state |= STATE_XFERRED_DATA; 5815 } 5816 break; 5817 case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED: 5818 if (cmd->cmd_active_expiration <= gethrtime()) { 5819 /* 5820 * When timeout requested, propagate 5821 * proper reason and statistics to 5822 * target drivers. 5823 */ 5824 mptsas_set_pkt_reason(mpt, cmd, CMD_TIMEOUT, 5825 STAT_BUS_RESET | STAT_TIMEOUT); 5826 } else { 5827 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, 5828 STAT_BUS_RESET); 5829 } 5830 break; 5831 case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED: 5832 case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED: 5833 mptsas_set_pkt_reason(mpt, 5834 cmd, CMD_RESET, STAT_DEV_RESET); 5835 break; 5836 case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR: 5837 case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR: 5838 pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET); 5839 mptsas_set_pkt_reason(mpt, 5840 cmd, CMD_TERMINATED, STAT_TERMINATED); 5841 break; 5842 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: 5843 case MPI2_IOCSTATUS_BUSY: 5844 /* 5845 * set throttles to drain 5846 */ 5847 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 5848 ptgt = refhash_next(mpt->m_targets, ptgt)) { 5849 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 5850 } 5851 5852 /* 5853 * retry command 5854 */ 5855 cmd->cmd_flags |= CFLAG_RETRY; 5856 cmd->cmd_pkt_flags |= FLAG_HEAD; 5857 5858 (void) mptsas_accept_pkt(mpt, cmd); 5859 break; 5860 default: 5861 mptsas_log(mpt, CE_WARN, 5862 "unknown ioc_status = %x\n", ioc_status); 5863 mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer " 5864 "count = %x, scsi_status = %x", scsi_state, 5865 xferred, scsi_status); 5866 break; 5867 } 5868 break; 5869 case MPI2_SCSI_STATUS_TASK_SET_FULL: 5870 mptsas_handle_qfull(mpt, cmd); 5871 break; 5872 case MPI2_SCSI_STATUS_BUSY: 5873 NDBG31(("scsi_status busy received")); 5874 break; 5875 case MPI2_SCSI_STATUS_RESERVATION_CONFLICT: 5876 NDBG31(("scsi_status reservation conflict received")); 5877 break; 5878 default: 5879 mptsas_log(mpt, CE_WARN, "scsi_status=%x, ioc_status=%x\n", 5880 scsi_status, ioc_status); 5881 mptsas_log(mpt, CE_WARN, 5882 "mptsas_process_intr: invalid scsi status\n"); 5883 break; 5884 } 5885 } 5886 5887 static void 5888 mptsas_check_task_mgt(mptsas_t *mpt, pMpi2SCSIManagementReply_t reply, 5889 mptsas_cmd_t *cmd) 5890 { 5891 uint8_t task_type; 5892 uint16_t ioc_status; 5893 uint32_t log_info; 5894 uint16_t dev_handle; 5895 struct scsi_pkt *pkt = CMD2PKT(cmd); 5896 5897 task_type = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->TaskType); 5898 ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus); 5899 log_info = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo); 5900 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->DevHandle); 5901 5902 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 5903 mptsas_log(mpt, CE_WARN, "mptsas_check_task_mgt: Task 0x%x " 5904 "failed. IOCStatus=0x%x IOCLogInfo=0x%x target=%d\n", 5905 task_type, ioc_status, log_info, dev_handle); 5906 pkt->pkt_reason = CMD_INCOMPLETE; 5907 return; 5908 } 5909 5910 switch (task_type) { 5911 case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK: 5912 case MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET: 5913 case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK: 5914 case MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA: 5915 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET: 5916 case MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION: 5917 break; 5918 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 5919 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 5920 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 5921 /* 5922 * Check for invalid DevHandle of 0 in case application 5923 * sends bad command. DevHandle of 0 could cause problems. 5924 */ 5925 if (dev_handle == 0) { 5926 mptsas_log(mpt, CE_WARN, "!Can't flush target with" 5927 " DevHandle of 0."); 5928 } else { 5929 mptsas_flush_target(mpt, dev_handle, Lun(cmd), 5930 task_type); 5931 } 5932 break; 5933 default: 5934 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.", 5935 task_type); 5936 mptsas_log(mpt, CE_WARN, "ioc status = %x", ioc_status); 5937 break; 5938 } 5939 } 5940 5941 static void 5942 mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg) 5943 { 5944 mptsas_t *mpt = arg->mpt; 5945 uint64_t t = arg->t; 5946 mptsas_cmd_t *cmd; 5947 struct scsi_pkt *pkt; 5948 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 5949 5950 mutex_enter(&item->mutex); 5951 while (item->flag & MPTSAS_DONEQ_THREAD_ACTIVE) { 5952 if (!item->doneq) { 5953 cv_wait(&item->cv, &item->mutex); 5954 } 5955 pkt = NULL; 5956 if ((cmd = mptsas_doneq_thread_rm(mpt, t)) != NULL) { 5957 cmd->cmd_flags |= CFLAG_COMPLETED; 5958 pkt = CMD2PKT(cmd); 5959 } 5960 mutex_exit(&item->mutex); 5961 if (pkt) { 5962 mptsas_pkt_comp(pkt, cmd); 5963 } 5964 mutex_enter(&item->mutex); 5965 } 5966 mutex_exit(&item->mutex); 5967 mutex_enter(&mpt->m_doneq_mutex); 5968 mpt->m_doneq_thread_n--; 5969 cv_broadcast(&mpt->m_doneq_thread_cv); 5970 mutex_exit(&mpt->m_doneq_mutex); 5971 } 5972 5973 5974 /* 5975 * mpt interrupt handler. 5976 */ 5977 static uint_t 5978 mptsas_intr(caddr_t arg1, caddr_t arg2) 5979 { 5980 mptsas_t *mpt = (void *)arg1; 5981 pMpi2ReplyDescriptorsUnion_t reply_desc_union; 5982 uchar_t did_reply = FALSE; 5983 5984 NDBG1(("mptsas_intr: arg1 0x%p arg2 0x%p", (void *)arg1, (void *)arg2)); 5985 5986 mutex_enter(&mpt->m_mutex); 5987 5988 /* 5989 * If interrupts are shared by two channels then check whether this 5990 * interrupt is genuinely for this channel by making sure first the 5991 * chip is in high power state. 5992 */ 5993 if ((mpt->m_options & MPTSAS_OPT_PM) && 5994 (mpt->m_power_level != PM_LEVEL_D0)) { 5995 mutex_exit(&mpt->m_mutex); 5996 return (DDI_INTR_UNCLAIMED); 5997 } 5998 5999 /* 6000 * If polling, interrupt was triggered by some shared interrupt because 6001 * IOC interrupts are disabled during polling, so polling routine will 6002 * handle any replies. Considering this, if polling is happening, 6003 * return with interrupt unclaimed. 6004 */ 6005 if (mpt->m_polled_intr) { 6006 mutex_exit(&mpt->m_mutex); 6007 mptsas_log(mpt, CE_WARN, "mpt_sas: Unclaimed interrupt"); 6008 return (DDI_INTR_UNCLAIMED); 6009 } 6010 6011 /* 6012 * Read the istat register. 6013 */ 6014 if ((INTPENDING(mpt)) != 0) { 6015 /* 6016 * read fifo until empty. 6017 */ 6018 #ifndef __lock_lint 6019 _NOTE(CONSTCOND) 6020 #endif 6021 while (TRUE) { 6022 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 6023 DDI_DMA_SYNC_FORCPU); 6024 reply_desc_union = (pMpi2ReplyDescriptorsUnion_t) 6025 MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index); 6026 6027 if (ddi_get32(mpt->m_acc_post_queue_hdl, 6028 &reply_desc_union->Words.Low) == 0xFFFFFFFF || 6029 ddi_get32(mpt->m_acc_post_queue_hdl, 6030 &reply_desc_union->Words.High) == 0xFFFFFFFF) { 6031 break; 6032 } 6033 6034 /* 6035 * The reply is valid, process it according to its 6036 * type. Also, set a flag for updating the reply index 6037 * after they've all been processed. 6038 */ 6039 did_reply = TRUE; 6040 6041 mptsas_process_intr(mpt, reply_desc_union); 6042 6043 /* 6044 * Increment post index and roll over if needed. 6045 */ 6046 if (++mpt->m_post_index == mpt->m_post_queue_depth) { 6047 mpt->m_post_index = 0; 6048 } 6049 } 6050 6051 /* 6052 * Update the global reply index if at least one reply was 6053 * processed. 6054 */ 6055 if (did_reply) { 6056 ddi_put32(mpt->m_datap, 6057 &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index); 6058 } 6059 } else { 6060 mutex_exit(&mpt->m_mutex); 6061 return (DDI_INTR_UNCLAIMED); 6062 } 6063 NDBG1(("mptsas_intr complete")); 6064 6065 /* 6066 * If no helper threads are created, process the doneq in ISR. If 6067 * helpers are created, use the doneq length as a metric to measure the 6068 * load on the interrupt CPU. If it is long enough, which indicates the 6069 * load is heavy, then we deliver the IO completions to the helpers. 6070 * This measurement has some limitations, although it is simple and 6071 * straightforward and works well for most of the cases at present. 6072 */ 6073 if (!mpt->m_doneq_thread_n || 6074 (mpt->m_doneq_len <= mpt->m_doneq_length_threshold)) { 6075 mptsas_doneq_empty(mpt); 6076 } else { 6077 mptsas_deliver_doneq_thread(mpt); 6078 } 6079 6080 /* 6081 * If there are queued cmd, start them now. 6082 */ 6083 if (mpt->m_waitq != NULL) { 6084 mptsas_restart_waitq(mpt); 6085 } 6086 6087 mutex_exit(&mpt->m_mutex); 6088 return (DDI_INTR_CLAIMED); 6089 } 6090 6091 static void 6092 mptsas_process_intr(mptsas_t *mpt, 6093 pMpi2ReplyDescriptorsUnion_t reply_desc_union) 6094 { 6095 uint8_t reply_type; 6096 6097 ASSERT(mutex_owned(&mpt->m_mutex)); 6098 6099 /* 6100 * The reply is valid, process it according to its 6101 * type. Also, set a flag for updated the reply index 6102 * after they've all been processed. 6103 */ 6104 reply_type = ddi_get8(mpt->m_acc_post_queue_hdl, 6105 &reply_desc_union->Default.ReplyFlags); 6106 reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; 6107 if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS || 6108 reply_type == MPI25_RPY_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO_SUCCESS) { 6109 mptsas_handle_scsi_io_success(mpt, reply_desc_union); 6110 } else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { 6111 mptsas_handle_address_reply(mpt, reply_desc_union); 6112 } else { 6113 mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type); 6114 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 6115 } 6116 6117 /* 6118 * Clear the reply descriptor for re-use and increment 6119 * index. 6120 */ 6121 ddi_put64(mpt->m_acc_post_queue_hdl, 6122 &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index], 6123 0xFFFFFFFFFFFFFFFF); 6124 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 6125 DDI_DMA_SYNC_FORDEV); 6126 } 6127 6128 /* 6129 * handle qfull condition 6130 */ 6131 static void 6132 mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd) 6133 { 6134 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 6135 6136 if ((++cmd->cmd_qfull_retries > ptgt->m_qfull_retries) || 6137 (ptgt->m_qfull_retries == 0)) { 6138 /* 6139 * We have exhausted the retries on QFULL, or, 6140 * the target driver has indicated that it 6141 * wants to handle QFULL itself by setting 6142 * qfull-retries capability to 0. In either case 6143 * we want the target driver's QFULL handling 6144 * to kick in. We do this by having pkt_reason 6145 * as CMD_CMPLT and pkt_scbp as STATUS_QFULL. 6146 */ 6147 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 6148 } else { 6149 if (ptgt->m_reset_delay == 0) { 6150 ptgt->m_t_throttle = 6151 max((ptgt->m_t_ncmds - 2), 0); 6152 } 6153 6154 cmd->cmd_pkt_flags |= FLAG_HEAD; 6155 cmd->cmd_flags &= ~(CFLAG_TRANFLAG); 6156 cmd->cmd_flags |= CFLAG_RETRY; 6157 6158 (void) mptsas_accept_pkt(mpt, cmd); 6159 6160 /* 6161 * when target gives queue full status with no commands 6162 * outstanding (m_t_ncmds == 0), throttle is set to 0 6163 * (HOLD_THROTTLE), and the queue full handling start 6164 * (see psarc/1994/313); if there are commands outstanding, 6165 * throttle is set to (m_t_ncmds - 2) 6166 */ 6167 if (ptgt->m_t_throttle == HOLD_THROTTLE) { 6168 /* 6169 * By setting throttle to QFULL_THROTTLE, we 6170 * avoid submitting new commands and in 6171 * mptsas_restart_cmd find out slots which need 6172 * their throttles to be cleared. 6173 */ 6174 mptsas_set_throttle(mpt, ptgt, QFULL_THROTTLE); 6175 if (mpt->m_restart_cmd_timeid == 0) { 6176 mpt->m_restart_cmd_timeid = 6177 timeout(mptsas_restart_cmd, mpt, 6178 ptgt->m_qfull_retry_interval); 6179 } 6180 } 6181 } 6182 } 6183 6184 mptsas_phymask_t 6185 mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport) 6186 { 6187 mptsas_phymask_t phy_mask = 0; 6188 uint8_t i = 0; 6189 6190 NDBG20(("mptsas%d physport_to_phymask enter", mpt->m_instance)); 6191 6192 ASSERT(mutex_owned(&mpt->m_mutex)); 6193 6194 /* 6195 * If physport is 0xFF, this is a RAID volume. Use phymask of 0. 6196 */ 6197 if (physport == 0xFF) { 6198 return (0); 6199 } 6200 6201 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 6202 if (mpt->m_phy_info[i].attached_devhdl && 6203 (mpt->m_phy_info[i].phy_mask != 0) && 6204 (mpt->m_phy_info[i].port_num == physport)) { 6205 phy_mask = mpt->m_phy_info[i].phy_mask; 6206 break; 6207 } 6208 } 6209 NDBG20(("mptsas%d physport_to_phymask:physport :%x phymask :%x, ", 6210 mpt->m_instance, physport, phy_mask)); 6211 return (phy_mask); 6212 } 6213 6214 /* 6215 * mpt free device handle after device gone, by use of passthrough 6216 */ 6217 static int 6218 mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl) 6219 { 6220 Mpi2SasIoUnitControlRequest_t req; 6221 Mpi2SasIoUnitControlReply_t rep; 6222 int ret; 6223 6224 ASSERT(mutex_owned(&mpt->m_mutex)); 6225 6226 /* 6227 * Need to compose a SAS IO Unit Control request message 6228 * and call mptsas_do_passthru() function 6229 */ 6230 bzero(&req, sizeof (req)); 6231 bzero(&rep, sizeof (rep)); 6232 6233 req.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 6234 req.Operation = MPI2_SAS_OP_REMOVE_DEVICE; 6235 req.DevHandle = LE_16(devhdl); 6236 6237 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL, 6238 sizeof (req), sizeof (rep), 0, MPTSAS_PASS_THRU_DIRECTION_NONE, 6239 NULL, 0, 60, FKIOCTL); 6240 if (ret != 0) { 6241 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit " 6242 "Control error %d", ret); 6243 return (DDI_FAILURE); 6244 } 6245 6246 /* do passthrough success, check the ioc status */ 6247 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 6248 cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit " 6249 "Control IOCStatus %d", LE_16(rep.IOCStatus)); 6250 return (DDI_FAILURE); 6251 } 6252 6253 return (DDI_SUCCESS); 6254 } 6255 6256 /* 6257 * We have a SATA target that has changed, which means the "bridge-port" 6258 * property must be updated to reflect the SAS WWN of the new attachment point. 6259 * This may change if a SATA device changes which bay, and therefore phy, it is 6260 * plugged into. This SATA device may be a multipath virtual device or may be a 6261 * physical device. We have to handle both cases. 6262 */ 6263 static boolean_t 6264 mptsas_update_sata_bridge(mptsas_t *mpt, dev_info_t *parent, 6265 mptsas_target_t *ptgt) 6266 { 6267 int rval; 6268 uint16_t dev_hdl; 6269 uint16_t pdev_hdl; 6270 uint64_t dev_sas_wwn; 6271 uint8_t physport; 6272 uint8_t phy_id; 6273 uint32_t page_address; 6274 uint16_t bay_num, enclosure, io_flags; 6275 uint32_t dev_info; 6276 char uabuf[SCSI_WWN_BUFLEN]; 6277 dev_info_t *dip; 6278 mdi_pathinfo_t *pip; 6279 6280 mutex_enter(&mpt->m_mutex); 6281 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 6282 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)ptgt->m_devhdl; 6283 rval = mptsas_get_sas_device_page0(mpt, page_address, &dev_hdl, 6284 &dev_sas_wwn, &dev_info, &physport, &phy_id, &pdev_hdl, &bay_num, 6285 &enclosure, &io_flags); 6286 mutex_exit(&mpt->m_mutex); 6287 if (rval != DDI_SUCCESS) { 6288 mptsas_log(mpt, CE_WARN, "unable to get SAS page 0 for " 6289 "handle %d", page_address); 6290 return (B_FALSE); 6291 } 6292 6293 if (scsi_wwn_to_wwnstr(dev_sas_wwn, 1, uabuf) == NULL) { 6294 mptsas_log(mpt, CE_WARN, 6295 "mptsas unable to format SATA bridge WWN"); 6296 return (B_FALSE); 6297 } 6298 6299 if (mpt->m_mpxio_enable == TRUE && (pip = mptsas_find_path_addr(parent, 6300 ptgt->m_addr.mta_wwn, 0)) != NULL) { 6301 if (mdi_prop_update_string(pip, SCSI_ADDR_PROP_BRIDGE_PORT, 6302 uabuf) != DDI_SUCCESS) { 6303 mptsas_log(mpt, CE_WARN, 6304 "mptsas unable to create SCSI bridge port " 6305 "property for SATA device"); 6306 return (B_FALSE); 6307 } 6308 return (B_TRUE); 6309 } 6310 6311 if ((dip = mptsas_find_child_addr(parent, ptgt->m_addr.mta_wwn, 6312 0)) != NULL) { 6313 if (ndi_prop_update_string(DDI_DEV_T_NONE, dip, 6314 SCSI_ADDR_PROP_BRIDGE_PORT, uabuf) != DDI_PROP_SUCCESS) { 6315 mptsas_log(mpt, CE_WARN, 6316 "mptsas unable to create SCSI bridge port " 6317 "property for SATA device"); 6318 return (B_FALSE); 6319 } 6320 return (B_TRUE); 6321 } 6322 6323 mptsas_log(mpt, CE_WARN, "mptsas failed to find dev_info_t or " 6324 "mdi_pathinfo_t for target with WWN %016" PRIx64, 6325 ptgt->m_addr.mta_wwn); 6326 6327 return (B_FALSE); 6328 } 6329 6330 static void 6331 mptsas_update_phymask(mptsas_t *mpt) 6332 { 6333 mptsas_phymask_t mask = 0, phy_mask; 6334 char *phy_mask_name; 6335 uint8_t current_port; 6336 int i, j; 6337 6338 NDBG20(("mptsas%d update phymask ", mpt->m_instance)); 6339 6340 ASSERT(mutex_owned(&mpt->m_mutex)); 6341 6342 (void) mptsas_get_sas_io_unit_page(mpt); 6343 6344 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 6345 6346 for (i = 0; i < mpt->m_num_phys; i++) { 6347 phy_mask = 0x00; 6348 6349 if (mpt->m_phy_info[i].attached_devhdl == 0) 6350 continue; 6351 6352 bzero(phy_mask_name, sizeof (phy_mask_name)); 6353 6354 current_port = mpt->m_phy_info[i].port_num; 6355 6356 if ((mask & (1 << i)) != 0) 6357 continue; 6358 6359 for (j = 0; j < mpt->m_num_phys; j++) { 6360 if (mpt->m_phy_info[j].attached_devhdl && 6361 (mpt->m_phy_info[j].port_num == current_port)) { 6362 phy_mask |= (1 << j); 6363 } 6364 } 6365 mask = mask | phy_mask; 6366 6367 for (j = 0; j < mpt->m_num_phys; j++) { 6368 if ((phy_mask >> j) & 0x01) { 6369 mpt->m_phy_info[j].phy_mask = phy_mask; 6370 } 6371 } 6372 6373 (void) sprintf(phy_mask_name, "%x", phy_mask); 6374 6375 mutex_exit(&mpt->m_mutex); 6376 /* 6377 * register a iport, if the port has already been existed 6378 * SCSA will do nothing and just return. 6379 */ 6380 (void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name); 6381 mutex_enter(&mpt->m_mutex); 6382 } 6383 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 6384 NDBG20(("mptsas%d update phymask return", mpt->m_instance)); 6385 } 6386 6387 /* 6388 * mptsas_handle_dr is a task handler for DR, the DR action includes: 6389 * 1. Directly attched Device Added/Removed. 6390 * 2. Expander Device Added/Removed. 6391 * 3. Indirectly Attached Device Added/Expander. 6392 * 4. LUNs of a existing device status change. 6393 * 5. RAID volume created/deleted. 6394 * 6. Member of RAID volume is released because of RAID deletion. 6395 * 7. Physical disks are removed because of RAID creation. 6396 */ 6397 static void 6398 mptsas_handle_dr(void *args) 6399 { 6400 mptsas_topo_change_list_t *topo_node = NULL; 6401 mptsas_topo_change_list_t *save_node = NULL; 6402 mptsas_t *mpt; 6403 dev_info_t *parent = NULL; 6404 mptsas_phymask_t phymask = 0; 6405 char *phy_mask_name; 6406 uint8_t flags = 0, physport = 0xff; 6407 uint8_t port_update = 0; 6408 uint_t event; 6409 6410 topo_node = (mptsas_topo_change_list_t *)args; 6411 6412 mpt = topo_node->mpt; 6413 event = topo_node->event; 6414 flags = topo_node->flags; 6415 6416 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 6417 6418 NDBG20(("mptsas%d handle_dr enter", mpt->m_instance)); 6419 6420 switch (event) { 6421 case MPTSAS_DR_EVENT_RECONFIG_TARGET: 6422 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 6423 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE) || 6424 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) { 6425 /* 6426 * Direct attached or expander attached device added 6427 * into system or a Phys Disk that is being unhidden. 6428 */ 6429 port_update = 1; 6430 } 6431 break; 6432 case MPTSAS_DR_EVENT_RECONFIG_SMP: 6433 /* 6434 * New expander added into system, it must be the head 6435 * of topo_change_list_t 6436 */ 6437 port_update = 1; 6438 break; 6439 default: 6440 port_update = 0; 6441 break; 6442 } 6443 /* 6444 * All cases port_update == 1 may cause initiator port form change 6445 */ 6446 mutex_enter(&mpt->m_mutex); 6447 if (mpt->m_port_chng && port_update) { 6448 /* 6449 * mpt->m_port_chng flag indicates some PHYs of initiator 6450 * port have changed to online. So when expander added or 6451 * directly attached device online event come, we force to 6452 * update port information by issueing SAS IO Unit Page and 6453 * update PHYMASKs. 6454 */ 6455 (void) mptsas_update_phymask(mpt); 6456 mpt->m_port_chng = 0; 6457 6458 } 6459 mutex_exit(&mpt->m_mutex); 6460 while (topo_node) { 6461 phymask = 0; 6462 if (parent == NULL) { 6463 physport = topo_node->un.physport; 6464 event = topo_node->event; 6465 flags = topo_node->flags; 6466 if (event & (MPTSAS_DR_EVENT_OFFLINE_TARGET | 6467 MPTSAS_DR_EVENT_OFFLINE_SMP)) { 6468 /* 6469 * For all offline events, phymask is known 6470 */ 6471 phymask = topo_node->un.phymask; 6472 goto find_parent; 6473 } 6474 if (event & MPTSAS_TOPO_FLAG_REMOVE_HANDLE) { 6475 goto handle_topo_change; 6476 } 6477 if (flags & MPTSAS_TOPO_FLAG_LUN_ASSOCIATED) { 6478 phymask = topo_node->un.phymask; 6479 goto find_parent; 6480 } 6481 6482 if ((flags == 6483 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) && 6484 (event == MPTSAS_DR_EVENT_RECONFIG_TARGET)) { 6485 /* 6486 * There is no any field in IR_CONFIG_CHANGE 6487 * event indicate physport/phynum, let's get 6488 * parent after SAS Device Page0 request. 6489 */ 6490 goto handle_topo_change; 6491 } 6492 6493 mutex_enter(&mpt->m_mutex); 6494 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 6495 /* 6496 * If the direct attached device added or a 6497 * phys disk is being unhidden, argument 6498 * physport actually is PHY#, so we have to get 6499 * phymask according PHY#. 6500 */ 6501 physport = mpt->m_phy_info[physport].port_num; 6502 } 6503 6504 /* 6505 * Translate physport to phymask so that we can search 6506 * parent dip. 6507 */ 6508 phymask = mptsas_physport_to_phymask(mpt, 6509 physport); 6510 mutex_exit(&mpt->m_mutex); 6511 6512 find_parent: 6513 bzero(phy_mask_name, MPTSAS_MAX_PHYS); 6514 /* 6515 * For RAID topology change node, write the iport name 6516 * as v0. 6517 */ 6518 if (flags & MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 6519 (void) sprintf(phy_mask_name, "v0"); 6520 } else { 6521 /* 6522 * phymask can bo 0 if the drive has been 6523 * pulled by the time an add event is 6524 * processed. If phymask is 0, just skip this 6525 * event and continue. 6526 */ 6527 if (phymask == 0) { 6528 mutex_enter(&mpt->m_mutex); 6529 save_node = topo_node; 6530 topo_node = topo_node->next; 6531 ASSERT(save_node); 6532 kmem_free(save_node, 6533 sizeof (mptsas_topo_change_list_t)); 6534 mutex_exit(&mpt->m_mutex); 6535 6536 parent = NULL; 6537 continue; 6538 } 6539 (void) sprintf(phy_mask_name, "%x", phymask); 6540 } 6541 parent = scsi_hba_iport_find(mpt->m_dip, 6542 phy_mask_name); 6543 if (parent == NULL) { 6544 mptsas_log(mpt, CE_WARN, "Failed to find an " 6545 "iport, should not happen!"); 6546 goto out; 6547 } 6548 6549 } 6550 ASSERT(parent); 6551 handle_topo_change: 6552 6553 mutex_enter(&mpt->m_mutex); 6554 /* 6555 * If HBA is being reset, don't perform operations depending 6556 * on the IOC. We must free the topo list, however. 6557 */ 6558 if (!mpt->m_in_reset) { 6559 mptsas_handle_topo_change(topo_node, parent); 6560 } else { 6561 NDBG20(("skipping topo change received during reset")); 6562 } 6563 save_node = topo_node; 6564 topo_node = topo_node->next; 6565 ASSERT(save_node); 6566 kmem_free(save_node, sizeof (mptsas_topo_change_list_t)); 6567 mutex_exit(&mpt->m_mutex); 6568 6569 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 6570 (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) || 6571 (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) { 6572 /* 6573 * If direct attached device associated, make sure 6574 * reset the parent before start the next one. But 6575 * all devices associated with expander shares the 6576 * parent. Also, reset parent if this is for RAID. 6577 */ 6578 parent = NULL; 6579 } 6580 } 6581 out: 6582 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 6583 } 6584 6585 static void 6586 mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node, 6587 dev_info_t *parent) 6588 { 6589 mptsas_target_t *ptgt = NULL; 6590 mptsas_smp_t *psmp = NULL; 6591 mptsas_t *mpt = (void *)topo_node->mpt; 6592 uint16_t devhdl; 6593 uint16_t attached_devhdl; 6594 uint64_t sas_wwn = 0; 6595 int rval = 0; 6596 uint32_t page_address; 6597 uint8_t phy, flags; 6598 char *addr = NULL; 6599 dev_info_t *lundip; 6600 char attached_wwnstr[MPTSAS_WWN_STRLEN]; 6601 6602 NDBG20(("mptsas%d handle_topo_change enter, devhdl 0x%x," 6603 "event 0x%x, flags 0x%x", mpt->m_instance, topo_node->devhdl, 6604 topo_node->event, topo_node->flags)); 6605 6606 ASSERT(mutex_owned(&mpt->m_mutex)); 6607 6608 switch (topo_node->event) { 6609 case MPTSAS_DR_EVENT_RECONFIG_TARGET: 6610 { 6611 char *phy_mask_name; 6612 mptsas_phymask_t phymask = 0; 6613 6614 if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 6615 /* 6616 * Get latest RAID info. 6617 */ 6618 (void) mptsas_get_raid_info(mpt); 6619 ptgt = refhash_linear_search(mpt->m_targets, 6620 mptsas_target_eval_devhdl, &topo_node->devhdl); 6621 if (ptgt == NULL) 6622 break; 6623 } else { 6624 ptgt = (void *)topo_node->object; 6625 } 6626 6627 if (ptgt == NULL) { 6628 /* 6629 * If a Phys Disk was deleted, RAID info needs to be 6630 * updated to reflect the new topology. 6631 */ 6632 (void) mptsas_get_raid_info(mpt); 6633 6634 /* 6635 * Get sas device page 0 by DevHandle to make sure if 6636 * SSP/SATA end device exist. 6637 */ 6638 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 6639 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 6640 topo_node->devhdl; 6641 6642 rval = mptsas_get_target_device_info(mpt, page_address, 6643 &devhdl, &ptgt); 6644 if (rval == DEV_INFO_WRONG_DEVICE_TYPE) { 6645 mptsas_log(mpt, CE_NOTE, 6646 "mptsas_handle_topo_change: target %d is " 6647 "not a SAS/SATA device. \n", 6648 topo_node->devhdl); 6649 } else if (rval == DEV_INFO_FAIL_ALLOC) { 6650 mptsas_log(mpt, CE_NOTE, 6651 "mptsas_handle_topo_change: could not " 6652 "allocate memory. \n"); 6653 } else if (rval == DEV_INFO_FAIL_GUID) { 6654 mptsas_log(mpt, CE_NOTE, 6655 "mptsas_handle_topo_change: could not " 6656 "get SATA GUID for target %d. \n", 6657 topo_node->devhdl); 6658 } 6659 /* 6660 * If rval is DEV_INFO_PHYS_DISK or indicates failure 6661 * then there is nothing else to do, just leave. 6662 */ 6663 if (rval != DEV_INFO_SUCCESS) { 6664 return; 6665 } 6666 } 6667 6668 ASSERT(ptgt->m_devhdl == topo_node->devhdl); 6669 6670 mutex_exit(&mpt->m_mutex); 6671 flags = topo_node->flags; 6672 6673 if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) { 6674 phymask = ptgt->m_addr.mta_phymask; 6675 phy_mask_name = kmem_zalloc(MPTSAS_MAX_PHYS, KM_SLEEP); 6676 (void) sprintf(phy_mask_name, "%x", phymask); 6677 parent = scsi_hba_iport_find(mpt->m_dip, 6678 phy_mask_name); 6679 kmem_free(phy_mask_name, MPTSAS_MAX_PHYS); 6680 if (parent == NULL) { 6681 mptsas_log(mpt, CE_WARN, "Failed to find a " 6682 "iport for PD, should not happen!"); 6683 mutex_enter(&mpt->m_mutex); 6684 break; 6685 } 6686 } 6687 6688 if (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) { 6689 ndi_devi_enter(parent); 6690 (void) mptsas_config_raid(parent, topo_node->devhdl, 6691 &lundip); 6692 ndi_devi_exit(parent); 6693 } else { 6694 /* 6695 * hold nexus for bus configure 6696 */ 6697 ndi_devi_enter(scsi_vhci_dip); 6698 ndi_devi_enter(parent); 6699 rval = mptsas_config_target(parent, ptgt); 6700 /* 6701 * release nexus for bus configure 6702 */ 6703 ndi_devi_exit(parent); 6704 ndi_devi_exit(scsi_vhci_dip); 6705 6706 /* 6707 * If this is a SATA device, make sure that the 6708 * bridge-port (the SAS WWN that the SATA device is 6709 * plugged into) is updated. This may change if a SATA 6710 * device changes which bay, and therefore phy, it is 6711 * plugged into. 6712 */ 6713 if (IS_SATA_DEVICE(ptgt->m_deviceinfo)) { 6714 if (!mptsas_update_sata_bridge(mpt, parent, 6715 ptgt)) { 6716 mutex_enter(&mpt->m_mutex); 6717 return; 6718 } 6719 } 6720 6721 /* 6722 * Add parent's props for SMHBA support 6723 */ 6724 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 6725 bzero(attached_wwnstr, 6726 sizeof (attached_wwnstr)); 6727 (void) sprintf(attached_wwnstr, "w%016"PRIx64, 6728 ptgt->m_addr.mta_wwn); 6729 if (ddi_prop_update_string(DDI_DEV_T_NONE, 6730 parent, 6731 SCSI_ADDR_PROP_ATTACHED_PORT, 6732 attached_wwnstr) 6733 != DDI_PROP_SUCCESS) { 6734 (void) ddi_prop_remove(DDI_DEV_T_NONE, 6735 parent, 6736 SCSI_ADDR_PROP_ATTACHED_PORT); 6737 mptsas_log(mpt, CE_WARN, "Failed to" 6738 "attached-port props"); 6739 mutex_enter(&mpt->m_mutex); 6740 return; 6741 } 6742 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6743 MPTSAS_NUM_PHYS, 1) != 6744 DDI_PROP_SUCCESS) { 6745 (void) ddi_prop_remove(DDI_DEV_T_NONE, 6746 parent, MPTSAS_NUM_PHYS); 6747 mptsas_log(mpt, CE_WARN, "Failed to" 6748 " create num-phys props"); 6749 mutex_enter(&mpt->m_mutex); 6750 return; 6751 } 6752 6753 /* 6754 * Update PHY info for smhba 6755 */ 6756 mutex_enter(&mpt->m_mutex); 6757 if (mptsas_smhba_phy_init(mpt)) { 6758 mptsas_log(mpt, CE_WARN, "mptsas phy" 6759 " update failed"); 6760 return; 6761 } 6762 mutex_exit(&mpt->m_mutex); 6763 6764 /* 6765 * topo_node->un.physport is really the PHY# 6766 * for direct attached devices 6767 */ 6768 mptsas_smhba_set_one_phy_props(mpt, parent, 6769 topo_node->un.physport, &attached_devhdl); 6770 6771 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6772 MPTSAS_VIRTUAL_PORT, 0) != 6773 DDI_PROP_SUCCESS) { 6774 (void) ddi_prop_remove(DDI_DEV_T_NONE, 6775 parent, MPTSAS_VIRTUAL_PORT); 6776 mptsas_log(mpt, CE_WARN, 6777 "mptsas virtual-port" 6778 "port prop update failed"); 6779 mutex_enter(&mpt->m_mutex); 6780 return; 6781 } 6782 } 6783 } 6784 mutex_enter(&mpt->m_mutex); 6785 6786 NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, " 6787 "phymask:%x.", mpt->m_instance, ptgt->m_devhdl, 6788 ptgt->m_addr.mta_phymask)); 6789 break; 6790 } 6791 case MPTSAS_DR_EVENT_OFFLINE_TARGET: 6792 { 6793 devhdl = topo_node->devhdl; 6794 ptgt = refhash_linear_search(mpt->m_targets, 6795 mptsas_target_eval_devhdl, &devhdl); 6796 if (ptgt == NULL) 6797 break; 6798 6799 sas_wwn = ptgt->m_addr.mta_wwn; 6800 phy = ptgt->m_phynum; 6801 6802 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 6803 6804 if (sas_wwn) { 6805 (void) sprintf(addr, "w%016"PRIx64, sas_wwn); 6806 } else { 6807 (void) sprintf(addr, "p%x", phy); 6808 } 6809 ASSERT(ptgt->m_devhdl == devhdl); 6810 6811 if ((topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) || 6812 (topo_node->flags == 6813 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) { 6814 /* 6815 * Get latest RAID info if RAID volume status changes 6816 * or Phys Disk status changes 6817 */ 6818 (void) mptsas_get_raid_info(mpt); 6819 } 6820 /* 6821 * Abort all outstanding command on the device 6822 */ 6823 rval = mptsas_do_scsi_reset(mpt, devhdl); 6824 if (rval) { 6825 NDBG20(("mptsas%d handle_topo_change to reset target " 6826 "before offline devhdl:%x, phymask:%x, rval:%x", 6827 mpt->m_instance, ptgt->m_devhdl, 6828 ptgt->m_addr.mta_phymask, rval)); 6829 } 6830 6831 mutex_exit(&mpt->m_mutex); 6832 6833 ndi_devi_enter(scsi_vhci_dip); 6834 ndi_devi_enter(parent); 6835 rval = mptsas_offline_target(parent, addr); 6836 ndi_devi_exit(parent); 6837 ndi_devi_exit(scsi_vhci_dip); 6838 NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, " 6839 "phymask:%x, rval:%x", mpt->m_instance, 6840 ptgt->m_devhdl, ptgt->m_addr.mta_phymask, rval)); 6841 6842 kmem_free(addr, SCSI_MAXNAMELEN); 6843 6844 /* 6845 * Clear parent's props for SMHBA support 6846 */ 6847 flags = topo_node->flags; 6848 if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) { 6849 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 6850 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent, 6851 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 6852 DDI_PROP_SUCCESS) { 6853 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6854 SCSI_ADDR_PROP_ATTACHED_PORT); 6855 mptsas_log(mpt, CE_WARN, "mptsas attached port " 6856 "prop update failed"); 6857 mutex_enter(&mpt->m_mutex); 6858 break; 6859 } 6860 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6861 MPTSAS_NUM_PHYS, 0) != 6862 DDI_PROP_SUCCESS) { 6863 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6864 MPTSAS_NUM_PHYS); 6865 mptsas_log(mpt, CE_WARN, "mptsas num phys " 6866 "prop update failed"); 6867 mutex_enter(&mpt->m_mutex); 6868 break; 6869 } 6870 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6871 MPTSAS_VIRTUAL_PORT, 1) != 6872 DDI_PROP_SUCCESS) { 6873 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6874 MPTSAS_VIRTUAL_PORT); 6875 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 6876 "prop update failed"); 6877 mutex_enter(&mpt->m_mutex); 6878 break; 6879 } 6880 } 6881 6882 mutex_enter(&mpt->m_mutex); 6883 if (rval == DDI_SUCCESS) { 6884 refhash_remove(mpt->m_targets, ptgt); 6885 ptgt = NULL; 6886 } else { 6887 /* 6888 * clean DR_INTRANSITION flag to allow I/O down to 6889 * PHCI driver since failover finished. 6890 * Invalidate the devhdl 6891 */ 6892 ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL; 6893 ptgt->m_tgt_unconfigured = 0; 6894 mutex_enter(&mpt->m_tx_waitq_mutex); 6895 ptgt->m_dr_flag = MPTSAS_DR_INACTIVE; 6896 mutex_exit(&mpt->m_tx_waitq_mutex); 6897 } 6898 6899 /* 6900 * Send SAS IO Unit Control to free the dev handle 6901 */ 6902 if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) || 6903 (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE)) { 6904 rval = mptsas_free_devhdl(mpt, devhdl); 6905 6906 NDBG20(("mptsas%d handle_topo_change to remove " 6907 "devhdl:%x, rval:%x", mpt->m_instance, devhdl, 6908 rval)); 6909 } 6910 6911 break; 6912 } 6913 case MPTSAS_TOPO_FLAG_REMOVE_HANDLE: 6914 { 6915 devhdl = topo_node->devhdl; 6916 /* 6917 * If this is the remove handle event, do a reset first. 6918 */ 6919 if (topo_node->event == MPTSAS_TOPO_FLAG_REMOVE_HANDLE) { 6920 rval = mptsas_do_scsi_reset(mpt, devhdl); 6921 if (rval) { 6922 NDBG20(("mpt%d reset target before remove " 6923 "devhdl:%x, rval:%x", mpt->m_instance, 6924 devhdl, rval)); 6925 } 6926 } 6927 6928 /* 6929 * Send SAS IO Unit Control to free the dev handle 6930 */ 6931 rval = mptsas_free_devhdl(mpt, devhdl); 6932 NDBG20(("mptsas%d handle_topo_change to remove " 6933 "devhdl:%x, rval:%x", mpt->m_instance, devhdl, 6934 rval)); 6935 break; 6936 } 6937 case MPTSAS_DR_EVENT_RECONFIG_SMP: 6938 { 6939 mptsas_smp_t smp; 6940 dev_info_t *smpdip; 6941 6942 devhdl = topo_node->devhdl; 6943 6944 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL & 6945 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl; 6946 rval = mptsas_get_sas_expander_page0(mpt, page_address, &smp); 6947 if (rval != DDI_SUCCESS) { 6948 mptsas_log(mpt, CE_WARN, "failed to online smp, " 6949 "handle %x", devhdl); 6950 return; 6951 } 6952 6953 psmp = mptsas_smp_alloc(mpt, &smp); 6954 if (psmp == NULL) { 6955 return; 6956 } 6957 6958 mutex_exit(&mpt->m_mutex); 6959 ndi_devi_enter(parent); 6960 (void) mptsas_online_smp(parent, psmp, &smpdip); 6961 ndi_devi_exit(parent); 6962 6963 mutex_enter(&mpt->m_mutex); 6964 break; 6965 } 6966 case MPTSAS_DR_EVENT_OFFLINE_SMP: 6967 { 6968 devhdl = topo_node->devhdl; 6969 uint32_t dev_info; 6970 6971 psmp = refhash_linear_search(mpt->m_smp_targets, 6972 mptsas_smp_eval_devhdl, &devhdl); 6973 if (psmp == NULL) 6974 break; 6975 /* 6976 * The mptsas_smp_t data is released only if the dip is offlined 6977 * successfully. 6978 */ 6979 mutex_exit(&mpt->m_mutex); 6980 6981 ndi_devi_enter(parent); 6982 rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE); 6983 ndi_devi_exit(parent); 6984 6985 dev_info = psmp->m_deviceinfo; 6986 if ((dev_info & DEVINFO_DIRECT_ATTACHED) == 6987 DEVINFO_DIRECT_ATTACHED) { 6988 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 6989 MPTSAS_VIRTUAL_PORT, 1) != 6990 DDI_PROP_SUCCESS) { 6991 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 6992 MPTSAS_VIRTUAL_PORT); 6993 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 6994 "prop update failed"); 6995 mutex_enter(&mpt->m_mutex); 6996 return; 6997 } 6998 /* 6999 * Check whether the smp connected to the iport, 7000 */ 7001 if (ddi_prop_update_int(DDI_DEV_T_NONE, parent, 7002 MPTSAS_NUM_PHYS, 0) != 7003 DDI_PROP_SUCCESS) { 7004 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 7005 MPTSAS_NUM_PHYS); 7006 mptsas_log(mpt, CE_WARN, "mptsas num phys" 7007 "prop update failed"); 7008 mutex_enter(&mpt->m_mutex); 7009 return; 7010 } 7011 /* 7012 * Clear parent's attached-port props 7013 */ 7014 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 7015 if (ddi_prop_update_string(DDI_DEV_T_NONE, parent, 7016 SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwnstr) != 7017 DDI_PROP_SUCCESS) { 7018 (void) ddi_prop_remove(DDI_DEV_T_NONE, parent, 7019 SCSI_ADDR_PROP_ATTACHED_PORT); 7020 mptsas_log(mpt, CE_WARN, "mptsas attached port " 7021 "prop update failed"); 7022 mutex_enter(&mpt->m_mutex); 7023 return; 7024 } 7025 } 7026 7027 mutex_enter(&mpt->m_mutex); 7028 NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, " 7029 "rval:%x", mpt->m_instance, psmp->m_devhdl, rval)); 7030 if (rval == DDI_SUCCESS) { 7031 refhash_remove(mpt->m_smp_targets, psmp); 7032 } else { 7033 psmp->m_devhdl = MPTSAS_INVALID_DEVHDL; 7034 } 7035 7036 bzero(attached_wwnstr, sizeof (attached_wwnstr)); 7037 7038 break; 7039 } 7040 default: 7041 return; 7042 } 7043 } 7044 7045 /* 7046 * Record the event if its type is enabled in mpt instance by ioctl. 7047 */ 7048 static void 7049 mptsas_record_event(void *args) 7050 { 7051 m_replyh_arg_t *replyh_arg; 7052 pMpi2EventNotificationReply_t eventreply; 7053 uint32_t event, rfm; 7054 mptsas_t *mpt; 7055 int i, j; 7056 uint16_t event_data_len; 7057 boolean_t sendAEN = FALSE; 7058 7059 replyh_arg = (m_replyh_arg_t *)args; 7060 rfm = replyh_arg->rfm; 7061 mpt = replyh_arg->mpt; 7062 7063 eventreply = (pMpi2EventNotificationReply_t) 7064 (mpt->m_reply_frame + (rfm - 7065 (mpt->m_reply_frame_dma_addr & 0xffffffffu))); 7066 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 7067 7068 7069 /* 7070 * Generate a system event to let anyone who cares know that a 7071 * LOG_ENTRY_ADDED event has occurred. This is sent no matter what the 7072 * event mask is set to. 7073 */ 7074 if (event == MPI2_EVENT_LOG_ENTRY_ADDED) { 7075 sendAEN = TRUE; 7076 } 7077 7078 /* 7079 * Record the event only if it is not masked. Determine which dword 7080 * and bit of event mask to test. 7081 */ 7082 i = (uint8_t)(event / 32); 7083 j = (uint8_t)(event % 32); 7084 if ((i < 4) && ((1 << j) & mpt->m_event_mask[i])) { 7085 i = mpt->m_event_index; 7086 mpt->m_events[i].Type = event; 7087 mpt->m_events[i].Number = ++mpt->m_event_number; 7088 bzero(mpt->m_events[i].Data, MPTSAS_MAX_EVENT_DATA_LENGTH * 4); 7089 event_data_len = ddi_get16(mpt->m_acc_reply_frame_hdl, 7090 &eventreply->EventDataLength); 7091 7092 if (event_data_len > 0) { 7093 /* 7094 * Limit data to size in m_event entry 7095 */ 7096 if (event_data_len > MPTSAS_MAX_EVENT_DATA_LENGTH) { 7097 event_data_len = MPTSAS_MAX_EVENT_DATA_LENGTH; 7098 } 7099 for (j = 0; j < event_data_len; j++) { 7100 mpt->m_events[i].Data[j] = 7101 ddi_get32(mpt->m_acc_reply_frame_hdl, 7102 &(eventreply->EventData[j])); 7103 } 7104 7105 /* 7106 * check for index wrap-around 7107 */ 7108 if (++i == MPTSAS_EVENT_QUEUE_SIZE) { 7109 i = 0; 7110 } 7111 mpt->m_event_index = (uint8_t)i; 7112 7113 /* 7114 * Set flag to send the event. 7115 */ 7116 sendAEN = TRUE; 7117 } 7118 } 7119 7120 /* 7121 * Generate a system event if flag is set to let anyone who cares know 7122 * that an event has occurred. 7123 */ 7124 if (sendAEN) { 7125 (void) ddi_log_sysevent(mpt->m_dip, DDI_VENDOR_LSI, "MPT_SAS", 7126 "SAS", NULL, NULL, DDI_NOSLEEP); 7127 } 7128 } 7129 7130 #define SMP_RESET_IN_PROGRESS MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS 7131 /* 7132 * handle sync events from ioc in interrupt 7133 * return value: 7134 * DDI_SUCCESS: The event is handled by this func 7135 * DDI_FAILURE: Event is not handled 7136 */ 7137 static int 7138 mptsas_handle_event_sync(void *args) 7139 { 7140 m_replyh_arg_t *replyh_arg; 7141 pMpi2EventNotificationReply_t eventreply; 7142 uint32_t event, rfm; 7143 mptsas_t *mpt; 7144 uint_t iocstatus; 7145 7146 replyh_arg = (m_replyh_arg_t *)args; 7147 rfm = replyh_arg->rfm; 7148 mpt = replyh_arg->mpt; 7149 7150 ASSERT(mutex_owned(&mpt->m_mutex)); 7151 7152 eventreply = (pMpi2EventNotificationReply_t) 7153 (mpt->m_reply_frame + (rfm - 7154 (mpt->m_reply_frame_dma_addr & 0xffffffffu))); 7155 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 7156 7157 if ((iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 7158 &eventreply->IOCStatus)) != 0) { 7159 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 7160 mptsas_log(mpt, CE_WARN, 7161 "!mptsas_handle_event_sync: event 0x%x, " 7162 "IOCStatus=0x%x, " 7163 "IOCLogInfo=0x%x", event, iocstatus, 7164 ddi_get32(mpt->m_acc_reply_frame_hdl, 7165 &eventreply->IOCLogInfo)); 7166 } else { 7167 mptsas_log(mpt, CE_WARN, 7168 "mptsas_handle_event_sync: event 0x%x, " 7169 "IOCStatus=0x%x, " 7170 "(IOCLogInfo=0x%x)", event, iocstatus, 7171 ddi_get32(mpt->m_acc_reply_frame_hdl, 7172 &eventreply->IOCLogInfo)); 7173 } 7174 } 7175 7176 /* 7177 * figure out what kind of event we got and handle accordingly 7178 */ 7179 switch (event) { 7180 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 7181 { 7182 pMpi2EventDataSasTopologyChangeList_t sas_topo_change_list; 7183 uint8_t num_entries, expstatus, phy; 7184 uint8_t phystatus, physport, state, i; 7185 uint8_t start_phy_num, link_rate; 7186 uint16_t dev_handle, reason_code; 7187 uint16_t enc_handle, expd_handle; 7188 char string[80], curr[80], prev[80]; 7189 mptsas_topo_change_list_t *topo_head = NULL; 7190 mptsas_topo_change_list_t *topo_tail = NULL; 7191 mptsas_topo_change_list_t *topo_node = NULL; 7192 mptsas_target_t *ptgt; 7193 mptsas_smp_t *psmp; 7194 uint8_t flags = 0, exp_flag; 7195 smhba_info_t *pSmhba = NULL; 7196 7197 NDBG20(("mptsas_handle_event_sync: SAS topology change")); 7198 7199 sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t) 7200 eventreply->EventData; 7201 7202 enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7203 &sas_topo_change_list->EnclosureHandle); 7204 expd_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7205 &sas_topo_change_list->ExpanderDevHandle); 7206 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl, 7207 &sas_topo_change_list->NumEntries); 7208 start_phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl, 7209 &sas_topo_change_list->StartPhyNum); 7210 expstatus = ddi_get8(mpt->m_acc_reply_frame_hdl, 7211 &sas_topo_change_list->ExpStatus); 7212 physport = ddi_get8(mpt->m_acc_reply_frame_hdl, 7213 &sas_topo_change_list->PhysicalPort); 7214 7215 string[0] = 0; 7216 if (expd_handle) { 7217 flags = MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED; 7218 switch (expstatus) { 7219 case MPI2_EVENT_SAS_TOPO_ES_ADDED: 7220 (void) sprintf(string, " added"); 7221 /* 7222 * New expander device added 7223 */ 7224 mpt->m_port_chng = 1; 7225 topo_node = kmem_zalloc( 7226 sizeof (mptsas_topo_change_list_t), 7227 KM_SLEEP); 7228 topo_node->mpt = mpt; 7229 topo_node->event = MPTSAS_DR_EVENT_RECONFIG_SMP; 7230 topo_node->un.physport = physport; 7231 topo_node->devhdl = expd_handle; 7232 topo_node->flags = flags; 7233 topo_node->object = NULL; 7234 if (topo_head == NULL) { 7235 topo_head = topo_tail = topo_node; 7236 } else { 7237 topo_tail->next = topo_node; 7238 topo_tail = topo_node; 7239 } 7240 break; 7241 case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING: 7242 (void) sprintf(string, " not responding, " 7243 "removed"); 7244 psmp = refhash_linear_search(mpt->m_smp_targets, 7245 mptsas_smp_eval_devhdl, &expd_handle); 7246 if (psmp == NULL) 7247 break; 7248 7249 topo_node = kmem_zalloc( 7250 sizeof (mptsas_topo_change_list_t), 7251 KM_SLEEP); 7252 topo_node->mpt = mpt; 7253 topo_node->un.phymask = 7254 psmp->m_addr.mta_phymask; 7255 topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP; 7256 topo_node->devhdl = expd_handle; 7257 topo_node->flags = flags; 7258 topo_node->object = NULL; 7259 if (topo_head == NULL) { 7260 topo_head = topo_tail = topo_node; 7261 } else { 7262 topo_tail->next = topo_node; 7263 topo_tail = topo_node; 7264 } 7265 break; 7266 case MPI2_EVENT_SAS_TOPO_ES_RESPONDING: 7267 break; 7268 case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING: 7269 (void) sprintf(string, " not responding, " 7270 "delaying removal"); 7271 break; 7272 default: 7273 break; 7274 } 7275 } else { 7276 flags = MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE; 7277 } 7278 7279 NDBG20(("SAS TOPOLOGY CHANGE for enclosure %x expander %x%s\n", 7280 enc_handle, expd_handle, string)); 7281 for (i = 0; i < num_entries; i++) { 7282 phy = i + start_phy_num; 7283 phystatus = ddi_get8(mpt->m_acc_reply_frame_hdl, 7284 &sas_topo_change_list->PHY[i].PhyStatus); 7285 dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7286 &sas_topo_change_list->PHY[i].AttachedDevHandle); 7287 reason_code = phystatus & MPI2_EVENT_SAS_TOPO_RC_MASK; 7288 /* 7289 * Filter out processing of Phy Vacant Status unless 7290 * the reason code is "Not Responding". Process all 7291 * other combinations of Phy Status and Reason Codes. 7292 */ 7293 if ((phystatus & 7294 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) && 7295 (reason_code != 7296 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) { 7297 continue; 7298 } 7299 curr[0] = 0; 7300 prev[0] = 0; 7301 string[0] = 0; 7302 switch (reason_code) { 7303 case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: 7304 { 7305 NDBG20(("mptsas%d phy %d physical_port %d " 7306 "dev_handle %d added", mpt->m_instance, phy, 7307 physport, dev_handle)); 7308 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl, 7309 &sas_topo_change_list->PHY[i].LinkRate); 7310 state = (link_rate & 7311 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >> 7312 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT; 7313 switch (state) { 7314 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 7315 (void) sprintf(curr, "is disabled"); 7316 break; 7317 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 7318 (void) sprintf(curr, "is offline, " 7319 "failed speed negotiation"); 7320 break; 7321 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 7322 (void) sprintf(curr, "SATA OOB " 7323 "complete"); 7324 break; 7325 case SMP_RESET_IN_PROGRESS: 7326 (void) sprintf(curr, "SMP reset in " 7327 "progress"); 7328 break; 7329 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 7330 (void) sprintf(curr, "is online at " 7331 "1.5 Gbps"); 7332 break; 7333 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 7334 (void) sprintf(curr, "is online at 3.0 " 7335 "Gbps"); 7336 break; 7337 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 7338 (void) sprintf(curr, "is online at 6.0 " 7339 "Gbps"); 7340 break; 7341 case MPI25_EVENT_SAS_TOPO_LR_RATE_12_0: 7342 (void) sprintf(curr, 7343 "is online at 12.0 Gbps"); 7344 break; 7345 default: 7346 (void) sprintf(curr, "state is " 7347 "unknown"); 7348 break; 7349 } 7350 /* 7351 * New target device added into the system. 7352 * Set association flag according to if an 7353 * expander is used or not. 7354 */ 7355 exp_flag = 7356 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE; 7357 if (flags == 7358 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) { 7359 flags = exp_flag; 7360 } 7361 topo_node = kmem_zalloc( 7362 sizeof (mptsas_topo_change_list_t), 7363 KM_SLEEP); 7364 topo_node->mpt = mpt; 7365 topo_node->event = 7366 MPTSAS_DR_EVENT_RECONFIG_TARGET; 7367 if (expd_handle == 0) { 7368 /* 7369 * Per MPI 2, if expander dev handle 7370 * is 0, it's a directly attached 7371 * device. So driver use PHY to decide 7372 * which iport is associated 7373 */ 7374 physport = phy; 7375 mpt->m_port_chng = 1; 7376 } 7377 topo_node->un.physport = physport; 7378 topo_node->devhdl = dev_handle; 7379 topo_node->flags = flags; 7380 topo_node->object = NULL; 7381 if (topo_head == NULL) { 7382 topo_head = topo_tail = topo_node; 7383 } else { 7384 topo_tail->next = topo_node; 7385 topo_tail = topo_node; 7386 } 7387 break; 7388 } 7389 case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: 7390 { 7391 NDBG20(("mptsas%d phy %d physical_port %d " 7392 "dev_handle %d removed", mpt->m_instance, 7393 phy, physport, dev_handle)); 7394 /* 7395 * Set association flag according to if an 7396 * expander is used or not. 7397 */ 7398 exp_flag = 7399 MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE; 7400 if (flags == 7401 MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) { 7402 flags = exp_flag; 7403 } 7404 /* 7405 * Target device is removed from the system 7406 * Before the device is really offline from 7407 * from system. 7408 */ 7409 ptgt = refhash_linear_search(mpt->m_targets, 7410 mptsas_target_eval_devhdl, &dev_handle); 7411 /* 7412 * If ptgt is NULL here, it means that the 7413 * DevHandle is not in the hash table. This is 7414 * reasonable sometimes. For example, if a 7415 * disk was pulled, then added, then pulled 7416 * again, the disk will not have been put into 7417 * the hash table because the add event will 7418 * have an invalid phymask. BUT, this does not 7419 * mean that the DevHandle is invalid. The 7420 * controller will still have a valid DevHandle 7421 * that must be removed. To do this, use the 7422 * MPTSAS_TOPO_FLAG_REMOVE_HANDLE event. 7423 */ 7424 if (ptgt == NULL) { 7425 topo_node = kmem_zalloc( 7426 sizeof (mptsas_topo_change_list_t), 7427 KM_SLEEP); 7428 topo_node->mpt = mpt; 7429 topo_node->un.phymask = 0; 7430 topo_node->event = 7431 MPTSAS_TOPO_FLAG_REMOVE_HANDLE; 7432 topo_node->devhdl = dev_handle; 7433 topo_node->flags = flags; 7434 topo_node->object = NULL; 7435 if (topo_head == NULL) { 7436 topo_head = topo_tail = 7437 topo_node; 7438 } else { 7439 topo_tail->next = topo_node; 7440 topo_tail = topo_node; 7441 } 7442 break; 7443 } 7444 7445 /* 7446 * Update DR flag immediately avoid I/O failure 7447 * before failover finish. Pay attention to the 7448 * mutex protect, we need grab m_tx_waitq_mutex 7449 * during set m_dr_flag because we won't add 7450 * the following command into waitq, instead, 7451 * we need return TRAN_BUSY in the tran_start 7452 * context. 7453 */ 7454 mutex_enter(&mpt->m_tx_waitq_mutex); 7455 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 7456 mutex_exit(&mpt->m_tx_waitq_mutex); 7457 7458 topo_node = kmem_zalloc( 7459 sizeof (mptsas_topo_change_list_t), 7460 KM_SLEEP); 7461 topo_node->mpt = mpt; 7462 topo_node->un.phymask = 7463 ptgt->m_addr.mta_phymask; 7464 topo_node->event = 7465 MPTSAS_DR_EVENT_OFFLINE_TARGET; 7466 topo_node->devhdl = dev_handle; 7467 topo_node->flags = flags; 7468 topo_node->object = NULL; 7469 if (topo_head == NULL) { 7470 topo_head = topo_tail = topo_node; 7471 } else { 7472 topo_tail->next = topo_node; 7473 topo_tail = topo_node; 7474 } 7475 break; 7476 } 7477 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 7478 link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl, 7479 &sas_topo_change_list->PHY[i].LinkRate); 7480 state = (link_rate & 7481 MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >> 7482 MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT; 7483 pSmhba = &mpt->m_phy_info[i].smhba_info; 7484 pSmhba->negotiated_link_rate = state; 7485 switch (state) { 7486 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 7487 (void) sprintf(curr, "is disabled"); 7488 mptsas_smhba_log_sysevent(mpt, 7489 ESC_SAS_PHY_EVENT, 7490 SAS_PHY_REMOVE, 7491 &mpt->m_phy_info[i].smhba_info); 7492 mpt->m_phy_info[i].smhba_info. 7493 negotiated_link_rate 7494 = 0x1; 7495 break; 7496 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 7497 (void) sprintf(curr, "is offline, " 7498 "failed speed negotiation"); 7499 mptsas_smhba_log_sysevent(mpt, 7500 ESC_SAS_PHY_EVENT, 7501 SAS_PHY_OFFLINE, 7502 &mpt->m_phy_info[i].smhba_info); 7503 break; 7504 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 7505 (void) sprintf(curr, "SATA OOB " 7506 "complete"); 7507 break; 7508 case SMP_RESET_IN_PROGRESS: 7509 (void) sprintf(curr, "SMP reset in " 7510 "progress"); 7511 break; 7512 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 7513 (void) sprintf(curr, "is online at " 7514 "1.5 Gbps"); 7515 if ((expd_handle == 0) && 7516 (enc_handle == 1)) { 7517 mpt->m_port_chng = 1; 7518 } 7519 mptsas_smhba_log_sysevent(mpt, 7520 ESC_SAS_PHY_EVENT, 7521 SAS_PHY_ONLINE, 7522 &mpt->m_phy_info[i].smhba_info); 7523 break; 7524 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 7525 (void) sprintf(curr, "is online at 3.0 " 7526 "Gbps"); 7527 if ((expd_handle == 0) && 7528 (enc_handle == 1)) { 7529 mpt->m_port_chng = 1; 7530 } 7531 mptsas_smhba_log_sysevent(mpt, 7532 ESC_SAS_PHY_EVENT, 7533 SAS_PHY_ONLINE, 7534 &mpt->m_phy_info[i].smhba_info); 7535 break; 7536 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 7537 (void) sprintf(curr, "is online at " 7538 "6.0 Gbps"); 7539 if ((expd_handle == 0) && 7540 (enc_handle == 1)) { 7541 mpt->m_port_chng = 1; 7542 } 7543 mptsas_smhba_log_sysevent(mpt, 7544 ESC_SAS_PHY_EVENT, 7545 SAS_PHY_ONLINE, 7546 &mpt->m_phy_info[i].smhba_info); 7547 break; 7548 case MPI25_EVENT_SAS_TOPO_LR_RATE_12_0: 7549 (void) sprintf(curr, "is online at " 7550 "12.0 Gbps"); 7551 if ((expd_handle == 0) && 7552 (enc_handle == 1)) { 7553 mpt->m_port_chng = 1; 7554 } 7555 mptsas_smhba_log_sysevent(mpt, 7556 ESC_SAS_PHY_EVENT, 7557 SAS_PHY_ONLINE, 7558 &mpt->m_phy_info[i].smhba_info); 7559 break; 7560 default: 7561 (void) sprintf(curr, "state is " 7562 "unknown"); 7563 break; 7564 } 7565 7566 state = (link_rate & 7567 MPI2_EVENT_SAS_TOPO_LR_PREV_MASK) >> 7568 MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT; 7569 switch (state) { 7570 case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: 7571 (void) sprintf(prev, ", was disabled"); 7572 break; 7573 case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: 7574 (void) sprintf(prev, ", was offline, " 7575 "failed speed negotiation"); 7576 break; 7577 case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: 7578 (void) sprintf(prev, ", was SATA OOB " 7579 "complete"); 7580 break; 7581 case SMP_RESET_IN_PROGRESS: 7582 (void) sprintf(prev, ", was SMP reset " 7583 "in progress"); 7584 break; 7585 case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: 7586 (void) sprintf(prev, ", was online at " 7587 "1.5 Gbps"); 7588 break; 7589 case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: 7590 (void) sprintf(prev, ", was online at " 7591 "3.0 Gbps"); 7592 break; 7593 case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: 7594 (void) sprintf(prev, ", was online at " 7595 "6.0 Gbps"); 7596 break; 7597 case MPI25_EVENT_SAS_TOPO_LR_RATE_12_0: 7598 (void) sprintf(prev, ", was online at " 7599 "12.0 Gbps"); 7600 break; 7601 default: 7602 break; 7603 } 7604 (void) sprintf(&string[strlen(string)], "link " 7605 "changed, "); 7606 break; 7607 case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE: 7608 continue; 7609 case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING: 7610 (void) sprintf(&string[strlen(string)], 7611 "target not responding, delaying " 7612 "removal"); 7613 break; 7614 } 7615 NDBG20(("mptsas%d phy %d DevHandle %x, %s%s%s\n", 7616 mpt->m_instance, phy, dev_handle, string, curr, 7617 prev)); 7618 } 7619 if (topo_head != NULL) { 7620 /* 7621 * Launch DR taskq to handle topology change 7622 */ 7623 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 7624 mptsas_handle_dr, (void *)topo_head, 7625 DDI_NOSLEEP)) != DDI_SUCCESS) { 7626 while (topo_head != NULL) { 7627 topo_node = topo_head; 7628 topo_head = topo_head->next; 7629 kmem_free(topo_node, 7630 sizeof (mptsas_topo_change_list_t)); 7631 } 7632 mptsas_log(mpt, CE_NOTE, "mptsas start taskq " 7633 "for handle SAS DR event failed. \n"); 7634 } 7635 } 7636 break; 7637 } 7638 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 7639 { 7640 Mpi2EventDataIrConfigChangeList_t *irChangeList; 7641 mptsas_topo_change_list_t *topo_head = NULL; 7642 mptsas_topo_change_list_t *topo_tail = NULL; 7643 mptsas_topo_change_list_t *topo_node = NULL; 7644 mptsas_target_t *ptgt; 7645 uint8_t num_entries, i, reason; 7646 uint16_t volhandle, diskhandle; 7647 7648 irChangeList = (pMpi2EventDataIrConfigChangeList_t) 7649 eventreply->EventData; 7650 num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl, 7651 &irChangeList->NumElements); 7652 7653 NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received", 7654 mpt->m_instance)); 7655 7656 for (i = 0; i < num_entries; i++) { 7657 reason = ddi_get8(mpt->m_acc_reply_frame_hdl, 7658 &irChangeList->ConfigElement[i].ReasonCode); 7659 volhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7660 &irChangeList->ConfigElement[i].VolDevHandle); 7661 diskhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 7662 &irChangeList->ConfigElement[i].PhysDiskDevHandle); 7663 7664 switch (reason) { 7665 case MPI2_EVENT_IR_CHANGE_RC_ADDED: 7666 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: 7667 { 7668 NDBG20(("mptsas %d volume added\n", 7669 mpt->m_instance)); 7670 7671 topo_node = kmem_zalloc( 7672 sizeof (mptsas_topo_change_list_t), 7673 KM_SLEEP); 7674 7675 topo_node->mpt = mpt; 7676 topo_node->event = 7677 MPTSAS_DR_EVENT_RECONFIG_TARGET; 7678 topo_node->un.physport = 0xff; 7679 topo_node->devhdl = volhandle; 7680 topo_node->flags = 7681 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED; 7682 topo_node->object = NULL; 7683 if (topo_head == NULL) { 7684 topo_head = topo_tail = topo_node; 7685 } else { 7686 topo_tail->next = topo_node; 7687 topo_tail = topo_node; 7688 } 7689 break; 7690 } 7691 case MPI2_EVENT_IR_CHANGE_RC_REMOVED: 7692 case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: 7693 { 7694 NDBG20(("mptsas %d volume deleted\n", 7695 mpt->m_instance)); 7696 ptgt = refhash_linear_search(mpt->m_targets, 7697 mptsas_target_eval_devhdl, &volhandle); 7698 if (ptgt == NULL) 7699 break; 7700 7701 /* 7702 * Clear any flags related to volume 7703 */ 7704 (void) mptsas_delete_volume(mpt, volhandle); 7705 7706 /* 7707 * Update DR flag immediately avoid I/O failure 7708 */ 7709 mutex_enter(&mpt->m_tx_waitq_mutex); 7710 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 7711 mutex_exit(&mpt->m_tx_waitq_mutex); 7712 7713 topo_node = kmem_zalloc( 7714 sizeof (mptsas_topo_change_list_t), 7715 KM_SLEEP); 7716 topo_node->mpt = mpt; 7717 topo_node->un.phymask = 7718 ptgt->m_addr.mta_phymask; 7719 topo_node->event = 7720 MPTSAS_DR_EVENT_OFFLINE_TARGET; 7721 topo_node->devhdl = volhandle; 7722 topo_node->flags = 7723 MPTSAS_TOPO_FLAG_RAID_ASSOCIATED; 7724 topo_node->object = (void *)ptgt; 7725 if (topo_head == NULL) { 7726 topo_head = topo_tail = topo_node; 7727 } else { 7728 topo_tail->next = topo_node; 7729 topo_tail = topo_node; 7730 } 7731 break; 7732 } 7733 case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: 7734 case MPI2_EVENT_IR_CHANGE_RC_HIDE: 7735 { 7736 ptgt = refhash_linear_search(mpt->m_targets, 7737 mptsas_target_eval_devhdl, &diskhandle); 7738 if (ptgt == NULL) 7739 break; 7740 7741 /* 7742 * Update DR flag immediately avoid I/O failure 7743 */ 7744 mutex_enter(&mpt->m_tx_waitq_mutex); 7745 ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION; 7746 mutex_exit(&mpt->m_tx_waitq_mutex); 7747 7748 topo_node = kmem_zalloc( 7749 sizeof (mptsas_topo_change_list_t), 7750 KM_SLEEP); 7751 topo_node->mpt = mpt; 7752 topo_node->un.phymask = 7753 ptgt->m_addr.mta_phymask; 7754 topo_node->event = 7755 MPTSAS_DR_EVENT_OFFLINE_TARGET; 7756 topo_node->devhdl = diskhandle; 7757 topo_node->flags = 7758 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED; 7759 topo_node->object = (void *)ptgt; 7760 if (topo_head == NULL) { 7761 topo_head = topo_tail = topo_node; 7762 } else { 7763 topo_tail->next = topo_node; 7764 topo_tail = topo_node; 7765 } 7766 break; 7767 } 7768 case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: 7769 case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: 7770 { 7771 /* 7772 * The physical drive is released by a IR 7773 * volume. But we cannot get the the physport 7774 * or phynum from the event data, so we only 7775 * can get the physport/phynum after SAS 7776 * Device Page0 request for the devhdl. 7777 */ 7778 topo_node = kmem_zalloc( 7779 sizeof (mptsas_topo_change_list_t), 7780 KM_SLEEP); 7781 topo_node->mpt = mpt; 7782 topo_node->un.phymask = 0; 7783 topo_node->event = 7784 MPTSAS_DR_EVENT_RECONFIG_TARGET; 7785 topo_node->devhdl = diskhandle; 7786 topo_node->flags = 7787 MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED; 7788 topo_node->object = NULL; 7789 mpt->m_port_chng = 1; 7790 if (topo_head == NULL) { 7791 topo_head = topo_tail = topo_node; 7792 } else { 7793 topo_tail->next = topo_node; 7794 topo_tail = topo_node; 7795 } 7796 break; 7797 } 7798 default: 7799 break; 7800 } 7801 } 7802 7803 if (topo_head != NULL) { 7804 /* 7805 * Launch DR taskq to handle topology change 7806 */ 7807 if ((ddi_taskq_dispatch(mpt->m_dr_taskq, 7808 mptsas_handle_dr, (void *)topo_head, 7809 DDI_NOSLEEP)) != DDI_SUCCESS) { 7810 while (topo_head != NULL) { 7811 topo_node = topo_head; 7812 topo_head = topo_head->next; 7813 kmem_free(topo_node, 7814 sizeof (mptsas_topo_change_list_t)); 7815 } 7816 mptsas_log(mpt, CE_NOTE, "mptsas start taskq " 7817 "for handle SAS DR event failed. \n"); 7818 } 7819 } 7820 break; 7821 } 7822 default: 7823 return (DDI_FAILURE); 7824 } 7825 7826 return (DDI_SUCCESS); 7827 } 7828 7829 /* 7830 * handle events from ioc 7831 */ 7832 static void 7833 mptsas_handle_event(void *args) 7834 { 7835 m_replyh_arg_t *replyh_arg; 7836 pMpi2EventNotificationReply_t eventreply; 7837 uint32_t event, iocloginfo, rfm; 7838 uint32_t status; 7839 uint8_t port; 7840 mptsas_t *mpt; 7841 uint_t iocstatus; 7842 7843 replyh_arg = (m_replyh_arg_t *)args; 7844 rfm = replyh_arg->rfm; 7845 mpt = replyh_arg->mpt; 7846 7847 mutex_enter(&mpt->m_mutex); 7848 /* 7849 * If HBA is being reset, drop incoming event. 7850 */ 7851 if (mpt->m_in_reset) { 7852 NDBG20(("dropping event received prior to reset")); 7853 mutex_exit(&mpt->m_mutex); 7854 return; 7855 } 7856 7857 eventreply = (pMpi2EventNotificationReply_t) 7858 (mpt->m_reply_frame + (rfm - 7859 (mpt->m_reply_frame_dma_addr & 0xffffffffu))); 7860 event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event); 7861 7862 if ((iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 7863 &eventreply->IOCStatus)) != 0) { 7864 if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 7865 mptsas_log(mpt, CE_WARN, 7866 "!mptsas_handle_event: IOCStatus=0x%x, " 7867 "IOCLogInfo=0x%x", iocstatus, 7868 ddi_get32(mpt->m_acc_reply_frame_hdl, 7869 &eventreply->IOCLogInfo)); 7870 } else { 7871 mptsas_log(mpt, CE_WARN, 7872 "mptsas_handle_event: IOCStatus=0x%x, " 7873 "IOCLogInfo=0x%x", iocstatus, 7874 ddi_get32(mpt->m_acc_reply_frame_hdl, 7875 &eventreply->IOCLogInfo)); 7876 } 7877 } 7878 7879 /* 7880 * figure out what kind of event we got and handle accordingly 7881 */ 7882 switch (event) { 7883 case MPI2_EVENT_LOG_ENTRY_ADDED: 7884 break; 7885 case MPI2_EVENT_LOG_DATA: 7886 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 7887 &eventreply->IOCLogInfo); 7888 NDBG20(("mptsas %d log info %x received.\n", mpt->m_instance, 7889 iocloginfo)); 7890 break; 7891 case MPI2_EVENT_STATE_CHANGE: 7892 NDBG20(("mptsas%d state change.", mpt->m_instance)); 7893 break; 7894 case MPI2_EVENT_HARD_RESET_RECEIVED: 7895 NDBG20(("mptsas%d event change.", mpt->m_instance)); 7896 break; 7897 case MPI2_EVENT_SAS_DISCOVERY: 7898 { 7899 MPI2_EVENT_DATA_SAS_DISCOVERY *sasdiscovery; 7900 char string[80]; 7901 uint8_t rc; 7902 7903 sasdiscovery = 7904 (pMpi2EventDataSasDiscovery_t)eventreply->EventData; 7905 7906 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7907 &sasdiscovery->ReasonCode); 7908 port = ddi_get8(mpt->m_acc_reply_frame_hdl, 7909 &sasdiscovery->PhysicalPort); 7910 status = ddi_get32(mpt->m_acc_reply_frame_hdl, 7911 &sasdiscovery->DiscoveryStatus); 7912 7913 string[0] = 0; 7914 switch (rc) { 7915 case MPI2_EVENT_SAS_DISC_RC_STARTED: 7916 (void) sprintf(string, "STARTING"); 7917 break; 7918 case MPI2_EVENT_SAS_DISC_RC_COMPLETED: 7919 (void) sprintf(string, "COMPLETED"); 7920 break; 7921 default: 7922 (void) sprintf(string, "UNKNOWN"); 7923 break; 7924 } 7925 7926 NDBG20(("SAS DISCOVERY is %s for port %d, status %x", string, 7927 port, status)); 7928 7929 break; 7930 } 7931 case MPI2_EVENT_EVENT_CHANGE: 7932 NDBG20(("mptsas%d event change.", mpt->m_instance)); 7933 break; 7934 case MPI2_EVENT_TASK_SET_FULL: 7935 { 7936 pMpi2EventDataTaskSetFull_t taskfull; 7937 7938 taskfull = (pMpi2EventDataTaskSetFull_t)eventreply->EventData; 7939 7940 NDBG20(("TASK_SET_FULL received for mptsas%d, depth %d\n", 7941 mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl, 7942 &taskfull->CurrentDepth))); 7943 break; 7944 } 7945 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 7946 { 7947 /* 7948 * SAS TOPOLOGY CHANGE LIST Event has already been handled 7949 * in mptsas_handle_event_sync() of interrupt context 7950 */ 7951 break; 7952 } 7953 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: 7954 { 7955 pMpi2EventDataSasEnclDevStatusChange_t encstatus; 7956 uint8_t rc; 7957 uint16_t enchdl; 7958 char string[80]; 7959 mptsas_enclosure_t *mep; 7960 7961 encstatus = (pMpi2EventDataSasEnclDevStatusChange_t) 7962 eventreply->EventData; 7963 7964 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 7965 &encstatus->ReasonCode); 7966 enchdl = ddi_get16(mpt->m_acc_reply_frame_hdl, 7967 &encstatus->EnclosureHandle); 7968 7969 switch (rc) { 7970 case MPI2_EVENT_SAS_ENCL_RC_ADDED: 7971 (void) sprintf(string, "added"); 7972 break; 7973 case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING: 7974 mep = mptsas_enc_lookup(mpt, enchdl); 7975 if (mep != NULL) { 7976 list_remove(&mpt->m_enclosures, mep); 7977 mptsas_enc_free(mep); 7978 mep = NULL; 7979 } 7980 (void) sprintf(string, ", not responding"); 7981 break; 7982 default: 7983 break; 7984 } 7985 NDBG20(("mptsas%d ENCLOSURE STATUS CHANGE for enclosure " 7986 "%x%s\n", mpt->m_instance, 7987 ddi_get16(mpt->m_acc_reply_frame_hdl, 7988 &encstatus->EnclosureHandle), string)); 7989 7990 /* 7991 * No matter what has happened, update all of our device state 7992 * for enclosures, by retriggering an evaluation. 7993 */ 7994 mpt->m_done_traverse_enc = 0; 7995 mptsas_update_hashtab(mpt); 7996 break; 7997 } 7998 7999 /* 8000 * MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE is handled by 8001 * mptsas_handle_event_sync,in here just send ack message. 8002 */ 8003 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: 8004 { 8005 pMpi2EventDataSasDeviceStatusChange_t statuschange; 8006 uint8_t rc; 8007 uint16_t devhdl; 8008 uint64_t wwn = 0; 8009 uint32_t wwn_lo, wwn_hi; 8010 8011 statuschange = (pMpi2EventDataSasDeviceStatusChange_t) 8012 eventreply->EventData; 8013 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 8014 &statuschange->ReasonCode); 8015 wwn_lo = ddi_get32(mpt->m_acc_reply_frame_hdl, 8016 (uint32_t *)(void *)&statuschange->SASAddress); 8017 wwn_hi = ddi_get32(mpt->m_acc_reply_frame_hdl, 8018 (uint32_t *)(void *)&statuschange->SASAddress + 1); 8019 wwn = ((uint64_t)wwn_hi << 32) | wwn_lo; 8020 devhdl = ddi_get16(mpt->m_acc_reply_frame_hdl, 8021 &statuschange->DevHandle); 8022 8023 NDBG13(("MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE wwn is %"PRIx64, 8024 wwn)); 8025 8026 switch (rc) { 8027 case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA: 8028 NDBG20(("SMART data received, ASC/ASCQ = %02x/%02x", 8029 ddi_get8(mpt->m_acc_reply_frame_hdl, 8030 &statuschange->ASC), 8031 ddi_get8(mpt->m_acc_reply_frame_hdl, 8032 &statuschange->ASCQ))); 8033 break; 8034 8035 case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED: 8036 NDBG20(("Device not supported")); 8037 break; 8038 8039 case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: 8040 NDBG20(("IOC internally generated the Target Reset " 8041 "for devhdl:%x", devhdl)); 8042 break; 8043 8044 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET: 8045 NDBG20(("IOC's internally generated Target Reset " 8046 "completed for devhdl:%x", devhdl)); 8047 break; 8048 8049 case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: 8050 NDBG20(("IOC internally generated Abort Task")); 8051 break; 8052 8053 case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL: 8054 NDBG20(("IOC's internally generated Abort Task " 8055 "completed")); 8056 break; 8057 8058 case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: 8059 NDBG20(("IOC internally generated Abort Task Set")); 8060 break; 8061 8062 case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: 8063 NDBG20(("IOC internally generated Clear Task Set")); 8064 break; 8065 8066 case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: 8067 NDBG20(("IOC internally generated Query Task")); 8068 break; 8069 8070 case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION: 8071 NDBG20(("Device sent an Asynchronous Notification")); 8072 break; 8073 8074 default: 8075 break; 8076 } 8077 break; 8078 } 8079 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 8080 { 8081 /* 8082 * IR TOPOLOGY CHANGE LIST Event has already been handled 8083 * in mpt_handle_event_sync() of interrupt context 8084 */ 8085 break; 8086 } 8087 case MPI2_EVENT_IR_OPERATION_STATUS: 8088 { 8089 Mpi2EventDataIrOperationStatus_t *irOpStatus; 8090 char reason_str[80]; 8091 uint8_t rc, percent; 8092 uint16_t handle; 8093 8094 irOpStatus = (pMpi2EventDataIrOperationStatus_t) 8095 eventreply->EventData; 8096 rc = ddi_get8(mpt->m_acc_reply_frame_hdl, 8097 &irOpStatus->RAIDOperation); 8098 percent = ddi_get8(mpt->m_acc_reply_frame_hdl, 8099 &irOpStatus->PercentComplete); 8100 handle = ddi_get16(mpt->m_acc_reply_frame_hdl, 8101 &irOpStatus->VolDevHandle); 8102 8103 switch (rc) { 8104 case MPI2_EVENT_IR_RAIDOP_RESYNC: 8105 (void) sprintf(reason_str, "resync"); 8106 break; 8107 case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION: 8108 (void) sprintf(reason_str, "online capacity " 8109 "expansion"); 8110 break; 8111 case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK: 8112 (void) sprintf(reason_str, "consistency check"); 8113 break; 8114 default: 8115 (void) sprintf(reason_str, "unknown reason %x", 8116 rc); 8117 } 8118 8119 NDBG20(("mptsas%d raid operational status: (%s)" 8120 "\thandle(0x%04x), percent complete(%d)\n", 8121 mpt->m_instance, reason_str, handle, percent)); 8122 break; 8123 } 8124 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: 8125 { 8126 pMpi2EventDataSasBroadcastPrimitive_t sas_broadcast; 8127 uint8_t phy_num; 8128 uint8_t primitive; 8129 8130 sas_broadcast = (pMpi2EventDataSasBroadcastPrimitive_t) 8131 eventreply->EventData; 8132 8133 phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl, 8134 &sas_broadcast->PhyNum); 8135 primitive = ddi_get8(mpt->m_acc_reply_frame_hdl, 8136 &sas_broadcast->Primitive); 8137 8138 switch (primitive) { 8139 case MPI2_EVENT_PRIMITIVE_CHANGE: 8140 mptsas_smhba_log_sysevent(mpt, 8141 ESC_SAS_HBA_PORT_BROADCAST, 8142 SAS_PORT_BROADCAST_CHANGE, 8143 &mpt->m_phy_info[phy_num].smhba_info); 8144 break; 8145 case MPI2_EVENT_PRIMITIVE_SES: 8146 mptsas_smhba_log_sysevent(mpt, 8147 ESC_SAS_HBA_PORT_BROADCAST, 8148 SAS_PORT_BROADCAST_SES, 8149 &mpt->m_phy_info[phy_num].smhba_info); 8150 break; 8151 case MPI2_EVENT_PRIMITIVE_EXPANDER: 8152 mptsas_smhba_log_sysevent(mpt, 8153 ESC_SAS_HBA_PORT_BROADCAST, 8154 SAS_PORT_BROADCAST_D01_4, 8155 &mpt->m_phy_info[phy_num].smhba_info); 8156 break; 8157 case MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT: 8158 mptsas_smhba_log_sysevent(mpt, 8159 ESC_SAS_HBA_PORT_BROADCAST, 8160 SAS_PORT_BROADCAST_D04_7, 8161 &mpt->m_phy_info[phy_num].smhba_info); 8162 break; 8163 case MPI2_EVENT_PRIMITIVE_RESERVED3: 8164 mptsas_smhba_log_sysevent(mpt, 8165 ESC_SAS_HBA_PORT_BROADCAST, 8166 SAS_PORT_BROADCAST_D16_7, 8167 &mpt->m_phy_info[phy_num].smhba_info); 8168 break; 8169 case MPI2_EVENT_PRIMITIVE_RESERVED4: 8170 mptsas_smhba_log_sysevent(mpt, 8171 ESC_SAS_HBA_PORT_BROADCAST, 8172 SAS_PORT_BROADCAST_D29_7, 8173 &mpt->m_phy_info[phy_num].smhba_info); 8174 break; 8175 case MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED: 8176 mptsas_smhba_log_sysevent(mpt, 8177 ESC_SAS_HBA_PORT_BROADCAST, 8178 SAS_PORT_BROADCAST_D24_0, 8179 &mpt->m_phy_info[phy_num].smhba_info); 8180 break; 8181 case MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED: 8182 mptsas_smhba_log_sysevent(mpt, 8183 ESC_SAS_HBA_PORT_BROADCAST, 8184 SAS_PORT_BROADCAST_D27_4, 8185 &mpt->m_phy_info[phy_num].smhba_info); 8186 break; 8187 default: 8188 NDBG16(("mptsas%d: unknown BROADCAST PRIMITIVE" 8189 " %x received", 8190 mpt->m_instance, primitive)); 8191 break; 8192 } 8193 NDBG16(("mptsas%d sas broadcast primitive: " 8194 "\tprimitive(0x%04x), phy(%d) complete\n", 8195 mpt->m_instance, primitive, phy_num)); 8196 break; 8197 } 8198 case MPI2_EVENT_IR_VOLUME: 8199 { 8200 Mpi2EventDataIrVolume_t *irVolume; 8201 uint16_t devhandle; 8202 uint32_t state; 8203 int config, vol; 8204 uint8_t found = FALSE; 8205 8206 irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData; 8207 state = ddi_get32(mpt->m_acc_reply_frame_hdl, 8208 &irVolume->NewValue); 8209 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 8210 &irVolume->VolDevHandle); 8211 8212 NDBG20(("EVENT_IR_VOLUME event is received")); 8213 8214 /* 8215 * Get latest RAID info and then find the DevHandle for this 8216 * event in the configuration. If the DevHandle is not found 8217 * just exit the event. 8218 */ 8219 (void) mptsas_get_raid_info(mpt); 8220 for (config = 0; (config < mpt->m_num_raid_configs) && 8221 (!found); config++) { 8222 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) { 8223 if (mpt->m_raidconfig[config].m_raidvol[vol]. 8224 m_raidhandle == devhandle) { 8225 found = TRUE; 8226 break; 8227 } 8228 } 8229 } 8230 if (!found) { 8231 break; 8232 } 8233 8234 switch (irVolume->ReasonCode) { 8235 case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED: 8236 { 8237 uint32_t i; 8238 mpt->m_raidconfig[config].m_raidvol[vol].m_settings = 8239 state; 8240 8241 i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING; 8242 mptsas_log(mpt, CE_NOTE, " Volume %d settings changed" 8243 ", auto-config of hot-swap drives is %s" 8244 ", write caching is %s" 8245 ", hot-spare pool mask is %02x\n", 8246 vol, state & 8247 MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE 8248 ? "disabled" : "enabled", 8249 i == MPI2_RAIDVOL0_SETTING_UNCHANGED 8250 ? "controlled by member disks" : 8251 i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING 8252 ? "disabled" : 8253 i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING 8254 ? "enabled" : 8255 "incorrectly set", 8256 (state >> 16) & 0xff); 8257 break; 8258 } 8259 case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED: 8260 { 8261 mpt->m_raidconfig[config].m_raidvol[vol].m_state = 8262 (uint8_t)state; 8263 8264 mptsas_log(mpt, CE_NOTE, 8265 "Volume %d is now %s\n", vol, 8266 state == MPI2_RAID_VOL_STATE_OPTIMAL 8267 ? "optimal" : 8268 state == MPI2_RAID_VOL_STATE_DEGRADED 8269 ? "degraded" : 8270 state == MPI2_RAID_VOL_STATE_ONLINE 8271 ? "online" : 8272 state == MPI2_RAID_VOL_STATE_INITIALIZING 8273 ? "initializing" : 8274 state == MPI2_RAID_VOL_STATE_FAILED 8275 ? "failed" : 8276 state == MPI2_RAID_VOL_STATE_MISSING 8277 ? "missing" : 8278 "state unknown"); 8279 break; 8280 } 8281 case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED: 8282 { 8283 mpt->m_raidconfig[config].m_raidvol[vol]. 8284 m_statusflags = state; 8285 8286 mptsas_log(mpt, CE_NOTE, 8287 " Volume %d is now %s%s%s%s%s%s%s%s%s\n", 8288 vol, 8289 state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED 8290 ? ", enabled" : ", disabled", 8291 state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED 8292 ? ", quiesced" : "", 8293 state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE 8294 ? ", inactive" : ", active", 8295 state & 8296 MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL 8297 ? ", bad block table is full" : "", 8298 state & 8299 MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS 8300 ? ", resync in progress" : "", 8301 state & MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT 8302 ? ", background initialization in progress" : "", 8303 state & 8304 MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION 8305 ? ", capacity expansion in progress" : "", 8306 state & 8307 MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK 8308 ? ", consistency check in progress" : "", 8309 state & MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB 8310 ? ", data scrub in progress" : ""); 8311 break; 8312 } 8313 default: 8314 break; 8315 } 8316 break; 8317 } 8318 case MPI2_EVENT_IR_PHYSICAL_DISK: 8319 { 8320 Mpi2EventDataIrPhysicalDisk_t *irPhysDisk; 8321 uint16_t devhandle, enchandle, slot; 8322 uint32_t status, state; 8323 uint8_t physdisknum, reason; 8324 8325 irPhysDisk = (Mpi2EventDataIrPhysicalDisk_t *) 8326 eventreply->EventData; 8327 physdisknum = ddi_get8(mpt->m_acc_reply_frame_hdl, 8328 &irPhysDisk->PhysDiskNum); 8329 devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 8330 &irPhysDisk->PhysDiskDevHandle); 8331 enchandle = ddi_get16(mpt->m_acc_reply_frame_hdl, 8332 &irPhysDisk->EnclosureHandle); 8333 slot = ddi_get16(mpt->m_acc_reply_frame_hdl, 8334 &irPhysDisk->Slot); 8335 state = ddi_get32(mpt->m_acc_reply_frame_hdl, 8336 &irPhysDisk->NewValue); 8337 reason = ddi_get8(mpt->m_acc_reply_frame_hdl, 8338 &irPhysDisk->ReasonCode); 8339 8340 NDBG20(("EVENT_IR_PHYSICAL_DISK event is received")); 8341 8342 switch (reason) { 8343 case MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED: 8344 mptsas_log(mpt, CE_NOTE, 8345 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 8346 "for enclosure with handle 0x%x is now in hot " 8347 "spare pool %d", 8348 physdisknum, devhandle, slot, enchandle, 8349 (state >> 16) & 0xff); 8350 break; 8351 8352 case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED: 8353 status = state; 8354 mptsas_log(mpt, CE_NOTE, 8355 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 8356 "for enclosure with handle 0x%x is now " 8357 "%s%s%s%s%s\n", physdisknum, devhandle, slot, 8358 enchandle, 8359 status & MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME 8360 ? ", inactive" : ", active", 8361 status & MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC 8362 ? ", out of sync" : "", 8363 status & MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED 8364 ? ", quiesced" : "", 8365 status & 8366 MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED 8367 ? ", write cache enabled" : "", 8368 status & MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET 8369 ? ", capacity expansion target" : ""); 8370 break; 8371 8372 case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED: 8373 mptsas_log(mpt, CE_NOTE, 8374 " PhysDiskNum %d with DevHandle 0x%x in slot %d " 8375 "for enclosure with handle 0x%x is now %s\n", 8376 physdisknum, devhandle, slot, enchandle, 8377 state == MPI2_RAID_PD_STATE_OPTIMAL 8378 ? "optimal" : 8379 state == MPI2_RAID_PD_STATE_REBUILDING 8380 ? "rebuilding" : 8381 state == MPI2_RAID_PD_STATE_DEGRADED 8382 ? "degraded" : 8383 state == MPI2_RAID_PD_STATE_HOT_SPARE 8384 ? "a hot spare" : 8385 state == MPI2_RAID_PD_STATE_ONLINE 8386 ? "online" : 8387 state == MPI2_RAID_PD_STATE_OFFLINE 8388 ? "offline" : 8389 state == MPI2_RAID_PD_STATE_NOT_COMPATIBLE 8390 ? "not compatible" : 8391 state == MPI2_RAID_PD_STATE_NOT_CONFIGURED 8392 ? "not configured" : 8393 "state unknown"); 8394 break; 8395 } 8396 break; 8397 } 8398 case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION: 8399 { 8400 pMpi26EventDataActiveCableExcept_t actcable; 8401 uint32_t power; 8402 uint8_t reason, id; 8403 8404 actcable = (pMpi26EventDataActiveCableExcept_t) 8405 eventreply->EventData; 8406 power = ddi_get32(mpt->m_acc_reply_frame_hdl, 8407 &actcable->ActiveCablePowerRequirement); 8408 reason = ddi_get8(mpt->m_acc_reply_frame_hdl, 8409 &actcable->ReasonCode); 8410 id = ddi_get8(mpt->m_acc_reply_frame_hdl, 8411 &actcable->ReceptacleID); 8412 8413 /* 8414 * It'd be nice if this weren't just logging to the system but 8415 * were telling FMA about the active cable problem and FMA was 8416 * aware of the cable topology and state. 8417 */ 8418 switch (reason) { 8419 case MPI26_EVENT_ACTIVE_CABLE_PRESENT: 8420 /* Don't log anything if it's fine */ 8421 break; 8422 case MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER: 8423 mptsas_log(mpt, CE_WARN, "An active cable (id %u) does " 8424 "not have sufficient power to be enabled. " 8425 "Devices connected to this cable will not be " 8426 "visible to the system.", id); 8427 if (power == UINT32_MAX) { 8428 mptsas_log(mpt, CE_CONT, "The cable's power " 8429 "requirements are unknown.\n"); 8430 } else { 8431 mptsas_log(mpt, CE_CONT, "The cable requires " 8432 "%u mW of power to function.\n", power); 8433 } 8434 break; 8435 case MPI26_EVENT_ACTIVE_CABLE_DEGRADED: 8436 mptsas_log(mpt, CE_WARN, "An active cable (id %u) is " 8437 "degraded and not running at its full speed. " 8438 "Some devices might not appear.", id); 8439 break; 8440 default: 8441 break; 8442 } 8443 break; 8444 } 8445 case MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE: 8446 case MPI2_EVENT_PCIE_ENUMERATION: 8447 case MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST: 8448 case MPI2_EVENT_PCIE_LINK_COUNTER: 8449 mptsas_log(mpt, CE_NOTE, "Unhandled mpt_sas PCIe device " 8450 "event received (0x%x)", event); 8451 break; 8452 default: 8453 NDBG20(("mptsas%d: unknown event %x received", 8454 mpt->m_instance, event)); 8455 break; 8456 } 8457 8458 /* 8459 * Return the reply frame to the free queue. 8460 */ 8461 ddi_put32(mpt->m_acc_free_queue_hdl, 8462 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], rfm); 8463 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 8464 DDI_DMA_SYNC_FORDEV); 8465 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 8466 mpt->m_free_index = 0; 8467 } 8468 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 8469 mpt->m_free_index); 8470 mutex_exit(&mpt->m_mutex); 8471 } 8472 8473 /* 8474 * invoked from timeout() to restart qfull cmds with throttle == 0 8475 */ 8476 static void 8477 mptsas_restart_cmd(void *arg) 8478 { 8479 mptsas_t *mpt = arg; 8480 mptsas_target_t *ptgt = NULL; 8481 8482 mutex_enter(&mpt->m_mutex); 8483 8484 mpt->m_restart_cmd_timeid = 0; 8485 8486 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 8487 ptgt = refhash_next(mpt->m_targets, ptgt)) { 8488 if (ptgt->m_reset_delay == 0) { 8489 if (ptgt->m_t_throttle == QFULL_THROTTLE) { 8490 mptsas_set_throttle(mpt, ptgt, 8491 MAX_THROTTLE); 8492 } 8493 } 8494 } 8495 mptsas_restart_hba(mpt); 8496 mutex_exit(&mpt->m_mutex); 8497 } 8498 8499 void 8500 mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 8501 { 8502 int slot; 8503 mptsas_slots_t *slots = mpt->m_active; 8504 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8505 8506 ASSERT(cmd != NULL); 8507 ASSERT(cmd->cmd_queued == FALSE); 8508 8509 /* 8510 * Task Management cmds are removed in their own routines. Also, 8511 * we don't want to modify timeout based on TM cmds. 8512 */ 8513 if (cmd->cmd_flags & CFLAG_TM_CMD) { 8514 return; 8515 } 8516 8517 slot = cmd->cmd_slot; 8518 8519 /* 8520 * remove the cmd. 8521 */ 8522 if (cmd == slots->m_slot[slot]) { 8523 NDBG31(("mptsas_remove_cmd: removing cmd=0x%p, flags " 8524 "0x%x", (void *)cmd, cmd->cmd_flags)); 8525 slots->m_slot[slot] = NULL; 8526 mpt->m_ncmds--; 8527 8528 /* 8529 * only decrement per target ncmds if command 8530 * has a target associated with it. 8531 */ 8532 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 8533 ptgt->m_t_ncmds--; 8534 /* 8535 * reset throttle if we just ran an untagged command 8536 * to a tagged target 8537 */ 8538 if ((ptgt->m_t_ncmds == 0) && 8539 ((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0)) { 8540 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 8541 } 8542 8543 /* 8544 * Remove this command from the active queue. 8545 */ 8546 if (cmd->cmd_active_expiration != 0) { 8547 TAILQ_REMOVE(&ptgt->m_active_cmdq, cmd, 8548 cmd_active_link); 8549 cmd->cmd_active_expiration = 0; 8550 } 8551 } 8552 } 8553 8554 /* 8555 * This is all we need to do for ioc commands. 8556 */ 8557 if (cmd->cmd_flags & CFLAG_CMDIOC) { 8558 mptsas_return_to_pool(mpt, cmd); 8559 return; 8560 } 8561 8562 ASSERT(cmd != slots->m_slot[cmd->cmd_slot]); 8563 } 8564 8565 /* 8566 * accept all cmds on the tx_waitq if any and then 8567 * start a fresh request from the top of the device queue. 8568 * 8569 * since there are always cmds queued on the tx_waitq, and rare cmds on 8570 * the instance waitq, so this function should not be invoked in the ISR, 8571 * the mptsas_restart_waitq() is invoked in the ISR instead. otherwise, the 8572 * burden belongs to the IO dispatch CPUs is moved the interrupt CPU. 8573 */ 8574 static void 8575 mptsas_restart_hba(mptsas_t *mpt) 8576 { 8577 ASSERT(mutex_owned(&mpt->m_mutex)); 8578 8579 mutex_enter(&mpt->m_tx_waitq_mutex); 8580 if (mpt->m_tx_waitq) { 8581 mptsas_accept_tx_waitq(mpt); 8582 } 8583 mutex_exit(&mpt->m_tx_waitq_mutex); 8584 mptsas_restart_waitq(mpt); 8585 } 8586 8587 /* 8588 * start a fresh request from the top of the device queue 8589 */ 8590 static void 8591 mptsas_restart_waitq(mptsas_t *mpt) 8592 { 8593 mptsas_cmd_t *cmd, *next_cmd; 8594 mptsas_target_t *ptgt = NULL; 8595 8596 NDBG1(("mptsas_restart_waitq: mpt=0x%p", (void *)mpt)); 8597 8598 ASSERT(mutex_owned(&mpt->m_mutex)); 8599 8600 /* 8601 * If there is a reset delay, don't start any cmds. Otherwise, start 8602 * as many cmds as possible. 8603 * Since SMID 0 is reserved and the TM slot is reserved, the actual max 8604 * commands is m_max_requests - 2. 8605 */ 8606 cmd = mpt->m_waitq; 8607 8608 while (cmd != NULL) { 8609 next_cmd = cmd->cmd_linkp; 8610 if (cmd->cmd_flags & CFLAG_PASSTHRU) { 8611 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 8612 /* 8613 * passthru command get slot need 8614 * set CFLAG_PREPARED. 8615 */ 8616 cmd->cmd_flags |= CFLAG_PREPARED; 8617 mptsas_waitq_delete(mpt, cmd); 8618 mptsas_start_passthru(mpt, cmd); 8619 } 8620 cmd = next_cmd; 8621 continue; 8622 } 8623 if (cmd->cmd_flags & CFLAG_CONFIG) { 8624 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 8625 /* 8626 * Send the config page request and delete it 8627 * from the waitq. 8628 */ 8629 cmd->cmd_flags |= CFLAG_PREPARED; 8630 mptsas_waitq_delete(mpt, cmd); 8631 mptsas_start_config_page_access(mpt, cmd); 8632 } 8633 cmd = next_cmd; 8634 continue; 8635 } 8636 if (cmd->cmd_flags & CFLAG_FW_DIAG) { 8637 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 8638 /* 8639 * Send the FW Diag request and delete if from 8640 * the waitq. 8641 */ 8642 cmd->cmd_flags |= CFLAG_PREPARED; 8643 mptsas_waitq_delete(mpt, cmd); 8644 mptsas_start_diag(mpt, cmd); 8645 } 8646 cmd = next_cmd; 8647 continue; 8648 } 8649 8650 ptgt = cmd->cmd_tgt_addr; 8651 if (ptgt && (ptgt->m_t_throttle == DRAIN_THROTTLE) && 8652 (ptgt->m_t_ncmds == 0)) { 8653 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 8654 } 8655 if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) && 8656 (ptgt && (ptgt->m_reset_delay == 0)) && 8657 (ptgt && (ptgt->m_t_ncmds < 8658 ptgt->m_t_throttle))) { 8659 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 8660 mptsas_waitq_delete(mpt, cmd); 8661 (void) mptsas_start_cmd(mpt, cmd); 8662 } 8663 } 8664 cmd = next_cmd; 8665 } 8666 } 8667 /* 8668 * Cmds are queued if tran_start() doesn't get the m_mutexlock(no wait). 8669 * Accept all those queued cmds before new cmd is accept so that the 8670 * cmds are sent in order. 8671 */ 8672 static void 8673 mptsas_accept_tx_waitq(mptsas_t *mpt) 8674 { 8675 mptsas_cmd_t *cmd; 8676 8677 ASSERT(mutex_owned(&mpt->m_mutex)); 8678 ASSERT(mutex_owned(&mpt->m_tx_waitq_mutex)); 8679 8680 /* 8681 * A Bus Reset could occur at any time and flush the tx_waitq, 8682 * so we cannot count on the tx_waitq to contain even one cmd. 8683 * And when the m_tx_waitq_mutex is released and run 8684 * mptsas_accept_pkt(), the tx_waitq may be flushed. 8685 */ 8686 cmd = mpt->m_tx_waitq; 8687 for (;;) { 8688 if ((cmd = mpt->m_tx_waitq) == NULL) { 8689 mpt->m_tx_draining = 0; 8690 break; 8691 } 8692 if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) { 8693 mpt->m_tx_waitqtail = &mpt->m_tx_waitq; 8694 } 8695 cmd->cmd_linkp = NULL; 8696 mutex_exit(&mpt->m_tx_waitq_mutex); 8697 if (mptsas_accept_pkt(mpt, cmd) != TRAN_ACCEPT) 8698 cmn_err(CE_WARN, "mpt: mptsas_accept_tx_waitq: failed " 8699 "to accept cmd on queue\n"); 8700 mutex_enter(&mpt->m_tx_waitq_mutex); 8701 } 8702 } 8703 8704 8705 /* 8706 * mpt tag type lookup 8707 */ 8708 static char mptsas_tag_lookup[] = 8709 {0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG}; 8710 8711 static int 8712 mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 8713 { 8714 struct scsi_pkt *pkt = CMD2PKT(cmd); 8715 uint32_t control = 0; 8716 caddr_t mem, arsbuf; 8717 pMpi2SCSIIORequest_t io_request; 8718 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; 8719 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl; 8720 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 8721 uint16_t SMID, io_flags = 0; 8722 uint8_t ars_size; 8723 uint64_t request_desc; 8724 uint32_t ars_dmaaddrlow; 8725 mptsas_cmd_t *c; 8726 8727 NDBG1(("mptsas_start_cmd: cmd=0x%p, flags 0x%x", (void *)cmd, 8728 cmd->cmd_flags)); 8729 8730 /* 8731 * Set SMID and increment index. Rollover to 1 instead of 0 if index 8732 * is at the max. 0 is an invalid SMID, so we call the first index 1. 8733 */ 8734 SMID = cmd->cmd_slot; 8735 8736 /* 8737 * It is possible for back to back device reset to 8738 * happen before the reset delay has expired. That's 8739 * ok, just let the device reset go out on the bus. 8740 */ 8741 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 8742 ASSERT(ptgt->m_reset_delay == 0); 8743 } 8744 8745 /* 8746 * if a non-tagged cmd is submitted to an active tagged target 8747 * then drain before submitting this cmd; SCSI-2 allows RQSENSE 8748 * to be untagged 8749 */ 8750 if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) && 8751 (ptgt->m_t_ncmds > 1) && 8752 ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) && 8753 (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) { 8754 if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) { 8755 NDBG23(("target=%d, untagged cmd, start draining\n", 8756 ptgt->m_devhdl)); 8757 8758 if (ptgt->m_reset_delay == 0) { 8759 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 8760 } 8761 8762 mptsas_remove_cmd(mpt, cmd); 8763 cmd->cmd_pkt_flags |= FLAG_HEAD; 8764 mptsas_waitq_add(mpt, cmd); 8765 } 8766 return (DDI_FAILURE); 8767 } 8768 8769 /* 8770 * Set correct tag bits. 8771 */ 8772 if (cmd->cmd_pkt_flags & FLAG_TAGMASK) { 8773 switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags & 8774 FLAG_TAGMASK) >> 12)]) { 8775 case MSG_SIMPLE_QTAG: 8776 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 8777 break; 8778 case MSG_HEAD_QTAG: 8779 control |= MPI2_SCSIIO_CONTROL_HEADOFQ; 8780 break; 8781 case MSG_ORDERED_QTAG: 8782 control |= MPI2_SCSIIO_CONTROL_ORDEREDQ; 8783 break; 8784 default: 8785 mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n"); 8786 break; 8787 } 8788 } else { 8789 if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) { 8790 ptgt->m_t_throttle = 1; 8791 } 8792 control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; 8793 } 8794 8795 if (cmd->cmd_pkt_flags & FLAG_TLR) { 8796 control |= MPI2_SCSIIO_CONTROL_TLR_ON; 8797 } 8798 8799 mem = mpt->m_req_frame + (mpt->m_req_frame_size * SMID); 8800 io_request = (pMpi2SCSIIORequest_t)mem; 8801 if (cmd->cmd_extrqslen != 0) { 8802 /* 8803 * Mapping of the buffer was done in mptsas_pkt_alloc_extern(). 8804 * Calculate the DMA address with the same offset. 8805 */ 8806 arsbuf = cmd->cmd_arq_buf; 8807 ars_size = cmd->cmd_extrqslen; 8808 ars_dmaaddrlow = (mpt->m_req_sense_dma_addr + 8809 ((uintptr_t)arsbuf - (uintptr_t)mpt->m_req_sense)) & 8810 0xffffffffu; 8811 } else { 8812 arsbuf = mpt->m_req_sense + (mpt->m_req_sense_size * (SMID-1)); 8813 cmd->cmd_arq_buf = arsbuf; 8814 ars_size = mpt->m_req_sense_size; 8815 ars_dmaaddrlow = (mpt->m_req_sense_dma_addr + 8816 (mpt->m_req_sense_size * (SMID-1))) & 8817 0xffffffffu; 8818 } 8819 bzero(io_request, sizeof (Mpi2SCSIIORequest_t)); 8820 bzero(arsbuf, ars_size); 8821 8822 ddi_put8(acc_hdl, &io_request->SGLOffset0, offsetof 8823 (MPI2_SCSI_IO_REQUEST, SGL) / 4); 8824 mptsas_init_std_hdr(acc_hdl, io_request, ptgt->m_devhdl, Lun(cmd), 0, 8825 MPI2_FUNCTION_SCSI_IO_REQUEST); 8826 8827 (void) ddi_rep_put8(acc_hdl, (uint8_t *)pkt->pkt_cdbp, 8828 io_request->CDB.CDB32, cmd->cmd_cdblen, DDI_DEV_AUTOINCR); 8829 8830 io_flags = cmd->cmd_cdblen; 8831 if (mptsas_use_fastpath && 8832 ptgt->m_io_flags & MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) { 8833 io_flags |= MPI25_SCSIIO_IOFLAGS_FAST_PATH; 8834 request_desc = MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO; 8835 } else { 8836 request_desc = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 8837 } 8838 ddi_put16(acc_hdl, &io_request->IoFlags, io_flags); 8839 /* 8840 * setup the Scatter/Gather DMA list for this request 8841 */ 8842 if (cmd->cmd_cookiec > 0) { 8843 mptsas_sge_setup(mpt, cmd, &control, io_request, acc_hdl); 8844 } else { 8845 ddi_put32(acc_hdl, &io_request->SGL.MpiSimple.FlagsLength, 8846 ((uint32_t)MPI2_SGE_FLAGS_LAST_ELEMENT | 8847 MPI2_SGE_FLAGS_END_OF_BUFFER | 8848 MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 8849 MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); 8850 } 8851 8852 /* 8853 * save ARQ information 8854 */ 8855 ddi_put8(acc_hdl, &io_request->SenseBufferLength, ars_size); 8856 ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress, ars_dmaaddrlow); 8857 8858 ddi_put32(acc_hdl, &io_request->Control, control); 8859 8860 NDBG31(("starting message=%d(0x%p), with cmd=0x%p", 8861 SMID, (void *)io_request, (void *)cmd)); 8862 8863 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 8864 (void) ddi_dma_sync(mpt->m_dma_req_sense_hdl, 0, 0, 8865 DDI_DMA_SYNC_FORDEV); 8866 8867 /* 8868 * Build request descriptor and write it to the request desc post reg. 8869 */ 8870 request_desc |= (SMID << 16); 8871 request_desc |= (uint64_t)ptgt->m_devhdl << 48; 8872 MPTSAS_START_CMD(mpt, request_desc); 8873 8874 /* 8875 * Start timeout. 8876 */ 8877 cmd->cmd_active_expiration = 8878 gethrtime() + (hrtime_t)pkt->pkt_time * NANOSEC; 8879 #ifdef MPTSAS_TEST 8880 /* 8881 * Force timeouts to happen immediately. 8882 */ 8883 if (mptsas_test_timeouts) 8884 cmd->cmd_active_expiration = gethrtime(); 8885 #endif 8886 c = TAILQ_FIRST(&ptgt->m_active_cmdq); 8887 if (c == NULL || 8888 c->cmd_active_expiration < cmd->cmd_active_expiration) { 8889 /* 8890 * Common case is that this is the last pending expiration 8891 * (or queue is empty). Insert at head of the queue. 8892 */ 8893 TAILQ_INSERT_HEAD(&ptgt->m_active_cmdq, cmd, cmd_active_link); 8894 } else { 8895 /* 8896 * Queue is not empty and first element expires later than 8897 * this command. Search for element expiring sooner. 8898 */ 8899 while ((c = TAILQ_NEXT(c, cmd_active_link)) != NULL) { 8900 if (c->cmd_active_expiration < 8901 cmd->cmd_active_expiration) { 8902 TAILQ_INSERT_BEFORE(c, cmd, cmd_active_link); 8903 break; 8904 } 8905 } 8906 if (c == NULL) { 8907 /* 8908 * No element found expiring sooner, append to 8909 * non-empty queue. 8910 */ 8911 TAILQ_INSERT_TAIL(&ptgt->m_active_cmdq, cmd, 8912 cmd_active_link); 8913 } 8914 } 8915 8916 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || 8917 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { 8918 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 8919 return (DDI_FAILURE); 8920 } 8921 return (DDI_SUCCESS); 8922 } 8923 8924 /* 8925 * Select a helper thread to handle current doneq 8926 */ 8927 static void 8928 mptsas_deliver_doneq_thread(mptsas_t *mpt) 8929 { 8930 uint64_t t, i; 8931 uint32_t min = 0xffffffff; 8932 mptsas_doneq_thread_list_t *item; 8933 8934 for (i = 0; i < mpt->m_doneq_thread_n; i++) { 8935 item = &mpt->m_doneq_thread_id[i]; 8936 /* 8937 * If the completed command on help thread[i] less than 8938 * doneq_thread_threshold, then pick the thread[i]. Otherwise 8939 * pick a thread which has least completed command. 8940 */ 8941 8942 mutex_enter(&item->mutex); 8943 if (item->len < mpt->m_doneq_thread_threshold) { 8944 t = i; 8945 mutex_exit(&item->mutex); 8946 break; 8947 } 8948 if (item->len < min) { 8949 min = item->len; 8950 t = i; 8951 } 8952 mutex_exit(&item->mutex); 8953 } 8954 mutex_enter(&mpt->m_doneq_thread_id[t].mutex); 8955 mptsas_doneq_mv(mpt, t); 8956 cv_signal(&mpt->m_doneq_thread_id[t].cv); 8957 mutex_exit(&mpt->m_doneq_thread_id[t].mutex); 8958 } 8959 8960 /* 8961 * move the current global doneq to the doneq of thead[t] 8962 */ 8963 static void 8964 mptsas_doneq_mv(mptsas_t *mpt, uint64_t t) 8965 { 8966 mptsas_cmd_t *cmd; 8967 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 8968 8969 ASSERT(mutex_owned(&item->mutex)); 8970 while ((cmd = mpt->m_doneq) != NULL) { 8971 if ((mpt->m_doneq = cmd->cmd_linkp) == NULL) { 8972 mpt->m_donetail = &mpt->m_doneq; 8973 } 8974 cmd->cmd_linkp = NULL; 8975 *item->donetail = cmd; 8976 item->donetail = &cmd->cmd_linkp; 8977 mpt->m_doneq_len--; 8978 item->len++; 8979 } 8980 } 8981 8982 void 8983 mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd) 8984 { 8985 struct scsi_pkt *pkt = CMD2PKT(cmd); 8986 8987 /* Check all acc and dma handles */ 8988 if ((mptsas_check_acc_handle(mpt->m_datap) != 8989 DDI_SUCCESS) || 8990 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 8991 DDI_SUCCESS) || 8992 (mptsas_check_acc_handle(mpt->m_acc_req_sense_hdl) != 8993 DDI_SUCCESS) || 8994 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) != 8995 DDI_SUCCESS) || 8996 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) != 8997 DDI_SUCCESS) || 8998 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) != 8999 DDI_SUCCESS) || 9000 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) != 9001 DDI_SUCCESS) || 9002 (mptsas_check_acc_handle(mpt->m_config_handle) != 9003 DDI_SUCCESS)) { 9004 ddi_fm_service_impact(mpt->m_dip, 9005 DDI_SERVICE_UNAFFECTED); 9006 ddi_fm_acc_err_clear(mpt->m_config_handle, 9007 DDI_FME_VER0); 9008 pkt->pkt_reason = CMD_TRAN_ERR; 9009 pkt->pkt_statistics = 0; 9010 } 9011 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 9012 DDI_SUCCESS) || 9013 (mptsas_check_dma_handle(mpt->m_dma_req_sense_hdl) != 9014 DDI_SUCCESS) || 9015 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) != 9016 DDI_SUCCESS) || 9017 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) != 9018 DDI_SUCCESS) || 9019 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) != 9020 DDI_SUCCESS) || 9021 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) != 9022 DDI_SUCCESS)) { 9023 ddi_fm_service_impact(mpt->m_dip, 9024 DDI_SERVICE_UNAFFECTED); 9025 pkt->pkt_reason = CMD_TRAN_ERR; 9026 pkt->pkt_statistics = 0; 9027 } 9028 if (cmd->cmd_dmahandle && 9029 (mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS)) { 9030 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 9031 pkt->pkt_reason = CMD_TRAN_ERR; 9032 pkt->pkt_statistics = 0; 9033 } 9034 if ((cmd->cmd_extra_frames && 9035 ((mptsas_check_dma_handle(cmd->cmd_extra_frames->m_dma_hdl) != 9036 DDI_SUCCESS) || 9037 (mptsas_check_acc_handle(cmd->cmd_extra_frames->m_acc_hdl) != 9038 DDI_SUCCESS)))) { 9039 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 9040 pkt->pkt_reason = CMD_TRAN_ERR; 9041 pkt->pkt_statistics = 0; 9042 } 9043 } 9044 9045 /* 9046 * These routines manipulate the queue of commands that 9047 * are waiting for their completion routines to be called. 9048 * The queue is usually in FIFO order but on an MP system 9049 * it's possible for the completion routines to get out 9050 * of order. If that's a problem you need to add a global 9051 * mutex around the code that calls the completion routine 9052 * in the interrupt handler. 9053 */ 9054 static void 9055 mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd) 9056 { 9057 struct scsi_pkt *pkt = CMD2PKT(cmd); 9058 9059 NDBG31(("mptsas_doneq_add: cmd=0x%p", (void *)cmd)); 9060 9061 ASSERT((cmd->cmd_flags & CFLAG_COMPLETED) == 0); 9062 cmd->cmd_linkp = NULL; 9063 cmd->cmd_flags |= CFLAG_FINISHED; 9064 cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT; 9065 9066 mptsas_fma_check(mpt, cmd); 9067 9068 /* 9069 * only add scsi pkts that have completion routines to 9070 * the doneq. no intr cmds do not have callbacks. 9071 */ 9072 if (pkt && (pkt->pkt_comp)) { 9073 *mpt->m_donetail = cmd; 9074 mpt->m_donetail = &cmd->cmd_linkp; 9075 mpt->m_doneq_len++; 9076 } 9077 } 9078 9079 static mptsas_cmd_t * 9080 mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t) 9081 { 9082 mptsas_cmd_t *cmd; 9083 mptsas_doneq_thread_list_t *item = &mpt->m_doneq_thread_id[t]; 9084 9085 /* pop one off the done queue */ 9086 if ((cmd = item->doneq) != NULL) { 9087 /* if the queue is now empty fix the tail pointer */ 9088 NDBG31(("mptsas_doneq_thread_rm: cmd=0x%p", (void *)cmd)); 9089 if ((item->doneq = cmd->cmd_linkp) == NULL) { 9090 item->donetail = &item->doneq; 9091 } 9092 cmd->cmd_linkp = NULL; 9093 item->len--; 9094 } 9095 return (cmd); 9096 } 9097 9098 static void 9099 mptsas_doneq_empty(mptsas_t *mpt) 9100 { 9101 if (mpt->m_doneq && !mpt->m_in_callback) { 9102 mptsas_cmd_t *cmd, *next; 9103 struct scsi_pkt *pkt; 9104 9105 mpt->m_in_callback = 1; 9106 cmd = mpt->m_doneq; 9107 mpt->m_doneq = NULL; 9108 mpt->m_donetail = &mpt->m_doneq; 9109 mpt->m_doneq_len = 0; 9110 9111 mutex_exit(&mpt->m_mutex); 9112 /* 9113 * run the completion routines of all the 9114 * completed commands 9115 */ 9116 while (cmd != NULL) { 9117 next = cmd->cmd_linkp; 9118 cmd->cmd_linkp = NULL; 9119 /* run this command's completion routine */ 9120 cmd->cmd_flags |= CFLAG_COMPLETED; 9121 pkt = CMD2PKT(cmd); 9122 mptsas_pkt_comp(pkt, cmd); 9123 cmd = next; 9124 } 9125 mutex_enter(&mpt->m_mutex); 9126 mpt->m_in_callback = 0; 9127 } 9128 } 9129 9130 /* 9131 * These routines manipulate the target's queue of pending requests 9132 */ 9133 void 9134 mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd) 9135 { 9136 NDBG7(("mptsas_waitq_add: cmd=0x%p", (void *)cmd)); 9137 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 9138 cmd->cmd_queued = TRUE; 9139 if (ptgt) 9140 ptgt->m_t_nwait++; 9141 if (cmd->cmd_pkt_flags & FLAG_HEAD) { 9142 if ((cmd->cmd_linkp = mpt->m_waitq) == NULL) { 9143 mpt->m_waitqtail = &cmd->cmd_linkp; 9144 } 9145 mpt->m_waitq = cmd; 9146 } else { 9147 cmd->cmd_linkp = NULL; 9148 *(mpt->m_waitqtail) = cmd; 9149 mpt->m_waitqtail = &cmd->cmd_linkp; 9150 } 9151 } 9152 9153 static mptsas_cmd_t * 9154 mptsas_waitq_rm(mptsas_t *mpt) 9155 { 9156 mptsas_cmd_t *cmd; 9157 mptsas_target_t *ptgt; 9158 NDBG7(("mptsas_waitq_rm")); 9159 9160 MPTSAS_WAITQ_RM(mpt, cmd); 9161 9162 NDBG7(("mptsas_waitq_rm: cmd=0x%p", (void *)cmd)); 9163 if (cmd) { 9164 ptgt = cmd->cmd_tgt_addr; 9165 if (ptgt) { 9166 ptgt->m_t_nwait--; 9167 ASSERT(ptgt->m_t_nwait >= 0); 9168 } 9169 } 9170 return (cmd); 9171 } 9172 9173 /* 9174 * remove specified cmd from the middle of the wait queue. 9175 */ 9176 static void 9177 mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd) 9178 { 9179 mptsas_cmd_t *prevp = mpt->m_waitq; 9180 mptsas_target_t *ptgt = cmd->cmd_tgt_addr; 9181 9182 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 9183 (void *)mpt, (void *)cmd)); 9184 if (ptgt) { 9185 ptgt->m_t_nwait--; 9186 ASSERT(ptgt->m_t_nwait >= 0); 9187 } 9188 9189 if (prevp == cmd) { 9190 if ((mpt->m_waitq = cmd->cmd_linkp) == NULL) 9191 mpt->m_waitqtail = &mpt->m_waitq; 9192 9193 cmd->cmd_linkp = NULL; 9194 cmd->cmd_queued = FALSE; 9195 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 9196 (void *)mpt, (void *)cmd)); 9197 return; 9198 } 9199 9200 while (prevp != NULL) { 9201 if (prevp->cmd_linkp == cmd) { 9202 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL) 9203 mpt->m_waitqtail = &prevp->cmd_linkp; 9204 9205 cmd->cmd_linkp = NULL; 9206 cmd->cmd_queued = FALSE; 9207 NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p", 9208 (void *)mpt, (void *)cmd)); 9209 return; 9210 } 9211 prevp = prevp->cmd_linkp; 9212 } 9213 cmn_err(CE_PANIC, "mpt: mptsas_waitq_delete: queue botch"); 9214 } 9215 9216 static mptsas_cmd_t * 9217 mptsas_tx_waitq_rm(mptsas_t *mpt) 9218 { 9219 mptsas_cmd_t *cmd; 9220 NDBG7(("mptsas_tx_waitq_rm")); 9221 9222 MPTSAS_TX_WAITQ_RM(mpt, cmd); 9223 9224 NDBG7(("mptsas_tx_waitq_rm: cmd=0x%p", (void *)cmd)); 9225 9226 return (cmd); 9227 } 9228 9229 /* 9230 * remove specified cmd from the middle of the tx_waitq. 9231 */ 9232 static void 9233 mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd) 9234 { 9235 mptsas_cmd_t *prevp = mpt->m_tx_waitq; 9236 9237 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p", 9238 (void *)mpt, (void *)cmd)); 9239 9240 if (prevp == cmd) { 9241 if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) 9242 mpt->m_tx_waitqtail = &mpt->m_tx_waitq; 9243 9244 cmd->cmd_linkp = NULL; 9245 cmd->cmd_queued = FALSE; 9246 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p", 9247 (void *)mpt, (void *)cmd)); 9248 return; 9249 } 9250 9251 while (prevp != NULL) { 9252 if (prevp->cmd_linkp == cmd) { 9253 if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL) 9254 mpt->m_tx_waitqtail = &prevp->cmd_linkp; 9255 9256 cmd->cmd_linkp = NULL; 9257 cmd->cmd_queued = FALSE; 9258 NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p", 9259 (void *)mpt, (void *)cmd)); 9260 return; 9261 } 9262 prevp = prevp->cmd_linkp; 9263 } 9264 cmn_err(CE_PANIC, "mpt: mptsas_tx_waitq_delete: queue botch"); 9265 } 9266 9267 /* 9268 * device and bus reset handling 9269 * 9270 * Notes: 9271 * - RESET_ALL: reset the controller 9272 * - RESET_TARGET: reset the target specified in scsi_address 9273 */ 9274 static int 9275 mptsas_scsi_reset(struct scsi_address *ap, int level) 9276 { 9277 mptsas_t *mpt = ADDR2MPT(ap); 9278 int rval; 9279 mptsas_tgt_private_t *tgt_private; 9280 mptsas_target_t *ptgt = NULL; 9281 9282 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->tran_tgt_private; 9283 ptgt = tgt_private->t_private; 9284 if (ptgt == NULL) { 9285 return (FALSE); 9286 } 9287 NDBG22(("mptsas_scsi_reset: target=%d level=%d", ptgt->m_devhdl, 9288 level)); 9289 9290 mutex_enter(&mpt->m_mutex); 9291 /* 9292 * if we are not in panic set up a reset delay for this target 9293 */ 9294 if (!ddi_in_panic()) { 9295 mptsas_setup_bus_reset_delay(mpt); 9296 } else { 9297 drv_usecwait(mpt->m_scsi_reset_delay * 1000); 9298 } 9299 rval = mptsas_do_scsi_reset(mpt, ptgt->m_devhdl); 9300 mutex_exit(&mpt->m_mutex); 9301 9302 /* 9303 * The transport layer expect to only see TRUE and 9304 * FALSE. Therefore, we will adjust the return value 9305 * if mptsas_do_scsi_reset returns FAILED. 9306 */ 9307 if (rval == FAILED) 9308 rval = FALSE; 9309 return (rval); 9310 } 9311 9312 static int 9313 mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl) 9314 { 9315 int rval = FALSE; 9316 uint8_t config, disk; 9317 9318 ASSERT(mutex_owned(&mpt->m_mutex)); 9319 9320 if (mptsas_debug_resets) { 9321 mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d", 9322 devhdl); 9323 } 9324 9325 /* 9326 * Issue a Target Reset message to the target specified but not to a 9327 * disk making up a raid volume. Just look through the RAID config 9328 * Phys Disk list of DevHandles. If the target's DevHandle is in this 9329 * list, then don't reset this target. 9330 */ 9331 for (config = 0; config < mpt->m_num_raid_configs; config++) { 9332 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) { 9333 if (devhdl == mpt->m_raidconfig[config]. 9334 m_physdisk_devhdl[disk]) { 9335 return (TRUE); 9336 } 9337 } 9338 } 9339 9340 rval = mptsas_ioc_task_management(mpt, 9341 MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, devhdl, 0, NULL, 0, 0); 9342 9343 mptsas_doneq_empty(mpt); 9344 return (rval); 9345 } 9346 9347 static int 9348 mptsas_scsi_reset_notify(struct scsi_address *ap, int flag, 9349 void (*callback)(caddr_t), caddr_t arg) 9350 { 9351 mptsas_t *mpt = ADDR2MPT(ap); 9352 9353 NDBG22(("mptsas_scsi_reset_notify: tgt=%d", ap->a_target)); 9354 9355 return (scsi_hba_reset_notify_setup(ap, flag, callback, arg, 9356 &mpt->m_mutex, &mpt->m_reset_notify_listf)); 9357 } 9358 9359 static int 9360 mptsas_get_name(struct scsi_device *sd, char *name, int len) 9361 { 9362 dev_info_t *lun_dip = NULL; 9363 9364 ASSERT(sd != NULL); 9365 ASSERT(name != NULL); 9366 lun_dip = sd->sd_dev; 9367 ASSERT(lun_dip != NULL); 9368 9369 if (mptsas_name_child(lun_dip, name, len) == DDI_SUCCESS) { 9370 return (1); 9371 } else { 9372 return (0); 9373 } 9374 } 9375 9376 static int 9377 mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len) 9378 { 9379 return (mptsas_get_name(sd, name, len)); 9380 } 9381 9382 void 9383 mptsas_set_throttle(mptsas_t *mpt, mptsas_target_t *ptgt, int what) 9384 { 9385 9386 NDBG25(("mptsas_set_throttle: throttle=%x", what)); 9387 9388 /* 9389 * if the bus is draining/quiesced, no changes to the throttles 9390 * are allowed. Not allowing change of throttles during draining 9391 * limits error recovery but will reduce draining time 9392 * 9393 * all throttles should have been set to HOLD_THROTTLE 9394 */ 9395 if (mpt->m_softstate & (MPTSAS_SS_QUIESCED | MPTSAS_SS_DRAINING)) { 9396 return; 9397 } 9398 9399 if (what == HOLD_THROTTLE) { 9400 ptgt->m_t_throttle = HOLD_THROTTLE; 9401 } else if (ptgt->m_reset_delay == 0) { 9402 ptgt->m_t_throttle = what; 9403 } 9404 } 9405 9406 /* 9407 * Clean up from a device reset. 9408 * For the case of target reset, this function clears the waitq of all 9409 * commands for a particular target. For the case of abort task set, this 9410 * function clears the waitq of all commonds for a particular target/lun. 9411 */ 9412 static void 9413 mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype) 9414 { 9415 mptsas_slots_t *slots = mpt->m_active; 9416 mptsas_cmd_t *cmd, *next_cmd; 9417 int slot; 9418 uchar_t reason; 9419 uint_t stat; 9420 hrtime_t timestamp; 9421 9422 NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun)); 9423 9424 timestamp = gethrtime(); 9425 9426 /* 9427 * Make sure the I/O Controller has flushed all cmds 9428 * that are associated with this target for a target reset 9429 * and target/lun for abort task set. 9430 * Account for TM requests, which use the last SMID. 9431 */ 9432 for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) { 9433 if ((cmd = slots->m_slot[slot]) == NULL) 9434 continue; 9435 reason = CMD_RESET; 9436 stat = STAT_DEV_RESET; 9437 switch (tasktype) { 9438 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 9439 if (Tgt(cmd) == target) { 9440 if (cmd->cmd_active_expiration <= timestamp) { 9441 /* 9442 * When timeout requested, propagate 9443 * proper reason and statistics to 9444 * target drivers. 9445 */ 9446 reason = CMD_TIMEOUT; 9447 stat |= STAT_TIMEOUT; 9448 } 9449 NDBG25(("mptsas_flush_target discovered non-" 9450 "NULL cmd in slot %d, tasktype 0x%x", slot, 9451 tasktype)); 9452 mptsas_dump_cmd(mpt, cmd); 9453 mptsas_remove_cmd(mpt, cmd); 9454 mptsas_set_pkt_reason(mpt, cmd, reason, stat); 9455 mptsas_doneq_add(mpt, cmd); 9456 } 9457 break; 9458 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 9459 reason = CMD_ABORTED; 9460 stat = STAT_ABORTED; 9461 /*FALLTHROUGH*/ 9462 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 9463 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 9464 9465 NDBG25(("mptsas_flush_target discovered non-" 9466 "NULL cmd in slot %d, tasktype 0x%x", slot, 9467 tasktype)); 9468 mptsas_dump_cmd(mpt, cmd); 9469 mptsas_remove_cmd(mpt, cmd); 9470 mptsas_set_pkt_reason(mpt, cmd, reason, 9471 stat); 9472 mptsas_doneq_add(mpt, cmd); 9473 } 9474 break; 9475 default: 9476 break; 9477 } 9478 } 9479 9480 /* 9481 * Flush the waitq and tx_waitq of this target's cmds 9482 */ 9483 cmd = mpt->m_waitq; 9484 9485 reason = CMD_RESET; 9486 stat = STAT_DEV_RESET; 9487 9488 switch (tasktype) { 9489 case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 9490 while (cmd != NULL) { 9491 next_cmd = cmd->cmd_linkp; 9492 if (Tgt(cmd) == target) { 9493 mptsas_waitq_delete(mpt, cmd); 9494 mptsas_set_pkt_reason(mpt, cmd, 9495 reason, stat); 9496 mptsas_doneq_add(mpt, cmd); 9497 } 9498 cmd = next_cmd; 9499 } 9500 mutex_enter(&mpt->m_tx_waitq_mutex); 9501 cmd = mpt->m_tx_waitq; 9502 while (cmd != NULL) { 9503 next_cmd = cmd->cmd_linkp; 9504 if (Tgt(cmd) == target) { 9505 mptsas_tx_waitq_delete(mpt, cmd); 9506 mutex_exit(&mpt->m_tx_waitq_mutex); 9507 mptsas_set_pkt_reason(mpt, cmd, 9508 reason, stat); 9509 mptsas_doneq_add(mpt, cmd); 9510 mutex_enter(&mpt->m_tx_waitq_mutex); 9511 } 9512 cmd = next_cmd; 9513 } 9514 mutex_exit(&mpt->m_tx_waitq_mutex); 9515 break; 9516 case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET: 9517 reason = CMD_ABORTED; 9518 stat = STAT_ABORTED; 9519 /*FALLTHROUGH*/ 9520 case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET: 9521 while (cmd != NULL) { 9522 next_cmd = cmd->cmd_linkp; 9523 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 9524 mptsas_waitq_delete(mpt, cmd); 9525 mptsas_set_pkt_reason(mpt, cmd, 9526 reason, stat); 9527 mptsas_doneq_add(mpt, cmd); 9528 } 9529 cmd = next_cmd; 9530 } 9531 mutex_enter(&mpt->m_tx_waitq_mutex); 9532 cmd = mpt->m_tx_waitq; 9533 while (cmd != NULL) { 9534 next_cmd = cmd->cmd_linkp; 9535 if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) { 9536 mptsas_tx_waitq_delete(mpt, cmd); 9537 mutex_exit(&mpt->m_tx_waitq_mutex); 9538 mptsas_set_pkt_reason(mpt, cmd, 9539 reason, stat); 9540 mptsas_doneq_add(mpt, cmd); 9541 mutex_enter(&mpt->m_tx_waitq_mutex); 9542 } 9543 cmd = next_cmd; 9544 } 9545 mutex_exit(&mpt->m_tx_waitq_mutex); 9546 break; 9547 default: 9548 mptsas_log(mpt, CE_WARN, "Unknown task management type %d.", 9549 tasktype); 9550 break; 9551 } 9552 } 9553 9554 /* 9555 * Clean up hba state, abort all outstanding command and commands in waitq 9556 * reset timeout of all targets. 9557 */ 9558 static void 9559 mptsas_flush_hba(mptsas_t *mpt) 9560 { 9561 mptsas_slots_t *slots = mpt->m_active; 9562 mptsas_cmd_t *cmd; 9563 int slot; 9564 9565 NDBG25(("mptsas_flush_hba")); 9566 9567 /* 9568 * The I/O Controller should have already sent back 9569 * all commands via the scsi I/O reply frame. Make 9570 * sure all commands have been flushed. 9571 * Account for TM request, which use the last SMID. 9572 */ 9573 for (slot = 0; slot <= mpt->m_active->m_n_normal; slot++) { 9574 if ((cmd = slots->m_slot[slot]) == NULL) 9575 continue; 9576 9577 if (cmd->cmd_flags & CFLAG_CMDIOC) { 9578 /* 9579 * Need to make sure to tell everyone that might be 9580 * waiting on this command that it's going to fail. If 9581 * we get here, this command will never timeout because 9582 * the active command table is going to be re-allocated, 9583 * so there will be nothing to check against a time out. 9584 * Instead, mark the command as failed due to reset. 9585 */ 9586 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, 9587 STAT_BUS_RESET); 9588 if ((cmd->cmd_flags & 9589 (CFLAG_PASSTHRU | CFLAG_CONFIG | CFLAG_FW_DIAG))) { 9590 cmd->cmd_flags |= CFLAG_FINISHED; 9591 cv_broadcast(&mpt->m_passthru_cv); 9592 cv_broadcast(&mpt->m_config_cv); 9593 cv_broadcast(&mpt->m_fw_diag_cv); 9594 } 9595 continue; 9596 } 9597 9598 NDBG25(("mptsas_flush_hba discovered non-NULL cmd in slot %d", 9599 slot)); 9600 mptsas_dump_cmd(mpt, cmd); 9601 9602 mptsas_remove_cmd(mpt, cmd); 9603 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 9604 mptsas_doneq_add(mpt, cmd); 9605 } 9606 9607 /* 9608 * Flush the waitq. 9609 */ 9610 while ((cmd = mptsas_waitq_rm(mpt)) != NULL) { 9611 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 9612 if ((cmd->cmd_flags & CFLAG_PASSTHRU) || 9613 (cmd->cmd_flags & CFLAG_CONFIG) || 9614 (cmd->cmd_flags & CFLAG_FW_DIAG)) { 9615 cmd->cmd_flags |= CFLAG_FINISHED; 9616 cv_broadcast(&mpt->m_passthru_cv); 9617 cv_broadcast(&mpt->m_config_cv); 9618 cv_broadcast(&mpt->m_fw_diag_cv); 9619 } else { 9620 mptsas_doneq_add(mpt, cmd); 9621 } 9622 } 9623 9624 /* 9625 * Flush the tx_waitq 9626 */ 9627 mutex_enter(&mpt->m_tx_waitq_mutex); 9628 while ((cmd = mptsas_tx_waitq_rm(mpt)) != NULL) { 9629 mutex_exit(&mpt->m_tx_waitq_mutex); 9630 mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET); 9631 mptsas_doneq_add(mpt, cmd); 9632 mutex_enter(&mpt->m_tx_waitq_mutex); 9633 } 9634 mutex_exit(&mpt->m_tx_waitq_mutex); 9635 9636 /* 9637 * Drain the taskqs prior to reallocating resources. The thread 9638 * passing through here could be launched from either (dr) 9639 * or (event) taskqs so only wait on the 'other' queue since 9640 * waiting on 'this' queue is a deadlock condition. 9641 */ 9642 mutex_exit(&mpt->m_mutex); 9643 if (!taskq_member((taskq_t *)mpt->m_event_taskq, curthread)) 9644 ddi_taskq_wait(mpt->m_event_taskq); 9645 if (!taskq_member((taskq_t *)mpt->m_dr_taskq, curthread)) 9646 ddi_taskq_wait(mpt->m_dr_taskq); 9647 9648 mutex_enter(&mpt->m_mutex); 9649 } 9650 9651 /* 9652 * set pkt_reason and OR in pkt_statistics flag 9653 */ 9654 static void 9655 mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, uchar_t reason, 9656 uint_t stat) 9657 { 9658 #ifndef __lock_lint 9659 _NOTE(ARGUNUSED(mpt)) 9660 #endif 9661 9662 NDBG25(("mptsas_set_pkt_reason: cmd=0x%p reason=%x stat=%x", 9663 (void *)cmd, reason, stat)); 9664 9665 if (cmd) { 9666 if (cmd->cmd_pkt->pkt_reason == CMD_CMPLT) { 9667 cmd->cmd_pkt->pkt_reason = reason; 9668 } 9669 cmd->cmd_pkt->pkt_statistics |= stat; 9670 } 9671 } 9672 9673 static void 9674 mptsas_start_watch_reset_delay() 9675 { 9676 NDBG22(("mptsas_start_watch_reset_delay")); 9677 9678 mutex_enter(&mptsas_global_mutex); 9679 if (mptsas_reset_watch == NULL && mptsas_timeouts_enabled) { 9680 mptsas_reset_watch = timeout(mptsas_watch_reset_delay, NULL, 9681 drv_usectohz((clock_t) 9682 MPTSAS_WATCH_RESET_DELAY_TICK * 1000)); 9683 ASSERT(mptsas_reset_watch != NULL); 9684 } 9685 mutex_exit(&mptsas_global_mutex); 9686 } 9687 9688 static void 9689 mptsas_setup_bus_reset_delay(mptsas_t *mpt) 9690 { 9691 mptsas_target_t *ptgt = NULL; 9692 9693 ASSERT(MUTEX_HELD(&mpt->m_mutex)); 9694 9695 NDBG22(("mptsas_setup_bus_reset_delay")); 9696 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 9697 ptgt = refhash_next(mpt->m_targets, ptgt)) { 9698 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 9699 ptgt->m_reset_delay = mpt->m_scsi_reset_delay; 9700 } 9701 9702 mptsas_start_watch_reset_delay(); 9703 } 9704 9705 /* 9706 * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every 9707 * mpt instance for active reset delays 9708 */ 9709 static void 9710 mptsas_watch_reset_delay(void *arg) 9711 { 9712 #ifndef __lock_lint 9713 _NOTE(ARGUNUSED(arg)) 9714 #endif 9715 9716 mptsas_t *mpt; 9717 int not_done = 0; 9718 9719 NDBG22(("mptsas_watch_reset_delay")); 9720 9721 mutex_enter(&mptsas_global_mutex); 9722 mptsas_reset_watch = 0; 9723 mutex_exit(&mptsas_global_mutex); 9724 rw_enter(&mptsas_global_rwlock, RW_READER); 9725 for (mpt = mptsas_head; mpt != NULL; mpt = mpt->m_next) { 9726 if (mpt->m_tran == 0) { 9727 continue; 9728 } 9729 mutex_enter(&mpt->m_mutex); 9730 not_done += mptsas_watch_reset_delay_subr(mpt); 9731 mutex_exit(&mpt->m_mutex); 9732 } 9733 rw_exit(&mptsas_global_rwlock); 9734 9735 if (not_done) { 9736 mptsas_start_watch_reset_delay(); 9737 } 9738 } 9739 9740 static int 9741 mptsas_watch_reset_delay_subr(mptsas_t *mpt) 9742 { 9743 int done = 0; 9744 int restart = 0; 9745 mptsas_target_t *ptgt = NULL; 9746 9747 NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt)); 9748 9749 ASSERT(mutex_owned(&mpt->m_mutex)); 9750 9751 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 9752 ptgt = refhash_next(mpt->m_targets, ptgt)) { 9753 if (ptgt->m_reset_delay != 0) { 9754 ptgt->m_reset_delay -= 9755 MPTSAS_WATCH_RESET_DELAY_TICK; 9756 if (ptgt->m_reset_delay <= 0) { 9757 ptgt->m_reset_delay = 0; 9758 mptsas_set_throttle(mpt, ptgt, 9759 MAX_THROTTLE); 9760 restart++; 9761 } else { 9762 done = -1; 9763 } 9764 } 9765 } 9766 9767 if (restart > 0) { 9768 mptsas_restart_hba(mpt); 9769 } 9770 return (done); 9771 } 9772 9773 #ifdef MPTSAS_TEST 9774 static void 9775 mptsas_test_reset(mptsas_t *mpt, int target) 9776 { 9777 mptsas_target_t *ptgt = NULL; 9778 9779 if (mptsas_rtest == target) { 9780 if (mptsas_do_scsi_reset(mpt, target) == TRUE) { 9781 mptsas_rtest = -1; 9782 } 9783 if (mptsas_rtest == -1) { 9784 NDBG22(("mptsas_test_reset success")); 9785 } 9786 } 9787 } 9788 #endif 9789 9790 /* 9791 * abort handling: 9792 * 9793 * Notes: 9794 * - if pkt is not NULL, abort just that command 9795 * - if pkt is NULL, abort all outstanding commands for target 9796 */ 9797 static int 9798 mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt) 9799 { 9800 mptsas_t *mpt = ADDR2MPT(ap); 9801 int rval; 9802 mptsas_tgt_private_t *tgt_private; 9803 int target, lun; 9804 9805 tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran-> 9806 tran_tgt_private; 9807 ASSERT(tgt_private != NULL); 9808 target = tgt_private->t_private->m_devhdl; 9809 lun = tgt_private->t_lun; 9810 9811 NDBG23(("mptsas_scsi_abort: target=%d.%d", target, lun)); 9812 9813 mutex_enter(&mpt->m_mutex); 9814 rval = mptsas_do_scsi_abort(mpt, target, lun, pkt); 9815 mutex_exit(&mpt->m_mutex); 9816 return (rval); 9817 } 9818 9819 static int 9820 mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, struct scsi_pkt *pkt) 9821 { 9822 mptsas_cmd_t *sp = NULL; 9823 mptsas_slots_t *slots = mpt->m_active; 9824 int rval = FALSE; 9825 9826 ASSERT(mutex_owned(&mpt->m_mutex)); 9827 9828 /* 9829 * Abort the command pkt on the target/lun in ap. If pkt is 9830 * NULL, abort all outstanding commands on that target/lun. 9831 * If you can abort them, return 1, else return 0. 9832 * Each packet that's aborted should be sent back to the target 9833 * driver through the callback routine, with pkt_reason set to 9834 * CMD_ABORTED. 9835 * 9836 * abort cmd pkt on HBA hardware; clean out of outstanding 9837 * command lists, etc. 9838 */ 9839 if (pkt != NULL) { 9840 /* abort the specified packet */ 9841 sp = PKT2CMD(pkt); 9842 9843 if (sp->cmd_queued) { 9844 NDBG23(("mptsas_do_scsi_abort: queued sp=0x%p aborted", 9845 (void *)sp)); 9846 mptsas_waitq_delete(mpt, sp); 9847 mptsas_set_pkt_reason(mpt, sp, CMD_ABORTED, 9848 STAT_ABORTED); 9849 mptsas_doneq_add(mpt, sp); 9850 rval = TRUE; 9851 goto done; 9852 } 9853 9854 /* 9855 * Have mpt firmware abort this command 9856 */ 9857 9858 if (slots->m_slot[sp->cmd_slot] != NULL) { 9859 rval = mptsas_ioc_task_management(mpt, 9860 MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, target, 9861 lun, NULL, 0, 0); 9862 9863 /* 9864 * The transport layer expects only TRUE and FALSE. 9865 * Therefore, if mptsas_ioc_task_management returns 9866 * FAILED we will return FALSE. 9867 */ 9868 if (rval == FAILED) 9869 rval = FALSE; 9870 goto done; 9871 } 9872 } 9873 9874 /* 9875 * If pkt is NULL then abort task set 9876 */ 9877 rval = mptsas_ioc_task_management(mpt, 9878 MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, target, lun, NULL, 0, 0); 9879 9880 /* 9881 * The transport layer expects only TRUE and FALSE. 9882 * Therefore, if mptsas_ioc_task_management returns 9883 * FAILED we will return FALSE. 9884 */ 9885 if (rval == FAILED) 9886 rval = FALSE; 9887 9888 #ifdef MPTSAS_TEST 9889 if (rval && mptsas_test_stop) { 9890 debug_enter("mptsas_do_scsi_abort"); 9891 } 9892 #endif 9893 9894 done: 9895 mptsas_doneq_empty(mpt); 9896 return (rval); 9897 } 9898 9899 /* 9900 * capability handling: 9901 * (*tran_getcap). Get the capability named, and return its value. 9902 */ 9903 static int 9904 mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly) 9905 { 9906 mptsas_t *mpt = ADDR2MPT(ap); 9907 int ckey; 9908 int rval = FALSE; 9909 9910 NDBG24(("mptsas_scsi_getcap: target=%d, cap=%s tgtonly=%x", 9911 ap->a_target, cap, tgtonly)); 9912 9913 mutex_enter(&mpt->m_mutex); 9914 9915 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) { 9916 mutex_exit(&mpt->m_mutex); 9917 return (UNDEFINED); 9918 } 9919 9920 switch (ckey) { 9921 case SCSI_CAP_DMA_MAX: 9922 rval = (int)mpt->m_msg_dma_attr.dma_attr_maxxfer; 9923 break; 9924 case SCSI_CAP_ARQ: 9925 rval = TRUE; 9926 break; 9927 case SCSI_CAP_MSG_OUT: 9928 case SCSI_CAP_PARITY: 9929 case SCSI_CAP_UNTAGGED_QING: 9930 rval = TRUE; 9931 break; 9932 case SCSI_CAP_TAGGED_QING: 9933 rval = TRUE; 9934 break; 9935 case SCSI_CAP_RESET_NOTIFICATION: 9936 rval = TRUE; 9937 break; 9938 case SCSI_CAP_LINKED_CMDS: 9939 rval = FALSE; 9940 break; 9941 case SCSI_CAP_QFULL_RETRIES: 9942 rval = ((mptsas_tgt_private_t *)(ap->a_hba_tran-> 9943 tran_tgt_private))->t_private->m_qfull_retries; 9944 break; 9945 case SCSI_CAP_QFULL_RETRY_INTERVAL: 9946 rval = drv_hztousec(((mptsas_tgt_private_t *) 9947 (ap->a_hba_tran->tran_tgt_private))-> 9948 t_private->m_qfull_retry_interval) / 1000; 9949 break; 9950 case SCSI_CAP_CDB_LEN: 9951 rval = CDB_GROUP4; 9952 break; 9953 case SCSI_CAP_INTERCONNECT_TYPE: 9954 rval = INTERCONNECT_SAS; 9955 break; 9956 case SCSI_CAP_TRAN_LAYER_RETRIES: 9957 if (mpt->m_ioc_capabilities & 9958 MPI2_IOCFACTS_CAPABILITY_TLR) 9959 rval = TRUE; 9960 else 9961 rval = FALSE; 9962 break; 9963 default: 9964 rval = UNDEFINED; 9965 break; 9966 } 9967 9968 NDBG24(("mptsas_scsi_getcap: %s, rval=%x", cap, rval)); 9969 9970 mutex_exit(&mpt->m_mutex); 9971 return (rval); 9972 } 9973 9974 /* 9975 * (*tran_setcap). Set the capability named to the value given. 9976 */ 9977 static int 9978 mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, int tgtonly) 9979 { 9980 mptsas_t *mpt = ADDR2MPT(ap); 9981 int ckey; 9982 int rval = FALSE; 9983 9984 NDBG24(("mptsas_scsi_setcap: target=%d, cap=%s value=%x tgtonly=%x", 9985 ap->a_target, cap, value, tgtonly)); 9986 9987 if (!tgtonly) { 9988 return (rval); 9989 } 9990 9991 mutex_enter(&mpt->m_mutex); 9992 9993 if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) { 9994 mutex_exit(&mpt->m_mutex); 9995 return (UNDEFINED); 9996 } 9997 9998 switch (ckey) { 9999 case SCSI_CAP_DMA_MAX: 10000 case SCSI_CAP_MSG_OUT: 10001 case SCSI_CAP_PARITY: 10002 case SCSI_CAP_INITIATOR_ID: 10003 case SCSI_CAP_LINKED_CMDS: 10004 case SCSI_CAP_UNTAGGED_QING: 10005 case SCSI_CAP_RESET_NOTIFICATION: 10006 /* 10007 * None of these are settable via 10008 * the capability interface. 10009 */ 10010 break; 10011 case SCSI_CAP_ARQ: 10012 /* 10013 * We cannot turn off arq so return false if asked to 10014 */ 10015 if (value) { 10016 rval = TRUE; 10017 } else { 10018 rval = FALSE; 10019 } 10020 break; 10021 case SCSI_CAP_TAGGED_QING: 10022 mptsas_set_throttle(mpt, ((mptsas_tgt_private_t *) 10023 (ap->a_hba_tran->tran_tgt_private))->t_private, 10024 MAX_THROTTLE); 10025 rval = TRUE; 10026 break; 10027 case SCSI_CAP_QFULL_RETRIES: 10028 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))-> 10029 t_private->m_qfull_retries = (uchar_t)value; 10030 rval = TRUE; 10031 break; 10032 case SCSI_CAP_QFULL_RETRY_INTERVAL: 10033 ((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))-> 10034 t_private->m_qfull_retry_interval = 10035 drv_usectohz(value * 1000); 10036 rval = TRUE; 10037 break; 10038 default: 10039 rval = UNDEFINED; 10040 break; 10041 } 10042 mutex_exit(&mpt->m_mutex); 10043 return (rval); 10044 } 10045 10046 /* 10047 * Utility routine for mptsas_ifsetcap/ifgetcap 10048 */ 10049 /*ARGSUSED*/ 10050 static int 10051 mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp) 10052 { 10053 NDBG24(("mptsas_scsi_capchk: cap=%s", cap)); 10054 10055 if (!cap) 10056 return (FALSE); 10057 10058 *cidxp = scsi_hba_lookup_capstr(cap); 10059 return (TRUE); 10060 } 10061 10062 static int 10063 mptsas_alloc_active_slots(mptsas_t *mpt, int flag) 10064 { 10065 mptsas_slots_t *old_active = mpt->m_active; 10066 mptsas_slots_t *new_active; 10067 size_t size; 10068 10069 /* 10070 * if there are active commands, then we cannot 10071 * change size of active slots array. 10072 */ 10073 ASSERT(mpt->m_ncmds == 0); 10074 10075 size = MPTSAS_SLOTS_SIZE(mpt); 10076 new_active = kmem_zalloc(size, flag); 10077 if (new_active == NULL) { 10078 NDBG1(("new active alloc failed")); 10079 return (-1); 10080 } 10081 /* 10082 * Since SMID 0 is reserved and the TM slot is reserved, the 10083 * number of slots that can be used at any one time is 10084 * m_max_requests - 2. 10085 */ 10086 new_active->m_n_normal = (mpt->m_max_requests - 2); 10087 new_active->m_size = size; 10088 new_active->m_rotor = 1; 10089 if (old_active) 10090 mptsas_free_active_slots(mpt); 10091 mpt->m_active = new_active; 10092 10093 return (0); 10094 } 10095 10096 static void 10097 mptsas_free_active_slots(mptsas_t *mpt) 10098 { 10099 mptsas_slots_t *active = mpt->m_active; 10100 size_t size; 10101 10102 if (active == NULL) 10103 return; 10104 size = active->m_size; 10105 kmem_free(active, size); 10106 mpt->m_active = NULL; 10107 } 10108 10109 /* 10110 * Error logging, printing, and debug print routines. 10111 */ 10112 static char *mptsas_label = "mpt_sas"; 10113 10114 /*PRINTFLIKE3*/ 10115 void 10116 mptsas_log(mptsas_t *mpt, int level, char *fmt, ...) 10117 { 10118 dev_info_t *dev; 10119 va_list ap; 10120 10121 if (mpt) { 10122 dev = mpt->m_dip; 10123 } else { 10124 dev = 0; 10125 } 10126 10127 mutex_enter(&mptsas_log_mutex); 10128 10129 va_start(ap, fmt); 10130 (void) vsprintf(mptsas_log_buf, fmt, ap); 10131 va_end(ap); 10132 10133 if (level == CE_CONT) { 10134 scsi_log(dev, mptsas_label, level, "%s\n", mptsas_log_buf); 10135 } else { 10136 scsi_log(dev, mptsas_label, level, "%s", mptsas_log_buf); 10137 } 10138 10139 mutex_exit(&mptsas_log_mutex); 10140 } 10141 10142 #ifdef MPTSAS_DEBUG 10143 /* 10144 * Use a circular buffer to log messages to private memory. 10145 * Increment idx atomically to minimize risk to miss lines. 10146 * It's fast and does not hold up the proceedings too much. 10147 */ 10148 static const size_t mptsas_dbglog_linecnt = MPTSAS_DBGLOG_LINECNT; 10149 static const size_t mptsas_dbglog_linelen = MPTSAS_DBGLOG_LINELEN; 10150 static char mptsas_dbglog_bufs[MPTSAS_DBGLOG_LINECNT][MPTSAS_DBGLOG_LINELEN]; 10151 static uint32_t mptsas_dbglog_idx = 0; 10152 10153 /*PRINTFLIKE1*/ 10154 void 10155 mptsas_debug_log(char *fmt, ...) 10156 { 10157 va_list ap; 10158 uint32_t idx; 10159 10160 idx = atomic_inc_32_nv(&mptsas_dbglog_idx) & 10161 (mptsas_dbglog_linecnt - 1); 10162 10163 va_start(ap, fmt); 10164 (void) vsnprintf(mptsas_dbglog_bufs[idx], 10165 mptsas_dbglog_linelen, fmt, ap); 10166 va_end(ap); 10167 } 10168 10169 /*PRINTFLIKE1*/ 10170 void 10171 mptsas_printf(char *fmt, ...) 10172 { 10173 dev_info_t *dev = 0; 10174 va_list ap; 10175 10176 mutex_enter(&mptsas_log_mutex); 10177 10178 va_start(ap, fmt); 10179 (void) vsprintf(mptsas_log_buf, fmt, ap); 10180 va_end(ap); 10181 10182 #ifdef PROM_PRINTF 10183 prom_printf("%s:\t%s\n", mptsas_label, mptsas_log_buf); 10184 #else 10185 scsi_log(dev, mptsas_label, CE_CONT, "!%s\n", mptsas_log_buf); 10186 #endif 10187 mutex_exit(&mptsas_log_mutex); 10188 } 10189 #endif 10190 10191 /* 10192 * timeout handling 10193 */ 10194 static void 10195 mptsas_watch(void *arg) 10196 { 10197 #ifndef __lock_lint 10198 _NOTE(ARGUNUSED(arg)) 10199 #endif 10200 10201 mptsas_t *mpt; 10202 uint32_t doorbell; 10203 10204 NDBG30(("mptsas_watch")); 10205 10206 rw_enter(&mptsas_global_rwlock, RW_READER); 10207 for (mpt = mptsas_head; mpt != (mptsas_t *)NULL; mpt = mpt->m_next) { 10208 10209 mutex_enter(&mpt->m_mutex); 10210 10211 /* Skip device if not powered on */ 10212 if (mpt->m_options & MPTSAS_OPT_PM) { 10213 if (mpt->m_power_level == PM_LEVEL_D0) { 10214 (void) pm_busy_component(mpt->m_dip, 0); 10215 mpt->m_busy = 1; 10216 } else { 10217 mutex_exit(&mpt->m_mutex); 10218 continue; 10219 } 10220 } 10221 10222 /* 10223 * Check if controller is in a FAULT state. If so, reset it. 10224 */ 10225 doorbell = mptsas_hirrd(mpt, &mpt->m_reg->Doorbell); 10226 if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { 10227 doorbell &= MPI2_DOORBELL_DATA_MASK; 10228 mptsas_log(mpt, CE_WARN, "MPT Firmware Fault, " 10229 "code: %04x", doorbell); 10230 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 10231 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 10232 mptsas_log(mpt, CE_WARN, "Reset failed" 10233 "after fault was detected"); 10234 } 10235 } 10236 10237 /* 10238 * For now, always call mptsas_watchsubr. 10239 */ 10240 mptsas_watchsubr(mpt); 10241 10242 if (mpt->m_options & MPTSAS_OPT_PM) { 10243 mpt->m_busy = 0; 10244 (void) pm_idle_component(mpt->m_dip, 0); 10245 } 10246 10247 mutex_exit(&mpt->m_mutex); 10248 } 10249 rw_exit(&mptsas_global_rwlock); 10250 10251 mutex_enter(&mptsas_global_mutex); 10252 if (mptsas_timeouts_enabled) 10253 mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick); 10254 mutex_exit(&mptsas_global_mutex); 10255 } 10256 10257 static void 10258 mptsas_watchsubr_tgt(mptsas_t *mpt, mptsas_target_t *ptgt, hrtime_t timestamp) 10259 { 10260 mptsas_cmd_t *cmd; 10261 10262 /* 10263 * If we were draining due to a qfull condition, 10264 * go back to full throttle. 10265 */ 10266 if ((ptgt->m_t_throttle < MAX_THROTTLE) && 10267 (ptgt->m_t_throttle > HOLD_THROTTLE) && 10268 (ptgt->m_t_ncmds < ptgt->m_t_throttle)) { 10269 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 10270 mptsas_restart_hba(mpt); 10271 } 10272 10273 cmd = TAILQ_LAST(&ptgt->m_active_cmdq, mptsas_active_cmdq); 10274 if (cmd == NULL) 10275 return; 10276 10277 if (cmd->cmd_active_expiration <= timestamp) { 10278 /* 10279 * Earliest command timeout expired. Drain throttle. 10280 */ 10281 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 10282 10283 /* 10284 * Check for remaining commands. 10285 */ 10286 cmd = TAILQ_FIRST(&ptgt->m_active_cmdq); 10287 if (cmd->cmd_active_expiration > timestamp) { 10288 /* 10289 * Wait for remaining commands to complete or 10290 * time out. 10291 */ 10292 NDBG23(("command timed out, pending drain")); 10293 return; 10294 } 10295 10296 /* 10297 * All command timeouts expired. 10298 */ 10299 mptsas_log(mpt, CE_NOTE, "Timeout of %d seconds " 10300 "expired with %d commands on target %d lun %d.", 10301 cmd->cmd_pkt->pkt_time, ptgt->m_t_ncmds, 10302 ptgt->m_devhdl, Lun(cmd)); 10303 10304 mptsas_cmd_timeout(mpt, ptgt); 10305 } else if (cmd->cmd_active_expiration <= 10306 timestamp + (hrtime_t)mptsas_scsi_watchdog_tick * NANOSEC) { 10307 NDBG23(("pending timeout")); 10308 mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE); 10309 } 10310 } 10311 10312 static void 10313 mptsas_watchsubr(mptsas_t *mpt) 10314 { 10315 int i; 10316 mptsas_cmd_t *cmd; 10317 mptsas_target_t *ptgt = NULL; 10318 hrtime_t timestamp = gethrtime(); 10319 10320 ASSERT(MUTEX_HELD(&mpt->m_mutex)); 10321 10322 NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt)); 10323 10324 #ifdef MPTSAS_TEST 10325 if (mptsas_enable_untagged) { 10326 mptsas_test_untagged++; 10327 } 10328 #endif 10329 10330 /* 10331 * Check for commands stuck in active slot 10332 * Account for TM requests, which use the last SMID. 10333 */ 10334 for (i = 0; i <= mpt->m_active->m_n_normal; i++) { 10335 if ((cmd = mpt->m_active->m_slot[i]) != NULL) { 10336 if (cmd->cmd_active_expiration <= timestamp) { 10337 if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) { 10338 /* 10339 * There seems to be a command stuck 10340 * in the active slot. Drain throttle. 10341 */ 10342 mptsas_set_throttle(mpt, 10343 cmd->cmd_tgt_addr, 10344 DRAIN_THROTTLE); 10345 } else if (cmd->cmd_flags & 10346 (CFLAG_PASSTHRU | CFLAG_CONFIG | 10347 CFLAG_FW_DIAG)) { 10348 /* 10349 * passthrough command timeout 10350 */ 10351 cmd->cmd_flags |= (CFLAG_FINISHED | 10352 CFLAG_TIMEOUT); 10353 cv_broadcast(&mpt->m_passthru_cv); 10354 cv_broadcast(&mpt->m_config_cv); 10355 cv_broadcast(&mpt->m_fw_diag_cv); 10356 } 10357 } 10358 } 10359 } 10360 10361 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 10362 ptgt = refhash_next(mpt->m_targets, ptgt)) { 10363 mptsas_watchsubr_tgt(mpt, ptgt, timestamp); 10364 } 10365 10366 for (ptgt = refhash_first(mpt->m_tmp_targets); ptgt != NULL; 10367 ptgt = refhash_next(mpt->m_tmp_targets, ptgt)) { 10368 mptsas_watchsubr_tgt(mpt, ptgt, timestamp); 10369 } 10370 } 10371 10372 /* 10373 * timeout recovery 10374 */ 10375 static void 10376 mptsas_cmd_timeout(mptsas_t *mpt, mptsas_target_t *ptgt) 10377 { 10378 uint16_t devhdl; 10379 uint64_t sas_wwn; 10380 uint8_t phy; 10381 char wwn_str[MPTSAS_WWN_STRLEN]; 10382 10383 devhdl = ptgt->m_devhdl; 10384 sas_wwn = ptgt->m_addr.mta_wwn; 10385 phy = ptgt->m_phynum; 10386 if (sas_wwn == 0) { 10387 (void) sprintf(wwn_str, "p%x", phy); 10388 } else { 10389 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 10390 } 10391 10392 NDBG29(("mptsas_cmd_timeout: target=%d", devhdl)); 10393 mptsas_log(mpt, CE_WARN, "Disconnected command timeout for " 10394 "target %d %s, enclosure %u", devhdl, wwn_str, 10395 ptgt->m_enclosure); 10396 10397 /* 10398 * Abort all outstanding commands on the device. 10399 */ 10400 NDBG29(("mptsas_cmd_timeout: device reset")); 10401 if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) { 10402 mptsas_log(mpt, CE_WARN, "Target %d reset for command timeout " 10403 "recovery failed!", devhdl); 10404 } 10405 } 10406 10407 /* 10408 * Device / Hotplug control 10409 */ 10410 static int 10411 mptsas_scsi_quiesce(dev_info_t *dip) 10412 { 10413 mptsas_t *mpt; 10414 scsi_hba_tran_t *tran; 10415 10416 tran = ddi_get_driver_private(dip); 10417 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL) 10418 return (-1); 10419 10420 return (mptsas_quiesce_bus(mpt)); 10421 } 10422 10423 static int 10424 mptsas_scsi_unquiesce(dev_info_t *dip) 10425 { 10426 mptsas_t *mpt; 10427 scsi_hba_tran_t *tran; 10428 10429 tran = ddi_get_driver_private(dip); 10430 if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL) 10431 return (-1); 10432 10433 return (mptsas_unquiesce_bus(mpt)); 10434 } 10435 10436 static int 10437 mptsas_quiesce_bus(mptsas_t *mpt) 10438 { 10439 mptsas_target_t *ptgt = NULL; 10440 10441 NDBG28(("mptsas_quiesce_bus")); 10442 mutex_enter(&mpt->m_mutex); 10443 10444 /* Set all the throttles to zero */ 10445 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 10446 ptgt = refhash_next(mpt->m_targets, ptgt)) { 10447 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 10448 } 10449 10450 /* If there are any outstanding commands in the queue */ 10451 if (mpt->m_ncmds) { 10452 mpt->m_softstate |= MPTSAS_SS_DRAINING; 10453 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain, 10454 mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000))); 10455 if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) { 10456 /* 10457 * Quiesce has been interrupted 10458 */ 10459 mpt->m_softstate &= ~MPTSAS_SS_DRAINING; 10460 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 10461 ptgt = refhash_next(mpt->m_targets, ptgt)) { 10462 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 10463 } 10464 mptsas_restart_hba(mpt); 10465 if (mpt->m_quiesce_timeid != 0) { 10466 timeout_id_t tid = mpt->m_quiesce_timeid; 10467 mpt->m_quiesce_timeid = 0; 10468 mutex_exit(&mpt->m_mutex); 10469 (void) untimeout(tid); 10470 return (-1); 10471 } 10472 mutex_exit(&mpt->m_mutex); 10473 return (-1); 10474 } else { 10475 /* Bus has been quiesced */ 10476 ASSERT(mpt->m_quiesce_timeid == 0); 10477 mpt->m_softstate &= ~MPTSAS_SS_DRAINING; 10478 mpt->m_softstate |= MPTSAS_SS_QUIESCED; 10479 mutex_exit(&mpt->m_mutex); 10480 return (0); 10481 } 10482 } 10483 /* Bus was not busy - QUIESCED */ 10484 mutex_exit(&mpt->m_mutex); 10485 10486 return (0); 10487 } 10488 10489 static int 10490 mptsas_unquiesce_bus(mptsas_t *mpt) 10491 { 10492 mptsas_target_t *ptgt = NULL; 10493 10494 NDBG28(("mptsas_unquiesce_bus")); 10495 mutex_enter(&mpt->m_mutex); 10496 mpt->m_softstate &= ~MPTSAS_SS_QUIESCED; 10497 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 10498 ptgt = refhash_next(mpt->m_targets, ptgt)) { 10499 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 10500 } 10501 mptsas_restart_hba(mpt); 10502 mutex_exit(&mpt->m_mutex); 10503 return (0); 10504 } 10505 10506 static void 10507 mptsas_ncmds_checkdrain(void *arg) 10508 { 10509 mptsas_t *mpt = arg; 10510 mptsas_target_t *ptgt = NULL; 10511 10512 mutex_enter(&mpt->m_mutex); 10513 if (mpt->m_softstate & MPTSAS_SS_DRAINING) { 10514 mpt->m_quiesce_timeid = 0; 10515 if (mpt->m_ncmds == 0) { 10516 /* Command queue has been drained */ 10517 cv_signal(&mpt->m_cv); 10518 } else { 10519 /* 10520 * The throttle may have been reset because 10521 * of a SCSI bus reset 10522 */ 10523 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 10524 ptgt = refhash_next(mpt->m_targets, ptgt)) { 10525 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 10526 } 10527 10528 mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain, 10529 mpt, (MPTSAS_QUIESCE_TIMEOUT * 10530 drv_usectohz(1000000))); 10531 } 10532 } 10533 mutex_exit(&mpt->m_mutex); 10534 } 10535 10536 /*ARGSUSED*/ 10537 static void 10538 mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd) 10539 { 10540 int i; 10541 uint8_t *cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp; 10542 char buf[128]; 10543 10544 buf[0] = '\0'; 10545 NDBG25(("?Cmd (0x%p) dump for Target %d Lun %d:\n", (void *)cmd, 10546 Tgt(cmd), Lun(cmd))); 10547 (void) sprintf(&buf[0], "\tcdb=["); 10548 for (i = 0; i < (int)cmd->cmd_cdblen; i++) { 10549 (void) sprintf(&buf[strlen(buf)], " 0x%x", *cp++); 10550 } 10551 (void) sprintf(&buf[strlen(buf)], " ]"); 10552 NDBG25(("?%s\n", buf)); 10553 NDBG25(("?pkt_flags=0x%x pkt_statistics=0x%x pkt_state=0x%x\n", 10554 cmd->cmd_pkt->pkt_flags, cmd->cmd_pkt->pkt_statistics, 10555 cmd->cmd_pkt->pkt_state)); 10556 NDBG25(("?pkt_scbp=0x%x cmd_flags=0x%x\n", cmd->cmd_pkt->pkt_scbp ? 10557 *(cmd->cmd_pkt->pkt_scbp) : 0, cmd->cmd_flags)); 10558 } 10559 10560 static void 10561 mptsas_passthru_sge(ddi_acc_handle_t acc_hdl, mptsas_pt_request_t *pt, 10562 pMpi2SGESimple64_t sgep) 10563 { 10564 uint32_t sge_flags; 10565 uint32_t data_size, dataout_size; 10566 ddi_dma_cookie_t data_cookie; 10567 ddi_dma_cookie_t dataout_cookie; 10568 10569 data_size = pt->data_size; 10570 dataout_size = pt->dataout_size; 10571 data_cookie = pt->data_cookie; 10572 dataout_cookie = pt->dataout_cookie; 10573 10574 if (dataout_size) { 10575 sge_flags = dataout_size | 10576 ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 10577 MPI2_SGE_FLAGS_END_OF_BUFFER | 10578 MPI2_SGE_FLAGS_HOST_TO_IOC | 10579 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 10580 MPI2_SGE_FLAGS_SHIFT); 10581 ddi_put32(acc_hdl, &sgep->FlagsLength, sge_flags); 10582 ddi_put32(acc_hdl, &sgep->Address.Low, 10583 (uint32_t)(dataout_cookie.dmac_laddress & 10584 0xffffffffull)); 10585 ddi_put32(acc_hdl, &sgep->Address.High, 10586 (uint32_t)(dataout_cookie.dmac_laddress 10587 >> 32)); 10588 sgep++; 10589 } 10590 sge_flags = data_size; 10591 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT | 10592 MPI2_SGE_FLAGS_LAST_ELEMENT | 10593 MPI2_SGE_FLAGS_END_OF_BUFFER | 10594 MPI2_SGE_FLAGS_END_OF_LIST | 10595 MPI2_SGE_FLAGS_64_BIT_ADDRESSING) << 10596 MPI2_SGE_FLAGS_SHIFT); 10597 if (pt->direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) { 10598 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_HOST_TO_IOC) << 10599 MPI2_SGE_FLAGS_SHIFT); 10600 } else { 10601 sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_IOC_TO_HOST) << 10602 MPI2_SGE_FLAGS_SHIFT); 10603 } 10604 ddi_put32(acc_hdl, &sgep->FlagsLength, 10605 sge_flags); 10606 ddi_put32(acc_hdl, &sgep->Address.Low, 10607 (uint32_t)(data_cookie.dmac_laddress & 10608 0xffffffffull)); 10609 ddi_put32(acc_hdl, &sgep->Address.High, 10610 (uint32_t)(data_cookie.dmac_laddress >> 32)); 10611 } 10612 10613 static void 10614 mptsas_passthru_ieee_sge(ddi_acc_handle_t acc_hdl, mptsas_pt_request_t *pt, 10615 pMpi2IeeeSgeSimple64_t ieeesgep) 10616 { 10617 uint8_t sge_flags; 10618 uint32_t data_size, dataout_size; 10619 ddi_dma_cookie_t data_cookie; 10620 ddi_dma_cookie_t dataout_cookie; 10621 10622 data_size = pt->data_size; 10623 dataout_size = pt->dataout_size; 10624 data_cookie = pt->data_cookie; 10625 dataout_cookie = pt->dataout_cookie; 10626 10627 sge_flags = (MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT | 10628 MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR); 10629 if (dataout_size) { 10630 ddi_put32(acc_hdl, &ieeesgep->Length, dataout_size); 10631 ddi_put32(acc_hdl, &ieeesgep->Address.Low, 10632 (uint32_t)(dataout_cookie.dmac_laddress & 10633 0xffffffffull)); 10634 ddi_put32(acc_hdl, &ieeesgep->Address.High, 10635 (uint32_t)(dataout_cookie.dmac_laddress >> 32)); 10636 ddi_put8(acc_hdl, &ieeesgep->Flags, sge_flags); 10637 ieeesgep++; 10638 } 10639 sge_flags |= MPI25_IEEE_SGE_FLAGS_END_OF_LIST; 10640 ddi_put32(acc_hdl, &ieeesgep->Length, data_size); 10641 ddi_put32(acc_hdl, &ieeesgep->Address.Low, 10642 (uint32_t)(data_cookie.dmac_laddress & 0xffffffffull)); 10643 ddi_put32(acc_hdl, &ieeesgep->Address.High, 10644 (uint32_t)(data_cookie.dmac_laddress >> 32)); 10645 ddi_put8(acc_hdl, &ieeesgep->Flags, sge_flags); 10646 } 10647 10648 static void 10649 mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd) 10650 { 10651 caddr_t memp; 10652 pMPI2RequestHeader_t request_hdrp; 10653 struct scsi_pkt *pkt = cmd->cmd_pkt; 10654 mptsas_pt_request_t *pt = pkt->pkt_ha_private; 10655 uint32_t request_size; 10656 uint32_t i; 10657 uint64_t request_desc = 0; 10658 uint8_t desc_type; 10659 uint16_t SMID; 10660 uint8_t *request, function; 10661 ddi_dma_handle_t dma_hdl = mpt->m_dma_req_frame_hdl; 10662 ddi_acc_handle_t acc_hdl = mpt->m_acc_req_frame_hdl; 10663 10664 desc_type = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 10665 10666 request = pt->request; 10667 request_size = pt->request_size; 10668 10669 SMID = cmd->cmd_slot; 10670 10671 /* 10672 * Store the passthrough message in memory location 10673 * corresponding to our slot number 10674 */ 10675 memp = mpt->m_req_frame + (mpt->m_req_frame_size * SMID); 10676 request_hdrp = (pMPI2RequestHeader_t)memp; 10677 bzero(memp, mpt->m_req_frame_size); 10678 10679 for (i = 0; i < request_size; i++) { 10680 bcopy(request + i, memp + i, 1); 10681 } 10682 10683 NDBG15(("mptsas_start_passthru: Func 0x%x, MsgFlags 0x%x, " 10684 "size=%d, in %d, out %d, SMID %d", request_hdrp->Function, 10685 request_hdrp->MsgFlags, request_size, 10686 pt->data_size, pt->dataout_size, SMID)); 10687 10688 /* 10689 * Add an SGE, even if the length is zero. 10690 */ 10691 if (mpt->m_MPI25 && pt->simple == 0) { 10692 mptsas_passthru_ieee_sge(acc_hdl, pt, 10693 (pMpi2IeeeSgeSimple64_t) 10694 ((uint8_t *)request_hdrp + pt->sgl_offset)); 10695 } else { 10696 mptsas_passthru_sge(acc_hdl, pt, 10697 (pMpi2SGESimple64_t) 10698 ((uint8_t *)request_hdrp + pt->sgl_offset)); 10699 } 10700 10701 function = request_hdrp->Function; 10702 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) || 10703 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 10704 pMpi2SCSIIORequest_t scsi_io_req; 10705 caddr_t arsbuf; 10706 uint8_t ars_size; 10707 uint32_t ars_dmaaddrlow; 10708 10709 NDBG15(("mptsas_start_passthru: Is SCSI IO Req")); 10710 scsi_io_req = (pMpi2SCSIIORequest_t)request_hdrp; 10711 10712 if (cmd->cmd_extrqslen != 0) { 10713 /* 10714 * Mapping of the buffer was done in 10715 * mptsas_do_passthru(). 10716 * Calculate the DMA address with the same offset. 10717 */ 10718 arsbuf = cmd->cmd_arq_buf; 10719 ars_size = cmd->cmd_extrqslen; 10720 ars_dmaaddrlow = (mpt->m_req_sense_dma_addr + 10721 ((uintptr_t)arsbuf - (uintptr_t)mpt->m_req_sense)) & 10722 0xffffffffu; 10723 } else { 10724 arsbuf = mpt->m_req_sense + 10725 (mpt->m_req_sense_size * (SMID-1)); 10726 cmd->cmd_arq_buf = arsbuf; 10727 ars_size = mpt->m_req_sense_size; 10728 ars_dmaaddrlow = (mpt->m_req_sense_dma_addr + 10729 (mpt->m_req_sense_size * (SMID-1))) & 10730 0xffffffffu; 10731 } 10732 bzero(arsbuf, ars_size); 10733 10734 ddi_put8(acc_hdl, &scsi_io_req->SenseBufferLength, ars_size); 10735 ddi_put32(acc_hdl, &scsi_io_req->SenseBufferLowAddress, 10736 ars_dmaaddrlow); 10737 10738 /* 10739 * Put SGE for data and data_out buffer at the end of 10740 * scsi_io_request message header.(64 bytes in total) 10741 * Set SGLOffset0 value 10742 */ 10743 ddi_put8(acc_hdl, &scsi_io_req->SGLOffset0, 10744 offsetof(MPI2_SCSI_IO_REQUEST, SGL) / 4); 10745 10746 /* 10747 * Setup descriptor info. RAID passthrough must use the 10748 * default request descriptor which is already set, so if this 10749 * is a SCSI IO request, change the descriptor to SCSI IO. 10750 */ 10751 if (function == MPI2_FUNCTION_SCSI_IO_REQUEST) { 10752 desc_type = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 10753 request_desc = ((uint64_t)ddi_get16(acc_hdl, 10754 &scsi_io_req->DevHandle) << 48); 10755 } 10756 (void) ddi_dma_sync(mpt->m_dma_req_sense_hdl, 0, 0, 10757 DDI_DMA_SYNC_FORDEV); 10758 } 10759 10760 /* 10761 * We must wait till the message has been completed before 10762 * beginning the next message so we wait for this one to 10763 * finish. 10764 */ 10765 (void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV); 10766 request_desc |= (SMID << 16) + desc_type; 10767 cmd->cmd_rfm = 0; 10768 MPTSAS_START_CMD(mpt, request_desc); 10769 if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) || 10770 (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) { 10771 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 10772 } 10773 } 10774 10775 typedef void (mptsas_pre_f)(mptsas_t *, mptsas_pt_request_t *); 10776 static mptsas_pre_f mpi_pre_ioc_facts; 10777 static mptsas_pre_f mpi_pre_port_facts; 10778 static mptsas_pre_f mpi_pre_fw_download; 10779 static mptsas_pre_f mpi_pre_fw_25_download; 10780 static mptsas_pre_f mpi_pre_fw_upload; 10781 static mptsas_pre_f mpi_pre_fw_25_upload; 10782 static mptsas_pre_f mpi_pre_sata_passthrough; 10783 static mptsas_pre_f mpi_pre_smp_passthrough; 10784 static mptsas_pre_f mpi_pre_config; 10785 static mptsas_pre_f mpi_pre_sas_io_unit_control; 10786 static mptsas_pre_f mpi_pre_scsi_io_req; 10787 10788 /* 10789 * Prepare the pt for a SAS2 FW_DOWNLOAD request. 10790 */ 10791 static void 10792 mpi_pre_fw_download(mptsas_t *mpt, mptsas_pt_request_t *pt) 10793 { 10794 pMpi2FWDownloadTCSGE_t tcsge; 10795 pMpi2FWDownloadRequest req; 10796 10797 /* 10798 * If SAS3, call separate function. 10799 */ 10800 if (mpt->m_MPI25) { 10801 mpi_pre_fw_25_download(mpt, pt); 10802 return; 10803 } 10804 10805 /* 10806 * User requests should come in with the Transaction 10807 * context element where the SGL will go. Putting the 10808 * SGL after that seems to work, but don't really know 10809 * why. Other drivers tend to create an extra SGL and 10810 * refer to the TCE through that. 10811 */ 10812 req = (pMpi2FWDownloadRequest)pt->request; 10813 tcsge = (pMpi2FWDownloadTCSGE_t)&req->SGL; 10814 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 || 10815 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) { 10816 mptsas_log(mpt, CE_WARN, "FW Download tce invalid!"); 10817 } 10818 10819 pt->sgl_offset = offsetof(MPI2_FW_DOWNLOAD_REQUEST, SGL) + 10820 sizeof (*tcsge); 10821 if (pt->request_size != pt->sgl_offset) { 10822 NDBG15(("mpi_pre_fw_download(): Incorrect req size, " 10823 "0x%x, should be 0x%x, dataoutsz 0x%x", 10824 (int)pt->request_size, (int)pt->sgl_offset, 10825 (int)pt->dataout_size)); 10826 } 10827 if (pt->data_size < sizeof (MPI2_FW_DOWNLOAD_REPLY)) { 10828 NDBG15(("mpi_pre_fw_download(): Incorrect rep size, " 10829 "0x%x, should be 0x%x", pt->data_size, 10830 (int)sizeof (MPI2_FW_DOWNLOAD_REPLY))); 10831 } 10832 } 10833 10834 /* 10835 * Prepare the pt for a SAS3 FW_DOWNLOAD request. 10836 */ 10837 static void 10838 mpi_pre_fw_25_download(mptsas_t *mpt, mptsas_pt_request_t *pt) 10839 { 10840 pMpi2FWDownloadTCSGE_t tcsge; 10841 pMpi2FWDownloadRequest req2; 10842 pMpi25FWDownloadRequest req25; 10843 10844 /* 10845 * User requests should come in with the Transaction 10846 * context element where the SGL will go. The new firmware 10847 * Doesn't use TCE and has space in the main request for 10848 * this information. So move to the right place. 10849 */ 10850 req2 = (pMpi2FWDownloadRequest)pt->request; 10851 req25 = (pMpi25FWDownloadRequest)pt->request; 10852 tcsge = (pMpi2FWDownloadTCSGE_t)&req2->SGL; 10853 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 || 10854 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) { 10855 mptsas_log(mpt, CE_WARN, "FW Download tce invalid!"); 10856 } 10857 req25->ImageOffset = tcsge->ImageOffset; 10858 req25->ImageSize = tcsge->ImageSize; 10859 10860 pt->sgl_offset = offsetof(MPI25_FW_DOWNLOAD_REQUEST, SGL); 10861 if (pt->request_size != pt->sgl_offset) { 10862 NDBG15(("mpi_pre_fw_25_download(): Incorrect req size, " 10863 "0x%x, should be 0x%x, dataoutsz 0x%x", 10864 pt->request_size, pt->sgl_offset, 10865 pt->dataout_size)); 10866 } 10867 if (pt->data_size < sizeof (MPI2_FW_DOWNLOAD_REPLY)) { 10868 NDBG15(("mpi_pre_fw_25_download(): Incorrect rep size, " 10869 "0x%x, should be 0x%x", pt->data_size, 10870 (int)sizeof (MPI2_FW_UPLOAD_REPLY))); 10871 } 10872 } 10873 10874 /* 10875 * Prepare the pt for a SAS2 FW_UPLOAD request. 10876 */ 10877 static void 10878 mpi_pre_fw_upload(mptsas_t *mpt, mptsas_pt_request_t *pt) 10879 { 10880 pMpi2FWUploadTCSGE_t tcsge; 10881 pMpi2FWUploadRequest_t req; 10882 10883 /* 10884 * If SAS3, call separate function. 10885 */ 10886 if (mpt->m_MPI25) { 10887 mpi_pre_fw_25_upload(mpt, pt); 10888 return; 10889 } 10890 10891 /* 10892 * User requests should come in with the Transaction 10893 * context element where the SGL will go. Putting the 10894 * SGL after that seems to work, but don't really know 10895 * why. Other drivers tend to create an extra SGL and 10896 * refer to the TCE through that. 10897 */ 10898 req = (pMpi2FWUploadRequest_t)pt->request; 10899 tcsge = (pMpi2FWUploadTCSGE_t)&req->SGL; 10900 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 || 10901 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) { 10902 mptsas_log(mpt, CE_WARN, "FW Upload tce invalid!"); 10903 } 10904 10905 pt->sgl_offset = offsetof(MPI2_FW_UPLOAD_REQUEST, SGL) + 10906 sizeof (*tcsge); 10907 if (pt->request_size != pt->sgl_offset) { 10908 NDBG15(("mpi_pre_fw_upload(): Incorrect req size, " 10909 "0x%x, should be 0x%x, dataoutsz 0x%x", 10910 pt->request_size, pt->sgl_offset, 10911 pt->dataout_size)); 10912 } 10913 if (pt->data_size < sizeof (MPI2_FW_UPLOAD_REPLY)) { 10914 NDBG15(("mpi_pre_fw_upload(): Incorrect rep size, " 10915 "0x%x, should be 0x%x", pt->data_size, 10916 (int)sizeof (MPI2_FW_UPLOAD_REPLY))); 10917 } 10918 } 10919 10920 /* 10921 * Prepare the pt a SAS3 FW_UPLOAD request. 10922 */ 10923 static void 10924 mpi_pre_fw_25_upload(mptsas_t *mpt, mptsas_pt_request_t *pt) 10925 { 10926 pMpi2FWUploadTCSGE_t tcsge; 10927 pMpi2FWUploadRequest_t req2; 10928 pMpi25FWUploadRequest_t req25; 10929 10930 /* 10931 * User requests should come in with the Transaction 10932 * context element where the SGL will go. The new firmware 10933 * Doesn't use TCE and has space in the main request for 10934 * this information. So move to the right place. 10935 */ 10936 req2 = (pMpi2FWUploadRequest_t)pt->request; 10937 req25 = (pMpi25FWUploadRequest_t)pt->request; 10938 tcsge = (pMpi2FWUploadTCSGE_t)&req2->SGL; 10939 if (tcsge->ContextSize != 0 || tcsge->DetailsLength != 12 || 10940 tcsge->Flags != MPI2_SGE_FLAGS_TRANSACTION_ELEMENT) { 10941 mptsas_log(mpt, CE_WARN, "FW Upload tce invalid!"); 10942 } 10943 req25->ImageOffset = tcsge->ImageOffset; 10944 req25->ImageSize = tcsge->ImageSize; 10945 10946 pt->sgl_offset = offsetof(MPI25_FW_UPLOAD_REQUEST, SGL); 10947 if (pt->request_size != pt->sgl_offset) { 10948 NDBG15(("mpi_pre_fw_25_upload(): Incorrect req size, " 10949 "0x%x, should be 0x%x, dataoutsz 0x%x", 10950 pt->request_size, pt->sgl_offset, 10951 pt->dataout_size)); 10952 } 10953 if (pt->data_size < sizeof (MPI2_FW_UPLOAD_REPLY)) { 10954 NDBG15(("mpi_pre_fw_25_upload(): Incorrect rep size, " 10955 "0x%x, should be 0x%x", pt->data_size, 10956 (int)sizeof (MPI2_FW_UPLOAD_REPLY))); 10957 } 10958 } 10959 10960 /* 10961 * Prepare the pt for an IOC_FACTS request. 10962 */ 10963 static void 10964 mpi_pre_ioc_facts(mptsas_t *mpt, mptsas_pt_request_t *pt) 10965 { 10966 #ifndef __lock_lint 10967 _NOTE(ARGUNUSED(mpt)) 10968 #endif 10969 if (pt->request_size != sizeof (MPI2_IOC_FACTS_REQUEST)) { 10970 NDBG15(("mpi_pre_ioc_facts(): Incorrect req size, " 10971 "0x%x, should be 0x%x, dataoutsz 0x%x", 10972 pt->request_size, 10973 (int)sizeof (MPI2_IOC_FACTS_REQUEST), 10974 pt->dataout_size)); 10975 } 10976 if (pt->data_size != sizeof (MPI2_IOC_FACTS_REPLY)) { 10977 NDBG15(("mpi_pre_ioc_facts(): Incorrect rep size, " 10978 "0x%x, should be 0x%x", pt->data_size, 10979 (int)sizeof (MPI2_IOC_FACTS_REPLY))); 10980 } 10981 pt->sgl_offset = (uint16_t)pt->request_size; 10982 } 10983 10984 /* 10985 * Prepare the pt for a PORT_FACTS request. 10986 */ 10987 static void 10988 mpi_pre_port_facts(mptsas_t *mpt, mptsas_pt_request_t *pt) 10989 { 10990 #ifndef __lock_lint 10991 _NOTE(ARGUNUSED(mpt)) 10992 #endif 10993 if (pt->request_size != sizeof (MPI2_PORT_FACTS_REQUEST)) { 10994 NDBG15(("mpi_pre_port_facts(): Incorrect req size, " 10995 "0x%x, should be 0x%x, dataoutsz 0x%x", 10996 pt->request_size, 10997 (int)sizeof (MPI2_PORT_FACTS_REQUEST), 10998 pt->dataout_size)); 10999 } 11000 if (pt->data_size != sizeof (MPI2_PORT_FACTS_REPLY)) { 11001 NDBG15(("mpi_pre_port_facts(): Incorrect rep size, " 11002 "0x%x, should be 0x%x", pt->data_size, 11003 (int)sizeof (MPI2_PORT_FACTS_REPLY))); 11004 } 11005 pt->sgl_offset = (uint16_t)pt->request_size; 11006 } 11007 11008 /* 11009 * Prepare pt for a SATA_PASSTHROUGH request. 11010 */ 11011 static void 11012 mpi_pre_sata_passthrough(mptsas_t *mpt, mptsas_pt_request_t *pt) 11013 { 11014 #ifndef __lock_lint 11015 _NOTE(ARGUNUSED(mpt)) 11016 #endif 11017 pt->sgl_offset = offsetof(MPI2_SATA_PASSTHROUGH_REQUEST, SGL); 11018 if (pt->request_size != pt->sgl_offset) { 11019 NDBG15(("mpi_pre_sata_passthrough(): Incorrect req size, " 11020 "0x%x, should be 0x%x, dataoutsz 0x%x", 11021 pt->request_size, pt->sgl_offset, 11022 pt->dataout_size)); 11023 } 11024 if (pt->data_size != sizeof (MPI2_SATA_PASSTHROUGH_REPLY)) { 11025 NDBG15(("mpi_pre_sata_passthrough(): Incorrect rep size, " 11026 "0x%x, should be 0x%x", pt->data_size, 11027 (int)sizeof (MPI2_SATA_PASSTHROUGH_REPLY))); 11028 } 11029 } 11030 11031 static void 11032 mpi_pre_smp_passthrough(mptsas_t *mpt, mptsas_pt_request_t *pt) 11033 { 11034 #ifndef __lock_lint 11035 _NOTE(ARGUNUSED(mpt)) 11036 #endif 11037 pt->sgl_offset = offsetof(MPI2_SMP_PASSTHROUGH_REQUEST, SGL); 11038 if (pt->request_size != pt->sgl_offset) { 11039 NDBG15(("mpi_pre_smp_passthrough(): Incorrect req size, " 11040 "0x%x, should be 0x%x, dataoutsz 0x%x", 11041 pt->request_size, pt->sgl_offset, 11042 pt->dataout_size)); 11043 } 11044 if (pt->data_size != sizeof (MPI2_SMP_PASSTHROUGH_REPLY)) { 11045 NDBG15(("mpi_pre_smp_passthrough(): Incorrect rep size, " 11046 "0x%x, should be 0x%x", pt->data_size, 11047 (int)sizeof (MPI2_SMP_PASSTHROUGH_REPLY))); 11048 } 11049 } 11050 11051 /* 11052 * Prepare pt for a CONFIG request. 11053 */ 11054 static void 11055 mpi_pre_config(mptsas_t *mpt, mptsas_pt_request_t *pt) 11056 { 11057 #ifndef __lock_lint 11058 _NOTE(ARGUNUSED(mpt)) 11059 #endif 11060 pt->sgl_offset = offsetof(MPI2_CONFIG_REQUEST, PageBufferSGE); 11061 if (pt->request_size != pt->sgl_offset) { 11062 NDBG15(("mpi_pre_config(): Incorrect req size, 0x%x, " 11063 "should be 0x%x, dataoutsz 0x%x", pt->request_size, 11064 pt->sgl_offset, pt->dataout_size)); 11065 } 11066 if (pt->data_size != sizeof (MPI2_CONFIG_REPLY)) { 11067 NDBG15(("mpi_pre_config(): Incorrect rep size, 0x%x, " 11068 "should be 0x%x", pt->data_size, 11069 (int)sizeof (MPI2_CONFIG_REPLY))); 11070 } 11071 pt->simple = 1; 11072 } 11073 11074 /* 11075 * Prepare pt for a SCSI_IO_REQ request. 11076 */ 11077 static void 11078 mpi_pre_scsi_io_req(mptsas_t *mpt, mptsas_pt_request_t *pt) 11079 { 11080 #ifndef __lock_lint 11081 _NOTE(ARGUNUSED(mpt)) 11082 #endif 11083 pt->sgl_offset = offsetof(MPI2_SCSI_IO_REQUEST, SGL); 11084 if (pt->request_size != pt->sgl_offset) { 11085 NDBG15(("mpi_pre_config(): Incorrect req size, 0x%x, " 11086 "should be 0x%x, dataoutsz 0x%x", pt->request_size, 11087 pt->sgl_offset, 11088 pt->dataout_size)); 11089 } 11090 if (pt->data_size != sizeof (MPI2_SCSI_IO_REPLY)) { 11091 NDBG15(("mpi_pre_config(): Incorrect rep size, 0x%x, " 11092 "should be 0x%x", pt->data_size, 11093 (int)sizeof (MPI2_SCSI_IO_REPLY))); 11094 } 11095 } 11096 11097 /* 11098 * Prepare the mptsas_cmd for a SAS_IO_UNIT_CONTROL request. 11099 */ 11100 static void 11101 mpi_pre_sas_io_unit_control(mptsas_t *mpt, mptsas_pt_request_t *pt) 11102 { 11103 #ifndef __lock_lint 11104 _NOTE(ARGUNUSED(mpt)) 11105 #endif 11106 pt->sgl_offset = (uint16_t)pt->request_size; 11107 } 11108 11109 /* 11110 * A set of functions to prepare an mptsas_cmd for the various 11111 * supported requests. 11112 */ 11113 static struct mptsas_func { 11114 U8 Function; 11115 char *Name; 11116 mptsas_pre_f *f_pre; 11117 } mptsas_func_list[] = { 11118 { MPI2_FUNCTION_IOC_FACTS, "IOC_FACTS", mpi_pre_ioc_facts }, 11119 { MPI2_FUNCTION_PORT_FACTS, "PORT_FACTS", mpi_pre_port_facts }, 11120 { MPI2_FUNCTION_FW_DOWNLOAD, "FW_DOWNLOAD", mpi_pre_fw_download }, 11121 { MPI2_FUNCTION_FW_UPLOAD, "FW_UPLOAD", mpi_pre_fw_upload }, 11122 { MPI2_FUNCTION_SATA_PASSTHROUGH, "SATA_PASSTHROUGH", 11123 mpi_pre_sata_passthrough }, 11124 { MPI2_FUNCTION_SMP_PASSTHROUGH, "SMP_PASSTHROUGH", 11125 mpi_pre_smp_passthrough}, 11126 { MPI2_FUNCTION_SCSI_IO_REQUEST, "SCSI_IO_REQUEST", 11127 mpi_pre_scsi_io_req}, 11128 { MPI2_FUNCTION_CONFIG, "CONFIG", mpi_pre_config}, 11129 { MPI2_FUNCTION_SAS_IO_UNIT_CONTROL, "SAS_IO_UNIT_CONTROL", 11130 mpi_pre_sas_io_unit_control }, 11131 { 0xFF, NULL, NULL } /* list end */ 11132 }; 11133 11134 static void 11135 mptsas_prep_sgl_offset(mptsas_t *mpt, mptsas_pt_request_t *pt) 11136 { 11137 pMPI2RequestHeader_t hdr; 11138 struct mptsas_func *f; 11139 11140 hdr = (pMPI2RequestHeader_t)pt->request; 11141 11142 for (f = mptsas_func_list; f->f_pre != NULL; f++) { 11143 if (hdr->Function == f->Function) { 11144 f->f_pre(mpt, pt); 11145 NDBG15(("mptsas_prep_sgl_offset: Function %s," 11146 " sgl_offset 0x%x", f->Name, 11147 pt->sgl_offset)); 11148 return; 11149 } 11150 } 11151 NDBG15(("mptsas_prep_sgl_offset: Unknown Function 0x%02x," 11152 " returning req_size 0x%x for sgl_offset", 11153 hdr->Function, pt->request_size)); 11154 pt->sgl_offset = (uint16_t)pt->request_size; 11155 } 11156 11157 11158 static int 11159 mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply, 11160 uint8_t *data, uint32_t request_size, uint32_t reply_size, 11161 uint32_t data_size, uint32_t direction, uint8_t *dataout, 11162 uint32_t dataout_size, short timeout, int mode) 11163 { 11164 mptsas_pt_request_t pt; 11165 mptsas_dma_alloc_state_t data_dma_state; 11166 mptsas_dma_alloc_state_t dataout_dma_state; 11167 caddr_t memp; 11168 mptsas_cmd_t *cmd = NULL; 11169 struct scsi_pkt *pkt; 11170 uint32_t reply_len = 0, sense_len = 0; 11171 pMPI2RequestHeader_t request_hdrp; 11172 pMPI2RequestHeader_t request_msg; 11173 pMPI2DefaultReply_t reply_msg; 11174 Mpi2SCSIIOReply_t rep_msg; 11175 int rvalue; 11176 int i, status = 0, pt_flags = 0, rv = 0; 11177 uint8_t function; 11178 11179 ASSERT(mutex_owned(&mpt->m_mutex)); 11180 11181 reply_msg = (pMPI2DefaultReply_t)(&rep_msg); 11182 bzero(reply_msg, sizeof (MPI2_DEFAULT_REPLY)); 11183 request_msg = kmem_zalloc(request_size, KM_SLEEP); 11184 11185 mutex_exit(&mpt->m_mutex); 11186 /* 11187 * copy in the request buffer since it could be used by 11188 * another thread when the pt request into waitq 11189 */ 11190 if (ddi_copyin(request, request_msg, request_size, mode)) { 11191 mutex_enter(&mpt->m_mutex); 11192 status = EFAULT; 11193 mptsas_log(mpt, CE_WARN, "failed to copy request data"); 11194 goto out; 11195 } 11196 NDBG27(("mptsas_do_passthru: mode 0x%x, size 0x%x, Func 0x%x", 11197 mode, request_size, request_msg->Function)); 11198 mutex_enter(&mpt->m_mutex); 11199 11200 function = request_msg->Function; 11201 if (function == MPI2_FUNCTION_SCSI_TASK_MGMT) { 11202 pMpi2SCSITaskManagementRequest_t task; 11203 task = (pMpi2SCSITaskManagementRequest_t)request_msg; 11204 mptsas_setup_bus_reset_delay(mpt); 11205 rv = mptsas_ioc_task_management(mpt, task->TaskType, 11206 task->DevHandle, (int)task->LUN[1], reply, reply_size, 11207 mode); 11208 11209 if (rv != TRUE) { 11210 status = EIO; 11211 mptsas_log(mpt, CE_WARN, "task management failed"); 11212 } 11213 goto out; 11214 } 11215 11216 if (data_size != 0) { 11217 data_dma_state.size = data_size; 11218 if (mptsas_dma_alloc(mpt, &data_dma_state) != DDI_SUCCESS) { 11219 status = ENOMEM; 11220 mptsas_log(mpt, CE_WARN, "failed to alloc DMA " 11221 "resource"); 11222 goto out; 11223 } 11224 pt_flags |= MPTSAS_DATA_ALLOCATED; 11225 if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) { 11226 mutex_exit(&mpt->m_mutex); 11227 for (i = 0; i < data_size; i++) { 11228 if (ddi_copyin(data + i, (uint8_t *) 11229 data_dma_state.memp + i, 1, mode)) { 11230 mutex_enter(&mpt->m_mutex); 11231 status = EFAULT; 11232 mptsas_log(mpt, CE_WARN, "failed to " 11233 "copy read data"); 11234 goto out; 11235 } 11236 } 11237 mutex_enter(&mpt->m_mutex); 11238 } 11239 } else { 11240 bzero(&data_dma_state, sizeof (data_dma_state)); 11241 } 11242 11243 if (dataout_size != 0) { 11244 dataout_dma_state.size = dataout_size; 11245 if (mptsas_dma_alloc(mpt, &dataout_dma_state) != DDI_SUCCESS) { 11246 status = ENOMEM; 11247 mptsas_log(mpt, CE_WARN, "failed to alloc DMA " 11248 "resource"); 11249 goto out; 11250 } 11251 pt_flags |= MPTSAS_DATAOUT_ALLOCATED; 11252 mutex_exit(&mpt->m_mutex); 11253 for (i = 0; i < dataout_size; i++) { 11254 if (ddi_copyin(dataout + i, (uint8_t *) 11255 dataout_dma_state.memp + i, 1, mode)) { 11256 mutex_enter(&mpt->m_mutex); 11257 mptsas_log(mpt, CE_WARN, "failed to copy out" 11258 " data"); 11259 status = EFAULT; 11260 goto out; 11261 } 11262 } 11263 mutex_enter(&mpt->m_mutex); 11264 } else { 11265 bzero(&dataout_dma_state, sizeof (dataout_dma_state)); 11266 } 11267 11268 if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 11269 status = EAGAIN; 11270 mptsas_log(mpt, CE_NOTE, "event ack command pool is full"); 11271 goto out; 11272 } 11273 pt_flags |= MPTSAS_REQUEST_POOL_CMD; 11274 11275 bzero((caddr_t)cmd, sizeof (*cmd)); 11276 bzero((caddr_t)pkt, scsi_pkt_size()); 11277 bzero((caddr_t)&pt, sizeof (pt)); 11278 11279 cmd->ioc_cmd_slot = (uint32_t)(rvalue); 11280 11281 pt.request = (uint8_t *)request_msg; 11282 pt.direction = direction; 11283 pt.simple = 0; 11284 pt.request_size = request_size; 11285 pt.data_size = data_size; 11286 pt.dataout_size = dataout_size; 11287 pt.data_cookie = data_dma_state.cookie; 11288 pt.dataout_cookie = dataout_dma_state.cookie; 11289 mptsas_prep_sgl_offset(mpt, &pt); 11290 11291 /* 11292 * Form a blank cmd/pkt to store the acknowledgement message 11293 */ 11294 pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb[0]; 11295 pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb; 11296 pkt->pkt_ha_private = (opaque_t)&pt; 11297 pkt->pkt_flags = FLAG_HEAD; 11298 pkt->pkt_time = timeout; 11299 cmd->cmd_pkt = pkt; 11300 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_PASSTHRU; 11301 11302 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) || 11303 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 11304 uint8_t com, cdb_group_id; 11305 boolean_t ret; 11306 11307 pkt->pkt_cdbp = ((pMpi2SCSIIORequest_t)request_msg)->CDB.CDB32; 11308 com = pkt->pkt_cdbp[0]; 11309 cdb_group_id = CDB_GROUPID(com); 11310 switch (cdb_group_id) { 11311 case CDB_GROUPID_0: cmd->cmd_cdblen = CDB_GROUP0; break; 11312 case CDB_GROUPID_1: cmd->cmd_cdblen = CDB_GROUP1; break; 11313 case CDB_GROUPID_2: cmd->cmd_cdblen = CDB_GROUP2; break; 11314 case CDB_GROUPID_4: cmd->cmd_cdblen = CDB_GROUP4; break; 11315 case CDB_GROUPID_5: cmd->cmd_cdblen = CDB_GROUP5; break; 11316 default: 11317 NDBG27(("mptsas_do_passthru: SCSI_IO, reserved " 11318 "CDBGROUP 0x%x requested!", cdb_group_id)); 11319 break; 11320 } 11321 11322 reply_len = sizeof (MPI2_SCSI_IO_REPLY); 11323 sense_len = reply_size - reply_len; 11324 ret = mptsas_cmdarqsize(mpt, cmd, sense_len, KM_SLEEP); 11325 VERIFY(ret == B_TRUE); 11326 } else { 11327 reply_len = reply_size; 11328 sense_len = 0; 11329 } 11330 11331 NDBG27(("mptsas_do_passthru: %s, dsz 0x%x, dosz 0x%x, replen 0x%x, " 11332 "snslen 0x%x", 11333 (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE)?"Write":"Read", 11334 data_size, dataout_size, reply_len, sense_len)); 11335 11336 /* 11337 * Save the command in a slot 11338 */ 11339 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 11340 /* 11341 * Once passthru command get slot, set cmd_flags 11342 * CFLAG_PREPARED. 11343 */ 11344 cmd->cmd_flags |= CFLAG_PREPARED; 11345 mptsas_start_passthru(mpt, cmd); 11346 } else { 11347 mptsas_waitq_add(mpt, cmd); 11348 } 11349 11350 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 11351 cv_wait(&mpt->m_passthru_cv, &mpt->m_mutex); 11352 } 11353 11354 NDBG27(("mptsas_do_passthru: Cmd complete, flags 0x%x, rfm 0x%x " 11355 "pktreason 0x%x", cmd->cmd_flags, cmd->cmd_rfm, 11356 pkt->pkt_reason)); 11357 11358 if (cmd->cmd_flags & CFLAG_PREPARED) { 11359 memp = mpt->m_req_frame + (mpt->m_req_frame_size * 11360 cmd->cmd_slot); 11361 request_hdrp = (pMPI2RequestHeader_t)memp; 11362 } 11363 11364 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 11365 status = ETIMEDOUT; 11366 mptsas_log(mpt, CE_WARN, "passthrough command timeout"); 11367 pt_flags |= MPTSAS_CMD_TIMEOUT; 11368 goto out; 11369 } 11370 11371 if (cmd->cmd_rfm) { 11372 /* 11373 * cmd_rfm is zero means the command reply is a CONTEXT 11374 * reply and no PCI Write to post the free reply SMFA 11375 * because no reply message frame is used. 11376 * cmd_rfm is non-zero means the reply is a ADDRESS 11377 * reply and reply message frame is used. 11378 */ 11379 pt_flags |= MPTSAS_ADDRESS_REPLY; 11380 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 11381 DDI_DMA_SYNC_FORCPU); 11382 reply_msg = (pMPI2DefaultReply_t) 11383 (mpt->m_reply_frame + (cmd->cmd_rfm - 11384 (mpt->m_reply_frame_dma_addr & 0xffffffffu))); 11385 } 11386 11387 mptsas_fma_check(mpt, cmd); 11388 if (pkt->pkt_reason == CMD_TRAN_ERR) { 11389 status = EAGAIN; 11390 mptsas_log(mpt, CE_WARN, "passthru fma error"); 11391 goto out; 11392 } 11393 if (pkt->pkt_reason == CMD_RESET) { 11394 status = EAGAIN; 11395 mptsas_log(mpt, CE_WARN, "ioc reset abort passthru"); 11396 goto out; 11397 } 11398 11399 if (pkt->pkt_reason == CMD_INCOMPLETE) { 11400 status = EIO; 11401 mptsas_log(mpt, CE_WARN, "passthrough command incomplete"); 11402 goto out; 11403 } 11404 11405 mutex_exit(&mpt->m_mutex); 11406 if (cmd->cmd_flags & CFLAG_PREPARED) { 11407 function = request_hdrp->Function; 11408 if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) || 11409 (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { 11410 reply_len = sizeof (MPI2_SCSI_IO_REPLY); 11411 sense_len = cmd->cmd_extrqslen ? 11412 min(sense_len, cmd->cmd_extrqslen) : 11413 min(sense_len, cmd->cmd_rqslen); 11414 } else { 11415 reply_len = reply_size; 11416 sense_len = 0; 11417 } 11418 11419 for (i = 0; i < reply_len; i++) { 11420 if (ddi_copyout((uint8_t *)reply_msg + i, reply + i, 1, 11421 mode)) { 11422 mutex_enter(&mpt->m_mutex); 11423 status = EFAULT; 11424 mptsas_log(mpt, CE_WARN, "failed to copy out " 11425 "reply data"); 11426 goto out; 11427 } 11428 } 11429 for (i = 0; i < sense_len; i++) { 11430 if (ddi_copyout((uint8_t *)request_hdrp + 64 + i, 11431 reply + reply_len + i, 1, mode)) { 11432 mutex_enter(&mpt->m_mutex); 11433 status = EFAULT; 11434 mptsas_log(mpt, CE_WARN, "failed to copy out " 11435 "sense data"); 11436 goto out; 11437 } 11438 } 11439 } 11440 11441 if (data_size) { 11442 if (direction != MPTSAS_PASS_THRU_DIRECTION_WRITE) { 11443 (void) ddi_dma_sync(data_dma_state.handle, 0, 0, 11444 DDI_DMA_SYNC_FORCPU); 11445 for (i = 0; i < data_size; i++) { 11446 if (ddi_copyout((uint8_t *)( 11447 data_dma_state.memp + i), data + i, 1, 11448 mode)) { 11449 mutex_enter(&mpt->m_mutex); 11450 status = EFAULT; 11451 mptsas_log(mpt, CE_WARN, "failed to " 11452 "copy out the reply data"); 11453 goto out; 11454 } 11455 } 11456 } 11457 } 11458 mutex_enter(&mpt->m_mutex); 11459 out: 11460 /* 11461 * Put the reply frame back on the free queue, increment the free 11462 * index, and write the new index to the free index register. But only 11463 * if this reply is an ADDRESS reply. 11464 */ 11465 if (pt_flags & MPTSAS_ADDRESS_REPLY) { 11466 ddi_put32(mpt->m_acc_free_queue_hdl, 11467 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 11468 cmd->cmd_rfm); 11469 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 11470 DDI_DMA_SYNC_FORDEV); 11471 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 11472 mpt->m_free_index = 0; 11473 } 11474 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 11475 mpt->m_free_index); 11476 } 11477 if (cmd) { 11478 if (cmd->cmd_extrqslen != 0) { 11479 rmfree(mpt->m_erqsense_map, cmd->cmd_extrqschunks, 11480 cmd->cmd_extrqsidx + 1); 11481 } 11482 if (cmd->cmd_flags & CFLAG_PREPARED) { 11483 mptsas_remove_cmd(mpt, cmd); 11484 pt_flags &= (~MPTSAS_REQUEST_POOL_CMD); 11485 } 11486 } 11487 if (pt_flags & MPTSAS_REQUEST_POOL_CMD) 11488 mptsas_return_to_pool(mpt, cmd); 11489 if (pt_flags & MPTSAS_DATA_ALLOCATED) { 11490 if (mptsas_check_dma_handle(data_dma_state.handle) != 11491 DDI_SUCCESS) { 11492 ddi_fm_service_impact(mpt->m_dip, 11493 DDI_SERVICE_UNAFFECTED); 11494 status = EFAULT; 11495 } 11496 mptsas_dma_free(&data_dma_state); 11497 } 11498 if (pt_flags & MPTSAS_DATAOUT_ALLOCATED) { 11499 if (mptsas_check_dma_handle(dataout_dma_state.handle) != 11500 DDI_SUCCESS) { 11501 ddi_fm_service_impact(mpt->m_dip, 11502 DDI_SERVICE_UNAFFECTED); 11503 status = EFAULT; 11504 } 11505 mptsas_dma_free(&dataout_dma_state); 11506 } 11507 if (pt_flags & MPTSAS_CMD_TIMEOUT) { 11508 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 11509 mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed"); 11510 } 11511 } 11512 if (request_msg) 11513 kmem_free(request_msg, request_size); 11514 NDBG27(("mptsas_do_passthru: Done status 0x%x", status)); 11515 11516 return (status); 11517 } 11518 11519 static int 11520 mptsas_pass_thru(mptsas_t *mpt, mptsas_pass_thru_t *data, int mode) 11521 { 11522 /* 11523 * If timeout is 0, set timeout to default of 60 seconds. 11524 */ 11525 if (data->Timeout == 0) { 11526 data->Timeout = MPTSAS_PASS_THRU_TIME_DEFAULT; 11527 } 11528 11529 if (((data->DataSize == 0) && 11530 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_NONE)) || 11531 ((data->DataSize != 0) && 11532 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_READ) || 11533 (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_WRITE) || 11534 ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) && 11535 (data->DataOutSize != 0))))) { 11536 if (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) { 11537 data->DataDirection = MPTSAS_PASS_THRU_DIRECTION_READ; 11538 } else { 11539 data->DataOutSize = 0; 11540 } 11541 /* 11542 * Send passthru request messages 11543 */ 11544 return (mptsas_do_passthru(mpt, 11545 (uint8_t *)((uintptr_t)data->PtrRequest), 11546 (uint8_t *)((uintptr_t)data->PtrReply), 11547 (uint8_t *)((uintptr_t)data->PtrData), 11548 data->RequestSize, data->ReplySize, 11549 data->DataSize, data->DataDirection, 11550 (uint8_t *)((uintptr_t)data->PtrDataOut), 11551 data->DataOutSize, data->Timeout, mode)); 11552 } else { 11553 return (EINVAL); 11554 } 11555 } 11556 11557 static uint8_t 11558 mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, uint32_t unique_id) 11559 { 11560 uint8_t index; 11561 11562 for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) { 11563 if (mpt->m_fw_diag_buffer_list[index].unique_id == unique_id) { 11564 return (index); 11565 } 11566 } 11567 11568 return (MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND); 11569 } 11570 11571 static void 11572 mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd) 11573 { 11574 pMpi2DiagBufferPostRequest_t pDiag_post_msg; 11575 pMpi2DiagReleaseRequest_t pDiag_release_msg; 11576 struct scsi_pkt *pkt = cmd->cmd_pkt; 11577 mptsas_diag_request_t *diag = pkt->pkt_ha_private; 11578 uint32_t i; 11579 uint64_t request_desc; 11580 11581 ASSERT(mutex_owned(&mpt->m_mutex)); 11582 11583 /* 11584 * Form the diag message depending on the post or release function. 11585 */ 11586 if (diag->function == MPI2_FUNCTION_DIAG_BUFFER_POST) { 11587 pDiag_post_msg = (pMpi2DiagBufferPostRequest_t) 11588 (mpt->m_req_frame + (mpt->m_req_frame_size * 11589 cmd->cmd_slot)); 11590 bzero(pDiag_post_msg, mpt->m_req_frame_size); 11591 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->Function, 11592 diag->function); 11593 ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->BufferType, 11594 diag->pBuffer->buffer_type); 11595 ddi_put8(mpt->m_acc_req_frame_hdl, 11596 &pDiag_post_msg->ExtendedType, 11597 diag->pBuffer->extended_type); 11598 ddi_put32(mpt->m_acc_req_frame_hdl, 11599 &pDiag_post_msg->BufferLength, 11600 diag->pBuffer->buffer_data.size); 11601 for (i = 0; i < (sizeof (pDiag_post_msg->ProductSpecific) / 4); 11602 i++) { 11603 ddi_put32(mpt->m_acc_req_frame_hdl, 11604 &pDiag_post_msg->ProductSpecific[i], 11605 diag->pBuffer->product_specific[i]); 11606 } 11607 ddi_put32(mpt->m_acc_req_frame_hdl, 11608 &pDiag_post_msg->BufferAddress.Low, 11609 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress 11610 & 0xffffffffull)); 11611 ddi_put32(mpt->m_acc_req_frame_hdl, 11612 &pDiag_post_msg->BufferAddress.High, 11613 (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress 11614 >> 32)); 11615 } else { 11616 pDiag_release_msg = (pMpi2DiagReleaseRequest_t) 11617 (mpt->m_req_frame + (mpt->m_req_frame_size * 11618 cmd->cmd_slot)); 11619 bzero(pDiag_release_msg, mpt->m_req_frame_size); 11620 ddi_put8(mpt->m_acc_req_frame_hdl, 11621 &pDiag_release_msg->Function, diag->function); 11622 ddi_put8(mpt->m_acc_req_frame_hdl, 11623 &pDiag_release_msg->BufferType, 11624 diag->pBuffer->buffer_type); 11625 } 11626 11627 /* 11628 * Send the message 11629 */ 11630 (void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0, 11631 DDI_DMA_SYNC_FORDEV); 11632 request_desc = (cmd->cmd_slot << 16) + 11633 MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 11634 cmd->cmd_rfm = 0; 11635 MPTSAS_START_CMD(mpt, request_desc); 11636 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 11637 DDI_SUCCESS) || 11638 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 11639 DDI_SUCCESS)) { 11640 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 11641 } 11642 } 11643 11644 static int 11645 mptsas_post_fw_diag_buffer(mptsas_t *mpt, 11646 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code) 11647 { 11648 mptsas_diag_request_t diag; 11649 int status, slot_num, post_flags = 0; 11650 mptsas_cmd_t *cmd = NULL; 11651 struct scsi_pkt *pkt; 11652 pMpi2DiagBufferPostReply_t reply; 11653 uint16_t iocstatus; 11654 uint32_t iocloginfo, transfer_length; 11655 11656 /* 11657 * If buffer is not enabled, just leave. 11658 */ 11659 *return_code = MPTSAS_FW_DIAG_ERROR_POST_FAILED; 11660 if (!pBuffer->enabled) { 11661 status = DDI_FAILURE; 11662 goto out; 11663 } 11664 11665 /* 11666 * Clear some flags initially. 11667 */ 11668 pBuffer->force_release = FALSE; 11669 pBuffer->valid_data = FALSE; 11670 pBuffer->owned_by_firmware = FALSE; 11671 11672 /* 11673 * Get a cmd buffer from the cmd buffer pool 11674 */ 11675 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 11676 status = DDI_FAILURE; 11677 mptsas_log(mpt, CE_NOTE, "command pool is full: Post FW Diag"); 11678 goto out; 11679 } 11680 post_flags |= MPTSAS_REQUEST_POOL_CMD; 11681 11682 bzero((caddr_t)cmd, sizeof (*cmd)); 11683 bzero((caddr_t)pkt, scsi_pkt_size()); 11684 11685 cmd->ioc_cmd_slot = (uint32_t)(slot_num); 11686 11687 diag.pBuffer = pBuffer; 11688 diag.function = MPI2_FUNCTION_DIAG_BUFFER_POST; 11689 11690 /* 11691 * Form a blank cmd/pkt to store the acknowledgement message 11692 */ 11693 pkt->pkt_ha_private = (opaque_t)&diag; 11694 pkt->pkt_flags = FLAG_HEAD; 11695 pkt->pkt_time = 60; 11696 cmd->cmd_pkt = pkt; 11697 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG; 11698 11699 /* 11700 * Save the command in a slot 11701 */ 11702 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 11703 /* 11704 * Once passthru command get slot, set cmd_flags 11705 * CFLAG_PREPARED. 11706 */ 11707 cmd->cmd_flags |= CFLAG_PREPARED; 11708 mptsas_start_diag(mpt, cmd); 11709 } else { 11710 mptsas_waitq_add(mpt, cmd); 11711 } 11712 11713 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 11714 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex); 11715 } 11716 11717 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 11718 status = DDI_FAILURE; 11719 mptsas_log(mpt, CE_WARN, "Post FW Diag command timeout"); 11720 goto out; 11721 } 11722 11723 /* 11724 * cmd_rfm points to the reply message if a reply was given. Check the 11725 * IOCStatus to make sure everything went OK with the FW diag request 11726 * and set buffer flags. 11727 */ 11728 if (cmd->cmd_rfm) { 11729 post_flags |= MPTSAS_ADDRESS_REPLY; 11730 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 11731 DDI_DMA_SYNC_FORCPU); 11732 reply = (pMpi2DiagBufferPostReply_t)(mpt->m_reply_frame + 11733 (cmd->cmd_rfm - 11734 (mpt->m_reply_frame_dma_addr & 0xffffffffu))); 11735 11736 /* 11737 * Get the reply message data 11738 */ 11739 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 11740 &reply->IOCStatus); 11741 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 11742 &reply->IOCLogInfo); 11743 transfer_length = ddi_get32(mpt->m_acc_reply_frame_hdl, 11744 &reply->TransferLength); 11745 11746 /* 11747 * If post failed quit. 11748 */ 11749 if (iocstatus != MPI2_IOCSTATUS_SUCCESS) { 11750 status = DDI_FAILURE; 11751 NDBG13(("post FW Diag Buffer failed: IOCStatus=0x%x, " 11752 "IOCLogInfo=0x%x, TransferLength=0x%x", iocstatus, 11753 iocloginfo, transfer_length)); 11754 goto out; 11755 } 11756 11757 /* 11758 * Post was successful. 11759 */ 11760 pBuffer->valid_data = TRUE; 11761 pBuffer->owned_by_firmware = TRUE; 11762 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 11763 status = DDI_SUCCESS; 11764 } 11765 11766 out: 11767 /* 11768 * Put the reply frame back on the free queue, increment the free 11769 * index, and write the new index to the free index register. But only 11770 * if this reply is an ADDRESS reply. 11771 */ 11772 if (post_flags & MPTSAS_ADDRESS_REPLY) { 11773 ddi_put32(mpt->m_acc_free_queue_hdl, 11774 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 11775 cmd->cmd_rfm); 11776 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 11777 DDI_DMA_SYNC_FORDEV); 11778 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 11779 mpt->m_free_index = 0; 11780 } 11781 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 11782 mpt->m_free_index); 11783 } 11784 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 11785 mptsas_remove_cmd(mpt, cmd); 11786 post_flags &= (~MPTSAS_REQUEST_POOL_CMD); 11787 } 11788 if (post_flags & MPTSAS_REQUEST_POOL_CMD) { 11789 mptsas_return_to_pool(mpt, cmd); 11790 } 11791 11792 return (status); 11793 } 11794 11795 static int 11796 mptsas_release_fw_diag_buffer(mptsas_t *mpt, 11797 mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code, 11798 uint32_t diag_type) 11799 { 11800 mptsas_diag_request_t diag; 11801 int status, slot_num, rel_flags = 0; 11802 mptsas_cmd_t *cmd = NULL; 11803 struct scsi_pkt *pkt; 11804 pMpi2DiagReleaseReply_t reply; 11805 uint16_t iocstatus; 11806 uint32_t iocloginfo; 11807 11808 /* 11809 * If buffer is not enabled, just leave. 11810 */ 11811 *return_code = MPTSAS_FW_DIAG_ERROR_RELEASE_FAILED; 11812 if (!pBuffer->enabled) { 11813 mptsas_log(mpt, CE_NOTE, "This buffer type is not supported " 11814 "by the IOC"); 11815 status = DDI_FAILURE; 11816 goto out; 11817 } 11818 11819 /* 11820 * Clear some flags initially. 11821 */ 11822 pBuffer->force_release = FALSE; 11823 pBuffer->valid_data = FALSE; 11824 pBuffer->owned_by_firmware = FALSE; 11825 11826 /* 11827 * Get a cmd buffer from the cmd buffer pool 11828 */ 11829 if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) { 11830 status = DDI_FAILURE; 11831 mptsas_log(mpt, CE_NOTE, "command pool is full: Release FW " 11832 "Diag"); 11833 goto out; 11834 } 11835 rel_flags |= MPTSAS_REQUEST_POOL_CMD; 11836 11837 bzero((caddr_t)cmd, sizeof (*cmd)); 11838 bzero((caddr_t)pkt, scsi_pkt_size()); 11839 11840 cmd->ioc_cmd_slot = (uint32_t)(slot_num); 11841 11842 diag.pBuffer = pBuffer; 11843 diag.function = MPI2_FUNCTION_DIAG_RELEASE; 11844 11845 /* 11846 * Form a blank cmd/pkt to store the acknowledgement message 11847 */ 11848 pkt->pkt_ha_private = (opaque_t)&diag; 11849 pkt->pkt_flags = FLAG_HEAD; 11850 pkt->pkt_time = 60; 11851 cmd->cmd_pkt = pkt; 11852 cmd->cmd_flags = CFLAG_CMDIOC | CFLAG_FW_DIAG; 11853 11854 /* 11855 * Save the command in a slot 11856 */ 11857 if (mptsas_save_cmd(mpt, cmd) == TRUE) { 11858 /* 11859 * Once passthru command get slot, set cmd_flags 11860 * CFLAG_PREPARED. 11861 */ 11862 cmd->cmd_flags |= CFLAG_PREPARED; 11863 mptsas_start_diag(mpt, cmd); 11864 } else { 11865 mptsas_waitq_add(mpt, cmd); 11866 } 11867 11868 while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) { 11869 cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex); 11870 } 11871 11872 if (cmd->cmd_flags & CFLAG_TIMEOUT) { 11873 status = DDI_FAILURE; 11874 mptsas_log(mpt, CE_WARN, "Release FW Diag command timeout"); 11875 goto out; 11876 } 11877 11878 /* 11879 * cmd_rfm points to the reply message if a reply was given. Check the 11880 * IOCStatus to make sure everything went OK with the FW diag request 11881 * and set buffer flags. 11882 */ 11883 if (cmd->cmd_rfm) { 11884 rel_flags |= MPTSAS_ADDRESS_REPLY; 11885 (void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0, 11886 DDI_DMA_SYNC_FORCPU); 11887 reply = (pMpi2DiagReleaseReply_t)(mpt->m_reply_frame + 11888 (cmd->cmd_rfm - 11889 (mpt->m_reply_frame_dma_addr & 0xffffffffu))); 11890 11891 /* 11892 * Get the reply message data 11893 */ 11894 iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl, 11895 &reply->IOCStatus); 11896 iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl, 11897 &reply->IOCLogInfo); 11898 11899 /* 11900 * If release failed quit. 11901 */ 11902 if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) || 11903 pBuffer->owned_by_firmware) { 11904 status = DDI_FAILURE; 11905 NDBG13(("release FW Diag Buffer failed: " 11906 "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus, 11907 iocloginfo)); 11908 goto out; 11909 } 11910 11911 /* 11912 * Release was successful. 11913 */ 11914 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 11915 status = DDI_SUCCESS; 11916 11917 /* 11918 * If this was for an UNREGISTER diag type command, clear the 11919 * unique ID. 11920 */ 11921 if (diag_type == MPTSAS_FW_DIAG_TYPE_UNREGISTER) { 11922 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID; 11923 } 11924 } 11925 11926 out: 11927 /* 11928 * Put the reply frame back on the free queue, increment the free 11929 * index, and write the new index to the free index register. But only 11930 * if this reply is an ADDRESS reply. 11931 */ 11932 if (rel_flags & MPTSAS_ADDRESS_REPLY) { 11933 ddi_put32(mpt->m_acc_free_queue_hdl, 11934 &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], 11935 cmd->cmd_rfm); 11936 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 11937 DDI_DMA_SYNC_FORDEV); 11938 if (++mpt->m_free_index == mpt->m_free_queue_depth) { 11939 mpt->m_free_index = 0; 11940 } 11941 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, 11942 mpt->m_free_index); 11943 } 11944 if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) { 11945 mptsas_remove_cmd(mpt, cmd); 11946 rel_flags &= (~MPTSAS_REQUEST_POOL_CMD); 11947 } 11948 if (rel_flags & MPTSAS_REQUEST_POOL_CMD) { 11949 mptsas_return_to_pool(mpt, cmd); 11950 } 11951 11952 return (status); 11953 } 11954 11955 static int 11956 mptsas_diag_register(mptsas_t *mpt, mptsas_fw_diag_register_t *diag_register, 11957 uint32_t *return_code) 11958 { 11959 mptsas_fw_diagnostic_buffer_t *pBuffer; 11960 uint8_t extended_type, buffer_type, i; 11961 uint32_t buffer_size; 11962 uint32_t unique_id; 11963 int status; 11964 11965 ASSERT(mutex_owned(&mpt->m_mutex)); 11966 11967 extended_type = diag_register->ExtendedType; 11968 buffer_type = diag_register->BufferType; 11969 buffer_size = diag_register->RequestedBufferSize; 11970 unique_id = diag_register->UniqueId; 11971 11972 /* 11973 * Check for valid buffer type 11974 */ 11975 if (buffer_type >= MPI2_DIAG_BUF_TYPE_COUNT) { 11976 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 11977 return (DDI_FAILURE); 11978 } 11979 11980 /* 11981 * Get the current buffer and look up the unique ID. The unique ID 11982 * should not be found. If it is, the ID is already in use. 11983 */ 11984 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 11985 pBuffer = &mpt->m_fw_diag_buffer_list[buffer_type]; 11986 if (i != MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 11987 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11988 return (DDI_FAILURE); 11989 } 11990 11991 /* 11992 * The buffer's unique ID should not be registered yet, and the given 11993 * unique ID cannot be 0. 11994 */ 11995 if ((pBuffer->unique_id != MPTSAS_FW_DIAG_INVALID_UID) || 11996 (unique_id == MPTSAS_FW_DIAG_INVALID_UID)) { 11997 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 11998 return (DDI_FAILURE); 11999 } 12000 12001 /* 12002 * If this buffer is already posted as immediate, just change owner. 12003 */ 12004 if (pBuffer->immediate && pBuffer->owned_by_firmware && 12005 (pBuffer->unique_id == MPTSAS_FW_DIAG_INVALID_UID)) { 12006 pBuffer->immediate = FALSE; 12007 pBuffer->unique_id = unique_id; 12008 return (DDI_SUCCESS); 12009 } 12010 12011 /* 12012 * Post a new buffer after checking if it's enabled. The DMA buffer 12013 * that is allocated will be contiguous (sgl_len = 1). 12014 */ 12015 if (!pBuffer->enabled) { 12016 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER; 12017 return (DDI_FAILURE); 12018 } 12019 bzero(&pBuffer->buffer_data, sizeof (mptsas_dma_alloc_state_t)); 12020 pBuffer->buffer_data.size = buffer_size; 12021 if (mptsas_dma_alloc(mpt, &pBuffer->buffer_data) != DDI_SUCCESS) { 12022 mptsas_log(mpt, CE_WARN, "failed to alloc DMA resource for " 12023 "diag buffer: size = %d bytes", buffer_size); 12024 *return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER; 12025 return (DDI_FAILURE); 12026 } 12027 12028 /* 12029 * Copy the given info to the diag buffer and post the buffer. 12030 */ 12031 pBuffer->buffer_type = buffer_type; 12032 pBuffer->immediate = FALSE; 12033 if (buffer_type == MPI2_DIAG_BUF_TYPE_TRACE) { 12034 for (i = 0; i < (sizeof (pBuffer->product_specific) / 4); 12035 i++) { 12036 pBuffer->product_specific[i] = 12037 diag_register->ProductSpecific[i]; 12038 } 12039 } 12040 pBuffer->extended_type = extended_type; 12041 pBuffer->unique_id = unique_id; 12042 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, return_code); 12043 12044 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) != 12045 DDI_SUCCESS) { 12046 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed in " 12047 "mptsas_diag_register."); 12048 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 12049 status = DDI_FAILURE; 12050 } 12051 12052 /* 12053 * In case there was a failure, free the DMA buffer. 12054 */ 12055 if (status == DDI_FAILURE) { 12056 mptsas_dma_free(&pBuffer->buffer_data); 12057 } 12058 12059 return (status); 12060 } 12061 12062 static int 12063 mptsas_diag_unregister(mptsas_t *mpt, 12064 mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code) 12065 { 12066 mptsas_fw_diagnostic_buffer_t *pBuffer; 12067 uint8_t i; 12068 uint32_t unique_id; 12069 int status; 12070 12071 ASSERT(mutex_owned(&mpt->m_mutex)); 12072 12073 unique_id = diag_unregister->UniqueId; 12074 12075 /* 12076 * Get the current buffer and look up the unique ID. The unique ID 12077 * should be there. 12078 */ 12079 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 12080 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 12081 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 12082 return (DDI_FAILURE); 12083 } 12084 12085 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 12086 12087 /* 12088 * Try to release the buffer from FW before freeing it. If release 12089 * fails, don't free the DMA buffer in case FW tries to access it 12090 * later. If buffer is not owned by firmware, can't release it. 12091 */ 12092 if (!pBuffer->owned_by_firmware) { 12093 status = DDI_SUCCESS; 12094 } else { 12095 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, 12096 return_code, MPTSAS_FW_DIAG_TYPE_UNREGISTER); 12097 } 12098 12099 /* 12100 * At this point, return the current status no matter what happens with 12101 * the DMA buffer. 12102 */ 12103 pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID; 12104 if (status == DDI_SUCCESS) { 12105 if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) != 12106 DDI_SUCCESS) { 12107 mptsas_log(mpt, CE_WARN, "Check of DMA handle failed " 12108 "in mptsas_diag_unregister."); 12109 ddi_fm_service_impact(mpt->m_dip, 12110 DDI_SERVICE_UNAFFECTED); 12111 } 12112 mptsas_dma_free(&pBuffer->buffer_data); 12113 } 12114 12115 return (status); 12116 } 12117 12118 static int 12119 mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query, 12120 uint32_t *return_code) 12121 { 12122 mptsas_fw_diagnostic_buffer_t *pBuffer; 12123 uint8_t i; 12124 uint32_t unique_id; 12125 12126 ASSERT(mutex_owned(&mpt->m_mutex)); 12127 12128 unique_id = diag_query->UniqueId; 12129 12130 /* 12131 * If ID is valid, query on ID. 12132 * If ID is invalid, query on buffer type. 12133 */ 12134 if (unique_id == MPTSAS_FW_DIAG_INVALID_UID) { 12135 i = diag_query->BufferType; 12136 if (i >= MPI2_DIAG_BUF_TYPE_COUNT) { 12137 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 12138 return (DDI_FAILURE); 12139 } 12140 } else { 12141 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 12142 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 12143 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 12144 return (DDI_FAILURE); 12145 } 12146 } 12147 12148 /* 12149 * Fill query structure with the diag buffer info. 12150 */ 12151 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 12152 diag_query->BufferType = pBuffer->buffer_type; 12153 diag_query->ExtendedType = pBuffer->extended_type; 12154 if (diag_query->BufferType == MPI2_DIAG_BUF_TYPE_TRACE) { 12155 for (i = 0; i < (sizeof (diag_query->ProductSpecific) / 4); 12156 i++) { 12157 diag_query->ProductSpecific[i] = 12158 pBuffer->product_specific[i]; 12159 } 12160 } 12161 diag_query->TotalBufferSize = pBuffer->buffer_data.size; 12162 diag_query->DriverAddedBufferSize = 0; 12163 diag_query->UniqueId = pBuffer->unique_id; 12164 diag_query->ApplicationFlags = 0; 12165 diag_query->DiagnosticFlags = 0; 12166 12167 /* 12168 * Set/Clear application flags 12169 */ 12170 if (pBuffer->immediate) { 12171 diag_query->ApplicationFlags &= ~MPTSAS_FW_DIAG_FLAG_APP_OWNED; 12172 } else { 12173 diag_query->ApplicationFlags |= MPTSAS_FW_DIAG_FLAG_APP_OWNED; 12174 } 12175 if (pBuffer->valid_data || pBuffer->owned_by_firmware) { 12176 diag_query->ApplicationFlags |= 12177 MPTSAS_FW_DIAG_FLAG_BUFFER_VALID; 12178 } else { 12179 diag_query->ApplicationFlags &= 12180 ~MPTSAS_FW_DIAG_FLAG_BUFFER_VALID; 12181 } 12182 if (pBuffer->owned_by_firmware) { 12183 diag_query->ApplicationFlags |= 12184 MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS; 12185 } else { 12186 diag_query->ApplicationFlags &= 12187 ~MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS; 12188 } 12189 12190 return (DDI_SUCCESS); 12191 } 12192 12193 static int 12194 mptsas_diag_read_buffer(mptsas_t *mpt, 12195 mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf, 12196 uint32_t *return_code, int ioctl_mode) 12197 { 12198 mptsas_fw_diagnostic_buffer_t *pBuffer; 12199 uint8_t i, *pData; 12200 uint32_t unique_id, byte; 12201 int status; 12202 12203 ASSERT(mutex_owned(&mpt->m_mutex)); 12204 12205 unique_id = diag_read_buffer->UniqueId; 12206 12207 /* 12208 * Get the current buffer and look up the unique ID. The unique ID 12209 * should be there. 12210 */ 12211 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 12212 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 12213 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 12214 return (DDI_FAILURE); 12215 } 12216 12217 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 12218 12219 /* 12220 * Make sure requested read is within limits 12221 */ 12222 if (diag_read_buffer->StartingOffset + diag_read_buffer->BytesToRead > 12223 pBuffer->buffer_data.size) { 12224 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 12225 return (DDI_FAILURE); 12226 } 12227 12228 /* 12229 * Copy the requested data from DMA to the diag_read_buffer. The DMA 12230 * buffer that was allocated is one contiguous buffer. 12231 */ 12232 pData = (uint8_t *)(pBuffer->buffer_data.memp + 12233 diag_read_buffer->StartingOffset); 12234 (void) ddi_dma_sync(pBuffer->buffer_data.handle, 0, 0, 12235 DDI_DMA_SYNC_FORCPU); 12236 for (byte = 0; byte < diag_read_buffer->BytesToRead; byte++) { 12237 if (ddi_copyout(pData + byte, ioctl_buf + byte, 1, ioctl_mode) 12238 != 0) { 12239 return (DDI_FAILURE); 12240 } 12241 } 12242 diag_read_buffer->Status = 0; 12243 12244 /* 12245 * Set or clear the Force Release flag. 12246 */ 12247 if (pBuffer->force_release) { 12248 diag_read_buffer->Flags |= MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE; 12249 } else { 12250 diag_read_buffer->Flags &= ~MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE; 12251 } 12252 12253 /* 12254 * If buffer is to be reregistered, make sure it's not already owned by 12255 * firmware first. 12256 */ 12257 status = DDI_SUCCESS; 12258 if (!pBuffer->owned_by_firmware) { 12259 if (diag_read_buffer->Flags & MPTSAS_FW_DIAG_FLAG_REREGISTER) { 12260 status = mptsas_post_fw_diag_buffer(mpt, pBuffer, 12261 return_code); 12262 } 12263 } 12264 12265 return (status); 12266 } 12267 12268 static int 12269 mptsas_diag_release(mptsas_t *mpt, mptsas_fw_diag_release_t *diag_release, 12270 uint32_t *return_code) 12271 { 12272 mptsas_fw_diagnostic_buffer_t *pBuffer; 12273 uint8_t i; 12274 uint32_t unique_id; 12275 int status; 12276 12277 ASSERT(mutex_owned(&mpt->m_mutex)); 12278 12279 unique_id = diag_release->UniqueId; 12280 12281 /* 12282 * Get the current buffer and look up the unique ID. The unique ID 12283 * should be there. 12284 */ 12285 i = mptsas_get_fw_diag_buffer_number(mpt, unique_id); 12286 if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) { 12287 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID; 12288 return (DDI_FAILURE); 12289 } 12290 12291 pBuffer = &mpt->m_fw_diag_buffer_list[i]; 12292 12293 /* 12294 * If buffer is not owned by firmware, it's already been released. 12295 */ 12296 if (!pBuffer->owned_by_firmware) { 12297 *return_code = MPTSAS_FW_DIAG_ERROR_ALREADY_RELEASED; 12298 return (DDI_FAILURE); 12299 } 12300 12301 /* 12302 * Release the buffer. 12303 */ 12304 status = mptsas_release_fw_diag_buffer(mpt, pBuffer, return_code, 12305 MPTSAS_FW_DIAG_TYPE_RELEASE); 12306 return (status); 12307 } 12308 12309 static int 12310 mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, uint8_t *diag_action, 12311 uint32_t length, uint32_t *return_code, int ioctl_mode) 12312 { 12313 mptsas_fw_diag_register_t diag_register; 12314 mptsas_fw_diag_unregister_t diag_unregister; 12315 mptsas_fw_diag_query_t diag_query; 12316 mptsas_diag_read_buffer_t diag_read_buffer; 12317 mptsas_fw_diag_release_t diag_release; 12318 int status = DDI_SUCCESS; 12319 uint32_t original_return_code, read_buf_len; 12320 12321 ASSERT(mutex_owned(&mpt->m_mutex)); 12322 12323 original_return_code = *return_code; 12324 *return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS; 12325 12326 switch (action) { 12327 case MPTSAS_FW_DIAG_TYPE_REGISTER: 12328 if (!length) { 12329 *return_code = 12330 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 12331 status = DDI_FAILURE; 12332 break; 12333 } 12334 if (ddi_copyin(diag_action, &diag_register, 12335 sizeof (diag_register), ioctl_mode) != 0) { 12336 return (DDI_FAILURE); 12337 } 12338 status = mptsas_diag_register(mpt, &diag_register, 12339 return_code); 12340 break; 12341 12342 case MPTSAS_FW_DIAG_TYPE_UNREGISTER: 12343 if (length < sizeof (diag_unregister)) { 12344 *return_code = 12345 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 12346 status = DDI_FAILURE; 12347 break; 12348 } 12349 if (ddi_copyin(diag_action, &diag_unregister, 12350 sizeof (diag_unregister), ioctl_mode) != 0) { 12351 return (DDI_FAILURE); 12352 } 12353 status = mptsas_diag_unregister(mpt, &diag_unregister, 12354 return_code); 12355 break; 12356 12357 case MPTSAS_FW_DIAG_TYPE_QUERY: 12358 if (length < sizeof (diag_query)) { 12359 *return_code = 12360 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 12361 status = DDI_FAILURE; 12362 break; 12363 } 12364 if (ddi_copyin(diag_action, &diag_query, 12365 sizeof (diag_query), ioctl_mode) != 0) { 12366 return (DDI_FAILURE); 12367 } 12368 status = mptsas_diag_query(mpt, &diag_query, 12369 return_code); 12370 if (status == DDI_SUCCESS) { 12371 if (ddi_copyout(&diag_query, diag_action, 12372 sizeof (diag_query), ioctl_mode) != 0) { 12373 return (DDI_FAILURE); 12374 } 12375 } 12376 break; 12377 12378 case MPTSAS_FW_DIAG_TYPE_READ_BUFFER: 12379 if (ddi_copyin(diag_action, &diag_read_buffer, 12380 sizeof (diag_read_buffer) - 4, ioctl_mode) != 0) { 12381 return (DDI_FAILURE); 12382 } 12383 read_buf_len = sizeof (diag_read_buffer) - 12384 sizeof (diag_read_buffer.DataBuffer) + 12385 diag_read_buffer.BytesToRead; 12386 if (length < read_buf_len) { 12387 *return_code = 12388 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 12389 status = DDI_FAILURE; 12390 break; 12391 } 12392 status = mptsas_diag_read_buffer(mpt, 12393 &diag_read_buffer, diag_action + 12394 sizeof (diag_read_buffer) - 4, return_code, 12395 ioctl_mode); 12396 if (status == DDI_SUCCESS) { 12397 if (ddi_copyout(&diag_read_buffer, diag_action, 12398 sizeof (diag_read_buffer) - 4, ioctl_mode) 12399 != 0) { 12400 return (DDI_FAILURE); 12401 } 12402 } 12403 break; 12404 12405 case MPTSAS_FW_DIAG_TYPE_RELEASE: 12406 if (length < sizeof (diag_release)) { 12407 *return_code = 12408 MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 12409 status = DDI_FAILURE; 12410 break; 12411 } 12412 if (ddi_copyin(diag_action, &diag_release, 12413 sizeof (diag_release), ioctl_mode) != 0) { 12414 return (DDI_FAILURE); 12415 } 12416 status = mptsas_diag_release(mpt, &diag_release, 12417 return_code); 12418 break; 12419 12420 default: 12421 *return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER; 12422 status = DDI_FAILURE; 12423 break; 12424 } 12425 12426 if ((status == DDI_FAILURE) && 12427 (original_return_code == MPTSAS_FW_DIAG_NEW) && 12428 (*return_code != MPTSAS_FW_DIAG_ERROR_SUCCESS)) { 12429 status = DDI_SUCCESS; 12430 } 12431 12432 return (status); 12433 } 12434 12435 static int 12436 mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *user_data, int mode) 12437 { 12438 int status; 12439 mptsas_diag_action_t driver_data; 12440 12441 ASSERT(mutex_owned(&mpt->m_mutex)); 12442 12443 /* 12444 * Copy the user data to a driver data buffer. 12445 */ 12446 if (ddi_copyin(user_data, &driver_data, sizeof (mptsas_diag_action_t), 12447 mode) == 0) { 12448 /* 12449 * Send diag action request if Action is valid 12450 */ 12451 if (driver_data.Action == MPTSAS_FW_DIAG_TYPE_REGISTER || 12452 driver_data.Action == MPTSAS_FW_DIAG_TYPE_UNREGISTER || 12453 driver_data.Action == MPTSAS_FW_DIAG_TYPE_QUERY || 12454 driver_data.Action == MPTSAS_FW_DIAG_TYPE_READ_BUFFER || 12455 driver_data.Action == MPTSAS_FW_DIAG_TYPE_RELEASE) { 12456 status = mptsas_do_diag_action(mpt, driver_data.Action, 12457 (void *)(uintptr_t)driver_data.PtrDiagAction, 12458 driver_data.Length, &driver_data.ReturnCode, 12459 mode); 12460 if (status == DDI_SUCCESS) { 12461 if (ddi_copyout(&driver_data.ReturnCode, 12462 &user_data->ReturnCode, 12463 sizeof (user_data->ReturnCode), mode) 12464 != 0) { 12465 status = EFAULT; 12466 } else { 12467 status = 0; 12468 } 12469 } else { 12470 status = EIO; 12471 } 12472 } else { 12473 status = EINVAL; 12474 } 12475 } else { 12476 status = EFAULT; 12477 } 12478 12479 return (status); 12480 } 12481 12482 /* 12483 * This routine handles the "event query" ioctl. 12484 */ 12485 static int 12486 mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, int mode, 12487 int *rval) 12488 { 12489 int status; 12490 mptsas_event_query_t driverdata; 12491 uint8_t i; 12492 12493 driverdata.Entries = MPTSAS_EVENT_QUEUE_SIZE; 12494 12495 mutex_enter(&mpt->m_mutex); 12496 for (i = 0; i < 4; i++) { 12497 driverdata.Types[i] = mpt->m_event_mask[i]; 12498 } 12499 mutex_exit(&mpt->m_mutex); 12500 12501 if (ddi_copyout(&driverdata, data, sizeof (driverdata), mode) != 0) { 12502 status = EFAULT; 12503 } else { 12504 *rval = MPTIOCTL_STATUS_GOOD; 12505 status = 0; 12506 } 12507 12508 return (status); 12509 } 12510 12511 /* 12512 * This routine handles the "event enable" ioctl. 12513 */ 12514 static int 12515 mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, int mode, 12516 int *rval) 12517 { 12518 int status; 12519 mptsas_event_enable_t driverdata; 12520 uint8_t i; 12521 12522 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) { 12523 mutex_enter(&mpt->m_mutex); 12524 for (i = 0; i < 4; i++) { 12525 mpt->m_event_mask[i] = driverdata.Types[i]; 12526 } 12527 mutex_exit(&mpt->m_mutex); 12528 12529 *rval = MPTIOCTL_STATUS_GOOD; 12530 status = 0; 12531 } else { 12532 status = EFAULT; 12533 } 12534 return (status); 12535 } 12536 12537 /* 12538 * This routine handles the "event report" ioctl. 12539 */ 12540 static int 12541 mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, int mode, 12542 int *rval) 12543 { 12544 int status; 12545 mptsas_event_report_t driverdata; 12546 12547 mutex_enter(&mpt->m_mutex); 12548 12549 if (ddi_copyin(&data->Size, &driverdata.Size, sizeof (driverdata.Size), 12550 mode) == 0) { 12551 if (driverdata.Size >= sizeof (mpt->m_events)) { 12552 if (ddi_copyout(mpt->m_events, data->Events, 12553 sizeof (mpt->m_events), mode) != 0) { 12554 status = EFAULT; 12555 } else { 12556 if (driverdata.Size > sizeof (mpt->m_events)) { 12557 driverdata.Size = 12558 sizeof (mpt->m_events); 12559 if (ddi_copyout(&driverdata.Size, 12560 &data->Size, 12561 sizeof (driverdata.Size), 12562 mode) != 0) { 12563 status = EFAULT; 12564 } else { 12565 *rval = MPTIOCTL_STATUS_GOOD; 12566 status = 0; 12567 } 12568 } else { 12569 *rval = MPTIOCTL_STATUS_GOOD; 12570 status = 0; 12571 } 12572 } 12573 } else { 12574 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT; 12575 status = 0; 12576 } 12577 } else { 12578 status = EFAULT; 12579 } 12580 12581 mutex_exit(&mpt->m_mutex); 12582 return (status); 12583 } 12584 12585 static void 12586 mptsas_lookup_pci_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data) 12587 { 12588 int *reg_data; 12589 uint_t reglen; 12590 12591 /* 12592 * Lookup the 'reg' property and extract the other data 12593 */ 12594 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip, 12595 DDI_PROP_DONTPASS, "reg", ®_data, ®len) == 12596 DDI_PROP_SUCCESS) { 12597 /* 12598 * Extract the PCI data from the 'reg' property first DWORD. 12599 * The entry looks like the following: 12600 * First DWORD: 12601 * Bits 0 - 7 8-bit Register number 12602 * Bits 8 - 10 3-bit Function number 12603 * Bits 11 - 15 5-bit Device number 12604 * Bits 16 - 23 8-bit Bus number 12605 * Bits 24 - 25 2-bit Address Space type identifier 12606 * 12607 */ 12608 adapter_data->PciInformation.u.bits.BusNumber = 12609 (reg_data[0] & 0x00FF0000) >> 16; 12610 adapter_data->PciInformation.u.bits.DeviceNumber = 12611 (reg_data[0] & 0x0000F800) >> 11; 12612 adapter_data->PciInformation.u.bits.FunctionNumber = 12613 (reg_data[0] & 0x00000700) >> 8; 12614 ddi_prop_free((void *)reg_data); 12615 } else { 12616 /* 12617 * If we can't determine the PCI data then we fill in FF's for 12618 * the data to indicate this. 12619 */ 12620 adapter_data->PCIDeviceHwId = 0xFFFFFFFF; 12621 adapter_data->MpiPortNumber = 0xFFFFFFFF; 12622 adapter_data->PciInformation.u.AsDWORD = 0xFFFFFFFF; 12623 } 12624 12625 /* 12626 * Saved in the mpt->m_fwversion 12627 */ 12628 adapter_data->MpiFirmwareVersion = mpt->m_fwversion; 12629 } 12630 12631 static void 12632 mptsas_read_adapter_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data) 12633 { 12634 char *driver_verstr = MPTSAS_MOD_STRING; 12635 12636 mptsas_lookup_pci_data(mpt, adapter_data); 12637 adapter_data->AdapterType = mpt->m_MPI25 ? 12638 MPTIOCTL_ADAPTER_TYPE_SAS3 : 12639 MPTIOCTL_ADAPTER_TYPE_SAS2; 12640 adapter_data->PCIDeviceHwId = (uint32_t)mpt->m_devid; 12641 adapter_data->PCIDeviceHwRev = (uint32_t)mpt->m_revid; 12642 adapter_data->SubSystemId = (uint32_t)mpt->m_ssid; 12643 adapter_data->SubsystemVendorId = (uint32_t)mpt->m_svid; 12644 (void) strcpy((char *)&adapter_data->DriverVersion[0], driver_verstr); 12645 adapter_data->BiosVersion = 0; 12646 (void) mptsas_get_bios_page3(mpt, &adapter_data->BiosVersion); 12647 } 12648 12649 static void 12650 mptsas_read_pci_info(mptsas_t *mpt, mptsas_pci_info_t *pci_info) 12651 { 12652 int *reg_data, i; 12653 uint_t reglen; 12654 12655 /* 12656 * Lookup the 'reg' property and extract the other data 12657 */ 12658 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip, 12659 DDI_PROP_DONTPASS, "reg", ®_data, ®len) == 12660 DDI_PROP_SUCCESS) { 12661 /* 12662 * Extract the PCI data from the 'reg' property first DWORD. 12663 * The entry looks like the following: 12664 * First DWORD: 12665 * Bits 8 - 10 3-bit Function number 12666 * Bits 11 - 15 5-bit Device number 12667 * Bits 16 - 23 8-bit Bus number 12668 */ 12669 pci_info->BusNumber = (reg_data[0] & 0x00FF0000) >> 16; 12670 pci_info->DeviceNumber = (reg_data[0] & 0x0000F800) >> 11; 12671 pci_info->FunctionNumber = (reg_data[0] & 0x00000700) >> 8; 12672 ddi_prop_free((void *)reg_data); 12673 } else { 12674 /* 12675 * If we can't determine the PCI info then we fill in FF's for 12676 * the data to indicate this. 12677 */ 12678 pci_info->BusNumber = 0xFFFFFFFF; 12679 pci_info->DeviceNumber = 0xFF; 12680 pci_info->FunctionNumber = 0xFF; 12681 } 12682 12683 /* 12684 * Now get the interrupt vector and the pci header. The vector can 12685 * only be 0 right now. The header is the first 256 bytes of config 12686 * space. 12687 */ 12688 pci_info->InterruptVector = 0; 12689 for (i = 0; i < sizeof (pci_info->PciHeader); i++) { 12690 pci_info->PciHeader[i] = pci_config_get8(mpt->m_config_handle, 12691 i); 12692 } 12693 } 12694 12695 static int 12696 mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, int mode) 12697 { 12698 int status = 0; 12699 mptsas_reg_access_t driverdata; 12700 12701 mutex_enter(&mpt->m_mutex); 12702 if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) { 12703 switch (driverdata.Command) { 12704 /* 12705 * IO access is not supported. 12706 */ 12707 case REG_IO_READ: 12708 case REG_IO_WRITE: 12709 mptsas_log(mpt, CE_WARN, "IO access is not " 12710 "supported. Use memory access."); 12711 status = EINVAL; 12712 break; 12713 12714 case REG_MEM_READ: 12715 driverdata.RegData = mptsas_hirrd(mpt, 12716 (uint32_t *)(void *)mpt->m_reg + 12717 driverdata.RegOffset); 12718 if (ddi_copyout(&driverdata.RegData, 12719 &data->RegData, 12720 sizeof (driverdata.RegData), mode) != 0) { 12721 mptsas_log(mpt, CE_WARN, "Register " 12722 "Read Failed"); 12723 status = EFAULT; 12724 } 12725 break; 12726 12727 case REG_MEM_WRITE: 12728 ddi_put32(mpt->m_datap, 12729 (uint32_t *)(void *)mpt->m_reg + 12730 driverdata.RegOffset, 12731 driverdata.RegData); 12732 break; 12733 12734 default: 12735 status = EINVAL; 12736 break; 12737 } 12738 } else { 12739 status = EFAULT; 12740 } 12741 12742 mutex_exit(&mpt->m_mutex); 12743 return (status); 12744 } 12745 12746 static int 12747 led_control(mptsas_t *mpt, intptr_t data, int mode) 12748 { 12749 int ret = 0; 12750 mptsas_led_control_t lc; 12751 mptsas_enclosure_t *mep; 12752 uint16_t slotidx; 12753 12754 if (ddi_copyin((void *)data, &lc, sizeof (lc), mode) != 0) { 12755 return (EFAULT); 12756 } 12757 12758 if ((lc.Command != MPTSAS_LEDCTL_FLAG_SET && 12759 lc.Command != MPTSAS_LEDCTL_FLAG_GET) || 12760 lc.Led < MPTSAS_LEDCTL_LED_MIN || 12761 lc.Led > MPTSAS_LEDCTL_LED_MAX || 12762 (lc.Command == MPTSAS_LEDCTL_FLAG_SET && lc.LedStatus != 0 && 12763 lc.LedStatus != 1)) { 12764 return (EINVAL); 12765 } 12766 12767 if ((lc.Command == MPTSAS_LEDCTL_FLAG_SET && (mode & FWRITE) == 0) || 12768 (lc.Command == MPTSAS_LEDCTL_FLAG_GET && (mode & FREAD) == 0)) 12769 return (EACCES); 12770 12771 /* Locate the required enclosure */ 12772 mutex_enter(&mpt->m_mutex); 12773 mep = mptsas_enc_lookup(mpt, lc.Enclosure); 12774 if (mep == NULL) { 12775 mutex_exit(&mpt->m_mutex); 12776 return (ENOENT); 12777 } 12778 12779 if (lc.Slot < mep->me_fslot) { 12780 mutex_exit(&mpt->m_mutex); 12781 return (ENOENT); 12782 } 12783 12784 /* 12785 * Slots on the enclosure are maintained in array where me_fslot is 12786 * entry zero. We normalize the requested slot. 12787 */ 12788 slotidx = lc.Slot - mep->me_fslot; 12789 if (slotidx >= mep->me_nslots) { 12790 mutex_exit(&mpt->m_mutex); 12791 return (ENOENT); 12792 } 12793 12794 if (lc.Command == MPTSAS_LEDCTL_FLAG_SET) { 12795 /* Update our internal LED state. */ 12796 mep->me_slotleds[slotidx] &= ~(1 << (lc.Led - 1)); 12797 mep->me_slotleds[slotidx] |= lc.LedStatus << (lc.Led - 1); 12798 12799 /* Flush it to the controller. */ 12800 ret = mptsas_flush_led_status(mpt, mep, slotidx); 12801 mutex_exit(&mpt->m_mutex); 12802 return (ret); 12803 } 12804 12805 /* Return our internal LED state. */ 12806 lc.LedStatus = (mep->me_slotleds[slotidx] >> (lc.Led - 1)) & 1; 12807 mutex_exit(&mpt->m_mutex); 12808 12809 if (ddi_copyout(&lc, (void *)data, sizeof (lc), mode) != 0) { 12810 return (EFAULT); 12811 } 12812 12813 return (0); 12814 } 12815 12816 static int 12817 get_disk_info(mptsas_t *mpt, intptr_t data, int mode) 12818 { 12819 uint16_t i = 0; 12820 uint16_t count = 0; 12821 int ret = 0; 12822 mptsas_target_t *ptgt; 12823 mptsas_disk_info_t *di; 12824 STRUCT_DECL(mptsas_get_disk_info, gdi); 12825 12826 if ((mode & FREAD) == 0) 12827 return (EACCES); 12828 12829 STRUCT_INIT(gdi, get_udatamodel()); 12830 12831 if (ddi_copyin((void *)data, STRUCT_BUF(gdi), STRUCT_SIZE(gdi), 12832 mode) != 0) { 12833 return (EFAULT); 12834 } 12835 12836 /* Find out how many targets there are. */ 12837 mutex_enter(&mpt->m_mutex); 12838 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 12839 ptgt = refhash_next(mpt->m_targets, ptgt)) { 12840 count++; 12841 } 12842 mutex_exit(&mpt->m_mutex); 12843 12844 /* 12845 * If we haven't been asked to copy out information on each target, 12846 * then just return the count. 12847 */ 12848 STRUCT_FSET(gdi, DiskCount, count); 12849 if (STRUCT_FGETP(gdi, PtrDiskInfoArray) == NULL) 12850 goto copy_out; 12851 12852 /* 12853 * If we haven't been given a large enough buffer to copy out into, 12854 * let the caller know. 12855 */ 12856 if (STRUCT_FGET(gdi, DiskInfoArraySize) < 12857 count * sizeof (mptsas_disk_info_t)) { 12858 ret = ENOSPC; 12859 goto copy_out; 12860 } 12861 12862 di = kmem_zalloc(count * sizeof (mptsas_disk_info_t), KM_SLEEP); 12863 12864 mutex_enter(&mpt->m_mutex); 12865 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 12866 ptgt = refhash_next(mpt->m_targets, ptgt)) { 12867 if (i >= count) { 12868 /* 12869 * The number of targets changed while we weren't 12870 * looking, so give up. 12871 */ 12872 refhash_rele(mpt->m_targets, ptgt); 12873 mutex_exit(&mpt->m_mutex); 12874 kmem_free(di, count * sizeof (mptsas_disk_info_t)); 12875 return (EAGAIN); 12876 } 12877 di[i].Instance = mpt->m_instance; 12878 di[i].Enclosure = ptgt->m_enclosure; 12879 di[i].Slot = ptgt->m_slot_num; 12880 di[i].SasAddress = ptgt->m_addr.mta_wwn; 12881 i++; 12882 } 12883 mutex_exit(&mpt->m_mutex); 12884 STRUCT_FSET(gdi, DiskCount, i); 12885 12886 /* Copy out the disk information to the caller. */ 12887 if (ddi_copyout((void *)di, STRUCT_FGETP(gdi, PtrDiskInfoArray), 12888 i * sizeof (mptsas_disk_info_t), mode) != 0) { 12889 ret = EFAULT; 12890 } 12891 12892 kmem_free(di, count * sizeof (mptsas_disk_info_t)); 12893 12894 copy_out: 12895 if (ddi_copyout(STRUCT_BUF(gdi), (void *)data, STRUCT_SIZE(gdi), 12896 mode) != 0) { 12897 ret = EFAULT; 12898 } 12899 12900 return (ret); 12901 } 12902 12903 static int 12904 mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp, 12905 int *rval) 12906 { 12907 int status = 0; 12908 mptsas_t *mpt; 12909 mptsas_update_flash_t flashdata; 12910 mptsas_pass_thru_t passthru_data; 12911 mptsas_adapter_data_t adapter_data; 12912 mptsas_pci_info_t pci_info; 12913 int copylen; 12914 12915 int iport_flag = 0; 12916 dev_info_t *dip = NULL; 12917 mptsas_phymask_t phymask = 0; 12918 struct devctl_iocdata *dcp = NULL; 12919 char *addr = NULL; 12920 mptsas_target_t *ptgt = NULL; 12921 12922 *rval = MPTIOCTL_STATUS_GOOD; 12923 if (secpolicy_sys_config(credp, B_FALSE) != 0) { 12924 return (EPERM); 12925 } 12926 12927 mpt = ddi_get_soft_state(mptsas_state, MINOR2INST(getminor(dev))); 12928 if (mpt == NULL) { 12929 /* 12930 * Called from iport node, get the states 12931 */ 12932 iport_flag = 1; 12933 dip = mptsas_get_dip_from_dev(dev, &phymask); 12934 if (dip == NULL) { 12935 return (ENXIO); 12936 } 12937 mpt = DIP2MPT(dip); 12938 } 12939 /* Make sure power level is D0 before accessing registers */ 12940 mutex_enter(&mpt->m_mutex); 12941 if (mpt->m_options & MPTSAS_OPT_PM) { 12942 (void) pm_busy_component(mpt->m_dip, 0); 12943 if (mpt->m_power_level != PM_LEVEL_D0) { 12944 mutex_exit(&mpt->m_mutex); 12945 if (pm_raise_power(mpt->m_dip, 0, PM_LEVEL_D0) != 12946 DDI_SUCCESS) { 12947 mptsas_log(mpt, CE_WARN, 12948 "mptsas%d: mptsas_ioctl: Raise power " 12949 "request failed.", mpt->m_instance); 12950 (void) pm_idle_component(mpt->m_dip, 0); 12951 return (ENXIO); 12952 } 12953 } else { 12954 mutex_exit(&mpt->m_mutex); 12955 } 12956 } else { 12957 mutex_exit(&mpt->m_mutex); 12958 } 12959 12960 if (iport_flag) { 12961 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, rval); 12962 if (status != 0) { 12963 goto out; 12964 } 12965 /* 12966 * The following code control the OK2RM LED, it doesn't affect 12967 * the ioctl return status. 12968 */ 12969 if ((cmd == DEVCTL_DEVICE_ONLINE) || 12970 (cmd == DEVCTL_DEVICE_OFFLINE)) { 12971 if (ndi_dc_allochdl((void *)data, &dcp) != 12972 NDI_SUCCESS) { 12973 goto out; 12974 } 12975 addr = ndi_dc_getaddr(dcp); 12976 ptgt = mptsas_addr_to_ptgt(mpt, addr, phymask); 12977 if (ptgt == NULL) { 12978 NDBG14(("mptsas_ioctl led control: tgt %s not " 12979 "found", addr)); 12980 ndi_dc_freehdl(dcp); 12981 goto out; 12982 } 12983 ndi_dc_freehdl(dcp); 12984 } 12985 goto out; 12986 } 12987 switch (cmd) { 12988 case MPTIOCTL_GET_DISK_INFO: 12989 status = get_disk_info(mpt, data, mode); 12990 break; 12991 case MPTIOCTL_LED_CONTROL: 12992 status = led_control(mpt, data, mode); 12993 break; 12994 case MPTIOCTL_UPDATE_FLASH: 12995 if (ddi_copyin((void *)data, &flashdata, 12996 sizeof (struct mptsas_update_flash), mode)) { 12997 status = EFAULT; 12998 break; 12999 } 13000 13001 mutex_enter(&mpt->m_mutex); 13002 if (mptsas_update_flash(mpt, 13003 (caddr_t)(long)flashdata.PtrBuffer, 13004 flashdata.ImageSize, flashdata.ImageType, mode)) { 13005 status = EFAULT; 13006 } 13007 13008 /* 13009 * Reset the chip to start using the new 13010 * firmware. Reset if failed also. 13011 */ 13012 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 13013 if (mptsas_restart_ioc(mpt) == DDI_FAILURE) { 13014 status = EFAULT; 13015 } 13016 mutex_exit(&mpt->m_mutex); 13017 break; 13018 case MPTIOCTL_PASS_THRU: 13019 /* 13020 * The user has requested to pass through a command to 13021 * be executed by the MPT firmware. Call our routine 13022 * which does this. Only allow one passthru IOCTL at 13023 * one time. Other threads will block on 13024 * m_passthru_mutex, which is of adaptive variant. 13025 */ 13026 if (ddi_copyin((void *)data, &passthru_data, 13027 sizeof (mptsas_pass_thru_t), mode)) { 13028 status = EFAULT; 13029 break; 13030 } 13031 mutex_enter(&mpt->m_passthru_mutex); 13032 mutex_enter(&mpt->m_mutex); 13033 status = mptsas_pass_thru(mpt, &passthru_data, mode); 13034 mutex_exit(&mpt->m_mutex); 13035 mutex_exit(&mpt->m_passthru_mutex); 13036 13037 break; 13038 case MPTIOCTL_GET_ADAPTER_DATA: 13039 /* 13040 * The user has requested to read adapter data. Call 13041 * our routine which does this. 13042 */ 13043 bzero(&adapter_data, sizeof (mptsas_adapter_data_t)); 13044 if (ddi_copyin((void *)data, (void *)&adapter_data, 13045 sizeof (mptsas_adapter_data_t), mode)) { 13046 status = EFAULT; 13047 break; 13048 } 13049 if (adapter_data.StructureLength >= 13050 sizeof (mptsas_adapter_data_t)) { 13051 adapter_data.StructureLength = (uint32_t) 13052 sizeof (mptsas_adapter_data_t); 13053 copylen = sizeof (mptsas_adapter_data_t); 13054 mutex_enter(&mpt->m_mutex); 13055 mptsas_read_adapter_data(mpt, &adapter_data); 13056 mutex_exit(&mpt->m_mutex); 13057 } else { 13058 adapter_data.StructureLength = (uint32_t) 13059 sizeof (mptsas_adapter_data_t); 13060 copylen = sizeof (adapter_data.StructureLength); 13061 *rval = MPTIOCTL_STATUS_LEN_TOO_SHORT; 13062 } 13063 if (ddi_copyout((void *)(&adapter_data), (void *)data, 13064 copylen, mode) != 0) { 13065 status = EFAULT; 13066 } 13067 break; 13068 case MPTIOCTL_GET_PCI_INFO: 13069 /* 13070 * The user has requested to read pci info. Call 13071 * our routine which does this. 13072 */ 13073 bzero(&pci_info, sizeof (mptsas_pci_info_t)); 13074 mutex_enter(&mpt->m_mutex); 13075 mptsas_read_pci_info(mpt, &pci_info); 13076 mutex_exit(&mpt->m_mutex); 13077 if (ddi_copyout((void *)(&pci_info), (void *)data, 13078 sizeof (mptsas_pci_info_t), mode) != 0) { 13079 status = EFAULT; 13080 } 13081 break; 13082 case MPTIOCTL_RESET_ADAPTER: 13083 mutex_enter(&mpt->m_mutex); 13084 mpt->m_softstate &= ~MPTSAS_SS_MSG_UNIT_RESET; 13085 if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) { 13086 mptsas_log(mpt, CE_WARN, "reset adapter IOCTL " 13087 "failed"); 13088 status = EFAULT; 13089 } 13090 mutex_exit(&mpt->m_mutex); 13091 break; 13092 case MPTIOCTL_DIAG_ACTION: 13093 /* 13094 * The user has done a diag buffer action. Call our 13095 * routine which does this. Only allow one diag action 13096 * at one time. 13097 */ 13098 mutex_enter(&mpt->m_mutex); 13099 if (mpt->m_diag_action_in_progress) { 13100 mutex_exit(&mpt->m_mutex); 13101 return (EBUSY); 13102 } 13103 mpt->m_diag_action_in_progress = 1; 13104 status = mptsas_diag_action(mpt, 13105 (mptsas_diag_action_t *)data, mode); 13106 mpt->m_diag_action_in_progress = 0; 13107 mutex_exit(&mpt->m_mutex); 13108 break; 13109 case MPTIOCTL_EVENT_QUERY: 13110 /* 13111 * The user has done an event query. Call our routine 13112 * which does this. 13113 */ 13114 status = mptsas_event_query(mpt, 13115 (mptsas_event_query_t *)data, mode, rval); 13116 break; 13117 case MPTIOCTL_EVENT_ENABLE: 13118 /* 13119 * The user has done an event enable. Call our routine 13120 * which does this. 13121 */ 13122 status = mptsas_event_enable(mpt, 13123 (mptsas_event_enable_t *)data, mode, rval); 13124 break; 13125 case MPTIOCTL_EVENT_REPORT: 13126 /* 13127 * The user has done an event report. Call our routine 13128 * which does this. 13129 */ 13130 status = mptsas_event_report(mpt, 13131 (mptsas_event_report_t *)data, mode, rval); 13132 break; 13133 case MPTIOCTL_REG_ACCESS: 13134 /* 13135 * The user has requested register access. Call our 13136 * routine which does this. 13137 */ 13138 status = mptsas_reg_access(mpt, 13139 (mptsas_reg_access_t *)data, mode); 13140 break; 13141 default: 13142 status = scsi_hba_ioctl(dev, cmd, data, mode, credp, 13143 rval); 13144 break; 13145 } 13146 13147 out: 13148 return (status); 13149 } 13150 13151 int 13152 mptsas_restart_ioc(mptsas_t *mpt) 13153 { 13154 int rval = DDI_SUCCESS; 13155 mptsas_target_t *ptgt = NULL; 13156 13157 ASSERT(mutex_owned(&mpt->m_mutex)); 13158 13159 /* 13160 * Set a flag telling I/O path that we're processing a reset. This is 13161 * needed because after the reset is complete, the hash table still 13162 * needs to be rebuilt. If I/Os are started before the hash table is 13163 * rebuilt, I/O errors will occur. This flag allows I/Os to be marked 13164 * so that they can be retried. 13165 */ 13166 mpt->m_in_reset = TRUE; 13167 13168 /* 13169 * Wait until all the allocated sense data buffers for DMA are freed. 13170 */ 13171 while (mpt->m_extreq_sense_refcount > 0) 13172 cv_wait(&mpt->m_extreq_sense_refcount_cv, &mpt->m_mutex); 13173 13174 /* 13175 * Set all throttles to HOLD 13176 */ 13177 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 13178 ptgt = refhash_next(mpt->m_targets, ptgt)) { 13179 mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE); 13180 } 13181 13182 /* 13183 * Disable interrupts 13184 */ 13185 MPTSAS_DISABLE_INTR(mpt); 13186 13187 /* 13188 * Abort all commands: outstanding commands, commands in waitq and 13189 * tx_waitq. 13190 */ 13191 mptsas_flush_hba(mpt); 13192 13193 /* 13194 * Reinitialize the chip. 13195 */ 13196 if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) { 13197 rval = DDI_FAILURE; 13198 } 13199 13200 /* 13201 * Enable interrupts again 13202 */ 13203 MPTSAS_ENABLE_INTR(mpt); 13204 13205 /* 13206 * If mptsas_init_chip was successful, update the driver data. 13207 */ 13208 if (rval == DDI_SUCCESS) { 13209 mptsas_update_driver_data(mpt); 13210 } 13211 13212 /* 13213 * Reset the throttles 13214 */ 13215 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 13216 ptgt = refhash_next(mpt->m_targets, ptgt)) { 13217 mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE); 13218 } 13219 13220 mptsas_doneq_empty(mpt); 13221 mptsas_restart_hba(mpt); 13222 13223 if (rval != DDI_SUCCESS) { 13224 mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE); 13225 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST); 13226 } 13227 13228 /* 13229 * Clear the reset flag so that I/Os can continue. 13230 */ 13231 mpt->m_in_reset = FALSE; 13232 13233 return (rval); 13234 } 13235 13236 static int 13237 mptsas_init_chip(mptsas_t *mpt, int first_time) 13238 { 13239 ddi_dma_cookie_t cookie; 13240 uint32_t i; 13241 int rval; 13242 13243 /* 13244 * Setup configuration space 13245 */ 13246 if (mptsas_config_space_init(mpt) == FALSE) { 13247 mptsas_log(mpt, CE_WARN, "mptsas_config_space_init " 13248 "failed!"); 13249 goto fail; 13250 } 13251 13252 /* 13253 * Check to see if the firmware image is valid 13254 */ 13255 if (mptsas_hirrd(mpt, &mpt->m_reg->HostDiagnostic) & 13256 MPI2_DIAG_FLASH_BAD_SIG) { 13257 mptsas_log(mpt, CE_WARN, "mptsas bad flash signature!"); 13258 goto fail; 13259 } 13260 13261 /* 13262 * Reset the chip 13263 */ 13264 rval = mptsas_ioc_reset(mpt, first_time); 13265 if (rval == MPTSAS_RESET_FAIL) { 13266 mptsas_log(mpt, CE_WARN, "hard reset failed!"); 13267 goto fail; 13268 } 13269 13270 if ((rval == MPTSAS_SUCCESS_MUR) && (!first_time)) { 13271 goto mur; 13272 } 13273 /* 13274 * IOC facts can change after a diag reset so all buffers that are 13275 * based on these numbers must be de-allocated and re-allocated. Get 13276 * new IOC facts each time chip is initialized. 13277 */ 13278 if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) { 13279 mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed"); 13280 goto fail; 13281 } 13282 13283 if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) { 13284 goto fail; 13285 } 13286 /* 13287 * Allocate request message frames, reply free queue, reply descriptor 13288 * post queue, and reply message frames using latest IOC facts. 13289 */ 13290 if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) { 13291 mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed"); 13292 goto fail; 13293 } 13294 if (mptsas_alloc_sense_bufs(mpt) == DDI_FAILURE) { 13295 mptsas_log(mpt, CE_WARN, "mptsas_alloc_sense_bufs failed"); 13296 goto fail; 13297 } 13298 if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) { 13299 mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue failed!"); 13300 goto fail; 13301 } 13302 if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) { 13303 mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue failed!"); 13304 goto fail; 13305 } 13306 if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) { 13307 mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames failed!"); 13308 goto fail; 13309 } 13310 13311 mur: 13312 /* 13313 * Re-Initialize ioc to operational state 13314 */ 13315 if (mptsas_ioc_init(mpt) == DDI_FAILURE) { 13316 mptsas_log(mpt, CE_WARN, "mptsas_ioc_init failed"); 13317 goto fail; 13318 } 13319 13320 mptsas_alloc_reply_args(mpt); 13321 13322 /* 13323 * Initialize reply post index. Reply free index is initialized after 13324 * the next loop. 13325 */ 13326 mpt->m_post_index = 0; 13327 13328 /* 13329 * Initialize the Reply Free Queue with the physical addresses of our 13330 * reply frames. 13331 */ 13332 cookie.dmac_address = mpt->m_reply_frame_dma_addr & 0xffffffffu; 13333 for (i = 0; i < mpt->m_max_replies; i++) { 13334 ddi_put32(mpt->m_acc_free_queue_hdl, 13335 &((uint32_t *)(void *)mpt->m_free_queue)[i], 13336 cookie.dmac_address); 13337 cookie.dmac_address += mpt->m_reply_frame_size; 13338 } 13339 (void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0, 13340 DDI_DMA_SYNC_FORDEV); 13341 13342 /* 13343 * Initialize the reply free index to one past the last frame on the 13344 * queue. This will signify that the queue is empty to start with. 13345 */ 13346 mpt->m_free_index = i; 13347 ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, i); 13348 13349 /* 13350 * Initialize the reply post queue to 0xFFFFFFFF,0xFFFFFFFF's. 13351 */ 13352 for (i = 0; i < mpt->m_post_queue_depth; i++) { 13353 ddi_put64(mpt->m_acc_post_queue_hdl, 13354 &((uint64_t *)(void *)mpt->m_post_queue)[i], 13355 0xFFFFFFFFFFFFFFFF); 13356 } 13357 (void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0, 13358 DDI_DMA_SYNC_FORDEV); 13359 13360 /* 13361 * Enable ports 13362 */ 13363 if (mptsas_ioc_enable_port(mpt) == DDI_FAILURE) { 13364 mptsas_log(mpt, CE_WARN, "mptsas_ioc_enable_port failed"); 13365 goto fail; 13366 } 13367 13368 /* 13369 * enable events 13370 */ 13371 if (mptsas_ioc_enable_event_notification(mpt)) { 13372 mptsas_log(mpt, CE_WARN, 13373 "mptsas_ioc_enable_event_notification failed"); 13374 goto fail; 13375 } 13376 13377 /* 13378 * We need checks in attach and these. 13379 * chip_init is called in mult. places 13380 */ 13381 13382 if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) != 13383 DDI_SUCCESS) || 13384 (mptsas_check_dma_handle(mpt->m_dma_req_sense_hdl) != 13385 DDI_SUCCESS) || 13386 (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) != 13387 DDI_SUCCESS) || 13388 (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) != 13389 DDI_SUCCESS) || 13390 (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) != 13391 DDI_SUCCESS) || 13392 (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) != 13393 DDI_SUCCESS)) { 13394 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 13395 goto fail; 13396 } 13397 13398 /* Check all acc handles */ 13399 if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) || 13400 (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) != 13401 DDI_SUCCESS) || 13402 (mptsas_check_acc_handle(mpt->m_acc_req_sense_hdl) != 13403 DDI_SUCCESS) || 13404 (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) != 13405 DDI_SUCCESS) || 13406 (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) != 13407 DDI_SUCCESS) || 13408 (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) != 13409 DDI_SUCCESS) || 13410 (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) != 13411 DDI_SUCCESS) || 13412 (mptsas_check_acc_handle(mpt->m_config_handle) != 13413 DDI_SUCCESS)) { 13414 ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED); 13415 goto fail; 13416 } 13417 13418 return (DDI_SUCCESS); 13419 13420 fail: 13421 return (DDI_FAILURE); 13422 } 13423 13424 static int 13425 mptsas_get_pci_cap(mptsas_t *mpt) 13426 { 13427 ushort_t caps_ptr, cap, cap_count; 13428 13429 if (mpt->m_config_handle == NULL) 13430 return (FALSE); 13431 /* 13432 * Check if capabilities list is supported and if so, 13433 * get initial capabilities pointer and clear bits 0,1. 13434 */ 13435 if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) 13436 & PCI_STAT_CAP) { 13437 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle, 13438 PCI_CONF_CAP_PTR), 4); 13439 } else { 13440 caps_ptr = PCI_CAP_NEXT_PTR_NULL; 13441 } 13442 13443 /* 13444 * Walk capabilities if supported. 13445 */ 13446 for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) { 13447 13448 /* 13449 * Check that we haven't exceeded the maximum number of 13450 * capabilities and that the pointer is in a valid range. 13451 */ 13452 if (++cap_count > 48) { 13453 mptsas_log(mpt, CE_WARN, 13454 "too many device capabilities.\n"); 13455 break; 13456 } 13457 if (caps_ptr < 64) { 13458 mptsas_log(mpt, CE_WARN, 13459 "capabilities pointer 0x%x out of range.\n", 13460 caps_ptr); 13461 break; 13462 } 13463 13464 /* 13465 * Get next capability and check that it is valid. 13466 * For now, we only support power management. 13467 */ 13468 cap = pci_config_get8(mpt->m_config_handle, caps_ptr); 13469 switch (cap) { 13470 case PCI_CAP_ID_PM: 13471 mptsas_log(mpt, CE_NOTE, 13472 "?mptsas%d supports power management.\n", 13473 mpt->m_instance); 13474 mpt->m_options |= MPTSAS_OPT_PM; 13475 13476 /* Save PMCSR offset */ 13477 mpt->m_pmcsr_offset = caps_ptr + PCI_PMCSR; 13478 break; 13479 /* 13480 * The following capabilities are valid. Any others 13481 * will cause a message to be logged. 13482 */ 13483 case PCI_CAP_ID_VPD: 13484 case PCI_CAP_ID_MSI: 13485 case PCI_CAP_ID_PCIX: 13486 case PCI_CAP_ID_PCI_E: 13487 case PCI_CAP_ID_MSI_X: 13488 break; 13489 default: 13490 mptsas_log(mpt, CE_NOTE, 13491 "?mptsas%d unrecognized capability " 13492 "0x%x.\n", mpt->m_instance, cap); 13493 break; 13494 } 13495 13496 /* 13497 * Get next capabilities pointer and clear bits 0,1. 13498 */ 13499 caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle, 13500 (caps_ptr + PCI_CAP_NEXT_PTR)), 4); 13501 } 13502 return (TRUE); 13503 } 13504 13505 static int 13506 mptsas_init_pm(mptsas_t *mpt) 13507 { 13508 char pmc_name[16]; 13509 char *pmc[] = { 13510 NULL, 13511 "0=Off (PCI D3 State)", 13512 "3=On (PCI D0 State)", 13513 NULL 13514 }; 13515 uint16_t pmcsr_stat; 13516 13517 if (mptsas_get_pci_cap(mpt) == FALSE) { 13518 return (DDI_FAILURE); 13519 } 13520 /* 13521 * If PCI's capability does not support PM, then don't need 13522 * to registe the pm-components 13523 */ 13524 if (!(mpt->m_options & MPTSAS_OPT_PM)) 13525 return (DDI_SUCCESS); 13526 /* 13527 * If power management is supported by this chip, create 13528 * pm-components property for the power management framework 13529 */ 13530 (void) sprintf(pmc_name, "NAME=mptsas%d", mpt->m_instance); 13531 pmc[0] = pmc_name; 13532 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, mpt->m_dip, 13533 "pm-components", pmc, 3) != DDI_PROP_SUCCESS) { 13534 mpt->m_options &= ~MPTSAS_OPT_PM; 13535 mptsas_log(mpt, CE_WARN, 13536 "mptsas%d: pm-component property creation failed.", 13537 mpt->m_instance); 13538 return (DDI_FAILURE); 13539 } 13540 13541 /* 13542 * Power on device. 13543 */ 13544 (void) pm_busy_component(mpt->m_dip, 0); 13545 pmcsr_stat = pci_config_get16(mpt->m_config_handle, 13546 mpt->m_pmcsr_offset); 13547 if ((pmcsr_stat & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_D0) { 13548 mptsas_log(mpt, CE_WARN, "mptsas%d: Power up the device", 13549 mpt->m_instance); 13550 pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset, 13551 PCI_PMCSR_D0); 13552 } 13553 if (pm_power_has_changed(mpt->m_dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) { 13554 mptsas_log(mpt, CE_WARN, "pm_power_has_changed failed"); 13555 return (DDI_FAILURE); 13556 } 13557 mpt->m_power_level = PM_LEVEL_D0; 13558 /* 13559 * Set pm idle delay. 13560 */ 13561 mpt->m_pm_idle_delay = ddi_prop_get_int(DDI_DEV_T_ANY, 13562 mpt->m_dip, 0, "mptsas-pm-idle-delay", MPTSAS_PM_IDLE_TIMEOUT); 13563 13564 return (DDI_SUCCESS); 13565 } 13566 13567 static int 13568 mptsas_register_intrs(mptsas_t *mpt) 13569 { 13570 dev_info_t *dip; 13571 int intr_types; 13572 13573 dip = mpt->m_dip; 13574 13575 /* Get supported interrupt types */ 13576 if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) { 13577 mptsas_log(mpt, CE_WARN, "ddi_intr_get_supported_types " 13578 "failed\n"); 13579 return (FALSE); 13580 } 13581 13582 NDBG6(("ddi_intr_get_supported_types() returned: 0x%x", intr_types)); 13583 13584 /* 13585 * Try MSI, but fall back to FIXED 13586 */ 13587 if (mptsas_enable_msi && (intr_types & DDI_INTR_TYPE_MSI)) { 13588 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_MSI) == DDI_SUCCESS) { 13589 NDBG0(("Using MSI interrupt type")); 13590 mpt->m_intr_type = DDI_INTR_TYPE_MSI; 13591 return (TRUE); 13592 } 13593 } 13594 if (intr_types & DDI_INTR_TYPE_FIXED) { 13595 if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_FIXED) == DDI_SUCCESS) { 13596 NDBG0(("Using FIXED interrupt type")); 13597 mpt->m_intr_type = DDI_INTR_TYPE_FIXED; 13598 return (TRUE); 13599 } else { 13600 NDBG0(("FIXED interrupt registration failed")); 13601 return (FALSE); 13602 } 13603 } 13604 13605 return (FALSE); 13606 } 13607 13608 static void 13609 mptsas_unregister_intrs(mptsas_t *mpt) 13610 { 13611 mptsas_rem_intrs(mpt); 13612 } 13613 13614 /* 13615 * mptsas_add_intrs: 13616 * 13617 * Register FIXED or MSI interrupts. 13618 */ 13619 static int 13620 mptsas_add_intrs(mptsas_t *mpt, int intr_type) 13621 { 13622 dev_info_t *dip = mpt->m_dip; 13623 int avail, actual, count = 0; 13624 int i, flag, ret; 13625 13626 NDBG6(("mptsas_add_intrs:interrupt type 0x%x", intr_type)); 13627 13628 /* Get number of interrupts */ 13629 ret = ddi_intr_get_nintrs(dip, intr_type, &count); 13630 if ((ret != DDI_SUCCESS) || (count <= 0)) { 13631 mptsas_log(mpt, CE_WARN, "ddi_intr_get_nintrs() failed, " 13632 "ret %d count %d\n", ret, count); 13633 13634 return (DDI_FAILURE); 13635 } 13636 13637 /* Get number of available interrupts */ 13638 ret = ddi_intr_get_navail(dip, intr_type, &avail); 13639 if ((ret != DDI_SUCCESS) || (avail == 0)) { 13640 mptsas_log(mpt, CE_WARN, "ddi_intr_get_navail() failed, " 13641 "ret %d avail %d\n", ret, avail); 13642 13643 return (DDI_FAILURE); 13644 } 13645 13646 if (avail < count) { 13647 mptsas_log(mpt, CE_NOTE, "ddi_intr_get_nvail returned %d, " 13648 "navail() returned %d", count, avail); 13649 } 13650 13651 /* Mpt only have one interrupt routine */ 13652 if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) { 13653 count = 1; 13654 } 13655 13656 /* Allocate an array of interrupt handles */ 13657 mpt->m_intr_size = count * sizeof (ddi_intr_handle_t); 13658 mpt->m_htable = kmem_alloc(mpt->m_intr_size, KM_SLEEP); 13659 13660 flag = DDI_INTR_ALLOC_NORMAL; 13661 13662 /* call ddi_intr_alloc() */ 13663 ret = ddi_intr_alloc(dip, mpt->m_htable, intr_type, 0, 13664 count, &actual, flag); 13665 13666 if ((ret != DDI_SUCCESS) || (actual == 0)) { 13667 mptsas_log(mpt, CE_WARN, "ddi_intr_alloc() failed, ret %d\n", 13668 ret); 13669 kmem_free(mpt->m_htable, mpt->m_intr_size); 13670 return (DDI_FAILURE); 13671 } 13672 13673 /* use interrupt count returned or abort? */ 13674 if (actual < count) { 13675 mptsas_log(mpt, CE_NOTE, "Requested: %d, Received: %d\n", 13676 count, actual); 13677 } 13678 13679 mpt->m_intr_cnt = actual; 13680 13681 /* 13682 * Get priority for first msi, assume remaining are all the same 13683 */ 13684 if ((ret = ddi_intr_get_pri(mpt->m_htable[0], 13685 &mpt->m_intr_pri)) != DDI_SUCCESS) { 13686 mptsas_log(mpt, CE_WARN, "ddi_intr_get_pri() failed %d\n", ret); 13687 13688 /* Free already allocated intr */ 13689 for (i = 0; i < actual; i++) { 13690 (void) ddi_intr_free(mpt->m_htable[i]); 13691 } 13692 13693 kmem_free(mpt->m_htable, mpt->m_intr_size); 13694 return (DDI_FAILURE); 13695 } 13696 13697 /* Test for high level mutex */ 13698 if (mpt->m_intr_pri >= ddi_intr_get_hilevel_pri()) { 13699 mptsas_log(mpt, CE_WARN, "mptsas_add_intrs: " 13700 "Hi level interrupt not supported\n"); 13701 13702 /* Free already allocated intr */ 13703 for (i = 0; i < actual; i++) { 13704 (void) ddi_intr_free(mpt->m_htable[i]); 13705 } 13706 13707 kmem_free(mpt->m_htable, mpt->m_intr_size); 13708 return (DDI_FAILURE); 13709 } 13710 13711 /* Call ddi_intr_add_handler() */ 13712 for (i = 0; i < actual; i++) { 13713 if ((ret = ddi_intr_add_handler(mpt->m_htable[i], mptsas_intr, 13714 (caddr_t)mpt, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) { 13715 mptsas_log(mpt, CE_WARN, "ddi_intr_add_handler() " 13716 "failed %d\n", ret); 13717 13718 /* Free already allocated intr */ 13719 for (i = 0; i < actual; i++) { 13720 (void) ddi_intr_free(mpt->m_htable[i]); 13721 } 13722 13723 kmem_free(mpt->m_htable, mpt->m_intr_size); 13724 return (DDI_FAILURE); 13725 } 13726 } 13727 13728 if ((ret = ddi_intr_get_cap(mpt->m_htable[0], &mpt->m_intr_cap)) 13729 != DDI_SUCCESS) { 13730 mptsas_log(mpt, CE_WARN, "ddi_intr_get_cap() failed %d\n", ret); 13731 13732 /* Free already allocated intr */ 13733 for (i = 0; i < actual; i++) { 13734 (void) ddi_intr_free(mpt->m_htable[i]); 13735 } 13736 13737 kmem_free(mpt->m_htable, mpt->m_intr_size); 13738 return (DDI_FAILURE); 13739 } 13740 13741 /* 13742 * Enable interrupts 13743 */ 13744 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) { 13745 /* Call ddi_intr_block_enable() for MSI interrupts */ 13746 (void) ddi_intr_block_enable(mpt->m_htable, mpt->m_intr_cnt); 13747 } else { 13748 /* Call ddi_intr_enable for MSI or FIXED interrupts */ 13749 for (i = 0; i < mpt->m_intr_cnt; i++) { 13750 (void) ddi_intr_enable(mpt->m_htable[i]); 13751 } 13752 } 13753 return (DDI_SUCCESS); 13754 } 13755 13756 /* 13757 * mptsas_rem_intrs: 13758 * 13759 * Unregister FIXED or MSI interrupts 13760 */ 13761 static void 13762 mptsas_rem_intrs(mptsas_t *mpt) 13763 { 13764 int i; 13765 13766 NDBG6(("mptsas_rem_intrs")); 13767 13768 /* Disable all interrupts */ 13769 if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) { 13770 /* Call ddi_intr_block_disable() */ 13771 (void) ddi_intr_block_disable(mpt->m_htable, mpt->m_intr_cnt); 13772 } else { 13773 for (i = 0; i < mpt->m_intr_cnt; i++) { 13774 (void) ddi_intr_disable(mpt->m_htable[i]); 13775 } 13776 } 13777 13778 /* Call ddi_intr_remove_handler() */ 13779 for (i = 0; i < mpt->m_intr_cnt; i++) { 13780 (void) ddi_intr_remove_handler(mpt->m_htable[i]); 13781 (void) ddi_intr_free(mpt->m_htable[i]); 13782 } 13783 13784 kmem_free(mpt->m_htable, mpt->m_intr_size); 13785 } 13786 13787 /* 13788 * The IO fault service error handling callback function 13789 */ 13790 /*ARGSUSED*/ 13791 static int 13792 mptsas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data) 13793 { 13794 /* 13795 * as the driver can always deal with an error in any dma or 13796 * access handle, we can just return the fme_status value. 13797 */ 13798 pci_ereport_post(dip, err, NULL); 13799 return (err->fme_status); 13800 } 13801 13802 /* 13803 * mptsas_fm_init - initialize fma capabilities and register with IO 13804 * fault services. 13805 */ 13806 static void 13807 mptsas_fm_init(mptsas_t *mpt) 13808 { 13809 /* 13810 * Need to change iblock to priority for new MSI intr 13811 */ 13812 ddi_iblock_cookie_t fm_ibc; 13813 13814 /* Only register with IO Fault Services if we have some capability */ 13815 if (mpt->m_fm_capabilities) { 13816 /* Adjust access and dma attributes for FMA */ 13817 mpt->m_reg_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC; 13818 mpt->m_msg_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 13819 mpt->m_io_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR; 13820 13821 /* 13822 * Register capabilities with IO Fault Services. 13823 * mpt->m_fm_capabilities will be updated to indicate 13824 * capabilities actually supported (not requested.) 13825 */ 13826 ddi_fm_init(mpt->m_dip, &mpt->m_fm_capabilities, &fm_ibc); 13827 13828 /* 13829 * Initialize pci ereport capabilities if ereport 13830 * capable (should always be.) 13831 */ 13832 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) || 13833 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 13834 pci_ereport_setup(mpt->m_dip); 13835 } 13836 13837 /* 13838 * Register error callback if error callback capable. 13839 */ 13840 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 13841 ddi_fm_handler_register(mpt->m_dip, 13842 mptsas_fm_error_cb, (void *) mpt); 13843 } 13844 } 13845 } 13846 13847 /* 13848 * mptsas_fm_fini - Releases fma capabilities and un-registers with IO 13849 * fault services. 13850 * 13851 */ 13852 static void 13853 mptsas_fm_fini(mptsas_t *mpt) 13854 { 13855 /* Only unregister FMA capabilities if registered */ 13856 if (mpt->m_fm_capabilities) { 13857 13858 /* 13859 * Un-register error callback if error callback capable. 13860 */ 13861 13862 if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 13863 ddi_fm_handler_unregister(mpt->m_dip); 13864 } 13865 13866 /* 13867 * Release any resources allocated by pci_ereport_setup() 13868 */ 13869 13870 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) || 13871 DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) { 13872 pci_ereport_teardown(mpt->m_dip); 13873 } 13874 13875 /* Unregister from IO Fault Services */ 13876 ddi_fm_fini(mpt->m_dip); 13877 13878 /* Adjust access and dma attributes for FMA */ 13879 mpt->m_reg_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC; 13880 mpt->m_msg_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 13881 mpt->m_io_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR; 13882 13883 } 13884 } 13885 13886 int 13887 mptsas_check_acc_handle(ddi_acc_handle_t handle) 13888 { 13889 ddi_fm_error_t de; 13890 13891 if (handle == NULL) 13892 return (DDI_FAILURE); 13893 ddi_fm_acc_err_get(handle, &de, DDI_FME_VER0); 13894 return (de.fme_status); 13895 } 13896 13897 int 13898 mptsas_check_dma_handle(ddi_dma_handle_t handle) 13899 { 13900 ddi_fm_error_t de; 13901 13902 if (handle == NULL) 13903 return (DDI_FAILURE); 13904 ddi_fm_dma_err_get(handle, &de, DDI_FME_VER0); 13905 return (de.fme_status); 13906 } 13907 13908 void 13909 mptsas_fm_ereport(mptsas_t *mpt, char *detail) 13910 { 13911 uint64_t ena; 13912 char buf[FM_MAX_CLASS]; 13913 13914 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail); 13915 ena = fm_ena_generate(0, FM_ENA_FMT1); 13916 if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities)) { 13917 ddi_fm_ereport_post(mpt->m_dip, buf, ena, DDI_NOSLEEP, 13918 FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL); 13919 } 13920 } 13921 13922 static int 13923 mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address, 13924 uint16_t *dev_handle, mptsas_target_t **pptgt) 13925 { 13926 int rval; 13927 uint32_t dev_info; 13928 uint64_t sas_wwn; 13929 mptsas_phymask_t phymask; 13930 uint8_t physport, phynum, config, disk; 13931 uint64_t devicename; 13932 uint16_t pdev_hdl; 13933 mptsas_target_t *tmp_tgt = NULL; 13934 uint16_t bay_num, enclosure, io_flags; 13935 13936 ASSERT(*pptgt == NULL); 13937 13938 rval = mptsas_get_sas_device_page0(mpt, page_address, dev_handle, 13939 &sas_wwn, &dev_info, &physport, &phynum, &pdev_hdl, 13940 &bay_num, &enclosure, &io_flags); 13941 if (rval != DDI_SUCCESS) { 13942 rval = DEV_INFO_FAIL_PAGE0; 13943 return (rval); 13944 } 13945 13946 if ((dev_info & (MPI2_SAS_DEVICE_INFO_SSP_TARGET | 13947 MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 13948 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) == 0) { 13949 rval = DEV_INFO_WRONG_DEVICE_TYPE; 13950 return (rval); 13951 } 13952 13953 /* 13954 * Check if the dev handle is for a Phys Disk. If so, set return value 13955 * and exit. Don't add Phys Disks to hash. 13956 */ 13957 for (config = 0; config < mpt->m_num_raid_configs; config++) { 13958 for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) { 13959 if (*dev_handle == mpt->m_raidconfig[config]. 13960 m_physdisk_devhdl[disk]) { 13961 rval = DEV_INFO_PHYS_DISK; 13962 return (rval); 13963 } 13964 } 13965 } 13966 13967 /* 13968 * Get SATA Device Name from SAS device page0 for 13969 * sata device, if device name doesn't exist, set mta_wwn to 13970 * 0 for direct attached SATA. For the device behind the expander 13971 * we still can use STP address assigned by expander. 13972 */ 13973 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 13974 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 13975 /* alloc a temporary target to send the cmd to */ 13976 tmp_tgt = mptsas_tgt_alloc(mpt->m_tmp_targets, *dev_handle, 13977 0, dev_info, 0, 0); 13978 mutex_exit(&mpt->m_mutex); 13979 13980 devicename = mptsas_get_sata_guid(mpt, tmp_tgt, 0); 13981 13982 if (devicename == -1) { 13983 mutex_enter(&mpt->m_mutex); 13984 refhash_remove(mpt->m_tmp_targets, tmp_tgt); 13985 rval = DEV_INFO_FAIL_GUID; 13986 return (rval); 13987 } 13988 13989 if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) { 13990 sas_wwn = devicename; 13991 } else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) { 13992 sas_wwn = 0; 13993 } 13994 13995 mutex_enter(&mpt->m_mutex); 13996 refhash_remove(mpt->m_tmp_targets, tmp_tgt); 13997 } 13998 13999 phymask = mptsas_physport_to_phymask(mpt, physport); 14000 *pptgt = mptsas_tgt_alloc(mpt->m_targets, *dev_handle, sas_wwn, 14001 dev_info, phymask, phynum); 14002 if (*pptgt == NULL) { 14003 mptsas_log(mpt, CE_WARN, "Failed to allocated target" 14004 "structure!"); 14005 rval = DEV_INFO_FAIL_ALLOC; 14006 return (rval); 14007 } 14008 (*pptgt)->m_io_flags = io_flags; 14009 (*pptgt)->m_enclosure = enclosure; 14010 (*pptgt)->m_slot_num = bay_num; 14011 return (DEV_INFO_SUCCESS); 14012 } 14013 14014 uint64_t 14015 mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun) 14016 { 14017 uint64_t sata_guid = 0, *pwwn = NULL; 14018 int target = ptgt->m_devhdl; 14019 uchar_t *inq83 = NULL; 14020 int inq83_len = 0xFF; 14021 uchar_t *dblk = NULL; 14022 int inq83_retry = 3; 14023 int rval = DDI_FAILURE; 14024 14025 inq83 = kmem_zalloc(inq83_len, KM_SLEEP); 14026 14027 inq83_retry: 14028 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83, 14029 inq83_len, NULL, 1); 14030 if (rval != DDI_SUCCESS) { 14031 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 14032 "0x83 for target:%x, lun:%x failed!", target, lun); 14033 sata_guid = -1; 14034 goto out; 14035 } 14036 /* According to SAT2, the first descriptor is logic unit name */ 14037 dblk = &inq83[4]; 14038 if ((dblk[1] & 0x30) != 0) { 14039 mptsas_log(mpt, CE_WARN, "!Descriptor is not lun associated."); 14040 goto out; 14041 } 14042 pwwn = (uint64_t *)(void *)(&dblk[4]); 14043 if ((dblk[4] & 0xf0) == 0x50) { 14044 sata_guid = BE_64(*pwwn); 14045 goto out; 14046 } else if (dblk[4] == 'A') { 14047 NDBG20(("SATA drive has no NAA format GUID.")); 14048 goto out; 14049 } else { 14050 /* The data is not ready, wait and retry */ 14051 inq83_retry--; 14052 if (inq83_retry <= 0) { 14053 goto out; 14054 } 14055 NDBG20(("The GUID is not ready, retry...")); 14056 delay(1 * drv_usectohz(1000000)); 14057 goto inq83_retry; 14058 } 14059 out: 14060 kmem_free(inq83, inq83_len); 14061 return (sata_guid); 14062 } 14063 14064 static int 14065 mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, uchar_t page, 14066 unsigned char *buf, int len, int *reallen, uchar_t evpd) 14067 { 14068 uchar_t cdb[CDB_GROUP0]; 14069 struct scsi_address ap; 14070 struct buf *data_bp = NULL; 14071 int resid = 0; 14072 int ret = DDI_FAILURE; 14073 14074 ASSERT(len <= 0xffff); 14075 14076 ap.a_target = MPTSAS_INVALID_DEVHDL; 14077 ap.a_lun = (uchar_t)(lun); 14078 ap.a_hba_tran = mpt->m_tran; 14079 14080 data_bp = scsi_alloc_consistent_buf(&ap, 14081 (struct buf *)NULL, len, B_READ, NULL_FUNC, NULL); 14082 if (data_bp == NULL) { 14083 return (ret); 14084 } 14085 bzero(cdb, CDB_GROUP0); 14086 cdb[0] = SCMD_INQUIRY; 14087 cdb[1] = evpd; 14088 cdb[2] = page; 14089 cdb[3] = (len & 0xff00) >> 8; 14090 cdb[4] = (len & 0x00ff); 14091 cdb[5] = 0; 14092 14093 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP0, data_bp, 14094 &resid); 14095 if (ret == DDI_SUCCESS) { 14096 if (reallen) { 14097 *reallen = len - resid; 14098 } 14099 bcopy((caddr_t)data_bp->b_un.b_addr, buf, len); 14100 } 14101 if (data_bp) { 14102 scsi_free_consistent_buf(data_bp); 14103 } 14104 return (ret); 14105 } 14106 14107 static int 14108 mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap, 14109 mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp, 14110 int *resid) 14111 { 14112 struct scsi_pkt *pktp = NULL; 14113 scsi_hba_tran_t *tran_clone = NULL; 14114 mptsas_tgt_private_t *tgt_private = NULL; 14115 int ret = DDI_FAILURE; 14116 14117 /* 14118 * scsi_hba_tran_t->tran_tgt_private is used to pass the address 14119 * information to scsi_init_pkt, allocate a scsi_hba_tran structure 14120 * to simulate the cmds from sd 14121 */ 14122 tran_clone = kmem_alloc( 14123 sizeof (scsi_hba_tran_t), KM_SLEEP); 14124 if (tran_clone == NULL) { 14125 goto out; 14126 } 14127 bcopy((caddr_t)mpt->m_tran, 14128 (caddr_t)tran_clone, sizeof (scsi_hba_tran_t)); 14129 tgt_private = kmem_alloc( 14130 sizeof (mptsas_tgt_private_t), KM_SLEEP); 14131 if (tgt_private == NULL) { 14132 goto out; 14133 } 14134 tgt_private->t_lun = ap->a_lun; 14135 tgt_private->t_private = ptgt; 14136 tran_clone->tran_tgt_private = tgt_private; 14137 ap->a_hba_tran = tran_clone; 14138 14139 pktp = scsi_init_pkt(ap, (struct scsi_pkt *)NULL, 14140 data_bp, cdblen, sizeof (struct scsi_arq_status), 14141 0, PKT_CONSISTENT, NULL, NULL); 14142 if (pktp == NULL) { 14143 goto out; 14144 } 14145 bcopy(cdb, pktp->pkt_cdbp, cdblen); 14146 pktp->pkt_flags = FLAG_NOPARITY; 14147 if (scsi_poll(pktp) < 0) { 14148 goto out; 14149 } 14150 if (((struct scsi_status *)pktp->pkt_scbp)->sts_chk) { 14151 goto out; 14152 } 14153 if (resid != NULL) { 14154 *resid = pktp->pkt_resid; 14155 } 14156 14157 ret = DDI_SUCCESS; 14158 out: 14159 if (pktp) { 14160 scsi_destroy_pkt(pktp); 14161 } 14162 if (tran_clone) { 14163 kmem_free(tran_clone, sizeof (scsi_hba_tran_t)); 14164 } 14165 if (tgt_private) { 14166 kmem_free(tgt_private, sizeof (mptsas_tgt_private_t)); 14167 } 14168 return (ret); 14169 } 14170 static int 14171 mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, int *lun) 14172 { 14173 char *cp = NULL; 14174 char *ptr = NULL; 14175 size_t s = 0; 14176 char *wwid_str = NULL; 14177 char *lun_str = NULL; 14178 long lunnum; 14179 long phyid = -1; 14180 int rc = DDI_FAILURE; 14181 14182 ptr = name; 14183 ASSERT(ptr[0] == 'w' || ptr[0] == 'p'); 14184 ptr++; 14185 if ((cp = strchr(ptr, ',')) == NULL) { 14186 return (DDI_FAILURE); 14187 } 14188 14189 wwid_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14190 s = (uintptr_t)cp - (uintptr_t)ptr; 14191 14192 bcopy(ptr, wwid_str, s); 14193 wwid_str[s] = '\0'; 14194 14195 ptr = ++cp; 14196 14197 if ((cp = strchr(ptr, '\0')) == NULL) { 14198 goto out; 14199 } 14200 lun_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14201 s = (uintptr_t)cp - (uintptr_t)ptr; 14202 14203 bcopy(ptr, lun_str, s); 14204 lun_str[s] = '\0'; 14205 14206 if (name[0] == 'p') { 14207 rc = ddi_strtol(wwid_str, NULL, 0x10, &phyid); 14208 } else { 14209 rc = scsi_wwnstr_to_wwn(wwid_str, wwid); 14210 } 14211 if (rc != DDI_SUCCESS) 14212 goto out; 14213 14214 if (phyid != -1) { 14215 ASSERT(phyid < MPTSAS_MAX_PHYS); 14216 *phy = (uint8_t)phyid; 14217 } 14218 rc = ddi_strtol(lun_str, NULL, 0x10, &lunnum); 14219 if (rc != 0) 14220 goto out; 14221 14222 *lun = (int)lunnum; 14223 rc = DDI_SUCCESS; 14224 out: 14225 if (wwid_str) 14226 kmem_free(wwid_str, SCSI_MAXNAMELEN); 14227 if (lun_str) 14228 kmem_free(lun_str, SCSI_MAXNAMELEN); 14229 14230 return (rc); 14231 } 14232 14233 /* 14234 * mptsas_parse_smp_name() is to parse sas wwn string 14235 * which format is "wWWN" 14236 */ 14237 static int 14238 mptsas_parse_smp_name(char *name, uint64_t *wwn) 14239 { 14240 char *ptr = name; 14241 14242 if (*ptr != 'w') { 14243 return (DDI_FAILURE); 14244 } 14245 14246 ptr++; 14247 if (scsi_wwnstr_to_wwn(ptr, wwn)) { 14248 return (DDI_FAILURE); 14249 } 14250 return (DDI_SUCCESS); 14251 } 14252 14253 static int 14254 mptsas_bus_config(dev_info_t *pdip, uint_t flag, 14255 ddi_bus_config_op_t op, void *arg, dev_info_t **childp) 14256 { 14257 int ret = NDI_FAILURE; 14258 mptsas_t *mpt; 14259 char *ptr = NULL; 14260 char *devnm = NULL; 14261 uint64_t wwid = 0; 14262 uint8_t phy = 0xFF; 14263 int lun = 0; 14264 uint_t mflags = flag; 14265 int bconfig = TRUE; 14266 14267 if (scsi_hba_iport_unit_address(pdip) == 0) { 14268 return (DDI_FAILURE); 14269 } 14270 14271 mpt = DIP2MPT(pdip); 14272 if (!mpt) { 14273 return (DDI_FAILURE); 14274 } 14275 /* 14276 * Hold the nexus across the bus_config 14277 */ 14278 ndi_devi_enter(scsi_vhci_dip); 14279 ndi_devi_enter(pdip); 14280 switch (op) { 14281 case BUS_CONFIG_ONE: 14282 /* parse wwid/target name out of name given */ 14283 if ((ptr = strchr((char *)arg, '@')) == NULL) { 14284 ret = NDI_FAILURE; 14285 break; 14286 } 14287 ptr++; 14288 if (strncmp((char *)arg, "smp", 3) == 0) { 14289 /* 14290 * This is a SMP target device 14291 */ 14292 ret = mptsas_parse_smp_name(ptr, &wwid); 14293 if (ret != DDI_SUCCESS) { 14294 ret = NDI_FAILURE; 14295 break; 14296 } 14297 ret = mptsas_config_smp(pdip, wwid, childp); 14298 } else if ((ptr[0] == 'w') || (ptr[0] == 'p')) { 14299 /* 14300 * OBP could pass down a non-canonical form 14301 * bootpath without LUN part when LUN is 0. 14302 * So driver need adjust the string. 14303 */ 14304 if (strchr(ptr, ',') == NULL) { 14305 devnm = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 14306 (void) sprintf(devnm, "%s,0", (char *)arg); 14307 ptr = strchr(devnm, '@'); 14308 ptr++; 14309 } 14310 14311 /* 14312 * The device path is wWWID format and the device 14313 * is not SMP target device. 14314 */ 14315 ret = mptsas_parse_address(ptr, &wwid, &phy, &lun); 14316 if (ret != DDI_SUCCESS) { 14317 ret = NDI_FAILURE; 14318 break; 14319 } 14320 *childp = NULL; 14321 if (ptr[0] == 'w') { 14322 ret = mptsas_config_one_addr(pdip, wwid, 14323 lun, childp); 14324 } else if (ptr[0] == 'p') { 14325 ret = mptsas_config_one_phy(pdip, phy, lun, 14326 childp); 14327 } 14328 14329 /* 14330 * If this is CD/DVD device in OBP path, the 14331 * ndi_busop_bus_config can be skipped as config one 14332 * operation is done above. 14333 */ 14334 if ((ret == NDI_SUCCESS) && (*childp != NULL) && 14335 (strcmp(ddi_node_name(*childp), "cdrom") == 0) && 14336 (strncmp((char *)arg, "disk", 4) == 0)) { 14337 bconfig = FALSE; 14338 ndi_hold_devi(*childp); 14339 } 14340 } else { 14341 ret = NDI_FAILURE; 14342 break; 14343 } 14344 14345 /* 14346 * DDI group instructed us to use this flag. 14347 */ 14348 mflags |= NDI_MDI_FALLBACK; 14349 break; 14350 case BUS_CONFIG_DRIVER: 14351 case BUS_CONFIG_ALL: 14352 mptsas_config_all(pdip); 14353 ret = NDI_SUCCESS; 14354 break; 14355 default: 14356 ret = NDI_FAILURE; 14357 break; 14358 } 14359 14360 if ((ret == NDI_SUCCESS) && bconfig) { 14361 ret = ndi_busop_bus_config(pdip, mflags, op, 14362 (devnm == NULL) ? arg : devnm, childp, 0); 14363 } 14364 14365 ndi_devi_exit(pdip); 14366 ndi_devi_exit(scsi_vhci_dip); 14367 if (devnm != NULL) 14368 kmem_free(devnm, SCSI_MAXNAMELEN); 14369 return (ret); 14370 } 14371 14372 static int 14373 mptsas_probe_lun(dev_info_t *pdip, int lun, dev_info_t **dip, 14374 mptsas_target_t *ptgt) 14375 { 14376 int rval = DDI_FAILURE; 14377 struct scsi_inquiry *sd_inq = NULL; 14378 mptsas_t *mpt = DIP2MPT(pdip); 14379 14380 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP); 14381 14382 rval = mptsas_inquiry(mpt, ptgt, lun, 0, (uchar_t *)sd_inq, 14383 SUN_INQSIZE, 0, (uchar_t)0); 14384 14385 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) { 14386 rval = mptsas_create_lun(pdip, sd_inq, dip, ptgt, lun); 14387 } else { 14388 rval = DDI_FAILURE; 14389 } 14390 14391 kmem_free(sd_inq, SUN_INQSIZE); 14392 return (rval); 14393 } 14394 14395 static int 14396 mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun, 14397 dev_info_t **lundip) 14398 { 14399 int rval; 14400 mptsas_t *mpt = DIP2MPT(pdip); 14401 int phymask; 14402 mptsas_target_t *ptgt = NULL; 14403 14404 /* 14405 * Get the physical port associated to the iport 14406 */ 14407 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 14408 "phymask", 0); 14409 14410 ptgt = mptsas_wwid_to_ptgt(mpt, phymask, sasaddr); 14411 if (ptgt == NULL) { 14412 /* 14413 * didn't match any device by searching 14414 */ 14415 return (DDI_FAILURE); 14416 } 14417 /* 14418 * If the LUN already exists and the status is online, 14419 * we just return the pointer to dev_info_t directly. 14420 * For the mdi_pathinfo node, we'll handle it in 14421 * mptsas_create_virt_lun() 14422 * TODO should be also in mptsas_handle_dr 14423 */ 14424 14425 *lundip = mptsas_find_child_addr(pdip, sasaddr, lun); 14426 if (*lundip != NULL) { 14427 /* 14428 * TODO Another senario is, we hotplug the same disk 14429 * on the same slot, the devhdl changed, is this 14430 * possible? 14431 * tgt_private->t_private != ptgt 14432 */ 14433 if (sasaddr != ptgt->m_addr.mta_wwn) { 14434 /* 14435 * The device has changed although the devhdl is the 14436 * same (Enclosure mapping mode, change drive on the 14437 * same slot) 14438 */ 14439 return (DDI_FAILURE); 14440 } 14441 return (DDI_SUCCESS); 14442 } 14443 14444 if (phymask == 0) { 14445 /* 14446 * Configure IR volume 14447 */ 14448 rval = mptsas_config_raid(pdip, ptgt->m_devhdl, lundip); 14449 return (rval); 14450 } 14451 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt); 14452 14453 return (rval); 14454 } 14455 14456 static int 14457 mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun, 14458 dev_info_t **lundip) 14459 { 14460 int rval; 14461 mptsas_t *mpt = DIP2MPT(pdip); 14462 mptsas_phymask_t phymask; 14463 mptsas_target_t *ptgt = NULL; 14464 14465 /* 14466 * Get the physical port associated to the iport 14467 */ 14468 phymask = (mptsas_phymask_t)ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 14469 "phymask", 0); 14470 14471 ptgt = mptsas_phy_to_tgt(mpt, phymask, phy); 14472 if (ptgt == NULL) { 14473 /* 14474 * didn't match any device by searching 14475 */ 14476 return (DDI_FAILURE); 14477 } 14478 14479 /* 14480 * If the LUN already exists and the status is online, 14481 * we just return the pointer to dev_info_t directly. 14482 * For the mdi_pathinfo node, we'll handle it in 14483 * mptsas_create_virt_lun(). 14484 */ 14485 14486 *lundip = mptsas_find_child_phy(pdip, phy); 14487 if (*lundip != NULL) { 14488 return (DDI_SUCCESS); 14489 } 14490 14491 rval = mptsas_probe_lun(pdip, lun, lundip, ptgt); 14492 14493 return (rval); 14494 } 14495 14496 static int 14497 mptsas_retrieve_lundata(int lun_cnt, uint8_t *buf, uint16_t *lun_num, 14498 uint8_t *lun_addr_type) 14499 { 14500 uint32_t lun_idx = 0; 14501 14502 ASSERT(lun_num != NULL); 14503 ASSERT(lun_addr_type != NULL); 14504 14505 lun_idx = (lun_cnt + 1) * MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE; 14506 /* determine report luns addressing type */ 14507 switch (buf[lun_idx] & MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) { 14508 /* 14509 * Vendors in the field have been found to be concatenating 14510 * bus/target/lun to equal the complete lun value instead 14511 * of switching to flat space addressing 14512 */ 14513 /* 00b - peripheral device addressing method */ 14514 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_PERIPHERAL: 14515 /* FALLTHRU */ 14516 /* 10b - logical unit addressing method */ 14517 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT: 14518 /* FALLTHRU */ 14519 /* 01b - flat space addressing method */ 14520 case MPTSAS_SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE: 14521 /* byte0 bit0-5=msb lun byte1 bit0-7=lsb lun */ 14522 *lun_addr_type = (buf[lun_idx] & 14523 MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) >> 6; 14524 *lun_num = (buf[lun_idx] & 0x3F) << 8; 14525 *lun_num |= buf[lun_idx + 1]; 14526 return (DDI_SUCCESS); 14527 default: 14528 return (DDI_FAILURE); 14529 } 14530 } 14531 14532 static int 14533 mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt) 14534 { 14535 struct buf *repluns_bp = NULL; 14536 struct scsi_address ap; 14537 uchar_t cdb[CDB_GROUP5]; 14538 int ret = DDI_FAILURE; 14539 int retry = 0; 14540 int lun_list_len = 0; 14541 uint16_t lun_num = 0; 14542 uint8_t lun_addr_type = 0; 14543 uint32_t lun_cnt = 0; 14544 uint32_t lun_total = 0; 14545 dev_info_t *cdip = NULL; 14546 uint16_t *saved_repluns = NULL; 14547 char *buffer = NULL; 14548 int buf_len = 128; 14549 mptsas_t *mpt = DIP2MPT(pdip); 14550 uint64_t sas_wwn = 0; 14551 uint8_t phy = 0xFF; 14552 uint32_t dev_info = 0; 14553 14554 mutex_enter(&mpt->m_mutex); 14555 sas_wwn = ptgt->m_addr.mta_wwn; 14556 phy = ptgt->m_phynum; 14557 dev_info = ptgt->m_deviceinfo; 14558 mutex_exit(&mpt->m_mutex); 14559 14560 if (sas_wwn == 0) { 14561 /* 14562 * It's a SATA without Device Name 14563 * So don't try multi-LUNs 14564 */ 14565 if (mptsas_find_child_phy(pdip, phy)) { 14566 return (DDI_SUCCESS); 14567 } else { 14568 /* 14569 * need configure and create node 14570 */ 14571 return (DDI_FAILURE); 14572 } 14573 } 14574 14575 /* 14576 * WWN (SAS address or Device Name exist) 14577 */ 14578 if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 14579 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 14580 /* 14581 * SATA device with Device Name 14582 * So don't try multi-LUNs 14583 */ 14584 if (mptsas_find_child_addr(pdip, sas_wwn, 0)) { 14585 return (DDI_SUCCESS); 14586 } else { 14587 return (DDI_FAILURE); 14588 } 14589 } 14590 14591 do { 14592 ap.a_target = MPTSAS_INVALID_DEVHDL; 14593 ap.a_lun = 0; 14594 ap.a_hba_tran = mpt->m_tran; 14595 repluns_bp = scsi_alloc_consistent_buf(&ap, 14596 (struct buf *)NULL, buf_len, B_READ, NULL_FUNC, NULL); 14597 if (repluns_bp == NULL) { 14598 retry++; 14599 continue; 14600 } 14601 bzero(cdb, CDB_GROUP5); 14602 cdb[0] = SCMD_REPORT_LUNS; 14603 cdb[6] = (buf_len & 0xff000000) >> 24; 14604 cdb[7] = (buf_len & 0x00ff0000) >> 16; 14605 cdb[8] = (buf_len & 0x0000ff00) >> 8; 14606 cdb[9] = (buf_len & 0x000000ff); 14607 14608 ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP5, 14609 repluns_bp, NULL); 14610 if (ret != DDI_SUCCESS) { 14611 scsi_free_consistent_buf(repluns_bp); 14612 retry++; 14613 continue; 14614 } 14615 lun_list_len = BE_32(*(int *)((void *)( 14616 repluns_bp->b_un.b_addr))); 14617 if (buf_len >= lun_list_len + 8) { 14618 ret = DDI_SUCCESS; 14619 break; 14620 } 14621 scsi_free_consistent_buf(repluns_bp); 14622 buf_len = lun_list_len + 8; 14623 14624 } while (retry < 3); 14625 14626 if (ret != DDI_SUCCESS) 14627 return (ret); 14628 buffer = (char *)repluns_bp->b_un.b_addr; 14629 /* 14630 * find out the number of luns returned by the SCSI ReportLun call 14631 * and allocate buffer space 14632 */ 14633 lun_total = lun_list_len / MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE; 14634 saved_repluns = kmem_zalloc(sizeof (uint16_t) * lun_total, KM_SLEEP); 14635 if (saved_repluns == NULL) { 14636 scsi_free_consistent_buf(repluns_bp); 14637 return (DDI_FAILURE); 14638 } 14639 for (lun_cnt = 0; lun_cnt < lun_total; lun_cnt++) { 14640 if (mptsas_retrieve_lundata(lun_cnt, (uint8_t *)(buffer), 14641 &lun_num, &lun_addr_type) != DDI_SUCCESS) { 14642 continue; 14643 } 14644 saved_repluns[lun_cnt] = lun_num; 14645 if ((cdip = mptsas_find_child_addr(pdip, sas_wwn, lun_num)) != 14646 NULL) { 14647 ret = DDI_SUCCESS; 14648 } else { 14649 ret = mptsas_probe_lun(pdip, lun_num, &cdip, 14650 ptgt); 14651 } 14652 if ((ret == DDI_SUCCESS) && (cdip != NULL)) { 14653 (void) ndi_prop_remove(DDI_DEV_T_NONE, cdip, 14654 MPTSAS_DEV_GONE); 14655 } 14656 } 14657 mptsas_offline_missed_luns(pdip, saved_repluns, lun_total, ptgt); 14658 kmem_free(saved_repluns, sizeof (uint16_t) * lun_total); 14659 scsi_free_consistent_buf(repluns_bp); 14660 return (DDI_SUCCESS); 14661 } 14662 14663 static int 14664 mptsas_config_raid(dev_info_t *pdip, uint16_t target, dev_info_t **dip) 14665 { 14666 int rval = DDI_FAILURE; 14667 struct scsi_inquiry *sd_inq = NULL; 14668 mptsas_t *mpt = DIP2MPT(pdip); 14669 mptsas_target_t *ptgt = NULL; 14670 14671 mutex_enter(&mpt->m_mutex); 14672 ptgt = refhash_linear_search(mpt->m_targets, 14673 mptsas_target_eval_devhdl, &target); 14674 mutex_exit(&mpt->m_mutex); 14675 if (ptgt == NULL) { 14676 mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x " 14677 "not found.", target); 14678 return (rval); 14679 } 14680 14681 sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP); 14682 rval = mptsas_inquiry(mpt, ptgt, 0, 0, (uchar_t *)sd_inq, 14683 SUN_INQSIZE, 0, (uchar_t)0); 14684 14685 if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) { 14686 rval = mptsas_create_phys_lun(pdip, sd_inq, NULL, dip, ptgt, 14687 0); 14688 } else { 14689 rval = DDI_FAILURE; 14690 } 14691 14692 kmem_free(sd_inq, SUN_INQSIZE); 14693 return (rval); 14694 } 14695 14696 /* 14697 * configure all RAID volumes for virtual iport 14698 */ 14699 static void 14700 mptsas_config_all_viport(dev_info_t *pdip) 14701 { 14702 mptsas_t *mpt = DIP2MPT(pdip); 14703 int config, vol; 14704 int target; 14705 dev_info_t *lundip = NULL; 14706 14707 /* 14708 * Get latest RAID info and search for any Volume DevHandles. If any 14709 * are found, configure the volume. 14710 */ 14711 mutex_enter(&mpt->m_mutex); 14712 for (config = 0; config < mpt->m_num_raid_configs; config++) { 14713 for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) { 14714 if (mpt->m_raidconfig[config].m_raidvol[vol].m_israid 14715 == 1) { 14716 target = mpt->m_raidconfig[config]. 14717 m_raidvol[vol].m_raidhandle; 14718 mutex_exit(&mpt->m_mutex); 14719 (void) mptsas_config_raid(pdip, target, 14720 &lundip); 14721 mutex_enter(&mpt->m_mutex); 14722 } 14723 } 14724 } 14725 mutex_exit(&mpt->m_mutex); 14726 } 14727 14728 static void 14729 mptsas_offline_missed_luns(dev_info_t *pdip, uint16_t *repluns, 14730 int lun_cnt, mptsas_target_t *ptgt) 14731 { 14732 dev_info_t *child = NULL, *savechild = NULL; 14733 mdi_pathinfo_t *pip = NULL, *savepip = NULL; 14734 uint64_t sas_wwn, wwid; 14735 uint8_t phy; 14736 int lun; 14737 int i; 14738 int find; 14739 char *addr; 14740 char *nodename; 14741 mptsas_t *mpt = DIP2MPT(pdip); 14742 14743 mutex_enter(&mpt->m_mutex); 14744 wwid = ptgt->m_addr.mta_wwn; 14745 mutex_exit(&mpt->m_mutex); 14746 14747 child = ddi_get_child(pdip); 14748 while (child) { 14749 find = 0; 14750 savechild = child; 14751 child = ddi_get_next_sibling(child); 14752 14753 nodename = ddi_node_name(savechild); 14754 if (strcmp(nodename, "smp") == 0) { 14755 continue; 14756 } 14757 14758 addr = ddi_get_name_addr(savechild); 14759 if (addr == NULL) { 14760 continue; 14761 } 14762 14763 if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) != 14764 DDI_SUCCESS) { 14765 continue; 14766 } 14767 14768 if (wwid == sas_wwn) { 14769 for (i = 0; i < lun_cnt; i++) { 14770 if (repluns[i] == lun) { 14771 find = 1; 14772 break; 14773 } 14774 } 14775 } else { 14776 continue; 14777 } 14778 if (find == 0) { 14779 /* 14780 * The lun has not been there already 14781 */ 14782 (void) mptsas_offline_lun(pdip, savechild, NULL, 14783 NDI_DEVI_REMOVE); 14784 } 14785 } 14786 14787 pip = mdi_get_next_client_path(pdip, NULL); 14788 while (pip) { 14789 find = 0; 14790 savepip = pip; 14791 addr = MDI_PI(pip)->pi_addr; 14792 14793 pip = mdi_get_next_client_path(pdip, pip); 14794 14795 if (addr == NULL) { 14796 continue; 14797 } 14798 14799 if (mptsas_parse_address(addr, &sas_wwn, &phy, 14800 &lun) != DDI_SUCCESS) { 14801 continue; 14802 } 14803 14804 if (sas_wwn == wwid) { 14805 for (i = 0; i < lun_cnt; i++) { 14806 if (repluns[i] == lun) { 14807 find = 1; 14808 break; 14809 } 14810 } 14811 } else { 14812 continue; 14813 } 14814 14815 if (find == 0) { 14816 /* 14817 * The lun has not been there already 14818 */ 14819 (void) mptsas_offline_lun(pdip, NULL, savepip, 14820 NDI_DEVI_REMOVE); 14821 } 14822 } 14823 } 14824 14825 /* 14826 * If this enclosure doesn't exist in the enclosure list, add it. If it does, 14827 * update it. 14828 */ 14829 static void 14830 mptsas_enclosure_update(mptsas_t *mpt, mptsas_enclosure_t *mep) 14831 { 14832 mptsas_enclosure_t *m; 14833 14834 ASSERT(MUTEX_HELD(&mpt->m_mutex)); 14835 m = mptsas_enc_lookup(mpt, mep->me_enchdl); 14836 if (m != NULL) { 14837 uint8_t *ledp; 14838 m->me_flags = mep->me_flags; 14839 14840 14841 /* 14842 * If the number of slots and the first slot entry in the 14843 * enclosure has not changed, then we don't need to do anything 14844 * here. Otherwise, we need to allocate a new array for the LED 14845 * status of the slot. 14846 */ 14847 if (m->me_fslot == mep->me_fslot && 14848 m->me_nslots == mep->me_nslots) 14849 return; 14850 14851 /* 14852 * If the number of slots or the first slot has changed, it's 14853 * not clear that we're really in a place that we can continue 14854 * to honor the existing flags. 14855 */ 14856 if (mep->me_nslots > 0) { 14857 ledp = kmem_zalloc(sizeof (uint8_t) * mep->me_nslots, 14858 KM_SLEEP); 14859 } else { 14860 ledp = NULL; 14861 } 14862 14863 if (m->me_slotleds != NULL) { 14864 kmem_free(m->me_slotleds, sizeof (uint8_t) * 14865 m->me_nslots); 14866 } 14867 m->me_slotleds = ledp; 14868 m->me_fslot = mep->me_fslot; 14869 m->me_nslots = mep->me_nslots; 14870 return; 14871 } 14872 14873 m = kmem_zalloc(sizeof (*m), KM_SLEEP); 14874 m->me_enchdl = mep->me_enchdl; 14875 m->me_flags = mep->me_flags; 14876 m->me_nslots = mep->me_nslots; 14877 m->me_fslot = mep->me_fslot; 14878 if (m->me_nslots > 0) { 14879 m->me_slotleds = kmem_zalloc(sizeof (uint8_t) * mep->me_nslots, 14880 KM_SLEEP); 14881 /* 14882 * It may make sense to optionally flush all of the slots and/or 14883 * read the slot status flag here to synchronize between 14884 * ourselves and the card. So far, that hasn't been needed 14885 * annecdotally when enumerating something new. If we do, we 14886 * should kick that off in a taskq potentially. 14887 */ 14888 } 14889 list_insert_tail(&mpt->m_enclosures, m); 14890 } 14891 14892 static void 14893 mptsas_update_hashtab(struct mptsas *mpt) 14894 { 14895 uint32_t page_address; 14896 int rval = 0; 14897 uint16_t dev_handle; 14898 mptsas_target_t *ptgt = NULL; 14899 mptsas_smp_t smp_node; 14900 14901 /* 14902 * Get latest RAID info. 14903 */ 14904 (void) mptsas_get_raid_info(mpt); 14905 14906 dev_handle = mpt->m_smp_devhdl; 14907 while (mpt->m_done_traverse_smp == 0) { 14908 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL & 14909 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)dev_handle; 14910 if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node) 14911 != DDI_SUCCESS) { 14912 break; 14913 } 14914 mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl; 14915 (void) mptsas_smp_alloc(mpt, &smp_node); 14916 } 14917 14918 /* 14919 * Loop over enclosures so we can understand what's there. 14920 */ 14921 dev_handle = MPTSAS_INVALID_DEVHDL; 14922 while (mpt->m_done_traverse_enc == 0) { 14923 mptsas_enclosure_t me; 14924 14925 page_address = (MPI2_SAS_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE & 14926 MPI2_SAS_ENCLOS_PGAD_FORM_MASK) | (uint32_t)dev_handle; 14927 14928 if (mptsas_get_enclosure_page0(mpt, page_address, &me) != 14929 DDI_SUCCESS) { 14930 break; 14931 } 14932 dev_handle = me.me_enchdl; 14933 mptsas_enclosure_update(mpt, &me); 14934 } 14935 14936 /* 14937 * Config target devices 14938 */ 14939 dev_handle = mpt->m_dev_handle; 14940 14941 /* 14942 * Loop to get sas device page 0 by GetNextHandle till the 14943 * the last handle. If the sas device is a SATA/SSP target, 14944 * we try to config it. 14945 */ 14946 while (mpt->m_done_traverse_dev == 0) { 14947 ptgt = NULL; 14948 page_address = 14949 (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 14950 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 14951 (uint32_t)dev_handle; 14952 rval = mptsas_get_target_device_info(mpt, page_address, 14953 &dev_handle, &ptgt); 14954 if ((rval == DEV_INFO_FAIL_PAGE0) || 14955 (rval == DEV_INFO_FAIL_ALLOC)) { 14956 break; 14957 } 14958 if (rval == DEV_INFO_FAIL_GUID) { 14959 continue; 14960 } 14961 14962 mpt->m_dev_handle = dev_handle; 14963 } 14964 14965 } 14966 14967 void 14968 mptsas_update_driver_data(struct mptsas *mpt) 14969 { 14970 mptsas_target_t *tp; 14971 mptsas_smp_t *sp; 14972 14973 ASSERT(MUTEX_HELD(&mpt->m_mutex)); 14974 14975 /* 14976 * TODO after hard reset, update the driver data structures 14977 * 1. update port/phymask mapping table mpt->m_phy_info 14978 * 2. invalid all the entries in hash table 14979 * m_devhdl = 0xffff and m_deviceinfo = 0 14980 * 3. call sas_device_page/expander_page to update hash table 14981 */ 14982 mptsas_update_phymask(mpt); 14983 14984 /* 14985 * Remove all the devhdls for existing entries but leave their 14986 * addresses alone. In update_hashtab() below, we'll find all 14987 * targets that are still present and reassociate them with 14988 * their potentially new devhdls. Leaving the targets around in 14989 * this fashion allows them to be used on the tx waitq even 14990 * while IOC reset is occurring. 14991 */ 14992 for (tp = refhash_first(mpt->m_targets); tp != NULL; 14993 tp = refhash_next(mpt->m_targets, tp)) { 14994 tp->m_devhdl = MPTSAS_INVALID_DEVHDL; 14995 tp->m_deviceinfo = 0; 14996 tp->m_dr_flag = MPTSAS_DR_INACTIVE; 14997 } 14998 for (sp = refhash_first(mpt->m_smp_targets); sp != NULL; 14999 sp = refhash_next(mpt->m_smp_targets, sp)) { 15000 sp->m_devhdl = MPTSAS_INVALID_DEVHDL; 15001 sp->m_deviceinfo = 0; 15002 } 15003 mpt->m_done_traverse_dev = 0; 15004 mpt->m_done_traverse_smp = 0; 15005 mpt->m_done_traverse_enc = 0; 15006 mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL; 15007 mptsas_update_hashtab(mpt); 15008 } 15009 15010 static void 15011 mptsas_config_all(dev_info_t *pdip) 15012 { 15013 dev_info_t *smpdip = NULL; 15014 mptsas_t *mpt = DIP2MPT(pdip); 15015 int phymask = 0; 15016 mptsas_phymask_t phy_mask; 15017 mptsas_target_t *ptgt = NULL; 15018 mptsas_smp_t *psmp; 15019 15020 /* 15021 * Get the phymask associated to the iport 15022 */ 15023 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 15024 "phymask", 0); 15025 15026 /* 15027 * Enumerate RAID volumes here (phymask == 0). 15028 */ 15029 if (phymask == 0) { 15030 mptsas_config_all_viport(pdip); 15031 return; 15032 } 15033 15034 mutex_enter(&mpt->m_mutex); 15035 15036 if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp || 15037 !mpt->m_done_traverse_enc) { 15038 mptsas_update_hashtab(mpt); 15039 } 15040 15041 for (psmp = refhash_first(mpt->m_smp_targets); psmp != NULL; 15042 psmp = refhash_next(mpt->m_smp_targets, psmp)) { 15043 phy_mask = psmp->m_addr.mta_phymask; 15044 if (phy_mask == phymask) { 15045 smpdip = NULL; 15046 mutex_exit(&mpt->m_mutex); 15047 (void) mptsas_online_smp(pdip, psmp, &smpdip); 15048 mutex_enter(&mpt->m_mutex); 15049 } 15050 } 15051 15052 for (ptgt = refhash_first(mpt->m_targets); ptgt != NULL; 15053 ptgt = refhash_next(mpt->m_targets, ptgt)) { 15054 phy_mask = ptgt->m_addr.mta_phymask; 15055 if (phy_mask == phymask) { 15056 mutex_exit(&mpt->m_mutex); 15057 (void) mptsas_config_target(pdip, ptgt); 15058 mutex_enter(&mpt->m_mutex); 15059 } 15060 } 15061 mutex_exit(&mpt->m_mutex); 15062 } 15063 15064 static int 15065 mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt) 15066 { 15067 int rval = DDI_FAILURE; 15068 dev_info_t *tdip; 15069 15070 rval = mptsas_config_luns(pdip, ptgt); 15071 if (rval != DDI_SUCCESS) { 15072 /* 15073 * The return value means the SCMD_REPORT_LUNS 15074 * did not execute successfully. The target maybe 15075 * doesn't support such command. 15076 */ 15077 rval = mptsas_probe_lun(pdip, 0, &tdip, ptgt); 15078 } 15079 return (rval); 15080 } 15081 15082 /* 15083 * Return fail if not all the childs/paths are freed. 15084 * if there is any path under the HBA, the return value will be always fail 15085 * because we didn't call mdi_pi_free for path 15086 */ 15087 static int 15088 mptsas_offline_target(dev_info_t *pdip, char *name) 15089 { 15090 dev_info_t *child = NULL, *prechild = NULL; 15091 mdi_pathinfo_t *pip = NULL, *savepip = NULL; 15092 int tmp_rval, rval = DDI_SUCCESS; 15093 char *addr, *cp; 15094 size_t s; 15095 mptsas_t *mpt = DIP2MPT(pdip); 15096 15097 child = ddi_get_child(pdip); 15098 while (child) { 15099 addr = ddi_get_name_addr(child); 15100 prechild = child; 15101 child = ddi_get_next_sibling(child); 15102 15103 if (addr == NULL) { 15104 continue; 15105 } 15106 if ((cp = strchr(addr, ',')) == NULL) { 15107 continue; 15108 } 15109 15110 s = (uintptr_t)cp - (uintptr_t)addr; 15111 15112 if (strncmp(addr, name, s) != 0) { 15113 continue; 15114 } 15115 15116 tmp_rval = mptsas_offline_lun(pdip, prechild, NULL, 15117 NDI_DEVI_REMOVE); 15118 if (tmp_rval != DDI_SUCCESS) { 15119 rval = DDI_FAILURE; 15120 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 15121 prechild, MPTSAS_DEV_GONE) != 15122 DDI_PROP_SUCCESS) { 15123 mptsas_log(mpt, CE_WARN, "mptsas driver " 15124 "unable to create property for " 15125 "SAS %s (MPTSAS_DEV_GONE)", addr); 15126 } 15127 } 15128 } 15129 15130 pip = mdi_get_next_client_path(pdip, NULL); 15131 while (pip) { 15132 addr = MDI_PI(pip)->pi_addr; 15133 savepip = pip; 15134 pip = mdi_get_next_client_path(pdip, pip); 15135 if (addr == NULL) { 15136 continue; 15137 } 15138 15139 if ((cp = strchr(addr, ',')) == NULL) { 15140 continue; 15141 } 15142 15143 s = (uintptr_t)cp - (uintptr_t)addr; 15144 15145 if (strncmp(addr, name, s) != 0) { 15146 continue; 15147 } 15148 15149 (void) mptsas_offline_lun(pdip, NULL, savepip, 15150 NDI_DEVI_REMOVE); 15151 /* 15152 * driver will not invoke mdi_pi_free, so path will not 15153 * be freed forever, return DDI_FAILURE. 15154 */ 15155 rval = DDI_FAILURE; 15156 } 15157 return (rval); 15158 } 15159 15160 static int 15161 mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip, 15162 mdi_pathinfo_t *rpip, uint_t flags) 15163 { 15164 int rval = DDI_FAILURE; 15165 char *devname; 15166 dev_info_t *cdip, *parent; 15167 15168 if (rpip != NULL) { 15169 parent = scsi_vhci_dip; 15170 cdip = mdi_pi_get_client(rpip); 15171 } else if (rdip != NULL) { 15172 parent = pdip; 15173 cdip = rdip; 15174 } else { 15175 return (DDI_FAILURE); 15176 } 15177 15178 /* 15179 * Make sure node is attached otherwise 15180 * it won't have related cache nodes to 15181 * clean up. i_ddi_devi_attached is 15182 * similiar to i_ddi_node_state(cdip) >= 15183 * DS_ATTACHED. 15184 */ 15185 if (i_ddi_devi_attached(cdip)) { 15186 15187 /* Get full devname */ 15188 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 15189 (void) ddi_deviname(cdip, devname); 15190 /* Clean cache */ 15191 (void) devfs_clean(parent, devname + 1, 15192 DV_CLEAN_FORCE); 15193 kmem_free(devname, MAXNAMELEN + 1); 15194 } 15195 if (rpip != NULL) { 15196 if (MDI_PI_IS_OFFLINE(rpip)) { 15197 rval = DDI_SUCCESS; 15198 } else { 15199 rval = mdi_pi_offline(rpip, 0); 15200 } 15201 } else { 15202 rval = ndi_devi_offline(cdip, flags); 15203 } 15204 15205 return (rval); 15206 } 15207 15208 static dev_info_t * 15209 mptsas_find_smp_child(dev_info_t *parent, char *str_wwn) 15210 { 15211 dev_info_t *child = NULL; 15212 char *smp_wwn = NULL; 15213 15214 child = ddi_get_child(parent); 15215 while (child) { 15216 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child, 15217 DDI_PROP_DONTPASS, SMP_WWN, &smp_wwn) 15218 != DDI_SUCCESS) { 15219 child = ddi_get_next_sibling(child); 15220 continue; 15221 } 15222 15223 if (strcmp(smp_wwn, str_wwn) == 0) { 15224 ddi_prop_free(smp_wwn); 15225 break; 15226 } 15227 child = ddi_get_next_sibling(child); 15228 ddi_prop_free(smp_wwn); 15229 } 15230 return (child); 15231 } 15232 15233 static int 15234 mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags) 15235 { 15236 int rval = DDI_FAILURE; 15237 char *devname; 15238 char wwn_str[MPTSAS_WWN_STRLEN]; 15239 dev_info_t *cdip; 15240 15241 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn); 15242 15243 cdip = mptsas_find_smp_child(pdip, wwn_str); 15244 15245 if (cdip == NULL) 15246 return (DDI_SUCCESS); 15247 15248 /* 15249 * Make sure node is attached otherwise 15250 * it won't have related cache nodes to 15251 * clean up. i_ddi_devi_attached is 15252 * similiar to i_ddi_node_state(cdip) >= 15253 * DS_ATTACHED. 15254 */ 15255 if (i_ddi_devi_attached(cdip)) { 15256 15257 /* Get full devname */ 15258 devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 15259 (void) ddi_deviname(cdip, devname); 15260 /* Clean cache */ 15261 (void) devfs_clean(pdip, devname + 1, 15262 DV_CLEAN_FORCE); 15263 kmem_free(devname, MAXNAMELEN + 1); 15264 } 15265 15266 rval = ndi_devi_offline(cdip, flags); 15267 15268 return (rval); 15269 } 15270 15271 static dev_info_t * 15272 mptsas_find_child(dev_info_t *pdip, char *name) 15273 { 15274 dev_info_t *child = NULL; 15275 char *rname = NULL; 15276 int rval = DDI_FAILURE; 15277 15278 rname = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 15279 15280 child = ddi_get_child(pdip); 15281 while (child) { 15282 rval = mptsas_name_child(child, rname, SCSI_MAXNAMELEN); 15283 if (rval != DDI_SUCCESS) { 15284 child = ddi_get_next_sibling(child); 15285 bzero(rname, SCSI_MAXNAMELEN); 15286 continue; 15287 } 15288 15289 if (strcmp(rname, name) == 0) { 15290 break; 15291 } 15292 child = ddi_get_next_sibling(child); 15293 bzero(rname, SCSI_MAXNAMELEN); 15294 } 15295 15296 kmem_free(rname, SCSI_MAXNAMELEN); 15297 15298 return (child); 15299 } 15300 15301 15302 static dev_info_t * 15303 mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, int lun) 15304 { 15305 dev_info_t *child = NULL; 15306 char *name = NULL; 15307 char *addr = NULL; 15308 15309 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 15310 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 15311 (void) sprintf(name, "%016"PRIx64, sasaddr); 15312 (void) sprintf(addr, "w%s,%x", name, lun); 15313 child = mptsas_find_child(pdip, addr); 15314 kmem_free(name, SCSI_MAXNAMELEN); 15315 kmem_free(addr, SCSI_MAXNAMELEN); 15316 return (child); 15317 } 15318 15319 static dev_info_t * 15320 mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy) 15321 { 15322 dev_info_t *child; 15323 char *addr; 15324 15325 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 15326 (void) sprintf(addr, "p%x,0", phy); 15327 child = mptsas_find_child(pdip, addr); 15328 kmem_free(addr, SCSI_MAXNAMELEN); 15329 return (child); 15330 } 15331 15332 static mdi_pathinfo_t * 15333 mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy) 15334 { 15335 mdi_pathinfo_t *path; 15336 char *addr = NULL; 15337 15338 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 15339 (void) sprintf(addr, "p%x,0", phy); 15340 path = mdi_pi_find(pdip, NULL, addr); 15341 kmem_free(addr, SCSI_MAXNAMELEN); 15342 return (path); 15343 } 15344 15345 static mdi_pathinfo_t * 15346 mptsas_find_path_addr(dev_info_t *parent, uint64_t sasaddr, int lun) 15347 { 15348 mdi_pathinfo_t *path; 15349 char *name = NULL; 15350 char *addr = NULL; 15351 15352 name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 15353 addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 15354 (void) sprintf(name, "%016"PRIx64, sasaddr); 15355 (void) sprintf(addr, "w%s,%x", name, lun); 15356 path = mdi_pi_find(parent, NULL, addr); 15357 kmem_free(name, SCSI_MAXNAMELEN); 15358 kmem_free(addr, SCSI_MAXNAMELEN); 15359 15360 return (path); 15361 } 15362 15363 static int 15364 mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq, 15365 dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun) 15366 { 15367 int i = 0; 15368 uchar_t *inq83 = NULL; 15369 int inq83_len1 = 0xFF; 15370 int inq83_len = 0; 15371 int rval = DDI_FAILURE; 15372 ddi_devid_t devid; 15373 char *guid = NULL; 15374 int target = ptgt->m_devhdl; 15375 mdi_pathinfo_t *pip = NULL; 15376 mptsas_t *mpt = DIP2MPT(pdip); 15377 15378 /* 15379 * For DVD/CD ROM and tape devices and optical 15380 * devices, we won't try to enumerate them under 15381 * scsi_vhci, so no need to try page83 15382 */ 15383 if (sd_inq && (sd_inq->inq_dtype == DTYPE_RODIRECT || 15384 sd_inq->inq_dtype == DTYPE_OPTICAL || 15385 sd_inq->inq_dtype == DTYPE_ESI)) 15386 goto create_lun; 15387 15388 /* 15389 * The LCA returns good SCSI status, but corrupt page 83 data the first 15390 * time it is queried. The solution is to keep trying to request page83 15391 * and verify the GUID is not (DDI_NOT_WELL_FORMED) in 15392 * mptsas_inq83_retry_timeout seconds. If the timeout expires, driver 15393 * give up to get VPD page at this stage and fail the enumeration. 15394 */ 15395 15396 inq83 = kmem_zalloc(inq83_len1, KM_SLEEP); 15397 15398 for (i = 0; i < mptsas_inq83_retry_timeout; i++) { 15399 rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83, 15400 inq83_len1, &inq83_len, 1); 15401 if (rval != 0) { 15402 mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page " 15403 "0x83 for target:%x, lun:%x failed!", target, lun); 15404 if (mptsas_physical_bind_failed_page_83 != B_FALSE) 15405 goto create_lun; 15406 goto out; 15407 } 15408 /* 15409 * create DEVID from inquiry data 15410 */ 15411 if ((rval = ddi_devid_scsi_encode( 15412 DEVID_SCSI_ENCODE_VERSION_LATEST, NULL, (uchar_t *)sd_inq, 15413 sizeof (struct scsi_inquiry), NULL, 0, inq83, 15414 (size_t)inq83_len, &devid)) == DDI_SUCCESS) { 15415 /* 15416 * extract GUID from DEVID 15417 */ 15418 guid = ddi_devid_to_guid(devid); 15419 15420 /* 15421 * Do not enable MPXIO if the strlen(guid) is greater 15422 * than MPTSAS_MAX_GUID_LEN, this constrain would be 15423 * handled by framework later. 15424 */ 15425 if (guid && (strlen(guid) > MPTSAS_MAX_GUID_LEN)) { 15426 ddi_devid_free_guid(guid); 15427 guid = NULL; 15428 if (mpt->m_mpxio_enable == TRUE) { 15429 mptsas_log(mpt, CE_NOTE, "!Target:%x, " 15430 "lun:%x doesn't have a valid GUID, " 15431 "multipathing for this drive is " 15432 "not enabled", target, lun); 15433 } 15434 } 15435 15436 /* 15437 * devid no longer needed 15438 */ 15439 ddi_devid_free(devid); 15440 break; 15441 } else if (rval == DDI_NOT_WELL_FORMED) { 15442 /* 15443 * return value of ddi_devid_scsi_encode equal to 15444 * DDI_NOT_WELL_FORMED means DEVID_RETRY, it worth 15445 * to retry inquiry page 0x83 and get GUID. 15446 */ 15447 NDBG20(("Not well formed devid, retry...")); 15448 delay(1 * drv_usectohz(1000000)); 15449 continue; 15450 } else { 15451 mptsas_log(mpt, CE_WARN, "!Encode devid failed for " 15452 "path target:%x, lun:%x", target, lun); 15453 rval = DDI_FAILURE; 15454 goto create_lun; 15455 } 15456 } 15457 15458 if (i == mptsas_inq83_retry_timeout) { 15459 mptsas_log(mpt, CE_WARN, "!Repeated page83 requests timeout " 15460 "for path target:%x, lun:%x", target, lun); 15461 } 15462 15463 rval = DDI_FAILURE; 15464 15465 create_lun: 15466 if ((guid != NULL) && (mpt->m_mpxio_enable == TRUE)) { 15467 rval = mptsas_create_virt_lun(pdip, sd_inq, guid, lun_dip, &pip, 15468 ptgt, lun); 15469 } 15470 if (rval != DDI_SUCCESS) { 15471 rval = mptsas_create_phys_lun(pdip, sd_inq, guid, lun_dip, 15472 ptgt, lun); 15473 15474 } 15475 out: 15476 if (guid != NULL) { 15477 /* 15478 * guid no longer needed 15479 */ 15480 ddi_devid_free_guid(guid); 15481 } 15482 if (inq83 != NULL) 15483 kmem_free(inq83, inq83_len1); 15484 return (rval); 15485 } 15486 15487 static int 15488 mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *inq, char *guid, 15489 dev_info_t **lun_dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, int lun) 15490 { 15491 int target; 15492 char *nodename = NULL; 15493 char **compatible = NULL; 15494 int ncompatible = 0; 15495 int mdi_rtn = MDI_FAILURE; 15496 int rval = DDI_FAILURE; 15497 char *old_guid = NULL; 15498 mptsas_t *mpt = DIP2MPT(pdip); 15499 char *lun_addr = NULL; 15500 char *wwn_str = NULL; 15501 char *attached_wwn_str = NULL; 15502 char *component = NULL; 15503 uint8_t phy = 0xFF; 15504 uint64_t sas_wwn; 15505 int64_t lun64 = 0; 15506 uint32_t devinfo; 15507 uint16_t dev_hdl; 15508 uint16_t pdev_hdl; 15509 uint64_t dev_sas_wwn; 15510 uint64_t pdev_sas_wwn; 15511 uint32_t pdev_info; 15512 uint8_t physport; 15513 uint8_t phy_id; 15514 uint32_t page_address; 15515 uint16_t bay_num, enclosure, io_flags; 15516 char pdev_wwn_str[MPTSAS_WWN_STRLEN]; 15517 uint32_t dev_info; 15518 15519 mutex_enter(&mpt->m_mutex); 15520 target = ptgt->m_devhdl; 15521 sas_wwn = ptgt->m_addr.mta_wwn; 15522 devinfo = ptgt->m_deviceinfo; 15523 phy = ptgt->m_phynum; 15524 mutex_exit(&mpt->m_mutex); 15525 15526 if (sas_wwn) { 15527 *pip = mptsas_find_path_addr(pdip, sas_wwn, lun); 15528 } else { 15529 *pip = mptsas_find_path_phy(pdip, phy); 15530 } 15531 15532 if (*pip != NULL) { 15533 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip; 15534 ASSERT(*lun_dip != NULL); 15535 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip, 15536 (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM), 15537 MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) { 15538 if (strncmp(guid, old_guid, strlen(guid)) == 0) { 15539 /* 15540 * Same path back online again. 15541 */ 15542 (void) ddi_prop_free(old_guid); 15543 if ((!MDI_PI_IS_ONLINE(*pip)) && 15544 (!MDI_PI_IS_STANDBY(*pip)) && 15545 (ptgt->m_tgt_unconfigured == 0)) { 15546 rval = mdi_pi_online(*pip, 0); 15547 } else { 15548 rval = DDI_SUCCESS; 15549 } 15550 if (rval != DDI_SUCCESS) { 15551 mptsas_log(mpt, CE_WARN, "path:target: " 15552 "%x, lun:%x online failed!", target, 15553 lun); 15554 *pip = NULL; 15555 *lun_dip = NULL; 15556 } 15557 return (rval); 15558 } else { 15559 /* 15560 * The GUID of the LUN has changed which maybe 15561 * because customer mapped another volume to the 15562 * same LUN. 15563 */ 15564 mptsas_log(mpt, CE_WARN, "The GUID of the " 15565 "target:%x, lun:%x was changed, maybe " 15566 "because someone mapped another volume " 15567 "to the same LUN", target, lun); 15568 (void) ddi_prop_free(old_guid); 15569 if (!MDI_PI_IS_OFFLINE(*pip)) { 15570 rval = mdi_pi_offline(*pip, 0); 15571 if (rval != MDI_SUCCESS) { 15572 mptsas_log(mpt, CE_WARN, "path:" 15573 "target:%x, lun:%x offline " 15574 "failed!", target, lun); 15575 *pip = NULL; 15576 *lun_dip = NULL; 15577 return (DDI_FAILURE); 15578 } 15579 } 15580 if (mdi_pi_free(*pip, 0) != MDI_SUCCESS) { 15581 mptsas_log(mpt, CE_WARN, "path:target:" 15582 "%x, lun:%x free failed!", target, 15583 lun); 15584 *pip = NULL; 15585 *lun_dip = NULL; 15586 return (DDI_FAILURE); 15587 } 15588 } 15589 } else { 15590 mptsas_log(mpt, CE_WARN, "Can't get client-guid " 15591 "property for path:target:%x, lun:%x", target, lun); 15592 *pip = NULL; 15593 *lun_dip = NULL; 15594 return (DDI_FAILURE); 15595 } 15596 } 15597 scsi_hba_nodename_compatible_get(inq, NULL, 15598 inq->inq_dtype, NULL, &nodename, &compatible, &ncompatible); 15599 15600 /* 15601 * if nodename can't be determined then print a message and skip it 15602 */ 15603 if (nodename == NULL) { 15604 mptsas_log(mpt, CE_WARN, "mptsas driver found no compatible " 15605 "driver for target%d lun %d dtype:0x%02x", target, lun, 15606 inq->inq_dtype); 15607 return (DDI_FAILURE); 15608 } 15609 15610 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP); 15611 /* The property is needed by MPAPI */ 15612 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn); 15613 15614 lun_addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP); 15615 if (guid) { 15616 (void) sprintf(lun_addr, "w%s,%x", wwn_str, lun); 15617 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 15618 } else { 15619 (void) sprintf(lun_addr, "p%x,%x", phy, lun); 15620 (void) sprintf(wwn_str, "p%x", phy); 15621 } 15622 15623 mdi_rtn = mdi_pi_alloc_compatible(pdip, nodename, 15624 guid, lun_addr, compatible, ncompatible, 15625 0, pip); 15626 if (mdi_rtn == MDI_SUCCESS) { 15627 15628 if (mdi_prop_update_string(*pip, MDI_GUID, 15629 guid) != DDI_SUCCESS) { 15630 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 15631 "create prop for target %d lun %d (MDI_GUID)", 15632 target, lun); 15633 mdi_rtn = MDI_FAILURE; 15634 goto virt_create_done; 15635 } 15636 15637 if (mdi_prop_update_int(*pip, LUN_PROP, 15638 lun) != DDI_SUCCESS) { 15639 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 15640 "create prop for target %d lun %d (LUN_PROP)", 15641 target, lun); 15642 mdi_rtn = MDI_FAILURE; 15643 goto virt_create_done; 15644 } 15645 lun64 = (int64_t)lun; 15646 if (mdi_prop_update_int64(*pip, LUN64_PROP, 15647 lun64) != DDI_SUCCESS) { 15648 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 15649 "create prop for target %d (LUN64_PROP)", 15650 target); 15651 mdi_rtn = MDI_FAILURE; 15652 goto virt_create_done; 15653 } 15654 if (mdi_prop_update_string_array(*pip, "compatible", 15655 compatible, ncompatible) != 15656 DDI_PROP_SUCCESS) { 15657 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 15658 "create prop for target %d lun %d (COMPATIBLE)", 15659 target, lun); 15660 mdi_rtn = MDI_FAILURE; 15661 goto virt_create_done; 15662 } 15663 if (sas_wwn && (mdi_prop_update_string(*pip, 15664 SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != DDI_PROP_SUCCESS)) { 15665 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 15666 "create prop for target %d lun %d " 15667 "(target-port)", target, lun); 15668 mdi_rtn = MDI_FAILURE; 15669 goto virt_create_done; 15670 } else if ((sas_wwn == 0) && (mdi_prop_update_int(*pip, 15671 "sata-phy", phy) != DDI_PROP_SUCCESS)) { 15672 /* 15673 * Direct attached SATA device without DeviceName 15674 */ 15675 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 15676 "create prop for SAS target %d lun %d " 15677 "(sata-phy)", target, lun); 15678 mdi_rtn = MDI_FAILURE; 15679 goto virt_create_done; 15680 } 15681 mutex_enter(&mpt->m_mutex); 15682 15683 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 15684 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 15685 (uint32_t)ptgt->m_devhdl; 15686 rval = mptsas_get_sas_device_page0(mpt, page_address, 15687 &dev_hdl, &dev_sas_wwn, &dev_info, &physport, 15688 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags); 15689 if (rval != DDI_SUCCESS) { 15690 mutex_exit(&mpt->m_mutex); 15691 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 15692 "parent device for handle %d", page_address); 15693 mdi_rtn = MDI_FAILURE; 15694 goto virt_create_done; 15695 } 15696 15697 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 15698 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl; 15699 rval = mptsas_get_sas_device_page0(mpt, page_address, 15700 &dev_hdl, &pdev_sas_wwn, &pdev_info, &physport, 15701 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags); 15702 if (rval != DDI_SUCCESS) { 15703 mutex_exit(&mpt->m_mutex); 15704 mptsas_log(mpt, CE_WARN, "mptsas unable to get" 15705 "device info for handle %d", page_address); 15706 mdi_rtn = MDI_FAILURE; 15707 goto virt_create_done; 15708 } 15709 15710 mutex_exit(&mpt->m_mutex); 15711 15712 /* 15713 * If this device direct attached to the controller 15714 * set the attached-port to the base wwid 15715 */ 15716 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 15717 != DEVINFO_DIRECT_ATTACHED) { 15718 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 15719 pdev_sas_wwn); 15720 } else { 15721 /* 15722 * Update the iport's attached-port to guid 15723 */ 15724 if (sas_wwn == 0) { 15725 (void) sprintf(wwn_str, "p%x", phy); 15726 } else { 15727 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 15728 } 15729 if (ddi_prop_update_string(DDI_DEV_T_NONE, 15730 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 15731 DDI_PROP_SUCCESS) { 15732 mptsas_log(mpt, CE_WARN, 15733 "mptsas unable to create " 15734 "property for iport target-port" 15735 " %s (sas_wwn)", 15736 wwn_str); 15737 mdi_rtn = MDI_FAILURE; 15738 goto virt_create_done; 15739 } 15740 15741 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 15742 mpt->un.m_base_wwid); 15743 } 15744 15745 if (IS_SATA_DEVICE(ptgt->m_deviceinfo)) { 15746 char uabuf[SCSI_WWN_BUFLEN]; 15747 15748 if (scsi_wwn_to_wwnstr(dev_sas_wwn, 1, uabuf) == NULL) { 15749 mptsas_log(mpt, CE_WARN, 15750 "mptsas unable to format SATA bridge WWN"); 15751 mdi_rtn = MDI_FAILURE; 15752 goto virt_create_done; 15753 } 15754 15755 if (mdi_prop_update_string(*pip, 15756 SCSI_ADDR_PROP_BRIDGE_PORT, uabuf) != 15757 DDI_SUCCESS) { 15758 mptsas_log(mpt, CE_WARN, 15759 "mptsas unable to create SCSI bridge port " 15760 "property for SATA device"); 15761 mdi_rtn = MDI_FAILURE; 15762 goto virt_create_done; 15763 } 15764 } 15765 15766 if (mdi_prop_update_string(*pip, 15767 SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) != 15768 DDI_PROP_SUCCESS) { 15769 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15770 "property for iport attached-port %s (sas_wwn)", 15771 attached_wwn_str); 15772 mdi_rtn = MDI_FAILURE; 15773 goto virt_create_done; 15774 } 15775 15776 15777 if (inq->inq_dtype == 0) { 15778 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 15779 /* 15780 * set obp path for pathinfo 15781 */ 15782 (void) snprintf(component, MAXPATHLEN, 15783 "disk@%s", lun_addr); 15784 15785 if (mdi_pi_pathname_obp_set(*pip, component) != 15786 DDI_SUCCESS) { 15787 mptsas_log(mpt, CE_WARN, "mpt_sas driver " 15788 "unable to set obp-path for object %s", 15789 component); 15790 mdi_rtn = MDI_FAILURE; 15791 goto virt_create_done; 15792 } 15793 } 15794 15795 *lun_dip = MDI_PI(*pip)->pi_client->ct_dip; 15796 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 15797 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 15798 if ((ndi_prop_update_int(DDI_DEV_T_NONE, *lun_dip, 15799 "pm-capable", 1)) != 15800 DDI_PROP_SUCCESS) { 15801 mptsas_log(mpt, CE_WARN, "mptsas driver" 15802 "failed to create pm-capable " 15803 "property, target %d", target); 15804 mdi_rtn = MDI_FAILURE; 15805 goto virt_create_done; 15806 } 15807 } 15808 /* 15809 * Create the phy-num property 15810 */ 15811 if (mdi_prop_update_int(*pip, "phy-num", 15812 ptgt->m_phynum) != DDI_SUCCESS) { 15813 mptsas_log(mpt, CE_WARN, "mptsas driver unable to " 15814 "create phy-num property for target %d lun %d", 15815 target, lun); 15816 mdi_rtn = MDI_FAILURE; 15817 goto virt_create_done; 15818 } 15819 NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr)); 15820 mdi_rtn = mdi_pi_online(*pip, 0); 15821 if (mdi_rtn == MDI_NOT_SUPPORTED) { 15822 mdi_rtn = MDI_FAILURE; 15823 } 15824 virt_create_done: 15825 if (*pip && mdi_rtn != MDI_SUCCESS) { 15826 (void) mdi_pi_free(*pip, 0); 15827 *pip = NULL; 15828 *lun_dip = NULL; 15829 } 15830 } 15831 15832 scsi_hba_nodename_compatible_free(nodename, compatible); 15833 if (lun_addr != NULL) { 15834 kmem_free(lun_addr, SCSI_MAXNAMELEN); 15835 } 15836 if (wwn_str != NULL) { 15837 kmem_free(wwn_str, MPTSAS_WWN_STRLEN); 15838 } 15839 if (component != NULL) { 15840 kmem_free(component, MAXPATHLEN); 15841 } 15842 15843 return ((mdi_rtn == MDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 15844 } 15845 15846 static int 15847 mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *inq, 15848 char *guid, dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun) 15849 { 15850 int target; 15851 int rval; 15852 int ndi_rtn = NDI_FAILURE; 15853 uint64_t be_sas_wwn; 15854 char *nodename = NULL; 15855 char **compatible = NULL; 15856 int ncompatible = 0; 15857 int instance = 0; 15858 mptsas_t *mpt = DIP2MPT(pdip); 15859 char *wwn_str = NULL; 15860 char *component = NULL; 15861 char *attached_wwn_str = NULL; 15862 uint8_t phy = 0xFF; 15863 uint64_t sas_wwn; 15864 uint32_t devinfo; 15865 uint16_t dev_hdl; 15866 uint16_t pdev_hdl; 15867 uint64_t pdev_sas_wwn; 15868 uint64_t dev_sas_wwn; 15869 uint32_t pdev_info; 15870 uint8_t physport; 15871 uint8_t phy_id; 15872 uint32_t page_address; 15873 uint16_t bay_num, enclosure, io_flags; 15874 char pdev_wwn_str[MPTSAS_WWN_STRLEN]; 15875 uint32_t dev_info; 15876 int64_t lun64 = 0; 15877 15878 mutex_enter(&mpt->m_mutex); 15879 target = ptgt->m_devhdl; 15880 sas_wwn = ptgt->m_addr.mta_wwn; 15881 devinfo = ptgt->m_deviceinfo; 15882 phy = ptgt->m_phynum; 15883 mutex_exit(&mpt->m_mutex); 15884 15885 /* 15886 * generate compatible property with binding-set "mpt" 15887 */ 15888 scsi_hba_nodename_compatible_get(inq, NULL, inq->inq_dtype, NULL, 15889 &nodename, &compatible, &ncompatible); 15890 15891 /* 15892 * if nodename can't be determined then print a message and skip it 15893 */ 15894 if (nodename == NULL) { 15895 mptsas_log(mpt, CE_WARN, "mptsas found no compatible driver " 15896 "for target %d lun %d", target, lun); 15897 return (DDI_FAILURE); 15898 } 15899 15900 ndi_rtn = ndi_devi_alloc(pdip, nodename, 15901 DEVI_SID_NODEID, lun_dip); 15902 15903 /* 15904 * if lun alloc success, set props 15905 */ 15906 if (ndi_rtn == NDI_SUCCESS) { 15907 15908 if (ndi_prop_update_int(DDI_DEV_T_NONE, 15909 *lun_dip, LUN_PROP, lun) != 15910 DDI_PROP_SUCCESS) { 15911 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15912 "property for target %d lun %d (LUN_PROP)", 15913 target, lun); 15914 ndi_rtn = NDI_FAILURE; 15915 goto phys_create_done; 15916 } 15917 15918 lun64 = (int64_t)lun; 15919 if (ndi_prop_update_int64(DDI_DEV_T_NONE, 15920 *lun_dip, LUN64_PROP, lun64) != 15921 DDI_PROP_SUCCESS) { 15922 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15923 "property for target %d lun64 %d (LUN64_PROP)", 15924 target, lun); 15925 ndi_rtn = NDI_FAILURE; 15926 goto phys_create_done; 15927 } 15928 if (ndi_prop_update_string_array(DDI_DEV_T_NONE, 15929 *lun_dip, "compatible", compatible, ncompatible) 15930 != DDI_PROP_SUCCESS) { 15931 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 15932 "property for target %d lun %d (COMPATIBLE)", 15933 target, lun); 15934 ndi_rtn = NDI_FAILURE; 15935 goto phys_create_done; 15936 } 15937 15938 /* 15939 * We need the SAS WWN for non-multipath devices, so 15940 * we'll use the same property as that multipathing 15941 * devices need to present for MPAPI. If we don't have 15942 * a WWN (e.g. parallel SCSI), don't create the prop. 15943 */ 15944 wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP); 15945 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 15946 if (sas_wwn && ndi_prop_update_string(DDI_DEV_T_NONE, 15947 *lun_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) 15948 != DDI_PROP_SUCCESS) { 15949 mptsas_log(mpt, CE_WARN, "mptsas unable to " 15950 "create property for SAS target %d lun %d " 15951 "(target-port)", target, lun); 15952 ndi_rtn = NDI_FAILURE; 15953 goto phys_create_done; 15954 } 15955 15956 be_sas_wwn = BE_64(sas_wwn); 15957 if (sas_wwn && ndi_prop_update_byte_array( 15958 DDI_DEV_T_NONE, *lun_dip, "port-wwn", 15959 (uchar_t *)&be_sas_wwn, 8) != DDI_PROP_SUCCESS) { 15960 mptsas_log(mpt, CE_WARN, "mptsas unable to " 15961 "create property for SAS target %d lun %d " 15962 "(port-wwn)", target, lun); 15963 ndi_rtn = NDI_FAILURE; 15964 goto phys_create_done; 15965 } else if ((sas_wwn == 0) && (ndi_prop_update_int( 15966 DDI_DEV_T_NONE, *lun_dip, "sata-phy", phy) != 15967 DDI_PROP_SUCCESS)) { 15968 /* 15969 * Direct attached SATA device without DeviceName 15970 */ 15971 mptsas_log(mpt, CE_WARN, "mptsas unable to " 15972 "create property for SAS target %d lun %d " 15973 "(sata-phy)", target, lun); 15974 ndi_rtn = NDI_FAILURE; 15975 goto phys_create_done; 15976 } 15977 15978 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 15979 *lun_dip, SAS_PROP) != DDI_PROP_SUCCESS) { 15980 mptsas_log(mpt, CE_WARN, "mptsas unable to" 15981 "create property for SAS target %d lun %d" 15982 " (SAS_PROP)", target, lun); 15983 ndi_rtn = NDI_FAILURE; 15984 goto phys_create_done; 15985 } 15986 if (guid && (ndi_prop_update_string(DDI_DEV_T_NONE, 15987 *lun_dip, NDI_GUID, guid) != DDI_SUCCESS)) { 15988 mptsas_log(mpt, CE_WARN, "mptsas unable " 15989 "to create guid property for target %d " 15990 "lun %d", target, lun); 15991 ndi_rtn = NDI_FAILURE; 15992 goto phys_create_done; 15993 } 15994 15995 /* 15996 * The following code is to set properties for SM-HBA support, 15997 * it doesn't apply to RAID volumes 15998 */ 15999 if (ptgt->m_addr.mta_phymask == 0) 16000 goto phys_raid_lun; 16001 16002 mutex_enter(&mpt->m_mutex); 16003 16004 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 16005 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 16006 (uint32_t)ptgt->m_devhdl; 16007 rval = mptsas_get_sas_device_page0(mpt, page_address, 16008 &dev_hdl, &dev_sas_wwn, &dev_info, 16009 &physport, &phy_id, &pdev_hdl, 16010 &bay_num, &enclosure, &io_flags); 16011 if (rval != DDI_SUCCESS) { 16012 mutex_exit(&mpt->m_mutex); 16013 mptsas_log(mpt, CE_WARN, "mptsas unable to get" 16014 "parent device for handle %d.", page_address); 16015 ndi_rtn = NDI_FAILURE; 16016 goto phys_create_done; 16017 } 16018 16019 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 16020 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)pdev_hdl; 16021 rval = mptsas_get_sas_device_page0(mpt, page_address, 16022 &dev_hdl, &pdev_sas_wwn, &pdev_info, &physport, 16023 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags); 16024 if (rval != DDI_SUCCESS) { 16025 mutex_exit(&mpt->m_mutex); 16026 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 16027 "device for handle %d.", page_address); 16028 ndi_rtn = NDI_FAILURE; 16029 goto phys_create_done; 16030 } 16031 16032 mutex_exit(&mpt->m_mutex); 16033 16034 /* 16035 * If this device direct attached to the controller 16036 * set the attached-port to the base wwid 16037 */ 16038 if ((ptgt->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 16039 != DEVINFO_DIRECT_ATTACHED) { 16040 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 16041 pdev_sas_wwn); 16042 } else { 16043 /* 16044 * Update the iport's attached-port to guid 16045 */ 16046 if (sas_wwn == 0) { 16047 (void) sprintf(wwn_str, "p%x", phy); 16048 } else { 16049 (void) sprintf(wwn_str, "w%016"PRIx64, sas_wwn); 16050 } 16051 if (ddi_prop_update_string(DDI_DEV_T_NONE, 16052 pdip, SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 16053 DDI_PROP_SUCCESS) { 16054 mptsas_log(mpt, CE_WARN, 16055 "mptsas unable to create " 16056 "property for iport target-port" 16057 " %s (sas_wwn)", 16058 wwn_str); 16059 ndi_rtn = NDI_FAILURE; 16060 goto phys_create_done; 16061 } 16062 16063 (void) sprintf(pdev_wwn_str, "w%016"PRIx64, 16064 mpt->un.m_base_wwid); 16065 } 16066 16067 if (ndi_prop_update_string(DDI_DEV_T_NONE, 16068 *lun_dip, SCSI_ADDR_PROP_ATTACHED_PORT, pdev_wwn_str) != 16069 DDI_PROP_SUCCESS) { 16070 mptsas_log(mpt, CE_WARN, 16071 "mptsas unable to create " 16072 "property for iport attached-port %s (sas_wwn)", 16073 attached_wwn_str); 16074 ndi_rtn = NDI_FAILURE; 16075 goto phys_create_done; 16076 } 16077 16078 if (IS_SATA_DEVICE(dev_info)) { 16079 char uabuf[SCSI_WWN_BUFLEN]; 16080 16081 if (ndi_prop_update_string(DDI_DEV_T_NONE, 16082 *lun_dip, MPTSAS_VARIANT, "sata") != 16083 DDI_PROP_SUCCESS) { 16084 mptsas_log(mpt, CE_WARN, 16085 "mptsas unable to create " 16086 "property for device variant "); 16087 ndi_rtn = NDI_FAILURE; 16088 goto phys_create_done; 16089 } 16090 16091 if (scsi_wwn_to_wwnstr(dev_sas_wwn, 1, uabuf) == NULL) { 16092 mptsas_log(mpt, CE_WARN, 16093 "mptsas unable to format SATA bridge WWN"); 16094 ndi_rtn = NDI_FAILURE; 16095 goto phys_create_done; 16096 } 16097 16098 if (ndi_prop_update_string(DDI_DEV_T_NONE, *lun_dip, 16099 SCSI_ADDR_PROP_BRIDGE_PORT, uabuf) != 16100 DDI_PROP_SUCCESS) { 16101 mptsas_log(mpt, CE_WARN, 16102 "mptsas unable to create SCSI bridge port " 16103 "property for SATA device"); 16104 ndi_rtn = NDI_FAILURE; 16105 goto phys_create_done; 16106 } 16107 } 16108 16109 if (IS_ATAPI_DEVICE(dev_info)) { 16110 if (ndi_prop_update_string(DDI_DEV_T_NONE, 16111 *lun_dip, MPTSAS_VARIANT, "atapi") != 16112 DDI_PROP_SUCCESS) { 16113 mptsas_log(mpt, CE_WARN, 16114 "mptsas unable to create " 16115 "property for device variant "); 16116 ndi_rtn = NDI_FAILURE; 16117 goto phys_create_done; 16118 } 16119 } 16120 16121 phys_raid_lun: 16122 /* 16123 * if this is a SAS controller, and the target is a SATA 16124 * drive, set the 'pm-capable' property for sd and if on 16125 * an OPL platform, also check if this is an ATAPI 16126 * device. 16127 */ 16128 instance = ddi_get_instance(mpt->m_dip); 16129 if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE | 16130 MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) { 16131 NDBG2(("mptsas%d: creating pm-capable property, " 16132 "target %d", instance, target)); 16133 16134 if ((ndi_prop_update_int(DDI_DEV_T_NONE, 16135 *lun_dip, "pm-capable", 1)) != 16136 DDI_PROP_SUCCESS) { 16137 mptsas_log(mpt, CE_WARN, "mptsas " 16138 "failed to create pm-capable " 16139 "property, target %d", target); 16140 ndi_rtn = NDI_FAILURE; 16141 goto phys_create_done; 16142 } 16143 16144 } 16145 16146 if ((inq->inq_dtype == 0) || (inq->inq_dtype == 5)) { 16147 /* 16148 * add 'obp-path' properties for devinfo 16149 */ 16150 bzero(wwn_str, sizeof (wwn_str)); 16151 (void) sprintf(wwn_str, "%016"PRIx64, sas_wwn); 16152 component = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 16153 if (guid) { 16154 (void) snprintf(component, MAXPATHLEN, 16155 "disk@w%s,%x", wwn_str, lun); 16156 } else { 16157 (void) snprintf(component, MAXPATHLEN, 16158 "disk@p%x,%x", phy, lun); 16159 } 16160 if (ddi_pathname_obp_set(*lun_dip, component) 16161 != DDI_SUCCESS) { 16162 mptsas_log(mpt, CE_WARN, "mpt_sas driver " 16163 "unable to set obp-path for SAS " 16164 "object %s", component); 16165 ndi_rtn = NDI_FAILURE; 16166 goto phys_create_done; 16167 } 16168 } 16169 /* 16170 * Create the phy-num property for non-raid disk 16171 */ 16172 if (ptgt->m_addr.mta_phymask != 0) { 16173 if (ndi_prop_update_int(DDI_DEV_T_NONE, 16174 *lun_dip, "phy-num", ptgt->m_phynum) != 16175 DDI_PROP_SUCCESS) { 16176 mptsas_log(mpt, CE_WARN, "mptsas driver " 16177 "failed to create phy-num property for " 16178 "target %d", target); 16179 ndi_rtn = NDI_FAILURE; 16180 goto phys_create_done; 16181 } 16182 } 16183 phys_create_done: 16184 /* 16185 * If props were setup ok, online the lun 16186 */ 16187 if (ndi_rtn == NDI_SUCCESS) { 16188 /* 16189 * Try to online the new node 16190 */ 16191 ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH); 16192 } 16193 16194 /* 16195 * If success set rtn flag, else unwire alloc'd lun 16196 */ 16197 if (ndi_rtn != NDI_SUCCESS) { 16198 NDBG12(("mptsas driver unable to online " 16199 "target %d lun %d", target, lun)); 16200 ndi_prop_remove_all(*lun_dip); 16201 (void) ndi_devi_free(*lun_dip); 16202 *lun_dip = NULL; 16203 } 16204 } 16205 16206 scsi_hba_nodename_compatible_free(nodename, compatible); 16207 16208 if (wwn_str != NULL) { 16209 kmem_free(wwn_str, MPTSAS_WWN_STRLEN); 16210 } 16211 if (component != NULL) { 16212 kmem_free(component, MAXPATHLEN); 16213 } 16214 16215 16216 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 16217 } 16218 16219 static int 16220 mptsas_probe_smp(dev_info_t *pdip, uint64_t wwn) 16221 { 16222 mptsas_t *mpt = DIP2MPT(pdip); 16223 struct smp_device smp_sd; 16224 16225 /* XXX An HBA driver should not be allocating an smp_device. */ 16226 bzero(&smp_sd, sizeof (struct smp_device)); 16227 smp_sd.smp_sd_address.smp_a_hba_tran = mpt->m_smptran; 16228 bcopy(&wwn, smp_sd.smp_sd_address.smp_a_wwn, SAS_WWN_BYTE_SIZE); 16229 16230 if (smp_probe(&smp_sd) != DDI_PROBE_SUCCESS) 16231 return (NDI_FAILURE); 16232 return (NDI_SUCCESS); 16233 } 16234 16235 static int 16236 mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, dev_info_t **smp_dip) 16237 { 16238 mptsas_t *mpt = DIP2MPT(pdip); 16239 mptsas_smp_t *psmp = NULL; 16240 int rval; 16241 int phymask; 16242 16243 /* 16244 * Get the physical port associated to the iport 16245 * PHYMASK TODO 16246 */ 16247 phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0, 16248 "phymask", 0); 16249 /* 16250 * Find the smp node in hash table with specified sas address and 16251 * physical port 16252 */ 16253 psmp = mptsas_wwid_to_psmp(mpt, phymask, sas_wwn); 16254 if (psmp == NULL) { 16255 return (DDI_FAILURE); 16256 } 16257 16258 rval = mptsas_online_smp(pdip, psmp, smp_dip); 16259 16260 return (rval); 16261 } 16262 16263 static int 16264 mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, 16265 dev_info_t **smp_dip) 16266 { 16267 char wwn_str[MPTSAS_WWN_STRLEN]; 16268 char attached_wwn_str[MPTSAS_WWN_STRLEN]; 16269 int ndi_rtn = NDI_FAILURE; 16270 int rval = 0; 16271 mptsas_smp_t dev_info; 16272 uint32_t page_address; 16273 mptsas_t *mpt = DIP2MPT(pdip); 16274 uint16_t dev_hdl; 16275 uint64_t sas_wwn; 16276 uint64_t smp_sas_wwn; 16277 uint8_t physport; 16278 uint8_t phy_id; 16279 uint16_t pdev_hdl; 16280 uint8_t numphys = 0; 16281 uint16_t i = 0; 16282 char phymask[MPTSAS_MAX_PHYS]; 16283 char *iport = NULL; 16284 mptsas_phymask_t phy_mask = 0; 16285 uint16_t attached_devhdl; 16286 uint16_t bay_num, enclosure, io_flags; 16287 16288 (void) sprintf(wwn_str, "%"PRIx64, smp_node->m_addr.mta_wwn); 16289 16290 /* 16291 * Probe smp device, prevent the node of removed device from being 16292 * configured succesfully 16293 */ 16294 if (mptsas_probe_smp(pdip, smp_node->m_addr.mta_wwn) != NDI_SUCCESS) { 16295 return (DDI_FAILURE); 16296 } 16297 16298 if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) { 16299 return (DDI_SUCCESS); 16300 } 16301 16302 ndi_rtn = ndi_devi_alloc(pdip, "smp", DEVI_SID_NODEID, smp_dip); 16303 16304 /* 16305 * if lun alloc success, set props 16306 */ 16307 if (ndi_rtn == NDI_SUCCESS) { 16308 /* 16309 * Set the flavor of the child to be SMP flavored 16310 */ 16311 ndi_flavor_set(*smp_dip, SCSA_FLAVOR_SMP); 16312 16313 if (ndi_prop_update_string(DDI_DEV_T_NONE, 16314 *smp_dip, SMP_WWN, wwn_str) != 16315 DDI_PROP_SUCCESS) { 16316 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 16317 "property for smp device %s (sas_wwn)", 16318 wwn_str); 16319 ndi_rtn = NDI_FAILURE; 16320 goto smp_create_done; 16321 } 16322 (void) sprintf(wwn_str, "w%"PRIx64, smp_node->m_addr.mta_wwn); 16323 if (ndi_prop_update_string(DDI_DEV_T_NONE, 16324 *smp_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != 16325 DDI_PROP_SUCCESS) { 16326 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 16327 "property for iport target-port %s (sas_wwn)", 16328 wwn_str); 16329 ndi_rtn = NDI_FAILURE; 16330 goto smp_create_done; 16331 } 16332 16333 mutex_enter(&mpt->m_mutex); 16334 16335 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL & 16336 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | smp_node->m_devhdl; 16337 rval = mptsas_get_sas_expander_page0(mpt, page_address, 16338 &dev_info); 16339 if (rval != DDI_SUCCESS) { 16340 mutex_exit(&mpt->m_mutex); 16341 mptsas_log(mpt, CE_WARN, 16342 "mptsas unable to get expander " 16343 "parent device info for %x", page_address); 16344 ndi_rtn = NDI_FAILURE; 16345 goto smp_create_done; 16346 } 16347 16348 smp_node->m_pdevhdl = dev_info.m_pdevhdl; 16349 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 16350 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 16351 (uint32_t)dev_info.m_pdevhdl; 16352 rval = mptsas_get_sas_device_page0(mpt, page_address, 16353 &dev_hdl, &sas_wwn, &smp_node->m_pdevinfo, &physport, 16354 &phy_id, &pdev_hdl, &bay_num, &enclosure, &io_flags); 16355 if (rval != DDI_SUCCESS) { 16356 mutex_exit(&mpt->m_mutex); 16357 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 16358 "device info for %x", page_address); 16359 ndi_rtn = NDI_FAILURE; 16360 goto smp_create_done; 16361 } 16362 16363 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE & 16364 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | 16365 (uint32_t)dev_info.m_devhdl; 16366 rval = mptsas_get_sas_device_page0(mpt, page_address, 16367 &dev_hdl, &smp_sas_wwn, &smp_node->m_deviceinfo, 16368 &physport, &phy_id, &pdev_hdl, &bay_num, &enclosure, 16369 &io_flags); 16370 if (rval != DDI_SUCCESS) { 16371 mutex_exit(&mpt->m_mutex); 16372 mptsas_log(mpt, CE_WARN, "mptsas unable to get " 16373 "device info for %x", page_address); 16374 ndi_rtn = NDI_FAILURE; 16375 goto smp_create_done; 16376 } 16377 mutex_exit(&mpt->m_mutex); 16378 16379 /* 16380 * If this smp direct attached to the controller 16381 * set the attached-port to the base wwid 16382 */ 16383 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 16384 != DEVINFO_DIRECT_ATTACHED) { 16385 (void) sprintf(attached_wwn_str, "w%016"PRIx64, 16386 sas_wwn); 16387 } else { 16388 (void) sprintf(attached_wwn_str, "w%016"PRIx64, 16389 mpt->un.m_base_wwid); 16390 } 16391 16392 if (ndi_prop_update_string(DDI_DEV_T_NONE, 16393 *smp_dip, SCSI_ADDR_PROP_ATTACHED_PORT, attached_wwn_str) != 16394 DDI_PROP_SUCCESS) { 16395 mptsas_log(mpt, CE_WARN, "mptsas unable to create " 16396 "property for smp attached-port %s (sas_wwn)", 16397 attached_wwn_str); 16398 ndi_rtn = NDI_FAILURE; 16399 goto smp_create_done; 16400 } 16401 16402 if (ndi_prop_create_boolean(DDI_DEV_T_NONE, 16403 *smp_dip, SMP_PROP) != DDI_PROP_SUCCESS) { 16404 mptsas_log(mpt, CE_WARN, "mptsas unable to " 16405 "create property for SMP %s (SMP_PROP) ", 16406 wwn_str); 16407 ndi_rtn = NDI_FAILURE; 16408 goto smp_create_done; 16409 } 16410 16411 /* 16412 * check the smp to see whether it direct 16413 * attached to the controller 16414 */ 16415 if ((smp_node->m_deviceinfo & DEVINFO_DIRECT_ATTACHED) 16416 != DEVINFO_DIRECT_ATTACHED) { 16417 goto smp_create_done; 16418 } 16419 numphys = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 16420 DDI_PROP_DONTPASS, MPTSAS_NUM_PHYS, -1); 16421 if (numphys > 0) { 16422 goto smp_create_done; 16423 } 16424 /* 16425 * this iport is an old iport, we need to 16426 * reconfig the props for it. 16427 */ 16428 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip, 16429 MPTSAS_VIRTUAL_PORT, 0) != 16430 DDI_PROP_SUCCESS) { 16431 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 16432 MPTSAS_VIRTUAL_PORT); 16433 mptsas_log(mpt, CE_WARN, "mptsas virtual port " 16434 "prop update failed"); 16435 goto smp_create_done; 16436 } 16437 16438 mutex_enter(&mpt->m_mutex); 16439 numphys = 0; 16440 iport = ddi_get_name_addr(pdip); 16441 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 16442 bzero(phymask, sizeof (phymask)); 16443 (void) sprintf(phymask, 16444 "%x", mpt->m_phy_info[i].phy_mask); 16445 if (strcmp(phymask, iport) == 0) { 16446 phy_mask = mpt->m_phy_info[i].phy_mask; 16447 break; 16448 } 16449 } 16450 16451 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 16452 if ((phy_mask >> i) & 0x01) { 16453 numphys++; 16454 } 16455 } 16456 /* 16457 * Update PHY info for smhba 16458 */ 16459 if (mptsas_smhba_phy_init(mpt)) { 16460 mutex_exit(&mpt->m_mutex); 16461 mptsas_log(mpt, CE_WARN, "mptsas phy update " 16462 "failed"); 16463 goto smp_create_done; 16464 } 16465 mutex_exit(&mpt->m_mutex); 16466 16467 mptsas_smhba_set_all_phy_props(mpt, pdip, numphys, phy_mask, 16468 &attached_devhdl); 16469 16470 if (ddi_prop_update_int(DDI_DEV_T_NONE, pdip, 16471 MPTSAS_NUM_PHYS, numphys) != 16472 DDI_PROP_SUCCESS) { 16473 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 16474 MPTSAS_NUM_PHYS); 16475 mptsas_log(mpt, CE_WARN, "mptsas update " 16476 "num phys props failed"); 16477 goto smp_create_done; 16478 } 16479 /* 16480 * Add parent's props for SMHBA support 16481 */ 16482 if (ddi_prop_update_string(DDI_DEV_T_NONE, pdip, 16483 SCSI_ADDR_PROP_ATTACHED_PORT, wwn_str) != 16484 DDI_PROP_SUCCESS) { 16485 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, 16486 SCSI_ADDR_PROP_ATTACHED_PORT); 16487 mptsas_log(mpt, CE_WARN, "mptsas update iport" 16488 "attached-port failed"); 16489 goto smp_create_done; 16490 } 16491 16492 smp_create_done: 16493 /* 16494 * If props were setup ok, online the lun 16495 */ 16496 if (ndi_rtn == NDI_SUCCESS) { 16497 /* 16498 * Try to online the new node 16499 */ 16500 ndi_rtn = ndi_devi_online(*smp_dip, NDI_ONLINE_ATTACH); 16501 } 16502 16503 /* 16504 * If success set rtn flag, else unwire alloc'd lun 16505 */ 16506 if (ndi_rtn != NDI_SUCCESS) { 16507 NDBG12(("mptsas unable to online " 16508 "SMP target %s", wwn_str)); 16509 ndi_prop_remove_all(*smp_dip); 16510 (void) ndi_devi_free(*smp_dip); 16511 } 16512 } 16513 16514 return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); 16515 } 16516 16517 /* smp transport routine */ 16518 static int mptsas_smp_start(struct smp_pkt *smp_pkt) 16519 { 16520 uint64_t wwn; 16521 Mpi2SmpPassthroughRequest_t req; 16522 Mpi2SmpPassthroughReply_t rep; 16523 uint32_t direction = 0; 16524 mptsas_t *mpt; 16525 int ret; 16526 uint64_t tmp64; 16527 16528 mpt = (mptsas_t *)smp_pkt->smp_pkt_address-> 16529 smp_a_hba_tran->smp_tran_hba_private; 16530 16531 bcopy(smp_pkt->smp_pkt_address->smp_a_wwn, &wwn, SAS_WWN_BYTE_SIZE); 16532 /* 16533 * Need to compose a SMP request message 16534 * and call mptsas_do_passthru() function 16535 */ 16536 bzero(&req, sizeof (req)); 16537 bzero(&rep, sizeof (rep)); 16538 req.PassthroughFlags = 0; 16539 req.PhysicalPort = 0xff; 16540 req.ChainOffset = 0; 16541 req.Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 16542 16543 if ((smp_pkt->smp_pkt_reqsize & 0xffff0000ul) != 0) { 16544 smp_pkt->smp_pkt_reason = ERANGE; 16545 return (DDI_FAILURE); 16546 } 16547 req.RequestDataLength = LE_16((uint16_t)(smp_pkt->smp_pkt_reqsize - 4)); 16548 16549 req.MsgFlags = 0; 16550 tmp64 = LE_64(wwn); 16551 bcopy(&tmp64, &req.SASAddress, SAS_WWN_BYTE_SIZE); 16552 if (smp_pkt->smp_pkt_rspsize > 0) { 16553 direction |= MPTSAS_PASS_THRU_DIRECTION_READ; 16554 } 16555 if (smp_pkt->smp_pkt_reqsize > 0) { 16556 direction |= MPTSAS_PASS_THRU_DIRECTION_WRITE; 16557 } 16558 16559 mutex_enter(&mpt->m_mutex); 16560 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, 16561 (uint8_t *)smp_pkt->smp_pkt_rsp, 16562 offsetof(Mpi2SmpPassthroughRequest_t, SGL), sizeof (rep), 16563 smp_pkt->smp_pkt_rspsize - 4, direction, 16564 (uint8_t *)smp_pkt->smp_pkt_req, smp_pkt->smp_pkt_reqsize - 4, 16565 smp_pkt->smp_pkt_timeout, FKIOCTL); 16566 mutex_exit(&mpt->m_mutex); 16567 if (ret != 0) { 16568 cmn_err(CE_WARN, "smp_start do passthru error %d", ret); 16569 smp_pkt->smp_pkt_reason = (uchar_t)(ret); 16570 return (DDI_FAILURE); 16571 } 16572 /* do passthrough success, check the smp status */ 16573 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 16574 switch (LE_16(rep.IOCStatus)) { 16575 case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 16576 smp_pkt->smp_pkt_reason = ENODEV; 16577 break; 16578 case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN: 16579 smp_pkt->smp_pkt_reason = EOVERFLOW; 16580 break; 16581 case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED: 16582 smp_pkt->smp_pkt_reason = EIO; 16583 break; 16584 default: 16585 mptsas_log(mpt, CE_NOTE, "smp_start: get unknown ioc" 16586 "status:%x", LE_16(rep.IOCStatus)); 16587 smp_pkt->smp_pkt_reason = EIO; 16588 break; 16589 } 16590 return (DDI_FAILURE); 16591 } 16592 if (rep.SASStatus != MPI2_SASSTATUS_SUCCESS) { 16593 mptsas_log(mpt, CE_NOTE, "smp_start: get error SAS status:%x", 16594 rep.SASStatus); 16595 smp_pkt->smp_pkt_reason = EIO; 16596 return (DDI_FAILURE); 16597 } 16598 16599 return (DDI_SUCCESS); 16600 } 16601 16602 /* 16603 * If we didn't get a match, we need to get sas page0 for each device, and 16604 * untill we get a match. If failed, return NULL 16605 */ 16606 static mptsas_target_t * 16607 mptsas_phy_to_tgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint8_t phy) 16608 { 16609 int i, j = 0; 16610 int rval = 0; 16611 uint16_t cur_handle; 16612 uint32_t page_address; 16613 mptsas_target_t *ptgt = NULL; 16614 16615 /* 16616 * PHY named device must be direct attached and attaches to 16617 * narrow port, if the iport is not parent of the device which 16618 * we are looking for. 16619 */ 16620 for (i = 0; i < MPTSAS_MAX_PHYS; i++) { 16621 if ((1 << i) & phymask) 16622 j++; 16623 } 16624 16625 if (j > 1) 16626 return (NULL); 16627 16628 /* 16629 * Must be a narrow port and single device attached to the narrow port 16630 * So the physical port num of device which is equal to the iport's 16631 * port num is the device what we are looking for. 16632 */ 16633 16634 if (mpt->m_phy_info[phy].phy_mask != phymask) 16635 return (NULL); 16636 16637 mutex_enter(&mpt->m_mutex); 16638 16639 ptgt = refhash_linear_search(mpt->m_targets, mptsas_target_eval_nowwn, 16640 &phy); 16641 if (ptgt != NULL) { 16642 mutex_exit(&mpt->m_mutex); 16643 return (ptgt); 16644 } 16645 16646 if (mpt->m_done_traverse_dev) { 16647 mutex_exit(&mpt->m_mutex); 16648 return (NULL); 16649 } 16650 16651 /* If didn't get a match, come here */ 16652 cur_handle = mpt->m_dev_handle; 16653 for (; ; ) { 16654 ptgt = NULL; 16655 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 16656 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)cur_handle; 16657 rval = mptsas_get_target_device_info(mpt, page_address, 16658 &cur_handle, &ptgt); 16659 if ((rval == DEV_INFO_FAIL_PAGE0) || 16660 (rval == DEV_INFO_FAIL_ALLOC)) { 16661 break; 16662 } 16663 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) || 16664 (rval == DEV_INFO_PHYS_DISK) || 16665 (rval == DEV_INFO_FAIL_GUID)) { 16666 continue; 16667 } 16668 mpt->m_dev_handle = cur_handle; 16669 16670 if ((ptgt->m_addr.mta_wwn == 0) && (ptgt->m_phynum == phy)) { 16671 break; 16672 } 16673 } 16674 16675 mutex_exit(&mpt->m_mutex); 16676 return (ptgt); 16677 } 16678 16679 /* 16680 * The ptgt->m_addr.mta_wwn contains the wwid for each disk. 16681 * For Raid volumes, we need to check m_raidvol[x].m_raidwwid 16682 * If we didn't get a match, we need to get sas page0 for each device, and 16683 * untill we get a match 16684 * If failed, return NULL 16685 */ 16686 static mptsas_target_t * 16687 mptsas_wwid_to_ptgt(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid) 16688 { 16689 int rval = 0; 16690 uint16_t cur_handle; 16691 uint32_t page_address; 16692 mptsas_target_t *tmp_tgt = NULL; 16693 mptsas_target_addr_t addr; 16694 16695 addr.mta_wwn = wwid; 16696 addr.mta_phymask = phymask; 16697 mutex_enter(&mpt->m_mutex); 16698 tmp_tgt = refhash_lookup(mpt->m_targets, &addr); 16699 if (tmp_tgt != NULL) { 16700 mutex_exit(&mpt->m_mutex); 16701 return (tmp_tgt); 16702 } 16703 16704 if (phymask == 0) { 16705 /* 16706 * It's IR volume 16707 */ 16708 rval = mptsas_get_raid_info(mpt); 16709 if (rval) { 16710 tmp_tgt = refhash_lookup(mpt->m_targets, &addr); 16711 } 16712 mutex_exit(&mpt->m_mutex); 16713 return (tmp_tgt); 16714 } 16715 16716 if (mpt->m_done_traverse_dev) { 16717 mutex_exit(&mpt->m_mutex); 16718 return (NULL); 16719 } 16720 16721 /* If didn't get a match, come here */ 16722 cur_handle = mpt->m_dev_handle; 16723 for (;;) { 16724 tmp_tgt = NULL; 16725 page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE & 16726 MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle; 16727 rval = mptsas_get_target_device_info(mpt, page_address, 16728 &cur_handle, &tmp_tgt); 16729 if ((rval == DEV_INFO_FAIL_PAGE0) || 16730 (rval == DEV_INFO_FAIL_ALLOC)) { 16731 tmp_tgt = NULL; 16732 break; 16733 } 16734 if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) || 16735 (rval == DEV_INFO_PHYS_DISK) || 16736 (rval == DEV_INFO_FAIL_GUID)) { 16737 continue; 16738 } 16739 mpt->m_dev_handle = cur_handle; 16740 if ((tmp_tgt->m_addr.mta_wwn) && 16741 (tmp_tgt->m_addr.mta_wwn == wwid) && 16742 (tmp_tgt->m_addr.mta_phymask == phymask)) { 16743 break; 16744 } 16745 } 16746 16747 mutex_exit(&mpt->m_mutex); 16748 return (tmp_tgt); 16749 } 16750 16751 static mptsas_smp_t * 16752 mptsas_wwid_to_psmp(mptsas_t *mpt, mptsas_phymask_t phymask, uint64_t wwid) 16753 { 16754 int rval = 0; 16755 uint16_t cur_handle; 16756 uint32_t page_address; 16757 mptsas_smp_t smp_node, *psmp = NULL; 16758 mptsas_target_addr_t addr; 16759 16760 addr.mta_wwn = wwid; 16761 addr.mta_phymask = phymask; 16762 mutex_enter(&mpt->m_mutex); 16763 psmp = refhash_lookup(mpt->m_smp_targets, &addr); 16764 if (psmp != NULL) { 16765 mutex_exit(&mpt->m_mutex); 16766 return (psmp); 16767 } 16768 16769 if (mpt->m_done_traverse_smp) { 16770 mutex_exit(&mpt->m_mutex); 16771 return (NULL); 16772 } 16773 16774 /* If didn't get a match, come here */ 16775 cur_handle = mpt->m_smp_devhdl; 16776 for (;;) { 16777 psmp = NULL; 16778 page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL & 16779 MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle; 16780 rval = mptsas_get_sas_expander_page0(mpt, page_address, 16781 &smp_node); 16782 if (rval != DDI_SUCCESS) { 16783 break; 16784 } 16785 mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl; 16786 psmp = mptsas_smp_alloc(mpt, &smp_node); 16787 ASSERT(psmp); 16788 if ((psmp->m_addr.mta_wwn) && (psmp->m_addr.mta_wwn == wwid) && 16789 (psmp->m_addr.mta_phymask == phymask)) { 16790 break; 16791 } 16792 } 16793 16794 mutex_exit(&mpt->m_mutex); 16795 return (psmp); 16796 } 16797 16798 mptsas_target_t * 16799 mptsas_tgt_alloc(refhash_t *refhash, uint16_t devhdl, uint64_t wwid, 16800 uint32_t devinfo, mptsas_phymask_t phymask, uint8_t phynum) 16801 { 16802 mptsas_target_t *tmp_tgt = NULL; 16803 mptsas_target_addr_t addr; 16804 16805 addr.mta_wwn = wwid; 16806 addr.mta_phymask = phymask; 16807 tmp_tgt = refhash_lookup(refhash, &addr); 16808 if (tmp_tgt != NULL) { 16809 NDBG20(("Hash item already exist")); 16810 tmp_tgt->m_deviceinfo = devinfo; 16811 tmp_tgt->m_devhdl = devhdl; /* XXX - duplicate? */ 16812 return (tmp_tgt); 16813 } 16814 tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP); 16815 if (tmp_tgt == NULL) { 16816 cmn_err(CE_WARN, "Fatal, allocated tgt failed"); 16817 return (NULL); 16818 } 16819 tmp_tgt->m_devhdl = devhdl; 16820 tmp_tgt->m_addr.mta_wwn = wwid; 16821 tmp_tgt->m_deviceinfo = devinfo; 16822 tmp_tgt->m_addr.mta_phymask = phymask; 16823 tmp_tgt->m_phynum = phynum; 16824 /* Initialized the tgt structure */ 16825 tmp_tgt->m_qfull_retries = QFULL_RETRIES; 16826 tmp_tgt->m_qfull_retry_interval = 16827 drv_usectohz(QFULL_RETRY_INTERVAL * 1000); 16828 tmp_tgt->m_t_throttle = MAX_THROTTLE; 16829 TAILQ_INIT(&tmp_tgt->m_active_cmdq); 16830 16831 refhash_insert(refhash, tmp_tgt); 16832 16833 return (tmp_tgt); 16834 } 16835 16836 static void 16837 mptsas_smp_target_copy(mptsas_smp_t *src, mptsas_smp_t *dst) 16838 { 16839 dst->m_devhdl = src->m_devhdl; 16840 dst->m_deviceinfo = src->m_deviceinfo; 16841 dst->m_pdevhdl = src->m_pdevhdl; 16842 dst->m_pdevinfo = src->m_pdevinfo; 16843 } 16844 16845 static mptsas_smp_t * 16846 mptsas_smp_alloc(mptsas_t *mpt, mptsas_smp_t *data) 16847 { 16848 mptsas_target_addr_t addr; 16849 mptsas_smp_t *ret_data; 16850 16851 addr.mta_wwn = data->m_addr.mta_wwn; 16852 addr.mta_phymask = data->m_addr.mta_phymask; 16853 ret_data = refhash_lookup(mpt->m_smp_targets, &addr); 16854 /* 16855 * If there's already a matching SMP target, update its fields 16856 * in place. Since the address is not changing, it's safe to do 16857 * this. We cannot just bcopy() here because the structure we've 16858 * been given has invalid hash links. 16859 */ 16860 if (ret_data != NULL) { 16861 mptsas_smp_target_copy(data, ret_data); 16862 return (ret_data); 16863 } 16864 16865 ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP); 16866 bcopy(data, ret_data, sizeof (mptsas_smp_t)); 16867 refhash_insert(mpt->m_smp_targets, ret_data); 16868 return (ret_data); 16869 } 16870 16871 /* 16872 * Functions for SGPIO LED support 16873 */ 16874 static dev_info_t * 16875 mptsas_get_dip_from_dev(dev_t dev, mptsas_phymask_t *phymask) 16876 { 16877 dev_info_t *dip; 16878 int prop; 16879 dip = e_ddi_hold_devi_by_dev(dev, 0); 16880 if (dip == NULL) 16881 return (dip); 16882 prop = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0, 16883 "phymask", 0); 16884 *phymask = (mptsas_phymask_t)prop; 16885 ddi_release_devi(dip); 16886 return (dip); 16887 } 16888 static mptsas_target_t * 16889 mptsas_addr_to_ptgt(mptsas_t *mpt, char *addr, mptsas_phymask_t phymask) 16890 { 16891 uint8_t phynum; 16892 uint64_t wwn; 16893 int lun; 16894 mptsas_target_t *ptgt = NULL; 16895 16896 if (mptsas_parse_address(addr, &wwn, &phynum, &lun) != DDI_SUCCESS) { 16897 return (NULL); 16898 } 16899 if (addr[0] == 'w') { 16900 ptgt = mptsas_wwid_to_ptgt(mpt, (int)phymask, wwn); 16901 } else { 16902 ptgt = mptsas_phy_to_tgt(mpt, (int)phymask, phynum); 16903 } 16904 return (ptgt); 16905 } 16906 16907 static int 16908 mptsas_flush_led_status(mptsas_t *mpt, mptsas_enclosure_t *mep, uint16_t idx) 16909 { 16910 uint32_t slotstatus = 0; 16911 16912 ASSERT3U(idx, <, mep->me_nslots); 16913 16914 /* Build an MPI2 Slot Status based on our view of the world */ 16915 if (mep->me_slotleds[idx] & (1 << (MPTSAS_LEDCTL_LED_IDENT - 1))) 16916 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST; 16917 if (mep->me_slotleds[idx] & (1 << (MPTSAS_LEDCTL_LED_FAIL - 1))) 16918 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT; 16919 if (mep->me_slotleds[idx] & (1 << (MPTSAS_LEDCTL_LED_OK2RM - 1))) 16920 slotstatus |= MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE; 16921 16922 /* Write it to the controller */ 16923 NDBG14(("mptsas_ioctl: set LED status %x for slot %x", 16924 slotstatus, idx + mep->me_fslot)); 16925 return (mptsas_send_sep(mpt, mep, idx, &slotstatus, 16926 MPI2_SEP_REQ_ACTION_WRITE_STATUS)); 16927 } 16928 16929 /* 16930 * send sep request, use enclosure/slot addressing 16931 */ 16932 static int 16933 mptsas_send_sep(mptsas_t *mpt, mptsas_enclosure_t *mep, uint16_t idx, 16934 uint32_t *status, uint8_t act) 16935 { 16936 Mpi2SepRequest_t req; 16937 Mpi2SepReply_t rep; 16938 int ret; 16939 uint16_t enctype; 16940 uint16_t slot; 16941 16942 ASSERT(mutex_owned(&mpt->m_mutex)); 16943 16944 /* 16945 * Look through the enclosures and make sure that this enclosure is 16946 * something that is directly attached device. If we didn't find an 16947 * enclosure for this device, don't send the ioctl. 16948 */ 16949 enctype = mep->me_flags & MPI2_SAS_ENCLS0_FLAGS_MNG_MASK; 16950 if (enctype != MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SES && 16951 enctype != MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SGPIO && 16952 enctype != MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_GPIO) { 16953 return (ENOTTY); 16954 } 16955 slot = idx + mep->me_fslot; 16956 16957 bzero(&req, sizeof (req)); 16958 bzero(&rep, sizeof (rep)); 16959 16960 req.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR; 16961 req.Action = act; 16962 req.Flags = MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS; 16963 req.EnclosureHandle = LE_16(mep->me_enchdl); 16964 req.Slot = LE_16(slot); 16965 if (act == MPI2_SEP_REQ_ACTION_WRITE_STATUS) { 16966 req.SlotStatus = LE_32(*status); 16967 } 16968 ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL, 16969 sizeof (req), sizeof (rep), 0, MPTSAS_PASS_THRU_DIRECTION_NONE, 16970 NULL, 0, 60, FKIOCTL); 16971 if (ret != 0) { 16972 mptsas_log(mpt, CE_NOTE, "mptsas_send_sep: passthru SEP " 16973 "Processor Request message error %d", ret); 16974 return (ret); 16975 } 16976 /* do passthrough success, check the ioc status */ 16977 if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) { 16978 mptsas_log(mpt, CE_NOTE, "send_sep act %x: ioc " 16979 "status:%x loginfo %x", act, LE_16(rep.IOCStatus), 16980 LE_32(rep.IOCLogInfo)); 16981 switch (LE_16(rep.IOCStatus) & MPI2_IOCSTATUS_MASK) { 16982 case MPI2_IOCSTATUS_INVALID_FUNCTION: 16983 case MPI2_IOCSTATUS_INVALID_VPID: 16984 case MPI2_IOCSTATUS_INVALID_FIELD: 16985 case MPI2_IOCSTATUS_INVALID_STATE: 16986 case MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED: 16987 case MPI2_IOCSTATUS_CONFIG_INVALID_ACTION: 16988 case MPI2_IOCSTATUS_CONFIG_INVALID_TYPE: 16989 case MPI2_IOCSTATUS_CONFIG_INVALID_PAGE: 16990 case MPI2_IOCSTATUS_CONFIG_INVALID_DATA: 16991 case MPI2_IOCSTATUS_CONFIG_NO_DEFAULTS: 16992 return (EINVAL); 16993 case MPI2_IOCSTATUS_BUSY: 16994 return (EBUSY); 16995 case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: 16996 return (EAGAIN); 16997 case MPI2_IOCSTATUS_INVALID_SGL: 16998 case MPI2_IOCSTATUS_INTERNAL_ERROR: 16999 case MPI2_IOCSTATUS_CONFIG_CANT_COMMIT: 17000 default: 17001 return (EIO); 17002 } 17003 } 17004 if (act != MPI2_SEP_REQ_ACTION_WRITE_STATUS) { 17005 *status = LE_32(rep.SlotStatus); 17006 } 17007 17008 return (0); 17009 } 17010 17011 int 17012 mptsas_dma_addr_create(mptsas_t *mpt, ddi_dma_attr_t dma_attr, 17013 ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp, caddr_t *dma_memp, 17014 uint32_t alloc_size, ddi_dma_cookie_t *cookiep) 17015 { 17016 ddi_dma_cookie_t new_cookie; 17017 size_t alloc_len; 17018 uint_t ncookie; 17019 17020 if (cookiep == NULL) 17021 cookiep = &new_cookie; 17022 17023 if (ddi_dma_alloc_handle(mpt->m_dip, &dma_attr, DDI_DMA_SLEEP, 17024 NULL, dma_hdp) != DDI_SUCCESS) { 17025 return (FALSE); 17026 } 17027 17028 if (ddi_dma_mem_alloc(*dma_hdp, alloc_size, &mpt->m_dev_acc_attr, 17029 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, dma_memp, &alloc_len, 17030 acc_hdp) != DDI_SUCCESS) { 17031 ddi_dma_free_handle(dma_hdp); 17032 *dma_hdp = NULL; 17033 return (FALSE); 17034 } 17035 17036 if (ddi_dma_addr_bind_handle(*dma_hdp, NULL, *dma_memp, alloc_len, 17037 (DDI_DMA_RDWR | DDI_DMA_CONSISTENT), DDI_DMA_SLEEP, NULL, 17038 cookiep, &ncookie) != DDI_DMA_MAPPED) { 17039 (void) ddi_dma_mem_free(acc_hdp); 17040 ddi_dma_free_handle(dma_hdp); 17041 *dma_hdp = NULL; 17042 return (FALSE); 17043 } 17044 17045 return (TRUE); 17046 } 17047 17048 void 17049 mptsas_dma_addr_destroy(ddi_dma_handle_t *dma_hdp, ddi_acc_handle_t *acc_hdp) 17050 { 17051 if (*dma_hdp == NULL) 17052 return; 17053 17054 (void) ddi_dma_unbind_handle(*dma_hdp); 17055 (void) ddi_dma_mem_free(acc_hdp); 17056 ddi_dma_free_handle(dma_hdp); 17057 *dma_hdp = NULL; 17058 } 17059 17060 /* 17061 * DDI UFM Callbacks 17062 */ 17063 static int 17064 mptsas_ufm_fill_image(ddi_ufm_handle_t *ufmh, void *arg, uint_t imgno, 17065 ddi_ufm_image_t *img) 17066 { 17067 if (imgno != 0) 17068 return (EINVAL); 17069 17070 ddi_ufm_image_set_desc(img, "IOC Firmware"); 17071 ddi_ufm_image_set_nslots(img, 1); 17072 17073 return (0); 17074 } 17075 17076 static int 17077 mptsas_ufm_fill_slot(ddi_ufm_handle_t *ufmh, void *arg, uint_t imgno, 17078 uint_t slotno, ddi_ufm_slot_t *slot) 17079 { 17080 mptsas_t *mpt = (mptsas_t *)arg; 17081 char *buf; 17082 17083 if (imgno != 0 || slotno != 0 || 17084 ddi_prop_lookup_string(DDI_DEV_T_ANY, mpt->m_dip, 17085 DDI_PROP_DONTPASS, "firmware-version", &buf) != DDI_PROP_SUCCESS) 17086 return (EINVAL); 17087 17088 ddi_ufm_slot_set_attrs(slot, DDI_UFM_ATTR_ACTIVE); 17089 ddi_ufm_slot_set_version(slot, buf); 17090 17091 ddi_prop_free(buf); 17092 17093 return (0); 17094 } 17095 17096 static int 17097 mptsas_ufm_getcaps(ddi_ufm_handle_t *ufmh, void *arg, ddi_ufm_cap_t *caps) 17098 { 17099 *caps = DDI_UFM_CAP_REPORT; 17100 17101 return (0); 17102 } 17103