xref: /onnv-gate/usr/src/uts/common/io/scsi/adapters/mpt_sas/mptsas.c (revision 11194:e429b4b36c3c)
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 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * Copyright (c) 2000 to 2009, LSI Corporation.
29  * All rights reserved.
30  *
31  * Redistribution and use in source and binary forms of all code within
32  * this file that is exclusively owned by LSI, with or without
33  * modification, is permitted provided that, in addition to the CDDL 1.0
34  * License requirements, the following conditions are met:
35  *
36  *    Neither the name of the author nor the names of its contributors may be
37  *    used to endorse or promote products derived from this software without
38  *    specific prior written permission.
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
43  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
44  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
45  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
46  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
47  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
48  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
51  * DAMAGE.
52  */
53 
54 /*
55  * mptsas - This is a driver based on LSI Logic's MPT2.0 interface.
56  *
57  */
58 
59 #if defined(lint) || defined(DEBUG)
60 #define	MPTSAS_DEBUG
61 #endif
62 
63 /*
64  * standard header files.
65  */
66 #include <sys/note.h>
67 #include <sys/scsi/scsi.h>
68 #include <sys/pci.h>
69 #include <sys/file.h>
70 #include <sys/policy.h>
71 #include <sys/sysevent.h>
72 #include <sys/sysevent/eventdefs.h>
73 #include <sys/sysevent/dr.h>
74 #include <sys/sata/sata_defs.h>
75 
76 #pragma pack(1)
77 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h>
78 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h>
79 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_cnfg.h>
80 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h>
81 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_ioc.h>
82 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_sas.h>
83 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_tool.h>
84 #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_raid.h>
85 #pragma pack()
86 
87 /*
88  * private header files.
89  *
90  */
91 #include <sys/scsi/impl/scsi_reset_notify.h>
92 #include <sys/scsi/adapters/mpt_sas/mptsas_var.h>
93 #include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h>
94 #include <sys/raidioctl.h>
95 
96 #include <sys/fs/dv_node.h>	/* devfs_clean */
97 
98 /*
99  * FMA header files
100  */
101 #include <sys/ddifm.h>
102 #include <sys/fm/protocol.h>
103 #include <sys/fm/util.h>
104 #include <sys/fm/io/ddi.h>
105 
106 /*
107  * autoconfiguration data and routines.
108  */
109 static int mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
110 static int mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
111 static int mptsas_power(dev_info_t *dip, int component, int level);
112 
113 /*
114  * cb_ops function
115  */
116 static int mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
117 	cred_t *credp, int *rval);
118 #ifndef	__sparc
119 static int mptsas_quiesce(dev_info_t *devi);
120 #endif	/* __sparc */
121 
122 /*
123  * Resource initilaization for hardware
124  */
125 static void mptsas_setup_cmd_reg(mptsas_t *mpt);
126 static void mptsas_disable_bus_master(mptsas_t *mpt);
127 static void mptsas_hba_fini(mptsas_t *mpt);
128 static void mptsas_cfg_fini(mptsas_t *mptsas_blkp);
129 static int mptsas_alloc_request_frames(mptsas_t *mpt);
130 static int mptsas_alloc_reply_frames(mptsas_t *mpt);
131 static int mptsas_alloc_free_queue(mptsas_t *mpt);
132 static int mptsas_alloc_post_queue(mptsas_t *mpt);
133 static int mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd);
134 static void mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd);
135 
136 /*
137  * SCSA function prototypes
138  */
139 static int mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt);
140 static int mptsas_scsi_reset(struct scsi_address *ap, int level);
141 static int mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt);
142 static int mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly);
143 static int mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value,
144     int tgtonly);
145 static void mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt);
146 static struct scsi_pkt *mptsas_scsi_init_pkt(struct scsi_address *ap,
147     struct scsi_pkt *pkt, struct buf *bp, int cmdlen, int statuslen,
148 	int tgtlen, int flags, int (*callback)(), caddr_t arg);
149 static void mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt);
150 static void mptsas_scsi_destroy_pkt(struct scsi_address *ap,
151     struct scsi_pkt *pkt);
152 static int mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
153     scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
154 static void mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
155     scsi_hba_tran_t *hba_tran, struct scsi_device *sd);
156 static int mptsas_scsi_reset_notify(struct scsi_address *ap, int flag,
157     void (*callback)(caddr_t), caddr_t arg);
158 static int mptsas_get_name(struct scsi_device *sd, char *name, int len);
159 static int mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len);
160 static int mptsas_scsi_quiesce(dev_info_t *dip);
161 static int mptsas_scsi_unquiesce(dev_info_t *dip);
162 static int mptsas_bus_config(dev_info_t *pdip, uint_t flags,
163     ddi_bus_config_op_t op, void *arg, dev_info_t **childp);
164 
165 /*
166  * SMP functions
167  */
168 static int mptsas_smp_start(struct smp_pkt *smp_pkt);
169 
170 /*
171  * internal function prototypes.
172  */
173 static int mptsas_quiesce_bus(mptsas_t *mpt);
174 static int mptsas_unquiesce_bus(mptsas_t *mpt);
175 
176 static int mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size);
177 static void mptsas_free_handshake_msg(mptsas_t *mpt);
178 
179 static void mptsas_ncmds_checkdrain(void *arg);
180 
181 static int mptsas_prepare_pkt(mptsas_cmd_t *cmd);
182 static int mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *sp);
183 static int mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *sp);
184 static void mptsas_accept_tx_waitq(mptsas_t *mpt);
185 
186 static int mptsas_do_detach(dev_info_t *dev);
187 static int mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl);
188 static int mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun,
189     struct scsi_pkt *pkt);
190 static int mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp);
191 
192 static void mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd);
193 static void mptsas_handle_event(void *args);
194 static int mptsas_handle_event_sync(void *args);
195 static void mptsas_handle_dr(void *args);
196 static void mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node,
197     dev_info_t *pdip);
198 
199 static void mptsas_restart_cmd(void *);
200 
201 static void mptsas_flush_hba(mptsas_t *mpt);
202 static void mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun,
203 	uint8_t tasktype);
204 static void mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd,
205     uchar_t reason, uint_t stat);
206 
207 static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2);
208 static void mptsas_process_intr(mptsas_t *mpt,
209     pMpi2ReplyDescriptorsUnion_t reply_desc_union);
210 static void mptsas_handle_scsi_io_success(mptsas_t *mpt,
211     pMpi2ReplyDescriptorsUnion_t reply_desc);
212 static void mptsas_handle_address_reply(mptsas_t *mpt,
213     pMpi2ReplyDescriptorsUnion_t reply_desc);
214 static int mptsas_wait_intr(mptsas_t *mpt, int polltime);
215 static void mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd,
216     uint32_t *control, pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl);
217 
218 static void mptsas_watch(void *arg);
219 static void mptsas_watchsubr(mptsas_t *mpt);
220 static void mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl);
221 
222 static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd);
223 static int mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
224     uint8_t *data, uint32_t request_size, uint32_t reply_size,
225     uint32_t data_size, uint32_t direction, uint8_t *dataout,
226     uint32_t dataout_size, short timeout, int mode);
227 static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl);
228 
229 static uint8_t mptsas_get_fw_diag_buffer_number(mptsas_t *mpt,
230     uint32_t unique_id);
231 static void mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd);
232 static int mptsas_post_fw_diag_buffer(mptsas_t *mpt,
233     mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code);
234 static int mptsas_release_fw_diag_buffer(mptsas_t *mpt,
235     mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code,
236     uint32_t diag_type);
237 static int mptsas_diag_register(mptsas_t *mpt,
238     mptsas_fw_diag_register_t *diag_register, uint32_t *return_code);
239 static int mptsas_diag_unregister(mptsas_t *mpt,
240     mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code);
241 static int mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query,
242     uint32_t *return_code);
243 static int mptsas_diag_read_buffer(mptsas_t *mpt,
244     mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf,
245     uint32_t *return_code, int ioctl_mode);
246 static int mptsas_diag_release(mptsas_t *mpt,
247     mptsas_fw_diag_release_t *diag_release, uint32_t *return_code);
248 static int mptsas_do_diag_action(mptsas_t *mpt, uint32_t action,
249     uint8_t *diag_action, uint32_t length, uint32_t *return_code,
250     int ioctl_mode);
251 static int mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *data,
252     int mode);
253 
254 static int mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd,
255     int cmdlen, int tgtlen, int statuslen, int kf);
256 static void mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd);
257 
258 static int mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags);
259 static void mptsas_kmem_cache_destructor(void *buf, void *cdrarg);
260 
261 static int mptsas_cache_frames_constructor(void *buf, void *cdrarg,
262     int kmflags);
263 static void mptsas_cache_frames_destructor(void *buf, void *cdrarg);
264 
265 static void mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply,
266     mptsas_cmd_t *cmd);
267 static void mptsas_check_task_mgt(mptsas_t *mpt,
268     pMpi2SCSIManagementReply_t reply, mptsas_cmd_t *cmd);
269 static int mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap,
270     mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp,
271     int *resid);
272 
273 static int mptsas_alloc_active_slots(mptsas_t *mpt, int flag);
274 static int mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
275 
276 static void mptsas_restart_hba(mptsas_t *mpt);
277 static void mptsas_restart_waitq(mptsas_t *mpt);
278 
279 static void mptsas_deliver_doneq_thread(mptsas_t *mpt);
280 static void mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd);
281 static void mptsas_doneq_mv(mptsas_t *mpt, uint64_t t);
282 
283 static mptsas_cmd_t *mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t);
284 static void mptsas_doneq_empty(mptsas_t *mpt);
285 static void mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg);
286 
287 static mptsas_cmd_t *mptsas_waitq_rm(mptsas_t *mpt);
288 static void mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd);
289 static mptsas_cmd_t *mptsas_tx_waitq_rm(mptsas_t *mpt);
290 static void mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd);
291 
292 
293 static void mptsas_start_watch_reset_delay();
294 static void mptsas_setup_bus_reset_delay(mptsas_t *mpt);
295 static void mptsas_watch_reset_delay(void *arg);
296 static int mptsas_watch_reset_delay_subr(mptsas_t *mpt);
297 
298 /*
299  * helper functions
300  */
301 static void mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
302 
303 static dev_info_t *mptsas_find_child(dev_info_t *pdip, char *name);
304 static dev_info_t *mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy);
305 static dev_info_t *mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr,
306     int lun);
307 static mdi_pathinfo_t *mptsas_find_path_addr(dev_info_t *pdip, uint64_t sasaddr,
308     int lun);
309 static mdi_pathinfo_t *mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy);
310 static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn);
311 
312 static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy,
313     int *lun);
314 static int mptsas_parse_smp_name(char *name, uint64_t *wwn);
315 
316 static mptsas_target_t *mptsas_phy_to_tgt(dev_info_t *pdip, uint8_t phy);
317 static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt, int port,
318     uint64_t wwid);
319 static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, int port,
320     uint64_t wwid);
321 
322 static int mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun,
323     uchar_t page, unsigned char *buf, int len, int *rlen, uchar_t evpd);
324 
325 static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
326     uint16_t *handle, mptsas_target_t **pptgt);
327 static void mptsas_update_phymask(mptsas_t *mpt);
328 
329 /*
330  * Enumeration / DR functions
331  */
332 static void mptsas_config_all(dev_info_t *pdip);
333 static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
334     dev_info_t **lundip);
335 static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
336     dev_info_t **lundip);
337 
338 static int mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt);
339 static int mptsas_offline_target(dev_info_t *pdip, char *name);
340 
341 static int mptsas_config_raid(dev_info_t *pdip, uint16_t target,
342     dev_info_t **dip);
343 
344 static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt);
345 static int mptsas_probe_lun(dev_info_t *pdip, int lun,
346     dev_info_t **dip, mptsas_target_t *ptgt);
347 
348 static int mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq,
349     dev_info_t **dip, mptsas_target_t *ptgt, int lun);
350 
351 static int mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *sd,
352     char *guid, dev_info_t **dip, mptsas_target_t *ptgt, int lun);
353 static int mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *sd,
354     char *guid, dev_info_t **dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt,
355     int lun);
356 
357 static void mptsas_offline_missed_luns(dev_info_t *pdip,
358     uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt);
359 static int mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
360     mdi_pathinfo_t *rpip, uint_t flags);
361 
362 static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn,
363     dev_info_t **smp_dip);
364 static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
365     uint_t flags);
366 
367 static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data,
368     int mode, int *rval);
369 static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data,
370     int mode, int *rval);
371 static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data,
372     int mode, int *rval);
373 static void mptsas_record_event(void *args);
374 static int mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data,
375     int mode);
376 
377 static void mptsas_hash_init(mptsas_hash_table_t *hashtab);
378 static void mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen);
379 static void mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data);
380 static void * mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1,
381     uint8_t key2);
382 static void * mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1,
383     uint8_t key2);
384 static void * mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos);
385 
386 mptsas_target_t *mptsas_tgt_alloc(mptsas_hash_table_t *, uint16_t, uint64_t,
387     uint32_t, uint8_t, uint8_t);
388 static mptsas_smp_t *mptsas_smp_alloc(mptsas_hash_table_t *hashtab,
389     mptsas_smp_t *data);
390 static void mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid,
391     uint8_t physport);
392 static void mptsas_tgt_free(mptsas_hash_table_t *, uint64_t, uint8_t);
393 static void * mptsas_search_by_devhdl(mptsas_hash_table_t *, uint16_t);
394 static int mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
395     dev_info_t **smp_dip);
396 
397 /*
398  * Power management functions
399  */
400 static void mptsas_idle_pm(void *arg);
401 static int mptsas_init_pm(mptsas_t *mpt);
402 
403 /*
404  * MPT MSI tunable:
405  *
406  * By default MSI is enabled on all supported platforms.
407  */
408 boolean_t mptsas_enable_msi = B_TRUE;
409 
410 static int mptsas_add_intrs(mptsas_t *, int);
411 static void mptsas_rem_intrs(mptsas_t *);
412 
413 /*
414  * FMA Prototypes
415  */
416 static void mptsas_fm_init(mptsas_t *mpt);
417 static void mptsas_fm_fini(mptsas_t *mpt);
418 static int mptsas_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *);
419 
420 extern pri_t minclsyspri, maxclsyspri;
421 
422 /*
423  * This device is created by the SCSI pseudo nexus driver (SCSI vHCI).  It is
424  * under this device that the paths to a physical device are created when
425  * MPxIO is used.
426  */
427 extern dev_info_t	*scsi_vhci_dip;
428 
429 /*
430  * Tunable timeout value for Inquiry VPD page 0x83
431  * By default the value is 30 seconds.
432  */
433 int mptsas_inq83_retry_timeout = 30;
434 
435 /*
436  * This is used to allocate memory for message frame storage, not for
437  * data I/O DMA. All message frames must be stored in the first 4G of
438  * physical memory.
439  */
440 ddi_dma_attr_t mptsas_dma_attrs = {
441 	DMA_ATTR_V0,	/* attribute layout version		*/
442 	0x0ull,		/* address low - should be 0 (longlong)	*/
443 	0xffffffffull,	/* address high - 32-bit max range	*/
444 	0x00ffffffull,	/* count max - max DMA object size	*/
445 	4,		/* allocation alignment requirements	*/
446 	0x78,		/* burstsizes - binary encoded values	*/
447 	1,		/* minxfer - gran. of DMA engine	*/
448 	0x00ffffffull,	/* maxxfer - gran. of DMA engine	*/
449 	0xffffffffull,	/* max segment size (DMA boundary)	*/
450 	MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length	*/
451 	512,		/* granularity - device transfer size	*/
452 	0		/* flags, set to 0			*/
453 };
454 
455 /*
456  * This is used for data I/O DMA memory allocation. (full 64-bit DMA
457  * physical addresses are supported.)
458  */
459 ddi_dma_attr_t mptsas_dma_attrs64 = {
460 	DMA_ATTR_V0,	/* attribute layout version		*/
461 	0x0ull,		/* address low - should be 0 (longlong)	*/
462 	0xffffffffffffffffull,	/* address high - 64-bit max	*/
463 	0x00ffffffull,	/* count max - max DMA object size	*/
464 	4,		/* allocation alignment requirements	*/
465 	0x78,		/* burstsizes - binary encoded values	*/
466 	1,		/* minxfer - gran. of DMA engine	*/
467 	0x00ffffffull,	/* maxxfer - gran. of DMA engine	*/
468 	0xffffffffull,	/* max segment size (DMA boundary)	*/
469 	MPTSAS_MAX_DMA_SEGS, /* scatter/gather list length	*/
470 	512,		/* granularity - device transfer size	*/
471 	DDI_DMA_RELAXED_ORDERING	/* flags, enable relaxed ordering */
472 };
473 
474 ddi_device_acc_attr_t mptsas_dev_attr = {
475 	DDI_DEVICE_ATTR_V0,
476 	DDI_STRUCTURE_LE_ACC,
477 	DDI_STRICTORDER_ACC
478 };
479 
480 static struct cb_ops mptsas_cb_ops = {
481 	scsi_hba_open,		/* open */
482 	scsi_hba_close,		/* close */
483 	nodev,			/* strategy */
484 	nodev,			/* print */
485 	nodev,			/* dump */
486 	nodev,			/* read */
487 	nodev,			/* write */
488 	mptsas_ioctl,		/* ioctl */
489 	nodev,			/* devmap */
490 	nodev,			/* mmap */
491 	nodev,			/* segmap */
492 	nochpoll,		/* chpoll */
493 	ddi_prop_op,		/* cb_prop_op */
494 	NULL,			/* streamtab */
495 	D_MP,			/* cb_flag */
496 	CB_REV,			/* rev */
497 	nodev,			/* aread */
498 	nodev			/* awrite */
499 };
500 
501 static struct dev_ops mptsas_ops = {
502 	DEVO_REV,		/* devo_rev, */
503 	0,			/* refcnt  */
504 	ddi_no_info,		/* info */
505 	nulldev,		/* identify */
506 	nulldev,		/* probe */
507 	mptsas_attach,		/* attach */
508 	mptsas_detach,		/* detach */
509 	nodev,			/* reset */
510 	&mptsas_cb_ops,		/* driver operations */
511 	NULL,			/* bus operations */
512 	mptsas_power,		/* power management */
513 #ifdef	__sparc
514 	ddi_quiesce_not_needed
515 #else
516 	mptsas_quiesce		/* quiesce */
517 #endif	/* __sparc */
518 };
519 
520 
521 #define	MPTSAS_MOD_STRING "MPTSAS HBA Driver 00.00.00.21"
522 
523 static struct modldrv modldrv = {
524 	&mod_driverops,	/* Type of module. This one is a driver */
525 	MPTSAS_MOD_STRING, /* Name of the module. */
526 	&mptsas_ops,	/* driver ops */
527 };
528 
529 static struct modlinkage modlinkage = {
530 	MODREV_1, &modldrv, NULL
531 };
532 #define	TARGET_PROP	"target"
533 #define	LUN_PROP	"lun"
534 #define	SAS_PROP	"sas-mpt"
535 #define	MDI_GUID	"wwn"
536 #define	NDI_GUID	"guid"
537 #define	MPTSAS_DEV_GONE	"mptsas_dev_gone"
538 
539 /*
540  * Local static data
541  */
542 #if defined(MPTSAS_DEBUG)
543 uint32_t mptsas_debug_flags = 0;
544 #endif	/* defined(MPTSAS_DEBUG) */
545 uint32_t mptsas_debug_resets = 0;
546 
547 static kmutex_t		mptsas_global_mutex;
548 static void		*mptsas_state;		/* soft	state ptr */
549 static krwlock_t	mptsas_global_rwlock;
550 
551 static kmutex_t		mptsas_log_mutex;
552 static char		mptsas_log_buf[256];
553 _NOTE(MUTEX_PROTECTS_DATA(mptsas_log_mutex, mptsas_log_buf))
554 
555 static mptsas_t *mptsas_head, *mptsas_tail;
556 static clock_t mptsas_scsi_watchdog_tick;
557 static clock_t mptsas_tick;
558 static timeout_id_t mptsas_reset_watch;
559 static timeout_id_t mptsas_timeout_id;
560 static int mptsas_timeouts_enabled = 0;
561 
562 /*
563  * warlock directives
564  */
565 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt \
566 	mptsas_cmd NcrTableIndirect buf scsi_cdb scsi_status))
567 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", smp_pkt))
568 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address))
569 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", mptsas_tgt_private))
570 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_hba_tran::tran_tgt_private))
571 
572 #ifdef MPTSAS_DEBUG
573 void debug_enter(char *);
574 #endif
575 
576 /*
577  * Notes:
578  *	- scsi_hba_init(9F) initializes SCSI HBA modules
579  *	- must call scsi_hba_fini(9F) if modload() fails
580  */
581 int
582 _init(void)
583 {
584 	int status;
585 	/* CONSTCOND */
586 	ASSERT(NO_COMPETING_THREADS);
587 
588 	NDBG0(("_init"));
589 
590 	status = ddi_soft_state_init(&mptsas_state, MPTSAS_SIZE,
591 	    MPTSAS_INITIAL_SOFT_SPACE);
592 	if (status != 0) {
593 		return (status);
594 	}
595 
596 	if ((status = scsi_hba_init(&modlinkage)) != 0) {
597 		ddi_soft_state_fini(&mptsas_state);
598 		return (status);
599 	}
600 
601 	mutex_init(&mptsas_global_mutex, NULL, MUTEX_DRIVER, NULL);
602 	rw_init(&mptsas_global_rwlock, NULL, RW_DRIVER, NULL);
603 	mutex_init(&mptsas_log_mutex, NULL, MUTEX_DRIVER, NULL);
604 
605 	if ((status = mod_install(&modlinkage)) != 0) {
606 		mutex_destroy(&mptsas_log_mutex);
607 		rw_destroy(&mptsas_global_rwlock);
608 		mutex_destroy(&mptsas_global_mutex);
609 		ddi_soft_state_fini(&mptsas_state);
610 		scsi_hba_fini(&modlinkage);
611 	}
612 
613 	return (status);
614 }
615 
616 /*
617  * Notes:
618  *	- scsi_hba_fini(9F) uninitializes SCSI HBA modules
619  */
620 int
621 _fini(void)
622 {
623 	int	status;
624 	/* CONSTCOND */
625 	ASSERT(NO_COMPETING_THREADS);
626 
627 	NDBG0(("_fini"));
628 
629 	if ((status = mod_remove(&modlinkage)) == 0) {
630 		ddi_soft_state_fini(&mptsas_state);
631 		scsi_hba_fini(&modlinkage);
632 		mutex_destroy(&mptsas_global_mutex);
633 		rw_destroy(&mptsas_global_rwlock);
634 		mutex_destroy(&mptsas_log_mutex);
635 	}
636 	return (status);
637 }
638 
639 /*
640  * The loadable-module _info(9E) entry point
641  */
642 int
643 _info(struct modinfo *modinfop)
644 {
645 	/* CONSTCOND */
646 	ASSERT(NO_COMPETING_THREADS);
647 	NDBG0(("mptsas _info"));
648 
649 	return (mod_info(&modlinkage, modinfop));
650 }
651 
652 
653 static int
654 mptsas_iport_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
655 {
656 	dev_info_t		*pdip;
657 	mptsas_t		*mpt;
658 	scsi_hba_tran_t		*hba_tran;
659 	char			*iport = NULL;
660 	char			phymask[8];
661 	uint8_t			phy_mask = 0;
662 	int			physport = -1;
663 	int			dynamic_port = 0;
664 	uint32_t		page_address;
665 	char			initiator_wwnstr[MPTSAS_WWN_STRLEN];
666 	int			rval = DDI_FAILURE;
667 	int			i = 0;
668 	uint64_t		wwid = 0;
669 	uint8_t			portwidth = 0;
670 
671 	/* CONSTCOND */
672 	ASSERT(NO_COMPETING_THREADS);
673 
674 	switch (cmd) {
675 	case DDI_ATTACH:
676 		break;
677 
678 	case DDI_RESUME:
679 		/*
680 		 * If this a scsi-iport node, nothing to do here.
681 		 */
682 		return (DDI_SUCCESS);
683 
684 	default:
685 		return (DDI_FAILURE);
686 	}
687 
688 	pdip = ddi_get_parent(dip);
689 
690 	if ((hba_tran = ndi_flavorv_get(pdip, SCSA_FLAVOR_SCSI_DEVICE)) ==
691 	    NULL) {
692 		cmn_err(CE_WARN, "Failed attach iport because fail to "
693 		    "get tran vector for the HBA node");
694 		return (DDI_FAILURE);
695 	}
696 
697 	mpt = TRAN2MPT(hba_tran);
698 	ASSERT(mpt != NULL);
699 	if (mpt == NULL)
700 		return (DDI_FAILURE);
701 
702 	if ((hba_tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) ==
703 	    NULL) {
704 		mptsas_log(mpt, CE_WARN, "Failed attach iport because fail to "
705 		    "get tran vector for the iport node");
706 		return (DDI_FAILURE);
707 	}
708 
709 	/*
710 	 * Overwrite parent's tran_hba_private to iport's tran vector
711 	 */
712 	hba_tran->tran_hba_private = mpt;
713 
714 	ddi_report_dev(dip);
715 
716 	/*
717 	 * Get SAS address for initiator port according dev_handle
718 	 */
719 	iport = ddi_get_name_addr(dip);
720 	if (iport && strncmp(iport, "v0", 2) == 0) {
721 		return (DDI_SUCCESS);
722 	}
723 
724 	mutex_enter(&mpt->m_mutex);
725 	for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
726 		bzero(phymask, sizeof (phymask));
727 		(void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask);
728 		if (strcmp(phymask, iport) == 0) {
729 			break;
730 		}
731 	}
732 
733 	if (i == MPTSAS_MAX_PHYS) {
734 		mptsas_log(mpt, CE_WARN, "Failed attach port %s because port"
735 		    "seems not exist", iport);
736 		mutex_exit(&mpt->m_mutex);
737 		return (DDI_FAILURE);
738 	}
739 
740 	phy_mask = mpt->m_phy_info[i].phy_mask;
741 	physport = mpt->m_phy_info[i].port_num;
742 
743 	if (mpt->m_phy_info[i].port_flags & AUTO_PORT_CONFIGURATION)
744 		dynamic_port = 1;
745 	else
746 		dynamic_port = 0;
747 
748 	page_address = (MPI2_SASPORT_PGAD_FORM_PORT_NUM |
749 	    (MPI2_SASPORT_PGAD_PORTNUMBER_MASK & physport));
750 
751 	rval = mptsas_get_sas_port_page0(mpt, page_address, &wwid, &portwidth);
752 	if (rval != DDI_SUCCESS) {
753 		mptsas_log(mpt, CE_WARN, "Failed attach port %s because get"
754 		    "SAS address of initiator failed!", iport);
755 		mutex_exit(&mpt->m_mutex);
756 		return (DDI_FAILURE);
757 	}
758 	mutex_exit(&mpt->m_mutex);
759 
760 	bzero(initiator_wwnstr, sizeof (initiator_wwnstr));
761 	(void) sprintf(initiator_wwnstr, "%016"PRIx64,
762 	    wwid);
763 
764 	if (ddi_prop_update_string(DDI_DEV_T_NONE, dip,
765 	    "initiator-port", initiator_wwnstr) !=
766 	    DDI_PROP_SUCCESS) {
767 		(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "initiator-port");
768 		return (DDI_FAILURE);
769 	}
770 
771 	if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
772 	    "phymask", phy_mask) !=
773 	    DDI_PROP_SUCCESS) {
774 		(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "phymask");
775 		return (DDI_FAILURE);
776 	}
777 
778 	if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
779 	    "dynamic-port", dynamic_port) !=
780 	    DDI_PROP_SUCCESS) {
781 		(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "dynamic-port");
782 		return (DDI_FAILURE);
783 	}
784 	/*
785 	 * register sas hba iport with mdi (MPxIO/vhci)
786 	 */
787 	if (mdi_phci_register(MDI_HCI_CLASS_SCSI,
788 	    dip, 0) == MDI_SUCCESS) {
789 		mpt->m_mpxio_enable = TRUE;
790 	}
791 	return (DDI_SUCCESS);
792 }
793 
794 /*
795  * Notes:
796  *	Set up all device state and allocate data structures,
797  *	mutexes, condition variables, etc. for device operation.
798  *	Add interrupts needed.
799  *	Return DDI_SUCCESS if device is ready, else return DDI_FAILURE.
800  */
801 static int
802 mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
803 {
804 	mptsas_t		*mpt = NULL;
805 	int			instance, i, j;
806 	int			doneq_thread_num;
807 	char			buf[64];
808 	char			intr_added = 0;
809 	char			map_setup = 0;
810 	char			config_setup = 0;
811 	char			hba_attach_setup = 0;
812 	char			smp_attach_setup = 0;
813 	char			mutex_init_done = 0;
814 	char			event_taskq_create = 0;
815 	char			dr_taskq_create = 0;
816 	char			doneq_thread_create = 0;
817 	scsi_hba_tran_t		*hba_tran;
818 	int			intr_types;
819 	uint_t			mem_bar = MEM_SPACE;
820 	uint8_t			mask = 0x0;
821 	int			tran_flags = 0;
822 	int			rval = DDI_FAILURE;
823 
824 	/* CONSTCOND */
825 	ASSERT(NO_COMPETING_THREADS);
826 
827 	if (scsi_hba_iport_unit_address(dip)) {
828 		return (mptsas_iport_attach(dip, cmd));
829 	}
830 
831 	switch (cmd) {
832 	case DDI_ATTACH:
833 		break;
834 
835 	case DDI_RESUME:
836 		if ((hba_tran = ddi_get_driver_private(dip)) == NULL)
837 			return (DDI_FAILURE);
838 
839 		mpt = TRAN2MPT(hba_tran);
840 
841 		if (!mpt) {
842 			return (DDI_FAILURE);
843 		}
844 
845 		/*
846 		 * Reset hardware and softc to "no outstanding commands"
847 		 * Note	that a check condition can result on first command
848 		 * to a	target.
849 		 */
850 		mutex_enter(&mpt->m_mutex);
851 
852 		/*
853 		 * raise power.
854 		 */
855 		if (mpt->m_options & MPTSAS_OPT_PM) {
856 			mutex_exit(&mpt->m_mutex);
857 			(void) pm_busy_component(dip, 0);
858 			if (mpt->m_power_level != PM_LEVEL_D0) {
859 				rval = pm_raise_power(dip, 0, PM_LEVEL_D0);
860 			} else {
861 				rval = pm_power_has_changed(dip, 0,
862 				    PM_LEVEL_D0);
863 			}
864 			if (rval == DDI_SUCCESS) {
865 				mutex_enter(&mpt->m_mutex);
866 			} else {
867 				/*
868 				 * The pm_raise_power() call above failed,
869 				 * and that can only occur if we were unable
870 				 * to reset the hardware.  This is probably
871 				 * due to unhealty hardware, and because
872 				 * important filesystems(such as the root
873 				 * filesystem) could be on the attached disks,
874 				 * it would not be a good idea to continue,
875 				 * as we won't be entirely certain we are
876 				 * writing correct data.  So we panic() here
877 				 * to not only prevent possible data corruption,
878 				 * but to give developers or end users a hope
879 				 * of identifying and correcting any problems.
880 				 */
881 				fm_panic("mptsas could not reset hardware "
882 				    "during resume");
883 			}
884 		}
885 
886 		mpt->m_suspended = 0;
887 
888 		/*
889 		 * Reinitialize ioc
890 		 */
891 		if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) {
892 			mutex_exit(&mpt->m_mutex);
893 			if (mpt->m_options & MPTSAS_OPT_PM) {
894 				(void) pm_idle_component(dip, 0);
895 			}
896 			fm_panic("mptsas init chip fail during resume");
897 		}
898 		/*
899 		 * mptsas_update_driver_data needs interrupts so enable them
900 		 * first.
901 		 */
902 		MPTSAS_ENABLE_INTR(mpt);
903 		mptsas_update_driver_data(mpt);
904 
905 		/* start requests, if possible */
906 		mptsas_restart_hba(mpt);
907 
908 		mutex_exit(&mpt->m_mutex);
909 
910 		/*
911 		 * Restart watch thread
912 		 */
913 		mutex_enter(&mptsas_global_mutex);
914 		if (mptsas_timeout_id == 0) {
915 			mptsas_timeout_id = timeout(mptsas_watch, NULL,
916 			    mptsas_tick);
917 			mptsas_timeouts_enabled = 1;
918 		}
919 		mutex_exit(&mptsas_global_mutex);
920 
921 		/* report idle status to pm framework */
922 		if (mpt->m_options & MPTSAS_OPT_PM) {
923 			(void) pm_idle_component(dip, 0);
924 		}
925 
926 		return (DDI_SUCCESS);
927 
928 	default:
929 		return (DDI_FAILURE);
930 
931 	}
932 
933 	instance = ddi_get_instance(dip);
934 
935 	/*
936 	 * Allocate softc information.
937 	 */
938 	if (ddi_soft_state_zalloc(mptsas_state, instance) != DDI_SUCCESS) {
939 		mptsas_log(NULL, CE_WARN,
940 		    "mptsas%d: cannot allocate soft state", instance);
941 		goto fail;
942 	}
943 
944 	mpt = ddi_get_soft_state(mptsas_state, instance);
945 
946 	if (mpt == NULL) {
947 		mptsas_log(NULL, CE_WARN,
948 		    "mptsas%d: cannot get soft state", instance);
949 		goto fail;
950 	}
951 
952 	/* Allocate a transport structure */
953 	hba_tran = mpt->m_tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
954 	ASSERT(mpt->m_tran != NULL);
955 
956 	/* Indicate that we are 'sizeof (scsi_*(9S))' clean. */
957 	scsi_size_clean(dip);
958 
959 	mpt->m_dip = dip;
960 	mpt->m_instance = instance;
961 
962 	/* Make a per-instance copy of the structures */
963 	mpt->m_io_dma_attr = mptsas_dma_attrs64;
964 	mpt->m_msg_dma_attr = mptsas_dma_attrs;
965 	mpt->m_dev_acc_attr = mptsas_dev_attr;
966 
967 	/*
968 	 * Initialize FMA
969 	 */
970 	mpt->m_fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, mpt->m_dip,
971 	    DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
972 	    DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
973 	    DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
974 
975 	mptsas_fm_init(mpt);
976 
977 	if (pci_config_setup(mpt->m_dip,
978 	    &mpt->m_config_handle) != DDI_SUCCESS) {
979 		mptsas_log(mpt, CE_WARN, "cannot map configuration space.");
980 		goto fail;
981 	}
982 	config_setup++;
983 
984 	if (mptsas_alloc_handshake_msg(mpt,
985 	    sizeof (Mpi2SCSITaskManagementRequest_t)) == DDI_FAILURE) {
986 		mptsas_log(mpt, CE_WARN, "cannot initialize handshake msg.");
987 		goto fail;
988 	}
989 
990 	/*
991 	 * This is a workaround for a XMITS ASIC bug which does not
992 	 * drive the CBE upper bits.
993 	 */
994 	if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) &
995 	    PCI_STAT_PERROR) {
996 		pci_config_put16(mpt->m_config_handle, PCI_CONF_STAT,
997 		    PCI_STAT_PERROR);
998 	}
999 
1000 	/*
1001 	 * Setup configuration space
1002 	 */
1003 	if (mptsas_config_space_init(mpt) == FALSE) {
1004 		mptsas_log(mpt, CE_WARN, "mptsas_config_space_init failed");
1005 		goto fail;
1006 	}
1007 
1008 	if (ddi_regs_map_setup(dip, mem_bar, (caddr_t *)&mpt->m_reg,
1009 	    0, 0, &mpt->m_dev_acc_attr, &mpt->m_datap) != DDI_SUCCESS) {
1010 		mptsas_log(mpt, CE_WARN, "map setup failed");
1011 		goto fail;
1012 	}
1013 	map_setup++;
1014 
1015 	/*
1016 	 * A taskq is created for dealing with the event handler
1017 	 */
1018 	if ((mpt->m_event_taskq = ddi_taskq_create(dip, "mptsas_event_taskq",
1019 	    1, TASKQ_DEFAULTPRI, 0)) == NULL) {
1020 		mptsas_log(mpt, CE_NOTE, "ddi_taskq_create failed");
1021 		goto fail;
1022 	}
1023 	event_taskq_create++;
1024 
1025 	/*
1026 	 * A taskq is created for dealing with dr events
1027 	 */
1028 	if ((mpt->m_dr_taskq = ddi_taskq_create(dip,
1029 	    "mptsas_dr_taskq",
1030 	    1, TASKQ_DEFAULTPRI, 0)) == NULL) {
1031 		mptsas_log(mpt, CE_NOTE, "ddi_taskq_create for discovery "
1032 		    "failed");
1033 		goto fail;
1034 	}
1035 	dr_taskq_create++;
1036 
1037 	mpt->m_doneq_thread_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1038 	    0, "mptsas_doneq_thread_threshold_prop", 10);
1039 	mpt->m_doneq_length_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1040 	    0, "mptsas_doneq_length_threshold_prop", 8);
1041 	mpt->m_doneq_thread_n = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1042 	    0, "mptsas_doneq_thread_n_prop", 8);
1043 
1044 	if (mpt->m_doneq_thread_n) {
1045 		cv_init(&mpt->m_doneq_thread_cv, NULL, CV_DRIVER, NULL);
1046 		mutex_init(&mpt->m_doneq_mutex, NULL, MUTEX_DRIVER, NULL);
1047 
1048 		mutex_enter(&mpt->m_doneq_mutex);
1049 		mpt->m_doneq_thread_id =
1050 		    kmem_zalloc(sizeof (mptsas_doneq_thread_list_t)
1051 		    * mpt->m_doneq_thread_n, KM_SLEEP);
1052 
1053 		for (j = 0; j < mpt->m_doneq_thread_n; j++) {
1054 			cv_init(&mpt->m_doneq_thread_id[j].cv, NULL,
1055 			    CV_DRIVER, NULL);
1056 			mutex_init(&mpt->m_doneq_thread_id[j].mutex, NULL,
1057 			    MUTEX_DRIVER, NULL);
1058 			mutex_enter(&mpt->m_doneq_thread_id[j].mutex);
1059 			mpt->m_doneq_thread_id[j].flag |=
1060 			    MPTSAS_DONEQ_THREAD_ACTIVE;
1061 			mpt->m_doneq_thread_id[j].arg.mpt = mpt;
1062 			mpt->m_doneq_thread_id[j].arg.t = j;
1063 			mpt->m_doneq_thread_id[j].threadp =
1064 			    thread_create(NULL, 0, mptsas_doneq_thread,
1065 			    &mpt->m_doneq_thread_id[j].arg,
1066 			    0, &p0, TS_RUN, minclsyspri);
1067 			mpt->m_doneq_thread_id[j].donetail =
1068 			    &mpt->m_doneq_thread_id[j].doneq;
1069 			mutex_exit(&mpt->m_doneq_thread_id[j].mutex);
1070 		}
1071 		mutex_exit(&mpt->m_doneq_mutex);
1072 		doneq_thread_create++;
1073 	}
1074 
1075 	/* Get supported interrupt types */
1076 	if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) {
1077 		mptsas_log(mpt, CE_WARN, "ddi_intr_get_supported_types "
1078 		    "failed\n");
1079 		goto fail;
1080 	}
1081 
1082 	NDBG6(("ddi_intr_get_supported_types() returned: 0x%x", intr_types));
1083 
1084 	if (mptsas_enable_msi && (intr_types & DDI_INTR_TYPE_MSI)) {
1085 		/*
1086 		 * Try MSI, but fall back to FIXED
1087 		 */
1088 		if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_MSI) == DDI_SUCCESS) {
1089 			NDBG0(("Using MSI interrupt type"));
1090 			mpt->m_intr_type = DDI_INTR_TYPE_MSI;
1091 			goto intr_done;
1092 		}
1093 	}
1094 
1095 	if (intr_types & DDI_INTR_TYPE_FIXED) {
1096 
1097 		if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_FIXED) == DDI_SUCCESS) {
1098 			NDBG0(("Using FIXED interrupt type"));
1099 			mpt->m_intr_type = DDI_INTR_TYPE_FIXED;
1100 
1101 			goto intr_done;
1102 		}
1103 
1104 		NDBG0(("FIXED interrupt registration failed"));
1105 	}
1106 
1107 	goto fail;
1108 
1109 intr_done:
1110 	intr_added++;
1111 
1112 	/* Initialize mutex used in interrupt handler */
1113 	mutex_init(&mpt->m_mutex, NULL, MUTEX_DRIVER,
1114 	    DDI_INTR_PRI(mpt->m_intr_pri));
1115 	mutex_init(&mpt->m_tx_waitq_mutex, NULL, MUTEX_DRIVER,
1116 	    DDI_INTR_PRI(mpt->m_intr_pri));
1117 	cv_init(&mpt->m_cv, NULL, CV_DRIVER, NULL);
1118 	cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL);
1119 	cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL);
1120 	cv_init(&mpt->m_config_cv, NULL, CV_DRIVER, NULL);
1121 	cv_init(&mpt->m_fw_diag_cv, NULL, CV_DRIVER, NULL);
1122 	mutex_init_done++;
1123 
1124 	/*
1125 	 * Disable hardware interrupt since we're not ready to
1126 	 * handle it yet.
1127 	 */
1128 	MPTSAS_DISABLE_INTR(mpt);
1129 
1130 	/*
1131 	 * Enable interrupts
1132 	 */
1133 	if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) {
1134 		/* Call ddi_intr_block_enable() for MSI interrupts */
1135 		(void) ddi_intr_block_enable(mpt->m_htable, mpt->m_intr_cnt);
1136 	} else {
1137 		/* Call ddi_intr_enable for MSI or FIXED interrupts */
1138 		for (i = 0; i < mpt->m_intr_cnt; i++) {
1139 			(void) ddi_intr_enable(mpt->m_htable[i]);
1140 		}
1141 	}
1142 
1143 	mutex_enter(&mpt->m_mutex);
1144 	/*
1145 	 * Initialize power management component
1146 	 */
1147 	if (mpt->m_options & MPTSAS_OPT_PM) {
1148 		if (mptsas_init_pm(mpt)) {
1149 			mutex_exit(&mpt->m_mutex);
1150 			mptsas_log(mpt, CE_WARN, "mptsas pm initialization "
1151 			    "failed");
1152 			goto fail;
1153 		}
1154 	}
1155 
1156 	/*
1157 	 * Initialize chip
1158 	 */
1159 	if (mptsas_init_chip(mpt, TRUE) == DDI_FAILURE) {
1160 		mutex_exit(&mpt->m_mutex);
1161 		mptsas_log(mpt, CE_WARN, "mptsas chip initialization failed");
1162 		goto fail;
1163 	}
1164 	mutex_exit(&mpt->m_mutex);
1165 
1166 	/*
1167 	 * initialize SCSI HBA transport structure
1168 	 */
1169 	hba_tran->tran_hba_private	= mpt;
1170 	hba_tran->tran_tgt_private	= NULL;
1171 
1172 	hba_tran->tran_tgt_init		= mptsas_scsi_tgt_init;
1173 	hba_tran->tran_tgt_free		= mptsas_scsi_tgt_free;
1174 
1175 	hba_tran->tran_start		= mptsas_scsi_start;
1176 	hba_tran->tran_reset		= mptsas_scsi_reset;
1177 	hba_tran->tran_abort		= mptsas_scsi_abort;
1178 	hba_tran->tran_getcap		= mptsas_scsi_getcap;
1179 	hba_tran->tran_setcap		= mptsas_scsi_setcap;
1180 	hba_tran->tran_init_pkt		= mptsas_scsi_init_pkt;
1181 	hba_tran->tran_destroy_pkt	= mptsas_scsi_destroy_pkt;
1182 
1183 	hba_tran->tran_dmafree		= mptsas_scsi_dmafree;
1184 	hba_tran->tran_sync_pkt		= mptsas_scsi_sync_pkt;
1185 	hba_tran->tran_reset_notify	= mptsas_scsi_reset_notify;
1186 
1187 	hba_tran->tran_get_bus_addr	= mptsas_get_bus_addr;
1188 	hba_tran->tran_get_name		= mptsas_get_name;
1189 
1190 	hba_tran->tran_quiesce		= mptsas_scsi_quiesce;
1191 	hba_tran->tran_unquiesce	= mptsas_scsi_unquiesce;
1192 	hba_tran->tran_bus_reset	= NULL;
1193 
1194 	hba_tran->tran_add_eventcall	= NULL;
1195 	hba_tran->tran_get_eventcookie	= NULL;
1196 	hba_tran->tran_post_event	= NULL;
1197 	hba_tran->tran_remove_eventcall	= NULL;
1198 
1199 	hba_tran->tran_bus_config	= mptsas_bus_config;
1200 
1201 	hba_tran->tran_interconnect_type = INTERCONNECT_SAS;
1202 
1203 	if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) {
1204 		goto fail;
1205 	}
1206 
1207 	/*
1208 	 * Register the iport for multiple port HBA
1209 	 */
1210 	/*
1211 	 * initial value of mask is 0
1212 	 */
1213 	mutex_enter(&mpt->m_mutex);
1214 	for (i = 0; i < mpt->m_num_phys; i++) {
1215 		uint8_t	phy_mask = 0x00;
1216 		char phy_mask_name[8];
1217 		uint8_t current_port;
1218 
1219 		if (mpt->m_phy_info[i].attached_devhdl == 0)
1220 			continue;
1221 
1222 		bzero(phy_mask_name, sizeof (phy_mask_name));
1223 
1224 		current_port = mpt->m_phy_info[i].port_num;
1225 
1226 		if ((mask & (1 << i)) != 0)
1227 			continue;
1228 
1229 		for (j = 0; j < mpt->m_num_phys; j++) {
1230 			if (mpt->m_phy_info[j].attached_devhdl &&
1231 			    (mpt->m_phy_info[j].port_num == current_port)) {
1232 				phy_mask |= (1 << j);
1233 			}
1234 		}
1235 		mask = mask | phy_mask;
1236 
1237 		for (j = 0; j < mpt->m_num_phys; j++) {
1238 			if ((phy_mask >> j) & 0x01) {
1239 				mpt->m_phy_info[j].phy_mask = phy_mask;
1240 			}
1241 		}
1242 
1243 		(void) sprintf(phy_mask_name, "%x", phy_mask);
1244 
1245 		mutex_exit(&mpt->m_mutex);
1246 		/*
1247 		 * register a iport
1248 		 */
1249 		(void) scsi_hba_iport_register(dip, phy_mask_name);
1250 		mutex_enter(&mpt->m_mutex);
1251 	}
1252 	mutex_exit(&mpt->m_mutex);
1253 	/*
1254 	 * register a virtual port for RAID volume always
1255 	 */
1256 	(void) scsi_hba_iport_register(dip, "v0");
1257 	/*
1258 	 * All children of the HBA are iports. We need tran was cloned.
1259 	 * So we pass the flags to SCSA. SCSI_HBA_TRAN_CLONE will be
1260 	 * inherited to iport's tran vector.
1261 	 */
1262 	tran_flags = (SCSI_HBA_HBA | SCSI_HBA_TRAN_CLONE);
1263 
1264 	if (scsi_hba_attach_setup(dip, &mpt->m_msg_dma_attr,
1265 	    hba_tran, tran_flags) != DDI_SUCCESS) {
1266 		mptsas_log(mpt, CE_WARN, "hba attach setup failed");
1267 		goto fail;
1268 	}
1269 	hba_attach_setup++;
1270 
1271 	mpt->m_smptran = smp_hba_tran_alloc(dip);
1272 	ASSERT(mpt->m_smptran != NULL);
1273 	mpt->m_smptran->smp_tran_hba_private = mpt;
1274 	mpt->m_smptran->smp_tran_start = mptsas_smp_start;
1275 	if (smp_hba_attach_setup(dip, mpt->m_smptran) != DDI_SUCCESS) {
1276 		mptsas_log(mpt, CE_WARN, "smp attach setup failed");
1277 		goto fail;
1278 	}
1279 	smp_attach_setup++;
1280 
1281 	/*
1282 	 * Initialize smp hash table
1283 	 */
1284 	mptsas_hash_init(&mpt->m_active->m_smptbl);
1285 	mpt->m_smp_devhdl = 0xFFFF;
1286 
1287 	/*
1288 	 * create kmem cache for packets
1289 	 */
1290 	(void) sprintf(buf, "mptsas%d_cache", instance);
1291 	mpt->m_kmem_cache = kmem_cache_create(buf,
1292 	    sizeof (struct mptsas_cmd) + scsi_pkt_size(), 8,
1293 	    mptsas_kmem_cache_constructor, mptsas_kmem_cache_destructor,
1294 	    NULL, (void *)mpt, NULL, 0);
1295 
1296 	if (mpt->m_kmem_cache == NULL) {
1297 		mptsas_log(mpt, CE_WARN, "creating kmem cache failed");
1298 		goto fail;
1299 	}
1300 
1301 	/*
1302 	 * create kmem cache for extra SGL frames if SGL cannot
1303 	 * be accomodated into main request frame.
1304 	 */
1305 	(void) sprintf(buf, "mptsas%d_cache_frames", instance);
1306 	mpt->m_cache_frames = kmem_cache_create(buf,
1307 	    sizeof (mptsas_cache_frames_t), 8,
1308 	    mptsas_cache_frames_constructor, mptsas_cache_frames_destructor,
1309 	    NULL, (void *)mpt, NULL, 0);
1310 
1311 	if (mpt->m_cache_frames == NULL) {
1312 		mptsas_log(mpt, CE_WARN, "creating cache for frames failed");
1313 		goto fail;
1314 	}
1315 
1316 	mpt->m_scsi_reset_delay	= ddi_prop_get_int(DDI_DEV_T_ANY,
1317 	    dip, 0, "scsi-reset-delay",	SCSI_DEFAULT_RESET_DELAY);
1318 	if (mpt->m_scsi_reset_delay == 0) {
1319 		mptsas_log(mpt, CE_NOTE,
1320 		    "scsi_reset_delay of 0 is not recommended,"
1321 		    " resetting to SCSI_DEFAULT_RESET_DELAY\n");
1322 		mpt->m_scsi_reset_delay = SCSI_DEFAULT_RESET_DELAY;
1323 	}
1324 
1325 	/*
1326 	 * Initialize the wait and done FIFO queue
1327 	 */
1328 	mpt->m_donetail = &mpt->m_doneq;
1329 	mpt->m_waitqtail = &mpt->m_waitq;
1330 
1331 	mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
1332 	mpt->m_tx_draining = 0;
1333 
1334 	/*
1335 	 * ioc cmd queue initialize
1336 	 */
1337 	mpt->m_ioc_event_cmdtail = &mpt->m_ioc_event_cmdq;
1338 
1339 	mpt->m_dev_handle = 0xFFFF;
1340 
1341 	MPTSAS_ENABLE_INTR(mpt);
1342 
1343 	/*
1344 	 * enable event notification
1345 	 */
1346 	mutex_enter(&mpt->m_mutex);
1347 	if (mptsas_ioc_enable_event_notification(mpt)) {
1348 		mutex_exit(&mpt->m_mutex);
1349 		goto fail;
1350 	}
1351 	mutex_exit(&mpt->m_mutex);
1352 
1353 
1354 	/* Check all dma handles allocated in attach */
1355 	if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl)
1356 	    != DDI_SUCCESS) ||
1357 	    (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl)
1358 	    != DDI_SUCCESS) ||
1359 	    (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl)
1360 	    != DDI_SUCCESS) ||
1361 	    (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl)
1362 	    != DDI_SUCCESS) ||
1363 	    (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl)
1364 	    != DDI_SUCCESS)) {
1365 		goto fail;
1366 	}
1367 
1368 	/* Check all acc handles allocated in attach */
1369 	if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) ||
1370 	    (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl)
1371 	    != DDI_SUCCESS) ||
1372 	    (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl)
1373 	    != DDI_SUCCESS) ||
1374 	    (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl)
1375 	    != DDI_SUCCESS) ||
1376 	    (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl)
1377 	    != DDI_SUCCESS) ||
1378 	    (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl)
1379 	    != DDI_SUCCESS) ||
1380 	    (mptsas_check_acc_handle(mpt->m_config_handle)
1381 	    != DDI_SUCCESS)) {
1382 		goto fail;
1383 	}
1384 
1385 	/*
1386 	 * After this point, we are not going to fail the attach.
1387 	 */
1388 	/*
1389 	 * used for mptsas_watch
1390 	 */
1391 	rw_enter(&mptsas_global_rwlock, RW_WRITER);
1392 	if (mptsas_head == NULL) {
1393 		mptsas_head = mpt;
1394 	} else {
1395 		mptsas_tail->m_next = mpt;
1396 	}
1397 	mptsas_tail = mpt;
1398 	rw_exit(&mptsas_global_rwlock);
1399 
1400 	mutex_enter(&mptsas_global_mutex);
1401 	if (mptsas_timeouts_enabled == 0) {
1402 		mptsas_scsi_watchdog_tick = ddi_prop_get_int(DDI_DEV_T_ANY,
1403 		    dip, 0, "scsi-watchdog-tick", DEFAULT_WD_TICK);
1404 
1405 		mptsas_tick = mptsas_scsi_watchdog_tick *
1406 		    drv_usectohz((clock_t)1000000);
1407 
1408 		mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick);
1409 		mptsas_timeouts_enabled = 1;
1410 	}
1411 	mutex_exit(&mptsas_global_mutex);
1412 
1413 	/* Print message of HBA present */
1414 	ddi_report_dev(dip);
1415 
1416 	/* report idle status to pm framework */
1417 	if (mpt->m_options & MPTSAS_OPT_PM) {
1418 		(void) pm_idle_component(dip, 0);
1419 	}
1420 
1421 	return (DDI_SUCCESS);
1422 
1423 fail:
1424 	mptsas_log(mpt, CE_WARN, "attach failed");
1425 	mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
1426 	ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
1427 	if (mpt) {
1428 		mutex_enter(&mptsas_global_mutex);
1429 
1430 		if (mptsas_timeout_id && (mptsas_head == NULL)) {
1431 			timeout_id_t tid = mptsas_timeout_id;
1432 			mptsas_timeouts_enabled = 0;
1433 			mptsas_timeout_id = 0;
1434 			mutex_exit(&mptsas_global_mutex);
1435 			(void) untimeout(tid);
1436 			mutex_enter(&mptsas_global_mutex);
1437 		}
1438 		mutex_exit(&mptsas_global_mutex);
1439 		/* deallocate in reverse order */
1440 		if (mpt->m_cache_frames) {
1441 			kmem_cache_destroy(mpt->m_cache_frames);
1442 		}
1443 		if (mpt->m_kmem_cache) {
1444 			kmem_cache_destroy(mpt->m_kmem_cache);
1445 		}
1446 		if (hba_attach_setup) {
1447 			(void) scsi_hba_detach(dip);
1448 		}
1449 		if (smp_attach_setup) {
1450 			(void) smp_hba_detach(dip);
1451 		}
1452 		if (intr_added) {
1453 			mptsas_rem_intrs(mpt);
1454 		}
1455 		if (doneq_thread_create) {
1456 			mutex_enter(&mpt->m_doneq_mutex);
1457 			doneq_thread_num = mpt->m_doneq_thread_n;
1458 			for (j = 0; j < mpt->m_doneq_thread_n; j++) {
1459 				mutex_enter(&mpt->m_doneq_thread_id[j].mutex);
1460 				mpt->m_doneq_thread_id[j].flag &=
1461 				    (~MPTSAS_DONEQ_THREAD_ACTIVE);
1462 				cv_signal(&mpt->m_doneq_thread_id[j].cv);
1463 				mutex_exit(&mpt->m_doneq_thread_id[j].mutex);
1464 			}
1465 			while (mpt->m_doneq_thread_n) {
1466 				cv_wait(&mpt->m_doneq_thread_cv,
1467 				    &mpt->m_doneq_mutex);
1468 			}
1469 			for (j = 0; j < doneq_thread_num; j++) {
1470 				cv_destroy(&mpt->m_doneq_thread_id[j].cv);
1471 				mutex_destroy(&mpt->m_doneq_thread_id[j].mutex);
1472 			}
1473 			kmem_free(mpt->m_doneq_thread_id,
1474 			    sizeof (mptsas_doneq_thread_list_t)
1475 			    * doneq_thread_num);
1476 			mutex_exit(&mpt->m_doneq_mutex);
1477 			cv_destroy(&mpt->m_doneq_thread_cv);
1478 			mutex_destroy(&mpt->m_doneq_mutex);
1479 		}
1480 		if (event_taskq_create) {
1481 			ddi_taskq_destroy(mpt->m_event_taskq);
1482 		}
1483 		if (dr_taskq_create) {
1484 			ddi_taskq_destroy(mpt->m_dr_taskq);
1485 		}
1486 		if (mutex_init_done) {
1487 			mutex_destroy(&mpt->m_tx_waitq_mutex);
1488 			mutex_destroy(&mpt->m_mutex);
1489 			cv_destroy(&mpt->m_cv);
1490 			cv_destroy(&mpt->m_passthru_cv);
1491 			cv_destroy(&mpt->m_fw_cv);
1492 			cv_destroy(&mpt->m_config_cv);
1493 			cv_destroy(&mpt->m_fw_diag_cv);
1494 		}
1495 		mptsas_free_handshake_msg(mpt);
1496 		mptsas_hba_fini(mpt);
1497 		if (map_setup) {
1498 			mptsas_cfg_fini(mpt);
1499 		}
1500 		if (config_setup) {
1501 			pci_config_teardown(&mpt->m_config_handle);
1502 		}
1503 		if (mpt->m_tran) {
1504 			scsi_hba_tran_free(mpt->m_tran);
1505 			mpt->m_tran = NULL;
1506 		}
1507 		if (mpt->m_smptran) {
1508 			smp_hba_tran_free(mpt->m_smptran);
1509 			mpt->m_smptran = NULL;
1510 		}
1511 		mptsas_fm_fini(mpt);
1512 		ddi_soft_state_free(mptsas_state, instance);
1513 		ddi_prop_remove_all(dip);
1514 	}
1515 	return (DDI_FAILURE);
1516 }
1517 
1518 static int
1519 mptsas_suspend(dev_info_t *devi)
1520 {
1521 	mptsas_t	*mpt, *g;
1522 	scsi_hba_tran_t	*tran;
1523 
1524 	if (scsi_hba_iport_unit_address(devi)) {
1525 		return (DDI_SUCCESS);
1526 	}
1527 
1528 	if ((tran = ddi_get_driver_private(devi)) == NULL)
1529 		return (DDI_SUCCESS);
1530 
1531 	mpt = TRAN2MPT(tran);
1532 	if (!mpt) {
1533 		return (DDI_SUCCESS);
1534 	}
1535 
1536 	mutex_enter(&mpt->m_mutex);
1537 
1538 	/*
1539 	 * Send RAID action system shutdown to sync IR
1540 	 */
1541 	mptsas_raid_action_system_shutdown(mpt);
1542 
1543 	if (mpt->m_suspended++) {
1544 		mutex_exit(&mpt->m_mutex);
1545 		return (DDI_SUCCESS);
1546 	}
1547 
1548 	/*
1549 	 * Cancel timeout threads for this mpt
1550 	 */
1551 	if (mpt->m_quiesce_timeid) {
1552 		timeout_id_t tid = mpt->m_quiesce_timeid;
1553 		mpt->m_quiesce_timeid = 0;
1554 		mutex_exit(&mpt->m_mutex);
1555 		(void) untimeout(tid);
1556 		mutex_enter(&mpt->m_mutex);
1557 	}
1558 
1559 	if (mpt->m_restart_cmd_timeid) {
1560 		timeout_id_t tid = mpt->m_restart_cmd_timeid;
1561 		mpt->m_restart_cmd_timeid = 0;
1562 		mutex_exit(&mpt->m_mutex);
1563 		(void) untimeout(tid);
1564 		mutex_enter(&mpt->m_mutex);
1565 	}
1566 
1567 	if (mpt->m_pm_timeid != 0) {
1568 		timeout_id_t tid = mpt->m_pm_timeid;
1569 		mpt->m_pm_timeid = 0;
1570 		mutex_exit(&mpt->m_mutex);
1571 		(void) untimeout(tid);
1572 		/*
1573 		 * Report idle status for last ioctl since
1574 		 * calls to pm_busy_component(9F) are stacked.
1575 		 */
1576 		(void) pm_idle_component(mpt->m_dip, 0);
1577 		mutex_enter(&mpt->m_mutex);
1578 	}
1579 	mutex_exit(&mpt->m_mutex);
1580 
1581 	/*
1582 	 * Cancel watch threads if all mpts suspended
1583 	 */
1584 	rw_enter(&mptsas_global_rwlock, RW_WRITER);
1585 	for (g = mptsas_head; g != NULL; g = g->m_next) {
1586 		if (!g->m_suspended)
1587 			break;
1588 	}
1589 	rw_exit(&mptsas_global_rwlock);
1590 
1591 	mutex_enter(&mptsas_global_mutex);
1592 	if (g == NULL) {
1593 		timeout_id_t tid;
1594 
1595 		mptsas_timeouts_enabled = 0;
1596 		if (mptsas_timeout_id) {
1597 			tid = mptsas_timeout_id;
1598 			mptsas_timeout_id = 0;
1599 			mutex_exit(&mptsas_global_mutex);
1600 			(void) untimeout(tid);
1601 			mutex_enter(&mptsas_global_mutex);
1602 		}
1603 		if (mptsas_reset_watch) {
1604 			tid = mptsas_reset_watch;
1605 			mptsas_reset_watch = 0;
1606 			mutex_exit(&mptsas_global_mutex);
1607 			(void) untimeout(tid);
1608 			mutex_enter(&mptsas_global_mutex);
1609 		}
1610 	}
1611 	mutex_exit(&mptsas_global_mutex);
1612 
1613 	mutex_enter(&mpt->m_mutex);
1614 
1615 	/*
1616 	 * If this mpt is not in full power(PM_LEVEL_D0), just return.
1617 	 */
1618 	if ((mpt->m_options & MPTSAS_OPT_PM) &&
1619 	    (mpt->m_power_level != PM_LEVEL_D0)) {
1620 		mutex_exit(&mpt->m_mutex);
1621 		return (DDI_SUCCESS);
1622 	}
1623 
1624 	/* Disable HBA interrupts in hardware */
1625 	MPTSAS_DISABLE_INTR(mpt);
1626 
1627 	mutex_exit(&mpt->m_mutex);
1628 
1629 	/* drain the taskq */
1630 	ddi_taskq_wait(mpt->m_event_taskq);
1631 	ddi_taskq_wait(mpt->m_dr_taskq);
1632 
1633 	return (DDI_SUCCESS);
1634 }
1635 
1636 /*
1637  * quiesce(9E) entry point.
1638  *
1639  * This function is called when the system is single-threaded at high
1640  * PIL with preemption disabled. Therefore, this function must not be
1641  * blocked.
1642  *
1643  * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
1644  * DDI_FAILURE indicates an error condition and should almost never happen.
1645  */
1646 #ifndef	__sparc
1647 static int
1648 mptsas_quiesce(dev_info_t *devi)
1649 {
1650 	mptsas_t	*mpt;
1651 	scsi_hba_tran_t *tran;
1652 
1653 	if ((tran = ddi_get_driver_private(devi)) == NULL)
1654 		return (DDI_SUCCESS);
1655 
1656 	if ((mpt = TRAN2MPT(tran)) == NULL)
1657 		return (DDI_SUCCESS);
1658 
1659 	/* Disable HBA interrupts in hardware */
1660 	MPTSAS_DISABLE_INTR(mpt);
1661 
1662 	return (DDI_SUCCESS);
1663 }
1664 #endif	/* __sparc */
1665 
1666 /*
1667  * detach(9E).	Remove all device allocations and system resources;
1668  * disable device interrupts.
1669  * Return DDI_SUCCESS if done; DDI_FAILURE if there's a problem.
1670  */
1671 static int
1672 mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
1673 {
1674 	/* CONSTCOND */
1675 	ASSERT(NO_COMPETING_THREADS);
1676 	NDBG0(("mptsas_detach: dip=0x%p cmd=0x%p", (void *)devi, (void *)cmd));
1677 
1678 	switch (cmd) {
1679 	case DDI_DETACH:
1680 		return (mptsas_do_detach(devi));
1681 
1682 	case DDI_SUSPEND:
1683 		return (mptsas_suspend(devi));
1684 
1685 	default:
1686 		return (DDI_FAILURE);
1687 	}
1688 	/* NOTREACHED */
1689 }
1690 
1691 static int
1692 mptsas_do_detach(dev_info_t *dip)
1693 {
1694 	mptsas_t	*mpt, *m;
1695 	scsi_hba_tran_t	*tran;
1696 	mptsas_slots_t	*active;
1697 	int		circ = 0;
1698 	int		circ1 = 0;
1699 	mdi_pathinfo_t	*pip = NULL;
1700 	int		i;
1701 	int		doneq_thread_num = 0;
1702 
1703 	NDBG0(("mptsas_do_detach: dip=0x%p", (void *)dip));
1704 
1705 	if ((tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == NULL)
1706 		return (DDI_FAILURE);
1707 
1708 	mpt = TRAN2MPT(tran);
1709 	if (!mpt) {
1710 		return (DDI_FAILURE);
1711 	}
1712 	/*
1713 	 * Still have pathinfo child, should not detach mpt driver
1714 	 */
1715 	if (scsi_hba_iport_unit_address(dip)) {
1716 		if (mpt->m_mpxio_enable) {
1717 			/*
1718 			 * MPxIO enabled for the iport
1719 			 */
1720 			ndi_devi_enter(scsi_vhci_dip, &circ1);
1721 			ndi_devi_enter(dip, &circ);
1722 			while (pip = mdi_get_next_client_path(dip, NULL)) {
1723 				if (mdi_pi_free(pip, 0) == MDI_SUCCESS) {
1724 					continue;
1725 				}
1726 				ndi_devi_exit(dip, circ);
1727 				ndi_devi_exit(scsi_vhci_dip, circ1);
1728 				NDBG12(("detach failed because of "
1729 				    "outstanding path info"));
1730 				return (DDI_FAILURE);
1731 			}
1732 			ndi_devi_exit(dip, circ);
1733 			ndi_devi_exit(scsi_vhci_dip, circ1);
1734 			(void) mdi_phci_unregister(dip, 0);
1735 		}
1736 
1737 		ddi_prop_remove_all(dip);
1738 
1739 		return (DDI_SUCCESS);
1740 	}
1741 
1742 	/* Make sure power level is D0 before accessing registers */
1743 	if (mpt->m_options & MPTSAS_OPT_PM) {
1744 		(void) pm_busy_component(dip, 0);
1745 		if (mpt->m_power_level != PM_LEVEL_D0) {
1746 			if (pm_raise_power(dip, 0, PM_LEVEL_D0) !=
1747 			    DDI_SUCCESS) {
1748 				mptsas_log(mpt, CE_WARN,
1749 				    "mptsas%d: Raise power request failed.",
1750 				    mpt->m_instance);
1751 				(void) pm_idle_component(dip, 0);
1752 				return (DDI_FAILURE);
1753 			}
1754 		}
1755 	}
1756 
1757 	mutex_enter(&mpt->m_mutex);
1758 
1759 	/*
1760 	 * Send RAID action system shutdown to sync IR
1761 	 */
1762 	mptsas_raid_action_system_shutdown(mpt);
1763 	MPTSAS_DISABLE_INTR(mpt);
1764 	mutex_exit(&mpt->m_mutex);
1765 	mptsas_rem_intrs(mpt);
1766 	ddi_taskq_destroy(mpt->m_event_taskq);
1767 	ddi_taskq_destroy(mpt->m_dr_taskq);
1768 
1769 	if (mpt->m_doneq_thread_n) {
1770 		mutex_enter(&mpt->m_doneq_mutex);
1771 		doneq_thread_num = mpt->m_doneq_thread_n;
1772 		for (i = 0; i < mpt->m_doneq_thread_n; i++) {
1773 			mutex_enter(&mpt->m_doneq_thread_id[i].mutex);
1774 			mpt->m_doneq_thread_id[i].flag &=
1775 			    (~MPTSAS_DONEQ_THREAD_ACTIVE);
1776 			cv_signal(&mpt->m_doneq_thread_id[i].cv);
1777 			mutex_exit(&mpt->m_doneq_thread_id[i].mutex);
1778 		}
1779 		while (mpt->m_doneq_thread_n) {
1780 			cv_wait(&mpt->m_doneq_thread_cv,
1781 			    &mpt->m_doneq_mutex);
1782 		}
1783 		for (i = 0;  i < doneq_thread_num; i++) {
1784 			cv_destroy(&mpt->m_doneq_thread_id[i].cv);
1785 			mutex_destroy(&mpt->m_doneq_thread_id[i].mutex);
1786 		}
1787 		kmem_free(mpt->m_doneq_thread_id,
1788 		    sizeof (mptsas_doneq_thread_list_t)
1789 		    * doneq_thread_num);
1790 		mutex_exit(&mpt->m_doneq_mutex);
1791 		cv_destroy(&mpt->m_doneq_thread_cv);
1792 		mutex_destroy(&mpt->m_doneq_mutex);
1793 	}
1794 
1795 	scsi_hba_reset_notify_tear_down(mpt->m_reset_notify_listf);
1796 
1797 	/*
1798 	 * Remove device instance from the global linked list
1799 	 */
1800 	rw_enter(&mptsas_global_rwlock, RW_WRITER);
1801 	if (mptsas_head == mpt) {
1802 		m = mptsas_head = mpt->m_next;
1803 	} else {
1804 		for (m = mptsas_head; m != NULL; m = m->m_next) {
1805 			if (m->m_next == mpt) {
1806 				m->m_next = mpt->m_next;
1807 				break;
1808 			}
1809 		}
1810 		if (m == NULL) {
1811 			mptsas_log(mpt, CE_PANIC, "Not in softc list!");
1812 		}
1813 	}
1814 
1815 	if (mptsas_tail == mpt) {
1816 		mptsas_tail = m;
1817 	}
1818 	rw_exit(&mptsas_global_rwlock);
1819 
1820 	/*
1821 	 * Cancel timeout threads for this mpt
1822 	 */
1823 	mutex_enter(&mpt->m_mutex);
1824 	if (mpt->m_quiesce_timeid) {
1825 		timeout_id_t tid = mpt->m_quiesce_timeid;
1826 		mpt->m_quiesce_timeid = 0;
1827 		mutex_exit(&mpt->m_mutex);
1828 		(void) untimeout(tid);
1829 		mutex_enter(&mpt->m_mutex);
1830 	}
1831 
1832 	if (mpt->m_restart_cmd_timeid) {
1833 		timeout_id_t tid = mpt->m_restart_cmd_timeid;
1834 		mpt->m_restart_cmd_timeid = 0;
1835 		mutex_exit(&mpt->m_mutex);
1836 		(void) untimeout(tid);
1837 		mutex_enter(&mpt->m_mutex);
1838 	}
1839 
1840 	if (mpt->m_pm_timeid != 0) {
1841 		timeout_id_t tid = mpt->m_pm_timeid;
1842 		mpt->m_pm_timeid = 0;
1843 		mutex_exit(&mpt->m_mutex);
1844 		(void) untimeout(tid);
1845 		/*
1846 		 * Report idle status for last ioctl since
1847 		 * calls to pm_busy_component(9F) are stacked.
1848 		 */
1849 		(void) pm_idle_component(mpt->m_dip, 0);
1850 		mutex_enter(&mpt->m_mutex);
1851 	}
1852 	mutex_exit(&mpt->m_mutex);
1853 
1854 	/*
1855 	 * last mpt? ... if active, CANCEL watch threads.
1856 	 */
1857 	mutex_enter(&mptsas_global_mutex);
1858 	if (mptsas_head == NULL) {
1859 		timeout_id_t tid;
1860 		/*
1861 		 * Clear mptsas_timeouts_enable so that the watch thread
1862 		 * gets restarted on DDI_ATTACH
1863 		 */
1864 		mptsas_timeouts_enabled = 0;
1865 		if (mptsas_timeout_id) {
1866 			tid = mptsas_timeout_id;
1867 			mptsas_timeout_id = 0;
1868 			mutex_exit(&mptsas_global_mutex);
1869 			(void) untimeout(tid);
1870 			mutex_enter(&mptsas_global_mutex);
1871 		}
1872 		if (mptsas_reset_watch) {
1873 			tid = mptsas_reset_watch;
1874 			mptsas_reset_watch = 0;
1875 			mutex_exit(&mptsas_global_mutex);
1876 			(void) untimeout(tid);
1877 			mutex_enter(&mptsas_global_mutex);
1878 		}
1879 	}
1880 	mutex_exit(&mptsas_global_mutex);
1881 
1882 	/*
1883 	 * Delete nt_active.
1884 	 */
1885 	active = mpt->m_active;
1886 	mutex_enter(&mpt->m_mutex);
1887 	mptsas_hash_uninit(&active->m_smptbl, sizeof (mptsas_smp_t));
1888 	mutex_exit(&mpt->m_mutex);
1889 
1890 	if (active) {
1891 		kmem_free(active, active->m_size);
1892 		mpt->m_active = NULL;
1893 	}
1894 
1895 	/* deallocate everything that was allocated in mptsas_attach */
1896 	mptsas_fm_fini(mpt);
1897 	kmem_cache_destroy(mpt->m_cache_frames);
1898 	kmem_cache_destroy(mpt->m_kmem_cache);
1899 
1900 	(void) scsi_hba_detach(dip);
1901 	(void) smp_hba_detach(dip);
1902 	mptsas_free_handshake_msg(mpt);
1903 	mptsas_hba_fini(mpt);
1904 	mptsas_cfg_fini(mpt);
1905 
1906 	/* Lower the power informing PM Framework */
1907 	if (mpt->m_options & MPTSAS_OPT_PM) {
1908 		if (pm_lower_power(dip, 0, PM_LEVEL_D3) != DDI_SUCCESS)
1909 			mptsas_log(mpt, CE_WARN,
1910 			    "!mptsas%d: Lower power request failed "
1911 			    "during detach, ignoring.",
1912 			    mpt->m_instance);
1913 	}
1914 
1915 	mutex_destroy(&mpt->m_tx_waitq_mutex);
1916 	mutex_destroy(&mpt->m_mutex);
1917 	cv_destroy(&mpt->m_cv);
1918 	cv_destroy(&mpt->m_passthru_cv);
1919 	cv_destroy(&mpt->m_fw_cv);
1920 	cv_destroy(&mpt->m_config_cv);
1921 	cv_destroy(&mpt->m_fw_diag_cv);
1922 
1923 	pci_config_teardown(&mpt->m_config_handle);
1924 	if (mpt->m_tran) {
1925 		scsi_hba_tran_free(mpt->m_tran);
1926 		mpt->m_tran = NULL;
1927 	}
1928 
1929 	if (mpt->m_smptran) {
1930 		smp_hba_tran_free(mpt->m_smptran);
1931 		mpt->m_smptran = NULL;
1932 	}
1933 
1934 	ddi_soft_state_free(mptsas_state, ddi_get_instance(dip));
1935 	ddi_prop_remove_all(dip);
1936 
1937 	return (DDI_SUCCESS);
1938 }
1939 
1940 static int
1941 mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size)
1942 {
1943 	ddi_dma_attr_t		task_dma_attrs;
1944 	ddi_dma_cookie_t	tmp_dma_cookie;
1945 	size_t			alloc_len;
1946 	uint_t			ncookie;
1947 
1948 	/* allocate Task Management ddi_dma resources */
1949 	task_dma_attrs = mpt->m_msg_dma_attr;
1950 	task_dma_attrs.dma_attr_sgllen = 1;
1951 	task_dma_attrs.dma_attr_granular = (uint32_t)(alloc_size);
1952 
1953 	if (ddi_dma_alloc_handle(mpt->m_dip, &task_dma_attrs,
1954 	    DDI_DMA_SLEEP, NULL, &mpt->m_hshk_dma_hdl) != DDI_SUCCESS) {
1955 		mpt->m_hshk_dma_hdl = NULL;
1956 		return (DDI_FAILURE);
1957 	}
1958 
1959 	if (ddi_dma_mem_alloc(mpt->m_hshk_dma_hdl, alloc_size,
1960 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
1961 	    &mpt->m_hshk_memp, &alloc_len, &mpt->m_hshk_acc_hdl)
1962 	    != DDI_SUCCESS) {
1963 		ddi_dma_free_handle(&mpt->m_hshk_dma_hdl);
1964 		mpt->m_hshk_dma_hdl = NULL;
1965 		return (DDI_FAILURE);
1966 	}
1967 
1968 	if (ddi_dma_addr_bind_handle(mpt->m_hshk_dma_hdl, NULL,
1969 	    mpt->m_hshk_memp, alloc_len, (DDI_DMA_RDWR | DDI_DMA_CONSISTENT),
1970 	    DDI_DMA_SLEEP, NULL, &tmp_dma_cookie, &ncookie)
1971 	    != DDI_DMA_MAPPED) {
1972 		(void) ddi_dma_mem_free(&mpt->m_hshk_acc_hdl);
1973 		ddi_dma_free_handle(&mpt->m_hshk_dma_hdl);
1974 		mpt->m_hshk_dma_hdl = NULL;
1975 		return (DDI_FAILURE);
1976 	}
1977 	mpt->m_hshk_dma_size = alloc_size;
1978 	return (DDI_SUCCESS);
1979 }
1980 
1981 static void
1982 mptsas_free_handshake_msg(mptsas_t *mpt)
1983 {
1984 	if (mpt->m_hshk_dma_hdl != NULL) {
1985 		(void) ddi_dma_unbind_handle(mpt->m_hshk_dma_hdl);
1986 		(void) ddi_dma_mem_free(&mpt->m_hshk_acc_hdl);
1987 		ddi_dma_free_handle(&mpt->m_hshk_dma_hdl);
1988 		mpt->m_hshk_dma_hdl = NULL;
1989 		mpt->m_hshk_dma_size = 0;
1990 	}
1991 }
1992 
1993 static int
1994 mptsas_power(dev_info_t *dip, int component, int level)
1995 {
1996 #ifndef __lock_lint
1997 	_NOTE(ARGUNUSED(component))
1998 #endif
1999 	mptsas_t	*mpt;
2000 	int		rval = DDI_SUCCESS;
2001 	int		polls = 0;
2002 	uint32_t	ioc_status;
2003 
2004 	if (scsi_hba_iport_unit_address(dip) != 0)
2005 		return (DDI_SUCCESS);
2006 
2007 	mpt = ddi_get_soft_state(mptsas_state, ddi_get_instance(dip));
2008 	if (mpt == NULL) {
2009 		return (DDI_FAILURE);
2010 	}
2011 
2012 	mutex_enter(&mpt->m_mutex);
2013 
2014 	/*
2015 	 * If the device is busy, don't lower its power level
2016 	 */
2017 	if (mpt->m_busy && (mpt->m_power_level > level)) {
2018 		mutex_exit(&mpt->m_mutex);
2019 		return (DDI_FAILURE);
2020 	}
2021 
2022 	switch (level) {
2023 	case PM_LEVEL_D0:
2024 		NDBG11(("mptsas%d: turning power ON.", mpt->m_instance));
2025 		MPTSAS_POWER_ON(mpt);
2026 		/*
2027 		 * Wait up to 30 seconds for IOC to come out of reset.
2028 		 */
2029 		while (((ioc_status = ddi_get32(mpt->m_datap,
2030 		    &mpt->m_reg->Doorbell)) &
2031 		    MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_RESET) {
2032 			if (polls++ > 3000) {
2033 				break;
2034 			}
2035 			delay(drv_usectohz(10000));
2036 		}
2037 		/*
2038 		 * If IOC is not in operational state, try to hard reset it.
2039 		 */
2040 		if ((ioc_status & MPI2_IOC_STATE_MASK) !=
2041 		    MPI2_IOC_STATE_OPERATIONAL) {
2042 			if (mptsas_restart_ioc(mpt) == DDI_FAILURE) {
2043 				mptsas_log(mpt, CE_WARN,
2044 				    "mptsas_power: hard reset failed");
2045 				mutex_exit(&mpt->m_mutex);
2046 				return (DDI_FAILURE);
2047 			}
2048 		}
2049 		mpt->m_power_level = PM_LEVEL_D0;
2050 		break;
2051 	case PM_LEVEL_D3:
2052 		NDBG11(("mptsas%d: turning power OFF.", mpt->m_instance));
2053 		MPTSAS_POWER_OFF(mpt);
2054 		break;
2055 	default:
2056 		mptsas_log(mpt, CE_WARN, "mptsas%d: unknown power level <%x>.",
2057 		    mpt->m_instance, level);
2058 		rval = DDI_FAILURE;
2059 		break;
2060 	}
2061 	mutex_exit(&mpt->m_mutex);
2062 	return (rval);
2063 }
2064 
2065 /*
2066  * Initialize configuration space and figure out which
2067  * chip and revison of the chip the mpt driver is using.
2068  */
2069 int
2070 mptsas_config_space_init(mptsas_t *mpt)
2071 {
2072 	ushort_t	caps_ptr, cap, cap_count;
2073 
2074 	NDBG0(("mptsas_config_space_init"));
2075 
2076 	mptsas_setup_cmd_reg(mpt);
2077 
2078 	/*
2079 	 * Get the chip device id:
2080 	 */
2081 	mpt->m_devid = pci_config_get16(mpt->m_config_handle, PCI_CONF_DEVID);
2082 
2083 	/*
2084 	 * Save the revision.
2085 	 */
2086 	mpt->m_revid = pci_config_get8(mpt->m_config_handle, PCI_CONF_REVID);
2087 
2088 	/*
2089 	 * Save the SubSystem Vendor and Device IDs
2090 	 */
2091 	mpt->m_svid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBVENID);
2092 	mpt->m_ssid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBSYSID);
2093 
2094 	/*
2095 	 * Set the latency timer to 0x40 as specified by the upa -> pci
2096 	 * bridge chip design team.  This may be done by the sparc pci
2097 	 * bus nexus driver, but the driver should make sure the latency
2098 	 * timer is correct for performance reasons.
2099 	 */
2100 	pci_config_put8(mpt->m_config_handle, PCI_CONF_LATENCY_TIMER,
2101 	    MPTSAS_LATENCY_TIMER);
2102 
2103 	/*
2104 	 * Check if capabilities list is supported and if so,
2105 	 * get initial capabilities pointer and clear bits 0,1.
2106 	 */
2107 	if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT)
2108 	    & PCI_STAT_CAP) {
2109 		caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle,
2110 		    PCI_CONF_CAP_PTR), 4);
2111 	} else {
2112 		caps_ptr = PCI_CAP_NEXT_PTR_NULL;
2113 	}
2114 
2115 	/*
2116 	 * Walk capabilities if supported.
2117 	 */
2118 	for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) {
2119 
2120 		/*
2121 		 * Check that we haven't exceeded the maximum number of
2122 		 * capabilities and that the pointer is in a valid range.
2123 		 */
2124 		if (++cap_count > 48) {
2125 			mptsas_log(mpt, CE_WARN,
2126 			    "too many device capabilities.\n");
2127 			return (FALSE);
2128 		}
2129 		if (caps_ptr < 64) {
2130 			mptsas_log(mpt, CE_WARN,
2131 			    "capabilities pointer 0x%x out of range.\n",
2132 			    caps_ptr);
2133 			return (FALSE);
2134 		}
2135 
2136 		/*
2137 		 * Get next capability and check that it is valid.
2138 		 * For now, we only support power management.
2139 		 */
2140 		cap = pci_config_get8(mpt->m_config_handle, caps_ptr);
2141 		switch (cap) {
2142 			case PCI_CAP_ID_PM:
2143 				mptsas_log(mpt, CE_NOTE,
2144 				    "?mptsas%d supports power management.\n",
2145 				    mpt->m_instance);
2146 				mpt->m_options |= MPTSAS_OPT_PM;
2147 
2148 				/* Save PMCSR offset */
2149 				mpt->m_pmcsr_offset = caps_ptr + PCI_PMCSR;
2150 				break;
2151 
2152 			/*
2153 			 * 0x5 is Message signaled interrupts and 0x7
2154 			 * is pci-x capable.  Both are unsupported for now
2155 			 * but supported by the 1030 chip so we don't
2156 			 * need to keep printing out the notice.
2157 			 * 0x10 is PCI-E support (1064E/1068E)
2158 			 * 0x11 is MSIX supported by the 1064/1068
2159 			 */
2160 			case 0x5:
2161 			case 0x7:
2162 			case 0x10:
2163 			case 0x11:
2164 				break;
2165 			default:
2166 				mptsas_log(mpt, CE_NOTE,
2167 				    "?mptsas%d unrecognized capability "
2168 				    "0x%x.\n", mpt->m_instance, cap);
2169 			break;
2170 		}
2171 
2172 		/*
2173 		 * Get next capabilities pointer and clear bits 0,1.
2174 		 */
2175 		caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle,
2176 		    (caps_ptr + PCI_CAP_NEXT_PTR)), 4);
2177 	}
2178 
2179 	return (TRUE);
2180 }
2181 
2182 static void
2183 mptsas_setup_cmd_reg(mptsas_t *mpt)
2184 {
2185 	ushort_t	cmdreg;
2186 
2187 	/*
2188 	 * Set the command register to the needed values.
2189 	 */
2190 	cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM);
2191 	cmdreg |= (PCI_COMM_ME | PCI_COMM_SERR_ENABLE |
2192 	    PCI_COMM_PARITY_DETECT | PCI_COMM_MAE);
2193 	cmdreg &= ~PCI_COMM_IO;
2194 	pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg);
2195 }
2196 
2197 static void
2198 mptsas_disable_bus_master(mptsas_t *mpt)
2199 {
2200 	ushort_t	cmdreg;
2201 
2202 	/*
2203 	 * Clear the master enable bit in the PCI command register.
2204 	 * This prevents any bus mastering activity like DMA.
2205 	 */
2206 	cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM);
2207 	cmdreg &= ~PCI_COMM_ME;
2208 	pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg);
2209 }
2210 
2211 int
2212 mptsas_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep)
2213 {
2214 	ddi_dma_attr_t	attrs;
2215 	uint_t		ncookie;
2216 	size_t		alloc_len;
2217 
2218 	attrs = mpt->m_io_dma_attr;
2219 	attrs.dma_attr_sgllen = 1;
2220 
2221 	ASSERT(dma_statep != NULL);
2222 
2223 	if (ddi_dma_alloc_handle(mpt->m_dip, &attrs,
2224 	    DDI_DMA_SLEEP, NULL, &dma_statep->handle) != DDI_SUCCESS) {
2225 		mptsas_log(mpt, CE_WARN,
2226 		    "unable to allocate dma handle.");
2227 		return (DDI_FAILURE);
2228 	}
2229 
2230 	if (ddi_dma_mem_alloc(dma_statep->handle, dma_statep->size,
2231 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
2232 	    &dma_statep->memp, &alloc_len, &dma_statep->accessp) !=
2233 	    DDI_SUCCESS) {
2234 		ddi_dma_free_handle(&dma_statep->handle);
2235 		dma_statep->handle = NULL;
2236 		mptsas_log(mpt, CE_WARN,
2237 		    "unable to allocate memory for dma xfer.");
2238 		return (DDI_FAILURE);
2239 	}
2240 
2241 	if (ddi_dma_addr_bind_handle(dma_statep->handle, NULL, dma_statep->memp,
2242 	    alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2243 	    NULL, &dma_statep->cookie, &ncookie) != DDI_DMA_MAPPED) {
2244 		ddi_dma_mem_free(&dma_statep->accessp);
2245 		dma_statep->accessp = NULL;
2246 		ddi_dma_free_handle(&dma_statep->handle);
2247 		dma_statep->handle = NULL;
2248 		mptsas_log(mpt, CE_WARN, "unable to bind DMA resources.");
2249 		return (DDI_FAILURE);
2250 	}
2251 	return (DDI_SUCCESS);
2252 }
2253 
2254 void
2255 mptsas_dma_free(mptsas_dma_alloc_state_t *dma_statep)
2256 {
2257 	ASSERT(dma_statep != NULL);
2258 	if (dma_statep->handle != NULL) {
2259 		(void) ddi_dma_unbind_handle(dma_statep->handle);
2260 		(void) ddi_dma_mem_free(&dma_statep->accessp);
2261 		ddi_dma_free_handle(&dma_statep->handle);
2262 	}
2263 }
2264 
2265 int
2266 mptsas_do_dma(mptsas_t *mpt, uint32_t size, int var, int (*callback)())
2267 {
2268 	ddi_dma_attr_t		attrs;
2269 	ddi_dma_handle_t	dma_handle;
2270 	caddr_t			memp;
2271 	uint_t			ncookie;
2272 	ddi_dma_cookie_t	cookie;
2273 	ddi_acc_handle_t	accessp;
2274 	size_t			alloc_len;
2275 	int			rval;
2276 
2277 	ASSERT(mutex_owned(&mpt->m_mutex));
2278 
2279 	attrs = mpt->m_msg_dma_attr;
2280 	attrs.dma_attr_sgllen = 1;
2281 	attrs.dma_attr_granular = size;
2282 
2283 	if (ddi_dma_alloc_handle(mpt->m_dip, &attrs,
2284 	    DDI_DMA_SLEEP, NULL, &dma_handle) != DDI_SUCCESS) {
2285 		mptsas_log(mpt, CE_WARN,
2286 		    "unable to allocate dma handle.");
2287 		return (DDI_FAILURE);
2288 	}
2289 
2290 	if (ddi_dma_mem_alloc(dma_handle, size,
2291 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
2292 	    &memp, &alloc_len, &accessp) != DDI_SUCCESS) {
2293 		ddi_dma_free_handle(&dma_handle);
2294 		mptsas_log(mpt, CE_WARN,
2295 		    "unable to allocate request structure.");
2296 		return (DDI_FAILURE);
2297 	}
2298 
2299 	if (ddi_dma_addr_bind_handle(dma_handle, NULL, memp,
2300 	    alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2301 	    NULL, &cookie, &ncookie) != DDI_DMA_MAPPED) {
2302 		(void) ddi_dma_mem_free(&accessp);
2303 		ddi_dma_free_handle(&dma_handle);
2304 		mptsas_log(mpt, CE_WARN, "unable to bind DMA resources.");
2305 		return (DDI_FAILURE);
2306 	}
2307 
2308 	rval = (*callback) (mpt, memp, var, accessp);
2309 
2310 	if ((mptsas_check_dma_handle(dma_handle) != DDI_SUCCESS) ||
2311 	    (mptsas_check_acc_handle(accessp) != DDI_SUCCESS)) {
2312 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
2313 		rval = DDI_FAILURE;
2314 	}
2315 
2316 	if (dma_handle != NULL) {
2317 		(void) ddi_dma_unbind_handle(dma_handle);
2318 		(void) ddi_dma_mem_free(&accessp);
2319 		ddi_dma_free_handle(&dma_handle);
2320 	}
2321 
2322 	return (rval);
2323 
2324 }
2325 
2326 static int
2327 mptsas_alloc_request_frames(mptsas_t *mpt)
2328 {
2329 	ddi_dma_attr_t		frame_dma_attrs;
2330 	caddr_t			memp;
2331 	uint_t			ncookie;
2332 	ddi_dma_cookie_t	cookie;
2333 	size_t			alloc_len;
2334 	size_t			mem_size;
2335 
2336 	/*
2337 	 * The size of the request frame pool is:
2338 	 *   Number of Request Frames * Request Frame Size
2339 	 */
2340 	mem_size = mpt->m_max_requests * mpt->m_req_frame_size;
2341 
2342 	/*
2343 	 * set the DMA attributes.  System Request Message Frames must be
2344 	 * aligned on a 16-byte boundry.
2345 	 */
2346 	frame_dma_attrs = mpt->m_msg_dma_attr;
2347 	frame_dma_attrs.dma_attr_align = 16;
2348 	frame_dma_attrs.dma_attr_sgllen = 1;
2349 
2350 	/*
2351 	 * allocate the request frame pool.
2352 	 */
2353 	if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attrs,
2354 	    DDI_DMA_SLEEP, NULL, &mpt->m_dma_req_frame_hdl) != DDI_SUCCESS) {
2355 		mptsas_log(mpt, CE_WARN,
2356 		    "Unable to allocate dma handle.");
2357 		return (DDI_FAILURE);
2358 	}
2359 
2360 	if (ddi_dma_mem_alloc(mpt->m_dma_req_frame_hdl,
2361 	    mem_size, &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2362 	    NULL, (caddr_t *)&memp, &alloc_len, &mpt->m_acc_req_frame_hdl)
2363 	    != DDI_SUCCESS) {
2364 		ddi_dma_free_handle(&mpt->m_dma_req_frame_hdl);
2365 		mpt->m_dma_req_frame_hdl = NULL;
2366 		mptsas_log(mpt, CE_WARN,
2367 		    "Unable to allocate request frames.");
2368 		return (DDI_FAILURE);
2369 	}
2370 
2371 	if (ddi_dma_addr_bind_handle(mpt->m_dma_req_frame_hdl, NULL,
2372 	    memp, alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2373 	    DDI_DMA_SLEEP, NULL, &cookie, &ncookie) != DDI_DMA_MAPPED) {
2374 		(void) ddi_dma_mem_free(&mpt->m_acc_req_frame_hdl);
2375 		ddi_dma_free_handle(&mpt->m_dma_req_frame_hdl);
2376 		mpt->m_dma_req_frame_hdl = NULL;
2377 		mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources.");
2378 		return (DDI_FAILURE);
2379 	}
2380 
2381 	/*
2382 	 * Store the request frame memory address.  This chip uses this
2383 	 * address to dma to and from the driver's frame.  The second
2384 	 * address is the address mpt uses to fill in the frame.
2385 	 */
2386 	mpt->m_req_frame_dma_addr = cookie.dmac_laddress;
2387 	mpt->m_req_frame = memp;
2388 
2389 	/*
2390 	 * Clear the request frame pool.
2391 	 */
2392 	bzero(mpt->m_req_frame, alloc_len);
2393 
2394 	return (DDI_SUCCESS);
2395 }
2396 
2397 static int
2398 mptsas_alloc_reply_frames(mptsas_t *mpt)
2399 {
2400 	ddi_dma_attr_t		frame_dma_attrs;
2401 	caddr_t			memp;
2402 	uint_t			ncookie;
2403 	ddi_dma_cookie_t	cookie;
2404 	size_t			alloc_len;
2405 	size_t			mem_size;
2406 
2407 	/*
2408 	 * The size of the reply frame pool is:
2409 	 *   Number of Reply Frames * Reply Frame Size
2410 	 */
2411 	mem_size = mpt->m_max_replies * mpt->m_reply_frame_size;
2412 
2413 	/*
2414 	 * set the DMA attributes.   System Reply Message Frames must be
2415 	 * aligned on a 4-byte boundry.  This is the default.
2416 	 */
2417 	frame_dma_attrs = mpt->m_msg_dma_attr;
2418 	frame_dma_attrs.dma_attr_sgllen = 1;
2419 
2420 	/*
2421 	 * allocate the reply frame pool
2422 	 */
2423 	if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attrs,
2424 	    DDI_DMA_SLEEP, NULL, &mpt->m_dma_reply_frame_hdl) != DDI_SUCCESS) {
2425 		mptsas_log(mpt, CE_WARN,
2426 		    "Unable to allocate dma handle.");
2427 		return (DDI_FAILURE);
2428 	}
2429 
2430 	if (ddi_dma_mem_alloc(mpt->m_dma_reply_frame_hdl,
2431 	    mem_size, &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2432 	    NULL, (caddr_t *)&memp, &alloc_len, &mpt->m_acc_reply_frame_hdl)
2433 	    != DDI_SUCCESS) {
2434 		ddi_dma_free_handle(&mpt->m_dma_reply_frame_hdl);
2435 		mpt->m_dma_reply_frame_hdl = NULL;
2436 		mptsas_log(mpt, CE_WARN,
2437 		    "Unable to allocate reply frames.");
2438 		return (DDI_FAILURE);
2439 	}
2440 
2441 	if (ddi_dma_addr_bind_handle(mpt->m_dma_reply_frame_hdl, NULL,
2442 	    memp, alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2443 	    DDI_DMA_SLEEP, NULL, &cookie, &ncookie) != DDI_DMA_MAPPED) {
2444 		(void) ddi_dma_mem_free(&mpt->m_acc_reply_frame_hdl);
2445 		ddi_dma_free_handle(&mpt->m_dma_reply_frame_hdl);
2446 		mpt->m_dma_reply_frame_hdl = NULL;
2447 		mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources.");
2448 		return (DDI_FAILURE);
2449 	}
2450 
2451 	/*
2452 	 * Store the reply frame memory address.  This chip uses this
2453 	 * address to dma to and from the driver's frame.  The second
2454 	 * address is the address mpt uses to process the frame.
2455 	 */
2456 	mpt->m_reply_frame_dma_addr = cookie.dmac_laddress;
2457 	mpt->m_reply_frame = memp;
2458 
2459 	/*
2460 	 * Clear the reply frame pool.
2461 	 */
2462 	bzero(mpt->m_reply_frame, alloc_len);
2463 
2464 	return (DDI_SUCCESS);
2465 }
2466 
2467 static int
2468 mptsas_alloc_free_queue(mptsas_t *mpt)
2469 {
2470 	ddi_dma_attr_t		frame_dma_attrs;
2471 	caddr_t			memp;
2472 	uint_t			ncookie;
2473 	ddi_dma_cookie_t	cookie;
2474 	size_t			alloc_len;
2475 	size_t			mem_size;
2476 
2477 	/*
2478 	 * The reply free queue size is:
2479 	 *   Reply Free Queue Depth * 4
2480 	 * The "4" is the size of one 32 bit address (low part of 64-bit
2481 	 *   address)
2482 	 */
2483 	mem_size = mpt->m_free_queue_depth * 4;
2484 
2485 	/*
2486 	 * set the DMA attributes  The Reply Free Queue must be aligned on a
2487 	 * 16-byte boundry.
2488 	 */
2489 	frame_dma_attrs = mpt->m_msg_dma_attr;
2490 	frame_dma_attrs.dma_attr_align = 16;
2491 	frame_dma_attrs.dma_attr_sgllen = 1;
2492 
2493 	/*
2494 	 * allocate the reply free queue
2495 	 */
2496 	if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attrs,
2497 	    DDI_DMA_SLEEP, NULL, &mpt->m_dma_free_queue_hdl) != DDI_SUCCESS) {
2498 		mptsas_log(mpt, CE_WARN,
2499 		    "Unable to allocate dma handle.");
2500 		return (DDI_FAILURE);
2501 	}
2502 
2503 	if (ddi_dma_mem_alloc(mpt->m_dma_free_queue_hdl,
2504 	    mem_size, &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2505 	    NULL, (caddr_t *)&memp, &alloc_len, &mpt->m_acc_free_queue_hdl)
2506 	    != DDI_SUCCESS) {
2507 		ddi_dma_free_handle(&mpt->m_dma_free_queue_hdl);
2508 		mpt->m_dma_free_queue_hdl = NULL;
2509 		mptsas_log(mpt, CE_WARN,
2510 		    "Unable to allocate free queue.");
2511 		return (DDI_FAILURE);
2512 	}
2513 
2514 	if (ddi_dma_addr_bind_handle(mpt->m_dma_free_queue_hdl, NULL,
2515 	    memp, alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2516 	    DDI_DMA_SLEEP, NULL, &cookie, &ncookie) != DDI_DMA_MAPPED) {
2517 		(void) ddi_dma_mem_free(&mpt->m_acc_free_queue_hdl);
2518 		ddi_dma_free_handle(&mpt->m_dma_free_queue_hdl);
2519 		mpt->m_dma_free_queue_hdl = NULL;
2520 		mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources.");
2521 		return (DDI_FAILURE);
2522 	}
2523 
2524 	/*
2525 	 * Store the reply free queue memory address.  This chip uses this
2526 	 * address to read from the reply free queue.  The second address
2527 	 * is the address mpt uses to manage the queue.
2528 	 */
2529 	mpt->m_free_queue_dma_addr = cookie.dmac_laddress;
2530 	mpt->m_free_queue = memp;
2531 
2532 	/*
2533 	 * Clear the reply free queue memory.
2534 	 */
2535 	bzero(mpt->m_free_queue, alloc_len);
2536 
2537 	return (DDI_SUCCESS);
2538 }
2539 
2540 static int
2541 mptsas_alloc_post_queue(mptsas_t *mpt)
2542 {
2543 	ddi_dma_attr_t		frame_dma_attrs;
2544 	caddr_t			memp;
2545 	uint_t			ncookie;
2546 	ddi_dma_cookie_t	cookie;
2547 	size_t			alloc_len;
2548 	size_t			mem_size;
2549 
2550 	/*
2551 	 * The reply descriptor post queue size is:
2552 	 *   Reply Descriptor Post Queue Depth * 8
2553 	 * The "8" is the size of each descriptor (8 bytes or 64 bits).
2554 	 */
2555 	mem_size = mpt->m_post_queue_depth * 8;
2556 
2557 	/*
2558 	 * set the DMA attributes.  The Reply Descriptor Post Queue must be
2559 	 * aligned on a 16-byte boundry.
2560 	 */
2561 	frame_dma_attrs = mpt->m_msg_dma_attr;
2562 	frame_dma_attrs.dma_attr_align = 16;
2563 	frame_dma_attrs.dma_attr_sgllen = 1;
2564 
2565 	/*
2566 	 * allocate the reply post queue
2567 	 */
2568 	if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attrs,
2569 	    DDI_DMA_SLEEP, NULL, &mpt->m_dma_post_queue_hdl) != DDI_SUCCESS) {
2570 		mptsas_log(mpt, CE_WARN,
2571 		    "Unable to allocate dma handle.");
2572 		return (DDI_FAILURE);
2573 	}
2574 
2575 	if (ddi_dma_mem_alloc(mpt->m_dma_post_queue_hdl,
2576 	    mem_size, &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2577 	    NULL, (caddr_t *)&memp, &alloc_len, &mpt->m_acc_post_queue_hdl)
2578 	    != DDI_SUCCESS) {
2579 		ddi_dma_free_handle(&mpt->m_dma_post_queue_hdl);
2580 		mpt->m_dma_post_queue_hdl = NULL;
2581 		mptsas_log(mpt, CE_WARN,
2582 		    "Unable to allocate post queue.");
2583 		return (DDI_FAILURE);
2584 	}
2585 
2586 	if (ddi_dma_addr_bind_handle(mpt->m_dma_post_queue_hdl, NULL,
2587 	    memp, alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2588 	    DDI_DMA_SLEEP, NULL, &cookie, &ncookie) != DDI_DMA_MAPPED) {
2589 		(void) ddi_dma_mem_free(&mpt->m_acc_post_queue_hdl);
2590 		ddi_dma_free_handle(&mpt->m_dma_post_queue_hdl);
2591 		mpt->m_dma_post_queue_hdl = NULL;
2592 		mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources.");
2593 		return (DDI_FAILURE);
2594 	}
2595 
2596 	/*
2597 	 * Store the reply descriptor post queue memory address.  This chip
2598 	 * uses this address to write to the reply descriptor post queue.  The
2599 	 * second address is the address mpt uses to manage the queue.
2600 	 */
2601 	mpt->m_post_queue_dma_addr = cookie.dmac_laddress;
2602 	mpt->m_post_queue = memp;
2603 
2604 	/*
2605 	 * Clear the reply post queue memory.
2606 	 */
2607 	bzero(mpt->m_post_queue, alloc_len);
2608 
2609 	return (DDI_SUCCESS);
2610 }
2611 
2612 static int
2613 mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd)
2614 {
2615 	mptsas_cache_frames_t	*frames = NULL;
2616 	if (cmd->cmd_extra_frames == NULL) {
2617 		frames = kmem_cache_alloc(mpt->m_cache_frames, KM_NOSLEEP);
2618 		if (frames == NULL) {
2619 			return (DDI_FAILURE);
2620 		}
2621 		cmd->cmd_extra_frames = frames;
2622 	}
2623 	return (DDI_SUCCESS);
2624 }
2625 
2626 static void
2627 mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd)
2628 {
2629 	if (cmd->cmd_extra_frames) {
2630 		kmem_cache_free(mpt->m_cache_frames,
2631 		    (void *)cmd->cmd_extra_frames);
2632 		cmd->cmd_extra_frames = NULL;
2633 	}
2634 }
2635 
2636 static void
2637 mptsas_cfg_fini(mptsas_t *mpt)
2638 {
2639 	NDBG0(("mptsas_cfg_fini"));
2640 	ddi_regs_map_free(&mpt->m_datap);
2641 }
2642 
2643 static void
2644 mptsas_hba_fini(mptsas_t *mpt)
2645 {
2646 	NDBG0(("mptsas_hba_fini"));
2647 
2648 	/*
2649 	 * Disable any bus mastering ability (i.e: DMA) prior to freeing any
2650 	 * allocated DMA resources.
2651 	 */
2652 	if (mpt->m_config_handle != NULL)
2653 		mptsas_disable_bus_master(mpt);
2654 
2655 	/*
2656 	 * Free up any allocated memory
2657 	 */
2658 	if (mpt->m_dma_req_frame_hdl != NULL) {
2659 		(void) ddi_dma_unbind_handle(mpt->m_dma_req_frame_hdl);
2660 		ddi_dma_mem_free(&mpt->m_acc_req_frame_hdl);
2661 		ddi_dma_free_handle(&mpt->m_dma_req_frame_hdl);
2662 		mpt->m_dma_req_frame_hdl = NULL;
2663 	}
2664 
2665 	if (mpt->m_dma_reply_frame_hdl != NULL) {
2666 		(void) ddi_dma_unbind_handle(mpt->m_dma_reply_frame_hdl);
2667 		ddi_dma_mem_free(&mpt->m_acc_reply_frame_hdl);
2668 		ddi_dma_free_handle(&mpt->m_dma_reply_frame_hdl);
2669 		mpt->m_dma_reply_frame_hdl = NULL;
2670 	}
2671 
2672 	if (mpt->m_dma_free_queue_hdl != NULL) {
2673 		(void) ddi_dma_unbind_handle(mpt->m_dma_free_queue_hdl);
2674 		ddi_dma_mem_free(&mpt->m_acc_free_queue_hdl);
2675 		ddi_dma_free_handle(&mpt->m_dma_free_queue_hdl);
2676 		mpt->m_dma_free_queue_hdl = NULL;
2677 	}
2678 
2679 	if (mpt->m_dma_post_queue_hdl != NULL) {
2680 		(void) ddi_dma_unbind_handle(mpt->m_dma_post_queue_hdl);
2681 		ddi_dma_mem_free(&mpt->m_acc_post_queue_hdl);
2682 		ddi_dma_free_handle(&mpt->m_dma_post_queue_hdl);
2683 		mpt->m_dma_post_queue_hdl = NULL;
2684 	}
2685 
2686 	if (mpt->m_replyh_args != NULL) {
2687 		kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t)
2688 		    * mpt->m_max_replies);
2689 	}
2690 }
2691 
2692 static int
2693 mptsas_name_child(dev_info_t *lun_dip, char *name, int len)
2694 {
2695 	int		lun = 0;
2696 	char		*sas_wwn = NULL;
2697 	int		phynum = -1;
2698 	int		reallen = 0;
2699 
2700 	/* Get the target num */
2701 	lun = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, DDI_PROP_DONTPASS,
2702 	    LUN_PROP, 0);
2703 
2704 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lun_dip, DDI_PROP_DONTPASS,
2705 	    SCSI_ADDR_PROP_TARGET_PORT, &sas_wwn) == DDI_PROP_SUCCESS) {
2706 		/*
2707 		 * Stick in the address of the form "wWWN,LUN"
2708 		 */
2709 		reallen = snprintf(name, len, "w%s,%x", sas_wwn, lun);
2710 		ddi_prop_free(sas_wwn);
2711 	} else if ((phynum = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip,
2712 	    DDI_PROP_DONTPASS, "sata-phy", -1)) != -1) {
2713 		/*
2714 		 * Stick in the address of form "pPHY,LUN"
2715 		 */
2716 		reallen = snprintf(name, len, "p%x,%x", phynum, lun);
2717 	} else {
2718 		return (DDI_FAILURE);
2719 	}
2720 
2721 	ASSERT(reallen < len);
2722 	if (reallen >= len) {
2723 		mptsas_log(0, CE_WARN, "!mptsas_get_name: name parameter "
2724 		    "length too small, it needs to be %d bytes", reallen + 1);
2725 	}
2726 	return (DDI_SUCCESS);
2727 }
2728 
2729 /*
2730  * tran_tgt_init(9E) - target device instance initialization
2731  */
2732 static int
2733 mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
2734     scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
2735 {
2736 #ifndef __lock_lint
2737 	_NOTE(ARGUNUSED(hba_tran))
2738 #endif
2739 
2740 	/*
2741 	 * At this point, the scsi_device structure already exists
2742 	 * and has been initialized.
2743 	 *
2744 	 * Use this function to allocate target-private data structures,
2745 	 * if needed by this HBA.  Add revised flow-control and queue
2746 	 * properties for child here, if desired and if you can tell they
2747 	 * support tagged queueing by now.
2748 	 */
2749 	mptsas_t		*mpt;
2750 	int			lun = sd->sd_address.a_lun;
2751 	mdi_pathinfo_t		*pip = NULL;
2752 	mptsas_tgt_private_t	*tgt_private = NULL;
2753 	mptsas_target_t		*ptgt = NULL;
2754 	char			*psas_wwn = NULL;
2755 	int			phymask = 0;
2756 	uint64_t		sas_wwn = 0;
2757 	mpt = SDEV2MPT(sd);
2758 
2759 	ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0);
2760 
2761 	NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d",
2762 	    (void *)hba_dip, (void *)tgt_dip, lun));
2763 
2764 	if (ndi_dev_is_persistent_node(tgt_dip) == 0) {
2765 		(void) ndi_merge_node(tgt_dip, mptsas_name_child);
2766 		ddi_set_name_addr(tgt_dip, NULL);
2767 		return (DDI_FAILURE);
2768 	}
2769 	/*
2770 	 * phymask is 0 means the virtual port for RAID
2771 	 */
2772 	phymask = ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0,
2773 	    "phymask", 0);
2774 	if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
2775 		if ((pip = (void *)(sd->sd_private)) == NULL) {
2776 			/*
2777 			 * Very bad news if this occurs. Somehow scsi_vhci has
2778 			 * lost the pathinfo node for this target.
2779 			 */
2780 			return (DDI_NOT_WELL_FORMED);
2781 		}
2782 
2783 		if (mdi_prop_lookup_int(pip, LUN_PROP, &lun) !=
2784 		    DDI_PROP_SUCCESS) {
2785 			mptsas_log(mpt, CE_WARN, "Get lun property failed\n");
2786 			return (DDI_FAILURE);
2787 		}
2788 
2789 		if (mdi_prop_lookup_string(pip, SCSI_ADDR_PROP_TARGET_PORT,
2790 		    &psas_wwn) == MDI_SUCCESS) {
2791 			if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) {
2792 				sas_wwn = 0;
2793 			}
2794 			(void) mdi_prop_free(psas_wwn);
2795 		}
2796 	} else {
2797 		lun = ddi_prop_get_int(DDI_DEV_T_ANY, tgt_dip,
2798 		    DDI_PROP_DONTPASS, LUN_PROP, 0);
2799 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, tgt_dip,
2800 		    DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &psas_wwn) ==
2801 		    DDI_PROP_SUCCESS) {
2802 			if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) {
2803 				sas_wwn = 0;
2804 			}
2805 			ddi_prop_free(psas_wwn);
2806 		} else {
2807 			sas_wwn = 0;
2808 		}
2809 	}
2810 	ASSERT((sas_wwn != 0) || (phymask != 0));
2811 	mutex_enter(&mpt->m_mutex);
2812 	ptgt = mptsas_hash_search(&mpt->m_active->m_tgttbl, sas_wwn, phymask);
2813 	mutex_exit(&mpt->m_mutex);
2814 	if (ptgt == NULL) {
2815 		mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or "
2816 		    "gone already! phymask:%x, saswwn %"PRIx64, phymask,
2817 		    sas_wwn);
2818 		return (DDI_FAILURE);
2819 	}
2820 	if (hba_tran->tran_tgt_private == NULL) {
2821 		tgt_private = kmem_zalloc(sizeof (mptsas_tgt_private_t),
2822 		    KM_SLEEP);
2823 		tgt_private->t_lun = lun;
2824 		tgt_private->t_private = ptgt;
2825 		hba_tran->tran_tgt_private = tgt_private;
2826 	}
2827 
2828 	if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
2829 		return (DDI_SUCCESS);
2830 	}
2831 	mutex_enter(&mpt->m_mutex);
2832 
2833 	if (ptgt->m_deviceinfo &
2834 	    (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
2835 	    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
2836 		uchar_t *inq89 = NULL;
2837 		int inq89_len = 0x238;
2838 		int reallen = 0;
2839 		int rval = 0;
2840 		struct sata_id *sid = NULL;
2841 		char model[SATA_ID_MODEL_LEN + 1];
2842 		char fw[SATA_ID_FW_LEN + 1];
2843 		char *vid, *pid;
2844 		int i;
2845 
2846 		mutex_exit(&mpt->m_mutex);
2847 		/*
2848 		 * According SCSI/ATA Translation -2 (SAT-2) revision 01a
2849 		 * chapter 12.4.2 VPD page 89h includes 512 bytes ATA IDENTIFY
2850 		 * DEVICE data or ATA IDENTIFY PACKET DEVICE data.
2851 		 */
2852 		inq89 = kmem_zalloc(inq89_len, KM_SLEEP);
2853 		rval = mptsas_inquiry(mpt, ptgt, 0, 0x89,
2854 		    inq89, inq89_len, &reallen, 1);
2855 
2856 		if (rval != 0) {
2857 			if (inq89 != NULL) {
2858 				kmem_free(inq89, inq89_len);
2859 			}
2860 
2861 			mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
2862 			    "0x89 for SATA target:%x failed!", ptgt->m_devhdl);
2863 			return (DDI_SUCCESS);
2864 		}
2865 		sid = (void *)(&inq89[60]);
2866 
2867 		swab(sid->ai_model, model, SATA_ID_MODEL_LEN);
2868 		swab(sid->ai_fw, fw, SATA_ID_FW_LEN);
2869 
2870 		model[SATA_ID_MODEL_LEN] = 0;
2871 		fw[SATA_ID_FW_LEN] = 0;
2872 
2873 		/*
2874 		 * split model into into vid/pid
2875 		 */
2876 		for (i = 0, pid = model; i < SATA_ID_MODEL_LEN; i++, pid++)
2877 			if ((*pid == ' ') || (*pid == '\t'))
2878 				break;
2879 		if (i < SATA_ID_MODEL_LEN) {
2880 			vid = model;
2881 			/*
2882 			 * terminate vid, establish pid
2883 			 */
2884 			*pid++ = 0;
2885 		} else {
2886 			/*
2887 			 * vid will stay "ATA     ", the rule is same
2888 			 * as sata framework implementation.
2889 			 */
2890 			vid = NULL;
2891 			/*
2892 			 * model is all pid
2893 			 */
2894 			pid = model;
2895 		}
2896 
2897 		/*
2898 		 * override SCSA "inquiry-*" properties
2899 		 */
2900 		if (vid)
2901 			(void) scsi_device_prop_update_inqstring(sd,
2902 			    INQUIRY_VENDOR_ID, vid, strlen(vid));
2903 		if (pid)
2904 			(void) scsi_device_prop_update_inqstring(sd,
2905 			    INQUIRY_PRODUCT_ID, pid, strlen(pid));
2906 		(void) scsi_device_prop_update_inqstring(sd,
2907 		    INQUIRY_REVISION_ID, fw, strlen(fw));
2908 
2909 		if (inq89 != NULL) {
2910 			kmem_free(inq89, inq89_len);
2911 		}
2912 	} else {
2913 		mutex_exit(&mpt->m_mutex);
2914 	}
2915 
2916 	return (DDI_SUCCESS);
2917 }
2918 /*
2919  * tran_tgt_free(9E) - target device instance deallocation
2920  */
2921 static void
2922 mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
2923     scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
2924 {
2925 #ifndef __lock_lint
2926 	_NOTE(ARGUNUSED(hba_dip, tgt_dip, hba_tran, sd))
2927 #endif
2928 
2929 	mptsas_tgt_private_t	*tgt_private = hba_tran->tran_tgt_private;
2930 
2931 	if (tgt_private != NULL) {
2932 		kmem_free(tgt_private, sizeof (mptsas_tgt_private_t));
2933 		hba_tran->tran_tgt_private = NULL;
2934 	}
2935 }
2936 
2937 /*
2938  * scsi_pkt handling
2939  *
2940  * Visible to the external world via the transport structure.
2941  */
2942 
2943 /*
2944  * Notes:
2945  *	- transport the command to the addressed SCSI target/lun device
2946  *	- normal operation is to schedule the command to be transported,
2947  *	  and return TRAN_ACCEPT if this is successful.
2948  *	- if NO_INTR, tran_start must poll device for command completion
2949  */
2950 static int
2951 mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt)
2952 {
2953 #ifndef __lock_lint
2954 	_NOTE(ARGUNUSED(ap))
2955 #endif
2956 	mptsas_t	*mpt = PKT2MPT(pkt);
2957 	mptsas_cmd_t	*cmd = PKT2CMD(pkt);
2958 	int		rval;
2959 	mptsas_target_t	*ptgt = cmd->cmd_tgt_addr;
2960 
2961 	NDBG1(("mptsas_scsi_start: pkt=0x%p", (void *)pkt));
2962 	ASSERT(ptgt);
2963 	if (ptgt == NULL)
2964 		return (TRAN_FATAL_ERROR);
2965 
2966 	/*
2967 	 * prepare the pkt before taking mutex.
2968 	 */
2969 	rval = mptsas_prepare_pkt(cmd);
2970 	if (rval != TRAN_ACCEPT) {
2971 		return (rval);
2972 	}
2973 
2974 	/*
2975 	 * Send the command to target/lun, however your HBA requires it.
2976 	 * If busy, return TRAN_BUSY; if there's some other formatting error
2977 	 * in the packet, return TRAN_BADPKT; otherwise, fall through to the
2978 	 * return of TRAN_ACCEPT.
2979 	 *
2980 	 * Remember that access to shared resources, including the mptsas_t
2981 	 * data structure and the HBA hardware registers, must be protected
2982 	 * with mutexes, here and everywhere.
2983 	 *
2984 	 * Also remember that at interrupt time, you'll get an argument
2985 	 * to the interrupt handler which is a pointer to your mptsas_t
2986 	 * structure; you'll have to remember which commands are outstanding
2987 	 * and which scsi_pkt is the currently-running command so the
2988 	 * interrupt handler can refer to the pkt to set completion
2989 	 * status, call the target driver back through pkt_comp, etc.
2990 	 *
2991 	 * If the instance lock is held by other thread, don't spin to wait
2992 	 * for it. Instead, queue the cmd and next time when the instance lock
2993 	 * is not held, accept all the queued cmd. A extra tx_waitq is
2994 	 * introduced to protect the queue.
2995 	 *
2996 	 * The polled cmd will not be queud and accepted as usual.
2997 	 *
2998 	 * Under the tx_waitq mutex, record whether a thread is draining
2999 	 * the tx_waitq.  An IO requesting thread that finds the instance
3000 	 * mutex contended appends to the tx_waitq and while holding the
3001 	 * tx_wait mutex, if the draining flag is not set, sets it and then
3002 	 * proceeds to spin for the instance mutex. This scheme ensures that
3003 	 * the last cmd in a burst be processed.
3004 	 *
3005 	 * we enable this feature only when the helper threads are enabled,
3006 	 * at which we think the loads are heavy.
3007 	 *
3008 	 * per instance mutex m_tx_waitq_mutex is introduced to protect the
3009 	 * m_tx_waitqtail, m_tx_waitq, m_tx_draining.
3010 	 */
3011 
3012 	if (mpt->m_doneq_thread_n) {
3013 		if (mutex_tryenter(&mpt->m_mutex) != 0) {
3014 			rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
3015 			mutex_exit(&mpt->m_mutex);
3016 		} else if (cmd->cmd_pkt_flags & FLAG_NOINTR) {
3017 			mutex_enter(&mpt->m_mutex);
3018 			rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
3019 			mutex_exit(&mpt->m_mutex);
3020 		} else {
3021 			mutex_enter(&mpt->m_tx_waitq_mutex);
3022 			/*
3023 			 * ptgt->m_dr_flag is protected by m_mutex or
3024 			 * m_tx_waitq_mutex. In this case, m_tx_waitq_mutex
3025 			 * is acquired.
3026 			 */
3027 			if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
3028 				if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
3029 					/*
3030 					 * The command should be allowed to
3031 					 * retry by returning TRAN_BUSY to
3032 					 * to stall the I/O's which come from
3033 					 * scsi_vhci since the device/path is
3034 					 * in unstable state now.
3035 					 */
3036 					mutex_exit(&mpt->m_tx_waitq_mutex);
3037 					return (TRAN_BUSY);
3038 				} else {
3039 					/*
3040 					 * The device is offline, just fail the
3041 					 * command by returning
3042 					 * TRAN_FATAL_ERROR.
3043 					 */
3044 					mutex_exit(&mpt->m_tx_waitq_mutex);
3045 					return (TRAN_FATAL_ERROR);
3046 				}
3047 			}
3048 			if (mpt->m_tx_draining) {
3049 				cmd->cmd_flags |= CFLAG_TXQ;
3050 				*mpt->m_tx_waitqtail = cmd;
3051 				mpt->m_tx_waitqtail = &cmd->cmd_linkp;
3052 				mutex_exit(&mpt->m_tx_waitq_mutex);
3053 			} else { /* drain the queue */
3054 				mpt->m_tx_draining = 1;
3055 				mutex_exit(&mpt->m_tx_waitq_mutex);
3056 				mutex_enter(&mpt->m_mutex);
3057 				rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
3058 				mutex_exit(&mpt->m_mutex);
3059 			}
3060 		}
3061 	} else {
3062 		mutex_enter(&mpt->m_mutex);
3063 		/*
3064 		 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex
3065 		 * in this case, m_mutex is acquired.
3066 		 */
3067 		if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
3068 			if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
3069 				/*
3070 				 * commands should be allowed to retry by
3071 				 * returning TRAN_BUSY to stall the I/O's
3072 				 * which come from scsi_vhci since the device/
3073 				 * path is in unstable state now.
3074 				 */
3075 				mutex_exit(&mpt->m_mutex);
3076 				return (TRAN_BUSY);
3077 			} else {
3078 				/*
3079 				 * The device is offline, just fail the
3080 				 * command by returning TRAN_FATAL_ERROR.
3081 				 */
3082 				mutex_exit(&mpt->m_mutex);
3083 				return (TRAN_FATAL_ERROR);
3084 			}
3085 		}
3086 		rval = mptsas_accept_pkt(mpt, cmd);
3087 		mutex_exit(&mpt->m_mutex);
3088 	}
3089 
3090 	return (rval);
3091 }
3092 
3093 /*
3094  * Accept all the queued cmds(if any) before accept the current one.
3095  */
3096 static int
3097 mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd)
3098 {
3099 	int rval;
3100 	mptsas_target_t	*ptgt = cmd->cmd_tgt_addr;
3101 
3102 	ASSERT(mutex_owned(&mpt->m_mutex));
3103 	/*
3104 	 * The call to mptsas_accept_tx_waitq() must always be performed
3105 	 * because that is where mpt->m_tx_draining is cleared.
3106 	 */
3107 	mutex_enter(&mpt->m_tx_waitq_mutex);
3108 	mptsas_accept_tx_waitq(mpt);
3109 	mutex_exit(&mpt->m_tx_waitq_mutex);
3110 	/*
3111 	 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex
3112 	 * in this case, m_mutex is acquired.
3113 	 */
3114 	if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
3115 		if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
3116 			/*
3117 			 * The command should be allowed to retry by returning
3118 			 * TRAN_BUSY to stall the I/O's which come from
3119 			 * scsi_vhci since the device/path is in unstable state
3120 			 * now.
3121 			 */
3122 			return (TRAN_BUSY);
3123 		} else {
3124 			/*
3125 			 * The device is offline, just fail the command by
3126 			 * return TRAN_FATAL_ERROR.
3127 			 */
3128 			return (TRAN_FATAL_ERROR);
3129 		}
3130 	}
3131 	rval = mptsas_accept_pkt(mpt, cmd);
3132 
3133 	return (rval);
3134 }
3135 
3136 static int
3137 mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd)
3138 {
3139 	int		rval = TRAN_ACCEPT;
3140 	mptsas_target_t	*ptgt = cmd->cmd_tgt_addr;
3141 
3142 	NDBG1(("mptsas_accept_pkt: cmd=0x%p", (void *)cmd));
3143 
3144 	ASSERT(mutex_owned(&mpt->m_mutex));
3145 
3146 	if ((cmd->cmd_flags & CFLAG_PREPARED) == 0) {
3147 		rval = mptsas_prepare_pkt(cmd);
3148 		if (rval != TRAN_ACCEPT) {
3149 			cmd->cmd_flags &= ~CFLAG_TRANFLAG;
3150 			return (rval);
3151 		}
3152 	}
3153 
3154 	/*
3155 	 * reset the throttle if we were draining
3156 	 */
3157 	if ((ptgt->m_t_ncmds == 0) &&
3158 	    (ptgt->m_t_throttle == DRAIN_THROTTLE)) {
3159 		NDBG23(("reset throttle"));
3160 		ASSERT(ptgt->m_reset_delay == 0);
3161 		mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
3162 	}
3163 
3164 	/*
3165 	 * If device handle has already been invalidated, just
3166 	 * fail the command. In theory, command from scsi_vhci
3167 	 * client is impossible send down command with invalid
3168 	 * devhdl since devhdl is set after path offline, target
3169 	 * driver is not suppose to select a offlined path.
3170 	 */
3171 	if (ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) {
3172 		NDBG20(("rejecting command, it might because invalid devhdl "
3173 		    "request."));
3174 		mptsas_set_pkt_reason(mpt, cmd, CMD_DEV_GONE, STAT_TERMINATED);
3175 		if (cmd->cmd_flags & CFLAG_TXQ) {
3176 			mptsas_doneq_add(mpt, cmd);
3177 			mptsas_doneq_empty(mpt);
3178 			return (rval);
3179 		} else {
3180 			return (TRAN_FATAL_ERROR);
3181 		}
3182 	}
3183 	/*
3184 	 * The first case is the normal case.  mpt gets a command from the
3185 	 * target driver and starts it.
3186 	 * Since SMID 0 is reserved and the TM slot is reserved, the actual max
3187 	 * commands is m_max_requests - 2.
3188 	 */
3189 	if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) &&
3190 	    (ptgt->m_t_throttle > HOLD_THROTTLE) &&
3191 	    (ptgt->m_t_ncmds < ptgt->m_t_throttle) &&
3192 	    (ptgt->m_reset_delay == 0) &&
3193 	    (ptgt->m_t_nwait == 0) &&
3194 	    ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0)) {
3195 		if (mptsas_save_cmd(mpt, cmd) == TRUE) {
3196 			(void) mptsas_start_cmd(mpt, cmd);
3197 		} else {
3198 			mptsas_waitq_add(mpt, cmd);
3199 		}
3200 	} else {
3201 		/*
3202 		 * Add this pkt to the work queue
3203 		 */
3204 		mptsas_waitq_add(mpt, cmd);
3205 
3206 		if (cmd->cmd_pkt_flags & FLAG_NOINTR) {
3207 			(void) mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME);
3208 
3209 			/*
3210 			 * Only flush the doneq if this is not a TM
3211 			 * cmd.  For TM cmds the flushing of the
3212 			 * doneq will be done in those routines.
3213 			 */
3214 			if ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
3215 				mptsas_doneq_empty(mpt);
3216 			}
3217 		}
3218 	}
3219 	return (rval);
3220 }
3221 
3222 int
3223 mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
3224 {
3225 	mptsas_slots_t	*slots;
3226 	int		slot;
3227 	mptsas_target_t	*ptgt = cmd->cmd_tgt_addr;
3228 
3229 	ASSERT(mutex_owned(&mpt->m_mutex));
3230 	slots = mpt->m_active;
3231 
3232 	/*
3233 	 * Account for reserved TM request slot and reserved SMID of 0.
3234 	 */
3235 	ASSERT(slots->m_n_slots == (mpt->m_max_requests - 2));
3236 
3237 	/*
3238 	 * m_tags is equivalent to the SMID when sending requests.  Since the
3239 	 * SMID cannot be 0, start out at one if rolling over past the size
3240 	 * of the request queue depth.  Also, don't use the last SMID, which is
3241 	 * reserved for TM requests.
3242 	 */
3243 	slot = (slots->m_tags)++;
3244 	if (slots->m_tags > slots->m_n_slots) {
3245 		slots->m_tags = 1;
3246 	}
3247 
3248 alloc_tag:
3249 	/* Validate tag, should never fail. */
3250 	if (slots->m_slot[slot] == NULL) {
3251 		/*
3252 		 * Make sure SMID is not using reserved value of 0
3253 		 * and the TM request slot.
3254 		 */
3255 		ASSERT((slot > 0) && (slot <= slots->m_n_slots));
3256 		cmd->cmd_slot = slot;
3257 		slots->m_slot[slot] = cmd;
3258 		mpt->m_ncmds++;
3259 
3260 		/*
3261 		 * only increment per target ncmds if this is not a
3262 		 * command that has no target associated with it (i.e. a
3263 		 * event acknoledgment)
3264 		 */
3265 		if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
3266 			ptgt->m_t_ncmds++;
3267 		}
3268 		cmd->cmd_active_timeout = cmd->cmd_pkt->pkt_time;
3269 
3270 		/*
3271 		 * If initial timout is less than or equal to one tick, bump
3272 		 * the timeout by a tick so that command doesn't timeout before
3273 		 * its allotted time.
3274 		 */
3275 		if (cmd->cmd_active_timeout <= mptsas_scsi_watchdog_tick) {
3276 			cmd->cmd_active_timeout += mptsas_scsi_watchdog_tick;
3277 		}
3278 		return (TRUE);
3279 	} else {
3280 		int i;
3281 
3282 		/*
3283 		 * If slot in use, scan until a free one is found. Don't use 0
3284 		 * or final slot, which is reserved for TM requests.
3285 		 */
3286 		for (i = 0; i < slots->m_n_slots; i++) {
3287 			slot = slots->m_tags;
3288 			if (++(slots->m_tags) > slots->m_n_slots) {
3289 				slots->m_tags = 1;
3290 			}
3291 			if (slots->m_slot[slot] == NULL) {
3292 				NDBG22(("found free slot %d", slot));
3293 				goto alloc_tag;
3294 			}
3295 		}
3296 	}
3297 	return (FALSE);
3298 }
3299 
3300 /*
3301  * prepare the pkt:
3302  * the pkt may have been resubmitted or just reused so
3303  * initialize some fields and do some checks.
3304  */
3305 static int
3306 mptsas_prepare_pkt(mptsas_cmd_t *cmd)
3307 {
3308 	struct scsi_pkt	*pkt = CMD2PKT(cmd);
3309 
3310 	NDBG1(("mptsas_prepare_pkt: cmd=0x%p", (void *)cmd));
3311 
3312 	/*
3313 	 * Reinitialize some fields that need it; the packet may
3314 	 * have been resubmitted
3315 	 */
3316 	pkt->pkt_reason = CMD_CMPLT;
3317 	pkt->pkt_state = 0;
3318 	pkt->pkt_statistics = 0;
3319 	pkt->pkt_resid = 0;
3320 	cmd->cmd_age = 0;
3321 	cmd->cmd_pkt_flags = pkt->pkt_flags;
3322 
3323 	/*
3324 	 * zero status byte.
3325 	 */
3326 	*(pkt->pkt_scbp) = 0;
3327 
3328 	if (cmd->cmd_flags & CFLAG_DMAVALID) {
3329 		pkt->pkt_resid = cmd->cmd_dmacount;
3330 
3331 		/*
3332 		 * consistent packets need to be sync'ed first
3333 		 * (only for data going out)
3334 		 */
3335 		if ((cmd->cmd_flags & CFLAG_CMDIOPB) &&
3336 		    (cmd->cmd_flags & CFLAG_DMASEND)) {
3337 			(void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
3338 			    DDI_DMA_SYNC_FORDEV);
3339 		}
3340 	}
3341 
3342 	cmd->cmd_flags =
3343 	    (cmd->cmd_flags & ~(CFLAG_TRANFLAG)) |
3344 	    CFLAG_PREPARED | CFLAG_IN_TRANSPORT;
3345 
3346 	return (TRAN_ACCEPT);
3347 }
3348 
3349 /*
3350  * tran_init_pkt(9E) - allocate scsi_pkt(9S) for command
3351  *
3352  * One of three possibilities:
3353  *	- allocate scsi_pkt
3354  *	- allocate scsi_pkt and DMA resources
3355  *	- allocate DMA resources to an already-allocated pkt
3356  */
3357 static struct scsi_pkt *
3358 mptsas_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt,
3359     struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags,
3360     int (*callback)(), caddr_t arg)
3361 {
3362 	mptsas_cmd_t		*cmd, *new_cmd;
3363 	mptsas_t		*mpt = ADDR2MPT(ap);
3364 	int			failure = 1;
3365 	uint_t			oldcookiec;
3366 	mptsas_target_t		*ptgt = NULL;
3367 	int			rval;
3368 	mptsas_tgt_private_t	*tgt_private;
3369 	int			kf;
3370 
3371 	kf = (callback == SLEEP_FUNC)? KM_SLEEP: KM_NOSLEEP;
3372 
3373 	tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->
3374 	    tran_tgt_private;
3375 	ASSERT(tgt_private != NULL);
3376 	if (tgt_private == NULL) {
3377 		return (NULL);
3378 	}
3379 	ptgt = tgt_private->t_private;
3380 	ASSERT(ptgt != NULL);
3381 	if (ptgt == NULL)
3382 		return (NULL);
3383 	ap->a_target = ptgt->m_devhdl;
3384 	ap->a_lun = tgt_private->t_lun;
3385 
3386 	ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC);
3387 #ifdef MPTSAS_TEST_EXTRN_ALLOC
3388 	statuslen *= 100; tgtlen *= 4;
3389 #endif
3390 	NDBG3(("mptsas_scsi_init_pkt:\n"
3391 	    "\ttgt=%d in=0x%p bp=0x%p clen=%d slen=%d tlen=%d flags=%x",
3392 	    ap->a_target, (void *)pkt, (void *)bp,
3393 	    cmdlen, statuslen, tgtlen, flags));
3394 
3395 	/*
3396 	 * Allocate the new packet.
3397 	 */
3398 	if (pkt == NULL) {
3399 		ddi_dma_handle_t	save_dma_handle;
3400 		ddi_dma_handle_t	save_arq_dma_handle;
3401 		struct buf		*save_arq_bp;
3402 		ddi_dma_cookie_t	save_arqcookie;
3403 
3404 		cmd = kmem_cache_alloc(mpt->m_kmem_cache, kf);
3405 
3406 		if (cmd) {
3407 			save_dma_handle = cmd->cmd_dmahandle;
3408 			save_arq_dma_handle = cmd->cmd_arqhandle;
3409 			save_arq_bp = cmd->cmd_arq_buf;
3410 			save_arqcookie = cmd->cmd_arqcookie;
3411 			bzero(cmd, sizeof (*cmd) + scsi_pkt_size());
3412 			cmd->cmd_dmahandle = save_dma_handle;
3413 			cmd->cmd_arqhandle = save_arq_dma_handle;
3414 			cmd->cmd_arq_buf = save_arq_bp;
3415 			cmd->cmd_arqcookie = save_arqcookie;
3416 
3417 			pkt = (void *)((uchar_t *)cmd +
3418 			    sizeof (struct mptsas_cmd));
3419 			pkt->pkt_ha_private = (opaque_t)cmd;
3420 			pkt->pkt_address = *ap;
3421 			pkt->pkt_private = (opaque_t)cmd->cmd_pkt_private;
3422 			pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb;
3423 			pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb;
3424 			cmd->cmd_pkt = (struct scsi_pkt *)pkt;
3425 			cmd->cmd_cdblen = (uchar_t)cmdlen;
3426 			cmd->cmd_scblen = statuslen;
3427 			cmd->cmd_rqslen = SENSE_LENGTH;
3428 			cmd->cmd_tgt_addr = ptgt;
3429 			failure = 0;
3430 		}
3431 
3432 		if (failure || (cmdlen > sizeof (cmd->cmd_cdb)) ||
3433 		    (tgtlen > PKT_PRIV_LEN) ||
3434 		    (statuslen > EXTCMDS_STATUS_SIZE)) {
3435 			if (failure == 0) {
3436 				/*
3437 				 * if extern alloc fails, all will be
3438 				 * deallocated, including cmd
3439 				 */
3440 				failure = mptsas_pkt_alloc_extern(mpt, cmd,
3441 				    cmdlen, tgtlen, statuslen, kf);
3442 			}
3443 			if (failure) {
3444 				/*
3445 				 * if extern allocation fails, it will
3446 				 * deallocate the new pkt as well
3447 				 */
3448 				return (NULL);
3449 			}
3450 		}
3451 		new_cmd = cmd;
3452 
3453 	} else {
3454 		cmd = PKT2CMD(pkt);
3455 		new_cmd = NULL;
3456 	}
3457 
3458 
3459 	/* grab cmd->cmd_cookiec here as oldcookiec */
3460 
3461 	oldcookiec = cmd->cmd_cookiec;
3462 
3463 	/*
3464 	 * If the dma was broken up into PARTIAL transfers cmd_nwin will be
3465 	 * greater than 0 and we'll need to grab the next dma window
3466 	 */
3467 	/*
3468 	 * SLM-not doing extra command frame right now; may add later
3469 	 */
3470 
3471 	if (cmd->cmd_nwin > 0) {
3472 
3473 		/*
3474 		 * Make sure we havn't gone past the the total number
3475 		 * of windows
3476 		 */
3477 		if (++cmd->cmd_winindex >= cmd->cmd_nwin) {
3478 			return (NULL);
3479 		}
3480 		if (ddi_dma_getwin(cmd->cmd_dmahandle, cmd->cmd_winindex,
3481 		    &cmd->cmd_dma_offset, &cmd->cmd_dma_len,
3482 		    &cmd->cmd_cookie, &cmd->cmd_cookiec) == DDI_FAILURE) {
3483 			return (NULL);
3484 		}
3485 		goto get_dma_cookies;
3486 	}
3487 
3488 
3489 	if (flags & PKT_XARQ) {
3490 		cmd->cmd_flags |= CFLAG_XARQ;
3491 	}
3492 
3493 	/*
3494 	 * DMA resource allocation.  This version assumes your
3495 	 * HBA has some sort of bus-mastering or onboard DMA capability, with a
3496 	 * scatter-gather list of length MPTSAS_MAX_DMA_SEGS, as given in the
3497 	 * ddi_dma_attr_t structure and passed to scsi_impl_dmaget.
3498 	 */
3499 	if (bp && (bp->b_bcount != 0) &&
3500 	    (cmd->cmd_flags & CFLAG_DMAVALID) == 0) {
3501 
3502 		int	cnt, dma_flags;
3503 		mptti_t	*dmap;		/* ptr to the S/G list */
3504 
3505 		/*
3506 		 * Set up DMA memory and position to the next DMA segment.
3507 		 */
3508 		ASSERT(cmd->cmd_dmahandle != NULL);
3509 
3510 		if (bp->b_flags & B_READ) {
3511 			dma_flags = DDI_DMA_READ;
3512 			cmd->cmd_flags &= ~CFLAG_DMASEND;
3513 		} else {
3514 			dma_flags = DDI_DMA_WRITE;
3515 			cmd->cmd_flags |= CFLAG_DMASEND;
3516 		}
3517 		if (flags & PKT_CONSISTENT) {
3518 			cmd->cmd_flags |= CFLAG_CMDIOPB;
3519 			dma_flags |= DDI_DMA_CONSISTENT;
3520 		}
3521 
3522 		if (flags & PKT_DMA_PARTIAL) {
3523 			dma_flags |= DDI_DMA_PARTIAL;
3524 		}
3525 
3526 		/*
3527 		 * workaround for byte hole issue on psycho and
3528 		 * schizo pre 2.1
3529 		 */
3530 		if ((bp->b_flags & B_READ) && ((bp->b_flags &
3531 		    (B_PAGEIO|B_REMAPPED)) != B_PAGEIO) &&
3532 		    ((uintptr_t)bp->b_un.b_addr & 0x7)) {
3533 			dma_flags |= DDI_DMA_CONSISTENT;
3534 		}
3535 
3536 		rval = ddi_dma_buf_bind_handle(cmd->cmd_dmahandle, bp,
3537 		    dma_flags, callback, arg,
3538 		    &cmd->cmd_cookie, &cmd->cmd_cookiec);
3539 		if (rval == DDI_DMA_PARTIAL_MAP) {
3540 			(void) ddi_dma_numwin(cmd->cmd_dmahandle,
3541 			    &cmd->cmd_nwin);
3542 			cmd->cmd_winindex = 0;
3543 			(void) ddi_dma_getwin(cmd->cmd_dmahandle,
3544 			    cmd->cmd_winindex, &cmd->cmd_dma_offset,
3545 			    &cmd->cmd_dma_len, &cmd->cmd_cookie,
3546 			    &cmd->cmd_cookiec);
3547 		} else if (rval && (rval != DDI_DMA_MAPPED)) {
3548 			switch (rval) {
3549 			case DDI_DMA_NORESOURCES:
3550 				bioerror(bp, 0);
3551 				break;
3552 			case DDI_DMA_BADATTR:
3553 			case DDI_DMA_NOMAPPING:
3554 				bioerror(bp, EFAULT);
3555 				break;
3556 			case DDI_DMA_TOOBIG:
3557 			default:
3558 				bioerror(bp, EINVAL);
3559 				break;
3560 			}
3561 			cmd->cmd_flags &= ~CFLAG_DMAVALID;
3562 			if (new_cmd) {
3563 				mptsas_scsi_destroy_pkt(ap, pkt);
3564 			}
3565 			return ((struct scsi_pkt *)NULL);
3566 		}
3567 
3568 get_dma_cookies:
3569 		cmd->cmd_flags |= CFLAG_DMAVALID;
3570 		ASSERT(cmd->cmd_cookiec > 0);
3571 
3572 		if (cmd->cmd_cookiec > MPTSAS_MAX_CMD_SEGS) {
3573 			mptsas_log(mpt, CE_NOTE, "large cookiec received %d\n",
3574 			    cmd->cmd_cookiec);
3575 			bioerror(bp, EINVAL);
3576 			if (new_cmd) {
3577 				mptsas_scsi_destroy_pkt(ap, pkt);
3578 			}
3579 			return ((struct scsi_pkt *)NULL);
3580 		}
3581 
3582 		/*
3583 		 * Allocate extra SGL buffer if needed.
3584 		 */
3585 		if ((cmd->cmd_cookiec > MPTSAS_MAX_FRAME_SGES64(mpt)) &&
3586 		    (cmd->cmd_extra_frames == NULL)) {
3587 			if (mptsas_alloc_extra_sgl_frame(mpt, cmd) ==
3588 			    DDI_FAILURE) {
3589 				mptsas_log(mpt, CE_WARN, "MPT SGL mem alloc "
3590 				    "failed");
3591 				bioerror(bp, ENOMEM);
3592 				if (new_cmd) {
3593 					mptsas_scsi_destroy_pkt(ap, pkt);
3594 				}
3595 				return ((struct scsi_pkt *)NULL);
3596 			}
3597 		}
3598 
3599 		/*
3600 		 * Always use scatter-gather transfer
3601 		 * Use the loop below to store physical addresses of
3602 		 * DMA segments, from the DMA cookies, into your HBA's
3603 		 * scatter-gather list.
3604 		 * We need to ensure we have enough kmem alloc'd
3605 		 * for the sg entries since we are no longer using an
3606 		 * array inside mptsas_cmd_t.
3607 		 *
3608 		 * We check cmd->cmd_cookiec against oldcookiec so
3609 		 * the scatter-gather list is correctly allocated
3610 		 */
3611 
3612 		if (oldcookiec != cmd->cmd_cookiec) {
3613 			if (cmd->cmd_sg != (mptti_t *)NULL) {
3614 				kmem_free(cmd->cmd_sg, sizeof (mptti_t) *
3615 				    oldcookiec);
3616 				cmd->cmd_sg = NULL;
3617 			}
3618 		}
3619 
3620 		if (cmd->cmd_sg == (mptti_t *)NULL) {
3621 			cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)*
3622 			    cmd->cmd_cookiec), kf);
3623 
3624 			if (cmd->cmd_sg == (mptti_t *)NULL) {
3625 				mptsas_log(mpt, CE_WARN,
3626 				    "unable to kmem_alloc enough memory "
3627 				    "for scatter/gather list");
3628 		/*
3629 		 * if we have an ENOMEM condition we need to behave
3630 		 * the same way as the rest of this routine
3631 		 */
3632 
3633 				bioerror(bp, ENOMEM);
3634 				if (new_cmd) {
3635 					mptsas_scsi_destroy_pkt(ap, pkt);
3636 				}
3637 				return ((struct scsi_pkt *)NULL);
3638 			}
3639 		}
3640 
3641 		dmap = cmd->cmd_sg;
3642 
3643 		ASSERT(cmd->cmd_cookie.dmac_size != 0);
3644 
3645 		/*
3646 		 * store the first segment into the S/G list
3647 		 */
3648 		dmap->count = cmd->cmd_cookie.dmac_size;
3649 		dmap->addr.address64.Low = (uint32_t)
3650 		    (cmd->cmd_cookie.dmac_laddress & 0xffffffffull);
3651 		dmap->addr.address64.High = (uint32_t)
3652 		    (cmd->cmd_cookie.dmac_laddress >> 32);
3653 
3654 		/*
3655 		 * dmacount counts the size of the dma for this window
3656 		 * (if partial dma is being used).  totaldmacount
3657 		 * keeps track of the total amount of dma we have
3658 		 * transferred for all the windows (needed to calculate
3659 		 * the resid value below).
3660 		 */
3661 		cmd->cmd_dmacount = cmd->cmd_cookie.dmac_size;
3662 		cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size;
3663 
3664 		/*
3665 		 * We already stored the first DMA scatter gather segment,
3666 		 * start at 1 if we need to store more.
3667 		 */
3668 		for (cnt = 1; cnt < cmd->cmd_cookiec; cnt++) {
3669 			/*
3670 			 * Get next DMA cookie
3671 			 */
3672 			ddi_dma_nextcookie(cmd->cmd_dmahandle,
3673 			    &cmd->cmd_cookie);
3674 			dmap++;
3675 
3676 			cmd->cmd_dmacount += cmd->cmd_cookie.dmac_size;
3677 			cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size;
3678 
3679 			/*
3680 			 * store the segment parms into the S/G list
3681 			 */
3682 			dmap->count = cmd->cmd_cookie.dmac_size;
3683 			dmap->addr.address64.Low = (uint32_t)
3684 			    (cmd->cmd_cookie.dmac_laddress & 0xffffffffull);
3685 			dmap->addr.address64.High = (uint32_t)
3686 			    (cmd->cmd_cookie.dmac_laddress >> 32);
3687 		}
3688 
3689 		/*
3690 		 * If this was partially allocated we set the resid
3691 		 * the amount of data NOT transferred in this window
3692 		 * If there is only one window, the resid will be 0
3693 		 */
3694 		pkt->pkt_resid = (bp->b_bcount - cmd->cmd_totaldmacount);
3695 		NDBG16(("mptsas_dmaget: cmd_dmacount=%d.", cmd->cmd_dmacount));
3696 	}
3697 	return (pkt);
3698 }
3699 
3700 /*
3701  * tran_destroy_pkt(9E) - scsi_pkt(9s) deallocation
3702  *
3703  * Notes:
3704  *	- also frees DMA resources if allocated
3705  *	- implicit DMA synchonization
3706  */
3707 static void
3708 mptsas_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
3709 {
3710 	mptsas_cmd_t	*cmd = PKT2CMD(pkt);
3711 	mptsas_t	*mpt = ADDR2MPT(ap);
3712 
3713 	NDBG3(("mptsas_scsi_destroy_pkt: target=%d pkt=0x%p",
3714 	    ap->a_target, (void *)pkt));
3715 
3716 	if (cmd->cmd_flags & CFLAG_DMAVALID) {
3717 		(void) ddi_dma_unbind_handle(cmd->cmd_dmahandle);
3718 		cmd->cmd_flags &= ~CFLAG_DMAVALID;
3719 	}
3720 
3721 	if (cmd->cmd_sg) {
3722 		kmem_free(cmd->cmd_sg, sizeof (mptti_t) * cmd->cmd_cookiec);
3723 		cmd->cmd_sg = NULL;
3724 	}
3725 
3726 	mptsas_free_extra_sgl_frame(mpt, cmd);
3727 
3728 	if ((cmd->cmd_flags &
3729 	    (CFLAG_FREE | CFLAG_CDBEXTERN | CFLAG_PRIVEXTERN |
3730 	    CFLAG_SCBEXTERN)) == 0) {
3731 		cmd->cmd_flags = CFLAG_FREE;
3732 		kmem_cache_free(mpt->m_kmem_cache, (void *)cmd);
3733 	} else {
3734 		mptsas_pkt_destroy_extern(mpt, cmd);
3735 	}
3736 }
3737 
3738 /*
3739  * kmem cache constructor and destructor:
3740  * When constructing, we bzero the cmd and allocate the dma handle
3741  * When destructing, just free the dma handle
3742  */
3743 static int
3744 mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags)
3745 {
3746 	mptsas_cmd_t		*cmd = buf;
3747 	mptsas_t		*mpt  = cdrarg;
3748 	struct scsi_address	ap;
3749 	uint_t			cookiec;
3750 	ddi_dma_attr_t		arq_dma_attr;
3751 	int			(*callback)(caddr_t);
3752 
3753 	callback = (kmflags == KM_SLEEP)? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT;
3754 
3755 	NDBG4(("mptsas_kmem_cache_constructor"));
3756 
3757 	ap.a_hba_tran = mpt->m_tran;
3758 	ap.a_target = 0;
3759 	ap.a_lun = 0;
3760 
3761 	/*
3762 	 * allocate a dma handle
3763 	 */
3764 	if ((ddi_dma_alloc_handle(mpt->m_dip, &mpt->m_io_dma_attr, callback,
3765 	    NULL, &cmd->cmd_dmahandle)) != DDI_SUCCESS) {
3766 		cmd->cmd_dmahandle = NULL;
3767 		return (-1);
3768 	}
3769 
3770 	cmd->cmd_arq_buf = scsi_alloc_consistent_buf(&ap, (struct buf *)NULL,
3771 	    SENSE_LENGTH, B_READ, callback, NULL);
3772 	if (cmd->cmd_arq_buf == NULL) {
3773 		ddi_dma_free_handle(&cmd->cmd_dmahandle);
3774 		cmd->cmd_dmahandle = NULL;
3775 		return (-1);
3776 	}
3777 
3778 	/*
3779 	 * allocate a arq handle
3780 	 */
3781 	arq_dma_attr = mpt->m_msg_dma_attr;
3782 	arq_dma_attr.dma_attr_sgllen = 1;
3783 	if ((ddi_dma_alloc_handle(mpt->m_dip, &arq_dma_attr, callback,
3784 	    NULL, &cmd->cmd_arqhandle)) != DDI_SUCCESS) {
3785 		ddi_dma_free_handle(&cmd->cmd_dmahandle);
3786 		scsi_free_consistent_buf(cmd->cmd_arq_buf);
3787 		cmd->cmd_dmahandle = NULL;
3788 		cmd->cmd_arqhandle = NULL;
3789 		return (-1);
3790 	}
3791 
3792 	if (ddi_dma_buf_bind_handle(cmd->cmd_arqhandle,
3793 	    cmd->cmd_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT),
3794 	    callback, NULL, &cmd->cmd_arqcookie, &cookiec) != DDI_SUCCESS) {
3795 		ddi_dma_free_handle(&cmd->cmd_dmahandle);
3796 		ddi_dma_free_handle(&cmd->cmd_arqhandle);
3797 		scsi_free_consistent_buf(cmd->cmd_arq_buf);
3798 		cmd->cmd_dmahandle = NULL;
3799 		cmd->cmd_arqhandle = NULL;
3800 		cmd->cmd_arq_buf = NULL;
3801 		return (-1);
3802 	}
3803 
3804 	return (0);
3805 }
3806 
3807 static void
3808 mptsas_kmem_cache_destructor(void *buf, void *cdrarg)
3809 {
3810 #ifndef __lock_lint
3811 	_NOTE(ARGUNUSED(cdrarg))
3812 #endif
3813 	mptsas_cmd_t	*cmd = buf;
3814 
3815 	NDBG4(("mptsas_kmem_cache_destructor"));
3816 
3817 	if (cmd->cmd_arqhandle) {
3818 		(void) ddi_dma_unbind_handle(cmd->cmd_arqhandle);
3819 		ddi_dma_free_handle(&cmd->cmd_arqhandle);
3820 		cmd->cmd_arqhandle = NULL;
3821 	}
3822 	if (cmd->cmd_arq_buf) {
3823 		scsi_free_consistent_buf(cmd->cmd_arq_buf);
3824 		cmd->cmd_arq_buf = NULL;
3825 	}
3826 	if (cmd->cmd_dmahandle) {
3827 		ddi_dma_free_handle(&cmd->cmd_dmahandle);
3828 		cmd->cmd_dmahandle = NULL;
3829 	}
3830 }
3831 
3832 static int
3833 mptsas_cache_frames_constructor(void *buf, void *cdrarg, int kmflags)
3834 {
3835 	mptsas_cache_frames_t	*p = buf;
3836 	mptsas_t		*mpt = cdrarg;
3837 	ddi_dma_attr_t		frame_dma_attr;
3838 	size_t			mem_size, alloc_len;
3839 	ddi_dma_cookie_t	cookie;
3840 	uint_t			ncookie;
3841 	int (*callback)(caddr_t) = (kmflags == KM_SLEEP)
3842 	    ? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT;
3843 
3844 	frame_dma_attr = mpt->m_msg_dma_attr;
3845 	frame_dma_attr.dma_attr_align = 0x10;
3846 	frame_dma_attr.dma_attr_sgllen = 1;
3847 
3848 	if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attr, callback, NULL,
3849 	    &p->m_dma_hdl) != DDI_SUCCESS) {
3850 		mptsas_log(mpt, CE_WARN, "Unable to allocate dma handle for"
3851 		    " extra SGL.");
3852 		return (DDI_FAILURE);
3853 	}
3854 
3855 	mem_size = (mpt->m_max_request_frames - 1) * mpt->m_req_frame_size;
3856 
3857 	if (ddi_dma_mem_alloc(p->m_dma_hdl, mem_size, &mpt->m_dev_acc_attr,
3858 	    DDI_DMA_CONSISTENT, callback, NULL, (caddr_t *)&p->m_frames_addr,
3859 	    &alloc_len, &p->m_acc_hdl) != DDI_SUCCESS) {
3860 		ddi_dma_free_handle(&p->m_dma_hdl);
3861 		p->m_dma_hdl = NULL;
3862 		mptsas_log(mpt, CE_WARN, "Unable to allocate dma memory for"
3863 		    " extra SGL.");
3864 		return (DDI_FAILURE);
3865 	}
3866 
3867 	if (ddi_dma_addr_bind_handle(p->m_dma_hdl, NULL, p->m_frames_addr,
3868 	    alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, callback, NULL,
3869 	    &cookie, &ncookie) != DDI_DMA_MAPPED) {
3870 		(void) ddi_dma_mem_free(&p->m_acc_hdl);
3871 		ddi_dma_free_handle(&p->m_dma_hdl);
3872 		p->m_dma_hdl = NULL;
3873 		mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources for"
3874 		    " extra SGL");
3875 		return (DDI_FAILURE);
3876 	}
3877 
3878 	/*
3879 	 * Store the SGL memory address.  This chip uses this
3880 	 * address to dma to and from the driver.  The second
3881 	 * address is the address mpt uses to fill in the SGL.
3882 	 */
3883 	p->m_phys_addr = cookie.dmac_address;
3884 
3885 	return (DDI_SUCCESS);
3886 }
3887 
3888 static void
3889 mptsas_cache_frames_destructor(void *buf, void *cdrarg)
3890 {
3891 #ifndef __lock_lint
3892 	_NOTE(ARGUNUSED(cdrarg))
3893 #endif
3894 	mptsas_cache_frames_t	*p = buf;
3895 	if (p->m_dma_hdl != NULL) {
3896 		(void) ddi_dma_unbind_handle(p->m_dma_hdl);
3897 		(void) ddi_dma_mem_free(&p->m_acc_hdl);
3898 		ddi_dma_free_handle(&p->m_dma_hdl);
3899 		p->m_phys_addr = NULL;
3900 		p->m_frames_addr = NULL;
3901 		p->m_dma_hdl = NULL;
3902 		p->m_acc_hdl = NULL;
3903 	}
3904 
3905 }
3906 
3907 /*
3908  * allocate and deallocate external pkt space (ie. not part of mptsas_cmd)
3909  * for non-standard length cdb, pkt_private, status areas
3910  * if allocation fails, then deallocate all external space and the pkt
3911  */
3912 /* ARGSUSED */
3913 static int
3914 mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd,
3915     int cmdlen, int tgtlen, int statuslen, int kf)
3916 {
3917 	caddr_t			cdbp, scbp, tgt;
3918 	int			(*callback)(caddr_t) = (kf == KM_SLEEP) ?
3919 	    DDI_DMA_SLEEP : DDI_DMA_DONTWAIT;
3920 	struct scsi_address	ap;
3921 	size_t			senselength;
3922 	ddi_dma_attr_t		ext_arq_dma_attr;
3923 	uint_t			cookiec;
3924 
3925 	NDBG3(("mptsas_pkt_alloc_extern: "
3926 	    "cmd=0x%p cmdlen=%d tgtlen=%d statuslen=%d kf=%x",
3927 	    (void *)cmd, cmdlen, tgtlen, statuslen, kf));
3928 
3929 	tgt = cdbp = scbp = NULL;
3930 	cmd->cmd_scblen		= statuslen;
3931 	cmd->cmd_privlen	= (uchar_t)tgtlen;
3932 
3933 	if (cmdlen > sizeof (cmd->cmd_cdb)) {
3934 		if ((cdbp = kmem_zalloc((size_t)cmdlen, kf)) == NULL) {
3935 			goto fail;
3936 		}
3937 		cmd->cmd_pkt->pkt_cdbp = (opaque_t)cdbp;
3938 		cmd->cmd_flags |= CFLAG_CDBEXTERN;
3939 	}
3940 	if (tgtlen > PKT_PRIV_LEN) {
3941 		if ((tgt = kmem_zalloc((size_t)tgtlen, kf)) == NULL) {
3942 			goto fail;
3943 		}
3944 		cmd->cmd_flags |= CFLAG_PRIVEXTERN;
3945 		cmd->cmd_pkt->pkt_private = tgt;
3946 	}
3947 	if (statuslen > EXTCMDS_STATUS_SIZE) {
3948 		if ((scbp = kmem_zalloc((size_t)statuslen, kf)) == NULL) {
3949 			goto fail;
3950 		}
3951 		cmd->cmd_flags |= CFLAG_SCBEXTERN;
3952 		cmd->cmd_pkt->pkt_scbp = (opaque_t)scbp;
3953 
3954 		/* allocate sense data buf for DMA */
3955 
3956 		senselength = statuslen - MPTSAS_GET_ITEM_OFF(
3957 		    struct scsi_arq_status, sts_sensedata);
3958 		cmd->cmd_rqslen = (uchar_t)senselength;
3959 
3960 		ap.a_hba_tran = mpt->m_tran;
3961 		ap.a_target = 0;
3962 		ap.a_lun = 0;
3963 
3964 		cmd->cmd_ext_arq_buf = scsi_alloc_consistent_buf(&ap,
3965 		    (struct buf *)NULL, senselength, B_READ,
3966 		    callback, NULL);
3967 
3968 		if (cmd->cmd_ext_arq_buf == NULL) {
3969 			goto fail;
3970 		}
3971 		/*
3972 		 * allocate a extern arq handle and bind the buf
3973 		 */
3974 		ext_arq_dma_attr = mpt->m_msg_dma_attr;
3975 		ext_arq_dma_attr.dma_attr_sgllen = 1;
3976 		if ((ddi_dma_alloc_handle(mpt->m_dip,
3977 		    &ext_arq_dma_attr, callback,
3978 		    NULL, &cmd->cmd_ext_arqhandle)) != DDI_SUCCESS) {
3979 			goto fail;
3980 		}
3981 
3982 		if (ddi_dma_buf_bind_handle(cmd->cmd_ext_arqhandle,
3983 		    cmd->cmd_ext_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT),
3984 		    callback, NULL, &cmd->cmd_ext_arqcookie,
3985 		    &cookiec)
3986 		    != DDI_SUCCESS) {
3987 			goto fail;
3988 		}
3989 		cmd->cmd_flags |= CFLAG_EXTARQBUFVALID;
3990 	}
3991 	return (0);
3992 fail:
3993 	mptsas_pkt_destroy_extern(mpt, cmd);
3994 	return (1);
3995 }
3996 
3997 /*
3998  * deallocate external pkt space and deallocate the pkt
3999  */
4000 static void
4001 mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd)
4002 {
4003 	NDBG3(("mptsas_pkt_destroy_extern: cmd=0x%p", (void *)cmd));
4004 
4005 	if (cmd->cmd_flags & CFLAG_FREE) {
4006 		mptsas_log(mpt, CE_PANIC,
4007 		    "mptsas_pkt_destroy_extern: freeing free packet");
4008 		_NOTE(NOT_REACHED)
4009 		/* NOTREACHED */
4010 	}
4011 	if (cmd->cmd_flags & CFLAG_CDBEXTERN) {
4012 		kmem_free(cmd->cmd_pkt->pkt_cdbp, (size_t)cmd->cmd_cdblen);
4013 	}
4014 	if (cmd->cmd_flags & CFLAG_SCBEXTERN) {
4015 		kmem_free(cmd->cmd_pkt->pkt_scbp, (size_t)cmd->cmd_scblen);
4016 		if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) {
4017 			(void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle);
4018 		}
4019 		if (cmd->cmd_ext_arqhandle) {
4020 			ddi_dma_free_handle(&cmd->cmd_ext_arqhandle);
4021 			cmd->cmd_ext_arqhandle = NULL;
4022 		}
4023 		if (cmd->cmd_ext_arq_buf)
4024 			scsi_free_consistent_buf(cmd->cmd_ext_arq_buf);
4025 	}
4026 	if (cmd->cmd_flags & CFLAG_PRIVEXTERN) {
4027 		kmem_free(cmd->cmd_pkt->pkt_private, (size_t)cmd->cmd_privlen);
4028 	}
4029 	cmd->cmd_flags = CFLAG_FREE;
4030 	kmem_cache_free(mpt->m_kmem_cache, (void *)cmd);
4031 }
4032 
4033 /*
4034  * tran_sync_pkt(9E) - explicit DMA synchronization
4035  */
4036 /*ARGSUSED*/
4037 static void
4038 mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
4039 {
4040 	mptsas_cmd_t	*cmd = PKT2CMD(pkt);
4041 
4042 	NDBG3(("mptsas_scsi_sync_pkt: target=%d, pkt=0x%p",
4043 	    ap->a_target, (void *)pkt));
4044 
4045 	if (cmd->cmd_dmahandle) {
4046 		(void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
4047 		    (cmd->cmd_flags & CFLAG_DMASEND) ?
4048 		    DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU);
4049 	}
4050 }
4051 
4052 /*
4053  * tran_dmafree(9E) - deallocate DMA resources allocated for command
4054  */
4055 /*ARGSUSED*/
4056 static void
4057 mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
4058 {
4059 	mptsas_cmd_t	*cmd = PKT2CMD(pkt);
4060 	mptsas_t	*mpt = ADDR2MPT(ap);
4061 
4062 	NDBG3(("mptsas_scsi_dmafree: target=%d pkt=0x%p",
4063 	    ap->a_target, (void *)pkt));
4064 
4065 	if (cmd->cmd_flags & CFLAG_DMAVALID) {
4066 		(void) ddi_dma_unbind_handle(cmd->cmd_dmahandle);
4067 		cmd->cmd_flags &= ~CFLAG_DMAVALID;
4068 	}
4069 
4070 	if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) {
4071 		(void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle);
4072 		cmd->cmd_flags &= ~CFLAG_EXTARQBUFVALID;
4073 	}
4074 
4075 	mptsas_free_extra_sgl_frame(mpt, cmd);
4076 }
4077 
4078 static void
4079 mptsas_pkt_comp(struct scsi_pkt *pkt, mptsas_cmd_t *cmd)
4080 {
4081 	if ((cmd->cmd_flags & CFLAG_CMDIOPB) &&
4082 	    (!(cmd->cmd_flags & CFLAG_DMASEND))) {
4083 		(void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
4084 		    DDI_DMA_SYNC_FORCPU);
4085 	}
4086 	(*pkt->pkt_comp)(pkt);
4087 }
4088 
4089 static void
4090 mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, uint32_t *control,
4091 	pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl)
4092 {
4093 	uint_t			cookiec;
4094 	mptti_t			*dmap;
4095 	uint32_t		flags;
4096 	pMpi2SGESimple64_t	sge;
4097 	pMpi2SGEChain64_t	sgechain;
4098 	ASSERT(cmd->cmd_flags & CFLAG_DMAVALID);
4099 
4100 	/*
4101 	 * Save the number of entries in the DMA
4102 	 * Scatter/Gather list
4103 	 */
4104 	cookiec = cmd->cmd_cookiec;
4105 
4106 	NDBG1(("mptsas_sge_setup: cookiec=%d", cookiec));
4107 
4108 	/*
4109 	 * Set read/write bit in control.
4110 	 */
4111 	if (cmd->cmd_flags & CFLAG_DMASEND) {
4112 		*control |= MPI2_SCSIIO_CONTROL_WRITE;
4113 	} else {
4114 		*control |= MPI2_SCSIIO_CONTROL_READ;
4115 	}
4116 
4117 	ddi_put32(acc_hdl, &frame->DataLength, cmd->cmd_dmacount);
4118 
4119 	/*
4120 	 * We have 2 cases here.  First where we can fit all the
4121 	 * SG elements into the main frame, and the case
4122 	 * where we can't.
4123 	 * If we have more cookies than we can attach to a frame
4124 	 * we will need to use a chain element to point
4125 	 * a location of memory where the rest of the S/G
4126 	 * elements reside.
4127 	 */
4128 	if (cookiec <= MPTSAS_MAX_FRAME_SGES64(mpt)) {
4129 		dmap = cmd->cmd_sg;
4130 		sge = (pMpi2SGESimple64_t)(&frame->SGL);
4131 		while (cookiec--) {
4132 			ddi_put32(acc_hdl,
4133 			    &sge->Address.Low, dmap->addr.address64.Low);
4134 			ddi_put32(acc_hdl,
4135 			    &sge->Address.High, dmap->addr.address64.High);
4136 			ddi_put32(acc_hdl, &sge->FlagsLength,
4137 			    dmap->count);
4138 			flags = ddi_get32(acc_hdl, &sge->FlagsLength);
4139 			flags |= ((uint32_t)
4140 			    (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4141 			    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4142 			    MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4143 			    MPI2_SGE_FLAGS_SHIFT);
4144 
4145 			/*
4146 			 * If this is the last cookie, we set the flags
4147 			 * to indicate so
4148 			 */
4149 			if (cookiec == 0) {
4150 				flags |=
4151 				    ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT
4152 				    | MPI2_SGE_FLAGS_END_OF_BUFFER
4153 				    | MPI2_SGE_FLAGS_END_OF_LIST) <<
4154 				    MPI2_SGE_FLAGS_SHIFT);
4155 			}
4156 			if (cmd->cmd_flags & CFLAG_DMASEND) {
4157 				flags |= (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4158 				    MPI2_SGE_FLAGS_SHIFT);
4159 			} else {
4160 				flags |= (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4161 				    MPI2_SGE_FLAGS_SHIFT);
4162 			}
4163 			ddi_put32(acc_hdl, &sge->FlagsLength, flags);
4164 			dmap++;
4165 			sge++;
4166 		}
4167 	} else {
4168 		/*
4169 		 * Hereby we start to deal with multiple frames.
4170 		 * The process is as follows:
4171 		 * 1. Determine how many frames are needed for SGL element
4172 		 *    storage; Note that all frames are stored in contiguous
4173 		 *    memory space and in 64-bit DMA mode each element is
4174 		 *    3 double-words (12 bytes) long.
4175 		 * 2. Fill up the main frame. We need to do this separately
4176 		 *    since it contains the SCSI IO request header and needs
4177 		 *    dedicated processing. Note that the last 4 double-words
4178 		 *    of the SCSI IO header is for SGL element storage
4179 		 *    (MPI2_SGE_IO_UNION).
4180 		 * 3. Fill the chain element in the main frame, so the DMA
4181 		 *    engine can use the following frames.
4182 		 * 4. Enter a loop to fill the remaining frames. Note that the
4183 		 *    last frame contains no chain element.  The remaining
4184 		 *    frames go into the mpt SGL buffer allocated on the fly,
4185 		 *    not immediately following the main message frame, as in
4186 		 *    Gen1.
4187 		 * Some restrictions:
4188 		 * 1. For 64-bit DMA, the simple element and chain element
4189 		 *    are both of 3 double-words (12 bytes) in size, even
4190 		 *    though all frames are stored in the first 4G of mem
4191 		 *    range and the higher 32-bits of the address are always 0.
4192 		 * 2. On some controllers (like the 1064/1068), a frame can
4193 		 *    hold SGL elements with the last 1 or 2 double-words
4194 		 *    (4 or 8 bytes) un-used. On these controllers, we should
4195 		 *    recognize that there's not enough room for another SGL
4196 		 *    element and move the sge pointer to the next frame.
4197 		 */
4198 		int		i, j, k, l, frames, sgemax;
4199 		int		temp;
4200 		uint8_t		chainflags;
4201 		uint16_t	chainlength;
4202 		mptsas_cache_frames_t *p;
4203 
4204 		/*
4205 		 * Sgemax is the number of SGE's that will fit
4206 		 * each extra frame and frames is total
4207 		 * number of frames we'll need.  1 sge entry per
4208 		 * frame is reseverd for the chain element thus the -1 below.
4209 		 */
4210 		sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_SGE_SIMPLE64))
4211 		    - 1);
4212 		temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax;
4213 
4214 		/*
4215 		 * A little check to see if we need to round up the number
4216 		 * of frames we need
4217 		 */
4218 		if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp *
4219 		    sgemax) > 1) {
4220 			frames = (temp + 1);
4221 		} else {
4222 			frames = temp;
4223 		}
4224 		dmap = cmd->cmd_sg;
4225 		sge = (pMpi2SGESimple64_t)(&frame->SGL);
4226 
4227 		/*
4228 		 * First fill in the main frame
4229 		 */
4230 		for (j = 1; j < MPTSAS_MAX_FRAME_SGES64(mpt); j++) {
4231 			ddi_put32(acc_hdl, &sge->Address.Low,
4232 			    dmap->addr.address64.Low);
4233 			ddi_put32(acc_hdl, &sge->Address.High,
4234 			    dmap->addr.address64.High);
4235 			ddi_put32(acc_hdl, &sge->FlagsLength, dmap->count);
4236 			flags = ddi_get32(acc_hdl, &sge->FlagsLength);
4237 			flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4238 			    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4239 			    MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4240 			    MPI2_SGE_FLAGS_SHIFT);
4241 
4242 			/*
4243 			 * If this is the last SGE of this frame
4244 			 * we set the end of list flag
4245 			 */
4246 			if (j == (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) {
4247 				flags |= ((uint32_t)
4248 				    (MPI2_SGE_FLAGS_LAST_ELEMENT) <<
4249 				    MPI2_SGE_FLAGS_SHIFT);
4250 			}
4251 			if (cmd->cmd_flags & CFLAG_DMASEND) {
4252 				flags |=
4253 				    (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4254 				    MPI2_SGE_FLAGS_SHIFT);
4255 			} else {
4256 				flags |=
4257 				    (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4258 				    MPI2_SGE_FLAGS_SHIFT);
4259 			}
4260 			ddi_put32(acc_hdl, &sge->FlagsLength, flags);
4261 			dmap++;
4262 			sge++;
4263 		}
4264 
4265 		/*
4266 		 * Fill in the chain element in the main frame.
4267 		 * About calculation on ChainOffset:
4268 		 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes)
4269 		 *    in the end reserved for SGL element storage
4270 		 *    (MPI2_SGE_IO_UNION); we should count it in our
4271 		 *    calculation.  See its definition in the header file.
4272 		 * 2. Constant j is the counter of the current SGL element
4273 		 *    that will be processed, and (j - 1) is the number of
4274 		 *    SGL elements that have been processed (stored in the
4275 		 *    main frame).
4276 		 * 3. ChainOffset value should be in units of double-words (4
4277 		 *    bytes) so the last value should be divided by 4.
4278 		 */
4279 		ddi_put8(acc_hdl, &frame->ChainOffset,
4280 		    (sizeof (MPI2_SCSI_IO_REQUEST) -
4281 		    sizeof (MPI2_SGE_IO_UNION) +
4282 		    (j - 1) * sizeof (MPI2_SGE_SIMPLE64)) >> 2);
4283 		sgechain = (pMpi2SGEChain64_t)sge;
4284 		chainflags = (MPI2_SGE_FLAGS_CHAIN_ELEMENT |
4285 		    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4286 		    MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
4287 		ddi_put8(acc_hdl, &sgechain->Flags, chainflags);
4288 
4289 		/*
4290 		 * The size of the next frame is the accurate size of space
4291 		 * (in bytes) used to store the SGL elements. j is the counter
4292 		 * of SGL elements. (j - 1) is the number of SGL elements that
4293 		 * have been processed (stored in frames).
4294 		 */
4295 		if (frames >= 2) {
4296 			chainlength = mpt->m_req_frame_size /
4297 			    sizeof (MPI2_SGE_SIMPLE64) *
4298 			    sizeof (MPI2_SGE_SIMPLE64);
4299 		} else {
4300 			chainlength = ((cookiec - (j - 1)) *
4301 			    sizeof (MPI2_SGE_SIMPLE64));
4302 		}
4303 
4304 		p = cmd->cmd_extra_frames;
4305 
4306 		ddi_put16(acc_hdl, &sgechain->Length, chainlength);
4307 		ddi_put32(acc_hdl, &sgechain->Address.Low,
4308 		    p->m_phys_addr);
4309 		/* SGL is allocated in the first 4G mem range */
4310 		ddi_put32(acc_hdl, &sgechain->Address.High, 0);
4311 
4312 		/*
4313 		 * If there are more than 2 frames left we have to
4314 		 * fill in the next chain offset to the location of
4315 		 * the chain element in the next frame.
4316 		 * sgemax is the number of simple elements in an extra
4317 		 * frame. Note that the value NextChainOffset should be
4318 		 * in double-words (4 bytes).
4319 		 */
4320 		if (frames >= 2) {
4321 			ddi_put8(acc_hdl, &sgechain->NextChainOffset,
4322 			    (sgemax * sizeof (MPI2_SGE_SIMPLE64)) >> 2);
4323 		} else {
4324 			ddi_put8(acc_hdl, &sgechain->NextChainOffset, 0);
4325 		}
4326 
4327 		/*
4328 		 * Jump to next frame;
4329 		 * Starting here, chain buffers go into the per command SGL.
4330 		 * This buffer is allocated when chain buffers are needed.
4331 		 */
4332 		sge = (pMpi2SGESimple64_t)p->m_frames_addr;
4333 		i = cookiec;
4334 
4335 		/*
4336 		 * Start filling in frames with SGE's.  If we
4337 		 * reach the end of frame and still have SGE's
4338 		 * to fill we need to add a chain element and
4339 		 * use another frame.  j will be our counter
4340 		 * for what cookie we are at and i will be
4341 		 * the total cookiec. k is the current frame
4342 		 */
4343 		for (k = 1; k <= frames; k++) {
4344 			for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) {
4345 
4346 				/*
4347 				 * If we have reached the end of frame
4348 				 * and we have more SGE's to fill in
4349 				 * we have to fill the final entry
4350 				 * with a chain element and then
4351 				 * continue to the next frame
4352 				 */
4353 				if ((l == (sgemax + 1)) && (k != frames)) {
4354 					sgechain = (pMpi2SGEChain64_t)sge;
4355 					j--;
4356 					chainflags = (
4357 					    MPI2_SGE_FLAGS_CHAIN_ELEMENT |
4358 					    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4359 					    MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
4360 					ddi_put8(p->m_acc_hdl,
4361 					    &sgechain->Flags, chainflags);
4362 					/*
4363 					 * k is the frame counter and (k + 1)
4364 					 * is the number of the next frame.
4365 					 * Note that frames are in contiguous
4366 					 * memory space.
4367 					 */
4368 					ddi_put32(p->m_acc_hdl,
4369 					    &sgechain->Address.Low,
4370 					    (p->m_phys_addr +
4371 					    (mpt->m_req_frame_size * k)));
4372 					ddi_put32(p->m_acc_hdl,
4373 					    &sgechain->Address.High, 0);
4374 
4375 					/*
4376 					 * If there are more than 2 frames left
4377 					 * we have to next chain offset to
4378 					 * the location of the chain element
4379 					 * in the next frame and fill in the
4380 					 * length of the next chain
4381 					 */
4382 					if ((frames - k) >= 2) {
4383 						ddi_put8(p->m_acc_hdl,
4384 						    &sgechain->NextChainOffset,
4385 						    (sgemax *
4386 						    sizeof (MPI2_SGE_SIMPLE64))
4387 						    >> 2);
4388 						ddi_put16(p->m_acc_hdl,
4389 						    &sgechain->Length,
4390 						    mpt->m_req_frame_size /
4391 						    sizeof (MPI2_SGE_SIMPLE64) *
4392 						    sizeof (MPI2_SGE_SIMPLE64));
4393 					} else {
4394 						/*
4395 						 * This is the last frame. Set
4396 						 * the NextChainOffset to 0 and
4397 						 * Length is the total size of
4398 						 * all remaining simple elements
4399 						 */
4400 						ddi_put8(p->m_acc_hdl,
4401 						    &sgechain->NextChainOffset,
4402 						    0);
4403 						ddi_put16(p->m_acc_hdl,
4404 						    &sgechain->Length,
4405 						    (cookiec - j) *
4406 						    sizeof (MPI2_SGE_SIMPLE64));
4407 					}
4408 
4409 					/* Jump to the next frame */
4410 					sge = (pMpi2SGESimple64_t)
4411 					    ((char *)p->m_frames_addr +
4412 					    (int)mpt->m_req_frame_size * k);
4413 
4414 					continue;
4415 				}
4416 
4417 				ddi_put32(p->m_acc_hdl,
4418 				    &sge->Address.Low,
4419 				    dmap->addr.address64.Low);
4420 				ddi_put32(p->m_acc_hdl,
4421 				    &sge->Address.High,
4422 				    dmap->addr.address64.High);
4423 				ddi_put32(p->m_acc_hdl,
4424 				    &sge->FlagsLength, dmap->count);
4425 				flags = ddi_get32(p->m_acc_hdl,
4426 				    &sge->FlagsLength);
4427 				flags |= ((uint32_t)(
4428 				    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4429 				    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4430 				    MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4431 				    MPI2_SGE_FLAGS_SHIFT);
4432 
4433 				/*
4434 				 * If we are at the end of the frame and
4435 				 * there is another frame to fill in
4436 				 * we set the last simple element as last
4437 				 * element
4438 				 */
4439 				if ((l == sgemax) && (k != frames)) {
4440 					flags |= ((uint32_t)
4441 					    (MPI2_SGE_FLAGS_LAST_ELEMENT) <<
4442 					    MPI2_SGE_FLAGS_SHIFT);
4443 				}
4444 
4445 				/*
4446 				 * If this is the final cookie we
4447 				 * indicate it by setting the flags
4448 				 */
4449 				if (j == i) {
4450 					flags |= ((uint32_t)
4451 					    (MPI2_SGE_FLAGS_LAST_ELEMENT |
4452 					    MPI2_SGE_FLAGS_END_OF_BUFFER |
4453 					    MPI2_SGE_FLAGS_END_OF_LIST) <<
4454 					    MPI2_SGE_FLAGS_SHIFT);
4455 				}
4456 				if (cmd->cmd_flags & CFLAG_DMASEND) {
4457 					flags |=
4458 					    (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4459 					    MPI2_SGE_FLAGS_SHIFT);
4460 				} else {
4461 					flags |=
4462 					    (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4463 					    MPI2_SGE_FLAGS_SHIFT);
4464 				}
4465 				ddi_put32(p->m_acc_hdl,
4466 				    &sge->FlagsLength, flags);
4467 				dmap++;
4468 				sge++;
4469 			}
4470 		}
4471 
4472 		/*
4473 		 * Sync DMA with the chain buffers that were just created
4474 		 */
4475 		(void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
4476 	}
4477 }
4478 
4479 /*
4480  * Interrupt handling
4481  * Utility routine.  Poll for status of a command sent to HBA
4482  * without interrupts (a FLAG_NOINTR command).
4483  */
4484 int
4485 mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime)
4486 {
4487 	int	rval = TRUE;
4488 
4489 	NDBG5(("mptsas_poll: cmd=0x%p", (void *)poll_cmd));
4490 
4491 	if ((poll_cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
4492 		mptsas_restart_hba(mpt);
4493 	}
4494 
4495 	/*
4496 	 * Wait, using drv_usecwait(), long enough for the command to
4497 	 * reasonably return from the target if the target isn't
4498 	 * "dead".  A polled command may well be sent from scsi_poll, and
4499 	 * there are retries built in to scsi_poll if the transport
4500 	 * accepted the packet (TRAN_ACCEPT).  scsi_poll waits 1 second
4501 	 * and retries the transport up to scsi_poll_busycnt times
4502 	 * (currently 60) if
4503 	 * 1. pkt_reason is CMD_INCOMPLETE and pkt_state is 0, or
4504 	 * 2. pkt_reason is CMD_CMPLT and *pkt_scbp has STATUS_BUSY
4505 	 *
4506 	 * limit the waiting to avoid a hang in the event that the
4507 	 * cmd never gets started but we are still receiving interrupts
4508 	 */
4509 	while (!(poll_cmd->cmd_flags & CFLAG_FINISHED)) {
4510 		if (mptsas_wait_intr(mpt, polltime) == FALSE) {
4511 			NDBG5(("mptsas_poll: command incomplete"));
4512 			rval = FALSE;
4513 			break;
4514 		}
4515 	}
4516 
4517 	if (rval == FALSE) {
4518 
4519 		/*
4520 		 * this isn't supposed to happen, the hba must be wedged
4521 		 * Mark this cmd as a timeout.
4522 		 */
4523 		mptsas_set_pkt_reason(mpt, poll_cmd, CMD_TIMEOUT,
4524 		    (STAT_TIMEOUT|STAT_ABORTED));
4525 
4526 		if (poll_cmd->cmd_queued == FALSE) {
4527 
4528 			NDBG5(("mptsas_poll: not on waitq"));
4529 
4530 			poll_cmd->cmd_pkt->pkt_state |=
4531 			    (STATE_GOT_BUS|STATE_GOT_TARGET|STATE_SENT_CMD);
4532 		} else {
4533 
4534 			/* find and remove it from the waitq */
4535 			NDBG5(("mptsas_poll: delete from waitq"));
4536 			mptsas_waitq_delete(mpt, poll_cmd);
4537 		}
4538 
4539 	}
4540 	mptsas_fma_check(mpt, poll_cmd);
4541 	NDBG5(("mptsas_poll: done"));
4542 	return (rval);
4543 }
4544 
4545 /*
4546  * Used for polling cmds and TM function
4547  */
4548 static int
4549 mptsas_wait_intr(mptsas_t *mpt, int polltime)
4550 {
4551 	int				cnt;
4552 	pMpi2ReplyDescriptorsUnion_t	reply_desc_union;
4553 	uint32_t			int_mask;
4554 
4555 	NDBG5(("mptsas_wait_intr"));
4556 
4557 	mpt->m_polled_intr = 1;
4558 
4559 	/*
4560 	 * Get the current interrupt mask and disable interrupts.  When
4561 	 * re-enabling ints, set mask to saved value.
4562 	 */
4563 	int_mask = ddi_get32(mpt->m_datap, &mpt->m_reg->HostInterruptMask);
4564 	MPTSAS_DISABLE_INTR(mpt);
4565 
4566 	/*
4567 	 * Keep polling for at least (polltime * 1000) seconds
4568 	 */
4569 	for (cnt = 0; cnt < polltime; cnt++) {
4570 		(void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
4571 		    DDI_DMA_SYNC_FORCPU);
4572 
4573 		reply_desc_union = (pMpi2ReplyDescriptorsUnion_t)
4574 		    MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index);
4575 
4576 		if (ddi_get32(mpt->m_acc_post_queue_hdl,
4577 		    &reply_desc_union->Words.Low) == 0xFFFFFFFF ||
4578 		    ddi_get32(mpt->m_acc_post_queue_hdl,
4579 		    &reply_desc_union->Words.High) == 0xFFFFFFFF) {
4580 			drv_usecwait(1000);
4581 			continue;
4582 		}
4583 
4584 		/*
4585 		 * The reply is valid, process it according to its
4586 		 * type.
4587 		 */
4588 		mptsas_process_intr(mpt, reply_desc_union);
4589 
4590 		if (++mpt->m_post_index == mpt->m_post_queue_depth) {
4591 			mpt->m_post_index = 0;
4592 		}
4593 
4594 		/*
4595 		 * Update the global reply index
4596 		 */
4597 		ddi_put32(mpt->m_datap,
4598 		    &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index);
4599 		mpt->m_polled_intr = 0;
4600 
4601 		/*
4602 		 * Re-enable interrupts and quit.
4603 		 */
4604 		ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask,
4605 		    int_mask);
4606 		return (TRUE);
4607 
4608 	}
4609 
4610 	/*
4611 	 * Clear polling flag, re-enable interrupts and quit.
4612 	 */
4613 	mpt->m_polled_intr = 0;
4614 	ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, int_mask);
4615 	return (FALSE);
4616 }
4617 
4618 static void
4619 mptsas_handle_scsi_io_success(mptsas_t *mpt,
4620     pMpi2ReplyDescriptorsUnion_t reply_desc)
4621 {
4622 	pMpi2SCSIIOSuccessReplyDescriptor_t	scsi_io_success;
4623 	uint16_t				SMID;
4624 	mptsas_slots_t				*slots = mpt->m_active;
4625 	mptsas_cmd_t				*cmd = NULL;
4626 	struct scsi_pkt				*pkt;
4627 
4628 	ASSERT(mutex_owned(&mpt->m_mutex));
4629 
4630 	scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc;
4631 	SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &scsi_io_success->SMID);
4632 
4633 	/*
4634 	 * This is a success reply so just complete the IO.  First, do a sanity
4635 	 * check on the SMID.  The final slot is used for TM requests, which
4636 	 * would not come into this reply handler.
4637 	 */
4638 	if ((SMID == 0) || (SMID > slots->m_n_slots)) {
4639 		mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n",
4640 		    SMID);
4641 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
4642 		return;
4643 	}
4644 
4645 	cmd = slots->m_slot[SMID];
4646 
4647 	/*
4648 	 * print warning and return if the slot is empty
4649 	 */
4650 	if (cmd == NULL) {
4651 		mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO "
4652 		    "in slot %d", SMID);
4653 		return;
4654 	}
4655 
4656 	pkt = CMD2PKT(cmd);
4657 	pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
4658 	    STATE_GOT_STATUS);
4659 	if (cmd->cmd_flags & CFLAG_DMAVALID) {
4660 		pkt->pkt_state |= STATE_XFERRED_DATA;
4661 	}
4662 	pkt->pkt_resid = 0;
4663 
4664 	if (cmd->cmd_flags & CFLAG_PASSTHRU) {
4665 		cmd->cmd_flags |= CFLAG_FINISHED;
4666 		cv_broadcast(&mpt->m_passthru_cv);
4667 		return;
4668 	} else {
4669 		mptsas_remove_cmd(mpt, cmd);
4670 	}
4671 
4672 	if (cmd->cmd_flags & CFLAG_RETRY) {
4673 		/*
4674 		 * The target returned QFULL or busy, do not add tihs
4675 		 * pkt to the doneq since the hba will retry
4676 		 * this cmd.
4677 		 *
4678 		 * The pkt has already been resubmitted in
4679 		 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error().
4680 		 * Remove this cmd_flag here.
4681 		 */
4682 		cmd->cmd_flags &= ~CFLAG_RETRY;
4683 	} else {
4684 		mptsas_doneq_add(mpt, cmd);
4685 	}
4686 }
4687 
4688 static void
4689 mptsas_handle_address_reply(mptsas_t *mpt,
4690     pMpi2ReplyDescriptorsUnion_t reply_desc)
4691 {
4692 	pMpi2AddressReplyDescriptor_t	address_reply;
4693 	pMPI2DefaultReply_t		reply;
4694 	mptsas_fw_diagnostic_buffer_t	*pBuffer;
4695 	uint32_t			reply_addr;
4696 	uint16_t			SMID, iocstatus, action;
4697 	mptsas_slots_t			*slots = mpt->m_active;
4698 	mptsas_cmd_t			*cmd = NULL;
4699 	uint8_t				function, buffer_type;
4700 	m_replyh_arg_t			*args;
4701 	int				reply_frame_no;
4702 
4703 	ASSERT(mutex_owned(&mpt->m_mutex));
4704 
4705 	address_reply = (pMpi2AddressReplyDescriptor_t)reply_desc;
4706 	reply_addr = ddi_get32(mpt->m_acc_post_queue_hdl,
4707 	    &address_reply->ReplyFrameAddress);
4708 	SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &address_reply->SMID);
4709 
4710 	/*
4711 	 * If reply frame is not in the proper range we should ignore this
4712 	 * message and exit the interrupt handler.
4713 	 */
4714 	if ((reply_addr < mpt->m_reply_frame_dma_addr) ||
4715 	    (reply_addr >= (mpt->m_reply_frame_dma_addr +
4716 	    (mpt->m_reply_frame_size * mpt->m_free_queue_depth))) ||
4717 	    ((reply_addr - mpt->m_reply_frame_dma_addr) %
4718 	    mpt->m_reply_frame_size != 0)) {
4719 		mptsas_log(mpt, CE_WARN, "?Received invalid reply frame "
4720 		    "address 0x%x\n", reply_addr);
4721 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
4722 		return;
4723 	}
4724 
4725 	(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
4726 	    DDI_DMA_SYNC_FORCPU);
4727 	reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame + (reply_addr -
4728 	    mpt->m_reply_frame_dma_addr));
4729 	function = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Function);
4730 
4731 	/*
4732 	 * don't get slot information and command for events since these values
4733 	 * don't exist
4734 	 */
4735 	if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) &&
4736 	    (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) {
4737 		/*
4738 		 * If this is a raid action reply for system shutdown just exit
4739 		 * because the reply doesn't matter.  Signal that we got the
4740 		 * reply even though it's not really necessary since we're
4741 		 * shutting down.
4742 		 */
4743 		if (function == MPI2_FUNCTION_RAID_ACTION) {
4744 			action = ddi_get16(mpt->m_acc_reply_frame_hdl,
4745 			    &reply->FunctionDependent1);
4746 			if (action ==
4747 			    MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED) {
4748 				cv_broadcast(&mpt->m_fw_diag_cv);
4749 				return;
4750 			}
4751 		}
4752 
4753 		/*
4754 		 * This could be a TM reply, which use the last allocated SMID,
4755 		 * so allow for that.
4756 		 */
4757 		if ((SMID == 0) || (SMID > (slots->m_n_slots + 1))) {
4758 			mptsas_log(mpt, CE_WARN, "?Received invalid SMID of "
4759 			    "%d\n", SMID);
4760 			ddi_fm_service_impact(mpt->m_dip,
4761 			    DDI_SERVICE_UNAFFECTED);
4762 			return;
4763 		}
4764 
4765 		cmd = slots->m_slot[SMID];
4766 
4767 		/*
4768 		 * print warning and return if the slot is empty
4769 		 */
4770 		if (cmd == NULL) {
4771 			mptsas_log(mpt, CE_WARN, "?NULL command for address "
4772 			    "reply in slot %d", SMID);
4773 			return;
4774 		}
4775 		if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
4776 		    (cmd->cmd_flags & CFLAG_CONFIG) ||
4777 		    (cmd->cmd_flags & CFLAG_FW_DIAG)) {
4778 			cmd->cmd_rfm = reply_addr;
4779 			cmd->cmd_flags |= CFLAG_FINISHED;
4780 			cv_broadcast(&mpt->m_passthru_cv);
4781 			cv_broadcast(&mpt->m_config_cv);
4782 			cv_broadcast(&mpt->m_fw_diag_cv);
4783 			return;
4784 		} else if (!(cmd->cmd_flags & CFLAG_FW_CMD)) {
4785 			mptsas_remove_cmd(mpt, cmd);
4786 		}
4787 		NDBG31(("\t\tmptsas_process_intr: slot=%d", SMID));
4788 	}
4789 	/*
4790 	 * Depending on the function, we need to handle
4791 	 * the reply frame (and cmd) differently.
4792 	 */
4793 	switch (function) {
4794 	case MPI2_FUNCTION_SCSI_IO_REQUEST:
4795 		mptsas_check_scsi_io_error(mpt, (pMpi2SCSIIOReply_t)reply, cmd);
4796 		break;
4797 	case MPI2_FUNCTION_SCSI_TASK_MGMT:
4798 		mptsas_check_task_mgt(mpt, (pMpi2SCSIManagementReply_t)reply,
4799 		    cmd);
4800 		break;
4801 	case MPI2_FUNCTION_FW_DOWNLOAD:
4802 		cmd->cmd_flags |= CFLAG_FINISHED;
4803 		cv_signal(&mpt->m_fw_cv);
4804 		break;
4805 	case MPI2_FUNCTION_EVENT_NOTIFICATION:
4806 		reply_frame_no = (reply_addr - mpt->m_reply_frame_dma_addr) /
4807 		    mpt->m_reply_frame_size;
4808 		args = &mpt->m_replyh_args[reply_frame_no];
4809 		args->mpt = (void *)mpt;
4810 		args->rfm = reply_addr;
4811 
4812 		/*
4813 		 * Record the event if its type is enabled in
4814 		 * this mpt instance by ioctl.
4815 		 */
4816 		mptsas_record_event(args);
4817 
4818 		/*
4819 		 * Handle time critical events
4820 		 * NOT_RESPONDING/ADDED only now
4821 		 */
4822 		if (mptsas_handle_event_sync(args) == DDI_SUCCESS) {
4823 			/*
4824 			 * Would not return main process,
4825 			 * just let taskq resolve ack action
4826 			 * and ack would be sent in taskq thread
4827 			 */
4828 			NDBG20(("send mptsas_handle_event_sync success"));
4829 		}
4830 		if ((ddi_taskq_dispatch(mpt->m_event_taskq, mptsas_handle_event,
4831 		    (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) {
4832 			mptsas_log(mpt, CE_WARN, "No memory available"
4833 			"for dispatch taskq");
4834 			/*
4835 			 * Return the reply frame to the free queue.
4836 			 */
4837 			ddi_put32(mpt->m_acc_free_queue_hdl,
4838 			    &((uint32_t *)(void *)
4839 			    mpt->m_free_queue)[mpt->m_free_index], reply_addr);
4840 			(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
4841 			    DDI_DMA_SYNC_FORDEV);
4842 			if (++mpt->m_free_index == mpt->m_free_queue_depth) {
4843 				mpt->m_free_index = 0;
4844 			}
4845 
4846 			ddi_put32(mpt->m_datap,
4847 			    &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index);
4848 		}
4849 		return;
4850 	case MPI2_FUNCTION_DIAG_BUFFER_POST:
4851 		/*
4852 		 * If SMID is 0, this implies that the reply is due to a
4853 		 * release function with a status that the buffer has been
4854 		 * released.  Set the buffer flags accordingly.
4855 		 */
4856 		if (SMID == 0) {
4857 			iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
4858 			    &reply->IOCStatus);
4859 			buffer_type = ddi_get8(mpt->m_acc_reply_frame_hdl,
4860 			    &(((pMpi2DiagBufferPostReply_t)reply)->BufferType));
4861 			if (iocstatus == MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED) {
4862 				pBuffer =
4863 				    &mpt->m_fw_diag_buffer_list[buffer_type];
4864 				pBuffer->valid_data = TRUE;
4865 				pBuffer->owned_by_firmware = FALSE;
4866 				pBuffer->immediate = FALSE;
4867 			}
4868 		} else {
4869 			/*
4870 			 * Normal handling of diag post reply with SMID.
4871 			 */
4872 			cmd = slots->m_slot[SMID];
4873 
4874 			/*
4875 			 * print warning and return if the slot is empty
4876 			 */
4877 			if (cmd == NULL) {
4878 				mptsas_log(mpt, CE_WARN, "?NULL command for "
4879 				    "address reply in slot %d", SMID);
4880 				return;
4881 			}
4882 			cmd->cmd_rfm = reply_addr;
4883 			cmd->cmd_flags |= CFLAG_FINISHED;
4884 			cv_broadcast(&mpt->m_fw_diag_cv);
4885 		}
4886 		return;
4887 	default:
4888 		mptsas_log(mpt, CE_WARN, "Unknown function 0x%x ", function);
4889 		break;
4890 	}
4891 
4892 	/*
4893 	 * Return the reply frame to the free queue.
4894 	 */
4895 	ddi_put32(mpt->m_acc_free_queue_hdl,
4896 	    &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
4897 	    reply_addr);
4898 	(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
4899 	    DDI_DMA_SYNC_FORDEV);
4900 	if (++mpt->m_free_index == mpt->m_free_queue_depth) {
4901 		mpt->m_free_index = 0;
4902 	}
4903 	ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
4904 	    mpt->m_free_index);
4905 
4906 	if (cmd->cmd_flags & CFLAG_FW_CMD)
4907 		return;
4908 
4909 	if (cmd->cmd_flags & CFLAG_RETRY) {
4910 		/*
4911 		 * The target returned QFULL or busy, do not add tihs
4912 		 * pkt to the doneq since the hba will retry
4913 		 * this cmd.
4914 		 *
4915 		 * The pkt has already been resubmitted in
4916 		 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error().
4917 		 * Remove this cmd_flag here.
4918 		 */
4919 		cmd->cmd_flags &= ~CFLAG_RETRY;
4920 	} else {
4921 		mptsas_doneq_add(mpt, cmd);
4922 	}
4923 }
4924 
4925 static void
4926 mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply,
4927     mptsas_cmd_t *cmd)
4928 {
4929 	uint8_t			scsi_status, scsi_state;
4930 	uint16_t		ioc_status;
4931 	uint32_t		xferred, sensecount, responsedata, loginfo = 0;
4932 	struct scsi_pkt		*pkt;
4933 	struct scsi_arq_status	*arqstat;
4934 	struct buf		*bp;
4935 	mptsas_target_t		*ptgt = cmd->cmd_tgt_addr;
4936 	uint8_t			*sensedata = NULL;
4937 
4938 	if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) ==
4939 	    (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) {
4940 		bp = cmd->cmd_ext_arq_buf;
4941 	} else {
4942 		bp = cmd->cmd_arq_buf;
4943 	}
4944 
4945 	scsi_status = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIStatus);
4946 	ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus);
4947 	scsi_state = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIState);
4948 	xferred = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->TransferCount);
4949 	sensecount = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->SenseCount);
4950 	responsedata = ddi_get32(mpt->m_acc_reply_frame_hdl,
4951 	    &reply->ResponseInfo);
4952 
4953 	if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
4954 		loginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
4955 		    &reply->IOCLogInfo);
4956 		mptsas_log(mpt, CE_NOTE,
4957 		    "?Log info 0x%x received for target %d.\n"
4958 		    "\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x",
4959 		    loginfo, Tgt(cmd), scsi_status, ioc_status,
4960 		    scsi_state);
4961 	}
4962 
4963 	NDBG31(("\t\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x",
4964 	    scsi_status, ioc_status, scsi_state));
4965 
4966 	pkt = CMD2PKT(cmd);
4967 	*(pkt->pkt_scbp) = scsi_status;
4968 
4969 	if (loginfo == 0x31170000) {
4970 		/*
4971 		 * if loginfo PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY
4972 		 * 0x31170000 comes, that means the device missing delay
4973 		 * is in progressing, the command need retry later.
4974 		 */
4975 		*(pkt->pkt_scbp) = STATUS_BUSY;
4976 		return;
4977 	}
4978 
4979 	if ((scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS) &&
4980 	    ((ioc_status & MPI2_IOCSTATUS_MASK) ==
4981 	    MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE)) {
4982 		pkt->pkt_reason = CMD_INCOMPLETE;
4983 		pkt->pkt_state |= STATE_GOT_BUS;
4984 		if (ptgt->m_reset_delay == 0) {
4985 			mptsas_set_throttle(mpt, ptgt,
4986 			    DRAIN_THROTTLE);
4987 		}
4988 		return;
4989 	}
4990 
4991 	if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
4992 		responsedata &= 0x000000FF;
4993 		if (responsedata & MPTSAS_SCSI_RESPONSE_CODE_TLR_OFF) {
4994 			mptsas_log(mpt, CE_NOTE, "Do not support the TLR\n");
4995 			pkt->pkt_reason = CMD_TLR_OFF;
4996 			return;
4997 		}
4998 	}
4999 
5000 
5001 	switch (scsi_status) {
5002 	case MPI2_SCSI_STATUS_CHECK_CONDITION:
5003 		pkt->pkt_resid = (cmd->cmd_dmacount - xferred);
5004 		arqstat = (void*)(pkt->pkt_scbp);
5005 		arqstat->sts_rqpkt_status = *((struct scsi_status *)
5006 		    (pkt->pkt_scbp));
5007 		pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
5008 		    STATE_SENT_CMD | STATE_GOT_STATUS | STATE_ARQ_DONE);
5009 		if (cmd->cmd_flags & CFLAG_XARQ) {
5010 			pkt->pkt_state |= STATE_XARQ_DONE;
5011 		}
5012 		if (pkt->pkt_resid != cmd->cmd_dmacount) {
5013 			pkt->pkt_state |= STATE_XFERRED_DATA;
5014 		}
5015 		arqstat->sts_rqpkt_reason = pkt->pkt_reason;
5016 		arqstat->sts_rqpkt_state  = pkt->pkt_state;
5017 		arqstat->sts_rqpkt_state |= STATE_XFERRED_DATA;
5018 		arqstat->sts_rqpkt_statistics = pkt->pkt_statistics;
5019 		sensedata = (uint8_t *)&arqstat->sts_sensedata;
5020 
5021 		bcopy((uchar_t *)bp->b_un.b_addr, sensedata,
5022 		    ((cmd->cmd_rqslen >= sensecount) ? sensecount :
5023 		    cmd->cmd_rqslen));
5024 		arqstat->sts_rqpkt_resid = (cmd->cmd_rqslen - sensecount);
5025 		cmd->cmd_flags |= CFLAG_CMDARQ;
5026 		/*
5027 		 * Set proper status for pkt if autosense was valid
5028 		 */
5029 		if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
5030 			struct scsi_status zero_status = { 0 };
5031 			arqstat->sts_rqpkt_status = zero_status;
5032 		}
5033 
5034 		/*
5035 		 * ASC=0x47 is parity error
5036 		 * ASC=0x48 is initiator detected error received
5037 		 */
5038 		if ((scsi_sense_key(sensedata) == KEY_ABORTED_COMMAND) &&
5039 		    ((scsi_sense_asc(sensedata) == 0x47) ||
5040 		    (scsi_sense_asc(sensedata) == 0x48))) {
5041 			mptsas_log(mpt, CE_NOTE, "Aborted_command!");
5042 		}
5043 
5044 		/*
5045 		 * ASC/ASCQ=0x3F/0x0E means report_luns data changed
5046 		 * ASC/ASCQ=0x25/0x00 means invalid lun
5047 		 */
5048 		if (((scsi_sense_key(sensedata) == KEY_UNIT_ATTENTION) &&
5049 		    (scsi_sense_asc(sensedata) == 0x3F) &&
5050 		    (scsi_sense_ascq(sensedata) == 0x0E)) ||
5051 		    ((scsi_sense_key(sensedata) == KEY_ILLEGAL_REQUEST) &&
5052 		    (scsi_sense_asc(sensedata) == 0x25) &&
5053 		    (scsi_sense_ascq(sensedata) == 0x00))) {
5054 			mptsas_topo_change_list_t *topo_node = NULL;
5055 
5056 			topo_node = kmem_zalloc(
5057 			    sizeof (mptsas_topo_change_list_t),
5058 			    KM_NOSLEEP);
5059 			if (topo_node == NULL) {
5060 				mptsas_log(mpt, CE_NOTE, "No memory"
5061 				    "resource for handle SAS dynamic"
5062 				    "reconfigure.\n");
5063 				break;
5064 			}
5065 			topo_node->mpt = mpt;
5066 			topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET;
5067 			topo_node->un.phymask = ptgt->m_phymask;
5068 			topo_node->devhdl = ptgt->m_devhdl;
5069 			topo_node->object = (void *)ptgt;
5070 			topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED;
5071 
5072 			if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
5073 			    mptsas_handle_dr,
5074 			    (void *)topo_node,
5075 			    DDI_NOSLEEP)) != DDI_SUCCESS) {
5076 				mptsas_log(mpt, CE_NOTE, "mptsas start taskq"
5077 				    "for handle SAS dynamic reconfigure"
5078 				    "failed. \n");
5079 			}
5080 		}
5081 		break;
5082 	case MPI2_SCSI_STATUS_GOOD:
5083 		switch (ioc_status & MPI2_IOCSTATUS_MASK) {
5084 		case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
5085 			pkt->pkt_reason = CMD_DEV_GONE;
5086 			pkt->pkt_state |= STATE_GOT_BUS;
5087 			if (ptgt->m_reset_delay == 0) {
5088 				mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5089 			}
5090 			NDBG31(("lost disk for target%d, command:%x",
5091 			    Tgt(cmd), pkt->pkt_cdbp[0]));
5092 			break;
5093 		case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
5094 			NDBG31(("data overrun: xferred=%d", xferred));
5095 			NDBG31(("dmacount=%d", cmd->cmd_dmacount));
5096 			pkt->pkt_reason = CMD_DATA_OVR;
5097 			pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET
5098 			    | STATE_SENT_CMD | STATE_GOT_STATUS
5099 			    | STATE_XFERRED_DATA);
5100 			pkt->pkt_resid = 0;
5101 			break;
5102 		case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
5103 		case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
5104 			NDBG31(("data underrun: xferred=%d", xferred));
5105 			NDBG31(("dmacount=%d", cmd->cmd_dmacount));
5106 			pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET
5107 			    | STATE_SENT_CMD | STATE_GOT_STATUS);
5108 			pkt->pkt_resid = (cmd->cmd_dmacount - xferred);
5109 			if (pkt->pkt_resid != cmd->cmd_dmacount) {
5110 				pkt->pkt_state |= STATE_XFERRED_DATA;
5111 			}
5112 			break;
5113 		case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
5114 			mptsas_set_pkt_reason(mpt,
5115 			    cmd, CMD_RESET, STAT_BUS_RESET);
5116 			break;
5117 		case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
5118 		case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
5119 			mptsas_set_pkt_reason(mpt,
5120 			    cmd, CMD_RESET, STAT_DEV_RESET);
5121 			break;
5122 		case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
5123 		case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
5124 			pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET);
5125 			mptsas_set_pkt_reason(mpt,
5126 			    cmd, CMD_TERMINATED, STAT_TERMINATED);
5127 			break;
5128 		case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
5129 		case MPI2_IOCSTATUS_BUSY:
5130 			/*
5131 			 * set throttles to drain
5132 			 */
5133 			ptgt = (mptsas_target_t *)mptsas_hash_traverse(
5134 			    &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
5135 			while (ptgt != NULL) {
5136 				mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5137 
5138 				ptgt = (mptsas_target_t *)mptsas_hash_traverse(
5139 				    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
5140 			}
5141 
5142 			/*
5143 			 * retry command
5144 			 */
5145 			cmd->cmd_flags |= CFLAG_RETRY;
5146 			cmd->cmd_pkt_flags |= FLAG_HEAD;
5147 
5148 			(void) mptsas_accept_pkt(mpt, cmd);
5149 			break;
5150 		default:
5151 			mptsas_log(mpt, CE_WARN,
5152 			    "unknown ioc_status = %x\n", ioc_status);
5153 			mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer "
5154 			    "count = %x, scsi_status = %x", scsi_state,
5155 			    xferred, scsi_status);
5156 			break;
5157 		}
5158 		break;
5159 	case MPI2_SCSI_STATUS_TASK_SET_FULL:
5160 		mptsas_handle_qfull(mpt, cmd);
5161 		break;
5162 	case MPI2_SCSI_STATUS_BUSY:
5163 		NDBG31(("scsi_status busy received"));
5164 		break;
5165 	case MPI2_SCSI_STATUS_RESERVATION_CONFLICT:
5166 		NDBG31(("scsi_status reservation conflict received"));
5167 		break;
5168 	default:
5169 		mptsas_log(mpt, CE_WARN, "scsi_status=%x, ioc_status=%x\n",
5170 		    scsi_status, ioc_status);
5171 		mptsas_log(mpt, CE_WARN,
5172 		    "mptsas_process_intr: invalid scsi status\n");
5173 		break;
5174 	}
5175 }
5176 
5177 static void
5178 mptsas_check_task_mgt(mptsas_t *mpt, pMpi2SCSIManagementReply_t reply,
5179 	mptsas_cmd_t *cmd)
5180 {
5181 	uint8_t		task_type;
5182 	uint16_t	ioc_status;
5183 	uint32_t	log_info;
5184 	uint16_t	dev_handle;
5185 	struct scsi_pkt *pkt = CMD2PKT(cmd);
5186 
5187 	task_type = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->TaskType);
5188 	ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus);
5189 	log_info = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo);
5190 	dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->DevHandle);
5191 
5192 	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
5193 		mptsas_log(mpt, CE_WARN, "mptsas_check_task_mgt: Task 0x%x "
5194 		    "failed. IOCStatus=0x%x IOCLogInfo=0x%x target=%d\n",
5195 		    task_type, ioc_status, log_info, dev_handle);
5196 		pkt->pkt_reason = CMD_INCOMPLETE;
5197 		return;
5198 	}
5199 
5200 	switch (task_type) {
5201 	case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
5202 	case MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET:
5203 	case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK:
5204 	case MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA:
5205 	case MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET:
5206 	case MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION:
5207 		break;
5208 	case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
5209 	case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
5210 	case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
5211 		mptsas_flush_target(mpt, dev_handle, Lun(cmd), task_type);
5212 		break;
5213 	default:
5214 		mptsas_log(mpt, CE_WARN, "Unknown task management type %d.",
5215 		    task_type);
5216 		mptsas_log(mpt, CE_WARN, "ioc status = %x", ioc_status);
5217 		break;
5218 	}
5219 }
5220 
5221 static void
5222 mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg)
5223 {
5224 	mptsas_t			*mpt = arg->mpt;
5225 	uint64_t			t = arg->t;
5226 	mptsas_cmd_t			*cmd;
5227 	struct scsi_pkt			*pkt;
5228 	mptsas_doneq_thread_list_t	*item = &mpt->m_doneq_thread_id[t];
5229 
5230 	mutex_enter(&item->mutex);
5231 	while (item->flag & MPTSAS_DONEQ_THREAD_ACTIVE) {
5232 		if (!item->doneq) {
5233 			cv_wait(&item->cv, &item->mutex);
5234 		}
5235 		pkt = NULL;
5236 		if ((cmd = mptsas_doneq_thread_rm(mpt, t)) != NULL) {
5237 			cmd->cmd_flags |= CFLAG_COMPLETED;
5238 			pkt = CMD2PKT(cmd);
5239 		}
5240 		mutex_exit(&item->mutex);
5241 		if (pkt) {
5242 			mptsas_pkt_comp(pkt, cmd);
5243 		}
5244 		mutex_enter(&item->mutex);
5245 	}
5246 	mutex_exit(&item->mutex);
5247 	mutex_enter(&mpt->m_doneq_mutex);
5248 	mpt->m_doneq_thread_n--;
5249 	cv_broadcast(&mpt->m_doneq_thread_cv);
5250 	mutex_exit(&mpt->m_doneq_mutex);
5251 }
5252 
5253 
5254 /*
5255  * mpt interrupt handler.
5256  */
5257 static uint_t
5258 mptsas_intr(caddr_t arg1, caddr_t arg2)
5259 {
5260 	mptsas_t			*mpt = (void *)arg1;
5261 	pMpi2ReplyDescriptorsUnion_t	reply_desc_union;
5262 	uchar_t				did_reply = FALSE;
5263 
5264 	NDBG1(("mptsas_intr: arg1 0x%p arg2 0x%p", (void *)arg1, (void *)arg2));
5265 
5266 	mutex_enter(&mpt->m_mutex);
5267 
5268 	/*
5269 	 * If interrupts are shared by two channels then check whether this
5270 	 * interrupt is genuinely for this channel by making sure first the
5271 	 * chip is in high power state.
5272 	 */
5273 	if ((mpt->m_options & MPTSAS_OPT_PM) &&
5274 	    (mpt->m_power_level != PM_LEVEL_D0)) {
5275 		mutex_exit(&mpt->m_mutex);
5276 		return (DDI_INTR_UNCLAIMED);
5277 	}
5278 
5279 	/*
5280 	 * If polling, interrupt was triggered by some shared interrupt because
5281 	 * IOC interrupts are disabled during polling, so polling routine will
5282 	 * handle any replies.  Considering this, if polling is happening,
5283 	 * return with interrupt unclaimed.
5284 	 */
5285 	if (mpt->m_polled_intr) {
5286 		mutex_exit(&mpt->m_mutex);
5287 		mptsas_log(mpt, CE_WARN, "mpt_sas: Unclaimed interrupt");
5288 		return (DDI_INTR_UNCLAIMED);
5289 	}
5290 
5291 	/*
5292 	 * Read the istat register.
5293 	 */
5294 	if ((INTPENDING(mpt)) != 0) {
5295 		/*
5296 		 * read fifo until empty.
5297 		 */
5298 #ifndef __lock_lint
5299 		_NOTE(CONSTCOND)
5300 #endif
5301 		while (TRUE) {
5302 			(void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
5303 			    DDI_DMA_SYNC_FORCPU);
5304 			reply_desc_union = (pMpi2ReplyDescriptorsUnion_t)
5305 			    MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index);
5306 
5307 			if (ddi_get32(mpt->m_acc_post_queue_hdl,
5308 			    &reply_desc_union->Words.Low) == 0xFFFFFFFF ||
5309 			    ddi_get32(mpt->m_acc_post_queue_hdl,
5310 			    &reply_desc_union->Words.High) == 0xFFFFFFFF) {
5311 				break;
5312 			}
5313 
5314 			/*
5315 			 * The reply is valid, process it according to its
5316 			 * type.  Also, set a flag for updating the reply index
5317 			 * after they've all been processed.
5318 			 */
5319 			did_reply = TRUE;
5320 
5321 			mptsas_process_intr(mpt, reply_desc_union);
5322 
5323 			/*
5324 			 * Increment post index and roll over if needed.
5325 			 */
5326 			if (++mpt->m_post_index == mpt->m_post_queue_depth) {
5327 				mpt->m_post_index = 0;
5328 			}
5329 		}
5330 
5331 		/*
5332 		 * Update the global reply index if at least one reply was
5333 		 * processed.
5334 		 */
5335 		if (did_reply) {
5336 			ddi_put32(mpt->m_datap,
5337 			    &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index);
5338 		}
5339 	} else {
5340 		mutex_exit(&mpt->m_mutex);
5341 		return (DDI_INTR_UNCLAIMED);
5342 	}
5343 	NDBG1(("mptsas_intr complete"));
5344 
5345 	/*
5346 	 * If no helper threads are created, process the doneq in ISR. If
5347 	 * helpers are created, use the doneq length as a metric to measure the
5348 	 * load on the interrupt CPU. If it is long enough, which indicates the
5349 	 * load is heavy, then we deliver the IO completions to the helpers.
5350 	 * This measurement has some limitations, although it is simple and
5351 	 * straightforward and works well for most of the cases at present.
5352 	 */
5353 	if (!mpt->m_doneq_thread_n ||
5354 	    (mpt->m_doneq_len <= mpt->m_doneq_length_threshold)) {
5355 		mptsas_doneq_empty(mpt);
5356 	} else {
5357 		mptsas_deliver_doneq_thread(mpt);
5358 	}
5359 
5360 	/*
5361 	 * If there are queued cmd, start them now.
5362 	 */
5363 	if (mpt->m_waitq != NULL) {
5364 		mptsas_restart_waitq(mpt);
5365 	}
5366 
5367 	mutex_exit(&mpt->m_mutex);
5368 	return (DDI_INTR_CLAIMED);
5369 }
5370 
5371 static void
5372 mptsas_process_intr(mptsas_t *mpt,
5373     pMpi2ReplyDescriptorsUnion_t reply_desc_union)
5374 {
5375 	uint8_t	reply_type;
5376 
5377 	ASSERT(mutex_owned(&mpt->m_mutex));
5378 
5379 	/*
5380 	 * The reply is valid, process it according to its
5381 	 * type.  Also, set a flag for updated the reply index
5382 	 * after they've all been processed.
5383 	 */
5384 	reply_type = ddi_get8(mpt->m_acc_post_queue_hdl,
5385 	    &reply_desc_union->Default.ReplyFlags);
5386 	reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
5387 	if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) {
5388 		mptsas_handle_scsi_io_success(mpt, reply_desc_union);
5389 	} else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
5390 		mptsas_handle_address_reply(mpt, reply_desc_union);
5391 	} else {
5392 		mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type);
5393 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5394 	}
5395 
5396 	/*
5397 	 * Clear the reply descriptor for re-use and increment
5398 	 * index.
5399 	 */
5400 	ddi_put64(mpt->m_acc_post_queue_hdl,
5401 	    &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index],
5402 	    0xFFFFFFFFFFFFFFFF);
5403 	(void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
5404 	    DDI_DMA_SYNC_FORDEV);
5405 }
5406 
5407 /*
5408  * handle qfull condition
5409  */
5410 static void
5411 mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd)
5412 {
5413 	mptsas_target_t	*ptgt = cmd->cmd_tgt_addr;
5414 
5415 	if ((++cmd->cmd_qfull_retries > ptgt->m_qfull_retries) ||
5416 	    (ptgt->m_qfull_retries == 0)) {
5417 		/*
5418 		 * We have exhausted the retries on QFULL, or,
5419 		 * the target driver has indicated that it
5420 		 * wants to handle QFULL itself by setting
5421 		 * qfull-retries capability to 0. In either case
5422 		 * we want the target driver's QFULL handling
5423 		 * to kick in. We do this by having pkt_reason
5424 		 * as CMD_CMPLT and pkt_scbp as STATUS_QFULL.
5425 		 */
5426 		mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5427 	} else {
5428 		if (ptgt->m_reset_delay == 0) {
5429 			ptgt->m_t_throttle =
5430 			    max((ptgt->m_t_ncmds - 2), 0);
5431 		}
5432 
5433 		cmd->cmd_pkt_flags |= FLAG_HEAD;
5434 		cmd->cmd_flags &= ~(CFLAG_TRANFLAG);
5435 		cmd->cmd_flags |= CFLAG_RETRY;
5436 
5437 		(void) mptsas_accept_pkt(mpt, cmd);
5438 
5439 		/*
5440 		 * when target gives queue full status with no commands
5441 		 * outstanding (m_t_ncmds == 0), throttle is set to 0
5442 		 * (HOLD_THROTTLE), and the queue full handling start
5443 		 * (see psarc/1994/313); if there are commands outstanding,
5444 		 * throttle is set to (m_t_ncmds - 2)
5445 		 */
5446 		if (ptgt->m_t_throttle == HOLD_THROTTLE) {
5447 			/*
5448 			 * By setting throttle to QFULL_THROTTLE, we
5449 			 * avoid submitting new commands and in
5450 			 * mptsas_restart_cmd find out slots which need
5451 			 * their throttles to be cleared.
5452 			 */
5453 			mptsas_set_throttle(mpt, ptgt, QFULL_THROTTLE);
5454 			if (mpt->m_restart_cmd_timeid == 0) {
5455 				mpt->m_restart_cmd_timeid =
5456 				    timeout(mptsas_restart_cmd, mpt,
5457 				    ptgt->m_qfull_retry_interval);
5458 			}
5459 		}
5460 	}
5461 }
5462 
5463 uint8_t
5464 mptsas_phymask_to_physport(mptsas_t *mpt, uint8_t phymask)
5465 {
5466 	int i;
5467 
5468 	/*
5469 	 * RAID doesn't have valid phymask and physport so we use phymask == 0
5470 	 * and physport == 0xff to indicate that it's RAID.
5471 	 */
5472 	if (phymask == 0) {
5473 		return (0xff);
5474 	}
5475 	for (i = 0; i < 8; i++) {
5476 		if (phymask & (1 << i)) {
5477 			break;
5478 		}
5479 	}
5480 	return (mpt->m_phy_info[i].port_num);
5481 }
5482 uint8_t
5483 mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport)
5484 {
5485 	uint8_t		phy_mask = 0;
5486 	uint8_t		i = 0;
5487 
5488 	NDBG20(("mptsas%d physport_to_phymask enter", mpt->m_instance));
5489 
5490 	ASSERT(mutex_owned(&mpt->m_mutex));
5491 
5492 	/*
5493 	 * If physport is 0xFF, this is a RAID volume.  Use phymask of 0.
5494 	 */
5495 	if (physport == 0xFF) {
5496 		return (0);
5497 	}
5498 
5499 	for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
5500 		if (mpt->m_phy_info[i].attached_devhdl &&
5501 		    (mpt->m_phy_info[i].phy_mask != 0) &&
5502 		    (mpt->m_phy_info[i].port_num == physport)) {
5503 			phy_mask = mpt->m_phy_info[i].phy_mask;
5504 			break;
5505 		}
5506 	}
5507 	NDBG20(("mptsas%d physport_to_phymask:physport :%x phymask :%x, ",
5508 	    mpt->m_instance, physport, phy_mask));
5509 	return (phy_mask);
5510 }
5511 
5512 /*
5513  * mpt free device handle after device gone, by use of passthrough
5514  */
5515 static int
5516 mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl)
5517 {
5518 	Mpi2SasIoUnitControlRequest_t	req;
5519 	Mpi2SasIoUnitControlReply_t	rep;
5520 	int				ret;
5521 
5522 	ASSERT(mutex_owned(&mpt->m_mutex));
5523 
5524 	/*
5525 	 * Need to compose a SAS IO Unit Control request message
5526 	 * and call mptsas_do_passthru() function
5527 	 */
5528 	bzero(&req, sizeof (req));
5529 	bzero(&rep, sizeof (rep));
5530 
5531 	req.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
5532 	req.Operation = MPI2_SAS_OP_REMOVE_DEVICE;
5533 	req.DevHandle = LE_16(devhdl);
5534 
5535 	ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL,
5536 	    sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL);
5537 	if (ret != 0) {
5538 		cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit "
5539 		    "Control error %d", ret);
5540 		return (DDI_FAILURE);
5541 	}
5542 
5543 	/* do passthrough success, check the ioc status */
5544 	if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
5545 		cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit "
5546 		    "Control IOCStatus %d", LE_16(rep.IOCStatus));
5547 		return (DDI_FAILURE);
5548 	}
5549 
5550 	return (DDI_SUCCESS);
5551 }
5552 
5553 static void
5554 mptsas_update_phymask(mptsas_t *mpt)
5555 {
5556 	uint8_t	mask = 0, phy_mask;
5557 	char	*phy_mask_name;
5558 	uint8_t current_port;
5559 	int	i, j;
5560 
5561 	NDBG20(("mptsas%d update phymask ", mpt->m_instance));
5562 
5563 	ASSERT(mutex_owned(&mpt->m_mutex));
5564 
5565 	(void) mptsas_get_sas_io_unit_page(mpt);
5566 
5567 	phy_mask_name = kmem_zalloc(8, KM_SLEEP);
5568 
5569 	for (i = 0; i < mpt->m_num_phys; i++) {
5570 		phy_mask = 0x00;
5571 
5572 		if (mpt->m_phy_info[i].attached_devhdl == 0)
5573 			continue;
5574 
5575 		bzero(phy_mask_name, sizeof (phy_mask_name));
5576 
5577 		current_port = mpt->m_phy_info[i].port_num;
5578 
5579 		if ((mask & (1 << i)) != 0)
5580 			continue;
5581 
5582 		for (j = 0; j < mpt->m_num_phys; j++) {
5583 			if (mpt->m_phy_info[j].attached_devhdl &&
5584 			    (mpt->m_phy_info[j].port_num == current_port)) {
5585 				phy_mask |= (1 << j);
5586 			}
5587 		}
5588 		mask = mask | phy_mask;
5589 
5590 		for (j = 0; j < mpt->m_num_phys; j++) {
5591 			if ((phy_mask >> j) & 0x01) {
5592 				mpt->m_phy_info[j].phy_mask = phy_mask;
5593 			}
5594 		}
5595 
5596 		(void) sprintf(phy_mask_name, "%x", phy_mask);
5597 
5598 		mutex_exit(&mpt->m_mutex);
5599 		/*
5600 		 * register a iport, if the port has already been existed
5601 		 * SCSA will do nothing and just return.
5602 		 */
5603 		(void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name);
5604 		mutex_enter(&mpt->m_mutex);
5605 	}
5606 	kmem_free(phy_mask_name, 8);
5607 	NDBG20(("mptsas%d update phymask return", mpt->m_instance));
5608 }
5609 
5610 /*
5611  * mptsas_handle_dr is a task handler for DR, the DR action includes:
5612  * 1. Directly attched Device Added/Removed.
5613  * 2. Expander Device Added/Removed.
5614  * 3. Indirectly Attached Device Added/Expander.
5615  * 4. LUNs of a existing device status change.
5616  * 5. RAID volume created/deleted.
5617  * 6. Member of RAID volume is released because of RAID deletion.
5618  * 7. Physical disks are removed because of RAID creation.
5619  */
5620 static void
5621 mptsas_handle_dr(void *args) {
5622 	mptsas_topo_change_list_t	*topo_node = NULL;
5623 	mptsas_topo_change_list_t	*save_node = NULL;
5624 	mptsas_t			*mpt;
5625 	dev_info_t			*parent = NULL;
5626 	uint8_t				phymask = 0;
5627 	char				*phy_mask_name;
5628 	uint8_t				flags = 0, physport = 0xff;
5629 	uint8_t				port_update = 0;
5630 	uint_t				event;
5631 
5632 	topo_node = (mptsas_topo_change_list_t *)args;
5633 
5634 	mpt = topo_node->mpt;
5635 	event = topo_node->event;
5636 	flags = topo_node->flags;
5637 
5638 	phy_mask_name = kmem_zalloc(8, KM_SLEEP);
5639 
5640 	NDBG20(("mptsas%d handle_dr enter", mpt->m_instance));
5641 
5642 	switch (event) {
5643 	case MPTSAS_DR_EVENT_RECONFIG_TARGET:
5644 		if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
5645 		    (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE) ||
5646 		    (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) {
5647 			/*
5648 			 * Direct attached or expander attached device added
5649 			 * into system or a Phys Disk that is being unhidden.
5650 			 */
5651 			port_update = 1;
5652 		}
5653 		break;
5654 	case MPTSAS_DR_EVENT_RECONFIG_SMP:
5655 		/*
5656 		 * New expander added into system, it must be the head
5657 		 * of topo_change_list_t
5658 		 */
5659 		port_update = 1;
5660 		break;
5661 	default:
5662 		port_update = 0;
5663 		break;
5664 	}
5665 	/*
5666 	 * All cases port_update == 1 may cause initiator port form change
5667 	 */
5668 	mutex_enter(&mpt->m_mutex);
5669 	if (mpt->m_port_chng && port_update) {
5670 		/*
5671 		 * mpt->m_port_chng flag indicates some PHYs of initiator
5672 		 * port have changed to online. So when expander added or
5673 		 * directly attached device online event come, we force to
5674 		 * update port information by issueing SAS IO Unit Page and
5675 		 * update PHYMASKs.
5676 		 */
5677 		(void) mptsas_update_phymask(mpt);
5678 		mpt->m_port_chng = 0;
5679 
5680 	}
5681 	mutex_exit(&mpt->m_mutex);
5682 	while (topo_node) {
5683 		phymask = 0;
5684 		if (parent == NULL) {
5685 			physport = topo_node->un.physport;
5686 			event = topo_node->event;
5687 			flags = topo_node->flags;
5688 			if (event & (MPTSAS_DR_EVENT_OFFLINE_TARGET |
5689 			    MPTSAS_DR_EVENT_OFFLINE_SMP)) {
5690 				/*
5691 				 * For all offline events, phymask is known
5692 				 */
5693 				phymask = topo_node->un.phymask;
5694 				goto find_parent;
5695 			}
5696 			if (event & MPTSAS_TOPO_FLAG_REMOVE_HANDLE) {
5697 				goto handle_topo_change;
5698 			}
5699 			if (flags & MPTSAS_TOPO_FLAG_LUN_ASSOCIATED) {
5700 				phymask = topo_node->un.phymask;
5701 				goto find_parent;
5702 			}
5703 
5704 			if ((flags ==
5705 			    MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) &&
5706 			    (event == MPTSAS_DR_EVENT_RECONFIG_TARGET)) {
5707 				/*
5708 				 * There is no any field in IR_CONFIG_CHANGE
5709 				 * event indicate physport/phynum, let's get
5710 				 * parent after SAS Device Page0 request.
5711 				 */
5712 				goto handle_topo_change;
5713 			}
5714 
5715 			mutex_enter(&mpt->m_mutex);
5716 			if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
5717 				/*
5718 				 * If the direct attached device added or a
5719 				 * phys disk is being unhidden, argument
5720 				 * physport actually is PHY#, so we have to get
5721 				 * phymask according PHY#.
5722 				 */
5723 				physport = mpt->m_phy_info[physport].port_num;
5724 			}
5725 
5726 			/*
5727 			 * Translate physport to phymask so that we can search
5728 			 * parent dip.
5729 			 */
5730 			phymask = mptsas_physport_to_phymask(mpt,
5731 			    physport);
5732 			mutex_exit(&mpt->m_mutex);
5733 
5734 find_parent:
5735 			bzero(phy_mask_name, 8);
5736 			/*
5737 			 * For RAID topology change node, write the iport name
5738 			 * as v0.
5739 			 */
5740 			if (flags & MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5741 				(void) sprintf(phy_mask_name, "v0");
5742 			} else {
5743 				/*
5744 				 * phymask can bo 0 if the drive has been
5745 				 * pulled by the time an add event is
5746 				 * processed.  If phymask is 0, just skip this
5747 				 * event and continue.
5748 				 */
5749 				if (phymask == 0) {
5750 					mutex_enter(&mpt->m_mutex);
5751 					save_node = topo_node;
5752 					topo_node = topo_node->next;
5753 					ASSERT(save_node);
5754 					kmem_free(save_node,
5755 					    sizeof (mptsas_topo_change_list_t));
5756 					mutex_exit(&mpt->m_mutex);
5757 
5758 					parent = NULL;
5759 					continue;
5760 				}
5761 				(void) sprintf(phy_mask_name, "%x", phymask);
5762 			}
5763 			parent = scsi_hba_iport_find(mpt->m_dip,
5764 			    phy_mask_name);
5765 			if (parent == NULL) {
5766 				mptsas_log(mpt, CE_WARN, "Failed to find an "
5767 				    "iport, should not happen!");
5768 				goto out;
5769 			}
5770 
5771 		}
5772 		ASSERT(parent);
5773 handle_topo_change:
5774 
5775 		mutex_enter(&mpt->m_mutex);
5776 
5777 		mptsas_handle_topo_change(topo_node, parent);
5778 		save_node = topo_node;
5779 		topo_node = topo_node->next;
5780 		ASSERT(save_node);
5781 		kmem_free(save_node, sizeof (mptsas_topo_change_list_t));
5782 		mutex_exit(&mpt->m_mutex);
5783 
5784 		if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
5785 		    (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) ||
5786 		    (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) {
5787 			/*
5788 			 * If direct attached device associated, make sure
5789 			 * reset the parent before start the next one. But
5790 			 * all devices associated with expander shares the
5791 			 * parent.  Also, reset parent if this is for RAID.
5792 			 */
5793 			parent = NULL;
5794 		}
5795 	}
5796 out:
5797 	kmem_free(phy_mask_name, 8);
5798 }
5799 
5800 static void
5801 mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node,
5802     dev_info_t *parent)
5803 {
5804 	mptsas_target_t	*ptgt = NULL;
5805 	mptsas_smp_t	*psmp = NULL;
5806 	mptsas_t	*mpt = (void *)topo_node->mpt;
5807 	uint16_t	devhdl;
5808 	uint64_t	sas_wwn = 0;
5809 	int		rval = 0;
5810 	uint32_t	page_address;
5811 	uint8_t		phy, flags;
5812 	char		*addr = NULL;
5813 	dev_info_t	*lundip;
5814 	int		circ = 0, circ1 = 0;
5815 
5816 	NDBG20(("mptsas%d handle_topo_change enter", mpt->m_instance));
5817 
5818 	ASSERT(mutex_owned(&mpt->m_mutex));
5819 
5820 	switch (topo_node->event) {
5821 	case MPTSAS_DR_EVENT_RECONFIG_TARGET:
5822 	{
5823 		char *phy_mask_name;
5824 		uint8_t phymask = 0;
5825 
5826 		if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5827 			/*
5828 			 * Get latest RAID info.
5829 			 */
5830 			(void) mptsas_get_raid_info(mpt);
5831 			ptgt = mptsas_search_by_devhdl(
5832 			    &mpt->m_active->m_tgttbl, topo_node->devhdl);
5833 			if (ptgt == NULL)
5834 				break;
5835 		} else {
5836 			ptgt = (void *)topo_node->object;
5837 		}
5838 
5839 		if (ptgt == NULL) {
5840 			/*
5841 			 * If a Phys Disk was deleted, RAID info needs to be
5842 			 * updated to reflect the new topology.
5843 			 */
5844 			(void) mptsas_get_raid_info(mpt);
5845 
5846 			/*
5847 			 * Get sas device page 0 by DevHandle to make sure if
5848 			 * SSP/SATA end device exist.
5849 			 */
5850 			page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
5851 			    MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
5852 			    topo_node->devhdl;
5853 
5854 			rval = mptsas_get_target_device_info(mpt, page_address,
5855 			    &devhdl, &ptgt);
5856 			if (rval == DEV_INFO_WRONG_DEVICE_TYPE) {
5857 				mptsas_log(mpt, CE_NOTE,
5858 				    "mptsas_handle_topo_change: target %d is "
5859 				    "not a SAS/SATA device. \n",
5860 				    topo_node->devhdl);
5861 			} else if (rval == DEV_INFO_FAIL_ALLOC) {
5862 				mptsas_log(mpt, CE_NOTE,
5863 				    "mptsas_handle_topo_change: could not "
5864 				    "allocate memory. \n");
5865 			}
5866 			/*
5867 			 * If rval is DEV_INFO_PHYS_DISK than there is nothing
5868 			 * else to do, just leave.
5869 			 */
5870 			if (rval != DEV_INFO_SUCCESS) {
5871 				return;
5872 			}
5873 		}
5874 
5875 		ASSERT(ptgt->m_devhdl == topo_node->devhdl);
5876 
5877 		mutex_exit(&mpt->m_mutex);
5878 		flags = topo_node->flags;
5879 
5880 		if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) {
5881 			phymask = ptgt->m_phymask;
5882 			phy_mask_name = kmem_zalloc(8, KM_SLEEP);
5883 			(void) sprintf(phy_mask_name, "%x", phymask);
5884 			parent = scsi_hba_iport_find(mpt->m_dip,
5885 			    phy_mask_name);
5886 			kmem_free(phy_mask_name, 8);
5887 			if (parent == NULL) {
5888 				mptsas_log(mpt, CE_WARN, "Failed to find a "
5889 				    "iport for PD, should not happen!");
5890 				mutex_enter(&mpt->m_mutex);
5891 				break;
5892 			}
5893 		}
5894 
5895 		if (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5896 			ndi_devi_enter(parent, &circ1);
5897 			(void) mptsas_config_raid(parent, topo_node->devhdl,
5898 			    &lundip);
5899 			ndi_devi_exit(parent, circ1);
5900 		} else {
5901 			/*
5902 			 * hold nexus for bus configure
5903 			 */
5904 			ndi_devi_enter(scsi_vhci_dip, &circ);
5905 			ndi_devi_enter(parent, &circ1);
5906 			rval = mptsas_config_target(parent, ptgt);
5907 			/*
5908 			 * release nexus for bus configure
5909 			 */
5910 			ndi_devi_exit(parent, circ1);
5911 			ndi_devi_exit(scsi_vhci_dip, circ);
5912 
5913 		}
5914 		mutex_enter(&mpt->m_mutex);
5915 
5916 		NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, "
5917 		    "phymask:%x.", mpt->m_instance, ptgt->m_devhdl,
5918 		    ptgt->m_phymask));
5919 		break;
5920 	}
5921 	case MPTSAS_DR_EVENT_OFFLINE_TARGET:
5922 	{
5923 		mptsas_hash_table_t *tgttbl = &mpt->m_active->m_tgttbl;
5924 		devhdl = topo_node->devhdl;
5925 		ptgt = mptsas_search_by_devhdl(tgttbl, devhdl);
5926 		if (ptgt == NULL)
5927 			break;
5928 
5929 		sas_wwn = ptgt->m_sas_wwn;
5930 		phy = ptgt->m_phynum;
5931 
5932 		addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
5933 
5934 		if (sas_wwn) {
5935 			(void) sprintf(addr, "w%016"PRIx64, sas_wwn);
5936 		} else {
5937 			(void) sprintf(addr, "p%x", phy);
5938 		}
5939 		ASSERT(ptgt->m_devhdl == devhdl);
5940 
5941 		if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5942 			/*
5943 			 * Get latest RAID info, if RAID volume status change
5944 			 */
5945 			(void) mptsas_get_raid_info(mpt);
5946 		}
5947 		/*
5948 		 * Abort all outstanding command on the device
5949 		 */
5950 		rval = mptsas_do_scsi_reset(mpt, devhdl);
5951 		if (rval) {
5952 			NDBG20(("mptsas%d handle_topo_change to reset target "
5953 			    "before offline devhdl:%x, phymask:%x, rval:%x",
5954 			    mpt->m_instance, ptgt->m_devhdl, ptgt->m_phymask,
5955 			    rval));
5956 		}
5957 
5958 		mutex_exit(&mpt->m_mutex);
5959 
5960 		ndi_devi_enter(scsi_vhci_dip, &circ);
5961 		ndi_devi_enter(parent, &circ1);
5962 		rval = mptsas_offline_target(parent, addr);
5963 		ndi_devi_exit(parent, circ1);
5964 		ndi_devi_exit(scsi_vhci_dip, circ);
5965 		NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, "
5966 		    "phymask:%x, rval:%x", mpt->m_instance,
5967 		    ptgt->m_devhdl, ptgt->m_phymask, rval));
5968 
5969 		kmem_free(addr, SCSI_MAXNAMELEN);
5970 
5971 		mutex_enter(&mpt->m_mutex);
5972 		if (rval == DDI_SUCCESS) {
5973 			mptsas_tgt_free(&mpt->m_active->m_tgttbl,
5974 			    ptgt->m_sas_wwn, ptgt->m_phymask);
5975 			ptgt = NULL;
5976 		} else {
5977 			/*
5978 			 * clean DR_INTRANSITION flag to allow I/O down to
5979 			 * PHCI driver since failover finished.
5980 			 * Invalidate the devhdl
5981 			 */
5982 			ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL;
5983 			mutex_enter(&mpt->m_tx_waitq_mutex);
5984 			ptgt->m_dr_flag = MPTSAS_DR_INACTIVE;
5985 			mutex_exit(&mpt->m_tx_waitq_mutex);
5986 		}
5987 
5988 		/*
5989 		 * Send SAS IO Unit Control to free the dev handle
5990 		 */
5991 		flags = topo_node->flags;
5992 		if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
5993 		    (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE)) {
5994 			rval = mptsas_free_devhdl(mpt, devhdl);
5995 
5996 			NDBG20(("mptsas%d handle_topo_change to remove "
5997 			    "devhdl:%x, rval:%x", mpt->m_instance, devhdl,
5998 			    rval));
5999 		}
6000 		break;
6001 	}
6002 	case MPTSAS_TOPO_FLAG_REMOVE_HANDLE:
6003 	{
6004 		devhdl = topo_node->devhdl;
6005 		/*
6006 		 * If this is the remove handle event, do a reset first.
6007 		 */
6008 		if (topo_node->event == MPTSAS_TOPO_FLAG_REMOVE_HANDLE) {
6009 			rval = mptsas_do_scsi_reset(mpt, devhdl);
6010 			if (rval) {
6011 				NDBG20(("mpt%d reset target before remove "
6012 				    "devhdl:%x, rval:%x", mpt->m_instance,
6013 				    devhdl, rval));
6014 			}
6015 		}
6016 
6017 		/*
6018 		 * Send SAS IO Unit Control to free the dev handle
6019 		 */
6020 		rval = mptsas_free_devhdl(mpt, devhdl);
6021 		NDBG20(("mptsas%d handle_topo_change to remove "
6022 		    "devhdl:%x, rval:%x", mpt->m_instance, devhdl,
6023 		    rval));
6024 		break;
6025 	}
6026 	case MPTSAS_DR_EVENT_RECONFIG_SMP:
6027 	{
6028 		mptsas_smp_t smp;
6029 		dev_info_t *smpdip;
6030 		mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl;
6031 
6032 		devhdl = topo_node->devhdl;
6033 
6034 		page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL &
6035 		    MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl;
6036 		rval = mptsas_get_sas_expander_page0(mpt, page_address, &smp);
6037 		if (rval != DDI_SUCCESS) {
6038 			mptsas_log(mpt, CE_WARN, "failed to online smp, "
6039 			    "handle %x", devhdl);
6040 			return;
6041 		}
6042 
6043 		psmp = mptsas_smp_alloc(smptbl, &smp);
6044 		if (psmp == NULL) {
6045 			return;
6046 		}
6047 
6048 		mutex_exit(&mpt->m_mutex);
6049 		ndi_devi_enter(parent, &circ1);
6050 		(void) mptsas_online_smp(parent, psmp, &smpdip);
6051 		ndi_devi_exit(parent, circ1);
6052 		mutex_enter(&mpt->m_mutex);
6053 		break;
6054 	}
6055 	case MPTSAS_DR_EVENT_OFFLINE_SMP:
6056 	{
6057 		mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl;
6058 		devhdl = topo_node->devhdl;
6059 		psmp = mptsas_search_by_devhdl(smptbl, devhdl);
6060 		if (psmp == NULL)
6061 			break;
6062 		/*
6063 		 * The mptsas_smp_t data is released only if the dip is offlined
6064 		 * successfully.
6065 		 */
6066 		mutex_exit(&mpt->m_mutex);
6067 		ndi_devi_enter(parent, &circ1);
6068 		rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE);
6069 		ndi_devi_exit(parent, circ1);
6070 		mutex_enter(&mpt->m_mutex);
6071 		NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, "
6072 		    "rval:%x", mpt->m_instance, psmp->m_devhdl, rval));
6073 		if (rval == DDI_SUCCESS) {
6074 			mptsas_smp_free(smptbl, psmp->m_sasaddr,
6075 			    psmp->m_phymask);
6076 		} else {
6077 			psmp->m_devhdl = MPTSAS_INVALID_DEVHDL;
6078 		}
6079 		break;
6080 	}
6081 	default:
6082 		return;
6083 	}
6084 }
6085 
6086 /*
6087  * Record the event if its type is enabled in mpt instance by ioctl.
6088  */
6089 static void
6090 mptsas_record_event(void *args)
6091 {
6092 	m_replyh_arg_t			*replyh_arg;
6093 	pMpi2EventNotificationReply_t	eventreply;
6094 	uint32_t			event, rfm;
6095 	mptsas_t			*mpt;
6096 	int				i, j;
6097 	uint16_t			event_data_len;
6098 	boolean_t			sendAEN = FALSE;
6099 
6100 	replyh_arg = (m_replyh_arg_t *)args;
6101 	rfm = replyh_arg->rfm;
6102 	mpt = replyh_arg->mpt;
6103 
6104 	eventreply = (pMpi2EventNotificationReply_t)
6105 	    (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr));
6106 	event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
6107 
6108 
6109 	/*
6110 	 * Generate a system event to let anyone who cares know that a
6111 	 * LOG_ENTRY_ADDED event has occurred.  This is sent no matter what the
6112 	 * event mask is set to.
6113 	 */
6114 	if (event == MPI2_EVENT_LOG_ENTRY_ADDED) {
6115 		sendAEN = TRUE;
6116 	}
6117 
6118 	/*
6119 	 * Record the event only if it is not masked.  Determine which dword
6120 	 * and bit of event mask to test.
6121 	 */
6122 	i = (uint8_t)(event / 32);
6123 	j = (uint8_t)(event % 32);
6124 	if ((i < 4) && ((1 << j) & mpt->m_event_mask[i])) {
6125 		i = mpt->m_event_index;
6126 		mpt->m_events[i].Type = event;
6127 		mpt->m_events[i].Number = ++mpt->m_event_number;
6128 		bzero(mpt->m_events[i].Data, MPTSAS_MAX_EVENT_DATA_LENGTH * 4);
6129 		event_data_len = ddi_get16(mpt->m_acc_reply_frame_hdl,
6130 		    &eventreply->EventDataLength);
6131 
6132 		if (event_data_len > 0) {
6133 			/*
6134 			 * Limit data to size in m_event entry
6135 			 */
6136 			if (event_data_len > MPTSAS_MAX_EVENT_DATA_LENGTH) {
6137 				event_data_len = MPTSAS_MAX_EVENT_DATA_LENGTH;
6138 			}
6139 			for (j = 0; j < event_data_len; j++) {
6140 				mpt->m_events[i].Data[j] =
6141 				    ddi_get32(mpt->m_acc_reply_frame_hdl,
6142 				    &(eventreply->EventData[j]));
6143 			}
6144 
6145 			/*
6146 			 * check for index wrap-around
6147 			 */
6148 			if (++i == MPTSAS_EVENT_QUEUE_SIZE) {
6149 				i = 0;
6150 			}
6151 			mpt->m_event_index = (uint8_t)i;
6152 
6153 			/*
6154 			 * Set flag to send the event.
6155 			 */
6156 			sendAEN = TRUE;
6157 		}
6158 	}
6159 
6160 	/*
6161 	 * Generate a system event if flag is set to let anyone who cares know
6162 	 * that an event has occurred.
6163 	 */
6164 	if (sendAEN) {
6165 		(void) ddi_log_sysevent(mpt->m_dip, DDI_VENDOR_LSI, "MPT_SAS",
6166 		    "SAS", NULL, NULL, DDI_NOSLEEP);
6167 	}
6168 }
6169 
6170 #define	SMP_RESET_IN_PROGRESS MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS
6171 /*
6172  * handle sync events from ioc in interrupt
6173  * return value:
6174  * DDI_SUCCESS: The event is handled by this func
6175  * DDI_FAILURE: Event is not handled
6176  */
6177 static int
6178 mptsas_handle_event_sync(void *args)
6179 {
6180 	m_replyh_arg_t			*replyh_arg;
6181 	pMpi2EventNotificationReply_t	eventreply;
6182 	uint32_t			event, rfm;
6183 	mptsas_t			*mpt;
6184 	uint_t				iocstatus;
6185 
6186 	replyh_arg = (m_replyh_arg_t *)args;
6187 	rfm = replyh_arg->rfm;
6188 	mpt = replyh_arg->mpt;
6189 
6190 	ASSERT(mutex_owned(&mpt->m_mutex));
6191 
6192 	eventreply = (pMpi2EventNotificationReply_t)
6193 	    (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr));
6194 	event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
6195 
6196 	if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
6197 	    &eventreply->IOCStatus)) {
6198 		if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
6199 			mptsas_log(mpt, CE_WARN,
6200 			    "!mptsas_handle_event_sync: IOCStatus=0x%x, "
6201 			    "IOCLogInfo=0x%x", iocstatus,
6202 			    ddi_get32(mpt->m_acc_reply_frame_hdl,
6203 			    &eventreply->IOCLogInfo));
6204 		} else {
6205 			mptsas_log(mpt, CE_WARN,
6206 			    "mptsas_handle_event_sync: IOCStatus=0x%x, "
6207 			    "IOCLogInfo=0x%x", iocstatus,
6208 			    ddi_get32(mpt->m_acc_reply_frame_hdl,
6209 			    &eventreply->IOCLogInfo));
6210 		}
6211 	}
6212 
6213 	/*
6214 	 * figure out what kind of event we got and handle accordingly
6215 	 */
6216 	switch (event) {
6217 	case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
6218 	{
6219 		pMpi2EventDataSasTopologyChangeList_t	sas_topo_change_list;
6220 		uint8_t				num_entries, expstatus, phy;
6221 		uint8_t				phystatus, physport, state, i;
6222 		uint8_t				start_phy_num, link_rate;
6223 		uint16_t			dev_handle, reason_code;
6224 		uint16_t			enc_handle, expd_handle;
6225 		char				string[80], curr[80], prev[80];
6226 		mptsas_topo_change_list_t	*topo_head = NULL;
6227 		mptsas_topo_change_list_t	*topo_tail = NULL;
6228 		mptsas_topo_change_list_t	*topo_node = NULL;
6229 		mptsas_target_t			*ptgt;
6230 		mptsas_smp_t			*psmp;
6231 		mptsas_hash_table_t		*tgttbl, *smptbl;
6232 		uint8_t				flags = 0, exp_flag;
6233 
6234 		NDBG20(("mptsas_handle_event_sync: SAS topology change"));
6235 
6236 		tgttbl = &mpt->m_active->m_tgttbl;
6237 		smptbl = &mpt->m_active->m_smptbl;
6238 
6239 		sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t)
6240 		    eventreply->EventData;
6241 
6242 		enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6243 		    &sas_topo_change_list->EnclosureHandle);
6244 		expd_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6245 		    &sas_topo_change_list->ExpanderDevHandle);
6246 		num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
6247 		    &sas_topo_change_list->NumEntries);
6248 		start_phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl,
6249 		    &sas_topo_change_list->StartPhyNum);
6250 		expstatus = ddi_get8(mpt->m_acc_reply_frame_hdl,
6251 		    &sas_topo_change_list->ExpStatus);
6252 		physport = ddi_get8(mpt->m_acc_reply_frame_hdl,
6253 		    &sas_topo_change_list->PhysicalPort);
6254 
6255 		string[0] = 0;
6256 		if (expd_handle) {
6257 			flags = MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED;
6258 			switch (expstatus) {
6259 			case MPI2_EVENT_SAS_TOPO_ES_ADDED:
6260 				(void) sprintf(string, " added");
6261 				/*
6262 				 * New expander device added
6263 				 */
6264 				mpt->m_port_chng = 1;
6265 				topo_node = kmem_zalloc(
6266 				    sizeof (mptsas_topo_change_list_t),
6267 				    KM_SLEEP);
6268 				topo_node->mpt = mpt;
6269 				topo_node->event = MPTSAS_DR_EVENT_RECONFIG_SMP;
6270 				topo_node->un.physport = physport;
6271 				topo_node->devhdl = expd_handle;
6272 				topo_node->flags = flags;
6273 				topo_node->object = NULL;
6274 				if (topo_head == NULL) {
6275 					topo_head = topo_tail = topo_node;
6276 				} else {
6277 					topo_tail->next = topo_node;
6278 					topo_tail = topo_node;
6279 				}
6280 				break;
6281 			case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING:
6282 				(void) sprintf(string, " not responding, "
6283 				    "removed");
6284 				psmp = mptsas_search_by_devhdl(smptbl,
6285 				    expd_handle);
6286 				if (psmp == NULL)
6287 					break;
6288 
6289 				topo_node = kmem_zalloc(
6290 				    sizeof (mptsas_topo_change_list_t),
6291 				    KM_SLEEP);
6292 				topo_node->mpt = mpt;
6293 				topo_node->un.phymask = psmp->m_phymask;
6294 				topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP;
6295 				topo_node->devhdl = expd_handle;
6296 				topo_node->flags = flags;
6297 				topo_node->object = NULL;
6298 				if (topo_head == NULL) {
6299 					topo_head = topo_tail = topo_node;
6300 				} else {
6301 					topo_tail->next = topo_node;
6302 					topo_tail = topo_node;
6303 				}
6304 				break;
6305 			case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
6306 				break;
6307 			case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
6308 				(void) sprintf(string, " not responding, "
6309 				    "delaying removal");
6310 				break;
6311 			default:
6312 				break;
6313 			}
6314 		} else {
6315 			flags = MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE;
6316 		}
6317 
6318 		NDBG20(("SAS TOPOLOGY CHANGE for enclosure %x expander %x%s\n",
6319 		    enc_handle, expd_handle, string));
6320 		for (i = 0; i < num_entries; i++) {
6321 			phy = i + start_phy_num;
6322 			phystatus = ddi_get8(mpt->m_acc_reply_frame_hdl,
6323 			    &sas_topo_change_list->PHY[i].PhyStatus);
6324 			dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6325 			    &sas_topo_change_list->PHY[i].AttachedDevHandle);
6326 			reason_code = phystatus & MPI2_EVENT_SAS_TOPO_RC_MASK;
6327 			/*
6328 			 * Filter out processing of Phy Vacant Status unless
6329 			 * the reason code is "Not Responding".  Process all
6330 			 * other combinations of Phy Status and Reason Codes.
6331 			 */
6332 			if ((phystatus &
6333 			    MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) &&
6334 			    (reason_code !=
6335 			    MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) {
6336 				continue;
6337 			}
6338 			curr[0] = 0;
6339 			prev[0] = 0;
6340 			string[0] = 0;
6341 			switch (reason_code) {
6342 			case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
6343 			{
6344 				NDBG20(("mptsas%d phy %d physical_port %d "
6345 				    "dev_handle %d added", mpt->m_instance, phy,
6346 				    physport, dev_handle));
6347 				link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl,
6348 				    &sas_topo_change_list->PHY[i].LinkRate);
6349 				state = (link_rate &
6350 				    MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >>
6351 				    MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT;
6352 				switch (state) {
6353 				case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
6354 					(void) sprintf(curr, "is disabled");
6355 					break;
6356 				case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
6357 					(void) sprintf(curr, "is offline, "
6358 					    "failed speed negotiation");
6359 					break;
6360 				case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
6361 					(void) sprintf(curr, "SATA OOB "
6362 					    "complete");
6363 					break;
6364 				case SMP_RESET_IN_PROGRESS:
6365 					(void) sprintf(curr, "SMP reset in "
6366 					    "progress");
6367 					break;
6368 				case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
6369 					(void) sprintf(curr, "is online at "
6370 					    "1.5 Gbps");
6371 					break;
6372 				case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
6373 					(void) sprintf(curr, "is online at 3.0 "
6374 					    "Gbps");
6375 					break;
6376 				case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
6377 					(void) sprintf(curr, "is online at 6.0 "
6378 					    "Gbps");
6379 					break;
6380 				default:
6381 					(void) sprintf(curr, "state is "
6382 					    "unknown");
6383 					break;
6384 				}
6385 				/*
6386 				 * New target device added into the system.
6387 				 * Set association flag according to if an
6388 				 * expander is used or not.
6389 				 */
6390 				exp_flag =
6391 				    MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
6392 				if (flags ==
6393 				    MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) {
6394 					flags = exp_flag;
6395 				}
6396 				topo_node = kmem_zalloc(
6397 				    sizeof (mptsas_topo_change_list_t),
6398 				    KM_SLEEP);
6399 				topo_node->mpt = mpt;
6400 				topo_node->event =
6401 				    MPTSAS_DR_EVENT_RECONFIG_TARGET;
6402 				if (expd_handle == 0) {
6403 					/*
6404 					 * Per MPI 2, if expander dev handle
6405 					 * is 0, it's a directly attached
6406 					 * device. So driver use PHY to decide
6407 					 * which iport is associated
6408 					 */
6409 					physport = phy;
6410 					mpt->m_port_chng = 1;
6411 				}
6412 				topo_node->un.physport = physport;
6413 				topo_node->devhdl = dev_handle;
6414 				topo_node->flags = flags;
6415 				topo_node->object = NULL;
6416 				if (topo_head == NULL) {
6417 					topo_head = topo_tail = topo_node;
6418 				} else {
6419 					topo_tail->next = topo_node;
6420 					topo_tail = topo_node;
6421 				}
6422 				break;
6423 			}
6424 			case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
6425 			{
6426 				NDBG20(("mptsas%d phy %d physical_port %d "
6427 				    "dev_handle %d removed", mpt->m_instance,
6428 				    phy, physport, dev_handle));
6429 				/*
6430 				 * Set association flag according to if an
6431 				 * expander is used or not.
6432 				 */
6433 				exp_flag =
6434 				    MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
6435 				if (flags ==
6436 				    MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) {
6437 					flags = exp_flag;
6438 				}
6439 				/*
6440 				 * Target device is removed from the system
6441 				 * Before the device is really offline from
6442 				 * from system.
6443 				 */
6444 				ptgt = mptsas_search_by_devhdl(tgttbl,
6445 				    dev_handle);
6446 				/*
6447 				 * If ptgt is NULL here, it means that the
6448 				 * DevHandle is not in the hash table.  This is
6449 				 * reasonable sometimes.  For example, if a
6450 				 * disk was pulled, then added, then pulled
6451 				 * again, the disk will not have been put into
6452 				 * the hash table because the add event will
6453 				 * have an invalid phymask.  BUT, this does not
6454 				 * mean that the DevHandle is invalid.  The
6455 				 * controller will still have a valid DevHandle
6456 				 * that must be removed.  To do this, use the
6457 				 * MPTSAS_TOPO_FLAG_REMOVE_HANDLE event.
6458 				 */
6459 				if (ptgt == NULL) {
6460 					topo_node = kmem_zalloc(
6461 					    sizeof (mptsas_topo_change_list_t),
6462 					    KM_SLEEP);
6463 					topo_node->mpt = mpt;
6464 					topo_node->un.phymask = 0;
6465 					topo_node->event =
6466 					    MPTSAS_TOPO_FLAG_REMOVE_HANDLE;
6467 					topo_node->devhdl = dev_handle;
6468 					topo_node->flags = flags;
6469 					topo_node->object = NULL;
6470 					if (topo_head == NULL) {
6471 						topo_head = topo_tail =
6472 						    topo_node;
6473 					} else {
6474 						topo_tail->next = topo_node;
6475 						topo_tail = topo_node;
6476 					}
6477 					break;
6478 				}
6479 
6480 				/*
6481 				 * Update DR flag immediately avoid I/O failure
6482 				 * before failover finish. Pay attention to the
6483 				 * mutex protect, we need grab m_tx_waitq_mutex
6484 				 * during set m_dr_flag because we won't add
6485 				 * the following command into waitq, instead,
6486 				 * we need return TRAN_BUSY in the tran_start
6487 				 * context.
6488 				 */
6489 				mutex_enter(&mpt->m_tx_waitq_mutex);
6490 				ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6491 				mutex_exit(&mpt->m_tx_waitq_mutex);
6492 
6493 				topo_node = kmem_zalloc(
6494 				    sizeof (mptsas_topo_change_list_t),
6495 				    KM_SLEEP);
6496 				topo_node->mpt = mpt;
6497 				topo_node->un.phymask = ptgt->m_phymask;
6498 				topo_node->event =
6499 				    MPTSAS_DR_EVENT_OFFLINE_TARGET;
6500 				topo_node->devhdl = dev_handle;
6501 				topo_node->flags = flags;
6502 				topo_node->object = NULL;
6503 				if (topo_head == NULL) {
6504 					topo_head = topo_tail = topo_node;
6505 				} else {
6506 					topo_tail->next = topo_node;
6507 					topo_tail = topo_node;
6508 				}
6509 
6510 				break;
6511 			}
6512 			case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
6513 				link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl,
6514 				    &sas_topo_change_list->PHY[i].LinkRate);
6515 				state = (link_rate &
6516 				    MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >>
6517 				    MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT;
6518 				switch (state) {
6519 				case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
6520 					(void) sprintf(curr, "is disabled");
6521 					break;
6522 				case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
6523 					(void) sprintf(curr, "is offline, "
6524 					    "failed speed negotiation");
6525 					break;
6526 				case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
6527 					(void) sprintf(curr, "SATA OOB "
6528 					    "complete");
6529 					break;
6530 				case SMP_RESET_IN_PROGRESS:
6531 					(void) sprintf(curr, "SMP reset in "
6532 					    "progress");
6533 					break;
6534 				case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
6535 					(void) sprintf(curr, "is online at "
6536 					    "1.5 Gbps");
6537 					if ((expd_handle == 0) &&
6538 					    (enc_handle == 1)) {
6539 						mpt->m_port_chng = 1;
6540 					}
6541 					break;
6542 				case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
6543 					(void) sprintf(curr, "is online at 3.0 "
6544 					    "Gbps");
6545 					if ((expd_handle == 0) &&
6546 					    (enc_handle == 1)) {
6547 						mpt->m_port_chng = 1;
6548 					}
6549 					break;
6550 				case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
6551 					(void) sprintf(curr, "is online at "
6552 					    "6.0 Gbps");
6553 					if ((expd_handle == 0) &&
6554 					    (enc_handle == 1)) {
6555 						mpt->m_port_chng = 1;
6556 					}
6557 					break;
6558 				default:
6559 					(void) sprintf(curr, "state is "
6560 					    "unknown");
6561 					break;
6562 				}
6563 
6564 				state = (link_rate &
6565 				    MPI2_EVENT_SAS_TOPO_LR_PREV_MASK) >>
6566 				    MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT;
6567 				switch (state) {
6568 				case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
6569 					(void) sprintf(prev, ", was disabled");
6570 					break;
6571 				case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
6572 					(void) sprintf(prev, ", was offline, "
6573 					    "failed speed negotiation");
6574 					break;
6575 				case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
6576 					(void) sprintf(prev, ", was SATA OOB "
6577 					    "complete");
6578 					break;
6579 				case SMP_RESET_IN_PROGRESS:
6580 					(void) sprintf(prev, ", was SMP reset "
6581 					    "in progress");
6582 					break;
6583 				case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
6584 					(void) sprintf(prev, ", was online at "
6585 					    "1.5 Gbps");
6586 					break;
6587 				case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
6588 					(void) sprintf(prev, ", was online at "
6589 					    "3.0 Gbps");
6590 					break;
6591 				case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
6592 					(void) sprintf(prev, ", was online at "
6593 					    "6.0 Gbps");
6594 					break;
6595 				default:
6596 				break;
6597 				}
6598 				(void) sprintf(&string[strlen(string)], "link "
6599 				    "changed, ");
6600 				break;
6601 			case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
6602 				continue;
6603 			case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
6604 				(void) sprintf(&string[strlen(string)],
6605 				    "target not responding, delaying "
6606 				    "removal");
6607 				break;
6608 			}
6609 			NDBG20(("mptsas%d phy %d DevHandle %x, %s%s%s\n",
6610 			    mpt->m_instance, phy, dev_handle, string, curr,
6611 			    prev));
6612 		}
6613 		if (topo_head != NULL) {
6614 			/*
6615 			 * Launch DR taskq to handle topology change
6616 			 */
6617 			if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
6618 			    mptsas_handle_dr, (void *)topo_head,
6619 			    DDI_NOSLEEP)) != DDI_SUCCESS) {
6620 				mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
6621 				    "for handle SAS DR event failed. \n");
6622 			}
6623 		}
6624 		break;
6625 	}
6626 	case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
6627 	{
6628 		Mpi2EventDataIrConfigChangeList_t	*irChangeList;
6629 		mptsas_topo_change_list_t		*topo_head = NULL;
6630 		mptsas_topo_change_list_t		*topo_tail = NULL;
6631 		mptsas_topo_change_list_t		*topo_node = NULL;
6632 		mptsas_target_t				*ptgt;
6633 		mptsas_hash_table_t			*tgttbl;
6634 		uint8_t					num_entries, i, reason;
6635 		uint16_t				volhandle, diskhandle;
6636 
6637 		irChangeList = (pMpi2EventDataIrConfigChangeList_t)
6638 		    eventreply->EventData;
6639 		num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
6640 		    &irChangeList->NumElements);
6641 
6642 		tgttbl = &mpt->m_active->m_tgttbl;
6643 
6644 		NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received",
6645 		    mpt->m_instance));
6646 
6647 		for (i = 0; i < num_entries; i++) {
6648 			reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
6649 			    &irChangeList->ConfigElement[i].ReasonCode);
6650 			volhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6651 			    &irChangeList->ConfigElement[i].VolDevHandle);
6652 			diskhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6653 			    &irChangeList->ConfigElement[i].PhysDiskDevHandle);
6654 
6655 			switch (reason) {
6656 			case MPI2_EVENT_IR_CHANGE_RC_ADDED:
6657 			case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
6658 			{
6659 				NDBG20(("mptsas %d volume added\n",
6660 				    mpt->m_instance));
6661 
6662 				topo_node = kmem_zalloc(
6663 				    sizeof (mptsas_topo_change_list_t),
6664 				    KM_SLEEP);
6665 
6666 				topo_node->mpt = mpt;
6667 				topo_node->event =
6668 				    MPTSAS_DR_EVENT_RECONFIG_TARGET;
6669 				topo_node->un.physport = 0xff;
6670 				topo_node->devhdl = volhandle;
6671 				topo_node->flags =
6672 				    MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
6673 				topo_node->object = NULL;
6674 				if (topo_head == NULL) {
6675 					topo_head = topo_tail = topo_node;
6676 				} else {
6677 					topo_tail->next = topo_node;
6678 					topo_tail = topo_node;
6679 				}
6680 				break;
6681 			}
6682 			case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
6683 			case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
6684 			{
6685 				NDBG20(("mptsas %d volume deleted\n",
6686 				    mpt->m_instance));
6687 				ptgt = mptsas_search_by_devhdl(tgttbl,
6688 				    volhandle);
6689 				if (ptgt == NULL)
6690 					break;
6691 
6692 				/*
6693 				 * Clear any flags related to volume
6694 				 */
6695 				(void) mptsas_delete_volume(mpt, volhandle);
6696 
6697 				/*
6698 				 * Update DR flag immediately avoid I/O failure
6699 				 */
6700 				mutex_enter(&mpt->m_tx_waitq_mutex);
6701 				ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6702 				mutex_exit(&mpt->m_tx_waitq_mutex);
6703 
6704 				topo_node = kmem_zalloc(
6705 				    sizeof (mptsas_topo_change_list_t),
6706 				    KM_SLEEP);
6707 				topo_node->mpt = mpt;
6708 				topo_node->un.phymask = ptgt->m_phymask;
6709 				topo_node->event =
6710 				    MPTSAS_DR_EVENT_OFFLINE_TARGET;
6711 				topo_node->devhdl = volhandle;
6712 				topo_node->flags =
6713 				    MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
6714 				topo_node->object = (void *)ptgt;
6715 				if (topo_head == NULL) {
6716 					topo_head = topo_tail = topo_node;
6717 				} else {
6718 					topo_tail->next = topo_node;
6719 					topo_tail = topo_node;
6720 				}
6721 				break;
6722 			}
6723 			case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
6724 			case MPI2_EVENT_IR_CHANGE_RC_HIDE:
6725 			{
6726 				ptgt = mptsas_search_by_devhdl(tgttbl,
6727 				    diskhandle);
6728 				if (ptgt == NULL)
6729 					break;
6730 
6731 				/*
6732 				 * Update DR flag immediately avoid I/O failure
6733 				 */
6734 				mutex_enter(&mpt->m_tx_waitq_mutex);
6735 				ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6736 				mutex_exit(&mpt->m_tx_waitq_mutex);
6737 
6738 				topo_node = kmem_zalloc(
6739 				    sizeof (mptsas_topo_change_list_t),
6740 				    KM_SLEEP);
6741 				topo_node->mpt = mpt;
6742 				topo_node->un.phymask = ptgt->m_phymask;
6743 				topo_node->event =
6744 				    MPTSAS_DR_EVENT_OFFLINE_TARGET;
6745 				topo_node->devhdl = diskhandle;
6746 				topo_node->flags =
6747 				    MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
6748 				topo_node->object = (void *)ptgt;
6749 				if (topo_head == NULL) {
6750 					topo_head = topo_tail = topo_node;
6751 				} else {
6752 					topo_tail->next = topo_node;
6753 					topo_tail = topo_node;
6754 				}
6755 				break;
6756 			}
6757 			case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
6758 			case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
6759 			{
6760 				/*
6761 				 * The physical drive is released by a IR
6762 				 * volume. But we cannot get the the physport
6763 				 * or phynum from the event data, so we only
6764 				 * can get the physport/phynum after SAS
6765 				 * Device Page0 request for the devhdl.
6766 				 */
6767 				topo_node = kmem_zalloc(
6768 				    sizeof (mptsas_topo_change_list_t),
6769 				    KM_SLEEP);
6770 				topo_node->mpt = mpt;
6771 				topo_node->un.phymask = 0;
6772 				topo_node->event =
6773 				    MPTSAS_DR_EVENT_RECONFIG_TARGET;
6774 				topo_node->devhdl = diskhandle;
6775 				topo_node->flags =
6776 				    MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
6777 				topo_node->object = NULL;
6778 				mpt->m_port_chng = 1;
6779 				if (topo_head == NULL) {
6780 					topo_head = topo_tail = topo_node;
6781 				} else {
6782 					topo_tail->next = topo_node;
6783 					topo_tail = topo_node;
6784 				}
6785 				break;
6786 			}
6787 			default:
6788 				break;
6789 			}
6790 		}
6791 
6792 		if (topo_head != NULL) {
6793 			/*
6794 			 * Launch DR taskq to handle topology change
6795 			 */
6796 			if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
6797 			    mptsas_handle_dr, (void *)topo_head,
6798 			    DDI_NOSLEEP)) != DDI_SUCCESS) {
6799 				mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
6800 				    "for handle SAS DR event failed. \n");
6801 			}
6802 		}
6803 		break;
6804 	}
6805 	default:
6806 		return (DDI_FAILURE);
6807 	}
6808 
6809 	return (DDI_SUCCESS);
6810 }
6811 
6812 /*
6813  * handle events from ioc
6814  */
6815 static void
6816 mptsas_handle_event(void *args)
6817 {
6818 	m_replyh_arg_t			*replyh_arg;
6819 	pMpi2EventNotificationReply_t	eventreply;
6820 	uint32_t			event, iocloginfo, rfm;
6821 	uint32_t			status;
6822 	uint8_t				port;
6823 	mptsas_t			*mpt;
6824 	uint_t				iocstatus;
6825 
6826 	replyh_arg = (m_replyh_arg_t *)args;
6827 	rfm = replyh_arg->rfm;
6828 	mpt = replyh_arg->mpt;
6829 
6830 	mutex_enter(&mpt->m_mutex);
6831 
6832 	eventreply = (pMpi2EventNotificationReply_t)
6833 	    (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr));
6834 	event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
6835 
6836 	if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
6837 	    &eventreply->IOCStatus)) {
6838 		if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
6839 			mptsas_log(mpt, CE_WARN,
6840 			    "!mptsas_handle_event: IOCStatus=0x%x, "
6841 			    "IOCLogInfo=0x%x", iocstatus,
6842 			    ddi_get32(mpt->m_acc_reply_frame_hdl,
6843 			    &eventreply->IOCLogInfo));
6844 		} else {
6845 			mptsas_log(mpt, CE_WARN,
6846 			    "mptsas_handle_event: IOCStatus=0x%x, "
6847 			    "IOCLogInfo=0x%x", iocstatus,
6848 			    ddi_get32(mpt->m_acc_reply_frame_hdl,
6849 			    &eventreply->IOCLogInfo));
6850 		}
6851 	}
6852 
6853 	/*
6854 	 * figure out what kind of event we got and handle accordingly
6855 	 */
6856 	switch (event) {
6857 	case MPI2_EVENT_LOG_ENTRY_ADDED:
6858 		break;
6859 	case MPI2_EVENT_LOG_DATA:
6860 		iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
6861 		    &eventreply->IOCLogInfo);
6862 		NDBG20(("mptsas %d log info %x received.\n", mpt->m_instance,
6863 		    iocloginfo));
6864 		break;
6865 	case MPI2_EVENT_STATE_CHANGE:
6866 		NDBG20(("mptsas%d state change.", mpt->m_instance));
6867 		break;
6868 	case MPI2_EVENT_HARD_RESET_RECEIVED:
6869 		NDBG20(("mptsas%d event change.", mpt->m_instance));
6870 		break;
6871 	case MPI2_EVENT_SAS_DISCOVERY:
6872 	{
6873 		MPI2_EVENT_DATA_SAS_DISCOVERY	*sasdiscovery;
6874 		char				string[80];
6875 		uint8_t				rc;
6876 
6877 		sasdiscovery =
6878 		    (pMpi2EventDataSasDiscovery_t)eventreply->EventData;
6879 
6880 		rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
6881 		    &sasdiscovery->ReasonCode);
6882 		port = ddi_get8(mpt->m_acc_reply_frame_hdl,
6883 		    &sasdiscovery->PhysicalPort);
6884 		status = ddi_get32(mpt->m_acc_reply_frame_hdl,
6885 		    &sasdiscovery->DiscoveryStatus);
6886 
6887 		string[0] = 0;
6888 		switch (rc) {
6889 		case MPI2_EVENT_SAS_DISC_RC_STARTED:
6890 			(void) sprintf(string, "STARTING");
6891 			break;
6892 		case MPI2_EVENT_SAS_DISC_RC_COMPLETED:
6893 			(void) sprintf(string, "COMPLETED");
6894 			break;
6895 		default:
6896 			(void) sprintf(string, "UNKNOWN");
6897 			break;
6898 		}
6899 
6900 		NDBG20(("SAS DISCOVERY is %s for port %d, status %x", string,
6901 		    port, status));
6902 
6903 		break;
6904 	}
6905 	case MPI2_EVENT_EVENT_CHANGE:
6906 		NDBG20(("mptsas%d event change.", mpt->m_instance));
6907 		break;
6908 	case MPI2_EVENT_TASK_SET_FULL:
6909 	{
6910 		pMpi2EventDataTaskSetFull_t	taskfull;
6911 
6912 		taskfull = (pMpi2EventDataTaskSetFull_t)eventreply->EventData;
6913 
6914 		NDBG20(("TASK_SET_FULL received for mptsas%d, depth %d\n",
6915 		    mpt->m_instance,  ddi_get16(mpt->m_acc_reply_frame_hdl,
6916 		    &taskfull->CurrentDepth)));
6917 		break;
6918 	}
6919 	case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
6920 	{
6921 		/*
6922 		 * SAS TOPOLOGY CHANGE LIST Event has already been handled
6923 		 * in mptsas_handle_event_sync() of interrupt context
6924 		 */
6925 		break;
6926 	}
6927 	case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
6928 	{
6929 		pMpi2EventDataSasEnclDevStatusChange_t	encstatus;
6930 		uint8_t					rc;
6931 		char					string[80];
6932 
6933 		encstatus = (pMpi2EventDataSasEnclDevStatusChange_t)
6934 		    eventreply->EventData;
6935 
6936 		rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
6937 		    &encstatus->ReasonCode);
6938 		switch (rc) {
6939 		case MPI2_EVENT_SAS_ENCL_RC_ADDED:
6940 			(void) sprintf(string, "added");
6941 			break;
6942 		case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING:
6943 			(void) sprintf(string, ", not responding");
6944 			break;
6945 		default:
6946 		break;
6947 		}
6948 		NDBG20(("mptsas%d ENCLOSURE STATUS CHANGE for enclosure %x%s\n",
6949 		    mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl,
6950 		    &encstatus->EnclosureHandle), string));
6951 		break;
6952 	}
6953 
6954 	/*
6955 	 * MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE is handled by
6956 	 * mptsas_handle_event_sync,in here just send ack message.
6957 	 */
6958 	case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
6959 	{
6960 		pMpi2EventDataSasDeviceStatusChange_t	statuschange;
6961 		uint8_t					rc;
6962 		uint16_t				devhdl;
6963 		uint64_t				wwn = 0;
6964 		uint32_t				wwn_lo, wwn_hi;
6965 
6966 		statuschange = (pMpi2EventDataSasDeviceStatusChange_t)
6967 		    eventreply->EventData;
6968 		rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
6969 		    &statuschange->ReasonCode);
6970 		wwn_lo = ddi_get32(mpt->m_acc_reply_frame_hdl,
6971 		    (uint32_t *)(void *)&statuschange->SASAddress);
6972 		wwn_hi = ddi_get32(mpt->m_acc_reply_frame_hdl,
6973 		    (uint32_t *)(void *)&statuschange->SASAddress + 1);
6974 		wwn = ((uint64_t)wwn_hi << 32) | wwn_lo;
6975 		devhdl =  ddi_get16(mpt->m_acc_reply_frame_hdl,
6976 		    &statuschange->DevHandle);
6977 
6978 		NDBG13(("MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE wwn is %"PRIx64,
6979 		    wwn));
6980 
6981 		switch (rc) {
6982 		case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6983 			NDBG20(("SMART data received, ASC/ASCQ = %02x/%02x",
6984 			    ddi_get8(mpt->m_acc_reply_frame_hdl,
6985 			    &statuschange->ASC),
6986 			    ddi_get8(mpt->m_acc_reply_frame_hdl,
6987 			    &statuschange->ASCQ)));
6988 			break;
6989 
6990 		case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6991 			NDBG20(("Device not supported"));
6992 			break;
6993 
6994 		case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6995 			NDBG20(("IOC internally generated the Target Reset "
6996 			    "for devhdl:%x", devhdl));
6997 			break;
6998 
6999 		case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET:
7000 			NDBG20(("IOC's internally generated Target Reset "
7001 			    "completed for devhdl:%x", devhdl));
7002 			break;
7003 
7004 		case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7005 			NDBG20(("IOC internally generated Abort Task"));
7006 			break;
7007 
7008 		case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL:
7009 			NDBG20(("IOC's internally generated Abort Task "
7010 			    "completed"));
7011 			break;
7012 
7013 		case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7014 			NDBG20(("IOC internally generated Abort Task Set"));
7015 			break;
7016 
7017 		case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7018 			NDBG20(("IOC internally generated Clear Task Set"));
7019 			break;
7020 
7021 		case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7022 			NDBG20(("IOC internally generated Query Task"));
7023 			break;
7024 
7025 		case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION:
7026 			NDBG20(("Device sent an Asynchronous Notification"));
7027 			break;
7028 
7029 		default:
7030 			break;
7031 		}
7032 		break;
7033 	}
7034 	case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
7035 	{
7036 		/*
7037 		 * IR TOPOLOGY CHANGE LIST Event has already been handled
7038 		 * in mpt_handle_event_sync() of interrupt context
7039 		 */
7040 		break;
7041 	}
7042 	case MPI2_EVENT_IR_OPERATION_STATUS:
7043 	{
7044 		Mpi2EventDataIrOperationStatus_t	*irOpStatus;
7045 		char					reason_str[80];
7046 		uint8_t					rc, percent;
7047 		uint16_t				handle;
7048 
7049 		irOpStatus = (pMpi2EventDataIrOperationStatus_t)
7050 		    eventreply->EventData;
7051 		rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
7052 		    &irOpStatus->RAIDOperation);
7053 		percent = ddi_get8(mpt->m_acc_reply_frame_hdl,
7054 		    &irOpStatus->PercentComplete);
7055 		handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7056 		    &irOpStatus->VolDevHandle);
7057 
7058 		switch (rc) {
7059 			case MPI2_EVENT_IR_RAIDOP_RESYNC:
7060 				(void) sprintf(reason_str, "resync");
7061 				break;
7062 			case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION:
7063 				(void) sprintf(reason_str, "online capacity "
7064 				    "expansion");
7065 				break;
7066 			case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK:
7067 				(void) sprintf(reason_str, "consistency check");
7068 				break;
7069 			default:
7070 				(void) sprintf(reason_str, "unknown reason %x",
7071 				    rc);
7072 		}
7073 
7074 		NDBG20(("mptsas%d raid operational status: (%s)"
7075 		    "\thandle(0x%04x), percent complete(%d)\n",
7076 		    mpt->m_instance, reason_str, handle, percent));
7077 		break;
7078 	}
7079 	case MPI2_EVENT_IR_VOLUME:
7080 	{
7081 		Mpi2EventDataIrVolume_t		*irVolume;
7082 		uint16_t			devhandle;
7083 		uint32_t			state;
7084 		int				config, vol;
7085 		mptsas_slots_t			*slots = mpt->m_active;
7086 		uint8_t				found = FALSE;
7087 
7088 		irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData;
7089 		state = ddi_get32(mpt->m_acc_reply_frame_hdl,
7090 		    &irVolume->NewValue);
7091 		devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7092 		    &irVolume->VolDevHandle);
7093 
7094 		NDBG20(("EVENT_IR_VOLUME event is received"));
7095 
7096 		/*
7097 		 * Get latest RAID info and then find the DevHandle for this
7098 		 * event in the configuration.  If the DevHandle is not found
7099 		 * just exit the event.
7100 		 */
7101 		(void) mptsas_get_raid_info(mpt);
7102 		for (config = 0; config < slots->m_num_raid_configs;
7103 		    config++) {
7104 			for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
7105 				if (slots->m_raidconfig[config].m_raidvol[vol].
7106 				    m_raidhandle == devhandle) {
7107 					found = TRUE;
7108 					break;
7109 				}
7110 			}
7111 		}
7112 		if (!found) {
7113 			break;
7114 		}
7115 
7116 		switch (irVolume->ReasonCode) {
7117 		case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED:
7118 		{
7119 			uint32_t i;
7120 			slots->m_raidconfig[config].m_raidvol[vol].m_settings =
7121 			    state;
7122 
7123 			i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING;
7124 			mptsas_log(mpt, CE_NOTE, " Volume %d settings changed"
7125 			    ", auto-config of hot-swap drives is %s"
7126 			    ", write caching is %s"
7127 			    ", hot-spare pool mask is %02x\n",
7128 			    vol, state &
7129 			    MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE
7130 			    ? "disabled" : "enabled",
7131 			    i == MPI2_RAIDVOL0_SETTING_UNCHANGED
7132 			    ? "controlled by member disks" :
7133 			    i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING
7134 			    ? "disabled" :
7135 			    i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING
7136 			    ? "enabled" :
7137 			    "incorrectly set",
7138 			    (state >> 16) & 0xff);
7139 				break;
7140 		}
7141 		case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED:
7142 		{
7143 			slots->m_raidconfig[config].m_raidvol[vol].m_state =
7144 			    (uint8_t)state;
7145 
7146 			mptsas_log(mpt, CE_NOTE,
7147 			    "Volume %d is now %s\n", vol,
7148 			    state == MPI2_RAID_VOL_STATE_OPTIMAL
7149 			    ? "optimal" :
7150 			    state == MPI2_RAID_VOL_STATE_DEGRADED
7151 			    ? "degraded" :
7152 			    state == MPI2_RAID_VOL_STATE_ONLINE
7153 			    ? "online" :
7154 			    state == MPI2_RAID_VOL_STATE_INITIALIZING
7155 			    ? "initializing" :
7156 			    state == MPI2_RAID_VOL_STATE_FAILED
7157 			    ? "failed" :
7158 			    state == MPI2_RAID_VOL_STATE_MISSING
7159 			    ? "missing" :
7160 			    "state unknown");
7161 			break;
7162 		}
7163 		case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED:
7164 		{
7165 			slots->m_raidconfig[config].m_raidvol[vol].
7166 			    m_statusflags = state;
7167 
7168 			mptsas_log(mpt, CE_NOTE,
7169 			    " Volume %d is now %s%s%s%s%s%s%s%s%s\n",
7170 			    vol,
7171 			    state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED
7172 			    ? ", enabled" : ", disabled",
7173 			    state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED
7174 			    ? ", quiesced" : "",
7175 			    state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
7176 			    ? ", inactive" : ", active",
7177 			    state &
7178 			    MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL
7179 			    ? ", bad block table is full" : "",
7180 			    state &
7181 			    MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
7182 			    ? ", resync in progress" : "",
7183 			    state & MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT
7184 			    ? ", background initialization in progress" : "",
7185 			    state &
7186 			    MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION
7187 			    ? ", capacity expansion in progress" : "",
7188 			    state &
7189 			    MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK
7190 			    ? ", consistency check in progress" : "",
7191 			    state & MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB
7192 			    ? ", data scrub in progress" : "");
7193 			break;
7194 		}
7195 		default:
7196 			break;
7197 		}
7198 		break;
7199 	}
7200 	case MPI2_EVENT_IR_PHYSICAL_DISK:
7201 	{
7202 		Mpi2EventDataIrPhysicalDisk_t	*irPhysDisk;
7203 		uint16_t			devhandle, enchandle, slot;
7204 		uint32_t			status, state;
7205 		uint8_t				physdisknum, reason;
7206 
7207 		irPhysDisk = (Mpi2EventDataIrPhysicalDisk_t *)
7208 		    eventreply->EventData;
7209 		physdisknum = ddi_get8(mpt->m_acc_reply_frame_hdl,
7210 		    &irPhysDisk->PhysDiskNum);
7211 		devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7212 		    &irPhysDisk->PhysDiskDevHandle);
7213 		enchandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7214 		    &irPhysDisk->EnclosureHandle);
7215 		slot = ddi_get16(mpt->m_acc_reply_frame_hdl,
7216 		    &irPhysDisk->Slot);
7217 		state = ddi_get32(mpt->m_acc_reply_frame_hdl,
7218 		    &irPhysDisk->NewValue);
7219 		reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
7220 		    &irPhysDisk->ReasonCode);
7221 
7222 		NDBG20(("EVENT_IR_PHYSICAL_DISK event is received"));
7223 
7224 		switch (reason) {
7225 		case MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED:
7226 			mptsas_log(mpt, CE_NOTE,
7227 			    " PhysDiskNum %d with DevHandle 0x%x in slot %d "
7228 			    "for enclosure with handle 0x%x is now in hot "
7229 			    "spare pool %d",
7230 			    physdisknum, devhandle, slot, enchandle,
7231 			    (state >> 16) & 0xff);
7232 			break;
7233 
7234 		case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED:
7235 			status = state;
7236 			mptsas_log(mpt, CE_NOTE,
7237 			    " PhysDiskNum %d with DevHandle 0x%x in slot %d "
7238 			    "for enclosure with handle 0x%x is now "
7239 			    "%s%s%s%s%s\n", physdisknum, devhandle, slot,
7240 			    enchandle,
7241 			    status & MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME
7242 			    ? ", inactive" : ", active",
7243 			    status & MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
7244 			    ? ", out of sync" : "",
7245 			    status & MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED
7246 			    ? ", quiesced" : "",
7247 			    status &
7248 			    MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED
7249 			    ? ", write cache enabled" : "",
7250 			    status & MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET
7251 			    ? ", capacity expansion target" : "");
7252 			break;
7253 
7254 		case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED:
7255 			mptsas_log(mpt, CE_NOTE,
7256 			    " PhysDiskNum %d with DevHandle 0x%x in slot %d "
7257 			    "for enclosure with handle 0x%x is now %s\n",
7258 			    physdisknum, devhandle, slot, enchandle,
7259 			    state == MPI2_RAID_PD_STATE_OPTIMAL
7260 			    ? "optimal" :
7261 			    state == MPI2_RAID_PD_STATE_REBUILDING
7262 			    ? "rebuilding" :
7263 			    state == MPI2_RAID_PD_STATE_DEGRADED
7264 			    ? "degraded" :
7265 			    state == MPI2_RAID_PD_STATE_HOT_SPARE
7266 			    ? "a hot spare" :
7267 			    state == MPI2_RAID_PD_STATE_ONLINE
7268 			    ? "online" :
7269 			    state == MPI2_RAID_PD_STATE_OFFLINE
7270 			    ? "offline" :
7271 			    state == MPI2_RAID_PD_STATE_NOT_COMPATIBLE
7272 			    ? "not compatible" :
7273 			    state == MPI2_RAID_PD_STATE_NOT_CONFIGURED
7274 			    ? "not configured" :
7275 			    "state unknown");
7276 			break;
7277 		}
7278 		break;
7279 	}
7280 	default:
7281 		NDBG20(("mptsas%d: unknown event %x received",
7282 		    mpt->m_instance, event));
7283 		break;
7284 	}
7285 
7286 	/*
7287 	 * Return the reply frame to the free queue.
7288 	 */
7289 	ddi_put32(mpt->m_acc_free_queue_hdl,
7290 	    &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], rfm);
7291 	(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
7292 	    DDI_DMA_SYNC_FORDEV);
7293 	if (++mpt->m_free_index == mpt->m_free_queue_depth) {
7294 		mpt->m_free_index = 0;
7295 	}
7296 	ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
7297 	    mpt->m_free_index);
7298 	mutex_exit(&mpt->m_mutex);
7299 }
7300 
7301 /*
7302  * invoked from timeout() to restart qfull cmds with throttle == 0
7303  */
7304 static void
7305 mptsas_restart_cmd(void *arg)
7306 {
7307 	mptsas_t	*mpt = arg;
7308 	mptsas_target_t	*ptgt = NULL;
7309 
7310 	mutex_enter(&mpt->m_mutex);
7311 
7312 	mpt->m_restart_cmd_timeid = 0;
7313 
7314 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
7315 	    MPTSAS_HASH_FIRST);
7316 	while (ptgt != NULL) {
7317 		if (ptgt->m_reset_delay == 0) {
7318 			if (ptgt->m_t_throttle == QFULL_THROTTLE) {
7319 				mptsas_set_throttle(mpt, ptgt,
7320 				    MAX_THROTTLE);
7321 			}
7322 		}
7323 
7324 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
7325 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
7326 	}
7327 	mptsas_restart_hba(mpt);
7328 	mutex_exit(&mpt->m_mutex);
7329 }
7330 
7331 void
7332 mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
7333 {
7334 	int		slot;
7335 	mptsas_slots_t	*slots = mpt->m_active;
7336 	int		t;
7337 	mptsas_target_t	*ptgt = cmd->cmd_tgt_addr;
7338 
7339 	ASSERT(cmd != NULL);
7340 	ASSERT(cmd->cmd_queued == FALSE);
7341 
7342 	/*
7343 	 * Task Management cmds are removed in their own routines.  Also,
7344 	 * we don't want to modify timeout based on TM cmds.
7345 	 */
7346 	if (cmd->cmd_flags & CFLAG_TM_CMD) {
7347 		return;
7348 	}
7349 
7350 	t = Tgt(cmd);
7351 	slot = cmd->cmd_slot;
7352 
7353 	/*
7354 	 * remove the cmd.
7355 	 */
7356 	if (cmd == slots->m_slot[slot]) {
7357 		NDBG31(("mptsas_remove_cmd: removing cmd=0x%p", (void *)cmd));
7358 		slots->m_slot[slot] = NULL;
7359 		mpt->m_ncmds--;
7360 
7361 		/*
7362 		 * only decrement per target ncmds if command
7363 		 * has a target associated with it.
7364 		 */
7365 		if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
7366 			ptgt->m_t_ncmds--;
7367 			/*
7368 			 * reset throttle if we just ran an untagged command
7369 			 * to a tagged target
7370 			 */
7371 			if ((ptgt->m_t_ncmds == 0) &&
7372 			    ((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0)) {
7373 				mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
7374 			}
7375 		}
7376 
7377 	}
7378 
7379 	/*
7380 	 * This is all we need to do for ioc commands.
7381 	 */
7382 	if (cmd->cmd_flags & CFLAG_CMDIOC) {
7383 		mptsas_return_to_pool(mpt, cmd);
7384 		return;
7385 	}
7386 
7387 	/*
7388 	 * Figure out what to set tag Q timeout for...
7389 	 *
7390 	 * Optimize: If we have duplicate's of same timeout
7391 	 * we're using, then we'll use it again until we run
7392 	 * out of duplicates.  This should be the normal case
7393 	 * for block and raw I/O.
7394 	 * If no duplicates, we have to scan through tag que and
7395 	 * find the longest timeout value and use it.  This is
7396 	 * going to take a while...
7397 	 * Add 1 to m_n_slots to account for TM request.
7398 	 */
7399 	if (cmd->cmd_pkt->pkt_time == ptgt->m_timebase) {
7400 		if (--(ptgt->m_dups) == 0) {
7401 			if (ptgt->m_t_ncmds) {
7402 				mptsas_cmd_t *ssp;
7403 				uint_t n = 0;
7404 				ushort_t nslots = (slots->m_n_slots + 1);
7405 				ushort_t i;
7406 				/*
7407 				 * This crude check assumes we don't do
7408 				 * this too often which seems reasonable
7409 				 * for block and raw I/O.
7410 				 */
7411 				for (i = 0; i < nslots; i++) {
7412 					ssp = slots->m_slot[i];
7413 					if (ssp && (Tgt(ssp) == t) &&
7414 					    (ssp->cmd_pkt->pkt_time > n)) {
7415 						n = ssp->cmd_pkt->pkt_time;
7416 						ptgt->m_dups = 1;
7417 					} else if (ssp && (Tgt(ssp) == t) &&
7418 					    (ssp->cmd_pkt->pkt_time == n)) {
7419 						ptgt->m_dups++;
7420 					}
7421 				}
7422 				ptgt->m_timebase = n;
7423 			} else {
7424 				ptgt->m_dups = 0;
7425 				ptgt->m_timebase = 0;
7426 			}
7427 		}
7428 	}
7429 	ptgt->m_timeout = ptgt->m_timebase;
7430 
7431 	ASSERT(cmd != slots->m_slot[cmd->cmd_slot]);
7432 }
7433 
7434 /*
7435  * accept all cmds on the tx_waitq if any and then
7436  * start a fresh request from the top of the device queue.
7437  *
7438  * since there are always cmds queued on the tx_waitq, and rare cmds on
7439  * the instance waitq, so this function should not be invoked in the ISR,
7440  * the mptsas_restart_waitq() is invoked in the ISR instead. otherwise, the
7441  * burden belongs to the IO dispatch CPUs is moved the interrupt CPU.
7442  */
7443 static void
7444 mptsas_restart_hba(mptsas_t *mpt)
7445 {
7446 	ASSERT(mutex_owned(&mpt->m_mutex));
7447 
7448 	mutex_enter(&mpt->m_tx_waitq_mutex);
7449 	if (mpt->m_tx_waitq) {
7450 		mptsas_accept_tx_waitq(mpt);
7451 	}
7452 	mutex_exit(&mpt->m_tx_waitq_mutex);
7453 	mptsas_restart_waitq(mpt);
7454 }
7455 
7456 /*
7457  * start a fresh request from the top of the device queue
7458  */
7459 static void
7460 mptsas_restart_waitq(mptsas_t *mpt)
7461 {
7462 	mptsas_cmd_t	*cmd, *next_cmd;
7463 	mptsas_target_t *ptgt = NULL;
7464 
7465 	NDBG1(("mptsas_restart_waitq: mpt=0x%p", (void *)mpt));
7466 
7467 	ASSERT(mutex_owned(&mpt->m_mutex));
7468 
7469 	/*
7470 	 * If there is a reset delay, don't start any cmds.  Otherwise, start
7471 	 * as many cmds as possible.
7472 	 * Since SMID 0 is reserved and the TM slot is reserved, the actual max
7473 	 * commands is m_max_requests - 2.
7474 	 */
7475 	cmd = mpt->m_waitq;
7476 
7477 	while (cmd != NULL) {
7478 		next_cmd = cmd->cmd_linkp;
7479 		if (cmd->cmd_flags & CFLAG_PASSTHRU) {
7480 			if (mptsas_save_cmd(mpt, cmd) == TRUE) {
7481 				/*
7482 				 * passthru command get slot need
7483 				 * set CFLAG_PREPARED.
7484 				 */
7485 				cmd->cmd_flags |= CFLAG_PREPARED;
7486 				mptsas_waitq_delete(mpt, cmd);
7487 				mptsas_start_passthru(mpt, cmd);
7488 			}
7489 			cmd = next_cmd;
7490 			continue;
7491 		}
7492 		if (cmd->cmd_flags & CFLAG_CONFIG) {
7493 			if (mptsas_save_cmd(mpt, cmd) == TRUE) {
7494 				/*
7495 				 * Send the config page request and delete it
7496 				 * from the waitq.
7497 				 */
7498 				cmd->cmd_flags |= CFLAG_PREPARED;
7499 				mptsas_waitq_delete(mpt, cmd);
7500 				mptsas_start_config_page_access(mpt, cmd);
7501 			}
7502 			cmd = next_cmd;
7503 			continue;
7504 		}
7505 		if (cmd->cmd_flags & CFLAG_FW_DIAG) {
7506 			if (mptsas_save_cmd(mpt, cmd) == TRUE) {
7507 				/*
7508 				 * Send the FW Diag request and delete if from
7509 				 * the waitq.
7510 				 */
7511 				cmd->cmd_flags |= CFLAG_PREPARED;
7512 				mptsas_waitq_delete(mpt, cmd);
7513 				mptsas_start_diag(mpt, cmd);
7514 			}
7515 			cmd = next_cmd;
7516 			continue;
7517 		}
7518 
7519 		ptgt = cmd->cmd_tgt_addr;
7520 		if (ptgt && (ptgt->m_t_throttle == DRAIN_THROTTLE) &&
7521 		    (ptgt->m_t_ncmds == 0)) {
7522 			mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
7523 		}
7524 		if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) &&
7525 		    (ptgt && (ptgt->m_reset_delay == 0)) &&
7526 		    (ptgt && (ptgt->m_t_ncmds <
7527 		    ptgt->m_t_throttle))) {
7528 			if (mptsas_save_cmd(mpt, cmd) == TRUE) {
7529 				mptsas_waitq_delete(mpt, cmd);
7530 				(void) mptsas_start_cmd(mpt, cmd);
7531 			}
7532 		}
7533 		cmd = next_cmd;
7534 	}
7535 }
7536 /*
7537  * Cmds are queued if tran_start() doesn't get the m_mutexlock(no wait).
7538  * Accept all those queued cmds before new cmd is accept so that the
7539  * cmds are sent in order.
7540  */
7541 static void
7542 mptsas_accept_tx_waitq(mptsas_t *mpt)
7543 {
7544 	mptsas_cmd_t *cmd;
7545 
7546 	ASSERT(mutex_owned(&mpt->m_mutex));
7547 	ASSERT(mutex_owned(&mpt->m_tx_waitq_mutex));
7548 
7549 	/*
7550 	 * A Bus Reset could occur at any time and flush the tx_waitq,
7551 	 * so we cannot count on the tx_waitq to contain even one cmd.
7552 	 * And when the m_tx_waitq_mutex is released and run
7553 	 * mptsas_accept_pkt(), the tx_waitq may be flushed.
7554 	 */
7555 	cmd = mpt->m_tx_waitq;
7556 	for (;;) {
7557 		if ((cmd = mpt->m_tx_waitq) == NULL) {
7558 			mpt->m_tx_draining = 0;
7559 			break;
7560 		}
7561 		if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) {
7562 			mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
7563 		}
7564 		cmd->cmd_linkp = NULL;
7565 		mutex_exit(&mpt->m_tx_waitq_mutex);
7566 		if (mptsas_accept_pkt(mpt, cmd) != TRAN_ACCEPT)
7567 			cmn_err(CE_WARN, "mpt: mptsas_accept_tx_waitq: failed "
7568 			    "to accept cmd on queue\n");
7569 		mutex_enter(&mpt->m_tx_waitq_mutex);
7570 	}
7571 }
7572 
7573 
7574 /*
7575  * mpt tag type lookup
7576  */
7577 static char mptsas_tag_lookup[] =
7578 	{0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG};
7579 
7580 static int
7581 mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
7582 {
7583 	struct scsi_pkt		*pkt = CMD2PKT(cmd);
7584 	uint32_t		control = 0;
7585 	int			n;
7586 	caddr_t			mem;
7587 	pMpi2SCSIIORequest_t	io_request;
7588 	ddi_dma_handle_t	dma_hdl = mpt->m_dma_req_frame_hdl;
7589 	ddi_acc_handle_t	acc_hdl = mpt->m_acc_req_frame_hdl;
7590 	mptsas_target_t		*ptgt = cmd->cmd_tgt_addr;
7591 	uint16_t		SMID, io_flags = 0;
7592 	uint32_t		request_desc_low, request_desc_high;
7593 
7594 	NDBG1(("mptsas_start_cmd: cmd=0x%p", (void *)cmd));
7595 
7596 	/*
7597 	 * Set SMID and increment index.  Rollover to 1 instead of 0 if index
7598 	 * is at the max.  0 is an invalid SMID, so we call the first index 1.
7599 	 */
7600 	SMID = cmd->cmd_slot;
7601 
7602 	/*
7603 	 * It is possible for back to back device reset to
7604 	 * happen before the reset delay has expired.  That's
7605 	 * ok, just let the device reset go out on the bus.
7606 	 */
7607 	if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) {
7608 		ASSERT(ptgt->m_reset_delay == 0);
7609 	}
7610 
7611 	/*
7612 	 * if a non-tagged cmd is submitted to an active tagged target
7613 	 * then drain before submitting this cmd; SCSI-2 allows RQSENSE
7614 	 * to be untagged
7615 	 */
7616 	if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) &&
7617 	    (ptgt->m_t_ncmds > 1) &&
7618 	    ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) &&
7619 	    (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) {
7620 		if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) {
7621 			NDBG23(("target=%d, untagged cmd, start draining\n",
7622 			    ptgt->m_devhdl));
7623 
7624 			if (ptgt->m_reset_delay == 0) {
7625 				mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
7626 			}
7627 
7628 			mptsas_remove_cmd(mpt, cmd);
7629 			cmd->cmd_pkt_flags |= FLAG_HEAD;
7630 			mptsas_waitq_add(mpt, cmd);
7631 		}
7632 		return (DDI_FAILURE);
7633 	}
7634 
7635 	/*
7636 	 * Set correct tag bits.
7637 	 */
7638 	if (cmd->cmd_pkt_flags & FLAG_TAGMASK) {
7639 		switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags &
7640 		    FLAG_TAGMASK) >> 12)]) {
7641 		case MSG_SIMPLE_QTAG:
7642 			control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
7643 			break;
7644 		case MSG_HEAD_QTAG:
7645 			control |= MPI2_SCSIIO_CONTROL_HEADOFQ;
7646 			break;
7647 		case MSG_ORDERED_QTAG:
7648 			control |= MPI2_SCSIIO_CONTROL_ORDEREDQ;
7649 			break;
7650 		default:
7651 			mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n");
7652 			break;
7653 		}
7654 	} else {
7655 		if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) {
7656 				ptgt->m_t_throttle = 1;
7657 		}
7658 		control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
7659 	}
7660 
7661 	if (cmd->cmd_pkt_flags & FLAG_TLR) {
7662 		control |= MPI2_SCSIIO_CONTROL_TLR_ON;
7663 	}
7664 
7665 	mem = mpt->m_req_frame + (mpt->m_req_frame_size * SMID);
7666 	io_request = (pMpi2SCSIIORequest_t)mem;
7667 
7668 	bzero(io_request, sizeof (Mpi2SCSIIORequest_t));
7669 	ddi_put8(acc_hdl, &io_request->SGLOffset0, offsetof
7670 	    (MPI2_SCSI_IO_REQUEST, SGL) / 4);
7671 	mptsas_init_std_hdr(acc_hdl, io_request, ptgt->m_devhdl, Lun(cmd), 0,
7672 	    MPI2_FUNCTION_SCSI_IO_REQUEST);
7673 
7674 	(void) ddi_rep_put8(acc_hdl, (uint8_t *)pkt->pkt_cdbp,
7675 	    io_request->CDB.CDB32, cmd->cmd_cdblen, DDI_DEV_AUTOINCR);
7676 
7677 	io_flags = cmd->cmd_cdblen;
7678 	ddi_put16(acc_hdl, &io_request->IoFlags, io_flags);
7679 	/*
7680 	 * setup the Scatter/Gather DMA list for this request
7681 	 */
7682 	if (cmd->cmd_cookiec > 0) {
7683 		mptsas_sge_setup(mpt, cmd, &control, io_request, acc_hdl);
7684 	} else {
7685 		ddi_put32(acc_hdl, &io_request->SGL.MpiSimple.FlagsLength,
7686 		    ((uint32_t)MPI2_SGE_FLAGS_LAST_ELEMENT |
7687 		    MPI2_SGE_FLAGS_END_OF_BUFFER |
7688 		    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
7689 		    MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
7690 	}
7691 
7692 	/*
7693 	 * save ARQ information
7694 	 */
7695 	ddi_put8(acc_hdl, &io_request->SenseBufferLength, cmd->cmd_rqslen);
7696 	if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) ==
7697 	    (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) {
7698 		ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress,
7699 		    cmd->cmd_ext_arqcookie.dmac_address);
7700 	} else {
7701 		ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress,
7702 		    cmd->cmd_arqcookie.dmac_address);
7703 	}
7704 
7705 	ddi_put32(acc_hdl, &io_request->Control, control);
7706 
7707 	NDBG31(("starting message=0x%p, with cmd=0x%p",
7708 	    (void *)(uintptr_t)mpt->m_req_frame_dma_addr, (void *)cmd));
7709 
7710 	(void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
7711 
7712 	/*
7713 	 * Build request descriptor and write it to the request desc post reg.
7714 	 */
7715 	request_desc_low = (SMID << 16) + MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
7716 	request_desc_high = ptgt->m_devhdl << 16;
7717 	MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high);
7718 
7719 	/*
7720 	 * Start timeout.
7721 	 */
7722 #ifdef MPTSAS_TEST
7723 	/*
7724 	 * Temporarily set timebase = 0;  needed for
7725 	 * timeout torture test.
7726 	 */
7727 	if (mptsas_test_timeouts) {
7728 		ptgt->m_timebase = 0;
7729 	}
7730 #endif
7731 	n = pkt->pkt_time - ptgt->m_timebase;
7732 
7733 	if (n == 0) {
7734 		(ptgt->m_dups)++;
7735 		ptgt->m_timeout = ptgt->m_timebase;
7736 	} else if (n > 0) {
7737 		ptgt->m_timeout =
7738 		    ptgt->m_timebase = pkt->pkt_time;
7739 		ptgt->m_dups = 1;
7740 	} else if (n < 0) {
7741 		ptgt->m_timeout = ptgt->m_timebase;
7742 	}
7743 #ifdef MPTSAS_TEST
7744 	/*
7745 	 * Set back to a number higher than
7746 	 * mptsas_scsi_watchdog_tick
7747 	 * so timeouts will happen in mptsas_watchsubr
7748 	 */
7749 	if (mptsas_test_timeouts) {
7750 		ptgt->m_timebase = 60;
7751 	}
7752 #endif
7753 
7754 	if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
7755 	    (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
7756 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
7757 		return (DDI_FAILURE);
7758 	}
7759 	return (DDI_SUCCESS);
7760 }
7761 
7762 /*
7763  * Select a helper thread to handle current doneq
7764  */
7765 static void
7766 mptsas_deliver_doneq_thread(mptsas_t *mpt)
7767 {
7768 	uint64_t			t, i;
7769 	uint32_t			min = 0xffffffff;
7770 	mptsas_doneq_thread_list_t	*item;
7771 
7772 	for (i = 0; i < mpt->m_doneq_thread_n; i++) {
7773 		item = &mpt->m_doneq_thread_id[i];
7774 		/*
7775 		 * If the completed command on help thread[i] less than
7776 		 * doneq_thread_threshold, then pick the thread[i]. Otherwise
7777 		 * pick a thread which has least completed command.
7778 		 */
7779 
7780 		mutex_enter(&item->mutex);
7781 		if (item->len < mpt->m_doneq_thread_threshold) {
7782 			t = i;
7783 			mutex_exit(&item->mutex);
7784 			break;
7785 		}
7786 		if (item->len < min) {
7787 			min = item->len;
7788 			t = i;
7789 		}
7790 		mutex_exit(&item->mutex);
7791 	}
7792 	mutex_enter(&mpt->m_doneq_thread_id[t].mutex);
7793 	mptsas_doneq_mv(mpt, t);
7794 	cv_signal(&mpt->m_doneq_thread_id[t].cv);
7795 	mutex_exit(&mpt->m_doneq_thread_id[t].mutex);
7796 }
7797 
7798 /*
7799  * move the current global doneq to the doneq of thead[t]
7800  */
7801 static void
7802 mptsas_doneq_mv(mptsas_t *mpt, uint64_t t)
7803 {
7804 	mptsas_cmd_t			*cmd;
7805 	mptsas_doneq_thread_list_t	*item = &mpt->m_doneq_thread_id[t];
7806 
7807 	ASSERT(mutex_owned(&item->mutex));
7808 	while ((cmd = mpt->m_doneq) != NULL) {
7809 		if ((mpt->m_doneq = cmd->cmd_linkp) == NULL) {
7810 			mpt->m_donetail = &mpt->m_doneq;
7811 		}
7812 		cmd->cmd_linkp = NULL;
7813 		*item->donetail = cmd;
7814 		item->donetail = &cmd->cmd_linkp;
7815 		mpt->m_doneq_len--;
7816 		item->len++;
7817 	}
7818 }
7819 
7820 void
7821 mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd)
7822 {
7823 	struct scsi_pkt	*pkt = CMD2PKT(cmd);
7824 
7825 	/* Check all acc and dma handles */
7826 	if ((mptsas_check_acc_handle(mpt->m_datap) !=
7827 	    DDI_SUCCESS) ||
7828 	    (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
7829 	    DDI_SUCCESS) ||
7830 	    (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) !=
7831 	    DDI_SUCCESS) ||
7832 	    (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) !=
7833 	    DDI_SUCCESS) ||
7834 	    (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) !=
7835 	    DDI_SUCCESS) ||
7836 	    (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) !=
7837 	    DDI_SUCCESS) ||
7838 	    (mptsas_check_acc_handle(mpt->m_config_handle) !=
7839 	    DDI_SUCCESS)) {
7840 		ddi_fm_service_impact(mpt->m_dip,
7841 		    DDI_SERVICE_UNAFFECTED);
7842 		ddi_fm_acc_err_clear(mpt->m_config_handle,
7843 		    DDI_FME_VER0);
7844 		pkt->pkt_reason = CMD_TRAN_ERR;
7845 		pkt->pkt_statistics = 0;
7846 	}
7847 	if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
7848 	    DDI_SUCCESS) ||
7849 	    (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) !=
7850 	    DDI_SUCCESS) ||
7851 	    (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) !=
7852 	    DDI_SUCCESS) ||
7853 	    (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) !=
7854 	    DDI_SUCCESS) ||
7855 	    (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) !=
7856 	    DDI_SUCCESS)) {
7857 		ddi_fm_service_impact(mpt->m_dip,
7858 		    DDI_SERVICE_UNAFFECTED);
7859 		pkt->pkt_reason = CMD_TRAN_ERR;
7860 		pkt->pkt_statistics = 0;
7861 	}
7862 	if (cmd->cmd_dmahandle &&
7863 	    (mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS)) {
7864 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
7865 		pkt->pkt_reason = CMD_TRAN_ERR;
7866 		pkt->pkt_statistics = 0;
7867 	}
7868 	if ((cmd->cmd_extra_frames &&
7869 	    ((mptsas_check_dma_handle(cmd->cmd_extra_frames->m_dma_hdl) !=
7870 	    DDI_SUCCESS) ||
7871 	    (mptsas_check_acc_handle(cmd->cmd_extra_frames->m_acc_hdl) !=
7872 	    DDI_SUCCESS)))) {
7873 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
7874 		pkt->pkt_reason = CMD_TRAN_ERR;
7875 		pkt->pkt_statistics = 0;
7876 	}
7877 	if (cmd->cmd_arqhandle &&
7878 	    (mptsas_check_dma_handle(cmd->cmd_arqhandle) != DDI_SUCCESS)) {
7879 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
7880 		pkt->pkt_reason = CMD_TRAN_ERR;
7881 		pkt->pkt_statistics = 0;
7882 	}
7883 	if (cmd->cmd_ext_arqhandle &&
7884 	    (mptsas_check_dma_handle(cmd->cmd_ext_arqhandle) != DDI_SUCCESS)) {
7885 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
7886 		pkt->pkt_reason = CMD_TRAN_ERR;
7887 		pkt->pkt_statistics = 0;
7888 	}
7889 }
7890 
7891 /*
7892  * These routines manipulate the queue of commands that
7893  * are waiting for their completion routines to be called.
7894  * The queue is usually in FIFO order but on an MP system
7895  * it's possible for the completion routines to get out
7896  * of order. If that's a problem you need to add a global
7897  * mutex around the code that calls the completion routine
7898  * in the interrupt handler.
7899  */
7900 static void
7901 mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd)
7902 {
7903 	struct scsi_pkt	*pkt = CMD2PKT(cmd);
7904 
7905 	NDBG31(("mptsas_doneq_add: cmd=0x%p", (void *)cmd));
7906 
7907 	ASSERT((cmd->cmd_flags & CFLAG_COMPLETED) == 0);
7908 	cmd->cmd_linkp = NULL;
7909 	cmd->cmd_flags |= CFLAG_FINISHED;
7910 	cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT;
7911 
7912 	mptsas_fma_check(mpt, cmd);
7913 
7914 	/*
7915 	 * only add scsi pkts that have completion routines to
7916 	 * the doneq.  no intr cmds do not have callbacks.
7917 	 */
7918 	if (pkt && (pkt->pkt_comp)) {
7919 		*mpt->m_donetail = cmd;
7920 		mpt->m_donetail = &cmd->cmd_linkp;
7921 		mpt->m_doneq_len++;
7922 	}
7923 }
7924 
7925 static mptsas_cmd_t *
7926 mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t)
7927 {
7928 	mptsas_cmd_t			*cmd;
7929 	mptsas_doneq_thread_list_t	*item = &mpt->m_doneq_thread_id[t];
7930 
7931 	/* pop one off the done queue */
7932 	if ((cmd = item->doneq) != NULL) {
7933 		/* if the queue is now empty fix the tail pointer */
7934 		NDBG31(("mptsas_doneq_thread_rm: cmd=0x%p", (void *)cmd));
7935 		if ((item->doneq = cmd->cmd_linkp) == NULL) {
7936 			item->donetail = &item->doneq;
7937 		}
7938 		cmd->cmd_linkp = NULL;
7939 		item->len--;
7940 	}
7941 	return (cmd);
7942 }
7943 
7944 static void
7945 mptsas_doneq_empty(mptsas_t *mpt)
7946 {
7947 	if (mpt->m_doneq && !mpt->m_in_callback) {
7948 		mptsas_cmd_t	*cmd, *next;
7949 		struct scsi_pkt *pkt;
7950 
7951 		mpt->m_in_callback = 1;
7952 		cmd = mpt->m_doneq;
7953 		mpt->m_doneq = NULL;
7954 		mpt->m_donetail = &mpt->m_doneq;
7955 		mpt->m_doneq_len = 0;
7956 
7957 		mutex_exit(&mpt->m_mutex);
7958 		/*
7959 		 * run the completion routines of all the
7960 		 * completed commands
7961 		 */
7962 		while (cmd != NULL) {
7963 			next = cmd->cmd_linkp;
7964 			cmd->cmd_linkp = NULL;
7965 			/* run this command's completion routine */
7966 			cmd->cmd_flags |= CFLAG_COMPLETED;
7967 			pkt = CMD2PKT(cmd);
7968 			mptsas_pkt_comp(pkt, cmd);
7969 			cmd = next;
7970 		}
7971 		mutex_enter(&mpt->m_mutex);
7972 		mpt->m_in_callback = 0;
7973 	}
7974 }
7975 
7976 /*
7977  * These routines manipulate the target's queue of pending requests
7978  */
7979 void
7980 mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd)
7981 {
7982 	NDBG7(("mptsas_waitq_add: cmd=0x%p", (void *)cmd));
7983 	mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
7984 	cmd->cmd_queued = TRUE;
7985 	if (ptgt)
7986 		ptgt->m_t_nwait++;
7987 	if (cmd->cmd_pkt_flags & FLAG_HEAD) {
7988 		if ((cmd->cmd_linkp = mpt->m_waitq) == NULL) {
7989 			mpt->m_waitqtail = &cmd->cmd_linkp;
7990 		}
7991 		mpt->m_waitq = cmd;
7992 	} else {
7993 		cmd->cmd_linkp = NULL;
7994 		*(mpt->m_waitqtail) = cmd;
7995 		mpt->m_waitqtail = &cmd->cmd_linkp;
7996 	}
7997 }
7998 
7999 static mptsas_cmd_t *
8000 mptsas_waitq_rm(mptsas_t *mpt)
8001 {
8002 	mptsas_cmd_t	*cmd;
8003 	mptsas_target_t *ptgt;
8004 	NDBG7(("mptsas_waitq_rm"));
8005 
8006 	MPTSAS_WAITQ_RM(mpt, cmd);
8007 
8008 	NDBG7(("mptsas_waitq_rm: cmd=0x%p", (void *)cmd));
8009 	if (cmd) {
8010 		ptgt = cmd->cmd_tgt_addr;
8011 		if (ptgt) {
8012 			ptgt->m_t_nwait--;
8013 			ASSERT(ptgt->m_t_nwait >= 0);
8014 		}
8015 	}
8016 	return (cmd);
8017 }
8018 
8019 /*
8020  * remove specified cmd from the middle of the wait queue.
8021  */
8022 static void
8023 mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd)
8024 {
8025 	mptsas_cmd_t	*prevp = mpt->m_waitq;
8026 	mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
8027 
8028 	NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
8029 	    (void *)mpt, (void *)cmd));
8030 	if (ptgt) {
8031 		ptgt->m_t_nwait--;
8032 		ASSERT(ptgt->m_t_nwait >= 0);
8033 	}
8034 
8035 	if (prevp == cmd) {
8036 		if ((mpt->m_waitq = cmd->cmd_linkp) == NULL)
8037 			mpt->m_waitqtail = &mpt->m_waitq;
8038 
8039 		cmd->cmd_linkp = NULL;
8040 		cmd->cmd_queued = FALSE;
8041 		NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
8042 		    (void *)mpt, (void *)cmd));
8043 		return;
8044 	}
8045 
8046 	while (prevp != NULL) {
8047 		if (prevp->cmd_linkp == cmd) {
8048 			if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL)
8049 				mpt->m_waitqtail = &prevp->cmd_linkp;
8050 
8051 			cmd->cmd_linkp = NULL;
8052 			cmd->cmd_queued = FALSE;
8053 			NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
8054 			    (void *)mpt, (void *)cmd));
8055 			return;
8056 		}
8057 		prevp = prevp->cmd_linkp;
8058 	}
8059 	cmn_err(CE_PANIC, "mpt: mptsas_waitq_delete: queue botch");
8060 }
8061 
8062 static mptsas_cmd_t *
8063 mptsas_tx_waitq_rm(mptsas_t *mpt)
8064 {
8065 	mptsas_cmd_t *cmd;
8066 	NDBG7(("mptsas_tx_waitq_rm"));
8067 
8068 	MPTSAS_TX_WAITQ_RM(mpt, cmd);
8069 
8070 	NDBG7(("mptsas_tx_waitq_rm: cmd=0x%p", (void *)cmd));
8071 
8072 	return (cmd);
8073 }
8074 
8075 /*
8076  * remove specified cmd from the middle of the tx_waitq.
8077  */
8078 static void
8079 mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd)
8080 {
8081 	mptsas_cmd_t *prevp = mpt->m_tx_waitq;
8082 
8083 	NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
8084 	    (void *)mpt, (void *)cmd));
8085 
8086 	if (prevp == cmd) {
8087 		if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL)
8088 			mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
8089 
8090 		cmd->cmd_linkp = NULL;
8091 		cmd->cmd_queued = FALSE;
8092 		NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
8093 		    (void *)mpt, (void *)cmd));
8094 		return;
8095 	}
8096 
8097 	while (prevp != NULL) {
8098 		if (prevp->cmd_linkp == cmd) {
8099 			if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL)
8100 				mpt->m_tx_waitqtail = &prevp->cmd_linkp;
8101 
8102 			cmd->cmd_linkp = NULL;
8103 			cmd->cmd_queued = FALSE;
8104 			NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
8105 			    (void *)mpt, (void *)cmd));
8106 			return;
8107 		}
8108 		prevp = prevp->cmd_linkp;
8109 	}
8110 	cmn_err(CE_PANIC, "mpt: mptsas_tx_waitq_delete: queue botch");
8111 }
8112 
8113 /*
8114  * device and bus reset handling
8115  *
8116  * Notes:
8117  *	- RESET_ALL:	reset the controller
8118  *	- RESET_TARGET:	reset the target specified in scsi_address
8119  */
8120 static int
8121 mptsas_scsi_reset(struct scsi_address *ap, int level)
8122 {
8123 	mptsas_t		*mpt = ADDR2MPT(ap);
8124 	int			rval;
8125 	mptsas_tgt_private_t	*tgt_private;
8126 	mptsas_target_t		*ptgt = NULL;
8127 
8128 	tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->tran_tgt_private;
8129 	ptgt = tgt_private->t_private;
8130 	if (ptgt == NULL) {
8131 		return (FALSE);
8132 	}
8133 	NDBG22(("mptsas_scsi_reset: target=%d level=%d", ptgt->m_devhdl,
8134 	    level));
8135 
8136 	mutex_enter(&mpt->m_mutex);
8137 	/*
8138 	 * if we are not in panic set up a reset delay for this target
8139 	 */
8140 	if (!ddi_in_panic()) {
8141 		mptsas_setup_bus_reset_delay(mpt);
8142 	} else {
8143 		drv_usecwait(mpt->m_scsi_reset_delay * 1000);
8144 	}
8145 	rval = mptsas_do_scsi_reset(mpt, ptgt->m_devhdl);
8146 	mutex_exit(&mpt->m_mutex);
8147 
8148 	/*
8149 	 * The transport layer expect to only see TRUE and
8150 	 * FALSE. Therefore, we will adjust the return value
8151 	 * if mptsas_do_scsi_reset returns FAILED.
8152 	 */
8153 	if (rval == FAILED)
8154 		rval = FALSE;
8155 	return (rval);
8156 }
8157 
8158 static int
8159 mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl)
8160 {
8161 	int		rval = FALSE;
8162 	uint8_t		config, disk;
8163 	mptsas_slots_t	*slots = mpt->m_active;
8164 
8165 	ASSERT(mutex_owned(&mpt->m_mutex));
8166 
8167 	if (mptsas_debug_resets) {
8168 		mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d",
8169 		    devhdl);
8170 	}
8171 
8172 	/*
8173 	 * Issue a Target Reset message to the target specified but not to a
8174 	 * disk making up a raid volume.  Just look through the RAID config
8175 	 * Phys Disk list of DevHandles.  If the target's DevHandle is in this
8176 	 * list, then don't reset this target.
8177 	 */
8178 	for (config = 0; config < slots->m_num_raid_configs; config++) {
8179 		for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
8180 			if (devhdl == slots->m_raidconfig[config].
8181 			    m_physdisk_devhdl[disk]) {
8182 				return (TRUE);
8183 			}
8184 		}
8185 	}
8186 
8187 	rval = mptsas_ioc_task_management(mpt,
8188 	    MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, devhdl, 0);
8189 
8190 	mptsas_doneq_empty(mpt);
8191 	return (rval);
8192 }
8193 
8194 static int
8195 mptsas_scsi_reset_notify(struct scsi_address *ap, int flag,
8196 	void (*callback)(caddr_t), caddr_t arg)
8197 {
8198 	mptsas_t	*mpt = ADDR2MPT(ap);
8199 
8200 	NDBG22(("mptsas_scsi_reset_notify: tgt=%d", ap->a_target));
8201 
8202 	return (scsi_hba_reset_notify_setup(ap, flag, callback, arg,
8203 	    &mpt->m_mutex, &mpt->m_reset_notify_listf));
8204 }
8205 
8206 static int
8207 mptsas_get_name(struct scsi_device *sd, char *name, int len)
8208 {
8209 	dev_info_t	*lun_dip = NULL;
8210 
8211 	ASSERT(sd != NULL);
8212 	ASSERT(name != NULL);
8213 	lun_dip = sd->sd_dev;
8214 	ASSERT(lun_dip != NULL);
8215 
8216 	if (mptsas_name_child(lun_dip, name, len) == DDI_SUCCESS) {
8217 		return (1);
8218 	} else {
8219 		return (0);
8220 	}
8221 }
8222 
8223 static int
8224 mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len)
8225 {
8226 	return (mptsas_get_name(sd, name, len));
8227 }
8228 
8229 void
8230 mptsas_set_throttle(mptsas_t *mpt, mptsas_target_t *ptgt, int what)
8231 {
8232 
8233 	NDBG25(("mptsas_set_throttle: throttle=%x", what));
8234 
8235 	/*
8236 	 * if the bus is draining/quiesced, no changes to the throttles
8237 	 * are allowed. Not allowing change of throttles during draining
8238 	 * limits error recovery but will reduce draining time
8239 	 *
8240 	 * all throttles should have been set to HOLD_THROTTLE
8241 	 */
8242 	if (mpt->m_softstate & (MPTSAS_SS_QUIESCED | MPTSAS_SS_DRAINING)) {
8243 		return;
8244 	}
8245 
8246 	if (what == HOLD_THROTTLE) {
8247 		ptgt->m_t_throttle = HOLD_THROTTLE;
8248 	} else if (ptgt->m_reset_delay == 0) {
8249 		ptgt->m_t_throttle = what;
8250 	}
8251 }
8252 
8253 /*
8254  * Clean up from a device reset.
8255  * For the case of target reset, this function clears the waitq of all
8256  * commands for a particular target.   For the case of abort task set, this
8257  * function clears the waitq of all commonds for a particular target/lun.
8258  */
8259 static void
8260 mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype)
8261 {
8262 	mptsas_slots_t	*slots = mpt->m_active;
8263 	mptsas_cmd_t	*cmd, *next_cmd;
8264 	int		slot;
8265 	uchar_t		reason;
8266 	uint_t		stat;
8267 
8268 	NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun));
8269 
8270 	/*
8271 	 * Make sure the I/O Controller has flushed all cmds
8272 	 * that are associated with this target for a target reset
8273 	 * and target/lun for abort task set.
8274 	 * Account for TM requests, which use the last SMID.
8275 	 */
8276 	for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) {
8277 		if ((cmd = slots->m_slot[slot]) == NULL)
8278 			continue;
8279 		reason = CMD_RESET;
8280 		stat = STAT_DEV_RESET;
8281 		switch (tasktype) {
8282 		case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
8283 			if (Tgt(cmd) == target) {
8284 				mptsas_log(mpt, CE_NOTE, "mptsas_flush_target "
8285 				    "discovered non-NULL cmd in slot %d, "
8286 				    "tasktype 0x%x", slot, tasktype);
8287 				mptsas_dump_cmd(mpt, cmd);
8288 				mptsas_remove_cmd(mpt, cmd);
8289 				mptsas_set_pkt_reason(mpt, cmd, reason, stat);
8290 				mptsas_doneq_add(mpt, cmd);
8291 			}
8292 			break;
8293 		case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
8294 			reason = CMD_ABORTED;
8295 			stat = STAT_ABORTED;
8296 			/*FALLTHROUGH*/
8297 		case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
8298 			if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
8299 
8300 				mptsas_log(mpt, CE_NOTE, "mptsas_flush_target "
8301 				    "discovered non-NULL cmd in slot %d, "
8302 				    "tasktype 0x%x", slot, tasktype);
8303 				mptsas_dump_cmd(mpt, cmd);
8304 				mptsas_remove_cmd(mpt, cmd);
8305 				mptsas_set_pkt_reason(mpt, cmd, reason,
8306 				    stat);
8307 				mptsas_doneq_add(mpt, cmd);
8308 			}
8309 			break;
8310 		default:
8311 			break;
8312 		}
8313 	}
8314 
8315 	/*
8316 	 * Flush the waitq and tx_waitq of this target's cmds
8317 	 */
8318 	cmd = mpt->m_waitq;
8319 
8320 	reason = CMD_RESET;
8321 	stat = STAT_DEV_RESET;
8322 
8323 	switch (tasktype) {
8324 	case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
8325 		while (cmd != NULL) {
8326 			next_cmd = cmd->cmd_linkp;
8327 			if (Tgt(cmd) == target) {
8328 				mptsas_waitq_delete(mpt, cmd);
8329 				mptsas_set_pkt_reason(mpt, cmd,
8330 				    reason, stat);
8331 				mptsas_doneq_add(mpt, cmd);
8332 			}
8333 			cmd = next_cmd;
8334 		}
8335 		mutex_enter(&mpt->m_tx_waitq_mutex);
8336 		cmd = mpt->m_tx_waitq;
8337 		while (cmd != NULL) {
8338 			next_cmd = cmd->cmd_linkp;
8339 			if (Tgt(cmd) == target) {
8340 				mptsas_tx_waitq_delete(mpt, cmd);
8341 				mutex_exit(&mpt->m_tx_waitq_mutex);
8342 				mptsas_set_pkt_reason(mpt, cmd,
8343 				    reason, stat);
8344 				mptsas_doneq_add(mpt, cmd);
8345 				mutex_enter(&mpt->m_tx_waitq_mutex);
8346 			}
8347 			cmd = next_cmd;
8348 		}
8349 		mutex_exit(&mpt->m_tx_waitq_mutex);
8350 		break;
8351 	case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
8352 		reason = CMD_ABORTED;
8353 		stat =  STAT_ABORTED;
8354 		/*FALLTHROUGH*/
8355 	case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
8356 		while (cmd != NULL) {
8357 			next_cmd = cmd->cmd_linkp;
8358 			if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
8359 				mptsas_waitq_delete(mpt, cmd);
8360 				mptsas_set_pkt_reason(mpt, cmd,
8361 				    reason, stat);
8362 				mptsas_doneq_add(mpt, cmd);
8363 			}
8364 			cmd = next_cmd;
8365 		}
8366 		mutex_enter(&mpt->m_tx_waitq_mutex);
8367 		cmd = mpt->m_tx_waitq;
8368 		while (cmd != NULL) {
8369 			next_cmd = cmd->cmd_linkp;
8370 			if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
8371 				mptsas_tx_waitq_delete(mpt, cmd);
8372 				mutex_exit(&mpt->m_tx_waitq_mutex);
8373 				mptsas_set_pkt_reason(mpt, cmd,
8374 				    reason, stat);
8375 				mptsas_doneq_add(mpt, cmd);
8376 				mutex_enter(&mpt->m_tx_waitq_mutex);
8377 			}
8378 			cmd = next_cmd;
8379 		}
8380 		mutex_exit(&mpt->m_tx_waitq_mutex);
8381 		break;
8382 	default:
8383 		mptsas_log(mpt, CE_WARN, "Unknown task management type %d.",
8384 		    tasktype);
8385 		break;
8386 	}
8387 }
8388 
8389 /*
8390  * Clean up hba state, abort all outstanding command and commands in waitq
8391  * reset timeout of all targets.
8392  */
8393 static void
8394 mptsas_flush_hba(mptsas_t *mpt)
8395 {
8396 	mptsas_slots_t	*slots = mpt->m_active;
8397 	mptsas_cmd_t	*cmd;
8398 	int		slot;
8399 
8400 	NDBG25(("mptsas_flush_hba"));
8401 
8402 	/*
8403 	 * The I/O Controller should have already sent back
8404 	 * all commands via the scsi I/O reply frame.  Make
8405 	 * sure all commands have been flushed.
8406 	 * Account for TM request, which use the last SMID.
8407 	 */
8408 	for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) {
8409 		if ((cmd = slots->m_slot[slot]) == NULL)
8410 			continue;
8411 
8412 		if (cmd->cmd_flags & CFLAG_CMDIOC) {
8413 			/*
8414 			 * Need to make sure to tell everyone that might be
8415 			 * waiting on this command that it's going to fail.  If
8416 			 * we get here, this command will never timeout because
8417 			 * the active command table is going to be re-allocated,
8418 			 * so there will be nothing to check against a time out.
8419 			 * Instead, mark the command as failed due to reset.
8420 			 */
8421 			mptsas_set_pkt_reason(mpt, cmd, CMD_RESET,
8422 			    STAT_BUS_RESET);
8423 			if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
8424 			    (cmd->cmd_flags & CFLAG_CONFIG) ||
8425 			    (cmd->cmd_flags & CFLAG_FW_DIAG)) {
8426 				cmd->cmd_flags |= CFLAG_FINISHED;
8427 				cv_broadcast(&mpt->m_passthru_cv);
8428 				cv_broadcast(&mpt->m_config_cv);
8429 				cv_broadcast(&mpt->m_fw_diag_cv);
8430 			}
8431 			continue;
8432 		}
8433 
8434 		mptsas_log(mpt, CE_NOTE, "mptsas_flush_hba discovered non-NULL "
8435 		    "cmd in slot %d", slot);
8436 		mptsas_dump_cmd(mpt, cmd);
8437 
8438 		mptsas_remove_cmd(mpt, cmd);
8439 		mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
8440 		mptsas_doneq_add(mpt, cmd);
8441 	}
8442 
8443 	/*
8444 	 * Flush the waitq.
8445 	 */
8446 	while ((cmd = mptsas_waitq_rm(mpt)) != NULL) {
8447 		mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
8448 		if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
8449 		    (cmd->cmd_flags & CFLAG_CONFIG) ||
8450 		    (cmd->cmd_flags & CFLAG_FW_DIAG)) {
8451 			cmd->cmd_flags |= CFLAG_FINISHED;
8452 			cv_broadcast(&mpt->m_passthru_cv);
8453 			cv_broadcast(&mpt->m_config_cv);
8454 			cv_broadcast(&mpt->m_fw_diag_cv);
8455 		} else {
8456 			mptsas_doneq_add(mpt, cmd);
8457 		}
8458 	}
8459 
8460 	/*
8461 	 * Flush the tx_waitq
8462 	 */
8463 	mutex_enter(&mpt->m_tx_waitq_mutex);
8464 	while ((cmd = mptsas_tx_waitq_rm(mpt)) != NULL) {
8465 		mutex_exit(&mpt->m_tx_waitq_mutex);
8466 		mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
8467 		mptsas_doneq_add(mpt, cmd);
8468 		mutex_enter(&mpt->m_tx_waitq_mutex);
8469 	}
8470 	mutex_exit(&mpt->m_tx_waitq_mutex);
8471 }
8472 
8473 /*
8474  * set pkt_reason and OR in pkt_statistics flag
8475  */
8476 static void
8477 mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, uchar_t reason,
8478     uint_t stat)
8479 {
8480 #ifndef __lock_lint
8481 	_NOTE(ARGUNUSED(mpt))
8482 #endif
8483 
8484 	NDBG25(("mptsas_set_pkt_reason: cmd=0x%p reason=%x stat=%x",
8485 	    (void *)cmd, reason, stat));
8486 
8487 	if (cmd) {
8488 		if (cmd->cmd_pkt->pkt_reason == CMD_CMPLT) {
8489 			cmd->cmd_pkt->pkt_reason = reason;
8490 		}
8491 		cmd->cmd_pkt->pkt_statistics |= stat;
8492 	}
8493 }
8494 
8495 static void
8496 mptsas_start_watch_reset_delay()
8497 {
8498 	NDBG22(("mptsas_start_watch_reset_delay"));
8499 
8500 	mutex_enter(&mptsas_global_mutex);
8501 	if (mptsas_reset_watch == NULL && mptsas_timeouts_enabled) {
8502 		mptsas_reset_watch = timeout(mptsas_watch_reset_delay, NULL,
8503 		    drv_usectohz((clock_t)
8504 		    MPTSAS_WATCH_RESET_DELAY_TICK * 1000));
8505 		ASSERT(mptsas_reset_watch != NULL);
8506 	}
8507 	mutex_exit(&mptsas_global_mutex);
8508 }
8509 
8510 static void
8511 mptsas_setup_bus_reset_delay(mptsas_t *mpt)
8512 {
8513 	mptsas_target_t	*ptgt = NULL;
8514 
8515 	NDBG22(("mptsas_setup_bus_reset_delay"));
8516 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
8517 	    MPTSAS_HASH_FIRST);
8518 	while (ptgt != NULL) {
8519 		mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
8520 		ptgt->m_reset_delay = mpt->m_scsi_reset_delay;
8521 
8522 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
8523 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
8524 	}
8525 
8526 	mptsas_start_watch_reset_delay();
8527 }
8528 
8529 /*
8530  * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every
8531  * mpt instance for active reset delays
8532  */
8533 static void
8534 mptsas_watch_reset_delay(void *arg)
8535 {
8536 #ifndef __lock_lint
8537 	_NOTE(ARGUNUSED(arg))
8538 #endif
8539 
8540 	mptsas_t	*mpt;
8541 	int		not_done = 0;
8542 
8543 	NDBG22(("mptsas_watch_reset_delay"));
8544 
8545 	mutex_enter(&mptsas_global_mutex);
8546 	mptsas_reset_watch = 0;
8547 	mutex_exit(&mptsas_global_mutex);
8548 	rw_enter(&mptsas_global_rwlock, RW_READER);
8549 	for (mpt = mptsas_head; mpt != NULL; mpt = mpt->m_next) {
8550 		if (mpt->m_tran == 0) {
8551 			continue;
8552 		}
8553 		mutex_enter(&mpt->m_mutex);
8554 		not_done += mptsas_watch_reset_delay_subr(mpt);
8555 		mutex_exit(&mpt->m_mutex);
8556 	}
8557 	rw_exit(&mptsas_global_rwlock);
8558 
8559 	if (not_done) {
8560 		mptsas_start_watch_reset_delay();
8561 	}
8562 }
8563 
8564 static int
8565 mptsas_watch_reset_delay_subr(mptsas_t *mpt)
8566 {
8567 	int		done = 0;
8568 	int		restart = 0;
8569 	mptsas_target_t	*ptgt = NULL;
8570 
8571 	NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt));
8572 
8573 	ASSERT(mutex_owned(&mpt->m_mutex));
8574 
8575 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
8576 	    MPTSAS_HASH_FIRST);
8577 	while (ptgt != NULL) {
8578 		if (ptgt->m_reset_delay != 0) {
8579 			ptgt->m_reset_delay -=
8580 			    MPTSAS_WATCH_RESET_DELAY_TICK;
8581 			if (ptgt->m_reset_delay <= 0) {
8582 				ptgt->m_reset_delay = 0;
8583 				mptsas_set_throttle(mpt, ptgt,
8584 				    MAX_THROTTLE);
8585 				restart++;
8586 			} else {
8587 				done = -1;
8588 			}
8589 		}
8590 
8591 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
8592 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
8593 	}
8594 
8595 	if (restart > 0) {
8596 		mptsas_restart_hba(mpt);
8597 	}
8598 	return (done);
8599 }
8600 
8601 #ifdef MPTSAS_TEST
8602 static void
8603 mptsas_test_reset(mptsas_t *mpt, int target)
8604 {
8605 	mptsas_target_t    *ptgt = NULL;
8606 
8607 	if (mptsas_rtest == target) {
8608 		if (mptsas_do_scsi_reset(mpt, target) == TRUE) {
8609 			mptsas_rtest = -1;
8610 		}
8611 		if (mptsas_rtest == -1) {
8612 			NDBG22(("mptsas_test_reset success"));
8613 		}
8614 	}
8615 }
8616 #endif
8617 
8618 /*
8619  * abort handling:
8620  *
8621  * Notes:
8622  *	- if pkt is not NULL, abort just that command
8623  *	- if pkt is NULL, abort all outstanding commands for target
8624  */
8625 static int
8626 mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
8627 {
8628 	mptsas_t		*mpt = ADDR2MPT(ap);
8629 	int			rval;
8630 	mptsas_tgt_private_t	*tgt_private;
8631 	int			target, lun;
8632 
8633 	tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->
8634 	    tran_tgt_private;
8635 	ASSERT(tgt_private != NULL);
8636 	target = tgt_private->t_private->m_devhdl;
8637 	lun = tgt_private->t_lun;
8638 
8639 	NDBG23(("mptsas_scsi_abort: target=%d.%d", target, lun));
8640 
8641 	mutex_enter(&mpt->m_mutex);
8642 	rval = mptsas_do_scsi_abort(mpt, target, lun, pkt);
8643 	mutex_exit(&mpt->m_mutex);
8644 	return (rval);
8645 }
8646 
8647 static int
8648 mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, struct scsi_pkt *pkt)
8649 {
8650 	mptsas_cmd_t	*sp = NULL;
8651 	mptsas_slots_t	*slots = mpt->m_active;
8652 	int		rval = FALSE;
8653 
8654 	ASSERT(mutex_owned(&mpt->m_mutex));
8655 
8656 	/*
8657 	 * Abort the command pkt on the target/lun in ap.  If pkt is
8658 	 * NULL, abort all outstanding commands on that target/lun.
8659 	 * If you can abort them, return 1, else return 0.
8660 	 * Each packet that's aborted should be sent back to the target
8661 	 * driver through the callback routine, with pkt_reason set to
8662 	 * CMD_ABORTED.
8663 	 *
8664 	 * abort cmd pkt on HBA hardware; clean out of outstanding
8665 	 * command lists, etc.
8666 	 */
8667 	if (pkt != NULL) {
8668 		/* abort the specified packet */
8669 		sp = PKT2CMD(pkt);
8670 
8671 		if (sp->cmd_queued) {
8672 			NDBG23(("mptsas_do_scsi_abort: queued sp=0x%p aborted",
8673 			    (void *)sp));
8674 			mptsas_waitq_delete(mpt, sp);
8675 			mptsas_set_pkt_reason(mpt, sp, CMD_ABORTED,
8676 			    STAT_ABORTED);
8677 			mptsas_doneq_add(mpt, sp);
8678 			rval = TRUE;
8679 			goto done;
8680 		}
8681 
8682 		/*
8683 		 * Have mpt firmware abort this command
8684 		 */
8685 
8686 		if (slots->m_slot[sp->cmd_slot] != NULL) {
8687 			rval = mptsas_ioc_task_management(mpt,
8688 			    MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, target,
8689 			    lun);
8690 
8691 			/*
8692 			 * The transport layer expects only TRUE and FALSE.
8693 			 * Therefore, if mptsas_ioc_task_management returns
8694 			 * FAILED we will return FALSE.
8695 			 */
8696 			if (rval == FAILED)
8697 				rval = FALSE;
8698 			goto done;
8699 		}
8700 	}
8701 
8702 	/*
8703 	 * If pkt is NULL then abort task set
8704 	 */
8705 	rval = mptsas_ioc_task_management(mpt,
8706 	    MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, target, lun);
8707 
8708 	/*
8709 	 * The transport layer expects only TRUE and FALSE.
8710 	 * Therefore, if mptsas_ioc_task_management returns
8711 	 * FAILED we will return FALSE.
8712 	 */
8713 	if (rval == FAILED)
8714 		rval = FALSE;
8715 
8716 #ifdef MPTSAS_TEST
8717 	if (rval && mptsas_test_stop) {
8718 		debug_enter("mptsas_do_scsi_abort");
8719 	}
8720 #endif
8721 
8722 done:
8723 	mptsas_doneq_empty(mpt);
8724 	return (rval);
8725 }
8726 
8727 /*
8728  * capability handling:
8729  * (*tran_getcap).  Get the capability named, and return its value.
8730  */
8731 static int
8732 mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly)
8733 {
8734 	mptsas_t	*mpt = ADDR2MPT(ap);
8735 	int		ckey;
8736 	int		rval = FALSE;
8737 
8738 	NDBG24(("mptsas_scsi_getcap: target=%d, cap=%s tgtonly=%x",
8739 	    ap->a_target, cap, tgtonly));
8740 
8741 	mutex_enter(&mpt->m_mutex);
8742 
8743 	if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) {
8744 		mutex_exit(&mpt->m_mutex);
8745 		return (UNDEFINED);
8746 	}
8747 
8748 	switch (ckey) {
8749 	case SCSI_CAP_DMA_MAX:
8750 		rval = (int)mpt->m_msg_dma_attr.dma_attr_maxxfer;
8751 		break;
8752 	case SCSI_CAP_ARQ:
8753 		rval = TRUE;
8754 		break;
8755 	case SCSI_CAP_MSG_OUT:
8756 	case SCSI_CAP_PARITY:
8757 	case SCSI_CAP_UNTAGGED_QING:
8758 		rval = TRUE;
8759 		break;
8760 	case SCSI_CAP_TAGGED_QING:
8761 		rval = TRUE;
8762 		break;
8763 	case SCSI_CAP_RESET_NOTIFICATION:
8764 		rval = TRUE;
8765 		break;
8766 	case SCSI_CAP_LINKED_CMDS:
8767 		rval = FALSE;
8768 		break;
8769 	case SCSI_CAP_QFULL_RETRIES:
8770 		rval = ((mptsas_tgt_private_t *)(ap->a_hba_tran->
8771 		    tran_tgt_private))->t_private->m_qfull_retries;
8772 		break;
8773 	case SCSI_CAP_QFULL_RETRY_INTERVAL:
8774 		rval = drv_hztousec(((mptsas_tgt_private_t *)
8775 		    (ap->a_hba_tran->tran_tgt_private))->
8776 		    t_private->m_qfull_retry_interval) / 1000;
8777 		break;
8778 	case SCSI_CAP_CDB_LEN:
8779 		rval = CDB_GROUP4;
8780 		break;
8781 	case SCSI_CAP_INTERCONNECT_TYPE:
8782 		rval = INTERCONNECT_SAS;
8783 		break;
8784 	case SCSI_CAP_TRAN_LAYER_RETRIES:
8785 		if (mpt->m_ioc_capabilities &
8786 		    MPI2_IOCFACTS_CAPABILITY_TLR)
8787 			rval = TRUE;
8788 		else
8789 			rval = FALSE;
8790 		break;
8791 	default:
8792 		rval = UNDEFINED;
8793 		break;
8794 	}
8795 
8796 	NDBG24(("mptsas_scsi_getcap: %s, rval=%x", cap, rval));
8797 
8798 	mutex_exit(&mpt->m_mutex);
8799 	return (rval);
8800 }
8801 
8802 /*
8803  * (*tran_setcap).  Set the capability named to the value given.
8804  */
8805 static int
8806 mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, int tgtonly)
8807 {
8808 	mptsas_t	*mpt = ADDR2MPT(ap);
8809 	int		ckey;
8810 	int		rval = FALSE;
8811 
8812 	NDBG24(("mptsas_scsi_setcap: target=%d, cap=%s value=%x tgtonly=%x",
8813 	    ap->a_target, cap, value, tgtonly));
8814 
8815 	if (!tgtonly) {
8816 		return (rval);
8817 	}
8818 
8819 	mutex_enter(&mpt->m_mutex);
8820 
8821 	if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) {
8822 		mutex_exit(&mpt->m_mutex);
8823 		return (UNDEFINED);
8824 	}
8825 
8826 	switch (ckey) {
8827 	case SCSI_CAP_DMA_MAX:
8828 	case SCSI_CAP_MSG_OUT:
8829 	case SCSI_CAP_PARITY:
8830 	case SCSI_CAP_INITIATOR_ID:
8831 	case SCSI_CAP_LINKED_CMDS:
8832 	case SCSI_CAP_UNTAGGED_QING:
8833 	case SCSI_CAP_RESET_NOTIFICATION:
8834 		/*
8835 		 * None of these are settable via
8836 		 * the capability interface.
8837 		 */
8838 		break;
8839 	case SCSI_CAP_ARQ:
8840 		/*
8841 		 * We cannot turn off arq so return false if asked to
8842 		 */
8843 		if (value) {
8844 			rval = TRUE;
8845 		} else {
8846 			rval = FALSE;
8847 		}
8848 		break;
8849 	case SCSI_CAP_TAGGED_QING:
8850 		mptsas_set_throttle(mpt, ((mptsas_tgt_private_t *)
8851 		    (ap->a_hba_tran->tran_tgt_private))->t_private,
8852 		    MAX_THROTTLE);
8853 		rval = TRUE;
8854 		break;
8855 	case SCSI_CAP_QFULL_RETRIES:
8856 		((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))->
8857 		    t_private->m_qfull_retries = (uchar_t)value;
8858 		rval = TRUE;
8859 		break;
8860 	case SCSI_CAP_QFULL_RETRY_INTERVAL:
8861 		((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))->
8862 		    t_private->m_qfull_retry_interval =
8863 		    drv_usectohz(value * 1000);
8864 		rval = TRUE;
8865 		break;
8866 	default:
8867 		rval = UNDEFINED;
8868 		break;
8869 	}
8870 	mutex_exit(&mpt->m_mutex);
8871 	return (rval);
8872 }
8873 
8874 /*
8875  * Utility routine for mptsas_ifsetcap/ifgetcap
8876  */
8877 /*ARGSUSED*/
8878 static int
8879 mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp)
8880 {
8881 	NDBG24(("mptsas_scsi_capchk: cap=%s", cap));
8882 
8883 	if (!cap)
8884 		return (FALSE);
8885 
8886 	*cidxp = scsi_hba_lookup_capstr(cap);
8887 	return (TRUE);
8888 }
8889 
8890 static int
8891 mptsas_alloc_active_slots(mptsas_t *mpt, int flag)
8892 {
8893 	mptsas_slots_t	*old_active = mpt->m_active;
8894 	mptsas_slots_t	*new_active;
8895 	size_t		size;
8896 	int		rval = -1;
8897 
8898 	if (mpt->m_ncmds) {
8899 		NDBG9(("cannot change size of active slots array"));
8900 		return (rval);
8901 	}
8902 
8903 	size = MPTSAS_SLOTS_SIZE(mpt);
8904 	new_active = kmem_zalloc(size, flag);
8905 	if (new_active == NULL) {
8906 		NDBG1(("new active alloc failed"));
8907 	} else {
8908 		/*
8909 		 * Since SMID 0 is reserved and the TM slot is reserved, the
8910 		 * number of slots that can be used at any one time is
8911 		 * m_max_requests - 2.
8912 		 */
8913 		mpt->m_active = new_active;
8914 		mpt->m_active->m_n_slots = (mpt->m_max_requests - 2);
8915 		mpt->m_active->m_size = size;
8916 		mpt->m_active->m_tags = 1;
8917 		if (old_active) {
8918 			kmem_free(old_active, old_active->m_size);
8919 		}
8920 		rval = 0;
8921 	}
8922 
8923 	return (rval);
8924 }
8925 
8926 /*
8927  * Error logging, printing, and debug print routines.
8928  */
8929 static char *mptsas_label = "mpt_sas";
8930 
8931 /*PRINTFLIKE3*/
8932 void
8933 mptsas_log(mptsas_t *mpt, int level, char *fmt, ...)
8934 {
8935 	dev_info_t	*dev;
8936 	va_list		ap;
8937 
8938 	if (mpt) {
8939 		dev = mpt->m_dip;
8940 	} else {
8941 		dev = 0;
8942 	}
8943 
8944 	mutex_enter(&mptsas_log_mutex);
8945 
8946 	va_start(ap, fmt);
8947 	(void) vsprintf(mptsas_log_buf, fmt, ap);
8948 	va_end(ap);
8949 
8950 	if (level == CE_CONT) {
8951 		scsi_log(dev, mptsas_label, level, "%s\n", mptsas_log_buf);
8952 	} else {
8953 		scsi_log(dev, mptsas_label, level, "%s", mptsas_log_buf);
8954 	}
8955 
8956 	mutex_exit(&mptsas_log_mutex);
8957 }
8958 
8959 #ifdef MPTSAS_DEBUG
8960 /*PRINTFLIKE1*/
8961 void
8962 mptsas_printf(char *fmt, ...)
8963 {
8964 	dev_info_t	*dev = 0;
8965 	va_list		ap;
8966 
8967 	mutex_enter(&mptsas_log_mutex);
8968 
8969 	va_start(ap, fmt);
8970 	(void) vsprintf(mptsas_log_buf, fmt, ap);
8971 	va_end(ap);
8972 
8973 #ifdef PROM_PRINTF
8974 	prom_printf("%s:\t%s\n", mptsas_label, mptsas_log_buf);
8975 #else
8976 	scsi_log(dev, mptsas_label, SCSI_DEBUG, "%s\n", mptsas_log_buf);
8977 #endif
8978 	mutex_exit(&mptsas_log_mutex);
8979 }
8980 #endif
8981 
8982 /*
8983  * timeout handling
8984  */
8985 static void
8986 mptsas_watch(void *arg)
8987 {
8988 #ifndef __lock_lint
8989 	_NOTE(ARGUNUSED(arg))
8990 #endif
8991 
8992 	mptsas_t	*mpt;
8993 	uint32_t	doorbell;
8994 
8995 	NDBG30(("mptsas_watch"));
8996 
8997 	rw_enter(&mptsas_global_rwlock, RW_READER);
8998 	for (mpt = mptsas_head; mpt != (mptsas_t *)NULL; mpt = mpt->m_next) {
8999 
9000 		mutex_enter(&mpt->m_mutex);
9001 
9002 		/* Skip device if not powered on */
9003 		if (mpt->m_options & MPTSAS_OPT_PM) {
9004 			if (mpt->m_power_level == PM_LEVEL_D0) {
9005 				(void) pm_busy_component(mpt->m_dip, 0);
9006 				mpt->m_busy = 1;
9007 			} else {
9008 				mutex_exit(&mpt->m_mutex);
9009 				continue;
9010 			}
9011 		}
9012 
9013 		/*
9014 		 * Check if controller is in a FAULT state. If so, reset it.
9015 		 */
9016 		doorbell = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell);
9017 		if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
9018 			doorbell &= MPI2_DOORBELL_DATA_MASK;
9019 			mptsas_log(mpt, CE_WARN, "MPT Firmware Fault, "
9020 			    "code: %04x", doorbell);
9021 			if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
9022 				mptsas_log(mpt, CE_WARN, "Reset failed"
9023 				    "after fault was detected");
9024 			}
9025 		}
9026 
9027 		/*
9028 		 * For now, always call mptsas_watchsubr.
9029 		 */
9030 		mptsas_watchsubr(mpt);
9031 
9032 		if (mpt->m_options & MPTSAS_OPT_PM) {
9033 			mpt->m_busy = 0;
9034 			(void) pm_idle_component(mpt->m_dip, 0);
9035 		}
9036 
9037 		mutex_exit(&mpt->m_mutex);
9038 	}
9039 	rw_exit(&mptsas_global_rwlock);
9040 
9041 	mutex_enter(&mptsas_global_mutex);
9042 	if (mptsas_timeouts_enabled)
9043 		mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick);
9044 	mutex_exit(&mptsas_global_mutex);
9045 }
9046 
9047 static void
9048 mptsas_watchsubr(mptsas_t *mpt)
9049 {
9050 	int		i;
9051 	mptsas_cmd_t	*cmd;
9052 	mptsas_target_t	*ptgt = NULL;
9053 
9054 	NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt));
9055 
9056 #ifdef MPTSAS_TEST
9057 	if (mptsas_enable_untagged) {
9058 		mptsas_test_untagged++;
9059 	}
9060 #endif
9061 
9062 	/*
9063 	 * Check for commands stuck in active slot
9064 	 * Account for TM requests, which use the last SMID.
9065 	 */
9066 	for (i = 0; i <= mpt->m_active->m_n_slots; i++) {
9067 		if ((cmd = mpt->m_active->m_slot[i]) != NULL) {
9068 			if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
9069 				cmd->cmd_active_timeout -=
9070 				    mptsas_scsi_watchdog_tick;
9071 				if (cmd->cmd_active_timeout <= 0) {
9072 					/*
9073 					 * There seems to be a command stuck
9074 					 * in the active slot.  Drain throttle.
9075 					 */
9076 					mptsas_set_throttle(mpt,
9077 					    cmd->cmd_tgt_addr,
9078 					    DRAIN_THROTTLE);
9079 				}
9080 			}
9081 			if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
9082 			    (cmd->cmd_flags & CFLAG_CONFIG) ||
9083 			    (cmd->cmd_flags & CFLAG_FW_DIAG)) {
9084 				cmd->cmd_active_timeout -=
9085 				    mptsas_scsi_watchdog_tick;
9086 				if (cmd->cmd_active_timeout <= 0) {
9087 					/*
9088 					 * passthrough command timeout
9089 					 */
9090 					cmd->cmd_flags |= (CFLAG_FINISHED |
9091 					    CFLAG_TIMEOUT);
9092 					cv_broadcast(&mpt->m_passthru_cv);
9093 					cv_broadcast(&mpt->m_config_cv);
9094 					cv_broadcast(&mpt->m_fw_diag_cv);
9095 				}
9096 			}
9097 		}
9098 	}
9099 
9100 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
9101 	    MPTSAS_HASH_FIRST);
9102 	while (ptgt != NULL) {
9103 		/*
9104 		 * If we were draining due to a qfull condition,
9105 		 * go back to full throttle.
9106 		 */
9107 		if ((ptgt->m_t_throttle < MAX_THROTTLE) &&
9108 		    (ptgt->m_t_throttle > HOLD_THROTTLE) &&
9109 		    (ptgt->m_t_ncmds < ptgt->m_t_throttle)) {
9110 			mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9111 			mptsas_restart_hba(mpt);
9112 		}
9113 
9114 		if ((ptgt->m_t_ncmds > 0) &&
9115 		    (ptgt->m_timebase)) {
9116 
9117 			if (ptgt->m_timebase <=
9118 			    mptsas_scsi_watchdog_tick) {
9119 				ptgt->m_timebase +=
9120 				    mptsas_scsi_watchdog_tick;
9121 				ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9122 				    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9123 				continue;
9124 			}
9125 
9126 			ptgt->m_timeout -= mptsas_scsi_watchdog_tick;
9127 
9128 			if (ptgt->m_timeout < 0) {
9129 				mptsas_cmd_timeout(mpt, ptgt->m_devhdl);
9130 				ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9131 				    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9132 				continue;
9133 			}
9134 
9135 			if ((ptgt->m_timeout) <=
9136 			    mptsas_scsi_watchdog_tick) {
9137 				NDBG23(("pending timeout"));
9138 				mptsas_set_throttle(mpt, ptgt,
9139 				    DRAIN_THROTTLE);
9140 			}
9141 		}
9142 
9143 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9144 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9145 	}
9146 }
9147 
9148 /*
9149  * timeout recovery
9150  */
9151 static void
9152 mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl)
9153 {
9154 
9155 	NDBG29(("mptsas_cmd_timeout: target=%d", devhdl));
9156 	mptsas_log(mpt, CE_WARN, "Disconnected command timeout for "
9157 	    "Target %d", devhdl);
9158 
9159 	/*
9160 	 * If the current target is not the target passed in,
9161 	 * try to reset that target.
9162 	 */
9163 	NDBG29(("mptsas_cmd_timeout: device reset"));
9164 	if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) {
9165 		mptsas_log(mpt, CE_WARN, "Target %d reset for command timeout "
9166 		    "recovery failed!", devhdl);
9167 	}
9168 }
9169 
9170 /*
9171  * Device / Hotplug control
9172  */
9173 static int
9174 mptsas_scsi_quiesce(dev_info_t *dip)
9175 {
9176 	mptsas_t	*mpt;
9177 	scsi_hba_tran_t	*tran;
9178 
9179 	tran = ddi_get_driver_private(dip);
9180 	if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
9181 		return (-1);
9182 
9183 	return (mptsas_quiesce_bus(mpt));
9184 }
9185 
9186 static int
9187 mptsas_scsi_unquiesce(dev_info_t *dip)
9188 {
9189 	mptsas_t		*mpt;
9190 	scsi_hba_tran_t	*tran;
9191 
9192 	tran = ddi_get_driver_private(dip);
9193 	if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
9194 		return (-1);
9195 
9196 	return (mptsas_unquiesce_bus(mpt));
9197 }
9198 
9199 static int
9200 mptsas_quiesce_bus(mptsas_t *mpt)
9201 {
9202 	mptsas_target_t	*ptgt = NULL;
9203 
9204 	NDBG28(("mptsas_quiesce_bus"));
9205 	mutex_enter(&mpt->m_mutex);
9206 
9207 	/* Set all the throttles to zero */
9208 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
9209 	    MPTSAS_HASH_FIRST);
9210 	while (ptgt != NULL) {
9211 		mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9212 
9213 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9214 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9215 	}
9216 
9217 	/* If there are any outstanding commands in the queue */
9218 	if (mpt->m_ncmds) {
9219 		mpt->m_softstate |= MPTSAS_SS_DRAINING;
9220 		mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
9221 		    mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000)));
9222 		if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) {
9223 			/*
9224 			 * Quiesce has been interrupted
9225 			 */
9226 			mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
9227 			ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9228 			    &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
9229 			while (ptgt != NULL) {
9230 				mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9231 
9232 				ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9233 				    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9234 			}
9235 			mptsas_restart_hba(mpt);
9236 			if (mpt->m_quiesce_timeid != 0) {
9237 				timeout_id_t tid = mpt->m_quiesce_timeid;
9238 				mpt->m_quiesce_timeid = 0;
9239 				mutex_exit(&mpt->m_mutex);
9240 				(void) untimeout(tid);
9241 				return (-1);
9242 			}
9243 			mutex_exit(&mpt->m_mutex);
9244 			return (-1);
9245 		} else {
9246 			/* Bus has been quiesced */
9247 			ASSERT(mpt->m_quiesce_timeid == 0);
9248 			mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
9249 			mpt->m_softstate |= MPTSAS_SS_QUIESCED;
9250 			mutex_exit(&mpt->m_mutex);
9251 			return (0);
9252 		}
9253 	}
9254 	/* Bus was not busy - QUIESCED */
9255 	mutex_exit(&mpt->m_mutex);
9256 
9257 	return (0);
9258 }
9259 
9260 static int
9261 mptsas_unquiesce_bus(mptsas_t *mpt)
9262 {
9263 	mptsas_target_t	*ptgt = NULL;
9264 
9265 	NDBG28(("mptsas_unquiesce_bus"));
9266 	mutex_enter(&mpt->m_mutex);
9267 	mpt->m_softstate &= ~MPTSAS_SS_QUIESCED;
9268 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
9269 	    MPTSAS_HASH_FIRST);
9270 	while (ptgt != NULL) {
9271 		mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9272 
9273 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9274 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9275 	}
9276 	mptsas_restart_hba(mpt);
9277 	mutex_exit(&mpt->m_mutex);
9278 	return (0);
9279 }
9280 
9281 static void
9282 mptsas_ncmds_checkdrain(void *arg)
9283 {
9284 	mptsas_t	*mpt = arg;
9285 	mptsas_target_t	*ptgt = NULL;
9286 
9287 	mutex_enter(&mpt->m_mutex);
9288 	if (mpt->m_softstate & MPTSAS_SS_DRAINING) {
9289 		mpt->m_quiesce_timeid = 0;
9290 		if (mpt->m_ncmds == 0) {
9291 			/* Command queue has been drained */
9292 			cv_signal(&mpt->m_cv);
9293 		} else {
9294 			/*
9295 			 * The throttle may have been reset because
9296 			 * of a SCSI bus reset
9297 			 */
9298 			ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9299 			    &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
9300 			while (ptgt != NULL) {
9301 				mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9302 
9303 				ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9304 				    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9305 			}
9306 
9307 			mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
9308 			    mpt, (MPTSAS_QUIESCE_TIMEOUT *
9309 			    drv_usectohz(1000000)));
9310 		}
9311 	}
9312 	mutex_exit(&mpt->m_mutex);
9313 }
9314 
9315 static void
9316 mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
9317 {
9318 	int	i;
9319 	uint8_t	*cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp;
9320 	char	buf[128];
9321 
9322 	buf[0] = '\0';
9323 	mptsas_log(mpt, CE_NOTE, "?Cmd (0x%p) dump for Target %d Lun %d:\n",
9324 	    (void *)cmd, Tgt(cmd), Lun(cmd));
9325 	(void) sprintf(&buf[0], "\tcdb=[");
9326 	for (i = 0; i < (int)cmd->cmd_cdblen; i++) {
9327 		(void) sprintf(&buf[strlen(buf)], " 0x%x", *cp++);
9328 	}
9329 	(void) sprintf(&buf[strlen(buf)], " ]");
9330 	mptsas_log(mpt, CE_NOTE, "?%s\n", buf);
9331 	mptsas_log(mpt, CE_NOTE,
9332 	    "?pkt_flags=0x%x pkt_statistics=0x%x pkt_state=0x%x\n",
9333 	    cmd->cmd_pkt->pkt_flags, cmd->cmd_pkt->pkt_statistics,
9334 	    cmd->cmd_pkt->pkt_state);
9335 	mptsas_log(mpt, CE_NOTE, "?pkt_scbp=0x%x cmd_flags=0x%x\n",
9336 	    *(cmd->cmd_pkt->pkt_scbp), cmd->cmd_flags);
9337 }
9338 
9339 static void
9340 mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd)
9341 {
9342 	caddr_t			memp;
9343 	pMPI2RequestHeader_t	request_hdrp;
9344 	struct scsi_pkt		*pkt = cmd->cmd_pkt;
9345 	mptsas_pt_request_t	*pt = pkt->pkt_ha_private;
9346 	uint32_t		request_size, data_size, dataout_size;
9347 	uint32_t		direction;
9348 	ddi_dma_cookie_t	data_cookie;
9349 	ddi_dma_cookie_t	dataout_cookie;
9350 	uint32_t		request_desc_low, request_desc_high = 0;
9351 	uint32_t		i, sense_bufp;
9352 	uint8_t			desc_type;
9353 	uint8_t			*request, function;
9354 	ddi_dma_handle_t	dma_hdl = mpt->m_dma_req_frame_hdl;
9355 	ddi_acc_handle_t	acc_hdl = mpt->m_acc_req_frame_hdl;
9356 
9357 	desc_type = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
9358 
9359 	request = pt->request;
9360 	direction = pt->direction;
9361 	request_size = pt->request_size;
9362 	data_size = pt->data_size;
9363 	dataout_size = pt->dataout_size;
9364 	data_cookie = pt->data_cookie;
9365 	dataout_cookie = pt->dataout_cookie;
9366 
9367 	/*
9368 	 * Store the passthrough message in memory location
9369 	 * corresponding to our slot number
9370 	 */
9371 	memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot);
9372 	request_hdrp = (pMPI2RequestHeader_t)memp;
9373 	bzero(memp, mpt->m_req_frame_size);
9374 
9375 	for (i = 0; i < request_size; i++) {
9376 		bcopy(request + i, memp + i, 1);
9377 	}
9378 
9379 	if (data_size || dataout_size) {
9380 		pMpi2SGESimple64_t	sgep;
9381 		uint32_t		sge_flags;
9382 
9383 		sgep = (pMpi2SGESimple64_t)((uint8_t *)request_hdrp +
9384 		    request_size);
9385 		if (dataout_size) {
9386 
9387 			sge_flags = dataout_size |
9388 			    ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
9389 			    MPI2_SGE_FLAGS_END_OF_BUFFER |
9390 			    MPI2_SGE_FLAGS_HOST_TO_IOC |
9391 			    MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
9392 			    MPI2_SGE_FLAGS_SHIFT);
9393 			ddi_put32(acc_hdl, &sgep->FlagsLength, sge_flags);
9394 			ddi_put32(acc_hdl, &sgep->Address.Low,
9395 			    (uint32_t)(dataout_cookie.dmac_laddress &
9396 			    0xffffffffull));
9397 			ddi_put32(acc_hdl, &sgep->Address.High,
9398 			    (uint32_t)(dataout_cookie.dmac_laddress
9399 			    >> 32));
9400 			sgep++;
9401 		}
9402 		sge_flags = data_size;
9403 		sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
9404 		    MPI2_SGE_FLAGS_LAST_ELEMENT |
9405 		    MPI2_SGE_FLAGS_END_OF_BUFFER |
9406 		    MPI2_SGE_FLAGS_END_OF_LIST |
9407 		    MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
9408 		    MPI2_SGE_FLAGS_SHIFT);
9409 		if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) {
9410 			sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_HOST_TO_IOC) <<
9411 			    MPI2_SGE_FLAGS_SHIFT);
9412 		} else {
9413 			sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_IOC_TO_HOST) <<
9414 			    MPI2_SGE_FLAGS_SHIFT);
9415 		}
9416 		ddi_put32(acc_hdl, &sgep->FlagsLength,
9417 		    sge_flags);
9418 		ddi_put32(acc_hdl, &sgep->Address.Low,
9419 		    (uint32_t)(data_cookie.dmac_laddress &
9420 		    0xffffffffull));
9421 		ddi_put32(acc_hdl, &sgep->Address.High,
9422 		    (uint32_t)(data_cookie.dmac_laddress >> 32));
9423 	}
9424 
9425 	function = request_hdrp->Function;
9426 	if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
9427 	    (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
9428 		pMpi2SCSIIORequest_t	scsi_io_req;
9429 
9430 		scsi_io_req = (pMpi2SCSIIORequest_t)request_hdrp;
9431 		/*
9432 		 * Put SGE for data and data_out buffer at the end of
9433 		 * scsi_io_request message header.(64 bytes in total)
9434 		 * Following above SGEs, the residual space will be
9435 		 * used by sense data.
9436 		 */
9437 		ddi_put8(acc_hdl,
9438 		    &scsi_io_req->SenseBufferLength,
9439 		    (uint8_t)(request_size - 64));
9440 
9441 		sense_bufp = mpt->m_req_frame_dma_addr +
9442 		    (mpt->m_req_frame_size * cmd->cmd_slot);
9443 		sense_bufp += 64;
9444 		ddi_put32(acc_hdl,
9445 		    &scsi_io_req->SenseBufferLowAddress, sense_bufp);
9446 
9447 		/*
9448 		 * Set SGLOffset0 value
9449 		 */
9450 		ddi_put8(acc_hdl, &scsi_io_req->SGLOffset0,
9451 		    offsetof(MPI2_SCSI_IO_REQUEST, SGL) / 4);
9452 
9453 		/*
9454 		 * Setup descriptor info
9455 		 */
9456 		desc_type = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
9457 		request_desc_high = (ddi_get16(acc_hdl,
9458 		    &scsi_io_req->DevHandle) << 16);
9459 	}
9460 
9461 	/*
9462 	 * We must wait till the message has been completed before
9463 	 * beginning the next message so we wait for this one to
9464 	 * finish.
9465 	 */
9466 	(void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
9467 	request_desc_low = (cmd->cmd_slot << 16) + desc_type;
9468 	cmd->cmd_rfm = NULL;
9469 	MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high);
9470 	if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
9471 	    (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
9472 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
9473 	}
9474 }
9475 
9476 
9477 
9478 static int
9479 mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
9480     uint8_t *data, uint32_t request_size, uint32_t reply_size,
9481     uint32_t data_size, uint32_t direction, uint8_t *dataout,
9482     uint32_t dataout_size, short timeout, int mode)
9483 {
9484 	mptsas_pt_request_t		pt;
9485 	mptsas_dma_alloc_state_t	data_dma_state;
9486 	mptsas_dma_alloc_state_t	dataout_dma_state;
9487 	caddr_t				memp;
9488 	mptsas_cmd_t			*cmd = NULL;
9489 	struct scsi_pkt			*pkt;
9490 	uint32_t			reply_len = 0, sense_len = 0;
9491 	pMPI2RequestHeader_t		request_hdrp;
9492 	pMPI2RequestHeader_t		request_msg;
9493 	pMPI2DefaultReply_t		reply_msg;
9494 	Mpi2SCSIIOReply_t		rep_msg;
9495 	int				i, status = 0, pt_flags = 0, rv = 0;
9496 	int				rvalue;
9497 	uint8_t				function;
9498 
9499 	ASSERT(mutex_owned(&mpt->m_mutex));
9500 
9501 	reply_msg = (pMPI2DefaultReply_t)(&rep_msg);
9502 	bzero(reply_msg, sizeof (MPI2_DEFAULT_REPLY));
9503 	request_msg = kmem_zalloc(request_size, KM_SLEEP);
9504 
9505 	mutex_exit(&mpt->m_mutex);
9506 	/*
9507 	 * copy in the request buffer since it could be used by
9508 	 * another thread when the pt request into waitq
9509 	 */
9510 	if (ddi_copyin(request, request_msg, request_size, mode)) {
9511 		mutex_enter(&mpt->m_mutex);
9512 		status = EFAULT;
9513 		mptsas_log(mpt, CE_WARN, "failed to copy request data");
9514 		goto out;
9515 	}
9516 	mutex_enter(&mpt->m_mutex);
9517 
9518 	function = request_msg->Function;
9519 	if (function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
9520 		pMpi2SCSITaskManagementRequest_t	task;
9521 		task = (pMpi2SCSITaskManagementRequest_t)request_msg;
9522 		mptsas_setup_bus_reset_delay(mpt);
9523 		rv = mptsas_ioc_task_management(mpt, task->TaskType,
9524 		    task->DevHandle, (int)task->LUN[1]);
9525 
9526 		if (rv != TRUE) {
9527 			status = EIO;
9528 			mptsas_log(mpt, CE_WARN, "task management failed");
9529 		}
9530 		goto out;
9531 	}
9532 
9533 	if (data_size != 0) {
9534 		data_dma_state.size = data_size;
9535 		if (mptsas_dma_alloc(mpt, &data_dma_state) != DDI_SUCCESS) {
9536 			status = ENOMEM;
9537 			mptsas_log(mpt, CE_WARN, "failed to alloc DMA "
9538 			    "resource");
9539 			goto out;
9540 		}
9541 		pt_flags |= MPTSAS_DATA_ALLOCATED;
9542 		if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) {
9543 			mutex_exit(&mpt->m_mutex);
9544 			for (i = 0; i < data_size; i++) {
9545 				if (ddi_copyin(data + i, (uint8_t *)
9546 				    data_dma_state.memp + i, 1, mode)) {
9547 					mutex_enter(&mpt->m_mutex);
9548 					status = EFAULT;
9549 					mptsas_log(mpt, CE_WARN, "failed to "
9550 					    "copy read data");
9551 					goto out;
9552 				}
9553 			}
9554 			mutex_enter(&mpt->m_mutex);
9555 		}
9556 	}
9557 
9558 	if (dataout_size != 0) {
9559 		dataout_dma_state.size = dataout_size;
9560 		if (mptsas_dma_alloc(mpt, &dataout_dma_state) != DDI_SUCCESS) {
9561 			status = ENOMEM;
9562 			mptsas_log(mpt, CE_WARN, "failed to alloc DMA "
9563 			    "resource");
9564 			goto out;
9565 		}
9566 		pt_flags |= MPTSAS_DATAOUT_ALLOCATED;
9567 		mutex_exit(&mpt->m_mutex);
9568 		for (i = 0; i < dataout_size; i++) {
9569 			if (ddi_copyin(dataout + i, (uint8_t *)
9570 			    dataout_dma_state.memp + i, 1, mode)) {
9571 				mutex_enter(&mpt->m_mutex);
9572 				mptsas_log(mpt, CE_WARN, "failed to copy out"
9573 				    " data");
9574 				status = EFAULT;
9575 				goto out;
9576 			}
9577 		}
9578 		mutex_enter(&mpt->m_mutex);
9579 	}
9580 
9581 	if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
9582 		status = EAGAIN;
9583 		mptsas_log(mpt, CE_NOTE, "event ack command pool is full");
9584 		goto out;
9585 	}
9586 	pt_flags |= MPTSAS_REQUEST_POOL_CMD;
9587 
9588 	bzero((caddr_t)cmd, sizeof (*cmd));
9589 	bzero((caddr_t)pkt, scsi_pkt_size());
9590 	bzero((caddr_t)&pt, sizeof (pt));
9591 
9592 	cmd->ioc_cmd_slot = (uint32_t)(rvalue);
9593 
9594 	pt.request = (uint8_t *)request_msg;
9595 	pt.direction = direction;
9596 	pt.request_size = request_size;
9597 	pt.data_size = data_size;
9598 	pt.dataout_size = dataout_size;
9599 	pt.data_cookie = data_dma_state.cookie;
9600 	pt.dataout_cookie = dataout_dma_state.cookie;
9601 
9602 	/*
9603 	 * Form a blank cmd/pkt to store the acknowledgement message
9604 	 */
9605 	pkt->pkt_cdbp		= (opaque_t)&cmd->cmd_cdb[0];
9606 	pkt->pkt_scbp		= (opaque_t)&cmd->cmd_scb;
9607 	pkt->pkt_ha_private	= (opaque_t)&pt;
9608 	pkt->pkt_flags		= FLAG_HEAD;
9609 	pkt->pkt_time		= timeout;
9610 	cmd->cmd_pkt		= pkt;
9611 	cmd->cmd_flags		= CFLAG_CMDIOC | CFLAG_PASSTHRU;
9612 
9613 	/*
9614 	 * Save the command in a slot
9615 	 */
9616 	if (mptsas_save_cmd(mpt, cmd) == TRUE) {
9617 		/*
9618 		 * Once passthru command get slot, set cmd_flags
9619 		 * CFLAG_PREPARED.
9620 		 */
9621 		cmd->cmd_flags |= CFLAG_PREPARED;
9622 		mptsas_start_passthru(mpt, cmd);
9623 	} else {
9624 		mptsas_waitq_add(mpt, cmd);
9625 	}
9626 
9627 	while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
9628 		cv_wait(&mpt->m_passthru_cv, &mpt->m_mutex);
9629 	}
9630 
9631 	if (cmd->cmd_flags & CFLAG_PREPARED) {
9632 		memp = mpt->m_req_frame + (mpt->m_req_frame_size *
9633 		    cmd->cmd_slot);
9634 		request_hdrp = (pMPI2RequestHeader_t)memp;
9635 	}
9636 
9637 	if (cmd->cmd_flags & CFLAG_TIMEOUT) {
9638 		status = ETIMEDOUT;
9639 		mptsas_log(mpt, CE_WARN, "passthrough command timeout");
9640 		pt_flags |= MPTSAS_CMD_TIMEOUT;
9641 		goto out;
9642 	}
9643 
9644 	if (cmd->cmd_rfm) {
9645 		/*
9646 		 * cmd_rfm is zero means the command reply is a CONTEXT
9647 		 * reply and no PCI Write to post the free reply SMFA
9648 		 * because no reply message frame is used.
9649 		 * cmd_rfm is non-zero means the reply is a ADDRESS
9650 		 * reply and reply message frame is used.
9651 		 */
9652 		pt_flags |= MPTSAS_ADDRESS_REPLY;
9653 		(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
9654 		    DDI_DMA_SYNC_FORCPU);
9655 		reply_msg = (pMPI2DefaultReply_t)
9656 		    (mpt->m_reply_frame + (cmd->cmd_rfm -
9657 		    mpt->m_reply_frame_dma_addr));
9658 	}
9659 
9660 	mptsas_fma_check(mpt, cmd);
9661 	if (pkt->pkt_reason == CMD_TRAN_ERR) {
9662 		status = EAGAIN;
9663 		mptsas_log(mpt, CE_WARN, "passthru fma error");
9664 		goto out;
9665 	}
9666 	if (pkt->pkt_reason == CMD_RESET) {
9667 		status = EAGAIN;
9668 		mptsas_log(mpt, CE_WARN, "ioc reset abort passthru");
9669 		goto out;
9670 	}
9671 
9672 	if (pkt->pkt_reason == CMD_INCOMPLETE) {
9673 		status = EIO;
9674 		mptsas_log(mpt, CE_WARN, "passthrough command incomplete");
9675 		goto out;
9676 	}
9677 
9678 	mutex_exit(&mpt->m_mutex);
9679 	if (cmd->cmd_flags & CFLAG_PREPARED) {
9680 		function = request_hdrp->Function;
9681 		if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
9682 		    (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
9683 			reply_len = sizeof (MPI2_SCSI_IO_REPLY);
9684 			sense_len = reply_size - reply_len;
9685 		} else {
9686 			reply_len = reply_size;
9687 			sense_len = 0;
9688 		}
9689 
9690 		for (i = 0; i < reply_len; i++) {
9691 			if (ddi_copyout((uint8_t *)reply_msg + i, reply + i, 1,
9692 			    mode)) {
9693 				mutex_enter(&mpt->m_mutex);
9694 				status = EFAULT;
9695 				mptsas_log(mpt, CE_WARN, "failed to copy out "
9696 				    "reply data");
9697 				goto out;
9698 			}
9699 		}
9700 		for (i = 0; i < sense_len; i++) {
9701 			if (ddi_copyout((uint8_t *)request_hdrp + 64 + i,
9702 			    reply + reply_len + i, 1, mode)) {
9703 				mutex_enter(&mpt->m_mutex);
9704 				status = EFAULT;
9705 				mptsas_log(mpt, CE_WARN, "failed to copy out "
9706 				    "sense data");
9707 				goto out;
9708 			}
9709 		}
9710 	}
9711 
9712 	if (data_size) {
9713 		if (direction != MPTSAS_PASS_THRU_DIRECTION_WRITE) {
9714 			(void) ddi_dma_sync(data_dma_state.handle, 0, 0,
9715 			    DDI_DMA_SYNC_FORCPU);
9716 			for (i = 0; i < data_size; i++) {
9717 				if (ddi_copyout((uint8_t *)(
9718 				    data_dma_state.memp + i), data + i,  1,
9719 				    mode)) {
9720 					mutex_enter(&mpt->m_mutex);
9721 					status = EFAULT;
9722 					mptsas_log(mpt, CE_WARN, "failed to "
9723 					    "copy out the reply data");
9724 					goto out;
9725 				}
9726 			}
9727 		}
9728 	}
9729 	mutex_enter(&mpt->m_mutex);
9730 out:
9731 	/*
9732 	 * Put the reply frame back on the free queue, increment the free
9733 	 * index, and write the new index to the free index register.  But only
9734 	 * if this reply is an ADDRESS reply.
9735 	 */
9736 	if (pt_flags & MPTSAS_ADDRESS_REPLY) {
9737 		ddi_put32(mpt->m_acc_free_queue_hdl,
9738 		    &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
9739 		    cmd->cmd_rfm);
9740 		(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
9741 		    DDI_DMA_SYNC_FORDEV);
9742 		if (++mpt->m_free_index == mpt->m_free_queue_depth) {
9743 			mpt->m_free_index = 0;
9744 		}
9745 		ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
9746 		    mpt->m_free_index);
9747 	}
9748 	if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
9749 		mptsas_remove_cmd(mpt, cmd);
9750 		pt_flags &= (~MPTSAS_REQUEST_POOL_CMD);
9751 	}
9752 	if (pt_flags & MPTSAS_REQUEST_POOL_CMD)
9753 		mptsas_return_to_pool(mpt, cmd);
9754 	if (pt_flags & MPTSAS_DATA_ALLOCATED) {
9755 		if (mptsas_check_dma_handle(data_dma_state.handle) !=
9756 		    DDI_SUCCESS) {
9757 			ddi_fm_service_impact(mpt->m_dip,
9758 			    DDI_SERVICE_UNAFFECTED);
9759 			status = EFAULT;
9760 		}
9761 		mptsas_dma_free(&data_dma_state);
9762 	}
9763 	if (pt_flags & MPTSAS_DATAOUT_ALLOCATED) {
9764 		if (mptsas_check_dma_handle(dataout_dma_state.handle) !=
9765 		    DDI_SUCCESS) {
9766 			ddi_fm_service_impact(mpt->m_dip,
9767 			    DDI_SERVICE_UNAFFECTED);
9768 			status = EFAULT;
9769 		}
9770 		mptsas_dma_free(&dataout_dma_state);
9771 	}
9772 	if (pt_flags & MPTSAS_CMD_TIMEOUT) {
9773 		if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
9774 			mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed");
9775 		}
9776 	}
9777 	if (request_msg)
9778 		kmem_free(request_msg, request_size);
9779 
9780 	return (status);
9781 }
9782 
9783 static int
9784 mptsas_pass_thru(mptsas_t *mpt, mptsas_pass_thru_t *data, int mode)
9785 {
9786 	/*
9787 	 * If timeout is 0, set timeout to default of 60 seconds.
9788 	 */
9789 	if (data->Timeout == 0) {
9790 		data->Timeout = MPTSAS_PASS_THRU_TIME_DEFAULT;
9791 	}
9792 
9793 	if (((data->DataSize == 0) &&
9794 	    (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_NONE)) ||
9795 	    ((data->DataSize != 0) &&
9796 	    ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_READ) ||
9797 	    (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_WRITE) ||
9798 	    ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) &&
9799 	    (data->DataOutSize != 0))))) {
9800 		if (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) {
9801 			data->DataDirection = MPTSAS_PASS_THRU_DIRECTION_READ;
9802 		} else {
9803 			data->DataOutSize = 0;
9804 		}
9805 		/*
9806 		 * Send passthru request messages
9807 		 */
9808 		return (mptsas_do_passthru(mpt,
9809 		    (uint8_t *)((uintptr_t)data->PtrRequest),
9810 		    (uint8_t *)((uintptr_t)data->PtrReply),
9811 		    (uint8_t *)((uintptr_t)data->PtrData),
9812 		    data->RequestSize, data->ReplySize,
9813 		    data->DataSize, data->DataDirection,
9814 		    (uint8_t *)((uintptr_t)data->PtrDataOut),
9815 		    data->DataOutSize, data->Timeout, mode));
9816 	} else {
9817 		return (EINVAL);
9818 	}
9819 }
9820 
9821 static uint8_t
9822 mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, uint32_t unique_id)
9823 {
9824 	uint8_t	index;
9825 
9826 	for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) {
9827 		if (mpt->m_fw_diag_buffer_list[index].unique_id == unique_id) {
9828 			return (index);
9829 		}
9830 	}
9831 
9832 	return (MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND);
9833 }
9834 
9835 static void
9836 mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd)
9837 {
9838 	pMpi2DiagBufferPostRequest_t	pDiag_post_msg;
9839 	pMpi2DiagReleaseRequest_t	pDiag_release_msg;
9840 	struct scsi_pkt			*pkt = cmd->cmd_pkt;
9841 	mptsas_diag_request_t		*diag = pkt->pkt_ha_private;
9842 	uint32_t			request_desc_low, i;
9843 
9844 	ASSERT(mutex_owned(&mpt->m_mutex));
9845 
9846 	/*
9847 	 * Form the diag message depending on the post or release function.
9848 	 */
9849 	if (diag->function == MPI2_FUNCTION_DIAG_BUFFER_POST) {
9850 		pDiag_post_msg = (pMpi2DiagBufferPostRequest_t)
9851 		    (mpt->m_req_frame + (mpt->m_req_frame_size *
9852 		    cmd->cmd_slot));
9853 		bzero(pDiag_post_msg, mpt->m_req_frame_size);
9854 		ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->Function,
9855 		    diag->function);
9856 		ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->BufferType,
9857 		    diag->pBuffer->buffer_type);
9858 		ddi_put8(mpt->m_acc_req_frame_hdl,
9859 		    &pDiag_post_msg->ExtendedType,
9860 		    diag->pBuffer->extended_type);
9861 		ddi_put32(mpt->m_acc_req_frame_hdl,
9862 		    &pDiag_post_msg->BufferLength,
9863 		    diag->pBuffer->buffer_data.size);
9864 		for (i = 0; i < (sizeof (pDiag_post_msg->ProductSpecific) / 4);
9865 		    i++) {
9866 			ddi_put32(mpt->m_acc_req_frame_hdl,
9867 			    &pDiag_post_msg->ProductSpecific[i],
9868 			    diag->pBuffer->product_specific[i]);
9869 		}
9870 		ddi_put32(mpt->m_acc_req_frame_hdl,
9871 		    &pDiag_post_msg->BufferAddress.Low,
9872 		    (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress
9873 		    & 0xffffffffull));
9874 		ddi_put32(mpt->m_acc_req_frame_hdl,
9875 		    &pDiag_post_msg->BufferAddress.High,
9876 		    (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress
9877 		    >> 32));
9878 	} else {
9879 		pDiag_release_msg = (pMpi2DiagReleaseRequest_t)
9880 		    (mpt->m_req_frame + (mpt->m_req_frame_size *
9881 		    cmd->cmd_slot));
9882 		bzero(pDiag_release_msg, mpt->m_req_frame_size);
9883 		ddi_put8(mpt->m_acc_req_frame_hdl,
9884 		    &pDiag_release_msg->Function, diag->function);
9885 		ddi_put8(mpt->m_acc_req_frame_hdl,
9886 		    &pDiag_release_msg->BufferType,
9887 		    diag->pBuffer->buffer_type);
9888 	}
9889 
9890 	/*
9891 	 * Send the message
9892 	 */
9893 	(void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
9894 	    DDI_DMA_SYNC_FORDEV);
9895 	request_desc_low = (cmd->cmd_slot << 16) +
9896 	    MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
9897 	cmd->cmd_rfm = NULL;
9898 	MPTSAS_START_CMD(mpt, request_desc_low, 0);
9899 	if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
9900 	    DDI_SUCCESS) ||
9901 	    (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
9902 	    DDI_SUCCESS)) {
9903 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
9904 	}
9905 }
9906 
9907 static int
9908 mptsas_post_fw_diag_buffer(mptsas_t *mpt,
9909     mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code)
9910 {
9911 	mptsas_diag_request_t		diag;
9912 	int				status, slot_num, post_flags = 0;
9913 	mptsas_cmd_t			*cmd = NULL;
9914 	struct scsi_pkt			*pkt;
9915 	pMpi2DiagBufferPostReply_t	reply;
9916 	uint16_t			iocstatus;
9917 	uint32_t			iocloginfo, transfer_length;
9918 
9919 	/*
9920 	 * If buffer is not enabled, just leave.
9921 	 */
9922 	*return_code = MPTSAS_FW_DIAG_ERROR_POST_FAILED;
9923 	if (!pBuffer->enabled) {
9924 		status = DDI_FAILURE;
9925 		goto out;
9926 	}
9927 
9928 	/*
9929 	 * Clear some flags initially.
9930 	 */
9931 	pBuffer->force_release = FALSE;
9932 	pBuffer->valid_data = FALSE;
9933 	pBuffer->owned_by_firmware = FALSE;
9934 
9935 	/*
9936 	 * Get a cmd buffer from the cmd buffer pool
9937 	 */
9938 	if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
9939 		status = DDI_FAILURE;
9940 		mptsas_log(mpt, CE_NOTE, "command pool is full: Post FW Diag");
9941 		goto out;
9942 	}
9943 	post_flags |= MPTSAS_REQUEST_POOL_CMD;
9944 
9945 	bzero((caddr_t)cmd, sizeof (*cmd));
9946 	bzero((caddr_t)pkt, scsi_pkt_size());
9947 
9948 	cmd->ioc_cmd_slot = (uint32_t)(slot_num);
9949 
9950 	diag.pBuffer = pBuffer;
9951 	diag.function = MPI2_FUNCTION_DIAG_BUFFER_POST;
9952 
9953 	/*
9954 	 * Form a blank cmd/pkt to store the acknowledgement message
9955 	 */
9956 	pkt->pkt_ha_private	= (opaque_t)&diag;
9957 	pkt->pkt_flags		= FLAG_HEAD;
9958 	pkt->pkt_time		= 60;
9959 	cmd->cmd_pkt		= pkt;
9960 	cmd->cmd_flags		= CFLAG_CMDIOC | CFLAG_FW_DIAG;
9961 
9962 	/*
9963 	 * Save the command in a slot
9964 	 */
9965 	if (mptsas_save_cmd(mpt, cmd) == TRUE) {
9966 		/*
9967 		 * Once passthru command get slot, set cmd_flags
9968 		 * CFLAG_PREPARED.
9969 		 */
9970 		cmd->cmd_flags |= CFLAG_PREPARED;
9971 		mptsas_start_diag(mpt, cmd);
9972 	} else {
9973 		mptsas_waitq_add(mpt, cmd);
9974 	}
9975 
9976 	while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
9977 		cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex);
9978 	}
9979 
9980 	if (cmd->cmd_flags & CFLAG_TIMEOUT) {
9981 		status = DDI_FAILURE;
9982 		mptsas_log(mpt, CE_WARN, "Post FW Diag command timeout");
9983 		goto out;
9984 	}
9985 
9986 	/*
9987 	 * cmd_rfm points to the reply message if a reply was given.  Check the
9988 	 * IOCStatus to make sure everything went OK with the FW diag request
9989 	 * and set buffer flags.
9990 	 */
9991 	if (cmd->cmd_rfm) {
9992 		post_flags |= MPTSAS_ADDRESS_REPLY;
9993 		(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
9994 		    DDI_DMA_SYNC_FORCPU);
9995 		reply = (pMpi2DiagBufferPostReply_t)(mpt->m_reply_frame +
9996 		    (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr));
9997 
9998 		/*
9999 		 * Get the reply message data
10000 		 */
10001 		iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
10002 		    &reply->IOCStatus);
10003 		iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
10004 		    &reply->IOCLogInfo);
10005 		transfer_length = ddi_get32(mpt->m_acc_reply_frame_hdl,
10006 		    &reply->TransferLength);
10007 
10008 		/*
10009 		 * If post failed quit.
10010 		 */
10011 		if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
10012 			status = DDI_FAILURE;
10013 			NDBG13(("post FW Diag Buffer failed: IOCStatus=0x%x, "
10014 			    "IOCLogInfo=0x%x, TransferLength=0x%x", iocstatus,
10015 			    iocloginfo, transfer_length));
10016 			goto out;
10017 		}
10018 
10019 		/*
10020 		 * Post was successful.
10021 		 */
10022 		pBuffer->valid_data = TRUE;
10023 		pBuffer->owned_by_firmware = TRUE;
10024 		*return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS;
10025 		status = DDI_SUCCESS;
10026 	}
10027 
10028 out:
10029 	/*
10030 	 * Put the reply frame back on the free queue, increment the free
10031 	 * index, and write the new index to the free index register.  But only
10032 	 * if this reply is an ADDRESS reply.
10033 	 */
10034 	if (post_flags & MPTSAS_ADDRESS_REPLY) {
10035 		ddi_put32(mpt->m_acc_free_queue_hdl,
10036 		    &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
10037 		    cmd->cmd_rfm);
10038 		(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
10039 		    DDI_DMA_SYNC_FORDEV);
10040 		if (++mpt->m_free_index == mpt->m_free_queue_depth) {
10041 			mpt->m_free_index = 0;
10042 		}
10043 		ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
10044 		    mpt->m_free_index);
10045 	}
10046 	if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
10047 		mptsas_remove_cmd(mpt, cmd);
10048 		post_flags &= (~MPTSAS_REQUEST_POOL_CMD);
10049 	}
10050 	if (post_flags & MPTSAS_REQUEST_POOL_CMD) {
10051 		mptsas_return_to_pool(mpt, cmd);
10052 	}
10053 
10054 	return (status);
10055 }
10056 
10057 static int
10058 mptsas_release_fw_diag_buffer(mptsas_t *mpt,
10059     mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code,
10060     uint32_t diag_type)
10061 {
10062 	mptsas_diag_request_t	diag;
10063 	int			status, slot_num, rel_flags = 0;
10064 	mptsas_cmd_t		*cmd = NULL;
10065 	struct scsi_pkt		*pkt;
10066 	pMpi2DiagReleaseReply_t	reply;
10067 	uint16_t		iocstatus;
10068 	uint32_t		iocloginfo;
10069 
10070 	/*
10071 	 * If buffer is not enabled, just leave.
10072 	 */
10073 	*return_code = MPTSAS_FW_DIAG_ERROR_RELEASE_FAILED;
10074 	if (!pBuffer->enabled) {
10075 		mptsas_log(mpt, CE_NOTE, "This buffer type is not supported "
10076 		    "by the IOC");
10077 		status = DDI_FAILURE;
10078 		goto out;
10079 	}
10080 
10081 	/*
10082 	 * Clear some flags initially.
10083 	 */
10084 	pBuffer->force_release = FALSE;
10085 	pBuffer->valid_data = FALSE;
10086 	pBuffer->owned_by_firmware = FALSE;
10087 
10088 	/*
10089 	 * Get a cmd buffer from the cmd buffer pool
10090 	 */
10091 	if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
10092 		status = DDI_FAILURE;
10093 		mptsas_log(mpt, CE_NOTE, "command pool is full: Release FW "
10094 		    "Diag");
10095 		goto out;
10096 	}
10097 	rel_flags |= MPTSAS_REQUEST_POOL_CMD;
10098 
10099 	bzero((caddr_t)cmd, sizeof (*cmd));
10100 	bzero((caddr_t)pkt, scsi_pkt_size());
10101 
10102 	cmd->ioc_cmd_slot = (uint32_t)(slot_num);
10103 
10104 	diag.pBuffer = pBuffer;
10105 	diag.function = MPI2_FUNCTION_DIAG_RELEASE;
10106 
10107 	/*
10108 	 * Form a blank cmd/pkt to store the acknowledgement message
10109 	 */
10110 	pkt->pkt_ha_private	= (opaque_t)&diag;
10111 	pkt->pkt_flags		= FLAG_HEAD;
10112 	pkt->pkt_time		= 60;
10113 	cmd->cmd_pkt		= pkt;
10114 	cmd->cmd_flags		= CFLAG_CMDIOC | CFLAG_FW_DIAG;
10115 
10116 	/*
10117 	 * Save the command in a slot
10118 	 */
10119 	if (mptsas_save_cmd(mpt, cmd) == TRUE) {
10120 		/*
10121 		 * Once passthru command get slot, set cmd_flags
10122 		 * CFLAG_PREPARED.
10123 		 */
10124 		cmd->cmd_flags |= CFLAG_PREPARED;
10125 		mptsas_start_diag(mpt, cmd);
10126 	} else {
10127 		mptsas_waitq_add(mpt, cmd);
10128 	}
10129 
10130 	while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
10131 		cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex);
10132 	}
10133 
10134 	if (cmd->cmd_flags & CFLAG_TIMEOUT) {
10135 		status = DDI_FAILURE;
10136 		mptsas_log(mpt, CE_WARN, "Release FW Diag command timeout");
10137 		goto out;
10138 	}
10139 
10140 	/*
10141 	 * cmd_rfm points to the reply message if a reply was given.  Check the
10142 	 * IOCStatus to make sure everything went OK with the FW diag request
10143 	 * and set buffer flags.
10144 	 */
10145 	if (cmd->cmd_rfm) {
10146 		rel_flags |= MPTSAS_ADDRESS_REPLY;
10147 		(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
10148 		    DDI_DMA_SYNC_FORCPU);
10149 		reply = (pMpi2DiagReleaseReply_t)(mpt->m_reply_frame +
10150 		    (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr));
10151 
10152 		/*
10153 		 * Get the reply message data
10154 		 */
10155 		iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
10156 		    &reply->IOCStatus);
10157 		iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
10158 		    &reply->IOCLogInfo);
10159 
10160 		/*
10161 		 * If release failed quit.
10162 		 */
10163 		if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) ||
10164 		    pBuffer->owned_by_firmware) {
10165 			status = DDI_FAILURE;
10166 			NDBG13(("release FW Diag Buffer failed: "
10167 			    "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
10168 			    iocloginfo));
10169 			goto out;
10170 		}
10171 
10172 		/*
10173 		 * Release was successful.
10174 		 */
10175 		*return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS;
10176 		status = DDI_SUCCESS;
10177 
10178 		/*
10179 		 * If this was for an UNREGISTER diag type command, clear the
10180 		 * unique ID.
10181 		 */
10182 		if (diag_type == MPTSAS_FW_DIAG_TYPE_UNREGISTER) {
10183 			pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID;
10184 		}
10185 	}
10186 
10187 out:
10188 	/*
10189 	 * Put the reply frame back on the free queue, increment the free
10190 	 * index, and write the new index to the free index register.  But only
10191 	 * if this reply is an ADDRESS reply.
10192 	 */
10193 	if (rel_flags & MPTSAS_ADDRESS_REPLY) {
10194 		ddi_put32(mpt->m_acc_free_queue_hdl,
10195 		    &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
10196 		    cmd->cmd_rfm);
10197 		(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
10198 		    DDI_DMA_SYNC_FORDEV);
10199 		if (++mpt->m_free_index == mpt->m_free_queue_depth) {
10200 			mpt->m_free_index = 0;
10201 		}
10202 		ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
10203 		    mpt->m_free_index);
10204 	}
10205 	if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
10206 		mptsas_remove_cmd(mpt, cmd);
10207 		rel_flags &= (~MPTSAS_REQUEST_POOL_CMD);
10208 	}
10209 	if (rel_flags & MPTSAS_REQUEST_POOL_CMD) {
10210 		mptsas_return_to_pool(mpt, cmd);
10211 	}
10212 
10213 	return (status);
10214 }
10215 
10216 static int
10217 mptsas_diag_register(mptsas_t *mpt, mptsas_fw_diag_register_t *diag_register,
10218     uint32_t *return_code)
10219 {
10220 	mptsas_fw_diagnostic_buffer_t	*pBuffer;
10221 	uint8_t				extended_type, buffer_type, i;
10222 	uint32_t			buffer_size;
10223 	uint32_t			unique_id;
10224 	int				status;
10225 
10226 	ASSERT(mutex_owned(&mpt->m_mutex));
10227 
10228 	extended_type = diag_register->ExtendedType;
10229 	buffer_type = diag_register->BufferType;
10230 	buffer_size = diag_register->RequestedBufferSize;
10231 	unique_id = diag_register->UniqueId;
10232 
10233 	/*
10234 	 * Check for valid buffer type
10235 	 */
10236 	if (buffer_type >= MPI2_DIAG_BUF_TYPE_COUNT) {
10237 		*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
10238 		return (DDI_FAILURE);
10239 	}
10240 
10241 	/*
10242 	 * Get the current buffer and look up the unique ID.  The unique ID
10243 	 * should not be found.  If it is, the ID is already in use.
10244 	 */
10245 	i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
10246 	pBuffer = &mpt->m_fw_diag_buffer_list[buffer_type];
10247 	if (i != MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
10248 		*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
10249 		return (DDI_FAILURE);
10250 	}
10251 
10252 	/*
10253 	 * The buffer's unique ID should not be registered yet, and the given
10254 	 * unique ID cannot be 0.
10255 	 */
10256 	if ((pBuffer->unique_id != MPTSAS_FW_DIAG_INVALID_UID) ||
10257 	    (unique_id == MPTSAS_FW_DIAG_INVALID_UID)) {
10258 		*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
10259 		return (DDI_FAILURE);
10260 	}
10261 
10262 	/*
10263 	 * If this buffer is already posted as immediate, just change owner.
10264 	 */
10265 	if (pBuffer->immediate && pBuffer->owned_by_firmware &&
10266 	    (pBuffer->unique_id == MPTSAS_FW_DIAG_INVALID_UID)) {
10267 		pBuffer->immediate = FALSE;
10268 		pBuffer->unique_id = unique_id;
10269 		return (DDI_SUCCESS);
10270 	}
10271 
10272 	/*
10273 	 * Post a new buffer after checking if it's enabled.  The DMA buffer
10274 	 * that is allocated will be contiguous (sgl_len = 1).
10275 	 */
10276 	if (!pBuffer->enabled) {
10277 		*return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER;
10278 		return (DDI_FAILURE);
10279 	}
10280 	bzero(&pBuffer->buffer_data, sizeof (mptsas_dma_alloc_state_t));
10281 	pBuffer->buffer_data.size = buffer_size;
10282 	if (mptsas_dma_alloc(mpt, &pBuffer->buffer_data) != DDI_SUCCESS) {
10283 		mptsas_log(mpt, CE_WARN, "failed to alloc DMA resource for "
10284 		    "diag buffer: size = %d bytes", buffer_size);
10285 		*return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER;
10286 		return (DDI_FAILURE);
10287 	}
10288 
10289 	/*
10290 	 * Copy the given info to the diag buffer and post the buffer.
10291 	 */
10292 	pBuffer->buffer_type = buffer_type;
10293 	pBuffer->immediate = FALSE;
10294 	if (buffer_type == MPI2_DIAG_BUF_TYPE_TRACE) {
10295 		for (i = 0; i < (sizeof (pBuffer->product_specific) / 4);
10296 		    i++) {
10297 			pBuffer->product_specific[i] =
10298 			    diag_register->ProductSpecific[i];
10299 		}
10300 	}
10301 	pBuffer->extended_type = extended_type;
10302 	pBuffer->unique_id = unique_id;
10303 	status = mptsas_post_fw_diag_buffer(mpt, pBuffer, return_code);
10304 
10305 	if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) !=
10306 	    DDI_SUCCESS) {
10307 		mptsas_log(mpt, CE_WARN, "Check of DMA handle failed in "
10308 		    "mptsas_diag_register.");
10309 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
10310 			status = DDI_FAILURE;
10311 	}
10312 
10313 	/*
10314 	 * In case there was a failure, free the DMA buffer.
10315 	 */
10316 	if (status == DDI_FAILURE) {
10317 		mptsas_dma_free(&pBuffer->buffer_data);
10318 	}
10319 
10320 	return (status);
10321 }
10322 
10323 static int
10324 mptsas_diag_unregister(mptsas_t *mpt,
10325     mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code)
10326 {
10327 	mptsas_fw_diagnostic_buffer_t	*pBuffer;
10328 	uint8_t				i;
10329 	uint32_t			unique_id;
10330 	int				status;
10331 
10332 	ASSERT(mutex_owned(&mpt->m_mutex));
10333 
10334 	unique_id = diag_unregister->UniqueId;
10335 
10336 	/*
10337 	 * Get the current buffer and look up the unique ID.  The unique ID
10338 	 * should be there.
10339 	 */
10340 	i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
10341 	if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
10342 		*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
10343 		return (DDI_FAILURE);
10344 	}
10345 
10346 	pBuffer = &mpt->m_fw_diag_buffer_list[i];
10347 
10348 	/*
10349 	 * Try to release the buffer from FW before freeing it.  If release
10350 	 * fails, don't free the DMA buffer in case FW tries to access it
10351 	 * later.  If buffer is not owned by firmware, can't release it.
10352 	 */
10353 	if (!pBuffer->owned_by_firmware) {
10354 		status = DDI_SUCCESS;
10355 	} else {
10356 		status = mptsas_release_fw_diag_buffer(mpt, pBuffer,
10357 		    return_code, MPTSAS_FW_DIAG_TYPE_UNREGISTER);
10358 	}
10359 
10360 	/*
10361 	 * At this point, return the current status no matter what happens with
10362 	 * the DMA buffer.
10363 	 */
10364 	pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID;
10365 	if (status == DDI_SUCCESS) {
10366 		if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) !=
10367 		    DDI_SUCCESS) {
10368 			mptsas_log(mpt, CE_WARN, "Check of DMA handle failed "
10369 			    "in mptsas_diag_unregister.");
10370 			ddi_fm_service_impact(mpt->m_dip,
10371 			    DDI_SERVICE_UNAFFECTED);
10372 		}
10373 		mptsas_dma_free(&pBuffer->buffer_data);
10374 	}
10375 
10376 	return (status);
10377 }
10378 
10379 static int
10380 mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query,
10381     uint32_t *return_code)
10382 {
10383 	mptsas_fw_diagnostic_buffer_t	*pBuffer;
10384 	uint8_t				i;
10385 	uint32_t			unique_id;
10386 
10387 	ASSERT(mutex_owned(&mpt->m_mutex));
10388 
10389 	unique_id = diag_query->UniqueId;
10390 
10391 	/*
10392 	 * If ID is valid, query on ID.
10393 	 * If ID is invalid, query on buffer type.
10394 	 */
10395 	if (unique_id == MPTSAS_FW_DIAG_INVALID_UID) {
10396 		i = diag_query->BufferType;
10397 		if (i >= MPI2_DIAG_BUF_TYPE_COUNT) {
10398 			*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
10399 			return (DDI_FAILURE);
10400 		}
10401 	} else {
10402 		i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
10403 		if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
10404 			*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
10405 			return (DDI_FAILURE);
10406 		}
10407 	}
10408 
10409 	/*
10410 	 * Fill query structure with the diag buffer info.
10411 	 */
10412 	pBuffer = &mpt->m_fw_diag_buffer_list[i];
10413 	diag_query->BufferType = pBuffer->buffer_type;
10414 	diag_query->ExtendedType = pBuffer->extended_type;
10415 	if (diag_query->BufferType == MPI2_DIAG_BUF_TYPE_TRACE) {
10416 		for (i = 0; i < (sizeof (diag_query->ProductSpecific) / 4);
10417 		    i++) {
10418 			diag_query->ProductSpecific[i] =
10419 			    pBuffer->product_specific[i];
10420 		}
10421 	}
10422 	diag_query->TotalBufferSize = pBuffer->buffer_data.size;
10423 	diag_query->DriverAddedBufferSize = 0;
10424 	diag_query->UniqueId = pBuffer->unique_id;
10425 	diag_query->ApplicationFlags = 0;
10426 	diag_query->DiagnosticFlags = 0;
10427 
10428 	/*
10429 	 * Set/Clear application flags
10430 	 */
10431 	if (pBuffer->immediate) {
10432 		diag_query->ApplicationFlags &= ~MPTSAS_FW_DIAG_FLAG_APP_OWNED;
10433 	} else {
10434 		diag_query->ApplicationFlags |= MPTSAS_FW_DIAG_FLAG_APP_OWNED;
10435 	}
10436 	if (pBuffer->valid_data || pBuffer->owned_by_firmware) {
10437 		diag_query->ApplicationFlags |=
10438 		    MPTSAS_FW_DIAG_FLAG_BUFFER_VALID;
10439 	} else {
10440 		diag_query->ApplicationFlags &=
10441 		    ~MPTSAS_FW_DIAG_FLAG_BUFFER_VALID;
10442 	}
10443 	if (pBuffer->owned_by_firmware) {
10444 		diag_query->ApplicationFlags |=
10445 		    MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS;
10446 	} else {
10447 		diag_query->ApplicationFlags &=
10448 		    ~MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS;
10449 	}
10450 
10451 	return (DDI_SUCCESS);
10452 }
10453 
10454 static int
10455 mptsas_diag_read_buffer(mptsas_t *mpt,
10456     mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf,
10457     uint32_t *return_code, int ioctl_mode)
10458 {
10459 	mptsas_fw_diagnostic_buffer_t	*pBuffer;
10460 	uint8_t				i, *pData;
10461 	uint32_t			unique_id, byte;
10462 	int				status;
10463 
10464 	ASSERT(mutex_owned(&mpt->m_mutex));
10465 
10466 	unique_id = diag_read_buffer->UniqueId;
10467 
10468 	/*
10469 	 * Get the current buffer and look up the unique ID.  The unique ID
10470 	 * should be there.
10471 	 */
10472 	i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
10473 	if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
10474 		*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
10475 		return (DDI_FAILURE);
10476 	}
10477 
10478 	pBuffer = &mpt->m_fw_diag_buffer_list[i];
10479 
10480 	/*
10481 	 * Make sure requested read is within limits
10482 	 */
10483 	if (diag_read_buffer->StartingOffset + diag_read_buffer->BytesToRead >
10484 	    pBuffer->buffer_data.size) {
10485 		*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
10486 		return (DDI_FAILURE);
10487 	}
10488 
10489 	/*
10490 	 * Copy the requested data from DMA to the diag_read_buffer.  The DMA
10491 	 * buffer that was allocated is one contiguous buffer.
10492 	 */
10493 	pData = (uint8_t *)(pBuffer->buffer_data.memp +
10494 	    diag_read_buffer->StartingOffset);
10495 	(void) ddi_dma_sync(pBuffer->buffer_data.handle, 0, 0,
10496 	    DDI_DMA_SYNC_FORCPU);
10497 	for (byte = 0; byte < diag_read_buffer->BytesToRead; byte++) {
10498 		if (ddi_copyout(pData + byte, ioctl_buf + byte, 1, ioctl_mode)
10499 		    != 0) {
10500 			return (DDI_FAILURE);
10501 		}
10502 	}
10503 	diag_read_buffer->Status = 0;
10504 
10505 	/*
10506 	 * Set or clear the Force Release flag.
10507 	 */
10508 	if (pBuffer->force_release) {
10509 		diag_read_buffer->Flags |= MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE;
10510 	} else {
10511 		diag_read_buffer->Flags &= ~MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE;
10512 	}
10513 
10514 	/*
10515 	 * If buffer is to be reregistered, make sure it's not already owned by
10516 	 * firmware first.
10517 	 */
10518 	status = DDI_SUCCESS;
10519 	if (!pBuffer->owned_by_firmware) {
10520 		if (diag_read_buffer->Flags & MPTSAS_FW_DIAG_FLAG_REREGISTER) {
10521 			status = mptsas_post_fw_diag_buffer(mpt, pBuffer,
10522 			    return_code);
10523 		}
10524 	}
10525 
10526 	return (status);
10527 }
10528 
10529 static int
10530 mptsas_diag_release(mptsas_t *mpt, mptsas_fw_diag_release_t *diag_release,
10531     uint32_t *return_code)
10532 {
10533 	mptsas_fw_diagnostic_buffer_t	*pBuffer;
10534 	uint8_t				i;
10535 	uint32_t			unique_id;
10536 	int				status;
10537 
10538 	ASSERT(mutex_owned(&mpt->m_mutex));
10539 
10540 	unique_id = diag_release->UniqueId;
10541 
10542 	/*
10543 	 * Get the current buffer and look up the unique ID.  The unique ID
10544 	 * should be there.
10545 	 */
10546 	i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
10547 	if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
10548 		*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
10549 		return (DDI_FAILURE);
10550 	}
10551 
10552 	pBuffer = &mpt->m_fw_diag_buffer_list[i];
10553 
10554 	/*
10555 	 * If buffer is not owned by firmware, it's already been released.
10556 	 */
10557 	if (!pBuffer->owned_by_firmware) {
10558 		*return_code = MPTSAS_FW_DIAG_ERROR_ALREADY_RELEASED;
10559 		return (DDI_FAILURE);
10560 	}
10561 
10562 	/*
10563 	 * Release the buffer.
10564 	 */
10565 	status = mptsas_release_fw_diag_buffer(mpt, pBuffer, return_code,
10566 	    MPTSAS_FW_DIAG_TYPE_RELEASE);
10567 	return (status);
10568 }
10569 
10570 static int
10571 mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, uint8_t *diag_action,
10572     uint32_t length, uint32_t *return_code, int ioctl_mode)
10573 {
10574 	mptsas_fw_diag_register_t	diag_register;
10575 	mptsas_fw_diag_unregister_t	diag_unregister;
10576 	mptsas_fw_diag_query_t		diag_query;
10577 	mptsas_diag_read_buffer_t	diag_read_buffer;
10578 	mptsas_fw_diag_release_t	diag_release;
10579 	int				status = DDI_SUCCESS;
10580 	uint32_t			original_return_code, read_buf_len;
10581 
10582 	ASSERT(mutex_owned(&mpt->m_mutex));
10583 
10584 	original_return_code = *return_code;
10585 	*return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS;
10586 
10587 	switch (action) {
10588 		case MPTSAS_FW_DIAG_TYPE_REGISTER:
10589 			if (!length) {
10590 				*return_code =
10591 				    MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
10592 				status = DDI_FAILURE;
10593 				break;
10594 			}
10595 			if (ddi_copyin(diag_action, &diag_register,
10596 			    sizeof (diag_register), ioctl_mode) != 0) {
10597 				return (DDI_FAILURE);
10598 			}
10599 			status = mptsas_diag_register(mpt, &diag_register,
10600 			    return_code);
10601 			break;
10602 
10603 		case MPTSAS_FW_DIAG_TYPE_UNREGISTER:
10604 			if (length < sizeof (diag_unregister)) {
10605 				*return_code =
10606 				    MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
10607 				status = DDI_FAILURE;
10608 				break;
10609 			}
10610 			if (ddi_copyin(diag_action, &diag_unregister,
10611 			    sizeof (diag_unregister), ioctl_mode) != 0) {
10612 				return (DDI_FAILURE);
10613 			}
10614 			status = mptsas_diag_unregister(mpt, &diag_unregister,
10615 			    return_code);
10616 			break;
10617 
10618 		case MPTSAS_FW_DIAG_TYPE_QUERY:
10619 			if (length < sizeof (diag_query)) {
10620 				*return_code =
10621 				    MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
10622 				status = DDI_FAILURE;
10623 				break;
10624 			}
10625 			if (ddi_copyin(diag_action, &diag_query,
10626 			    sizeof (diag_query), ioctl_mode) != 0) {
10627 				return (DDI_FAILURE);
10628 			}
10629 			status = mptsas_diag_query(mpt, &diag_query,
10630 			    return_code);
10631 			if (status == DDI_SUCCESS) {
10632 				if (ddi_copyout(&diag_query, diag_action,
10633 				    sizeof (diag_query), ioctl_mode) != 0) {
10634 					return (DDI_FAILURE);
10635 				}
10636 			}
10637 			break;
10638 
10639 		case MPTSAS_FW_DIAG_TYPE_READ_BUFFER:
10640 			if (ddi_copyin(diag_action, &diag_read_buffer,
10641 			    sizeof (diag_read_buffer) - 4, ioctl_mode) != 0) {
10642 				return (DDI_FAILURE);
10643 			}
10644 			read_buf_len = sizeof (diag_read_buffer) -
10645 			    sizeof (diag_read_buffer.DataBuffer) +
10646 			    diag_read_buffer.BytesToRead;
10647 			if (length < read_buf_len) {
10648 				*return_code =
10649 				    MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
10650 				status = DDI_FAILURE;
10651 				break;
10652 			}
10653 			status = mptsas_diag_read_buffer(mpt,
10654 			    &diag_read_buffer, diag_action +
10655 			    sizeof (diag_read_buffer) - 4, return_code,
10656 			    ioctl_mode);
10657 			if (status == DDI_SUCCESS) {
10658 				if (ddi_copyout(&diag_read_buffer, diag_action,
10659 				    sizeof (diag_read_buffer) - 4, ioctl_mode)
10660 				    != 0) {
10661 					return (DDI_FAILURE);
10662 				}
10663 			}
10664 			break;
10665 
10666 		case MPTSAS_FW_DIAG_TYPE_RELEASE:
10667 			if (length < sizeof (diag_release)) {
10668 				*return_code =
10669 				    MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
10670 				status = DDI_FAILURE;
10671 				break;
10672 			}
10673 			if (ddi_copyin(diag_action, &diag_release,
10674 			    sizeof (diag_release), ioctl_mode) != 0) {
10675 				return (DDI_FAILURE);
10676 			}
10677 			status = mptsas_diag_release(mpt, &diag_release,
10678 			    return_code);
10679 			break;
10680 
10681 		default:
10682 			*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
10683 			status = DDI_FAILURE;
10684 			break;
10685 	}
10686 
10687 	if ((status == DDI_FAILURE) &&
10688 	    (original_return_code == MPTSAS_FW_DIAG_NEW) &&
10689 	    (*return_code != MPTSAS_FW_DIAG_ERROR_SUCCESS)) {
10690 		status = DDI_SUCCESS;
10691 	}
10692 
10693 	return (status);
10694 }
10695 
10696 static int
10697 mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *user_data, int mode)
10698 {
10699 	int			status;
10700 	mptsas_diag_action_t	driver_data;
10701 
10702 	ASSERT(mutex_owned(&mpt->m_mutex));
10703 
10704 	/*
10705 	 * Copy the user data to a driver data buffer.
10706 	 */
10707 	if (ddi_copyin(user_data, &driver_data, sizeof (mptsas_diag_action_t),
10708 	    mode) == 0) {
10709 		/*
10710 		 * Send diag action request if Action is valid
10711 		 */
10712 		if (driver_data.Action == MPTSAS_FW_DIAG_TYPE_REGISTER ||
10713 		    driver_data.Action == MPTSAS_FW_DIAG_TYPE_UNREGISTER ||
10714 		    driver_data.Action == MPTSAS_FW_DIAG_TYPE_QUERY ||
10715 		    driver_data.Action == MPTSAS_FW_DIAG_TYPE_READ_BUFFER ||
10716 		    driver_data.Action == MPTSAS_FW_DIAG_TYPE_RELEASE) {
10717 			status = mptsas_do_diag_action(mpt, driver_data.Action,
10718 			    (void *)(uintptr_t)driver_data.PtrDiagAction,
10719 			    driver_data.Length, &driver_data.ReturnCode,
10720 			    mode);
10721 			if (status == DDI_SUCCESS) {
10722 				if (ddi_copyout(&driver_data.ReturnCode,
10723 				    &user_data->ReturnCode,
10724 				    sizeof (user_data->ReturnCode), mode)
10725 				    != 0) {
10726 					status = EFAULT;
10727 				} else {
10728 					status = 0;
10729 				}
10730 			} else {
10731 				status = EIO;
10732 			}
10733 		} else {
10734 			status = EINVAL;
10735 		}
10736 	} else {
10737 		status = EFAULT;
10738 	}
10739 
10740 	return (status);
10741 }
10742 
10743 /*
10744  * This routine handles the "event query" ioctl.
10745  */
10746 static int
10747 mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, int mode,
10748     int *rval)
10749 {
10750 	int			status;
10751 	mptsas_event_query_t	driverdata;
10752 	uint8_t			i;
10753 
10754 	driverdata.Entries = MPTSAS_EVENT_QUEUE_SIZE;
10755 
10756 	mutex_enter(&mpt->m_mutex);
10757 	for (i = 0; i < 4; i++) {
10758 		driverdata.Types[i] = mpt->m_event_mask[i];
10759 	}
10760 	mutex_exit(&mpt->m_mutex);
10761 
10762 	if (ddi_copyout(&driverdata, data, sizeof (driverdata), mode) != 0) {
10763 		status = EFAULT;
10764 	} else {
10765 		*rval = MPTIOCTL_STATUS_GOOD;
10766 		status = 0;
10767 	}
10768 
10769 	return (status);
10770 }
10771 
10772 /*
10773  * This routine handles the "event enable" ioctl.
10774  */
10775 static int
10776 mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, int mode,
10777     int *rval)
10778 {
10779 	int			status;
10780 	mptsas_event_enable_t	driverdata;
10781 	uint8_t			i;
10782 
10783 	if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) {
10784 		mutex_enter(&mpt->m_mutex);
10785 		for (i = 0; i < 4; i++) {
10786 			mpt->m_event_mask[i] = driverdata.Types[i];
10787 		}
10788 		mutex_exit(&mpt->m_mutex);
10789 
10790 		*rval = MPTIOCTL_STATUS_GOOD;
10791 		status = 0;
10792 	} else {
10793 		status = EFAULT;
10794 	}
10795 	return (status);
10796 }
10797 
10798 /*
10799  * This routine handles the "event report" ioctl.
10800  */
10801 static int
10802 mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, int mode,
10803     int *rval)
10804 {
10805 	int			status;
10806 	mptsas_event_report_t	driverdata;
10807 
10808 	mutex_enter(&mpt->m_mutex);
10809 
10810 	if (ddi_copyin(&data->Size, &driverdata.Size, sizeof (driverdata.Size),
10811 	    mode) == 0) {
10812 		if (driverdata.Size >= sizeof (mpt->m_events)) {
10813 			if (ddi_copyout(mpt->m_events, data->Events,
10814 			    sizeof (mpt->m_events), mode) != 0) {
10815 				status = EFAULT;
10816 			} else {
10817 				if (driverdata.Size > sizeof (mpt->m_events)) {
10818 					driverdata.Size =
10819 					    sizeof (mpt->m_events);
10820 					if (ddi_copyout(&driverdata.Size,
10821 					    &data->Size,
10822 					    sizeof (driverdata.Size),
10823 					    mode) != 0) {
10824 						status = EFAULT;
10825 					} else {
10826 						*rval = MPTIOCTL_STATUS_GOOD;
10827 						status = 0;
10828 					}
10829 				} else {
10830 					*rval = MPTIOCTL_STATUS_GOOD;
10831 					status = 0;
10832 				}
10833 			}
10834 		} else {
10835 			*rval = MPTIOCTL_STATUS_LEN_TOO_SHORT;
10836 			status = 0;
10837 		}
10838 	} else {
10839 		status = EFAULT;
10840 	}
10841 
10842 	mutex_exit(&mpt->m_mutex);
10843 	return (status);
10844 }
10845 
10846 static void
10847 mptsas_lookup_pci_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data)
10848 {
10849 	int	*reg_data;
10850 	uint_t	reglen;
10851 
10852 	/*
10853 	 * Lookup the 'reg' property and extract the other data
10854 	 */
10855 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip,
10856 	    DDI_PROP_DONTPASS, "reg", &reg_data, &reglen) ==
10857 	    DDI_PROP_SUCCESS) {
10858 		/*
10859 		 * Extract the PCI data from the 'reg' property first DWORD.
10860 		 * The entry looks like the following:
10861 		 * First DWORD:
10862 		 * Bits 0 - 7 8-bit Register number
10863 		 * Bits 8 - 10 3-bit Function number
10864 		 * Bits 11 - 15 5-bit Device number
10865 		 * Bits 16 - 23 8-bit Bus number
10866 		 * Bits 24 - 25 2-bit Address Space type identifier
10867 		 *
10868 		 * Store the device number in PCIDeviceHwId.
10869 		 * Store the function number in MpiPortNumber.
10870 		 * PciInformation stores bus, device, and function together
10871 		 */
10872 		adapter_data->PCIDeviceHwId = (reg_data[0] & 0x0000F800) >> 11;
10873 		adapter_data->MpiPortNumber = (reg_data[0] & 0x00000700) >> 8;
10874 		adapter_data->PciInformation = (reg_data[0] & 0x00FFFF00) >> 8;
10875 		ddi_prop_free((void *)reg_data);
10876 	} else {
10877 		/*
10878 		 * If we can't determine the PCI data then we fill in FF's for
10879 		 * the data to indicate this.
10880 		 */
10881 		adapter_data->PCIDeviceHwId = 0xFFFFFFFF;
10882 		adapter_data->MpiPortNumber = 0xFFFFFFFF;
10883 		adapter_data->PciInformation = 0xFFFFFFFF;
10884 	}
10885 
10886 	/*
10887 	 * Saved in the mpt->m_fwversion
10888 	 */
10889 	adapter_data->MpiFirmwareVersion = mpt->m_fwversion;
10890 }
10891 
10892 static void
10893 mptsas_read_adapter_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data)
10894 {
10895 	char	*driver_verstr = MPTSAS_MOD_STRING;
10896 
10897 	mptsas_lookup_pci_data(mpt, adapter_data);
10898 	adapter_data->AdapterType = MPTIOCTL_ADAPTER_TYPE_SAS2;
10899 	adapter_data->PCIDeviceHwId = (uint32_t)mpt->m_devid;
10900 	adapter_data->PCIDeviceHwRev = (uint32_t)mpt->m_revid;
10901 	adapter_data->SubSystemId = (uint32_t)mpt->m_ssid;
10902 	adapter_data->SubsystemVendorId = (uint32_t)mpt->m_svid;
10903 	(void) strcpy((char *)&adapter_data->DriverVersion[0], driver_verstr);
10904 	adapter_data->BiosVersion = 0;
10905 	(void) mptsas_get_bios_page3(mpt, &adapter_data->BiosVersion);
10906 }
10907 
10908 static void
10909 mptsas_read_pci_info(mptsas_t *mpt, mptsas_pci_info_t *pci_info)
10910 {
10911 	int	*reg_data, i;
10912 	uint_t	reglen;
10913 
10914 	/*
10915 	 * Lookup the 'reg' property and extract the other data
10916 	 */
10917 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip,
10918 	    DDI_PROP_DONTPASS, "reg", &reg_data, &reglen) ==
10919 	    DDI_PROP_SUCCESS) {
10920 		/*
10921 		 * Extract the PCI data from the 'reg' property first DWORD.
10922 		 * The entry looks like the following:
10923 		 * First DWORD:
10924 		 * Bits 8 - 10 3-bit Function number
10925 		 * Bits 11 - 15 5-bit Device number
10926 		 * Bits 16 - 23 8-bit Bus number
10927 		 */
10928 		pci_info->BusNumber = (reg_data[0] & 0x00FF0000) >> 16;
10929 		pci_info->DeviceNumber = (reg_data[0] & 0x0000F800) >> 11;
10930 		pci_info->FunctionNumber = (reg_data[0] & 0x00000700) >> 8;
10931 		ddi_prop_free((void *)reg_data);
10932 	} else {
10933 		/*
10934 		 * If we can't determine the PCI info then we fill in FF's for
10935 		 * the data to indicate this.
10936 		 */
10937 		pci_info->BusNumber = 0xFFFFFFFF;
10938 		pci_info->DeviceNumber = 0xFF;
10939 		pci_info->FunctionNumber = 0xFF;
10940 	}
10941 
10942 	/*
10943 	 * Now get the interrupt vector and the pci header.  The vector can
10944 	 * only be 0 right now.  The header is the first 256 bytes of config
10945 	 * space.
10946 	 */
10947 	pci_info->InterruptVector = 0;
10948 	for (i = 0; i < sizeof (pci_info->PciHeader); i++) {
10949 		pci_info->PciHeader[i] = pci_config_get8(mpt->m_config_handle,
10950 		    i);
10951 	}
10952 }
10953 
10954 static int
10955 mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, int mode)
10956 {
10957 	int			status = 0;
10958 	mptsas_reg_access_t	driverdata;
10959 
10960 	mutex_enter(&mpt->m_mutex);
10961 	if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) {
10962 		switch (driverdata.Command) {
10963 			/*
10964 			 * IO access is not supported.
10965 			 */
10966 			case REG_IO_READ:
10967 			case REG_IO_WRITE:
10968 				mptsas_log(mpt, CE_WARN, "IO access is not "
10969 				    "supported.  Use memory access.");
10970 				status = EINVAL;
10971 				break;
10972 
10973 			case REG_MEM_READ:
10974 				driverdata.RegData = ddi_get32(mpt->m_datap,
10975 				    (uint32_t *)(void *)mpt->m_reg +
10976 				    driverdata.RegOffset);
10977 				if (ddi_copyout(&driverdata.RegData,
10978 				    &data->RegData,
10979 				    sizeof (driverdata.RegData), mode) != 0) {
10980 					mptsas_log(mpt, CE_WARN, "Register "
10981 					    "Read Failed");
10982 					status = EFAULT;
10983 				}
10984 				break;
10985 
10986 			case REG_MEM_WRITE:
10987 				ddi_put32(mpt->m_datap,
10988 				    (uint32_t *)(void *)mpt->m_reg +
10989 				    driverdata.RegOffset,
10990 				    driverdata.RegData);
10991 				break;
10992 
10993 			default:
10994 				status = EINVAL;
10995 				break;
10996 		}
10997 	} else {
10998 		status = EFAULT;
10999 	}
11000 
11001 	mutex_exit(&mpt->m_mutex);
11002 	return (status);
11003 }
11004 
11005 static int
11006 mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp,
11007     int *rval)
11008 {
11009 	int			status = 0;
11010 	mptsas_t		*mpt;
11011 	mptsas_update_flash_t	flashdata;
11012 	mptsas_pass_thru_t	passthru_data;
11013 	mptsas_adapter_data_t   adapter_data;
11014 	mptsas_pci_info_t	pci_info;
11015 	int			copylen;
11016 
11017 	*rval = MPTIOCTL_STATUS_GOOD;
11018 	mpt = ddi_get_soft_state(mptsas_state, MINOR2INST(getminor(dev)));
11019 	if (mpt == NULL) {
11020 		return (scsi_hba_ioctl(dev, cmd, data, mode, credp, rval));
11021 	}
11022 	if (secpolicy_sys_config(credp, B_FALSE) != 0) {
11023 		return (EPERM);
11024 	}
11025 
11026 	/* Make sure power level is D0 before accessing registers */
11027 	mutex_enter(&mpt->m_mutex);
11028 	if (mpt->m_options & MPTSAS_OPT_PM) {
11029 		(void) pm_busy_component(mpt->m_dip, 0);
11030 		if (mpt->m_power_level != PM_LEVEL_D0) {
11031 			mutex_exit(&mpt->m_mutex);
11032 			if (pm_raise_power(mpt->m_dip, 0, PM_LEVEL_D0) !=
11033 			    DDI_SUCCESS) {
11034 				mptsas_log(mpt, CE_WARN,
11035 				    "mptsas%d: mptsas_ioctl: Raise power "
11036 				    "request failed.", mpt->m_instance);
11037 				(void) pm_idle_component(mpt->m_dip, 0);
11038 				return (ENXIO);
11039 			}
11040 		} else {
11041 			mutex_exit(&mpt->m_mutex);
11042 		}
11043 	} else {
11044 		mutex_exit(&mpt->m_mutex);
11045 	}
11046 
11047 	switch (cmd) {
11048 		case MPTIOCTL_UPDATE_FLASH:
11049 			if (ddi_copyin((void *)data, &flashdata,
11050 				sizeof (struct mptsas_update_flash), mode)) {
11051 				status = EFAULT;
11052 				break;
11053 			}
11054 
11055 			mutex_enter(&mpt->m_mutex);
11056 			if (mptsas_update_flash(mpt,
11057 			    (caddr_t)(long)flashdata.PtrBuffer,
11058 			    flashdata.ImageSize, flashdata.ImageType, mode)) {
11059 				status = EFAULT;
11060 			}
11061 
11062 			/*
11063 			 * Reset the chip to start using the new
11064 			 * firmware.  Reset if failed also.
11065 			 */
11066 			if (mptsas_restart_ioc(mpt) == DDI_FAILURE) {
11067 				status = EFAULT;
11068 			}
11069 			mutex_exit(&mpt->m_mutex);
11070 			break;
11071 		case MPTIOCTL_PASS_THRU:
11072 			/*
11073 			 * The user has requested to pass through a command to
11074 			 * be executed by the MPT firmware.  Call our routine
11075 			 * which does this.  Only allow one passthru IOCTL at
11076 			 * one time.
11077 			 */
11078 			if (ddi_copyin((void *)data, &passthru_data,
11079 			    sizeof (mptsas_pass_thru_t), mode)) {
11080 				status = EFAULT;
11081 				break;
11082 			}
11083 			mutex_enter(&mpt->m_mutex);
11084 			if (mpt->m_passthru_in_progress) {
11085 				mutex_exit(&mpt->m_mutex);
11086 				return (EBUSY);
11087 			}
11088 			mpt->m_passthru_in_progress = 1;
11089 			status = mptsas_pass_thru(mpt, &passthru_data, mode);
11090 			mpt->m_passthru_in_progress = 0;
11091 			mutex_exit(&mpt->m_mutex);
11092 
11093 			break;
11094 		case MPTIOCTL_GET_ADAPTER_DATA:
11095 			/*
11096 			 * The user has requested to read adapter data.  Call
11097 			 * our routine which does this.
11098 			 */
11099 			bzero(&adapter_data, sizeof (mptsas_adapter_data_t));
11100 			if (ddi_copyin((void *)data, (void *)&adapter_data,
11101 			    sizeof (mptsas_adapter_data_t), mode)) {
11102 				status = EFAULT;
11103 				break;
11104 			}
11105 			if (adapter_data.StructureLength >=
11106 			    sizeof (mptsas_adapter_data_t)) {
11107 				adapter_data.StructureLength = (uint32_t)
11108 				    sizeof (mptsas_adapter_data_t);
11109 				copylen = sizeof (mptsas_adapter_data_t);
11110 				mutex_enter(&mpt->m_mutex);
11111 				mptsas_read_adapter_data(mpt, &adapter_data);
11112 				mutex_exit(&mpt->m_mutex);
11113 			} else {
11114 				adapter_data.StructureLength = (uint32_t)
11115 				    sizeof (mptsas_adapter_data_t);
11116 				copylen = sizeof (adapter_data.StructureLength);
11117 				*rval = MPTIOCTL_STATUS_LEN_TOO_SHORT;
11118 			}
11119 			if (ddi_copyout((void *)(&adapter_data), (void *)data,
11120 			    copylen, mode) != 0) {
11121 				status = EFAULT;
11122 			}
11123 			break;
11124 		case MPTIOCTL_GET_PCI_INFO:
11125 			/*
11126 			 * The user has requested to read pci info.  Call
11127 			 * our routine which does this.
11128 			 */
11129 			bzero(&pci_info, sizeof (mptsas_pci_info_t));
11130 			mutex_enter(&mpt->m_mutex);
11131 			mptsas_read_pci_info(mpt, &pci_info);
11132 			mutex_exit(&mpt->m_mutex);
11133 			if (ddi_copyout((void *)(&pci_info), (void *)data,
11134 			    sizeof (mptsas_pci_info_t), mode) != 0) {
11135 				status = EFAULT;
11136 			}
11137 			break;
11138 		case MPTIOCTL_RESET_ADAPTER:
11139 			mutex_enter(&mpt->m_mutex);
11140 			if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
11141 				mptsas_log(mpt, CE_WARN, "reset adapter IOCTL "
11142 				    "failed");
11143 				status = EFAULT;
11144 			}
11145 			mutex_exit(&mpt->m_mutex);
11146 			break;
11147 		case MPTIOCTL_DIAG_ACTION:
11148 			/*
11149 			 * The user has done a diag buffer action.  Call our
11150 			 * routine which does this.  Only allow one diag action
11151 			 * at one time.
11152 			 */
11153 			mutex_enter(&mpt->m_mutex);
11154 			if (mpt->m_diag_action_in_progress) {
11155 				mutex_exit(&mpt->m_mutex);
11156 				return (EBUSY);
11157 			}
11158 			mpt->m_diag_action_in_progress = 1;
11159 			status = mptsas_diag_action(mpt,
11160 			    (mptsas_diag_action_t *)data, mode);
11161 			mpt->m_diag_action_in_progress = 0;
11162 			mutex_exit(&mpt->m_mutex);
11163 			break;
11164 		case MPTIOCTL_EVENT_QUERY:
11165 			/*
11166 			 * The user has done an event query. Call our routine
11167 			 * which does this.
11168 			 */
11169 			status = mptsas_event_query(mpt,
11170 			    (mptsas_event_query_t *)data, mode, rval);
11171 			break;
11172 		case MPTIOCTL_EVENT_ENABLE:
11173 			/*
11174 			 * The user has done an event enable. Call our routine
11175 			 * which does this.
11176 			 */
11177 			status = mptsas_event_enable(mpt,
11178 			    (mptsas_event_enable_t *)data, mode, rval);
11179 			break;
11180 		case MPTIOCTL_EVENT_REPORT:
11181 			/*
11182 			 * The user has done an event report. Call our routine
11183 			 * which does this.
11184 			 */
11185 			status = mptsas_event_report(mpt,
11186 			    (mptsas_event_report_t *)data, mode, rval);
11187 			break;
11188 		case MPTIOCTL_REG_ACCESS:
11189 			/*
11190 			 * The user has requested register access.  Call our
11191 			 * routine which does this.
11192 			 */
11193 			status = mptsas_reg_access(mpt,
11194 			    (mptsas_reg_access_t *)data, mode);
11195 			break;
11196 		default:
11197 			status = scsi_hba_ioctl(dev, cmd, data, mode, credp,
11198 			    rval);
11199 			break;
11200 	}
11201 
11202 	/*
11203 	 * Report idle status to pm after grace period because
11204 	 * multiple ioctls may be queued and raising power
11205 	 * for every ioctl is time consuming.  If a timeout is
11206 	 * pending for the previous ioctl, cancel the timeout and
11207 	 * report idle status to pm because calls to pm_busy_component(9F)
11208 	 * are stacked.
11209 	 */
11210 	mutex_enter(&mpt->m_mutex);
11211 	if (mpt->m_options & MPTSAS_OPT_PM) {
11212 		if (mpt->m_pm_timeid != 0) {
11213 			timeout_id_t tid = mpt->m_pm_timeid;
11214 			mpt->m_pm_timeid = 0;
11215 			mutex_exit(&mpt->m_mutex);
11216 			(void) untimeout(tid);
11217 			/*
11218 			 * Report idle status for previous ioctl since
11219 			 * calls to pm_busy_component(9F) are stacked.
11220 			 */
11221 			(void) pm_idle_component(mpt->m_dip, 0);
11222 			mutex_enter(&mpt->m_mutex);
11223 		}
11224 		mpt->m_pm_timeid = timeout(mptsas_idle_pm, mpt,
11225 		    drv_usectohz((clock_t)mpt->m_pm_idle_delay * 1000000));
11226 	}
11227 	mutex_exit(&mpt->m_mutex);
11228 
11229 	return (status);
11230 }
11231 
11232 int
11233 mptsas_restart_ioc(mptsas_t *mpt) {
11234 	int		rval = DDI_SUCCESS;
11235 	mptsas_target_t	*ptgt = NULL;
11236 
11237 	ASSERT(mutex_owned(&mpt->m_mutex));
11238 
11239 	/*
11240 	 * Set all throttles to HOLD
11241 	 */
11242 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11243 	    MPTSAS_HASH_FIRST);
11244 	while (ptgt != NULL) {
11245 		mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
11246 
11247 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11248 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
11249 	}
11250 
11251 	/*
11252 	 * Disable interrupts
11253 	 */
11254 	MPTSAS_DISABLE_INTR(mpt);
11255 
11256 	/*
11257 	 * Abort all commands: outstanding commands, commands in waitq and
11258 	 * tx_waitq.
11259 	 */
11260 	mptsas_flush_hba(mpt);
11261 
11262 	/*
11263 	 * Reinitialize the chip.
11264 	 */
11265 	if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) {
11266 		rval = DDI_FAILURE;
11267 	}
11268 
11269 	/*
11270 	 * Enable interrupts again
11271 	 */
11272 	MPTSAS_ENABLE_INTR(mpt);
11273 
11274 	/*
11275 	 * If mptsas_init_chip was successful, update the driver data.
11276 	 */
11277 	if (rval == DDI_SUCCESS) {
11278 		mptsas_update_driver_data(mpt);
11279 	}
11280 
11281 	/*
11282 	 * Reset the throttles
11283 	 */
11284 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11285 	    MPTSAS_HASH_FIRST);
11286 	while (ptgt != NULL) {
11287 		mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
11288 
11289 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11290 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
11291 	}
11292 
11293 	mptsas_doneq_empty(mpt);
11294 
11295 	if (rval != DDI_SUCCESS) {
11296 		mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
11297 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
11298 	}
11299 	return (rval);
11300 }
11301 
11302 int
11303 mptsas_init_chip(mptsas_t *mpt, int first_time)
11304 {
11305 	ddi_dma_cookie_t	cookie;
11306 	uint32_t		i;
11307 	mptsas_slots_t		*new_active;
11308 
11309 	/*
11310 	 * Check to see if the firmware image is valid
11311 	 */
11312 	if (ddi_get32(mpt->m_datap, &mpt->m_reg->HostDiagnostic) &
11313 	    MPI2_DIAG_FLASH_BAD_SIG) {
11314 		mptsas_log(mpt, CE_WARN, "mptsas bad flash signature!");
11315 		goto fail;
11316 	}
11317 
11318 	/*
11319 	 * Reset the chip
11320 	 */
11321 	if (mptsas_ioc_reset(mpt) == MPTSAS_RESET_FAIL) {
11322 		mptsas_log(mpt, CE_WARN, "hard reset failed!");
11323 		goto fail;
11324 	}
11325 
11326 	if (first_time == FALSE) {
11327 		/*
11328 		 * De-allocate buffers before re-allocating them using the
11329 		 * latest IOC facts.
11330 		 */
11331 		mptsas_hba_fini(mpt);
11332 
11333 		/*
11334 		 * Setup configuration space
11335 		 */
11336 		if (mptsas_config_space_init(mpt) == FALSE) {
11337 			mptsas_log(mpt, CE_WARN, "mptsas_config_space_init "
11338 			    "failed!");
11339 			goto fail;
11340 		}
11341 	}
11342 
11343 	/*
11344 	 * IOC facts can change after a diag reset so all buffers that are
11345 	 * based on these numbers must be de-allocated and re-allocated.  Get
11346 	 * new IOC facts each time chip is initialized.
11347 	 */
11348 	if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) {
11349 		mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed");
11350 		goto fail;
11351 	}
11352 	/*
11353 	 * Re-allocate active slots here if not the first reset.  Since
11354 	 * m_active could have a different number of slots allocated after a
11355 	 * reset, just de-allocate the old m_active structure and re-allocate a
11356 	 * new one.  Save the tables and IR info from the old m_active.
11357 	 */
11358 	if (first_time == FALSE) {
11359 		new_active = kmem_zalloc(MPTSAS_SLOTS_SIZE(mpt), KM_SLEEP);
11360 		if (new_active == NULL) {
11361 			mptsas_log(mpt, CE_WARN, "Re-alloc of active slots "
11362 			    "failed!");
11363 			goto fail;
11364 		} else {
11365 			new_active->m_n_slots = (mpt->m_max_requests - 2);
11366 			new_active->m_size = MPTSAS_SLOTS_SIZE(mpt);
11367 			new_active->m_tags = 1;
11368 			new_active->m_tgttbl = mpt->m_active->m_tgttbl;
11369 			new_active->m_smptbl = mpt->m_active->m_smptbl;
11370 			new_active->m_num_raid_configs =
11371 			    mpt->m_active->m_num_raid_configs;
11372 			for (i = 0; i < new_active->m_num_raid_configs; i++) {
11373 				new_active->m_raidconfig[i] =
11374 				    mpt->m_active->m_raidconfig[i];
11375 			}
11376 			kmem_free(mpt->m_active, mpt->m_active->m_size);
11377 			mpt->m_active = new_active;
11378 		}
11379 	}
11380 
11381 	/*
11382 	 * Allocate request message frames, reply free queue, reply descriptor
11383 	 * post queue, and reply message frames using latest IOC facts.
11384 	 */
11385 	if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) {
11386 		mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed");
11387 		goto fail;
11388 	}
11389 	if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) {
11390 		mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue failed!");
11391 		goto fail;
11392 	}
11393 	if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) {
11394 		mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue failed!");
11395 		goto fail;
11396 	}
11397 	if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) {
11398 		mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames failed!");
11399 		goto fail;
11400 	}
11401 
11402 	/*
11403 	 * Re-Initialize ioc to operational state
11404 	 */
11405 	if (mptsas_ioc_init(mpt) == DDI_FAILURE) {
11406 		mptsas_log(mpt, CE_WARN, "mptsas_ioc_init failed");
11407 		goto fail;
11408 	}
11409 
11410 	mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) *
11411 	    mpt->m_max_replies, KM_SLEEP);
11412 
11413 	/*
11414 	 * Initialize reply post index.  Reply free index is initialized after
11415 	 * the next loop.
11416 	 */
11417 	mpt->m_post_index = 0;
11418 
11419 	/*
11420 	 * Initialize the Reply Free Queue with the physical addresses of our
11421 	 * reply frames.
11422 	 */
11423 	cookie.dmac_address = mpt->m_reply_frame_dma_addr;
11424 	for (i = 0; i < mpt->m_free_queue_depth - 1; i++) {
11425 		ddi_put32(mpt->m_acc_free_queue_hdl,
11426 		    &((uint32_t *)(void *)mpt->m_free_queue)[i],
11427 		    cookie.dmac_address);
11428 		cookie.dmac_address += mpt->m_reply_frame_size;
11429 	}
11430 	(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
11431 	    DDI_DMA_SYNC_FORDEV);
11432 
11433 	/*
11434 	 * Initialize the reply free index to one past the last frame on the
11435 	 * queue.  This will signify that the queue is empty to start with.
11436 	 */
11437 	mpt->m_free_index = i;
11438 	ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, i);
11439 
11440 	/*
11441 	 * Initialize the reply post queue to 0xFFFFFFFF,0xFFFFFFFF's.
11442 	 */
11443 	for (i = 0; i < mpt->m_post_queue_depth; i++) {
11444 		ddi_put64(mpt->m_acc_post_queue_hdl,
11445 		    &((uint64_t *)(void *)mpt->m_post_queue)[i],
11446 		    0xFFFFFFFFFFFFFFFF);
11447 	}
11448 	(void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
11449 	    DDI_DMA_SYNC_FORDEV);
11450 
11451 	/*
11452 	 * Enable ports
11453 	 */
11454 	if (mptsas_ioc_enable_port(mpt) == DDI_FAILURE) {
11455 		mptsas_log(mpt, CE_WARN, "mptsas_ioc_enable_port failed");
11456 		goto fail;
11457 	}
11458 
11459 	/*
11460 	 * First, make sure the HBA is set in "initiator" mode.  Once that
11461 	 * is complete, get the base WWID.
11462 	 */
11463 
11464 	if (first_time == TRUE) {
11465 		if (mptsas_set_initiator_mode(mpt)) {
11466 			mptsas_log(mpt, CE_WARN, "mptsas_set_initiator_mode "
11467 			    "failed!");
11468 			goto fail;
11469 		}
11470 
11471 		if (mptsas_get_manufacture_page5(mpt) == DDI_FAILURE) {
11472 			mptsas_log(mpt, CE_WARN,
11473 			    "mptsas_get_manufacture_page5 failed!");
11474 			goto fail;
11475 		}
11476 	}
11477 
11478 	/*
11479 	 * enable events
11480 	 */
11481 	if (first_time == FALSE) {
11482 		if (mptsas_ioc_enable_event_notification(mpt)) {
11483 			goto fail;
11484 		}
11485 	}
11486 
11487 	/*
11488 	 * We need checks in attach and these.
11489 	 * chip_init is called in mult. places
11490 	 */
11491 
11492 	if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
11493 	    DDI_SUCCESS) ||
11494 	    (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) !=
11495 	    DDI_SUCCESS) ||
11496 	    (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) !=
11497 	    DDI_SUCCESS) ||
11498 	    (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) !=
11499 	    DDI_SUCCESS) ||
11500 	    (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) !=
11501 	    DDI_SUCCESS)) {
11502 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
11503 		goto fail;
11504 	}
11505 
11506 	/* Check all acc handles */
11507 	if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) ||
11508 	    (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
11509 	    DDI_SUCCESS) ||
11510 	    (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) !=
11511 	    DDI_SUCCESS) ||
11512 	    (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) !=
11513 	    DDI_SUCCESS) ||
11514 	    (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) !=
11515 	    DDI_SUCCESS) ||
11516 	    (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) !=
11517 	    DDI_SUCCESS) ||
11518 	    (mptsas_check_acc_handle(mpt->m_config_handle) !=
11519 	    DDI_SUCCESS)) {
11520 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
11521 		goto fail;
11522 	}
11523 
11524 	return (DDI_SUCCESS);
11525 
11526 fail:
11527 	return (DDI_FAILURE);
11528 }
11529 
11530 static int
11531 mptsas_init_pm(mptsas_t *mpt)
11532 {
11533 	char		pmc_name[16];
11534 	char		*pmc[] = {
11535 				NULL,
11536 				"0=Off (PCI D3 State)",
11537 				"3=On (PCI D0 State)",
11538 				NULL
11539 			};
11540 	uint16_t	pmcsr_stat;
11541 
11542 	/*
11543 	 * If power management is supported by this chip, create
11544 	 * pm-components property for the power management framework
11545 	 */
11546 	(void) sprintf(pmc_name, "NAME=mptsas%d", mpt->m_instance);
11547 	pmc[0] = pmc_name;
11548 	if (ddi_prop_update_string_array(DDI_DEV_T_NONE, mpt->m_dip,
11549 	    "pm-components", pmc, 3) != DDI_PROP_SUCCESS) {
11550 		mpt->m_options &= ~MPTSAS_OPT_PM;
11551 		mptsas_log(mpt, CE_WARN,
11552 		    "mptsas%d: pm-component property creation failed.",
11553 		    mpt->m_instance);
11554 		return (DDI_FAILURE);
11555 	}
11556 
11557 	/*
11558 	 * Power on device.
11559 	 */
11560 	(void) pm_busy_component(mpt->m_dip, 0);
11561 	pmcsr_stat = pci_config_get16(mpt->m_config_handle,
11562 	    mpt->m_pmcsr_offset);
11563 	if ((pmcsr_stat & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_D0) {
11564 		mptsas_log(mpt, CE_WARN, "mptsas%d: Power up the device",
11565 		    mpt->m_instance);
11566 		pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset,
11567 		    PCI_PMCSR_D0);
11568 	}
11569 	if (pm_power_has_changed(mpt->m_dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) {
11570 		mptsas_log(mpt, CE_WARN, "pm_power_has_changed failed");
11571 		return (DDI_FAILURE);
11572 	}
11573 	mpt->m_power_level = PM_LEVEL_D0;
11574 	/*
11575 	 * Set pm idle delay.
11576 	 */
11577 	mpt->m_pm_idle_delay = ddi_prop_get_int(DDI_DEV_T_ANY,
11578 	    mpt->m_dip, 0, "mptsas-pm-idle-delay", MPTSAS_PM_IDLE_TIMEOUT);
11579 
11580 	return (DDI_SUCCESS);
11581 }
11582 
11583 /*
11584  * mptsas_add_intrs:
11585  *
11586  * Register FIXED or MSI interrupts.
11587  */
11588 static int
11589 mptsas_add_intrs(mptsas_t *mpt, int intr_type)
11590 {
11591 	dev_info_t	*dip = mpt->m_dip;
11592 	int		avail, actual, count = 0;
11593 	int		i, flag, ret;
11594 
11595 	NDBG6(("mptsas_add_intrs:interrupt type 0x%x", intr_type));
11596 
11597 	/* Get number of interrupts */
11598 	ret = ddi_intr_get_nintrs(dip, intr_type, &count);
11599 	if ((ret != DDI_SUCCESS) || (count <= 0)) {
11600 		mptsas_log(mpt, CE_WARN, "ddi_intr_get_nintrs() failed, "
11601 		    "ret %d count %d\n", ret, count);
11602 
11603 		return (DDI_FAILURE);
11604 	}
11605 
11606 	/* Get number of available interrupts */
11607 	ret = ddi_intr_get_navail(dip, intr_type, &avail);
11608 	if ((ret != DDI_SUCCESS) || (avail == 0)) {
11609 		mptsas_log(mpt, CE_WARN, "ddi_intr_get_navail() failed, "
11610 		    "ret %d avail %d\n", ret, avail);
11611 
11612 		return (DDI_FAILURE);
11613 	}
11614 
11615 	if (avail < count) {
11616 		mptsas_log(mpt, CE_NOTE, "ddi_intr_get_nvail returned %d, "
11617 		    "navail() returned %d", count, avail);
11618 	}
11619 
11620 	/* Mpt only have one interrupt routine */
11621 	if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) {
11622 		count = 1;
11623 	}
11624 
11625 	/* Allocate an array of interrupt handles */
11626 	mpt->m_intr_size = count * sizeof (ddi_intr_handle_t);
11627 	mpt->m_htable = kmem_alloc(mpt->m_intr_size, KM_SLEEP);
11628 
11629 	flag = DDI_INTR_ALLOC_NORMAL;
11630 
11631 	/* call ddi_intr_alloc() */
11632 	ret = ddi_intr_alloc(dip, mpt->m_htable, intr_type, 0,
11633 	    count, &actual, flag);
11634 
11635 	if ((ret != DDI_SUCCESS) || (actual == 0)) {
11636 		mptsas_log(mpt, CE_WARN, "ddi_intr_alloc() failed, ret %d\n",
11637 		    ret);
11638 		kmem_free(mpt->m_htable, mpt->m_intr_size);
11639 		return (DDI_FAILURE);
11640 	}
11641 
11642 	/* use interrupt count returned or abort? */
11643 	if (actual < count) {
11644 		mptsas_log(mpt, CE_NOTE, "Requested: %d, Received: %d\n",
11645 		    count, actual);
11646 	}
11647 
11648 	mpt->m_intr_cnt = actual;
11649 
11650 	/*
11651 	 * Get priority for first msi, assume remaining are all the same
11652 	 */
11653 	if ((ret = ddi_intr_get_pri(mpt->m_htable[0],
11654 	    &mpt->m_intr_pri)) != DDI_SUCCESS) {
11655 		mptsas_log(mpt, CE_WARN, "ddi_intr_get_pri() failed %d\n", ret);
11656 
11657 		/* Free already allocated intr */
11658 		for (i = 0; i < actual; i++) {
11659 			(void) ddi_intr_free(mpt->m_htable[i]);
11660 		}
11661 
11662 		kmem_free(mpt->m_htable, mpt->m_intr_size);
11663 		return (DDI_FAILURE);
11664 	}
11665 
11666 	/* Test for high level mutex */
11667 	if (mpt->m_intr_pri >= ddi_intr_get_hilevel_pri()) {
11668 		mptsas_log(mpt, CE_WARN, "mptsas_add_intrs: "
11669 		    "Hi level interrupt not supported\n");
11670 
11671 		/* Free already allocated intr */
11672 		for (i = 0; i < actual; i++) {
11673 			(void) ddi_intr_free(mpt->m_htable[i]);
11674 		}
11675 
11676 		kmem_free(mpt->m_htable, mpt->m_intr_size);
11677 		return (DDI_FAILURE);
11678 	}
11679 
11680 	/* Call ddi_intr_add_handler() */
11681 	for (i = 0; i < actual; i++) {
11682 		if ((ret = ddi_intr_add_handler(mpt->m_htable[i], mptsas_intr,
11683 		    (caddr_t)mpt, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) {
11684 			mptsas_log(mpt, CE_WARN, "ddi_intr_add_handler() "
11685 			    "failed %d\n", ret);
11686 
11687 			/* Free already allocated intr */
11688 			for (i = 0; i < actual; i++) {
11689 				(void) ddi_intr_free(mpt->m_htable[i]);
11690 			}
11691 
11692 			kmem_free(mpt->m_htable, mpt->m_intr_size);
11693 			return (DDI_FAILURE);
11694 		}
11695 	}
11696 
11697 	if ((ret = ddi_intr_get_cap(mpt->m_htable[0], &mpt->m_intr_cap))
11698 	    != DDI_SUCCESS) {
11699 		mptsas_log(mpt, CE_WARN, "ddi_intr_get_cap() failed %d\n", ret);
11700 
11701 		/* Free already allocated intr */
11702 		for (i = 0; i < actual; i++) {
11703 			(void) ddi_intr_free(mpt->m_htable[i]);
11704 		}
11705 
11706 		kmem_free(mpt->m_htable, mpt->m_intr_size);
11707 		return (DDI_FAILURE);
11708 	}
11709 
11710 	return (DDI_SUCCESS);
11711 }
11712 
11713 /*
11714  * mptsas_rem_intrs:
11715  *
11716  * Unregister FIXED or MSI interrupts
11717  */
11718 static void
11719 mptsas_rem_intrs(mptsas_t *mpt)
11720 {
11721 	int	i;
11722 
11723 	NDBG6(("mptsas_rem_intrs"));
11724 
11725 	/* Disable all interrupts */
11726 	if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) {
11727 		/* Call ddi_intr_block_disable() */
11728 		(void) ddi_intr_block_disable(mpt->m_htable, mpt->m_intr_cnt);
11729 	} else {
11730 		for (i = 0; i < mpt->m_intr_cnt; i++) {
11731 			(void) ddi_intr_disable(mpt->m_htable[i]);
11732 		}
11733 	}
11734 
11735 	/* Call ddi_intr_remove_handler() */
11736 	for (i = 0; i < mpt->m_intr_cnt; i++) {
11737 		(void) ddi_intr_remove_handler(mpt->m_htable[i]);
11738 		(void) ddi_intr_free(mpt->m_htable[i]);
11739 	}
11740 
11741 	kmem_free(mpt->m_htable, mpt->m_intr_size);
11742 }
11743 
11744 /*
11745  * The IO fault service error handling callback function
11746  */
11747 /*ARGSUSED*/
11748 static int
11749 mptsas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
11750 {
11751 	/*
11752 	 * as the driver can always deal with an error in any dma or
11753 	 * access handle, we can just return the fme_status value.
11754 	 */
11755 	pci_ereport_post(dip, err, NULL);
11756 	return (err->fme_status);
11757 }
11758 
11759 /*
11760  * mptsas_fm_init - initialize fma capabilities and register with IO
11761  *               fault services.
11762  */
11763 static void
11764 mptsas_fm_init(mptsas_t *mpt)
11765 {
11766 	/*
11767 	 * Need to change iblock to priority for new MSI intr
11768 	 */
11769 	ddi_iblock_cookie_t	fm_ibc;
11770 
11771 	/* Only register with IO Fault Services if we have some capability */
11772 	if (mpt->m_fm_capabilities) {
11773 		/* Adjust access and dma attributes for FMA */
11774 		mpt->m_dev_acc_attr.devacc_attr_access |= DDI_FLAGERR_ACC;
11775 		mpt->m_msg_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
11776 		mpt->m_io_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
11777 
11778 		/*
11779 		 * Register capabilities with IO Fault Services.
11780 		 * mpt->m_fm_capabilities will be updated to indicate
11781 		 * capabilities actually supported (not requested.)
11782 		 */
11783 		ddi_fm_init(mpt->m_dip, &mpt->m_fm_capabilities, &fm_ibc);
11784 
11785 		/*
11786 		 * Initialize pci ereport capabilities if ereport
11787 		 * capable (should always be.)
11788 		 */
11789 		if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) ||
11790 		    DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
11791 			pci_ereport_setup(mpt->m_dip);
11792 		}
11793 
11794 		/*
11795 		 * Register error callback if error callback capable.
11796 		 */
11797 		if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
11798 			ddi_fm_handler_register(mpt->m_dip,
11799 			    mptsas_fm_error_cb, (void *) mpt);
11800 		}
11801 	}
11802 }
11803 
11804 /*
11805  * mptsas_fm_fini - Releases fma capabilities and un-registers with IO
11806  *               fault services.
11807  *
11808  */
11809 static void
11810 mptsas_fm_fini(mptsas_t *mpt)
11811 {
11812 	/* Only unregister FMA capabilities if registered */
11813 	if (mpt->m_fm_capabilities) {
11814 
11815 		/*
11816 		 * Un-register error callback if error callback capable.
11817 		 */
11818 
11819 		if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
11820 			ddi_fm_handler_unregister(mpt->m_dip);
11821 		}
11822 
11823 		/*
11824 		 * Release any resources allocated by pci_ereport_setup()
11825 		 */
11826 
11827 		if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) ||
11828 		    DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
11829 			pci_ereport_teardown(mpt->m_dip);
11830 		}
11831 
11832 		/* Unregister from IO Fault Services */
11833 		ddi_fm_fini(mpt->m_dip);
11834 
11835 		/* Adjust access and dma attributes for FMA */
11836 		mpt->m_dev_acc_attr.devacc_attr_access &= ~DDI_FLAGERR_ACC;
11837 		mpt->m_msg_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
11838 		mpt->m_io_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
11839 
11840 	}
11841 }
11842 
11843 int
11844 mptsas_check_acc_handle(ddi_acc_handle_t handle)
11845 {
11846 	ddi_fm_error_t	de;
11847 
11848 	if (handle == NULL)
11849 		return (DDI_FAILURE);
11850 	ddi_fm_acc_err_get(handle, &de, DDI_FME_VER0);
11851 	return (de.fme_status);
11852 }
11853 
11854 int
11855 mptsas_check_dma_handle(ddi_dma_handle_t handle)
11856 {
11857 	ddi_fm_error_t	de;
11858 
11859 	if (handle == NULL)
11860 		return (DDI_FAILURE);
11861 	ddi_fm_dma_err_get(handle, &de, DDI_FME_VER0);
11862 	return (de.fme_status);
11863 }
11864 
11865 void
11866 mptsas_fm_ereport(mptsas_t *mpt, char *detail)
11867 {
11868 	uint64_t	ena;
11869 	char		buf[FM_MAX_CLASS];
11870 
11871 	(void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
11872 	ena = fm_ena_generate(0, FM_ENA_FMT1);
11873 	if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities)) {
11874 		ddi_fm_ereport_post(mpt->m_dip, buf, ena, DDI_NOSLEEP,
11875 		    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL);
11876 	}
11877 }
11878 
11879 static int
11880 mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
11881     uint16_t *dev_handle, mptsas_target_t **pptgt)
11882 {
11883 	int		rval;
11884 	uint32_t	dev_info;
11885 	uint64_t	sas_wwn;
11886 	uint8_t		physport, phymask;
11887 	uint8_t		phynum, config, disk;
11888 	mptsas_slots_t	*slots = mpt->m_active;
11889 	uint64_t		devicename;
11890 	mptsas_target_t		*tmp_tgt = NULL;
11891 
11892 	ASSERT(*pptgt == NULL);
11893 
11894 	rval = mptsas_get_sas_device_page0(mpt, page_address, dev_handle,
11895 	    &sas_wwn, &dev_info, &physport, &phynum);
11896 	if (rval != DDI_SUCCESS) {
11897 		rval = DEV_INFO_FAIL_PAGE0;
11898 		return (rval);
11899 	}
11900 
11901 	if ((dev_info & (MPI2_SAS_DEVICE_INFO_SSP_TARGET |
11902 	    MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
11903 	    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) == NULL) {
11904 		rval = DEV_INFO_WRONG_DEVICE_TYPE;
11905 		return (rval);
11906 	}
11907 
11908 	/*
11909 	 * Get SATA Device Name from SAS device page0 for
11910 	 * sata device, if device name doesn't exist, set m_sas_wwn to
11911 	 * 0 for direct attached SATA. For the device behind the expander
11912 	 * we still can use STP address assigned by expander.
11913 	 */
11914 	if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
11915 	    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
11916 		mutex_exit(&mpt->m_mutex);
11917 		/* alloc a tmp_tgt to send the cmd */
11918 		tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target),
11919 		    KM_SLEEP);
11920 		tmp_tgt->m_devhdl = *dev_handle;
11921 		tmp_tgt->m_deviceinfo = dev_info;
11922 		tmp_tgt->m_qfull_retries = QFULL_RETRIES;
11923 		tmp_tgt->m_qfull_retry_interval =
11924 		    drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
11925 		tmp_tgt->m_t_throttle = MAX_THROTTLE;
11926 		devicename = mptsas_get_sata_guid(mpt, tmp_tgt, 0);
11927 		kmem_free(tmp_tgt, sizeof (struct mptsas_target));
11928 		mutex_enter(&mpt->m_mutex);
11929 		if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) {
11930 			sas_wwn = devicename;
11931 		} else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) {
11932 			sas_wwn = 0;
11933 		}
11934 	}
11935 
11936 	/*
11937 	 * Check if the dev handle is for a Phys Disk. If so, set return value
11938 	 * and exit.  Don't add Phys Disks to hash.
11939 	 */
11940 	for (config = 0; config < slots->m_num_raid_configs; config++) {
11941 		for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
11942 			if (*dev_handle == slots->m_raidconfig[config].
11943 			    m_physdisk_devhdl[disk]) {
11944 				rval = DEV_INFO_PHYS_DISK;
11945 				return (rval);
11946 			}
11947 		}
11948 	}
11949 
11950 	phymask = mptsas_physport_to_phymask(mpt, physport);
11951 	*pptgt = mptsas_tgt_alloc(&slots->m_tgttbl, *dev_handle, sas_wwn,
11952 	    dev_info, phymask, phynum);
11953 	if (*pptgt == NULL) {
11954 		mptsas_log(mpt, CE_WARN, "Failed to allocated target"
11955 		    "structure!");
11956 		rval = DEV_INFO_FAIL_ALLOC;
11957 		return (rval);
11958 	}
11959 	return (DEV_INFO_SUCCESS);
11960 }
11961 
11962 uint64_t
11963 mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun)
11964 {
11965 	uint64_t	sata_guid = 0, *pwwn = NULL;
11966 	int		target = ptgt->m_devhdl;
11967 	uchar_t		*inq83 = NULL;
11968 	int		inq83_len = 0xFF;
11969 	uchar_t		*dblk = NULL;
11970 	int		inq83_retry = 3;
11971 	int		rval = DDI_FAILURE;
11972 
11973 	inq83	= kmem_zalloc(inq83_len, KM_SLEEP);
11974 
11975 inq83_retry:
11976 	rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83,
11977 	    inq83_len, NULL, 1);
11978 	if (rval != DDI_SUCCESS) {
11979 		mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
11980 		    "0x83 for target:%x, lun:%x failed!", target, lun);
11981 		goto out;
11982 	}
11983 	/* According to SAT2, the first descriptor is logic unit name */
11984 	dblk = &inq83[4];
11985 	if ((dblk[1] & 0x30) != 0) {
11986 		mptsas_log(mpt, CE_WARN, "!Descriptor is not lun associated.");
11987 		goto out;
11988 	}
11989 	pwwn = (uint64_t *)(void *)(&dblk[4]);
11990 	if ((dblk[4] & 0xf0) == 0x50) {
11991 		sata_guid = BE_64(*pwwn);
11992 		goto out;
11993 	} else if (dblk[4] == 'A') {
11994 		NDBG20(("SATA drive has no NAA format GUID."));
11995 		goto out;
11996 	} else {
11997 		/* The data is not ready, wait and retry */
11998 		inq83_retry--;
11999 		if (inq83_retry <= 0) {
12000 			goto out;
12001 		}
12002 		NDBG20(("The GUID is not ready, retry..."));
12003 		delay(1 * drv_usectohz(1000000));
12004 		goto inq83_retry;
12005 	}
12006 out:
12007 	kmem_free(inq83, inq83_len);
12008 	return (sata_guid);
12009 }
12010 
12011 static int
12012 mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, uchar_t page,
12013     unsigned char *buf, int len, int *reallen, uchar_t evpd)
12014 {
12015 	uchar_t			cdb[CDB_GROUP0];
12016 	struct scsi_address	ap;
12017 	struct buf		*data_bp = NULL;
12018 	int			resid = 0;
12019 	int			ret = DDI_FAILURE;
12020 
12021 	ASSERT(len <= 0xffff);
12022 
12023 	ap.a_target = MPTSAS_INVALID_DEVHDL;
12024 	ap.a_lun = (uchar_t)(lun);
12025 	ap.a_hba_tran = mpt->m_tran;
12026 
12027 	data_bp = scsi_alloc_consistent_buf(&ap,
12028 	    (struct buf *)NULL, len, B_READ, NULL_FUNC, NULL);
12029 	if (data_bp == NULL) {
12030 		return (ret);
12031 	}
12032 	bzero(cdb, CDB_GROUP0);
12033 	cdb[0] = SCMD_INQUIRY;
12034 	cdb[1] = evpd;
12035 	cdb[2] = page;
12036 	cdb[3] = (len & 0xff00) >> 8;
12037 	cdb[4] = (len & 0x00ff);
12038 	cdb[5] = 0;
12039 
12040 	ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP0, data_bp,
12041 	    &resid);
12042 	if (ret == DDI_SUCCESS) {
12043 		if (reallen) {
12044 			*reallen = len - resid;
12045 		}
12046 		bcopy((caddr_t)data_bp->b_un.b_addr, buf, len);
12047 	}
12048 	if (data_bp) {
12049 		scsi_free_consistent_buf(data_bp);
12050 	}
12051 	return (ret);
12052 }
12053 
12054 static int
12055 mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap,
12056     mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp,
12057     int *resid)
12058 {
12059 	struct scsi_pkt		*pktp = NULL;
12060 	scsi_hba_tran_t		*tran_clone = NULL;
12061 	mptsas_tgt_private_t	*tgt_private = NULL;
12062 	int			ret = DDI_FAILURE;
12063 
12064 	/*
12065 	 * scsi_hba_tran_t->tran_tgt_private is used to pass the address
12066 	 * information to scsi_init_pkt, allocate a scsi_hba_tran structure
12067 	 * to simulate the cmds from sd
12068 	 */
12069 	tran_clone = kmem_alloc(
12070 	    sizeof (scsi_hba_tran_t), KM_SLEEP);
12071 	if (tran_clone == NULL) {
12072 		goto out;
12073 	}
12074 	bcopy((caddr_t)mpt->m_tran,
12075 	    (caddr_t)tran_clone, sizeof (scsi_hba_tran_t));
12076 	tgt_private = kmem_alloc(
12077 	    sizeof (mptsas_tgt_private_t), KM_SLEEP);
12078 	if (tgt_private == NULL) {
12079 		goto out;
12080 	}
12081 	tgt_private->t_lun = ap->a_lun;
12082 	tgt_private->t_private = ptgt;
12083 	tran_clone->tran_tgt_private = tgt_private;
12084 	ap->a_hba_tran = tran_clone;
12085 
12086 	pktp = scsi_init_pkt(ap, (struct scsi_pkt *)NULL,
12087 	    data_bp, cdblen, sizeof (struct scsi_arq_status),
12088 	    0, PKT_CONSISTENT, NULL, NULL);
12089 	if (pktp == NULL) {
12090 		goto out;
12091 	}
12092 	bcopy(cdb, pktp->pkt_cdbp, cdblen);
12093 	pktp->pkt_flags = FLAG_NOPARITY;
12094 	if (scsi_poll(pktp) < 0) {
12095 		goto out;
12096 	}
12097 	if (((struct scsi_status *)pktp->pkt_scbp)->sts_chk) {
12098 		goto out;
12099 	}
12100 	if (resid != NULL) {
12101 		*resid = pktp->pkt_resid;
12102 	}
12103 
12104 	ret = DDI_SUCCESS;
12105 out:
12106 	if (pktp) {
12107 		scsi_destroy_pkt(pktp);
12108 	}
12109 	if (tran_clone) {
12110 		kmem_free(tran_clone, sizeof (scsi_hba_tran_t));
12111 	}
12112 	if (tgt_private) {
12113 		kmem_free(tgt_private, sizeof (mptsas_tgt_private_t));
12114 	}
12115 	return (ret);
12116 }
12117 static int
12118 mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, int *lun)
12119 {
12120 	char	*cp = NULL;
12121 	char	*ptr = NULL;
12122 	size_t	s = 0;
12123 	char	*wwid_str = NULL;
12124 	char	*lun_str = NULL;
12125 	long	lunnum;
12126 	long	phyid = -1;
12127 	int	rc = DDI_FAILURE;
12128 
12129 	ptr = name;
12130 	ASSERT(ptr[0] == 'w' || ptr[0] == 'p');
12131 	ptr++;
12132 	if ((cp = strchr(ptr, ',')) == NULL) {
12133 		return (DDI_FAILURE);
12134 	}
12135 
12136 	wwid_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
12137 	s = (uintptr_t)cp - (uintptr_t)ptr;
12138 
12139 	bcopy(ptr, wwid_str, s);
12140 	wwid_str[s] = '\0';
12141 
12142 	ptr = ++cp;
12143 
12144 	if ((cp = strchr(ptr, '\0')) == NULL) {
12145 		goto out;
12146 	}
12147 	lun_str =  kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
12148 	s = (uintptr_t)cp - (uintptr_t)ptr;
12149 
12150 	bcopy(ptr, lun_str, s);
12151 	lun_str[s] = '\0';
12152 
12153 	if (name[0] == 'p') {
12154 		rc = ddi_strtol(wwid_str, NULL, 0x10, &phyid);
12155 	} else {
12156 		rc = scsi_wwnstr_to_wwn(wwid_str, wwid);
12157 	}
12158 	if (rc != DDI_SUCCESS)
12159 		goto out;
12160 
12161 	if (phyid != -1) {
12162 		ASSERT(phyid < 8);
12163 		*phy = (uint8_t)phyid;
12164 	}
12165 	rc = ddi_strtol(lun_str, NULL, 0x10, &lunnum);
12166 	if (rc != 0)
12167 		goto out;
12168 
12169 	*lun = (int)lunnum;
12170 	rc = DDI_SUCCESS;
12171 out:
12172 	if (wwid_str)
12173 		kmem_free(wwid_str, SCSI_MAXNAMELEN);
12174 	if (lun_str)
12175 		kmem_free(lun_str, SCSI_MAXNAMELEN);
12176 
12177 	return (rc);
12178 }
12179 
12180 /*
12181  * mptsas_parse_smp_name() is to parse sas wwn string
12182  * which format is "wWWN"
12183  */
12184 static int
12185 mptsas_parse_smp_name(char *name, uint64_t *wwn)
12186 {
12187 	char	*ptr = name;
12188 
12189 	if (*ptr != 'w') {
12190 		return (DDI_FAILURE);
12191 	}
12192 
12193 	ptr++;
12194 	if (scsi_wwnstr_to_wwn(ptr, wwn)) {
12195 		return (DDI_FAILURE);
12196 	}
12197 	return (DDI_SUCCESS);
12198 }
12199 
12200 static int
12201 mptsas_bus_config(dev_info_t *pdip, uint_t flag,
12202     ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
12203 {
12204 	int		ret = NDI_FAILURE;
12205 	int		circ = 0;
12206 	int		circ1 = 0;
12207 	mptsas_t	*mpt;
12208 	char		*ptr = NULL;
12209 	char		*devnm = NULL;
12210 	uint64_t	wwid = 0;
12211 	uint8_t		phy = 0xFF;
12212 	int		lun = 0;
12213 	uint_t		mflags = flag;
12214 
12215 	if (scsi_hba_iport_unit_address(pdip) == 0) {
12216 		return (DDI_FAILURE);
12217 	}
12218 
12219 	mpt = DIP2MPT(pdip);
12220 	if (!mpt) {
12221 		return (DDI_FAILURE);
12222 	}
12223 
12224 	/*
12225 	 * Hold the nexus across the bus_config
12226 	 */
12227 	ndi_devi_enter(scsi_vhci_dip, &circ);
12228 	ndi_devi_enter(pdip, &circ1);
12229 	switch (op) {
12230 	case BUS_CONFIG_ONE:
12231 		/* parse wwid/target name out of name given */
12232 		if ((ptr = strchr((char *)arg, '@')) == NULL) {
12233 			ret = NDI_FAILURE;
12234 			break;
12235 		}
12236 		ptr++;
12237 		if (strncmp((char *)arg, "smp", 3) == 0) {
12238 			/*
12239 			 * This is a SMP target device
12240 			 */
12241 			ret = mptsas_parse_smp_name(ptr, &wwid);
12242 			if (ret != DDI_SUCCESS) {
12243 				ret = NDI_FAILURE;
12244 				break;
12245 			}
12246 			ret = mptsas_config_smp(pdip, wwid, childp);
12247 		} else if ((ptr[0] == 'w') || (ptr[0] == 'p')) {
12248 			/*
12249 			 * OBP could pass down a non-canonical form
12250 			 * bootpath without LUN part when LUN is 0.
12251 			 * So driver need adjust the string.
12252 			 */
12253 			if (strchr(ptr, ',') == NULL) {
12254 				devnm = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
12255 				(void) sprintf(devnm, "%s,0", (char *)arg);
12256 				ptr = strchr(devnm, '@');
12257 				ptr++;
12258 			}
12259 
12260 			/*
12261 			 * The device path is wWWID format and the device
12262 			 * is not SMP target device.
12263 			 */
12264 			ret = mptsas_parse_address(ptr, &wwid, &phy, &lun);
12265 			if (ret != DDI_SUCCESS) {
12266 				ret = NDI_FAILURE;
12267 				break;
12268 			}
12269 			if (ptr[0] == 'w') {
12270 				ret = mptsas_config_one_addr(pdip, wwid,
12271 				    lun, childp);
12272 			} else if (ptr[0] == 'p') {
12273 				ret = mptsas_config_one_phy(pdip, phy, lun,
12274 				    childp);
12275 			}
12276 		} else {
12277 			ret = NDI_FAILURE;
12278 			break;
12279 		}
12280 
12281 		/*
12282 		 * DDI group instructed us to use this flag.
12283 		 */
12284 		mflags |= NDI_MDI_FALLBACK;
12285 		break;
12286 	case BUS_CONFIG_DRIVER:
12287 	case BUS_CONFIG_ALL:
12288 		mptsas_config_all(pdip);
12289 		ret = NDI_SUCCESS;
12290 		break;
12291 	}
12292 
12293 	if (ret == NDI_SUCCESS) {
12294 		ret = ndi_busop_bus_config(pdip, mflags, op,
12295 		    (devnm == NULL) ? arg : devnm, childp, 0);
12296 	}
12297 
12298 	ndi_devi_exit(pdip, circ1);
12299 	ndi_devi_exit(scsi_vhci_dip, circ);
12300 	if (devnm != NULL)
12301 		kmem_free(devnm, SCSI_MAXNAMELEN);
12302 	return (ret);
12303 }
12304 
12305 static int
12306 mptsas_probe_lun(dev_info_t *pdip, int lun, dev_info_t **dip,
12307     mptsas_target_t *ptgt)
12308 {
12309 	int			rval = DDI_FAILURE;
12310 	struct scsi_inquiry	*sd_inq = NULL;
12311 	mptsas_t		*mpt = DIP2MPT(pdip);
12312 
12313 	sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP);
12314 
12315 	rval = mptsas_inquiry(mpt, ptgt, lun, 0, (uchar_t *)sd_inq,
12316 	    SUN_INQSIZE, 0, (uchar_t)0);
12317 
12318 	if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) {
12319 		rval = mptsas_create_lun(pdip, sd_inq, dip, ptgt, lun);
12320 	} else {
12321 		rval = DDI_FAILURE;
12322 	}
12323 
12324 	kmem_free(sd_inq, SUN_INQSIZE);
12325 	return (rval);
12326 }
12327 
12328 static int
12329 mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
12330     dev_info_t **lundip)
12331 {
12332 	int		rval;
12333 	mptsas_t		*mpt = DIP2MPT(pdip);
12334 	int		phymask;
12335 	mptsas_target_t	*ptgt = NULL;
12336 
12337 	/*
12338 	 * Get the physical port associated to the iport
12339 	 */
12340 	phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
12341 	    "phymask", 0);
12342 
12343 	ptgt = mptsas_wwid_to_ptgt(mpt, phymask, sasaddr);
12344 	if (ptgt == NULL) {
12345 		/*
12346 		 * didn't match any device by searching
12347 		 */
12348 		return (DDI_FAILURE);
12349 	}
12350 	/*
12351 	 * If the LUN already exists and the status is online,
12352 	 * we just return the pointer to dev_info_t directly.
12353 	 * For the mdi_pathinfo node, we'll handle it in
12354 	 * mptsas_create_virt_lun()
12355 	 * TODO should be also in mptsas_handle_dr
12356 	 */
12357 
12358 	*lundip = mptsas_find_child_addr(pdip, sasaddr, lun);
12359 	if (*lundip != NULL) {
12360 		/*
12361 		 * TODO Another senario is, we hotplug the same disk
12362 		 * on the same slot, the devhdl changed, is this
12363 		 * possible?
12364 		 * tgt_private->t_private != ptgt
12365 		 */
12366 		if (sasaddr != ptgt->m_sas_wwn) {
12367 			/*
12368 			 * The device has changed although the devhdl is the
12369 			 * same (Enclosure mapping mode, change drive on the
12370 			 * same slot)
12371 			 */
12372 			return (DDI_FAILURE);
12373 		}
12374 		return (DDI_SUCCESS);
12375 	}
12376 
12377 	if (phymask == 0) {
12378 		/*
12379 		 * Configure IR volume
12380 		 */
12381 		rval =  mptsas_config_raid(pdip, ptgt->m_devhdl, lundip);
12382 		return (rval);
12383 	}
12384 	rval = mptsas_probe_lun(pdip, lun, lundip, ptgt);
12385 
12386 	return (rval);
12387 }
12388 
12389 static int
12390 mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
12391     dev_info_t **lundip)
12392 {
12393 	int		rval;
12394 	mptsas_target_t	*ptgt = NULL;
12395 
12396 	ptgt = mptsas_phy_to_tgt(pdip, phy);
12397 	if (ptgt == NULL) {
12398 		/*
12399 		 * didn't match any device by searching
12400 		 */
12401 		return (DDI_FAILURE);
12402 	}
12403 
12404 	/*
12405 	 * If the LUN already exists and the status is online,
12406 	 * we just return the pointer to dev_info_t directly.
12407 	 * For the mdi_pathinfo node, we'll handle it in
12408 	 * mptsas_create_virt_lun().
12409 	 */
12410 
12411 	*lundip = mptsas_find_child_phy(pdip, phy);
12412 	if (*lundip != NULL) {
12413 		return (DDI_SUCCESS);
12414 	}
12415 
12416 	rval = mptsas_probe_lun(pdip, lun, lundip, ptgt);
12417 
12418 	return (rval);
12419 }
12420 
12421 static int
12422 mptsas_retrieve_lundata(int lun_cnt, uint8_t *buf, uint16_t *lun_num,
12423     uint8_t *lun_addr_type)
12424 {
12425 	uint32_t	lun_idx = 0;
12426 
12427 	ASSERT(lun_num != NULL);
12428 	ASSERT(lun_addr_type != NULL);
12429 
12430 	lun_idx = (lun_cnt + 1) * MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE;
12431 	/* determine report luns addressing type */
12432 	switch (buf[lun_idx] & MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) {
12433 		/*
12434 		 * Vendors in the field have been found to be concatenating
12435 		 * bus/target/lun to equal the complete lun value instead
12436 		 * of switching to flat space addressing
12437 		 */
12438 		/* 00b - peripheral device addressing method */
12439 	case MPTSAS_SCSI_REPORTLUNS_ADDRESS_PERIPHERAL:
12440 		/* FALLTHRU */
12441 		/* 10b - logical unit addressing method */
12442 	case MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT:
12443 		/* FALLTHRU */
12444 		/* 01b - flat space addressing method */
12445 	case MPTSAS_SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE:
12446 		/* byte0 bit0-5=msb lun byte1 bit0-7=lsb lun */
12447 		*lun_addr_type = (buf[lun_idx] &
12448 		    MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) >> 6;
12449 		*lun_num = (buf[lun_idx] & 0x3F) << 8;
12450 		*lun_num |= buf[lun_idx + 1];
12451 		return (DDI_SUCCESS);
12452 	default:
12453 		return (DDI_FAILURE);
12454 	}
12455 }
12456 
12457 static int
12458 mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt)
12459 {
12460 	struct buf		*repluns_bp = NULL;
12461 	struct scsi_address	ap;
12462 	uchar_t			cdb[CDB_GROUP5];
12463 	int			ret = DDI_FAILURE;
12464 	int			retry = 0;
12465 	int			lun_list_len = 0;
12466 	uint16_t		lun_num = 0;
12467 	uint8_t			lun_addr_type = 0;
12468 	uint32_t		lun_cnt = 0;
12469 	uint32_t		lun_total = 0;
12470 	dev_info_t		*cdip = NULL;
12471 	uint16_t		*saved_repluns = NULL;
12472 	char			*buffer = NULL;
12473 	int			buf_len = 128;
12474 	mptsas_t		*mpt = DIP2MPT(pdip);
12475 	uint64_t		sas_wwn = 0;
12476 	uint8_t			phy = 0xFF;
12477 	uint32_t		dev_info = 0;
12478 
12479 	mutex_enter(&mpt->m_mutex);
12480 	sas_wwn = ptgt->m_sas_wwn;
12481 	phy = ptgt->m_phynum;
12482 	dev_info = ptgt->m_deviceinfo;
12483 	mutex_exit(&mpt->m_mutex);
12484 
12485 	if (sas_wwn == 0) {
12486 		/*
12487 		 * It's a SATA without Device Name
12488 		 * So don't try multi-LUNs
12489 		 */
12490 		if (mptsas_find_child_phy(pdip, phy)) {
12491 			return (DDI_SUCCESS);
12492 		} else {
12493 			/*
12494 			 * need configure and create node
12495 			 */
12496 			return (DDI_FAILURE);
12497 		}
12498 	}
12499 
12500 	/*
12501 	 * WWN (SAS address or Device Name exist)
12502 	 */
12503 	if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
12504 	    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
12505 		/*
12506 		 * SATA device with Device Name
12507 		 * So don't try multi-LUNs
12508 		 */
12509 		if (mptsas_find_child_addr(pdip, sas_wwn, 0)) {
12510 			return (DDI_SUCCESS);
12511 		} else {
12512 			return (DDI_FAILURE);
12513 		}
12514 	}
12515 
12516 	do {
12517 		ap.a_target = MPTSAS_INVALID_DEVHDL;
12518 		ap.a_lun = 0;
12519 		ap.a_hba_tran = mpt->m_tran;
12520 		repluns_bp = scsi_alloc_consistent_buf(&ap,
12521 		    (struct buf *)NULL, buf_len, B_READ, NULL_FUNC, NULL);
12522 		if (repluns_bp == NULL) {
12523 			retry++;
12524 			continue;
12525 		}
12526 		bzero(cdb, CDB_GROUP5);
12527 		cdb[0] = SCMD_REPORT_LUNS;
12528 		cdb[6] = (buf_len & 0xff000000) >> 24;
12529 		cdb[7] = (buf_len & 0x00ff0000) >> 16;
12530 		cdb[8] = (buf_len & 0x0000ff00) >> 8;
12531 		cdb[9] = (buf_len & 0x000000ff);
12532 
12533 		ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP5,
12534 		    repluns_bp, NULL);
12535 		if (ret != DDI_SUCCESS) {
12536 			scsi_free_consistent_buf(repluns_bp);
12537 			retry++;
12538 			continue;
12539 		}
12540 		lun_list_len = BE_32(*(int *)((void *)(
12541 		    repluns_bp->b_un.b_addr)));
12542 		if (buf_len >= lun_list_len + 8) {
12543 			ret = DDI_SUCCESS;
12544 			break;
12545 		}
12546 		scsi_free_consistent_buf(repluns_bp);
12547 		buf_len = lun_list_len + 8;
12548 
12549 	} while (retry < 3);
12550 
12551 	if (ret != DDI_SUCCESS)
12552 		return (ret);
12553 	buffer = (char *)repluns_bp->b_un.b_addr;
12554 	/*
12555 	 * find out the number of luns returned by the SCSI ReportLun call
12556 	 * and allocate buffer space
12557 	 */
12558 	lun_total = lun_list_len / MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE;
12559 	saved_repluns = kmem_zalloc(sizeof (uint16_t) * lun_total, KM_SLEEP);
12560 	if (saved_repluns == NULL) {
12561 		scsi_free_consistent_buf(repluns_bp);
12562 		return (DDI_FAILURE);
12563 	}
12564 	for (lun_cnt = 0; lun_cnt < lun_total; lun_cnt++) {
12565 		if (mptsas_retrieve_lundata(lun_cnt, (uint8_t *)(buffer),
12566 		    &lun_num, &lun_addr_type) != DDI_SUCCESS) {
12567 			continue;
12568 		}
12569 		saved_repluns[lun_cnt] = lun_num;
12570 		if (cdip = mptsas_find_child_addr(pdip, sas_wwn, lun_num))
12571 			ret = DDI_SUCCESS;
12572 		else
12573 			ret = mptsas_probe_lun(pdip, lun_num, &cdip,
12574 			    ptgt);
12575 		if ((ret == DDI_SUCCESS) && (cdip != NULL)) {
12576 			(void) ndi_prop_remove(DDI_DEV_T_NONE, cdip,
12577 			    MPTSAS_DEV_GONE);
12578 		}
12579 	}
12580 	mptsas_offline_missed_luns(pdip, saved_repluns, lun_total, ptgt);
12581 	kmem_free(saved_repluns, sizeof (uint16_t) * lun_total);
12582 	scsi_free_consistent_buf(repluns_bp);
12583 	return (DDI_SUCCESS);
12584 }
12585 
12586 static int
12587 mptsas_config_raid(dev_info_t *pdip, uint16_t target, dev_info_t **dip)
12588 {
12589 	int			rval = DDI_FAILURE;
12590 	struct scsi_inquiry	*sd_inq = NULL;
12591 	mptsas_t		*mpt = DIP2MPT(pdip);
12592 	mptsas_target_t		*ptgt = NULL;
12593 
12594 	mutex_enter(&mpt->m_mutex);
12595 	ptgt = mptsas_search_by_devhdl(&mpt->m_active->m_tgttbl, target);
12596 	mutex_exit(&mpt->m_mutex);
12597 	if (ptgt == NULL) {
12598 		mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x "
12599 		    "not found.", target);
12600 		return (rval);
12601 	}
12602 
12603 	sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP);
12604 	rval = mptsas_inquiry(mpt, ptgt, 0, 0, (uchar_t *)sd_inq,
12605 	    SUN_INQSIZE, 0, (uchar_t)0);
12606 
12607 	if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) {
12608 		rval = mptsas_create_phys_lun(pdip, sd_inq, NULL, dip, ptgt,
12609 		    0);
12610 	} else {
12611 		rval = DDI_FAILURE;
12612 	}
12613 
12614 	kmem_free(sd_inq, SUN_INQSIZE);
12615 	return (rval);
12616 }
12617 
12618 /*
12619  * configure all RAID volumes for virtual iport
12620  */
12621 static void
12622 mptsas_config_all_viport(dev_info_t *pdip)
12623 {
12624 	mptsas_t	*mpt = DIP2MPT(pdip);
12625 	int		config, vol;
12626 	int		target;
12627 	dev_info_t	*lundip = NULL;
12628 	mptsas_slots_t	*slots = mpt->m_active;
12629 
12630 	/*
12631 	 * Get latest RAID info and search for any Volume DevHandles.  If any
12632 	 * are found, configure the volume.
12633 	 */
12634 	mutex_enter(&mpt->m_mutex);
12635 	for (config = 0; config < slots->m_num_raid_configs; config++) {
12636 		for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
12637 			if (slots->m_raidconfig[config].m_raidvol[vol].m_israid
12638 			    == 1) {
12639 				target = slots->m_raidconfig[config].
12640 				    m_raidvol[vol].m_raidhandle;
12641 				mutex_exit(&mpt->m_mutex);
12642 				(void) mptsas_config_raid(pdip, target,
12643 				    &lundip);
12644 				mutex_enter(&mpt->m_mutex);
12645 			}
12646 		}
12647 	}
12648 	mutex_exit(&mpt->m_mutex);
12649 }
12650 
12651 static void
12652 mptsas_offline_missed_luns(dev_info_t *pdip, uint16_t *repluns,
12653     int lun_cnt, mptsas_target_t *ptgt)
12654 {
12655 	dev_info_t	*child = NULL, *savechild = NULL;
12656 	mdi_pathinfo_t	*pip = NULL, *savepip = NULL;
12657 	uint64_t	sas_wwn, wwid;
12658 	uint8_t		phy;
12659 	int		lun;
12660 	int		i;
12661 	int		find;
12662 	char		*addr;
12663 	char		*nodename;
12664 	mptsas_t	*mpt = DIP2MPT(pdip);
12665 
12666 	mutex_enter(&mpt->m_mutex);
12667 	wwid = ptgt->m_sas_wwn;
12668 	mutex_exit(&mpt->m_mutex);
12669 
12670 	child = ddi_get_child(pdip);
12671 	while (child) {
12672 		find = 0;
12673 		savechild = child;
12674 		child = ddi_get_next_sibling(child);
12675 
12676 		nodename = ddi_node_name(savechild);
12677 		if (strcmp(nodename, "smp") == 0) {
12678 			continue;
12679 		}
12680 
12681 		addr = ddi_get_name_addr(savechild);
12682 		if (addr == NULL) {
12683 			continue;
12684 		}
12685 
12686 		if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) !=
12687 		    DDI_SUCCESS) {
12688 			continue;
12689 		}
12690 
12691 		if (wwid == sas_wwn) {
12692 			for (i = 0; i < lun_cnt; i++) {
12693 				if (repluns[i] == lun) {
12694 					find = 1;
12695 					break;
12696 				}
12697 			}
12698 		} else {
12699 			continue;
12700 		}
12701 		if (find == 0) {
12702 			/*
12703 			 * The lun has not been there already
12704 			 */
12705 			(void) mptsas_offline_lun(pdip, savechild, NULL,
12706 			    NDI_DEVI_REMOVE);
12707 		}
12708 	}
12709 
12710 	pip = mdi_get_next_client_path(pdip, NULL);
12711 	while (pip) {
12712 		find = 0;
12713 		savepip = pip;
12714 		addr = MDI_PI(pip)->pi_addr;
12715 
12716 		pip = mdi_get_next_client_path(pdip, pip);
12717 
12718 		if (addr == NULL) {
12719 			continue;
12720 		}
12721 
12722 		if (mptsas_parse_address(addr, &sas_wwn, &phy,
12723 		    &lun) != DDI_SUCCESS) {
12724 			continue;
12725 		}
12726 
12727 		if (sas_wwn == wwid) {
12728 			for (i = 0; i < lun_cnt; i++) {
12729 				if (repluns[i] == lun) {
12730 					find = 1;
12731 					break;
12732 				}
12733 			}
12734 		} else {
12735 			continue;
12736 		}
12737 
12738 		if (find == 0) {
12739 			/*
12740 			 * The lun has not been there already
12741 			 */
12742 			(void) mptsas_offline_lun(pdip, NULL, savepip,
12743 			    NDI_DEVI_REMOVE);
12744 		}
12745 	}
12746 }
12747 
12748 void
12749 mptsas_update_hashtab(struct mptsas *mpt)
12750 {
12751 	uint32_t	page_address;
12752 	int		rval = 0;
12753 	uint16_t	dev_handle;
12754 	mptsas_target_t	*ptgt = NULL;
12755 	mptsas_smp_t	smp_node;
12756 
12757 	/*
12758 	 * Get latest RAID info.
12759 	 */
12760 	(void) mptsas_get_raid_info(mpt);
12761 
12762 	dev_handle = mpt->m_smp_devhdl;
12763 	for (; mpt->m_done_traverse_smp == 0; ) {
12764 		page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
12765 		    MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)dev_handle;
12766 		if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node)
12767 		    != DDI_SUCCESS) {
12768 			break;
12769 		}
12770 		mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl;
12771 		(void) mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node);
12772 	}
12773 
12774 	/*
12775 	 * Config target devices
12776 	 */
12777 	dev_handle = mpt->m_dev_handle;
12778 
12779 	/*
12780 	 * Do loop to get sas device page 0 by GetNextHandle till the
12781 	 * the last handle. If the sas device is a SATA/SSP target,
12782 	 * we try to config it.
12783 	 */
12784 	for (; mpt->m_done_traverse_dev == 0; ) {
12785 		ptgt = NULL;
12786 		page_address =
12787 		    (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
12788 		    MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
12789 		    (uint32_t)dev_handle;
12790 		rval = mptsas_get_target_device_info(mpt, page_address,
12791 		    &dev_handle, &ptgt);
12792 		if ((rval == DEV_INFO_FAIL_PAGE0) ||
12793 		    (rval == DEV_INFO_FAIL_ALLOC)) {
12794 			break;
12795 		}
12796 
12797 		mpt->m_dev_handle = dev_handle;
12798 	}
12799 
12800 }
12801 
12802 void
12803 mptsas_invalid_hashtab(mptsas_hash_table_t *hashtab)
12804 {
12805 	mptsas_hash_data_t *data;
12806 	data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST);
12807 	while (data != NULL) {
12808 		data->devhdl = MPTSAS_INVALID_DEVHDL;
12809 		data->device_info = 0;
12810 		/*
12811 		 * For tgttbl, clear dr_flag.
12812 		 */
12813 		data->dr_flag = MPTSAS_DR_INACTIVE;
12814 		data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT);
12815 	}
12816 }
12817 
12818 void
12819 mptsas_update_driver_data(struct mptsas *mpt)
12820 {
12821 	/*
12822 	 * TODO after hard reset, update the driver data structures
12823 	 * 1. update port/phymask mapping table mpt->m_phy_info
12824 	 * 2. invalid all the entries in hash table
12825 	 *    m_devhdl = 0xffff and m_deviceinfo = 0
12826 	 * 3. call sas_device_page/expander_page to update hash table
12827 	 */
12828 	mptsas_update_phymask(mpt);
12829 	/*
12830 	 * Invalid the existing entries
12831 	 */
12832 	mptsas_invalid_hashtab(&mpt->m_active->m_tgttbl);
12833 	mptsas_invalid_hashtab(&mpt->m_active->m_smptbl);
12834 	mpt->m_done_traverse_dev = 0;
12835 	mpt->m_done_traverse_smp = 0;
12836 	mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL;
12837 	mptsas_update_hashtab(mpt);
12838 }
12839 
12840 static void
12841 mptsas_config_all(dev_info_t *pdip)
12842 {
12843 	dev_info_t	*smpdip = NULL;
12844 	mptsas_t	*mpt = DIP2MPT(pdip);
12845 	int		phymask = 0;
12846 	uint8_t		phy_mask;
12847 	mptsas_target_t	*ptgt = NULL;
12848 	mptsas_smp_t	*psmp;
12849 
12850 	/*
12851 	 * Get the phymask associated to the iport
12852 	 */
12853 	phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
12854 	    "phymask", 0);
12855 
12856 	/*
12857 	 * Enumerate RAID volumes here (phymask == 0).
12858 	 */
12859 	if (phymask == 0) {
12860 		mptsas_config_all_viport(pdip);
12861 		return;
12862 	}
12863 
12864 	mutex_enter(&mpt->m_mutex);
12865 
12866 	if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp) {
12867 		mptsas_update_hashtab(mpt);
12868 	}
12869 
12870 	psmp = (mptsas_smp_t *)mptsas_hash_traverse(&mpt->m_active->m_smptbl,
12871 	    MPTSAS_HASH_FIRST);
12872 	while (psmp != NULL) {
12873 		phy_mask = psmp->m_phymask;
12874 		if (phy_mask == phymask) {
12875 			smpdip = NULL;
12876 			mutex_exit(&mpt->m_mutex);
12877 			(void) mptsas_online_smp(pdip, psmp, &smpdip);
12878 			mutex_enter(&mpt->m_mutex);
12879 		}
12880 		psmp = (mptsas_smp_t *)mptsas_hash_traverse(
12881 		    &mpt->m_active->m_smptbl, MPTSAS_HASH_NEXT);
12882 	}
12883 
12884 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
12885 	    MPTSAS_HASH_FIRST);
12886 	while (ptgt != NULL) {
12887 		phy_mask = ptgt->m_phymask;
12888 		if (phy_mask == phymask) {
12889 			mutex_exit(&mpt->m_mutex);
12890 			(void) mptsas_config_target(pdip, ptgt);
12891 			mutex_enter(&mpt->m_mutex);
12892 		}
12893 
12894 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
12895 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
12896 	}
12897 	mutex_exit(&mpt->m_mutex);
12898 }
12899 
12900 static int
12901 mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt)
12902 {
12903 	int		rval = DDI_FAILURE;
12904 	dev_info_t	*tdip;
12905 
12906 	rval = mptsas_config_luns(pdip, ptgt);
12907 	if (rval != DDI_SUCCESS) {
12908 		/*
12909 		 * The return value means the SCMD_REPORT_LUNS
12910 		 * did not execute successfully. The target maybe
12911 		 * doesn't support such command.
12912 		 */
12913 		rval = mptsas_probe_lun(pdip, 0, &tdip, ptgt);
12914 	}
12915 	return (rval);
12916 }
12917 
12918 /*
12919  * Return fail if not all the childs/paths are freed.
12920  * if there is any path under the HBA, the return value will be always fail
12921  * because we didn't call mdi_pi_free for path
12922  */
12923 static int
12924 mptsas_offline_target(dev_info_t *pdip, char *name)
12925 {
12926 	dev_info_t		*child = NULL, *prechild = NULL;
12927 	mdi_pathinfo_t		*pip = NULL, *savepip = NULL;
12928 	int			tmp_rval, rval = DDI_SUCCESS;
12929 	char			*addr, *cp;
12930 	size_t			s;
12931 	mptsas_t		*mpt = DIP2MPT(pdip);
12932 
12933 	child = ddi_get_child(pdip);
12934 	while (child) {
12935 		addr = ddi_get_name_addr(child);
12936 		prechild = child;
12937 		child = ddi_get_next_sibling(child);
12938 
12939 		if (addr == NULL) {
12940 			continue;
12941 		}
12942 		if ((cp = strchr(addr, ',')) == NULL) {
12943 			continue;
12944 		}
12945 
12946 		s = (uintptr_t)cp - (uintptr_t)addr;
12947 
12948 		if (strncmp(addr, name, s) != 0) {
12949 			continue;
12950 		}
12951 
12952 		tmp_rval = mptsas_offline_lun(pdip, prechild, NULL,
12953 		    NDI_DEVI_REMOVE);
12954 		if (tmp_rval != DDI_SUCCESS) {
12955 			rval = DDI_FAILURE;
12956 			if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
12957 			    prechild, MPTSAS_DEV_GONE) !=
12958 			    DDI_PROP_SUCCESS) {
12959 				mptsas_log(mpt, CE_WARN, "mptsas driver "
12960 				    "unable to create property for "
12961 				    "SAS %s (MPTSAS_DEV_GONE)", addr);
12962 			}
12963 		}
12964 	}
12965 
12966 	pip = mdi_get_next_client_path(pdip, NULL);
12967 	while (pip) {
12968 		addr = MDI_PI(pip)->pi_addr;
12969 		savepip = pip;
12970 		pip = mdi_get_next_client_path(pdip, pip);
12971 		if (addr == NULL) {
12972 			continue;
12973 		}
12974 
12975 		if ((cp = strchr(addr, ',')) == NULL) {
12976 			continue;
12977 		}
12978 
12979 		s = (uintptr_t)cp - (uintptr_t)addr;
12980 
12981 		if (strncmp(addr, name, s) != 0) {
12982 			continue;
12983 		}
12984 
12985 		(void) mptsas_offline_lun(pdip, NULL, savepip,
12986 		    NDI_DEVI_REMOVE);
12987 		/*
12988 		 * driver will not invoke mdi_pi_free, so path will not
12989 		 * be freed forever, return DDI_FAILURE.
12990 		 */
12991 		rval = DDI_FAILURE;
12992 	}
12993 	return (rval);
12994 }
12995 
12996 static int
12997 mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
12998     mdi_pathinfo_t *rpip, uint_t flags)
12999 {
13000 	int		rval = DDI_FAILURE;
13001 	char		*devname;
13002 	dev_info_t	*cdip, *parent;
13003 
13004 	if (rpip != NULL) {
13005 		parent = scsi_vhci_dip;
13006 		cdip = mdi_pi_get_client(rpip);
13007 	} else if (rdip != NULL) {
13008 		parent = pdip;
13009 		cdip = rdip;
13010 	} else {
13011 		return (DDI_FAILURE);
13012 	}
13013 
13014 	/*
13015 	 * Make sure node is attached otherwise
13016 	 * it won't have related cache nodes to
13017 	 * clean up.  i_ddi_devi_attached is
13018 	 * similiar to i_ddi_node_state(cdip) >=
13019 	 * DS_ATTACHED.
13020 	 */
13021 	if (i_ddi_devi_attached(cdip)) {
13022 
13023 		/* Get full devname */
13024 		devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
13025 		(void) ddi_deviname(cdip, devname);
13026 		/* Clean cache */
13027 		(void) devfs_clean(parent, devname + 1,
13028 		    DV_CLEAN_FORCE);
13029 		kmem_free(devname, MAXNAMELEN + 1);
13030 	}
13031 	if (rpip != NULL) {
13032 		if (MDI_PI_IS_OFFLINE(rpip)) {
13033 			rval = DDI_SUCCESS;
13034 		} else {
13035 			rval = mdi_pi_offline(rpip, 0);
13036 		}
13037 	} else {
13038 		rval = ndi_devi_offline(cdip, flags);
13039 	}
13040 
13041 	return (rval);
13042 }
13043 
13044 static dev_info_t *
13045 mptsas_find_smp_child(dev_info_t *parent, char *str_wwn)
13046 {
13047 	dev_info_t	*child = NULL;
13048 	char		*smp_wwn = NULL;
13049 
13050 	child = ddi_get_child(parent);
13051 	while (child) {
13052 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
13053 		    DDI_PROP_DONTPASS, SMP_WWN, &smp_wwn)
13054 		    != DDI_SUCCESS) {
13055 			child = ddi_get_next_sibling(child);
13056 			continue;
13057 		}
13058 
13059 		if (strcmp(smp_wwn, str_wwn) == 0) {
13060 			ddi_prop_free(smp_wwn);
13061 			break;
13062 		}
13063 		child = ddi_get_next_sibling(child);
13064 		ddi_prop_free(smp_wwn);
13065 	}
13066 	return (child);
13067 }
13068 
13069 static int
13070 mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags)
13071 {
13072 	int		rval = DDI_FAILURE;
13073 	char		*devname;
13074 	char		wwn_str[MPTSAS_WWN_STRLEN];
13075 	dev_info_t	*cdip;
13076 
13077 	(void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr);
13078 
13079 	cdip = mptsas_find_smp_child(pdip, wwn_str);
13080 
13081 	if (cdip == NULL)
13082 		return (DDI_SUCCESS);
13083 
13084 	/*
13085 	 * Make sure node is attached otherwise
13086 	 * it won't have related cache nodes to
13087 	 * clean up.  i_ddi_devi_attached is
13088 	 * similiar to i_ddi_node_state(cdip) >=
13089 	 * DS_ATTACHED.
13090 	 */
13091 	if (i_ddi_devi_attached(cdip)) {
13092 
13093 		/* Get full devname */
13094 		devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
13095 		(void) ddi_deviname(cdip, devname);
13096 		/* Clean cache */
13097 		(void) devfs_clean(pdip, devname + 1,
13098 		    DV_CLEAN_FORCE);
13099 		kmem_free(devname, MAXNAMELEN + 1);
13100 	}
13101 
13102 	rval = ndi_devi_offline(cdip, flags);
13103 
13104 	return (rval);
13105 }
13106 
13107 static dev_info_t *
13108 mptsas_find_child(dev_info_t *pdip, char *name)
13109 {
13110 	dev_info_t	*child = NULL;
13111 	char		*rname = NULL;
13112 	int		rval = DDI_FAILURE;
13113 
13114 	rname = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13115 
13116 	child = ddi_get_child(pdip);
13117 	while (child) {
13118 		rval = mptsas_name_child(child, rname, SCSI_MAXNAMELEN);
13119 		if (rval != DDI_SUCCESS) {
13120 			child = ddi_get_next_sibling(child);
13121 			bzero(rname, SCSI_MAXNAMELEN);
13122 			continue;
13123 		}
13124 
13125 		if (strcmp(rname, name) == 0) {
13126 			break;
13127 		}
13128 		child = ddi_get_next_sibling(child);
13129 		bzero(rname, SCSI_MAXNAMELEN);
13130 	}
13131 
13132 	kmem_free(rname, SCSI_MAXNAMELEN);
13133 
13134 	return (child);
13135 }
13136 
13137 
13138 static dev_info_t *
13139 mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, int lun)
13140 {
13141 	dev_info_t	*child = NULL;
13142 	char		*name = NULL;
13143 	char		*addr = NULL;
13144 
13145 	name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13146 	addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13147 	(void) sprintf(name, "%016"PRIx64, sasaddr);
13148 	(void) sprintf(addr, "w%s,%x", name, lun);
13149 	child = mptsas_find_child(pdip, addr);
13150 	kmem_free(name, SCSI_MAXNAMELEN);
13151 	kmem_free(addr, SCSI_MAXNAMELEN);
13152 	return (child);
13153 }
13154 
13155 static dev_info_t *
13156 mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy)
13157 {
13158 	dev_info_t	*child;
13159 	char		*addr;
13160 
13161 	addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13162 	(void) sprintf(addr, "p%x,0", phy);
13163 	child = mptsas_find_child(pdip, addr);
13164 	kmem_free(addr, SCSI_MAXNAMELEN);
13165 	return (child);
13166 }
13167 
13168 static mdi_pathinfo_t *
13169 mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy)
13170 {
13171 	mdi_pathinfo_t	*path;
13172 	char		*addr = NULL;
13173 
13174 	addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13175 	(void) sprintf(addr, "p%x,0", phy);
13176 	path = mdi_pi_find(pdip, NULL, addr);
13177 	kmem_free(addr, SCSI_MAXNAMELEN);
13178 	return (path);
13179 }
13180 
13181 static mdi_pathinfo_t *
13182 mptsas_find_path_addr(dev_info_t *parent, uint64_t sasaddr, int lun)
13183 {
13184 	mdi_pathinfo_t	*path;
13185 	char		*name = NULL;
13186 	char		*addr = NULL;
13187 
13188 	name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13189 	addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13190 	(void) sprintf(name, "%016"PRIx64, sasaddr);
13191 	(void) sprintf(addr, "w%s,%x", name, lun);
13192 	path = mdi_pi_find(parent, NULL, addr);
13193 	kmem_free(name, SCSI_MAXNAMELEN);
13194 	kmem_free(addr, SCSI_MAXNAMELEN);
13195 
13196 	return (path);
13197 }
13198 
13199 static int
13200 mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq,
13201     dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun)
13202 {
13203 	int			i = 0;
13204 	uchar_t			*inq83 = NULL;
13205 	int			inq83_len1 = 0xFF;
13206 	int			inq83_len = 0;
13207 	int			rval = DDI_FAILURE;
13208 	ddi_devid_t		devid;
13209 	char			*guid = NULL;
13210 	int			target = ptgt->m_devhdl;
13211 	mdi_pathinfo_t		*pip = NULL;
13212 	mptsas_t		*mpt = DIP2MPT(pdip);
13213 
13214 	/*
13215 	 * For DVD/CD ROM and tape devices and optical
13216 	 * devices, we won't try to enumerate them under
13217 	 * scsi_vhci, so no need to try page83
13218 	 */
13219 	if (sd_inq && (sd_inq->inq_dtype == DTYPE_RODIRECT ||
13220 	    sd_inq->inq_dtype == DTYPE_OPTICAL))
13221 		goto create_lun;
13222 
13223 	/*
13224 	 * The LCA returns good SCSI status, but corrupt page 83 data the first
13225 	 * time it is queried. The solution is to keep trying to request page83
13226 	 * and verify the GUID is not (DDI_NOT_WELL_FORMED) in
13227 	 * mptsas_inq83_retry_timeout seconds. If the timeout expires, driver
13228 	 * give up to get VPD page at this stage and fail the enumeration.
13229 	 */
13230 
13231 	inq83	= kmem_zalloc(inq83_len1, KM_SLEEP);
13232 
13233 	for (i = 0; i < mptsas_inq83_retry_timeout; i++) {
13234 		rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83,
13235 		    inq83_len1, &inq83_len, 1);
13236 		if (rval != 0) {
13237 			mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
13238 			    "0x83 for target:%x, lun:%x failed!", target, lun);
13239 			goto out;
13240 		}
13241 		/*
13242 		 * create DEVID from inquiry data
13243 		 */
13244 		if ((rval = ddi_devid_scsi_encode(
13245 		    DEVID_SCSI_ENCODE_VERSION_LATEST, NULL, (uchar_t *)sd_inq,
13246 		    sizeof (struct scsi_inquiry), NULL, 0, inq83,
13247 		    (size_t)inq83_len, &devid)) == DDI_SUCCESS) {
13248 			/*
13249 			 * extract GUID from DEVID
13250 			 */
13251 			guid = ddi_devid_to_guid(devid);
13252 
13253 			/*
13254 			 * Do not enable MPXIO if the strlen(guid) is greater
13255 			 * than MPTSAS_MAX_GUID_LEN, this constrain would be
13256 			 * handled by framework later.
13257 			 */
13258 			if (guid && (strlen(guid) > MPTSAS_MAX_GUID_LEN)) {
13259 				ddi_devid_free_guid(guid);
13260 				guid = NULL;
13261 				if (mpt->m_mpxio_enable == TRUE) {
13262 					mptsas_log(mpt, CE_NOTE, "!Target:%x, "
13263 					    "lun:%x doesn't have a valid GUID, "
13264 					    "multipathing for this drive is "
13265 					    "not enabled", target, lun);
13266 				}
13267 			}
13268 
13269 			/*
13270 			 * devid no longer needed
13271 			 */
13272 			ddi_devid_free(devid);
13273 			break;
13274 		} else if (rval == DDI_NOT_WELL_FORMED) {
13275 			/*
13276 			 * return value of ddi_devid_scsi_encode equal to
13277 			 * DDI_NOT_WELL_FORMED means DEVID_RETRY, it worth
13278 			 * to retry inquiry page 0x83 and get GUID.
13279 			 */
13280 			NDBG20(("Not well formed devid, retry..."));
13281 			delay(1 * drv_usectohz(1000000));
13282 			continue;
13283 		} else {
13284 			mptsas_log(mpt, CE_WARN, "!Encode devid failed for "
13285 			    "path target:%x, lun:%x", target, lun);
13286 			rval = DDI_FAILURE;
13287 			goto create_lun;
13288 		}
13289 	}
13290 
13291 	if (i == mptsas_inq83_retry_timeout) {
13292 		mptsas_log(mpt, CE_WARN, "!Repeated page83 requests timeout "
13293 		    "for path target:%x, lun:%x", target, lun);
13294 	}
13295 
13296 	rval = DDI_FAILURE;
13297 
13298 create_lun:
13299 	if ((guid != NULL) && (mpt->m_mpxio_enable == TRUE)) {
13300 		rval = mptsas_create_virt_lun(pdip, sd_inq, guid, lun_dip, &pip,
13301 		    ptgt, lun);
13302 	}
13303 	if (rval != DDI_SUCCESS) {
13304 		rval = mptsas_create_phys_lun(pdip, sd_inq, guid, lun_dip,
13305 		    ptgt, lun);
13306 	}
13307 out:
13308 	if (guid != NULL) {
13309 		/*
13310 		 * guid no longer needed
13311 		 */
13312 		ddi_devid_free_guid(guid);
13313 	}
13314 	if (inq83 != NULL)
13315 		kmem_free(inq83, inq83_len1);
13316 	return (rval);
13317 }
13318 
13319 static int
13320 mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *inq, char *guid,
13321     dev_info_t **lun_dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, int lun)
13322 {
13323 	int			target;
13324 	char			*nodename = NULL;
13325 	char			**compatible = NULL;
13326 	int			ncompatible	= 0;
13327 	int			mdi_rtn = MDI_FAILURE;
13328 	int			rval = DDI_FAILURE;
13329 	char			*old_guid = NULL;
13330 	mptsas_t		*mpt = DIP2MPT(pdip);
13331 	char			*lun_addr = NULL;
13332 	char			*wwn_str = NULL;
13333 	char			*component = NULL;
13334 	uint8_t			phy = 0xFF;
13335 	uint64_t		sas_wwn;
13336 	uint32_t		devinfo;
13337 
13338 	mutex_enter(&mpt->m_mutex);
13339 	target = ptgt->m_devhdl;
13340 	sas_wwn = ptgt->m_sas_wwn;
13341 	devinfo = ptgt->m_deviceinfo;
13342 	phy = ptgt->m_phynum;
13343 	mutex_exit(&mpt->m_mutex);
13344 
13345 	if (sas_wwn) {
13346 		*pip = mptsas_find_path_addr(pdip, sas_wwn, lun);
13347 	} else {
13348 		*pip = mptsas_find_path_phy(pdip, phy);
13349 	}
13350 
13351 	if (*pip != NULL) {
13352 		*lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
13353 		ASSERT(*lun_dip != NULL);
13354 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip,
13355 		    (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM),
13356 		    MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) {
13357 			if (strncmp(guid, old_guid, strlen(guid)) == 0) {
13358 				/*
13359 				 * Same path back online again.
13360 				 */
13361 				(void) ddi_prop_free(old_guid);
13362 				if (!MDI_PI_IS_ONLINE(*pip) &&
13363 				    !MDI_PI_IS_STANDBY(*pip)) {
13364 					rval = mdi_pi_online(*pip, 0);
13365 				} else {
13366 					rval = DDI_SUCCESS;
13367 				}
13368 				if (rval != DDI_SUCCESS) {
13369 					mptsas_log(mpt, CE_WARN, "path:target: "
13370 					    "%x, lun:%x online failed!", target,
13371 					    lun);
13372 					*pip = NULL;
13373 					*lun_dip = NULL;
13374 				}
13375 				return (rval);
13376 			} else {
13377 				/*
13378 				 * The GUID of the LUN has changed which maybe
13379 				 * because customer mapped another volume to the
13380 				 * same LUN.
13381 				 */
13382 				mptsas_log(mpt, CE_WARN, "The GUID of the "
13383 				    "target:%x, lun:%x was changed, maybe "
13384 				    "because someone mapped another volume "
13385 				    "to the same LUN", target, lun);
13386 				(void) ddi_prop_free(old_guid);
13387 				if (!MDI_PI_IS_OFFLINE(*pip)) {
13388 					rval = mdi_pi_offline(*pip, 0);
13389 					if (rval != MDI_SUCCESS) {
13390 						mptsas_log(mpt, CE_WARN, "path:"
13391 						    "target:%x, lun:%x offline "
13392 						    "failed!", target, lun);
13393 						*pip = NULL;
13394 						*lun_dip = NULL;
13395 						return (DDI_FAILURE);
13396 					}
13397 				}
13398 				if (mdi_pi_free(*pip, 0) != MDI_SUCCESS) {
13399 					mptsas_log(mpt, CE_WARN, "path:target:"
13400 					    "%x, lun:%x free failed!", target,
13401 					    lun);
13402 					*pip = NULL;
13403 					*lun_dip = NULL;
13404 					return (DDI_FAILURE);
13405 				}
13406 			}
13407 		} else {
13408 			mptsas_log(mpt, CE_WARN, "Can't get client-guid "
13409 			    "property for path:target:%x, lun:%x", target, lun);
13410 			*pip = NULL;
13411 			*lun_dip = NULL;
13412 			return (DDI_FAILURE);
13413 		}
13414 	}
13415 	scsi_hba_nodename_compatible_get(inq, NULL,
13416 	    inq->inq_dtype, NULL, &nodename, &compatible, &ncompatible);
13417 
13418 	/*
13419 	 * if nodename can't be determined then print a message and skip it
13420 	 */
13421 	if (nodename == NULL) {
13422 		mptsas_log(mpt, CE_WARN, "mptsas driver found no compatible "
13423 		    "driver for target%d lun %d dtype:0x%02x", target, lun,
13424 		    inq->inq_dtype);
13425 		return (DDI_FAILURE);
13426 	}
13427 
13428 	wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP);
13429 	/* The property is needed by MPAPI */
13430 	(void) sprintf(wwn_str, "%016"PRIx64, sas_wwn);
13431 
13432 	lun_addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13433 	if (sas_wwn)
13434 		(void) sprintf(lun_addr, "w%s,%x", wwn_str, lun);
13435 	else
13436 		(void) sprintf(lun_addr, "p%x,%x", phy, lun);
13437 
13438 	mdi_rtn = mdi_pi_alloc_compatible(pdip, nodename,
13439 	    guid, lun_addr, compatible, ncompatible,
13440 	    0, pip);
13441 	if (mdi_rtn == MDI_SUCCESS) {
13442 
13443 		if (mdi_prop_update_string(*pip, MDI_GUID,
13444 		    guid) != DDI_SUCCESS) {
13445 			mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
13446 			    "create property for target %d lun %d (MDI_GUID)",
13447 			    target, lun);
13448 			mdi_rtn = MDI_FAILURE;
13449 			goto virt_create_done;
13450 		}
13451 
13452 		if (mdi_prop_update_int(*pip, LUN_PROP,
13453 		    lun) != DDI_SUCCESS) {
13454 			mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
13455 			    "create property for target %d lun %d (LUN_PROP)",
13456 			    target, lun);
13457 			mdi_rtn = MDI_FAILURE;
13458 			goto virt_create_done;
13459 		}
13460 		if (mdi_prop_update_string_array(*pip, "compatible",
13461 		    compatible, ncompatible) !=
13462 		    DDI_PROP_SUCCESS) {
13463 			mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
13464 			    "create property for target %d lun %d (COMPATIBLE)",
13465 			    target, lun);
13466 			mdi_rtn = MDI_FAILURE;
13467 			goto virt_create_done;
13468 		}
13469 		if (sas_wwn && (mdi_prop_update_string(*pip,
13470 		    SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != DDI_PROP_SUCCESS)) {
13471 			mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
13472 			    "create property for target %d lun %d "
13473 			    "(target-port)", target, lun);
13474 			mdi_rtn = MDI_FAILURE;
13475 			goto virt_create_done;
13476 		} else if ((sas_wwn == 0) && (mdi_prop_update_int(*pip,
13477 		    "sata-phy", phy) != DDI_PROP_SUCCESS)) {
13478 			/*
13479 			 * Direct attached SATA device without DeviceName
13480 			 */
13481 			mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
13482 			    "create property for SAS target %d lun %d "
13483 			    "(sata-phy)", target, lun);
13484 			mdi_rtn = NDI_FAILURE;
13485 			goto virt_create_done;
13486 		}
13487 
13488 		if (inq->inq_dtype == 0) {
13489 			component = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
13490 			/*
13491 			 * set obp path for pathinfo
13492 			 */
13493 			(void) snprintf(component, MAXPATHLEN,
13494 			    "disk@%s", lun_addr);
13495 
13496 			if (mdi_pi_pathname_obp_set(*pip, component) !=
13497 			    DDI_SUCCESS) {
13498 				mptsas_log(mpt, CE_WARN, "mpt_sas driver "
13499 				    "unable to set obp-path for object %s",
13500 				    component);
13501 				mdi_rtn = MDI_FAILURE;
13502 				goto virt_create_done;
13503 			}
13504 		}
13505 
13506 		*lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
13507 		if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
13508 		    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
13509 			if ((ndi_prop_update_int(DDI_DEV_T_NONE, *lun_dip,
13510 			    "pm-capable", 1)) !=
13511 			    DDI_PROP_SUCCESS) {
13512 				mptsas_log(mpt, CE_WARN, "mptsas driver"
13513 				    "failed to create pm-capable "
13514 				    "property, target %d", target);
13515 				mdi_rtn = MDI_FAILURE;
13516 				goto virt_create_done;
13517 			}
13518 		}
13519 		NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr));
13520 		mdi_rtn = mdi_pi_online(*pip, 0);
13521 		if (mdi_rtn == MDI_NOT_SUPPORTED) {
13522 			mdi_rtn = MDI_FAILURE;
13523 		}
13524 virt_create_done:
13525 		if (*pip && mdi_rtn != MDI_SUCCESS) {
13526 			(void) mdi_pi_free(*pip, 0);
13527 			*pip = NULL;
13528 			*lun_dip = NULL;
13529 		}
13530 	}
13531 
13532 	scsi_hba_nodename_compatible_free(nodename, compatible);
13533 	if (lun_addr != NULL) {
13534 		kmem_free(lun_addr, SCSI_MAXNAMELEN);
13535 	}
13536 	if (wwn_str != NULL) {
13537 		kmem_free(wwn_str, MPTSAS_WWN_STRLEN);
13538 	}
13539 	if (component != NULL) {
13540 		kmem_free(component, MAXPATHLEN);
13541 	}
13542 
13543 	return ((mdi_rtn == MDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
13544 }
13545 
13546 static int
13547 mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *inq,
13548     char *guid, dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun)
13549 {
13550 	int			target;
13551 	int			ndi_rtn = NDI_FAILURE;
13552 	uint64_t		be_sas_wwn;
13553 	char			*nodename = NULL;
13554 	char			**compatible = NULL;
13555 	int			ncompatible = 0;
13556 	int			instance = 0;
13557 	mptsas_t		*mpt = DIP2MPT(pdip);
13558 	char			*wwn_str = NULL;
13559 	char			*component = NULL;
13560 	uint8_t			phy = 0xFF;
13561 	uint64_t		sas_wwn;
13562 	uint32_t		devinfo;
13563 
13564 	mutex_enter(&mpt->m_mutex);
13565 	target = ptgt->m_devhdl;
13566 	sas_wwn = ptgt->m_sas_wwn;
13567 	devinfo = ptgt->m_deviceinfo;
13568 	phy = ptgt->m_phynum;
13569 	mutex_exit(&mpt->m_mutex);
13570 
13571 	/*
13572 	 * generate compatible property with binding-set "mpt"
13573 	 */
13574 	scsi_hba_nodename_compatible_get(inq, NULL, inq->inq_dtype, NULL,
13575 	    &nodename, &compatible, &ncompatible);
13576 
13577 	/*
13578 	 * if nodename can't be determined then print a message and skip it
13579 	 */
13580 	if (nodename == NULL) {
13581 		mptsas_log(mpt, CE_WARN, "mptsas found no compatible driver "
13582 		    "for target %d lun %d", target, lun);
13583 		return (DDI_FAILURE);
13584 	}
13585 
13586 	ndi_rtn = ndi_devi_alloc(pdip, nodename,
13587 	    DEVI_SID_NODEID, lun_dip);
13588 
13589 	/*
13590 	 * if lun alloc success, set props
13591 	 */
13592 	if (ndi_rtn == NDI_SUCCESS) {
13593 
13594 		if (ndi_prop_update_int(DDI_DEV_T_NONE,
13595 		    *lun_dip, LUN_PROP, lun) !=
13596 		    DDI_PROP_SUCCESS) {
13597 			mptsas_log(mpt, CE_WARN, "mptsas unable to create "
13598 			    "property for target %d lun %d (LUN_PROP)",
13599 			    target, lun);
13600 			ndi_rtn = NDI_FAILURE;
13601 			goto phys_create_done;
13602 		}
13603 
13604 		if (ndi_prop_update_string_array(DDI_DEV_T_NONE,
13605 		    *lun_dip, "compatible", compatible, ncompatible)
13606 		    != DDI_PROP_SUCCESS) {
13607 			mptsas_log(mpt, CE_WARN, "mptsas unable to create "
13608 			    "property for target %d lun %d (COMPATIBLE)",
13609 			    target, lun);
13610 			ndi_rtn = NDI_FAILURE;
13611 			goto phys_create_done;
13612 		}
13613 
13614 		/*
13615 		 * We need the SAS WWN for non-multipath devices, so
13616 		 * we'll use the same property as that multipathing
13617 		 * devices need to present for MPAPI. If we don't have
13618 		 * a WWN (e.g. parallel SCSI), don't create the prop.
13619 		 */
13620 		wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP);
13621 		(void) sprintf(wwn_str, "%016"PRIx64, sas_wwn);
13622 		if (sas_wwn && ndi_prop_update_string(DDI_DEV_T_NONE,
13623 		    *lun_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str)
13624 		    != DDI_PROP_SUCCESS) {
13625 			mptsas_log(mpt, CE_WARN, "mptsas unable to "
13626 			    "create property for SAS target %d lun %d "
13627 			    "(target-port)", target, lun);
13628 			ndi_rtn = NDI_FAILURE;
13629 			goto phys_create_done;
13630 		}
13631 		be_sas_wwn = BE_64(sas_wwn);
13632 		if (sas_wwn && ndi_prop_update_byte_array(
13633 		    DDI_DEV_T_NONE, *lun_dip, "port-wwn",
13634 		    (uchar_t *)&be_sas_wwn, 8) != DDI_PROP_SUCCESS) {
13635 			mptsas_log(mpt, CE_WARN, "mptsas unable to "
13636 			    "create property for SAS target %d lun %d "
13637 			    "(port-wwn)", target, lun);
13638 			ndi_rtn = NDI_FAILURE;
13639 			goto phys_create_done;
13640 		} else if ((sas_wwn == 0) && (ndi_prop_update_int(
13641 		    DDI_DEV_T_NONE, *lun_dip, "sata-phy", phy) !=
13642 		    DDI_PROP_SUCCESS)) {
13643 			/*
13644 			 * Direct attached SATA device without DeviceName
13645 			 */
13646 			mptsas_log(mpt, CE_WARN, "mptsas unable to "
13647 			    "create property for SAS target %d lun %d "
13648 			    "(sata-phy)", target, lun);
13649 			ndi_rtn = NDI_FAILURE;
13650 			goto phys_create_done;
13651 		}
13652 		if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
13653 		    *lun_dip, SAS_PROP) != DDI_PROP_SUCCESS) {
13654 			mptsas_log(mpt, CE_WARN, "mptsas unable to"
13655 			    "create property for SAS target %d lun %d"
13656 			    " (SAS_PROP)", target, lun);
13657 			ndi_rtn = NDI_FAILURE;
13658 			goto phys_create_done;
13659 		}
13660 		if (guid && (ndi_prop_update_string(DDI_DEV_T_NONE,
13661 		    *lun_dip, NDI_GUID, guid) != DDI_SUCCESS)) {
13662 			mptsas_log(mpt, CE_WARN, "mptsas unable "
13663 			    "to create guid property for target %d "
13664 			    "lun %d", target, lun);
13665 			ndi_rtn = NDI_FAILURE;
13666 			goto phys_create_done;
13667 		}
13668 
13669 		/*
13670 		 * if this is a SAS controller, and the target is a SATA
13671 		 * drive, set the 'pm-capable' property for sd and if on
13672 		 * an OPL platform, also check if this is an ATAPI
13673 		 * device.
13674 		 */
13675 		instance = ddi_get_instance(mpt->m_dip);
13676 		if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
13677 		    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
13678 			NDBG2(("mptsas%d: creating pm-capable property, "
13679 			    "target %d", instance, target));
13680 
13681 			if ((ndi_prop_update_int(DDI_DEV_T_NONE,
13682 			    *lun_dip, "pm-capable", 1)) !=
13683 			    DDI_PROP_SUCCESS) {
13684 				mptsas_log(mpt, CE_WARN, "mptsas "
13685 				    "failed to create pm-capable "
13686 				    "property, target %d", target);
13687 				ndi_rtn = NDI_FAILURE;
13688 				goto phys_create_done;
13689 			}
13690 
13691 		}
13692 
13693 		if (inq->inq_dtype == 0) {
13694 			/*
13695 			 * add 'obp-path' properties for devinfo
13696 			 */
13697 			component = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
13698 			if (sas_wwn) {
13699 				(void) snprintf(component, MAXPATHLEN,
13700 				    "disk@w%s,%x", wwn_str, lun);
13701 			} else {
13702 				(void) snprintf(component, MAXPATHLEN,
13703 				    "disk@p%x,%x", phy, lun);
13704 			}
13705 			if (ddi_pathname_obp_set(*lun_dip, component)
13706 			    != DDI_SUCCESS) {
13707 				mptsas_log(mpt, CE_WARN, "mpt_sas driver "
13708 				    "unable to set obp-path for SAS "
13709 				    "object %s", component);
13710 				ndi_rtn = NDI_FAILURE;
13711 				goto phys_create_done;
13712 			}
13713 		}
13714 
13715 phys_create_done:
13716 		/*
13717 		 * If props were setup ok, online the lun
13718 		 */
13719 		if (ndi_rtn == NDI_SUCCESS) {
13720 			/*
13721 			 * Try to online the new node
13722 			 */
13723 			ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH);
13724 		}
13725 
13726 		/*
13727 		 * If success set rtn flag, else unwire alloc'd lun
13728 		 */
13729 		if (ndi_rtn != NDI_SUCCESS) {
13730 			NDBG12(("mptsas driver unable to online "
13731 			    "target %d lun %d", target, lun));
13732 			ndi_prop_remove_all(*lun_dip);
13733 			(void) ndi_devi_free(*lun_dip);
13734 			*lun_dip = NULL;
13735 		}
13736 	}
13737 
13738 	scsi_hba_nodename_compatible_free(nodename, compatible);
13739 
13740 	if (wwn_str != NULL) {
13741 		kmem_free(wwn_str, MPTSAS_WWN_STRLEN);
13742 	}
13743 	if (component != NULL) {
13744 		kmem_free(component, MAXPATHLEN);
13745 	}
13746 
13747 	return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
13748 }
13749 
13750 static int
13751 mptsas_probe_smp(dev_info_t *pdip, uint64_t wwn)
13752 {
13753 	mptsas_t	*mpt = DIP2MPT(pdip);
13754 	struct smp_device smp_sd;
13755 
13756 	/* XXX An HBA driver should not be allocating an smp_device. */
13757 	bzero(&smp_sd, sizeof (struct smp_device));
13758 	smp_sd.smp_sd_address.smp_a_hba_tran = mpt->m_smptran;
13759 	bcopy(&wwn, smp_sd.smp_sd_address.smp_a_wwn, SAS_WWN_BYTE_SIZE);
13760 
13761 	if (smp_probe(&smp_sd) != DDI_PROBE_SUCCESS)
13762 		return (NDI_FAILURE);
13763 	return (NDI_SUCCESS);
13764 }
13765 
13766 static int
13767 mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, dev_info_t **smp_dip)
13768 {
13769 	mptsas_t	*mpt = DIP2MPT(pdip);
13770 	mptsas_smp_t	*psmp = NULL;
13771 	int		rval;
13772 	int		phymask;
13773 
13774 	/*
13775 	 * Get the physical port associated to the iport
13776 	 * PHYMASK TODO
13777 	 */
13778 	phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
13779 	    "phymask", 0);
13780 	/*
13781 	 * Find the smp node in hash table with specified sas address and
13782 	 * physical port
13783 	 */
13784 	psmp = mptsas_wwid_to_psmp(mpt, phymask, sas_wwn);
13785 	if (psmp == NULL) {
13786 		return (DDI_FAILURE);
13787 	}
13788 
13789 	rval = mptsas_online_smp(pdip, psmp, smp_dip);
13790 
13791 	return (rval);
13792 }
13793 
13794 static int
13795 mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
13796     dev_info_t **smp_dip)
13797 {
13798 	char		wwn_str[MPTSAS_WWN_STRLEN];
13799 	int		ndi_rtn = NDI_FAILURE;
13800 	mptsas_t	*mpt = DIP2MPT(pdip);
13801 
13802 	(void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr);
13803 
13804 	/*
13805 	 * Probe smp device, prevent the node of removed device from being
13806 	 * configured succesfully
13807 	 */
13808 	if (mptsas_probe_smp(pdip, smp_node->m_sasaddr) != NDI_SUCCESS) {
13809 		return (DDI_FAILURE);
13810 	}
13811 
13812 	if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) {
13813 		return (DDI_SUCCESS);
13814 	}
13815 
13816 	ndi_rtn = ndi_devi_alloc(pdip, "smp", DEVI_SID_NODEID, smp_dip);
13817 
13818 	/*
13819 	 * if lun alloc success, set props
13820 	 */
13821 	if (ndi_rtn == NDI_SUCCESS) {
13822 		/*
13823 		 * Set the flavor of the child to be SMP flavored
13824 		 */
13825 		ndi_flavor_set(*smp_dip, SCSA_FLAVOR_SMP);
13826 
13827 		if (ndi_prop_update_string(DDI_DEV_T_NONE,
13828 		    *smp_dip, SMP_WWN, wwn_str) !=
13829 		    DDI_PROP_SUCCESS) {
13830 			mptsas_log(mpt, CE_WARN, "mptsas unable to create "
13831 			    "property for smp device %s (sas_wwn)",
13832 			    wwn_str);
13833 			ndi_rtn = NDI_FAILURE;
13834 			goto smp_create_done;
13835 		}
13836 
13837 		if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
13838 		    *smp_dip, SMP_PROP) != DDI_PROP_SUCCESS) {
13839 			mptsas_log(mpt, CE_WARN, "mptsas unable to "
13840 			    "create property for SMP %s (SMP_PROP) ",
13841 			    wwn_str);
13842 			ndi_rtn = NDI_FAILURE;
13843 			goto smp_create_done;
13844 		}
13845 
13846 smp_create_done:
13847 		/*
13848 		 * If props were setup ok, online the lun
13849 		 */
13850 		if (ndi_rtn == NDI_SUCCESS) {
13851 			/*
13852 			 * Try to online the new node
13853 			 */
13854 			ndi_rtn = ndi_devi_online(*smp_dip, NDI_ONLINE_ATTACH);
13855 		}
13856 
13857 		/*
13858 		 * If success set rtn flag, else unwire alloc'd lun
13859 		 */
13860 		if (ndi_rtn != NDI_SUCCESS) {
13861 			NDBG12(("mptsas unable to online "
13862 			    "SMP target %s", wwn_str));
13863 			ndi_prop_remove_all(*smp_dip);
13864 			(void) ndi_devi_free(*smp_dip);
13865 		}
13866 	}
13867 
13868 	return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
13869 }
13870 
13871 /* smp transport routine */
13872 static int mptsas_smp_start(struct smp_pkt *smp_pkt)
13873 {
13874 	uint64_t			wwn;
13875 	Mpi2SmpPassthroughRequest_t	req;
13876 	Mpi2SmpPassthroughReply_t	rep;
13877 	uint32_t			direction = 0;
13878 	mptsas_t			*mpt;
13879 	int				ret;
13880 	uint64_t			tmp64;
13881 
13882 	mpt = (mptsas_t *)smp_pkt->smp_pkt_address->
13883 	    smp_a_hba_tran->smp_tran_hba_private;
13884 
13885 	bcopy(smp_pkt->smp_pkt_address->smp_a_wwn, &wwn, SAS_WWN_BYTE_SIZE);
13886 	/*
13887 	 * Need to compose a SMP request message
13888 	 * and call mptsas_do_passthru() function
13889 	 */
13890 	bzero(&req, sizeof (req));
13891 	bzero(&rep, sizeof (rep));
13892 	req.PassthroughFlags = 0;
13893 	req.PhysicalPort = 0xff;
13894 	req.ChainOffset = 0;
13895 	req.Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
13896 
13897 	if ((smp_pkt->smp_pkt_reqsize & 0xffff0000ul) != 0) {
13898 		smp_pkt->smp_pkt_reason = ERANGE;
13899 		return (DDI_FAILURE);
13900 	}
13901 	req.RequestDataLength = LE_16((uint16_t)(smp_pkt->smp_pkt_reqsize - 4));
13902 
13903 	req.MsgFlags = 0;
13904 	tmp64 = LE_64(wwn);
13905 	bcopy(&tmp64, &req.SASAddress, SAS_WWN_BYTE_SIZE);
13906 	if (smp_pkt->smp_pkt_rspsize > 0) {
13907 		direction |= MPTSAS_PASS_THRU_DIRECTION_READ;
13908 	}
13909 	if (smp_pkt->smp_pkt_reqsize > 0) {
13910 		direction |= MPTSAS_PASS_THRU_DIRECTION_WRITE;
13911 	}
13912 
13913 	mutex_enter(&mpt->m_mutex);
13914 	ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep,
13915 	    (uint8_t *)smp_pkt->smp_pkt_rsp,
13916 	    offsetof(Mpi2SmpPassthroughRequest_t, SGL), sizeof (rep),
13917 	    smp_pkt->smp_pkt_rspsize - 4, direction,
13918 	    (uint8_t *)smp_pkt->smp_pkt_req, smp_pkt->smp_pkt_reqsize - 4,
13919 	    smp_pkt->smp_pkt_timeout, FKIOCTL);
13920 	mutex_exit(&mpt->m_mutex);
13921 	if (ret != 0) {
13922 		cmn_err(CE_WARN, "smp_start do passthru error %d", ret);
13923 		smp_pkt->smp_pkt_reason = (uchar_t)(ret);
13924 		return (DDI_FAILURE);
13925 	}
13926 	/* do passthrough success, check the smp status */
13927 	if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
13928 		switch (LE_16(rep.IOCStatus)) {
13929 		case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
13930 			smp_pkt->smp_pkt_reason = ENODEV;
13931 			break;
13932 		case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN:
13933 			smp_pkt->smp_pkt_reason = EOVERFLOW;
13934 			break;
13935 		case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED:
13936 			smp_pkt->smp_pkt_reason = EIO;
13937 			break;
13938 		default:
13939 			mptsas_log(mpt, CE_NOTE, "smp_start: get unknown ioc"
13940 			    "status:%x", LE_16(rep.IOCStatus));
13941 			smp_pkt->smp_pkt_reason = EIO;
13942 			break;
13943 		}
13944 		return (DDI_FAILURE);
13945 	}
13946 	if (rep.SASStatus != MPI2_SASSTATUS_SUCCESS) {
13947 		mptsas_log(mpt, CE_NOTE, "smp_start: get error SAS status:%x",
13948 		    rep.SASStatus);
13949 		smp_pkt->smp_pkt_reason = EIO;
13950 		return (DDI_FAILURE);
13951 	}
13952 
13953 	return (DDI_SUCCESS);
13954 }
13955 
13956 static void
13957 mptsas_idle_pm(void *arg)
13958 {
13959 	mptsas_t	*mpt = arg;
13960 
13961 	(void) pm_idle_component(mpt->m_dip, 0);
13962 	mutex_enter(&mpt->m_mutex);
13963 	mpt->m_pm_timeid = 0;
13964 	mutex_exit(&mpt->m_mutex);
13965 }
13966 
13967 /*
13968  * If we didn't get a match, we need to get sas page0 for each device, and
13969  * untill we get a match. If failed, return NULL
13970  * TODO should be implemented similar to mptsas_wwid_to_ptgt?
13971  */
13972 static mptsas_target_t *
13973 mptsas_phy_to_tgt(dev_info_t *pdip, uint8_t phy)
13974 {
13975 	int		i, j = 0;
13976 	int		rval = 0;
13977 	uint16_t	cur_handle;
13978 	uint32_t	page_address;
13979 	mptsas_target_t	*ptgt = NULL;
13980 	mptsas_t	*mpt = DIP2MPT(pdip);
13981 	int		phymask;
13982 
13983 	/*
13984 	 * Get the physical port associated to the iport
13985 	 */
13986 	phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
13987 	    "phymask", 0);
13988 
13989 	if (phymask == 0)
13990 		return (NULL);
13991 
13992 	/*
13993 	 * PHY named device must be direct attached and attaches to
13994 	 * narrow port, if the iport is not parent of the device which
13995 	 * we are looking for.
13996 	 */
13997 	for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
13998 		if ((1 << i) & phymask)
13999 			j++;
14000 	}
14001 
14002 	if (j > 1)
14003 		return (NULL);
14004 
14005 	/*
14006 	 * Must be a narrow port and single device attached to the narrow port
14007 	 * So the physical port num of device  which is equal to the iport's
14008 	 * port num is the device what we are looking for.
14009 	 */
14010 
14011 	if (mpt->m_phy_info[phy].phy_mask != phymask)
14012 		return (NULL);
14013 
14014 	mutex_enter(&mpt->m_mutex);
14015 
14016 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
14017 	    MPTSAS_HASH_FIRST);
14018 	while (ptgt != NULL) {
14019 			if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) {
14020 			mutex_exit(&mpt->m_mutex);
14021 			return (ptgt);
14022 		}
14023 
14024 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
14025 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
14026 	}
14027 
14028 	if (mpt->m_done_traverse_dev) {
14029 		mutex_exit(&mpt->m_mutex);
14030 		return (NULL);
14031 	}
14032 
14033 	/* If didn't get a match, come here */
14034 	cur_handle = mpt->m_dev_handle;
14035 	for (; ; ) {
14036 		ptgt = NULL;
14037 		page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
14038 		    MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)cur_handle;
14039 		rval = mptsas_get_target_device_info(mpt, page_address,
14040 		    &cur_handle, &ptgt);
14041 		if ((rval == DEV_INFO_FAIL_PAGE0) ||
14042 		    (rval == DEV_INFO_FAIL_ALLOC)) {
14043 			break;
14044 		}
14045 		if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
14046 		    (rval == DEV_INFO_PHYS_DISK)) {
14047 			continue;
14048 		}
14049 		mpt->m_dev_handle = cur_handle;
14050 
14051 		if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) {
14052 			break;
14053 		}
14054 	}
14055 
14056 	mutex_exit(&mpt->m_mutex);
14057 	return (ptgt);
14058 }
14059 
14060 /*
14061  * The ptgt->m_sas_wwn contains the wwid for each disk.
14062  * For Raid volumes, we need to check m_raidvol[x].m_raidwwid
14063  * If we didn't get a match, we need to get sas page0 for each device, and
14064  * untill we get a match
14065  * If failed, return NULL
14066  */
14067 static mptsas_target_t *
14068 mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask, uint64_t wwid)
14069 {
14070 	int		rval = 0;
14071 	uint16_t	cur_handle;
14072 	uint32_t	page_address;
14073 	mptsas_target_t	*tmp_tgt = NULL;
14074 
14075 	mutex_enter(&mpt->m_mutex);
14076 	tmp_tgt = (struct mptsas_target *)mptsas_hash_search(
14077 	    &mpt->m_active->m_tgttbl, wwid, phymask);
14078 	if (tmp_tgt != NULL) {
14079 		mutex_exit(&mpt->m_mutex);
14080 		return (tmp_tgt);
14081 	}
14082 
14083 	if (phymask == 0) {
14084 		/*
14085 		 * It's IR volume
14086 		 */
14087 		rval = mptsas_get_raid_info(mpt);
14088 		if (rval) {
14089 			tmp_tgt = (struct mptsas_target *)mptsas_hash_search(
14090 			    &mpt->m_active->m_tgttbl, wwid, phymask);
14091 		}
14092 		mutex_exit(&mpt->m_mutex);
14093 		return (tmp_tgt);
14094 	}
14095 
14096 	if (mpt->m_done_traverse_dev) {
14097 		mutex_exit(&mpt->m_mutex);
14098 		return (NULL);
14099 	}
14100 
14101 	/* If didn't get a match, come here */
14102 	cur_handle = mpt->m_dev_handle;
14103 	for (; ; ) {
14104 		tmp_tgt = NULL;
14105 		page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
14106 		    MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle;
14107 		rval = mptsas_get_target_device_info(mpt, page_address,
14108 		    &cur_handle, &tmp_tgt);
14109 		if ((rval == DEV_INFO_FAIL_PAGE0) ||
14110 		    (rval == DEV_INFO_FAIL_ALLOC)) {
14111 			tmp_tgt = NULL;
14112 			break;
14113 		}
14114 		if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
14115 		    (rval == DEV_INFO_PHYS_DISK)) {
14116 			continue;
14117 		}
14118 		mpt->m_dev_handle = cur_handle;
14119 		if ((tmp_tgt->m_sas_wwn) && (tmp_tgt->m_sas_wwn == wwid) &&
14120 		    (tmp_tgt->m_phymask == phymask)) {
14121 			break;
14122 		}
14123 	}
14124 
14125 	mutex_exit(&mpt->m_mutex);
14126 	return (tmp_tgt);
14127 }
14128 
14129 static mptsas_smp_t *
14130 mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask, uint64_t wwid)
14131 {
14132 	int		rval = 0;
14133 	uint16_t	cur_handle;
14134 	uint32_t	page_address;
14135 	mptsas_smp_t	smp_node, *psmp = NULL;
14136 
14137 	mutex_enter(&mpt->m_mutex);
14138 	psmp = (struct mptsas_smp *)mptsas_hash_search(&mpt->m_active->m_smptbl,
14139 	    wwid, phymask);
14140 	if (psmp != NULL) {
14141 		mutex_exit(&mpt->m_mutex);
14142 		return (psmp);
14143 	}
14144 
14145 	if (mpt->m_done_traverse_smp) {
14146 		mutex_exit(&mpt->m_mutex);
14147 		return (NULL);
14148 	}
14149 
14150 	/* If didn't get a match, come here */
14151 	cur_handle = mpt->m_smp_devhdl;
14152 	for (; ; ) {
14153 		psmp = NULL;
14154 		page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
14155 		    MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle;
14156 		rval = mptsas_get_sas_expander_page0(mpt, page_address,
14157 		    &smp_node);
14158 		if (rval != DDI_SUCCESS) {
14159 			break;
14160 		}
14161 		mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl;
14162 		psmp = mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node);
14163 		ASSERT(psmp);
14164 		if ((psmp->m_sasaddr) && (psmp->m_sasaddr == wwid) &&
14165 		    (psmp->m_phymask == phymask)) {
14166 			break;
14167 		}
14168 	}
14169 
14170 	mutex_exit(&mpt->m_mutex);
14171 	return (psmp);
14172 }
14173 
14174 /* helper functions using hash */
14175 
14176 /*
14177  * Can't have duplicate entries for same devhdl,
14178  * if there are invalid entries, the devhdl should be set to 0xffff
14179  */
14180 static void *
14181 mptsas_search_by_devhdl(mptsas_hash_table_t *hashtab, uint16_t devhdl)
14182 {
14183 	mptsas_hash_data_t *data;
14184 
14185 	data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST);
14186 	while (data != NULL) {
14187 		if (data->devhdl == devhdl) {
14188 			break;
14189 		}
14190 		data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT);
14191 	}
14192 	return (data);
14193 }
14194 
14195 mptsas_target_t *
14196 mptsas_tgt_alloc(mptsas_hash_table_t *hashtab, uint16_t devhdl, uint64_t wwid,
14197     uint32_t devinfo, uint8_t phymask, uint8_t phynum)
14198 {
14199 	mptsas_target_t *tmp_tgt = NULL;
14200 
14201 	tmp_tgt = mptsas_hash_search(hashtab, wwid, phymask);
14202 	if (tmp_tgt != NULL) {
14203 		NDBG20(("Hash item already exist"));
14204 		tmp_tgt->m_deviceinfo = devinfo;
14205 		tmp_tgt->m_devhdl = devhdl;
14206 		return (tmp_tgt);
14207 	}
14208 	tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP);
14209 	if (tmp_tgt == NULL) {
14210 		cmn_err(CE_WARN, "Fatal, allocated tgt failed");
14211 		return (NULL);
14212 	}
14213 	tmp_tgt->m_devhdl = devhdl;
14214 	tmp_tgt->m_sas_wwn = wwid;
14215 	tmp_tgt->m_deviceinfo = devinfo;
14216 	tmp_tgt->m_phymask = phymask;
14217 	tmp_tgt->m_phynum = phynum;
14218 	/* Initialized the tgt structure */
14219 	tmp_tgt->m_qfull_retries = QFULL_RETRIES;
14220 	tmp_tgt->m_qfull_retry_interval =
14221 	    drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
14222 	tmp_tgt->m_t_throttle = MAX_THROTTLE;
14223 
14224 	mptsas_hash_add(hashtab, tmp_tgt);
14225 
14226 	return (tmp_tgt);
14227 }
14228 
14229 static void
14230 mptsas_tgt_free(mptsas_hash_table_t *hashtab, uint64_t wwid, uint8_t phymask)
14231 {
14232 	mptsas_target_t *tmp_tgt;
14233 	tmp_tgt = mptsas_hash_rem(hashtab, wwid, phymask);
14234 	if (tmp_tgt == NULL) {
14235 		cmn_err(CE_WARN, "Tgt not found, nothing to free");
14236 	} else {
14237 		kmem_free(tmp_tgt, sizeof (struct mptsas_target));
14238 	}
14239 }
14240 
14241 /*
14242  * Return the entry in the hash table
14243  */
14244 static mptsas_smp_t *
14245 mptsas_smp_alloc(mptsas_hash_table_t *hashtab, mptsas_smp_t *data)
14246 {
14247 	uint64_t key1 = data->m_sasaddr;
14248 	uint8_t key2 = data->m_phymask;
14249 	mptsas_smp_t *ret_data;
14250 
14251 	ret_data = mptsas_hash_search(hashtab, key1, key2);
14252 	if (ret_data != NULL) {
14253 		bcopy(data, ret_data, sizeof (mptsas_smp_t));
14254 		return (ret_data);
14255 	}
14256 
14257 	ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP);
14258 	bcopy(data, ret_data, sizeof (mptsas_smp_t));
14259 	mptsas_hash_add(hashtab, ret_data);
14260 	return (ret_data);
14261 }
14262 
14263 static void
14264 mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid, uint8_t phymask)
14265 {
14266 	mptsas_smp_t *tmp_smp;
14267 	tmp_smp = mptsas_hash_rem(hashtab, wwid, phymask);
14268 	if (tmp_smp == NULL) {
14269 		cmn_err(CE_WARN, "Smp element not found, nothing to free");
14270 	} else {
14271 		kmem_free(tmp_smp, sizeof (struct mptsas_smp));
14272 	}
14273 }
14274 
14275 /*
14276  * Hash operation functions
14277  * key1 is the sas_wwn, key2 is the phymask
14278  */
14279 static void
14280 mptsas_hash_init(mptsas_hash_table_t *hashtab)
14281 {
14282 	if (hashtab == NULL) {
14283 		return;
14284 	}
14285 	bzero(hashtab->head, sizeof (mptsas_hash_node_t) *
14286 	    MPTSAS_HASH_ARRAY_SIZE);
14287 	hashtab->cur = NULL;
14288 	hashtab->line = 0;
14289 }
14290 
14291 static void
14292 mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen)
14293 {
14294 	uint16_t line = 0;
14295 	mptsas_hash_node_t *cur = NULL, *last = NULL;
14296 
14297 	if (hashtab == NULL) {
14298 		return;
14299 	}
14300 	for (line = 0; line < MPTSAS_HASH_ARRAY_SIZE; line++) {
14301 		cur = hashtab->head[line];
14302 		while (cur != NULL) {
14303 			last = cur;
14304 			cur = cur->next;
14305 			kmem_free(last->data, datalen);
14306 			kmem_free(last, sizeof (mptsas_hash_node_t));
14307 		}
14308 	}
14309 }
14310 
14311 /*
14312  * You must guarantee the element doesn't exist in the hash table
14313  * before you call mptsas_hash_add()
14314  */
14315 static void
14316 mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data)
14317 {
14318 	uint64_t key1 = ((mptsas_hash_data_t *)data)->key1;
14319 	uint8_t	key2 = ((mptsas_hash_data_t *)data)->key2;
14320 	mptsas_hash_node_t **head = NULL;
14321 	mptsas_hash_node_t *node = NULL;
14322 
14323 	if (hashtab == NULL) {
14324 		return;
14325 	}
14326 	ASSERT(mptsas_hash_search(hashtab, key1, key2) == NULL);
14327 	node = kmem_zalloc(sizeof (mptsas_hash_node_t), KM_NOSLEEP);
14328 	node->data = data;
14329 
14330 	head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]);
14331 	if (*head == NULL) {
14332 		*head = node;
14333 	} else {
14334 		node->next = *head;
14335 		*head = node;
14336 	}
14337 }
14338 
14339 static void *
14340 mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1, uint8_t key2)
14341 {
14342 	mptsas_hash_node_t **head = NULL;
14343 	mptsas_hash_node_t *last = NULL, *cur = NULL;
14344 	mptsas_hash_data_t *data;
14345 	if (hashtab == NULL) {
14346 		return (NULL);
14347 	}
14348 	head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]);
14349 	cur = *head;
14350 	while (cur != NULL) {
14351 		data = cur->data;
14352 		if ((data->key1 == key1) && (data->key2 == key2)) {
14353 			if (last == NULL) {
14354 				(*head) = cur->next;
14355 			} else {
14356 				last->next = cur->next;
14357 			}
14358 			kmem_free(cur, sizeof (mptsas_hash_node_t));
14359 			return (data);
14360 		} else {
14361 			last = cur;
14362 			cur = cur->next;
14363 		}
14364 	}
14365 	return (NULL);
14366 }
14367 
14368 static void *
14369 mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1, uint8_t key2)
14370 {
14371 	mptsas_hash_node_t *cur = NULL;
14372 	mptsas_hash_data_t *data;
14373 	if (hashtab == NULL) {
14374 		return (NULL);
14375 	}
14376 	cur = hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE];
14377 	while (cur != NULL) {
14378 		data = cur->data;
14379 		if ((data->key1 == key1) && (data->key2 == key2)) {
14380 			return (data);
14381 		} else {
14382 			cur = cur->next;
14383 		}
14384 	}
14385 	return (NULL);
14386 }
14387 
14388 static void *
14389 mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos)
14390 {
14391 	mptsas_hash_node_t *this = NULL;
14392 
14393 	if (hashtab == NULL) {
14394 		return (NULL);
14395 	}
14396 
14397 	if (pos == MPTSAS_HASH_FIRST) {
14398 		hashtab->line = 0;
14399 		hashtab->cur = NULL;
14400 		this = hashtab->head[0];
14401 	} else {
14402 		if (hashtab->cur == NULL) {
14403 			return (NULL);
14404 		} else {
14405 			this = hashtab->cur->next;
14406 		}
14407 	}
14408 
14409 	while (this == NULL) {
14410 		hashtab->line++;
14411 		if (hashtab->line >= MPTSAS_HASH_ARRAY_SIZE) {
14412 			/* the traverse reaches the end */
14413 			hashtab->cur = NULL;
14414 			return (NULL);
14415 		} else {
14416 			this = hashtab->head[hashtab->line];
14417 		}
14418 	}
14419 	hashtab->cur = this;
14420 	return (this->data);
14421 }
14422