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 2010 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_V1,
476 	DDI_STRUCTURE_LE_ACC,
477 	DDI_STRICTORDER_ACC,
478 	DDI_DEFAULT_ACC
479 };
480 
481 static struct cb_ops mptsas_cb_ops = {
482 	scsi_hba_open,		/* open */
483 	scsi_hba_close,		/* close */
484 	nodev,			/* strategy */
485 	nodev,			/* print */
486 	nodev,			/* dump */
487 	nodev,			/* read */
488 	nodev,			/* write */
489 	mptsas_ioctl,		/* ioctl */
490 	nodev,			/* devmap */
491 	nodev,			/* mmap */
492 	nodev,			/* segmap */
493 	nochpoll,		/* chpoll */
494 	ddi_prop_op,		/* cb_prop_op */
495 	NULL,			/* streamtab */
496 	D_MP,			/* cb_flag */
497 	CB_REV,			/* rev */
498 	nodev,			/* aread */
499 	nodev			/* awrite */
500 };
501 
502 static struct dev_ops mptsas_ops = {
503 	DEVO_REV,		/* devo_rev, */
504 	0,			/* refcnt  */
505 	ddi_no_info,		/* info */
506 	nulldev,		/* identify */
507 	nulldev,		/* probe */
508 	mptsas_attach,		/* attach */
509 	mptsas_detach,		/* detach */
510 	nodev,			/* reset */
511 	&mptsas_cb_ops,		/* driver operations */
512 	NULL,			/* bus operations */
513 	mptsas_power,		/* power management */
514 #ifdef	__sparc
515 	ddi_quiesce_not_needed
516 #else
517 	mptsas_quiesce		/* quiesce */
518 #endif	/* __sparc */
519 };
520 
521 
522 #define	MPTSAS_MOD_STRING "MPTSAS HBA Driver 00.00.00.21"
523 
524 static struct modldrv modldrv = {
525 	&mod_driverops,	/* Type of module. This one is a driver */
526 	MPTSAS_MOD_STRING, /* Name of the module. */
527 	&mptsas_ops,	/* driver ops */
528 };
529 
530 static struct modlinkage modlinkage = {
531 	MODREV_1, &modldrv, NULL
532 };
533 #define	TARGET_PROP	"target"
534 #define	LUN_PROP	"lun"
535 #define	SAS_PROP	"sas-mpt"
536 #define	MDI_GUID	"wwn"
537 #define	NDI_GUID	"guid"
538 #define	MPTSAS_DEV_GONE	"mptsas_dev_gone"
539 
540 /*
541  * Local static data
542  */
543 #if defined(MPTSAS_DEBUG)
544 uint32_t mptsas_debug_flags = 0;
545 #endif	/* defined(MPTSAS_DEBUG) */
546 uint32_t mptsas_debug_resets = 0;
547 
548 static kmutex_t		mptsas_global_mutex;
549 static void		*mptsas_state;		/* soft	state ptr */
550 static krwlock_t	mptsas_global_rwlock;
551 
552 static kmutex_t		mptsas_log_mutex;
553 static char		mptsas_log_buf[256];
554 _NOTE(MUTEX_PROTECTS_DATA(mptsas_log_mutex, mptsas_log_buf))
555 
556 static mptsas_t *mptsas_head, *mptsas_tail;
557 static clock_t mptsas_scsi_watchdog_tick;
558 static clock_t mptsas_tick;
559 static timeout_id_t mptsas_reset_watch;
560 static timeout_id_t mptsas_timeout_id;
561 static int mptsas_timeouts_enabled = 0;
562 
563 /*
564  * warlock directives
565  */
566 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", scsi_pkt \
567 	mptsas_cmd NcrTableIndirect buf scsi_cdb scsi_status))
568 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", smp_pkt))
569 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address))
570 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", mptsas_tgt_private))
571 _NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_hba_tran::tran_tgt_private))
572 
573 #ifdef MPTSAS_DEBUG
574 void debug_enter(char *);
575 #endif
576 
577 /*
578  * Notes:
579  *	- scsi_hba_init(9F) initializes SCSI HBA modules
580  *	- must call scsi_hba_fini(9F) if modload() fails
581  */
582 int
583 _init(void)
584 {
585 	int status;
586 	/* CONSTCOND */
587 	ASSERT(NO_COMPETING_THREADS);
588 
589 	NDBG0(("_init"));
590 
591 	status = ddi_soft_state_init(&mptsas_state, MPTSAS_SIZE,
592 	    MPTSAS_INITIAL_SOFT_SPACE);
593 	if (status != 0) {
594 		return (status);
595 	}
596 
597 	if ((status = scsi_hba_init(&modlinkage)) != 0) {
598 		ddi_soft_state_fini(&mptsas_state);
599 		return (status);
600 	}
601 
602 	mutex_init(&mptsas_global_mutex, NULL, MUTEX_DRIVER, NULL);
603 	rw_init(&mptsas_global_rwlock, NULL, RW_DRIVER, NULL);
604 	mutex_init(&mptsas_log_mutex, NULL, MUTEX_DRIVER, NULL);
605 
606 	if ((status = mod_install(&modlinkage)) != 0) {
607 		mutex_destroy(&mptsas_log_mutex);
608 		rw_destroy(&mptsas_global_rwlock);
609 		mutex_destroy(&mptsas_global_mutex);
610 		ddi_soft_state_fini(&mptsas_state);
611 		scsi_hba_fini(&modlinkage);
612 	}
613 
614 	return (status);
615 }
616 
617 /*
618  * Notes:
619  *	- scsi_hba_fini(9F) uninitializes SCSI HBA modules
620  */
621 int
622 _fini(void)
623 {
624 	int	status;
625 	/* CONSTCOND */
626 	ASSERT(NO_COMPETING_THREADS);
627 
628 	NDBG0(("_fini"));
629 
630 	if ((status = mod_remove(&modlinkage)) == 0) {
631 		ddi_soft_state_fini(&mptsas_state);
632 		scsi_hba_fini(&modlinkage);
633 		mutex_destroy(&mptsas_global_mutex);
634 		rw_destroy(&mptsas_global_rwlock);
635 		mutex_destroy(&mptsas_log_mutex);
636 	}
637 	return (status);
638 }
639 
640 /*
641  * The loadable-module _info(9E) entry point
642  */
643 int
644 _info(struct modinfo *modinfop)
645 {
646 	/* CONSTCOND */
647 	ASSERT(NO_COMPETING_THREADS);
648 	NDBG0(("mptsas _info"));
649 
650 	return (mod_info(&modlinkage, modinfop));
651 }
652 
653 
654 static int
655 mptsas_iport_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
656 {
657 	dev_info_t		*pdip;
658 	mptsas_t		*mpt;
659 	scsi_hba_tran_t		*hba_tran;
660 	char			*iport = NULL;
661 	char			phymask[8];
662 	uint8_t			phy_mask = 0;
663 	int			physport = -1;
664 	int			dynamic_port = 0;
665 	uint32_t		page_address;
666 	char			initiator_wwnstr[MPTSAS_WWN_STRLEN];
667 	int			rval = DDI_FAILURE;
668 	int			i = 0;
669 	uint64_t		wwid = 0;
670 	uint8_t			portwidth = 0;
671 
672 	/* CONSTCOND */
673 	ASSERT(NO_COMPETING_THREADS);
674 
675 	switch (cmd) {
676 	case DDI_ATTACH:
677 		break;
678 
679 	case DDI_RESUME:
680 		/*
681 		 * If this a scsi-iport node, nothing to do here.
682 		 */
683 		return (DDI_SUCCESS);
684 
685 	default:
686 		return (DDI_FAILURE);
687 	}
688 
689 	pdip = ddi_get_parent(dip);
690 
691 	if ((hba_tran = ndi_flavorv_get(pdip, SCSA_FLAVOR_SCSI_DEVICE)) ==
692 	    NULL) {
693 		cmn_err(CE_WARN, "Failed attach iport because fail to "
694 		    "get tran vector for the HBA node");
695 		return (DDI_FAILURE);
696 	}
697 
698 	mpt = TRAN2MPT(hba_tran);
699 	ASSERT(mpt != NULL);
700 	if (mpt == NULL)
701 		return (DDI_FAILURE);
702 
703 	if ((hba_tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) ==
704 	    NULL) {
705 		mptsas_log(mpt, CE_WARN, "Failed attach iport because fail to "
706 		    "get tran vector for the iport node");
707 		return (DDI_FAILURE);
708 	}
709 
710 	/*
711 	 * Overwrite parent's tran_hba_private to iport's tran vector
712 	 */
713 	hba_tran->tran_hba_private = mpt;
714 
715 	ddi_report_dev(dip);
716 
717 	/*
718 	 * Get SAS address for initiator port according dev_handle
719 	 */
720 	iport = ddi_get_name_addr(dip);
721 	if (iport && strncmp(iport, "v0", 2) == 0) {
722 		return (DDI_SUCCESS);
723 	}
724 
725 	mutex_enter(&mpt->m_mutex);
726 	for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
727 		bzero(phymask, sizeof (phymask));
728 		(void) sprintf(phymask, "%x", mpt->m_phy_info[i].phy_mask);
729 		if (strcmp(phymask, iport) == 0) {
730 			break;
731 		}
732 	}
733 
734 	if (i == MPTSAS_MAX_PHYS) {
735 		mptsas_log(mpt, CE_WARN, "Failed attach port %s because port"
736 		    "seems not exist", iport);
737 		mutex_exit(&mpt->m_mutex);
738 		return (DDI_FAILURE);
739 	}
740 
741 	phy_mask = mpt->m_phy_info[i].phy_mask;
742 	physport = mpt->m_phy_info[i].port_num;
743 
744 	if (mpt->m_phy_info[i].port_flags & AUTO_PORT_CONFIGURATION)
745 		dynamic_port = 1;
746 	else
747 		dynamic_port = 0;
748 
749 	page_address = (MPI2_SASPORT_PGAD_FORM_PORT_NUM |
750 	    (MPI2_SASPORT_PGAD_PORTNUMBER_MASK & physport));
751 
752 	rval = mptsas_get_sas_port_page0(mpt, page_address, &wwid, &portwidth);
753 	if (rval != DDI_SUCCESS) {
754 		mptsas_log(mpt, CE_WARN, "Failed attach port %s because get"
755 		    "SAS address of initiator failed!", iport);
756 		mutex_exit(&mpt->m_mutex);
757 		return (DDI_FAILURE);
758 	}
759 	mutex_exit(&mpt->m_mutex);
760 
761 	bzero(initiator_wwnstr, sizeof (initiator_wwnstr));
762 	(void) sprintf(initiator_wwnstr, "%016"PRIx64,
763 	    wwid);
764 
765 	if (ddi_prop_update_string(DDI_DEV_T_NONE, dip,
766 	    "initiator-port", initiator_wwnstr) !=
767 	    DDI_PROP_SUCCESS) {
768 		(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "initiator-port");
769 		return (DDI_FAILURE);
770 	}
771 
772 	if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
773 	    "phymask", phy_mask) !=
774 	    DDI_PROP_SUCCESS) {
775 		(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "phymask");
776 		return (DDI_FAILURE);
777 	}
778 
779 	if (ddi_prop_update_int(DDI_DEV_T_NONE, dip,
780 	    "dynamic-port", dynamic_port) !=
781 	    DDI_PROP_SUCCESS) {
782 		(void) ddi_prop_remove(DDI_DEV_T_NONE, dip, "dynamic-port");
783 		return (DDI_FAILURE);
784 	}
785 	/*
786 	 * register sas hba iport with mdi (MPxIO/vhci)
787 	 */
788 	if (mdi_phci_register(MDI_HCI_CLASS_SCSI,
789 	    dip, 0) == MDI_SUCCESS) {
790 		mpt->m_mpxio_enable = TRUE;
791 	}
792 	return (DDI_SUCCESS);
793 }
794 
795 /*
796  * Notes:
797  *	Set up all device state and allocate data structures,
798  *	mutexes, condition variables, etc. for device operation.
799  *	Add interrupts needed.
800  *	Return DDI_SUCCESS if device is ready, else return DDI_FAILURE.
801  */
802 static int
803 mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
804 {
805 	mptsas_t		*mpt = NULL;
806 	int			instance, i, j;
807 	int			doneq_thread_num;
808 	char			buf[64];
809 	char			intr_added = 0;
810 	char			map_setup = 0;
811 	char			config_setup = 0;
812 	char			hba_attach_setup = 0;
813 	char			smp_attach_setup = 0;
814 	char			mutex_init_done = 0;
815 	char			event_taskq_create = 0;
816 	char			dr_taskq_create = 0;
817 	char			doneq_thread_create = 0;
818 	scsi_hba_tran_t		*hba_tran;
819 	int			intr_types;
820 	uint_t			mem_bar = MEM_SPACE;
821 	uint8_t			mask = 0x0;
822 	int			tran_flags = 0;
823 	int			rval = DDI_FAILURE;
824 
825 	/* CONSTCOND */
826 	ASSERT(NO_COMPETING_THREADS);
827 
828 	if (scsi_hba_iport_unit_address(dip)) {
829 		return (mptsas_iport_attach(dip, cmd));
830 	}
831 
832 	switch (cmd) {
833 	case DDI_ATTACH:
834 		break;
835 
836 	case DDI_RESUME:
837 		if ((hba_tran = ddi_get_driver_private(dip)) == NULL)
838 			return (DDI_FAILURE);
839 
840 		mpt = TRAN2MPT(hba_tran);
841 
842 		if (!mpt) {
843 			return (DDI_FAILURE);
844 		}
845 
846 		/*
847 		 * Reset hardware and softc to "no outstanding commands"
848 		 * Note	that a check condition can result on first command
849 		 * to a	target.
850 		 */
851 		mutex_enter(&mpt->m_mutex);
852 
853 		/*
854 		 * raise power.
855 		 */
856 		if (mpt->m_options & MPTSAS_OPT_PM) {
857 			mutex_exit(&mpt->m_mutex);
858 			(void) pm_busy_component(dip, 0);
859 			if (mpt->m_power_level != PM_LEVEL_D0) {
860 				rval = pm_raise_power(dip, 0, PM_LEVEL_D0);
861 			} else {
862 				rval = pm_power_has_changed(dip, 0,
863 				    PM_LEVEL_D0);
864 			}
865 			if (rval == DDI_SUCCESS) {
866 				mutex_enter(&mpt->m_mutex);
867 			} else {
868 				/*
869 				 * The pm_raise_power() call above failed,
870 				 * and that can only occur if we were unable
871 				 * to reset the hardware.  This is probably
872 				 * due to unhealty hardware, and because
873 				 * important filesystems(such as the root
874 				 * filesystem) could be on the attached disks,
875 				 * it would not be a good idea to continue,
876 				 * as we won't be entirely certain we are
877 				 * writing correct data.  So we panic() here
878 				 * to not only prevent possible data corruption,
879 				 * but to give developers or end users a hope
880 				 * of identifying and correcting any problems.
881 				 */
882 				fm_panic("mptsas could not reset hardware "
883 				    "during resume");
884 			}
885 		}
886 
887 		mpt->m_suspended = 0;
888 
889 		/*
890 		 * Reinitialize ioc
891 		 */
892 		if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) {
893 			mutex_exit(&mpt->m_mutex);
894 			if (mpt->m_options & MPTSAS_OPT_PM) {
895 				(void) pm_idle_component(dip, 0);
896 			}
897 			fm_panic("mptsas init chip fail during resume");
898 		}
899 		/*
900 		 * mptsas_update_driver_data needs interrupts so enable them
901 		 * first.
902 		 */
903 		MPTSAS_ENABLE_INTR(mpt);
904 		mptsas_update_driver_data(mpt);
905 
906 		/* start requests, if possible */
907 		mptsas_restart_hba(mpt);
908 
909 		mutex_exit(&mpt->m_mutex);
910 
911 		/*
912 		 * Restart watch thread
913 		 */
914 		mutex_enter(&mptsas_global_mutex);
915 		if (mptsas_timeout_id == 0) {
916 			mptsas_timeout_id = timeout(mptsas_watch, NULL,
917 			    mptsas_tick);
918 			mptsas_timeouts_enabled = 1;
919 		}
920 		mutex_exit(&mptsas_global_mutex);
921 
922 		/* report idle status to pm framework */
923 		if (mpt->m_options & MPTSAS_OPT_PM) {
924 			(void) pm_idle_component(dip, 0);
925 		}
926 
927 		return (DDI_SUCCESS);
928 
929 	default:
930 		return (DDI_FAILURE);
931 
932 	}
933 
934 	instance = ddi_get_instance(dip);
935 
936 	/*
937 	 * Allocate softc information.
938 	 */
939 	if (ddi_soft_state_zalloc(mptsas_state, instance) != DDI_SUCCESS) {
940 		mptsas_log(NULL, CE_WARN,
941 		    "mptsas%d: cannot allocate soft state", instance);
942 		goto fail;
943 	}
944 
945 	mpt = ddi_get_soft_state(mptsas_state, instance);
946 
947 	if (mpt == NULL) {
948 		mptsas_log(NULL, CE_WARN,
949 		    "mptsas%d: cannot get soft state", instance);
950 		goto fail;
951 	}
952 
953 	/* Allocate a transport structure */
954 	hba_tran = mpt->m_tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
955 	ASSERT(mpt->m_tran != NULL);
956 
957 	/* Indicate that we are 'sizeof (scsi_*(9S))' clean. */
958 	scsi_size_clean(dip);
959 
960 	mpt->m_dip = dip;
961 	mpt->m_instance = instance;
962 
963 	/* Make a per-instance copy of the structures */
964 	mpt->m_io_dma_attr = mptsas_dma_attrs64;
965 	mpt->m_msg_dma_attr = mptsas_dma_attrs;
966 	mpt->m_reg_acc_attr = mptsas_dev_attr;
967 	mpt->m_dev_acc_attr = mptsas_dev_attr;
968 
969 	/*
970 	 * Initialize FMA
971 	 */
972 	mpt->m_fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, mpt->m_dip,
973 	    DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
974 	    DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
975 	    DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
976 
977 	mptsas_fm_init(mpt);
978 
979 	if (pci_config_setup(mpt->m_dip,
980 	    &mpt->m_config_handle) != DDI_SUCCESS) {
981 		mptsas_log(mpt, CE_WARN, "cannot map configuration space.");
982 		goto fail;
983 	}
984 	config_setup++;
985 
986 	if (mptsas_alloc_handshake_msg(mpt,
987 	    sizeof (Mpi2SCSITaskManagementRequest_t)) == DDI_FAILURE) {
988 		mptsas_log(mpt, CE_WARN, "cannot initialize handshake msg.");
989 		goto fail;
990 	}
991 
992 	/*
993 	 * This is a workaround for a XMITS ASIC bug which does not
994 	 * drive the CBE upper bits.
995 	 */
996 	if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT) &
997 	    PCI_STAT_PERROR) {
998 		pci_config_put16(mpt->m_config_handle, PCI_CONF_STAT,
999 		    PCI_STAT_PERROR);
1000 	}
1001 
1002 	/*
1003 	 * Setup configuration space
1004 	 */
1005 	if (mptsas_config_space_init(mpt) == FALSE) {
1006 		mptsas_log(mpt, CE_WARN, "mptsas_config_space_init failed");
1007 		goto fail;
1008 	}
1009 
1010 	if (ddi_regs_map_setup(dip, mem_bar, (caddr_t *)&mpt->m_reg,
1011 	    0, 0, &mpt->m_reg_acc_attr, &mpt->m_datap) != DDI_SUCCESS) {
1012 		mptsas_log(mpt, CE_WARN, "map setup failed");
1013 		goto fail;
1014 	}
1015 	map_setup++;
1016 
1017 	/*
1018 	 * A taskq is created for dealing with the event handler
1019 	 */
1020 	if ((mpt->m_event_taskq = ddi_taskq_create(dip, "mptsas_event_taskq",
1021 	    1, TASKQ_DEFAULTPRI, 0)) == NULL) {
1022 		mptsas_log(mpt, CE_NOTE, "ddi_taskq_create failed");
1023 		goto fail;
1024 	}
1025 	event_taskq_create++;
1026 
1027 	/*
1028 	 * A taskq is created for dealing with dr events
1029 	 */
1030 	if ((mpt->m_dr_taskq = ddi_taskq_create(dip,
1031 	    "mptsas_dr_taskq",
1032 	    1, TASKQ_DEFAULTPRI, 0)) == NULL) {
1033 		mptsas_log(mpt, CE_NOTE, "ddi_taskq_create for discovery "
1034 		    "failed");
1035 		goto fail;
1036 	}
1037 	dr_taskq_create++;
1038 
1039 	mpt->m_doneq_thread_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1040 	    0, "mptsas_doneq_thread_threshold_prop", 10);
1041 	mpt->m_doneq_length_threshold = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1042 	    0, "mptsas_doneq_length_threshold_prop", 8);
1043 	mpt->m_doneq_thread_n = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1044 	    0, "mptsas_doneq_thread_n_prop", 8);
1045 
1046 	if (mpt->m_doneq_thread_n) {
1047 		cv_init(&mpt->m_doneq_thread_cv, NULL, CV_DRIVER, NULL);
1048 		mutex_init(&mpt->m_doneq_mutex, NULL, MUTEX_DRIVER, NULL);
1049 
1050 		mutex_enter(&mpt->m_doneq_mutex);
1051 		mpt->m_doneq_thread_id =
1052 		    kmem_zalloc(sizeof (mptsas_doneq_thread_list_t)
1053 		    * mpt->m_doneq_thread_n, KM_SLEEP);
1054 
1055 		for (j = 0; j < mpt->m_doneq_thread_n; j++) {
1056 			cv_init(&mpt->m_doneq_thread_id[j].cv, NULL,
1057 			    CV_DRIVER, NULL);
1058 			mutex_init(&mpt->m_doneq_thread_id[j].mutex, NULL,
1059 			    MUTEX_DRIVER, NULL);
1060 			mutex_enter(&mpt->m_doneq_thread_id[j].mutex);
1061 			mpt->m_doneq_thread_id[j].flag |=
1062 			    MPTSAS_DONEQ_THREAD_ACTIVE;
1063 			mpt->m_doneq_thread_id[j].arg.mpt = mpt;
1064 			mpt->m_doneq_thread_id[j].arg.t = j;
1065 			mpt->m_doneq_thread_id[j].threadp =
1066 			    thread_create(NULL, 0, mptsas_doneq_thread,
1067 			    &mpt->m_doneq_thread_id[j].arg,
1068 			    0, &p0, TS_RUN, minclsyspri);
1069 			mpt->m_doneq_thread_id[j].donetail =
1070 			    &mpt->m_doneq_thread_id[j].doneq;
1071 			mutex_exit(&mpt->m_doneq_thread_id[j].mutex);
1072 		}
1073 		mutex_exit(&mpt->m_doneq_mutex);
1074 		doneq_thread_create++;
1075 	}
1076 
1077 	/* Get supported interrupt types */
1078 	if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) {
1079 		mptsas_log(mpt, CE_WARN, "ddi_intr_get_supported_types "
1080 		    "failed\n");
1081 		goto fail;
1082 	}
1083 
1084 	NDBG6(("ddi_intr_get_supported_types() returned: 0x%x", intr_types));
1085 
1086 	if (mptsas_enable_msi && (intr_types & DDI_INTR_TYPE_MSI)) {
1087 		/*
1088 		 * Try MSI, but fall back to FIXED
1089 		 */
1090 		if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_MSI) == DDI_SUCCESS) {
1091 			NDBG0(("Using MSI interrupt type"));
1092 			mpt->m_intr_type = DDI_INTR_TYPE_MSI;
1093 			goto intr_done;
1094 		}
1095 	}
1096 
1097 	if (intr_types & DDI_INTR_TYPE_FIXED) {
1098 
1099 		if (mptsas_add_intrs(mpt, DDI_INTR_TYPE_FIXED) == DDI_SUCCESS) {
1100 			NDBG0(("Using FIXED interrupt type"));
1101 			mpt->m_intr_type = DDI_INTR_TYPE_FIXED;
1102 
1103 			goto intr_done;
1104 		}
1105 
1106 		NDBG0(("FIXED interrupt registration failed"));
1107 	}
1108 
1109 	goto fail;
1110 
1111 intr_done:
1112 	intr_added++;
1113 
1114 	/* Initialize mutex used in interrupt handler */
1115 	mutex_init(&mpt->m_mutex, NULL, MUTEX_DRIVER,
1116 	    DDI_INTR_PRI(mpt->m_intr_pri));
1117 	mutex_init(&mpt->m_tx_waitq_mutex, NULL, MUTEX_DRIVER,
1118 	    DDI_INTR_PRI(mpt->m_intr_pri));
1119 	cv_init(&mpt->m_cv, NULL, CV_DRIVER, NULL);
1120 	cv_init(&mpt->m_passthru_cv, NULL, CV_DRIVER, NULL);
1121 	cv_init(&mpt->m_fw_cv, NULL, CV_DRIVER, NULL);
1122 	cv_init(&mpt->m_config_cv, NULL, CV_DRIVER, NULL);
1123 	cv_init(&mpt->m_fw_diag_cv, NULL, CV_DRIVER, NULL);
1124 	mutex_init_done++;
1125 
1126 	/*
1127 	 * Disable hardware interrupt since we're not ready to
1128 	 * handle it yet.
1129 	 */
1130 	MPTSAS_DISABLE_INTR(mpt);
1131 
1132 	/*
1133 	 * Enable interrupts
1134 	 */
1135 	if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) {
1136 		/* Call ddi_intr_block_enable() for MSI interrupts */
1137 		(void) ddi_intr_block_enable(mpt->m_htable, mpt->m_intr_cnt);
1138 	} else {
1139 		/* Call ddi_intr_enable for MSI or FIXED interrupts */
1140 		for (i = 0; i < mpt->m_intr_cnt; i++) {
1141 			(void) ddi_intr_enable(mpt->m_htable[i]);
1142 		}
1143 	}
1144 
1145 	mutex_enter(&mpt->m_mutex);
1146 	/*
1147 	 * Initialize power management component
1148 	 */
1149 	if (mpt->m_options & MPTSAS_OPT_PM) {
1150 		if (mptsas_init_pm(mpt)) {
1151 			mutex_exit(&mpt->m_mutex);
1152 			mptsas_log(mpt, CE_WARN, "mptsas pm initialization "
1153 			    "failed");
1154 			goto fail;
1155 		}
1156 	}
1157 
1158 	/*
1159 	 * Initialize chip
1160 	 */
1161 	if (mptsas_init_chip(mpt, TRUE) == DDI_FAILURE) {
1162 		mutex_exit(&mpt->m_mutex);
1163 		mptsas_log(mpt, CE_WARN, "mptsas chip initialization failed");
1164 		goto fail;
1165 	}
1166 	mutex_exit(&mpt->m_mutex);
1167 
1168 	/*
1169 	 * initialize SCSI HBA transport structure
1170 	 */
1171 	hba_tran->tran_hba_private	= mpt;
1172 	hba_tran->tran_tgt_private	= NULL;
1173 
1174 	hba_tran->tran_tgt_init		= mptsas_scsi_tgt_init;
1175 	hba_tran->tran_tgt_free		= mptsas_scsi_tgt_free;
1176 
1177 	hba_tran->tran_start		= mptsas_scsi_start;
1178 	hba_tran->tran_reset		= mptsas_scsi_reset;
1179 	hba_tran->tran_abort		= mptsas_scsi_abort;
1180 	hba_tran->tran_getcap		= mptsas_scsi_getcap;
1181 	hba_tran->tran_setcap		= mptsas_scsi_setcap;
1182 	hba_tran->tran_init_pkt		= mptsas_scsi_init_pkt;
1183 	hba_tran->tran_destroy_pkt	= mptsas_scsi_destroy_pkt;
1184 
1185 	hba_tran->tran_dmafree		= mptsas_scsi_dmafree;
1186 	hba_tran->tran_sync_pkt		= mptsas_scsi_sync_pkt;
1187 	hba_tran->tran_reset_notify	= mptsas_scsi_reset_notify;
1188 
1189 	hba_tran->tran_get_bus_addr	= mptsas_get_bus_addr;
1190 	hba_tran->tran_get_name		= mptsas_get_name;
1191 
1192 	hba_tran->tran_quiesce		= mptsas_scsi_quiesce;
1193 	hba_tran->tran_unquiesce	= mptsas_scsi_unquiesce;
1194 	hba_tran->tran_bus_reset	= NULL;
1195 
1196 	hba_tran->tran_add_eventcall	= NULL;
1197 	hba_tran->tran_get_eventcookie	= NULL;
1198 	hba_tran->tran_post_event	= NULL;
1199 	hba_tran->tran_remove_eventcall	= NULL;
1200 
1201 	hba_tran->tran_bus_config	= mptsas_bus_config;
1202 
1203 	hba_tran->tran_interconnect_type = INTERCONNECT_SAS;
1204 
1205 	if (mptsas_alloc_active_slots(mpt, KM_SLEEP)) {
1206 		goto fail;
1207 	}
1208 
1209 	/*
1210 	 * Register the iport for multiple port HBA
1211 	 */
1212 	/*
1213 	 * initial value of mask is 0
1214 	 */
1215 	mutex_enter(&mpt->m_mutex);
1216 	for (i = 0; i < mpt->m_num_phys; i++) {
1217 		uint8_t	phy_mask = 0x00;
1218 		char phy_mask_name[8];
1219 		uint8_t current_port;
1220 
1221 		if (mpt->m_phy_info[i].attached_devhdl == 0)
1222 			continue;
1223 
1224 		bzero(phy_mask_name, sizeof (phy_mask_name));
1225 
1226 		current_port = mpt->m_phy_info[i].port_num;
1227 
1228 		if ((mask & (1 << i)) != 0)
1229 			continue;
1230 
1231 		for (j = 0; j < mpt->m_num_phys; j++) {
1232 			if (mpt->m_phy_info[j].attached_devhdl &&
1233 			    (mpt->m_phy_info[j].port_num == current_port)) {
1234 				phy_mask |= (1 << j);
1235 			}
1236 		}
1237 		mask = mask | phy_mask;
1238 
1239 		for (j = 0; j < mpt->m_num_phys; j++) {
1240 			if ((phy_mask >> j) & 0x01) {
1241 				mpt->m_phy_info[j].phy_mask = phy_mask;
1242 			}
1243 		}
1244 
1245 		(void) sprintf(phy_mask_name, "%x", phy_mask);
1246 
1247 		mutex_exit(&mpt->m_mutex);
1248 		/*
1249 		 * register a iport
1250 		 */
1251 		(void) scsi_hba_iport_register(dip, phy_mask_name);
1252 		mutex_enter(&mpt->m_mutex);
1253 	}
1254 	mutex_exit(&mpt->m_mutex);
1255 	/*
1256 	 * register a virtual port for RAID volume always
1257 	 */
1258 	(void) scsi_hba_iport_register(dip, "v0");
1259 	/*
1260 	 * All children of the HBA are iports. We need tran was cloned.
1261 	 * So we pass the flags to SCSA. SCSI_HBA_TRAN_CLONE will be
1262 	 * inherited to iport's tran vector.
1263 	 */
1264 	tran_flags = (SCSI_HBA_HBA | SCSI_HBA_TRAN_CLONE);
1265 
1266 	if (scsi_hba_attach_setup(dip, &mpt->m_msg_dma_attr,
1267 	    hba_tran, tran_flags) != DDI_SUCCESS) {
1268 		mptsas_log(mpt, CE_WARN, "hba attach setup failed");
1269 		goto fail;
1270 	}
1271 	hba_attach_setup++;
1272 
1273 	mpt->m_smptran = smp_hba_tran_alloc(dip);
1274 	ASSERT(mpt->m_smptran != NULL);
1275 	mpt->m_smptran->smp_tran_hba_private = mpt;
1276 	mpt->m_smptran->smp_tran_start = mptsas_smp_start;
1277 	if (smp_hba_attach_setup(dip, mpt->m_smptran) != DDI_SUCCESS) {
1278 		mptsas_log(mpt, CE_WARN, "smp attach setup failed");
1279 		goto fail;
1280 	}
1281 	smp_attach_setup++;
1282 
1283 	/*
1284 	 * Initialize smp hash table
1285 	 */
1286 	mptsas_hash_init(&mpt->m_active->m_smptbl);
1287 	mpt->m_smp_devhdl = 0xFFFF;
1288 
1289 	/*
1290 	 * create kmem cache for packets
1291 	 */
1292 	(void) sprintf(buf, "mptsas%d_cache", instance);
1293 	mpt->m_kmem_cache = kmem_cache_create(buf,
1294 	    sizeof (struct mptsas_cmd) + scsi_pkt_size(), 8,
1295 	    mptsas_kmem_cache_constructor, mptsas_kmem_cache_destructor,
1296 	    NULL, (void *)mpt, NULL, 0);
1297 
1298 	if (mpt->m_kmem_cache == NULL) {
1299 		mptsas_log(mpt, CE_WARN, "creating kmem cache failed");
1300 		goto fail;
1301 	}
1302 
1303 	/*
1304 	 * create kmem cache for extra SGL frames if SGL cannot
1305 	 * be accomodated into main request frame.
1306 	 */
1307 	(void) sprintf(buf, "mptsas%d_cache_frames", instance);
1308 	mpt->m_cache_frames = kmem_cache_create(buf,
1309 	    sizeof (mptsas_cache_frames_t), 8,
1310 	    mptsas_cache_frames_constructor, mptsas_cache_frames_destructor,
1311 	    NULL, (void *)mpt, NULL, 0);
1312 
1313 	if (mpt->m_cache_frames == NULL) {
1314 		mptsas_log(mpt, CE_WARN, "creating cache for frames failed");
1315 		goto fail;
1316 	}
1317 
1318 	mpt->m_scsi_reset_delay	= ddi_prop_get_int(DDI_DEV_T_ANY,
1319 	    dip, 0, "scsi-reset-delay",	SCSI_DEFAULT_RESET_DELAY);
1320 	if (mpt->m_scsi_reset_delay == 0) {
1321 		mptsas_log(mpt, CE_NOTE,
1322 		    "scsi_reset_delay of 0 is not recommended,"
1323 		    " resetting to SCSI_DEFAULT_RESET_DELAY\n");
1324 		mpt->m_scsi_reset_delay = SCSI_DEFAULT_RESET_DELAY;
1325 	}
1326 
1327 	/*
1328 	 * Initialize the wait and done FIFO queue
1329 	 */
1330 	mpt->m_donetail = &mpt->m_doneq;
1331 	mpt->m_waitqtail = &mpt->m_waitq;
1332 
1333 	mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
1334 	mpt->m_tx_draining = 0;
1335 
1336 	/*
1337 	 * ioc cmd queue initialize
1338 	 */
1339 	mpt->m_ioc_event_cmdtail = &mpt->m_ioc_event_cmdq;
1340 
1341 	mpt->m_dev_handle = 0xFFFF;
1342 
1343 	MPTSAS_ENABLE_INTR(mpt);
1344 
1345 	/*
1346 	 * enable event notification
1347 	 */
1348 	mutex_enter(&mpt->m_mutex);
1349 	if (mptsas_ioc_enable_event_notification(mpt)) {
1350 		mutex_exit(&mpt->m_mutex);
1351 		goto fail;
1352 	}
1353 	mutex_exit(&mpt->m_mutex);
1354 
1355 
1356 	/* Check all dma handles allocated in attach */
1357 	if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl)
1358 	    != DDI_SUCCESS) ||
1359 	    (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl)
1360 	    != DDI_SUCCESS) ||
1361 	    (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl)
1362 	    != DDI_SUCCESS) ||
1363 	    (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl)
1364 	    != DDI_SUCCESS) ||
1365 	    (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl)
1366 	    != DDI_SUCCESS)) {
1367 		goto fail;
1368 	}
1369 
1370 	/* Check all acc handles allocated in attach */
1371 	if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) ||
1372 	    (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl)
1373 	    != DDI_SUCCESS) ||
1374 	    (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl)
1375 	    != DDI_SUCCESS) ||
1376 	    (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl)
1377 	    != DDI_SUCCESS) ||
1378 	    (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl)
1379 	    != DDI_SUCCESS) ||
1380 	    (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl)
1381 	    != DDI_SUCCESS) ||
1382 	    (mptsas_check_acc_handle(mpt->m_config_handle)
1383 	    != DDI_SUCCESS)) {
1384 		goto fail;
1385 	}
1386 
1387 	/*
1388 	 * After this point, we are not going to fail the attach.
1389 	 */
1390 	/*
1391 	 * used for mptsas_watch
1392 	 */
1393 	rw_enter(&mptsas_global_rwlock, RW_WRITER);
1394 	if (mptsas_head == NULL) {
1395 		mptsas_head = mpt;
1396 	} else {
1397 		mptsas_tail->m_next = mpt;
1398 	}
1399 	mptsas_tail = mpt;
1400 	rw_exit(&mptsas_global_rwlock);
1401 
1402 	mutex_enter(&mptsas_global_mutex);
1403 	if (mptsas_timeouts_enabled == 0) {
1404 		mptsas_scsi_watchdog_tick = ddi_prop_get_int(DDI_DEV_T_ANY,
1405 		    dip, 0, "scsi-watchdog-tick", DEFAULT_WD_TICK);
1406 
1407 		mptsas_tick = mptsas_scsi_watchdog_tick *
1408 		    drv_usectohz((clock_t)1000000);
1409 
1410 		mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick);
1411 		mptsas_timeouts_enabled = 1;
1412 	}
1413 	mutex_exit(&mptsas_global_mutex);
1414 
1415 	/* Print message of HBA present */
1416 	ddi_report_dev(dip);
1417 
1418 	/* report idle status to pm framework */
1419 	if (mpt->m_options & MPTSAS_OPT_PM) {
1420 		(void) pm_idle_component(dip, 0);
1421 	}
1422 
1423 	return (DDI_SUCCESS);
1424 
1425 fail:
1426 	mptsas_log(mpt, CE_WARN, "attach failed");
1427 	mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
1428 	ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
1429 	if (mpt) {
1430 		mutex_enter(&mptsas_global_mutex);
1431 
1432 		if (mptsas_timeout_id && (mptsas_head == NULL)) {
1433 			timeout_id_t tid = mptsas_timeout_id;
1434 			mptsas_timeouts_enabled = 0;
1435 			mptsas_timeout_id = 0;
1436 			mutex_exit(&mptsas_global_mutex);
1437 			(void) untimeout(tid);
1438 			mutex_enter(&mptsas_global_mutex);
1439 		}
1440 		mutex_exit(&mptsas_global_mutex);
1441 		/* deallocate in reverse order */
1442 		if (mpt->m_cache_frames) {
1443 			kmem_cache_destroy(mpt->m_cache_frames);
1444 		}
1445 		if (mpt->m_kmem_cache) {
1446 			kmem_cache_destroy(mpt->m_kmem_cache);
1447 		}
1448 		if (hba_attach_setup) {
1449 			(void) scsi_hba_detach(dip);
1450 		}
1451 		if (smp_attach_setup) {
1452 			(void) smp_hba_detach(dip);
1453 		}
1454 		if (intr_added) {
1455 			mptsas_rem_intrs(mpt);
1456 		}
1457 		if (doneq_thread_create) {
1458 			mutex_enter(&mpt->m_doneq_mutex);
1459 			doneq_thread_num = mpt->m_doneq_thread_n;
1460 			for (j = 0; j < mpt->m_doneq_thread_n; j++) {
1461 				mutex_enter(&mpt->m_doneq_thread_id[j].mutex);
1462 				mpt->m_doneq_thread_id[j].flag &=
1463 				    (~MPTSAS_DONEQ_THREAD_ACTIVE);
1464 				cv_signal(&mpt->m_doneq_thread_id[j].cv);
1465 				mutex_exit(&mpt->m_doneq_thread_id[j].mutex);
1466 			}
1467 			while (mpt->m_doneq_thread_n) {
1468 				cv_wait(&mpt->m_doneq_thread_cv,
1469 				    &mpt->m_doneq_mutex);
1470 			}
1471 			for (j = 0; j < doneq_thread_num; j++) {
1472 				cv_destroy(&mpt->m_doneq_thread_id[j].cv);
1473 				mutex_destroy(&mpt->m_doneq_thread_id[j].mutex);
1474 			}
1475 			kmem_free(mpt->m_doneq_thread_id,
1476 			    sizeof (mptsas_doneq_thread_list_t)
1477 			    * doneq_thread_num);
1478 			mutex_exit(&mpt->m_doneq_mutex);
1479 			cv_destroy(&mpt->m_doneq_thread_cv);
1480 			mutex_destroy(&mpt->m_doneq_mutex);
1481 		}
1482 		if (event_taskq_create) {
1483 			ddi_taskq_destroy(mpt->m_event_taskq);
1484 		}
1485 		if (dr_taskq_create) {
1486 			ddi_taskq_destroy(mpt->m_dr_taskq);
1487 		}
1488 		if (mutex_init_done) {
1489 			mutex_destroy(&mpt->m_tx_waitq_mutex);
1490 			mutex_destroy(&mpt->m_mutex);
1491 			cv_destroy(&mpt->m_cv);
1492 			cv_destroy(&mpt->m_passthru_cv);
1493 			cv_destroy(&mpt->m_fw_cv);
1494 			cv_destroy(&mpt->m_config_cv);
1495 			cv_destroy(&mpt->m_fw_diag_cv);
1496 		}
1497 		mptsas_free_handshake_msg(mpt);
1498 		mptsas_hba_fini(mpt);
1499 		if (map_setup) {
1500 			mptsas_cfg_fini(mpt);
1501 		}
1502 		if (config_setup) {
1503 			pci_config_teardown(&mpt->m_config_handle);
1504 		}
1505 		if (mpt->m_tran) {
1506 			scsi_hba_tran_free(mpt->m_tran);
1507 			mpt->m_tran = NULL;
1508 		}
1509 		if (mpt->m_smptran) {
1510 			smp_hba_tran_free(mpt->m_smptran);
1511 			mpt->m_smptran = NULL;
1512 		}
1513 		mptsas_fm_fini(mpt);
1514 		ddi_soft_state_free(mptsas_state, instance);
1515 		ddi_prop_remove_all(dip);
1516 	}
1517 	return (DDI_FAILURE);
1518 }
1519 
1520 static int
1521 mptsas_suspend(dev_info_t *devi)
1522 {
1523 	mptsas_t	*mpt, *g;
1524 	scsi_hba_tran_t	*tran;
1525 
1526 	if (scsi_hba_iport_unit_address(devi)) {
1527 		return (DDI_SUCCESS);
1528 	}
1529 
1530 	if ((tran = ddi_get_driver_private(devi)) == NULL)
1531 		return (DDI_SUCCESS);
1532 
1533 	mpt = TRAN2MPT(tran);
1534 	if (!mpt) {
1535 		return (DDI_SUCCESS);
1536 	}
1537 
1538 	mutex_enter(&mpt->m_mutex);
1539 
1540 	/*
1541 	 * Send RAID action system shutdown to sync IR
1542 	 */
1543 	mptsas_raid_action_system_shutdown(mpt);
1544 
1545 	if (mpt->m_suspended++) {
1546 		mutex_exit(&mpt->m_mutex);
1547 		return (DDI_SUCCESS);
1548 	}
1549 
1550 	/*
1551 	 * Cancel timeout threads for this mpt
1552 	 */
1553 	if (mpt->m_quiesce_timeid) {
1554 		timeout_id_t tid = mpt->m_quiesce_timeid;
1555 		mpt->m_quiesce_timeid = 0;
1556 		mutex_exit(&mpt->m_mutex);
1557 		(void) untimeout(tid);
1558 		mutex_enter(&mpt->m_mutex);
1559 	}
1560 
1561 	if (mpt->m_restart_cmd_timeid) {
1562 		timeout_id_t tid = mpt->m_restart_cmd_timeid;
1563 		mpt->m_restart_cmd_timeid = 0;
1564 		mutex_exit(&mpt->m_mutex);
1565 		(void) untimeout(tid);
1566 		mutex_enter(&mpt->m_mutex);
1567 	}
1568 
1569 	if (mpt->m_pm_timeid != 0) {
1570 		timeout_id_t tid = mpt->m_pm_timeid;
1571 		mpt->m_pm_timeid = 0;
1572 		mutex_exit(&mpt->m_mutex);
1573 		(void) untimeout(tid);
1574 		/*
1575 		 * Report idle status for last ioctl since
1576 		 * calls to pm_busy_component(9F) are stacked.
1577 		 */
1578 		(void) pm_idle_component(mpt->m_dip, 0);
1579 		mutex_enter(&mpt->m_mutex);
1580 	}
1581 	mutex_exit(&mpt->m_mutex);
1582 
1583 	/*
1584 	 * Cancel watch threads if all mpts suspended
1585 	 */
1586 	rw_enter(&mptsas_global_rwlock, RW_WRITER);
1587 	for (g = mptsas_head; g != NULL; g = g->m_next) {
1588 		if (!g->m_suspended)
1589 			break;
1590 	}
1591 	rw_exit(&mptsas_global_rwlock);
1592 
1593 	mutex_enter(&mptsas_global_mutex);
1594 	if (g == NULL) {
1595 		timeout_id_t tid;
1596 
1597 		mptsas_timeouts_enabled = 0;
1598 		if (mptsas_timeout_id) {
1599 			tid = mptsas_timeout_id;
1600 			mptsas_timeout_id = 0;
1601 			mutex_exit(&mptsas_global_mutex);
1602 			(void) untimeout(tid);
1603 			mutex_enter(&mptsas_global_mutex);
1604 		}
1605 		if (mptsas_reset_watch) {
1606 			tid = mptsas_reset_watch;
1607 			mptsas_reset_watch = 0;
1608 			mutex_exit(&mptsas_global_mutex);
1609 			(void) untimeout(tid);
1610 			mutex_enter(&mptsas_global_mutex);
1611 		}
1612 	}
1613 	mutex_exit(&mptsas_global_mutex);
1614 
1615 	mutex_enter(&mpt->m_mutex);
1616 
1617 	/*
1618 	 * If this mpt is not in full power(PM_LEVEL_D0), just return.
1619 	 */
1620 	if ((mpt->m_options & MPTSAS_OPT_PM) &&
1621 	    (mpt->m_power_level != PM_LEVEL_D0)) {
1622 		mutex_exit(&mpt->m_mutex);
1623 		return (DDI_SUCCESS);
1624 	}
1625 
1626 	/* Disable HBA interrupts in hardware */
1627 	MPTSAS_DISABLE_INTR(mpt);
1628 
1629 	mutex_exit(&mpt->m_mutex);
1630 
1631 	/* drain the taskq */
1632 	ddi_taskq_wait(mpt->m_event_taskq);
1633 	ddi_taskq_wait(mpt->m_dr_taskq);
1634 
1635 	return (DDI_SUCCESS);
1636 }
1637 
1638 /*
1639  * quiesce(9E) entry point.
1640  *
1641  * This function is called when the system is single-threaded at high
1642  * PIL with preemption disabled. Therefore, this function must not be
1643  * blocked.
1644  *
1645  * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
1646  * DDI_FAILURE indicates an error condition and should almost never happen.
1647  */
1648 #ifndef	__sparc
1649 static int
1650 mptsas_quiesce(dev_info_t *devi)
1651 {
1652 	mptsas_t	*mpt;
1653 	scsi_hba_tran_t *tran;
1654 
1655 	if ((tran = ddi_get_driver_private(devi)) == NULL)
1656 		return (DDI_SUCCESS);
1657 
1658 	if ((mpt = TRAN2MPT(tran)) == NULL)
1659 		return (DDI_SUCCESS);
1660 
1661 	/* Disable HBA interrupts in hardware */
1662 	MPTSAS_DISABLE_INTR(mpt);
1663 
1664 	return (DDI_SUCCESS);
1665 }
1666 #endif	/* __sparc */
1667 
1668 /*
1669  * detach(9E).	Remove all device allocations and system resources;
1670  * disable device interrupts.
1671  * Return DDI_SUCCESS if done; DDI_FAILURE if there's a problem.
1672  */
1673 static int
1674 mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
1675 {
1676 	/* CONSTCOND */
1677 	ASSERT(NO_COMPETING_THREADS);
1678 	NDBG0(("mptsas_detach: dip=0x%p cmd=0x%p", (void *)devi, (void *)cmd));
1679 
1680 	switch (cmd) {
1681 	case DDI_DETACH:
1682 		return (mptsas_do_detach(devi));
1683 
1684 	case DDI_SUSPEND:
1685 		return (mptsas_suspend(devi));
1686 
1687 	default:
1688 		return (DDI_FAILURE);
1689 	}
1690 	/* NOTREACHED */
1691 }
1692 
1693 static int
1694 mptsas_do_detach(dev_info_t *dip)
1695 {
1696 	mptsas_t	*mpt, *m;
1697 	scsi_hba_tran_t	*tran;
1698 	mptsas_slots_t	*active;
1699 	int		circ = 0;
1700 	int		circ1 = 0;
1701 	mdi_pathinfo_t	*pip = NULL;
1702 	int		i;
1703 	int		doneq_thread_num = 0;
1704 
1705 	NDBG0(("mptsas_do_detach: dip=0x%p", (void *)dip));
1706 
1707 	if ((tran = ndi_flavorv_get(dip, SCSA_FLAVOR_SCSI_DEVICE)) == NULL)
1708 		return (DDI_FAILURE);
1709 
1710 	mpt = TRAN2MPT(tran);
1711 	if (!mpt) {
1712 		return (DDI_FAILURE);
1713 	}
1714 	/*
1715 	 * Still have pathinfo child, should not detach mpt driver
1716 	 */
1717 	if (scsi_hba_iport_unit_address(dip)) {
1718 		if (mpt->m_mpxio_enable) {
1719 			/*
1720 			 * MPxIO enabled for the iport
1721 			 */
1722 			ndi_devi_enter(scsi_vhci_dip, &circ1);
1723 			ndi_devi_enter(dip, &circ);
1724 			while (pip = mdi_get_next_client_path(dip, NULL)) {
1725 				if (mdi_pi_free(pip, 0) == MDI_SUCCESS) {
1726 					continue;
1727 				}
1728 				ndi_devi_exit(dip, circ);
1729 				ndi_devi_exit(scsi_vhci_dip, circ1);
1730 				NDBG12(("detach failed because of "
1731 				    "outstanding path info"));
1732 				return (DDI_FAILURE);
1733 			}
1734 			ndi_devi_exit(dip, circ);
1735 			ndi_devi_exit(scsi_vhci_dip, circ1);
1736 			(void) mdi_phci_unregister(dip, 0);
1737 		}
1738 
1739 		ddi_prop_remove_all(dip);
1740 
1741 		return (DDI_SUCCESS);
1742 	}
1743 
1744 	/* Make sure power level is D0 before accessing registers */
1745 	if (mpt->m_options & MPTSAS_OPT_PM) {
1746 		(void) pm_busy_component(dip, 0);
1747 		if (mpt->m_power_level != PM_LEVEL_D0) {
1748 			if (pm_raise_power(dip, 0, PM_LEVEL_D0) !=
1749 			    DDI_SUCCESS) {
1750 				mptsas_log(mpt, CE_WARN,
1751 				    "mptsas%d: Raise power request failed.",
1752 				    mpt->m_instance);
1753 				(void) pm_idle_component(dip, 0);
1754 				return (DDI_FAILURE);
1755 			}
1756 		}
1757 	}
1758 
1759 	mutex_enter(&mpt->m_mutex);
1760 
1761 	/*
1762 	 * Send RAID action system shutdown to sync IR
1763 	 */
1764 	mptsas_raid_action_system_shutdown(mpt);
1765 	MPTSAS_DISABLE_INTR(mpt);
1766 	mutex_exit(&mpt->m_mutex);
1767 	mptsas_rem_intrs(mpt);
1768 	ddi_taskq_destroy(mpt->m_event_taskq);
1769 	ddi_taskq_destroy(mpt->m_dr_taskq);
1770 
1771 	if (mpt->m_doneq_thread_n) {
1772 		mutex_enter(&mpt->m_doneq_mutex);
1773 		doneq_thread_num = mpt->m_doneq_thread_n;
1774 		for (i = 0; i < mpt->m_doneq_thread_n; i++) {
1775 			mutex_enter(&mpt->m_doneq_thread_id[i].mutex);
1776 			mpt->m_doneq_thread_id[i].flag &=
1777 			    (~MPTSAS_DONEQ_THREAD_ACTIVE);
1778 			cv_signal(&mpt->m_doneq_thread_id[i].cv);
1779 			mutex_exit(&mpt->m_doneq_thread_id[i].mutex);
1780 		}
1781 		while (mpt->m_doneq_thread_n) {
1782 			cv_wait(&mpt->m_doneq_thread_cv,
1783 			    &mpt->m_doneq_mutex);
1784 		}
1785 		for (i = 0;  i < doneq_thread_num; i++) {
1786 			cv_destroy(&mpt->m_doneq_thread_id[i].cv);
1787 			mutex_destroy(&mpt->m_doneq_thread_id[i].mutex);
1788 		}
1789 		kmem_free(mpt->m_doneq_thread_id,
1790 		    sizeof (mptsas_doneq_thread_list_t)
1791 		    * doneq_thread_num);
1792 		mutex_exit(&mpt->m_doneq_mutex);
1793 		cv_destroy(&mpt->m_doneq_thread_cv);
1794 		mutex_destroy(&mpt->m_doneq_mutex);
1795 	}
1796 
1797 	scsi_hba_reset_notify_tear_down(mpt->m_reset_notify_listf);
1798 
1799 	/*
1800 	 * Remove device instance from the global linked list
1801 	 */
1802 	rw_enter(&mptsas_global_rwlock, RW_WRITER);
1803 	if (mptsas_head == mpt) {
1804 		m = mptsas_head = mpt->m_next;
1805 	} else {
1806 		for (m = mptsas_head; m != NULL; m = m->m_next) {
1807 			if (m->m_next == mpt) {
1808 				m->m_next = mpt->m_next;
1809 				break;
1810 			}
1811 		}
1812 		if (m == NULL) {
1813 			mptsas_log(mpt, CE_PANIC, "Not in softc list!");
1814 		}
1815 	}
1816 
1817 	if (mptsas_tail == mpt) {
1818 		mptsas_tail = m;
1819 	}
1820 	rw_exit(&mptsas_global_rwlock);
1821 
1822 	/*
1823 	 * Cancel timeout threads for this mpt
1824 	 */
1825 	mutex_enter(&mpt->m_mutex);
1826 	if (mpt->m_quiesce_timeid) {
1827 		timeout_id_t tid = mpt->m_quiesce_timeid;
1828 		mpt->m_quiesce_timeid = 0;
1829 		mutex_exit(&mpt->m_mutex);
1830 		(void) untimeout(tid);
1831 		mutex_enter(&mpt->m_mutex);
1832 	}
1833 
1834 	if (mpt->m_restart_cmd_timeid) {
1835 		timeout_id_t tid = mpt->m_restart_cmd_timeid;
1836 		mpt->m_restart_cmd_timeid = 0;
1837 		mutex_exit(&mpt->m_mutex);
1838 		(void) untimeout(tid);
1839 		mutex_enter(&mpt->m_mutex);
1840 	}
1841 
1842 	if (mpt->m_pm_timeid != 0) {
1843 		timeout_id_t tid = mpt->m_pm_timeid;
1844 		mpt->m_pm_timeid = 0;
1845 		mutex_exit(&mpt->m_mutex);
1846 		(void) untimeout(tid);
1847 		/*
1848 		 * Report idle status for last ioctl since
1849 		 * calls to pm_busy_component(9F) are stacked.
1850 		 */
1851 		(void) pm_idle_component(mpt->m_dip, 0);
1852 		mutex_enter(&mpt->m_mutex);
1853 	}
1854 	mutex_exit(&mpt->m_mutex);
1855 
1856 	/*
1857 	 * last mpt? ... if active, CANCEL watch threads.
1858 	 */
1859 	mutex_enter(&mptsas_global_mutex);
1860 	if (mptsas_head == NULL) {
1861 		timeout_id_t tid;
1862 		/*
1863 		 * Clear mptsas_timeouts_enable so that the watch thread
1864 		 * gets restarted on DDI_ATTACH
1865 		 */
1866 		mptsas_timeouts_enabled = 0;
1867 		if (mptsas_timeout_id) {
1868 			tid = mptsas_timeout_id;
1869 			mptsas_timeout_id = 0;
1870 			mutex_exit(&mptsas_global_mutex);
1871 			(void) untimeout(tid);
1872 			mutex_enter(&mptsas_global_mutex);
1873 		}
1874 		if (mptsas_reset_watch) {
1875 			tid = mptsas_reset_watch;
1876 			mptsas_reset_watch = 0;
1877 			mutex_exit(&mptsas_global_mutex);
1878 			(void) untimeout(tid);
1879 			mutex_enter(&mptsas_global_mutex);
1880 		}
1881 	}
1882 	mutex_exit(&mptsas_global_mutex);
1883 
1884 	/*
1885 	 * Delete nt_active.
1886 	 */
1887 	active = mpt->m_active;
1888 	mutex_enter(&mpt->m_mutex);
1889 	mptsas_hash_uninit(&active->m_smptbl, sizeof (mptsas_smp_t));
1890 	mutex_exit(&mpt->m_mutex);
1891 
1892 	if (active) {
1893 		kmem_free(active, active->m_size);
1894 		mpt->m_active = NULL;
1895 	}
1896 
1897 	/* deallocate everything that was allocated in mptsas_attach */
1898 	mptsas_fm_fini(mpt);
1899 	kmem_cache_destroy(mpt->m_cache_frames);
1900 	kmem_cache_destroy(mpt->m_kmem_cache);
1901 
1902 	(void) scsi_hba_detach(dip);
1903 	(void) smp_hba_detach(dip);
1904 	mptsas_free_handshake_msg(mpt);
1905 	mptsas_hba_fini(mpt);
1906 	mptsas_cfg_fini(mpt);
1907 
1908 	/* Lower the power informing PM Framework */
1909 	if (mpt->m_options & MPTSAS_OPT_PM) {
1910 		if (pm_lower_power(dip, 0, PM_LEVEL_D3) != DDI_SUCCESS)
1911 			mptsas_log(mpt, CE_WARN,
1912 			    "!mptsas%d: Lower power request failed "
1913 			    "during detach, ignoring.",
1914 			    mpt->m_instance);
1915 	}
1916 
1917 	mutex_destroy(&mpt->m_tx_waitq_mutex);
1918 	mutex_destroy(&mpt->m_mutex);
1919 	cv_destroy(&mpt->m_cv);
1920 	cv_destroy(&mpt->m_passthru_cv);
1921 	cv_destroy(&mpt->m_fw_cv);
1922 	cv_destroy(&mpt->m_config_cv);
1923 	cv_destroy(&mpt->m_fw_diag_cv);
1924 
1925 	pci_config_teardown(&mpt->m_config_handle);
1926 	if (mpt->m_tran) {
1927 		scsi_hba_tran_free(mpt->m_tran);
1928 		mpt->m_tran = NULL;
1929 	}
1930 
1931 	if (mpt->m_smptran) {
1932 		smp_hba_tran_free(mpt->m_smptran);
1933 		mpt->m_smptran = NULL;
1934 	}
1935 
1936 	ddi_soft_state_free(mptsas_state, ddi_get_instance(dip));
1937 	ddi_prop_remove_all(dip);
1938 
1939 	return (DDI_SUCCESS);
1940 }
1941 
1942 static int
1943 mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size)
1944 {
1945 	ddi_dma_attr_t		task_dma_attrs;
1946 	ddi_dma_cookie_t	tmp_dma_cookie;
1947 	size_t			alloc_len;
1948 	uint_t			ncookie;
1949 
1950 	/* allocate Task Management ddi_dma resources */
1951 	task_dma_attrs = mpt->m_msg_dma_attr;
1952 	task_dma_attrs.dma_attr_sgllen = 1;
1953 	task_dma_attrs.dma_attr_granular = (uint32_t)(alloc_size);
1954 
1955 	if (ddi_dma_alloc_handle(mpt->m_dip, &task_dma_attrs,
1956 	    DDI_DMA_SLEEP, NULL, &mpt->m_hshk_dma_hdl) != DDI_SUCCESS) {
1957 		mpt->m_hshk_dma_hdl = NULL;
1958 		return (DDI_FAILURE);
1959 	}
1960 
1961 	if (ddi_dma_mem_alloc(mpt->m_hshk_dma_hdl, alloc_size,
1962 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
1963 	    &mpt->m_hshk_memp, &alloc_len, &mpt->m_hshk_acc_hdl)
1964 	    != DDI_SUCCESS) {
1965 		ddi_dma_free_handle(&mpt->m_hshk_dma_hdl);
1966 		mpt->m_hshk_dma_hdl = NULL;
1967 		return (DDI_FAILURE);
1968 	}
1969 
1970 	if (ddi_dma_addr_bind_handle(mpt->m_hshk_dma_hdl, NULL,
1971 	    mpt->m_hshk_memp, alloc_len, (DDI_DMA_RDWR | DDI_DMA_CONSISTENT),
1972 	    DDI_DMA_SLEEP, NULL, &tmp_dma_cookie, &ncookie)
1973 	    != DDI_DMA_MAPPED) {
1974 		(void) ddi_dma_mem_free(&mpt->m_hshk_acc_hdl);
1975 		ddi_dma_free_handle(&mpt->m_hshk_dma_hdl);
1976 		mpt->m_hshk_dma_hdl = NULL;
1977 		return (DDI_FAILURE);
1978 	}
1979 	mpt->m_hshk_dma_size = alloc_size;
1980 	return (DDI_SUCCESS);
1981 }
1982 
1983 static void
1984 mptsas_free_handshake_msg(mptsas_t *mpt)
1985 {
1986 	if (mpt->m_hshk_dma_hdl != NULL) {
1987 		(void) ddi_dma_unbind_handle(mpt->m_hshk_dma_hdl);
1988 		(void) ddi_dma_mem_free(&mpt->m_hshk_acc_hdl);
1989 		ddi_dma_free_handle(&mpt->m_hshk_dma_hdl);
1990 		mpt->m_hshk_dma_hdl = NULL;
1991 		mpt->m_hshk_dma_size = 0;
1992 	}
1993 }
1994 
1995 static int
1996 mptsas_power(dev_info_t *dip, int component, int level)
1997 {
1998 #ifndef __lock_lint
1999 	_NOTE(ARGUNUSED(component))
2000 #endif
2001 	mptsas_t	*mpt;
2002 	int		rval = DDI_SUCCESS;
2003 	int		polls = 0;
2004 	uint32_t	ioc_status;
2005 
2006 	if (scsi_hba_iport_unit_address(dip) != 0)
2007 		return (DDI_SUCCESS);
2008 
2009 	mpt = ddi_get_soft_state(mptsas_state, ddi_get_instance(dip));
2010 	if (mpt == NULL) {
2011 		return (DDI_FAILURE);
2012 	}
2013 
2014 	mutex_enter(&mpt->m_mutex);
2015 
2016 	/*
2017 	 * If the device is busy, don't lower its power level
2018 	 */
2019 	if (mpt->m_busy && (mpt->m_power_level > level)) {
2020 		mutex_exit(&mpt->m_mutex);
2021 		return (DDI_FAILURE);
2022 	}
2023 
2024 	switch (level) {
2025 	case PM_LEVEL_D0:
2026 		NDBG11(("mptsas%d: turning power ON.", mpt->m_instance));
2027 		MPTSAS_POWER_ON(mpt);
2028 		/*
2029 		 * Wait up to 30 seconds for IOC to come out of reset.
2030 		 */
2031 		while (((ioc_status = ddi_get32(mpt->m_datap,
2032 		    &mpt->m_reg->Doorbell)) &
2033 		    MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_RESET) {
2034 			if (polls++ > 3000) {
2035 				break;
2036 			}
2037 			delay(drv_usectohz(10000));
2038 		}
2039 		/*
2040 		 * If IOC is not in operational state, try to hard reset it.
2041 		 */
2042 		if ((ioc_status & MPI2_IOC_STATE_MASK) !=
2043 		    MPI2_IOC_STATE_OPERATIONAL) {
2044 			if (mptsas_restart_ioc(mpt) == DDI_FAILURE) {
2045 				mptsas_log(mpt, CE_WARN,
2046 				    "mptsas_power: hard reset failed");
2047 				mutex_exit(&mpt->m_mutex);
2048 				return (DDI_FAILURE);
2049 			}
2050 		}
2051 		mpt->m_power_level = PM_LEVEL_D0;
2052 		break;
2053 	case PM_LEVEL_D3:
2054 		NDBG11(("mptsas%d: turning power OFF.", mpt->m_instance));
2055 		MPTSAS_POWER_OFF(mpt);
2056 		break;
2057 	default:
2058 		mptsas_log(mpt, CE_WARN, "mptsas%d: unknown power level <%x>.",
2059 		    mpt->m_instance, level);
2060 		rval = DDI_FAILURE;
2061 		break;
2062 	}
2063 	mutex_exit(&mpt->m_mutex);
2064 	return (rval);
2065 }
2066 
2067 /*
2068  * Initialize configuration space and figure out which
2069  * chip and revison of the chip the mpt driver is using.
2070  */
2071 int
2072 mptsas_config_space_init(mptsas_t *mpt)
2073 {
2074 	ushort_t	caps_ptr, cap, cap_count;
2075 
2076 	NDBG0(("mptsas_config_space_init"));
2077 
2078 	mptsas_setup_cmd_reg(mpt);
2079 
2080 	/*
2081 	 * Get the chip device id:
2082 	 */
2083 	mpt->m_devid = pci_config_get16(mpt->m_config_handle, PCI_CONF_DEVID);
2084 
2085 	/*
2086 	 * Save the revision.
2087 	 */
2088 	mpt->m_revid = pci_config_get8(mpt->m_config_handle, PCI_CONF_REVID);
2089 
2090 	/*
2091 	 * Save the SubSystem Vendor and Device IDs
2092 	 */
2093 	mpt->m_svid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBVENID);
2094 	mpt->m_ssid = pci_config_get16(mpt->m_config_handle, PCI_CONF_SUBSYSID);
2095 
2096 	/*
2097 	 * Set the latency timer to 0x40 as specified by the upa -> pci
2098 	 * bridge chip design team.  This may be done by the sparc pci
2099 	 * bus nexus driver, but the driver should make sure the latency
2100 	 * timer is correct for performance reasons.
2101 	 */
2102 	pci_config_put8(mpt->m_config_handle, PCI_CONF_LATENCY_TIMER,
2103 	    MPTSAS_LATENCY_TIMER);
2104 
2105 	/*
2106 	 * Check if capabilities list is supported and if so,
2107 	 * get initial capabilities pointer and clear bits 0,1.
2108 	 */
2109 	if (pci_config_get16(mpt->m_config_handle, PCI_CONF_STAT)
2110 	    & PCI_STAT_CAP) {
2111 		caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle,
2112 		    PCI_CONF_CAP_PTR), 4);
2113 	} else {
2114 		caps_ptr = PCI_CAP_NEXT_PTR_NULL;
2115 	}
2116 
2117 	/*
2118 	 * Walk capabilities if supported.
2119 	 */
2120 	for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) {
2121 
2122 		/*
2123 		 * Check that we haven't exceeded the maximum number of
2124 		 * capabilities and that the pointer is in a valid range.
2125 		 */
2126 		if (++cap_count > 48) {
2127 			mptsas_log(mpt, CE_WARN,
2128 			    "too many device capabilities.\n");
2129 			return (FALSE);
2130 		}
2131 		if (caps_ptr < 64) {
2132 			mptsas_log(mpt, CE_WARN,
2133 			    "capabilities pointer 0x%x out of range.\n",
2134 			    caps_ptr);
2135 			return (FALSE);
2136 		}
2137 
2138 		/*
2139 		 * Get next capability and check that it is valid.
2140 		 * For now, we only support power management.
2141 		 */
2142 		cap = pci_config_get8(mpt->m_config_handle, caps_ptr);
2143 		switch (cap) {
2144 			case PCI_CAP_ID_PM:
2145 				mptsas_log(mpt, CE_NOTE,
2146 				    "?mptsas%d supports power management.\n",
2147 				    mpt->m_instance);
2148 				mpt->m_options |= MPTSAS_OPT_PM;
2149 
2150 				/* Save PMCSR offset */
2151 				mpt->m_pmcsr_offset = caps_ptr + PCI_PMCSR;
2152 				break;
2153 
2154 			/*
2155 			 * 0x5 is Message signaled interrupts and 0x7
2156 			 * is pci-x capable.  Both are unsupported for now
2157 			 * but supported by the 1030 chip so we don't
2158 			 * need to keep printing out the notice.
2159 			 * 0x10 is PCI-E support (1064E/1068E)
2160 			 * 0x11 is MSIX supported by the 1064/1068
2161 			 */
2162 			case 0x5:
2163 			case 0x7:
2164 			case 0x10:
2165 			case 0x11:
2166 				break;
2167 			default:
2168 				mptsas_log(mpt, CE_NOTE,
2169 				    "?mptsas%d unrecognized capability "
2170 				    "0x%x.\n", mpt->m_instance, cap);
2171 			break;
2172 		}
2173 
2174 		/*
2175 		 * Get next capabilities pointer and clear bits 0,1.
2176 		 */
2177 		caps_ptr = P2ALIGN(pci_config_get8(mpt->m_config_handle,
2178 		    (caps_ptr + PCI_CAP_NEXT_PTR)), 4);
2179 	}
2180 
2181 	return (TRUE);
2182 }
2183 
2184 static void
2185 mptsas_setup_cmd_reg(mptsas_t *mpt)
2186 {
2187 	ushort_t	cmdreg;
2188 
2189 	/*
2190 	 * Set the command register to the needed values.
2191 	 */
2192 	cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM);
2193 	cmdreg |= (PCI_COMM_ME | PCI_COMM_SERR_ENABLE |
2194 	    PCI_COMM_PARITY_DETECT | PCI_COMM_MAE);
2195 	cmdreg &= ~PCI_COMM_IO;
2196 	pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg);
2197 }
2198 
2199 static void
2200 mptsas_disable_bus_master(mptsas_t *mpt)
2201 {
2202 	ushort_t	cmdreg;
2203 
2204 	/*
2205 	 * Clear the master enable bit in the PCI command register.
2206 	 * This prevents any bus mastering activity like DMA.
2207 	 */
2208 	cmdreg = pci_config_get16(mpt->m_config_handle, PCI_CONF_COMM);
2209 	cmdreg &= ~PCI_COMM_ME;
2210 	pci_config_put16(mpt->m_config_handle, PCI_CONF_COMM, cmdreg);
2211 }
2212 
2213 int
2214 mptsas_dma_alloc(mptsas_t *mpt, mptsas_dma_alloc_state_t *dma_statep)
2215 {
2216 	ddi_dma_attr_t	attrs;
2217 	uint_t		ncookie;
2218 	size_t		alloc_len;
2219 
2220 	attrs = mpt->m_io_dma_attr;
2221 	attrs.dma_attr_sgllen = 1;
2222 
2223 	ASSERT(dma_statep != NULL);
2224 
2225 	if (ddi_dma_alloc_handle(mpt->m_dip, &attrs,
2226 	    DDI_DMA_SLEEP, NULL, &dma_statep->handle) != DDI_SUCCESS) {
2227 		mptsas_log(mpt, CE_WARN,
2228 		    "unable to allocate dma handle.");
2229 		return (DDI_FAILURE);
2230 	}
2231 
2232 	if (ddi_dma_mem_alloc(dma_statep->handle, dma_statep->size,
2233 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
2234 	    &dma_statep->memp, &alloc_len, &dma_statep->accessp) !=
2235 	    DDI_SUCCESS) {
2236 		ddi_dma_free_handle(&dma_statep->handle);
2237 		dma_statep->handle = NULL;
2238 		mptsas_log(mpt, CE_WARN,
2239 		    "unable to allocate memory for dma xfer.");
2240 		return (DDI_FAILURE);
2241 	}
2242 
2243 	if (ddi_dma_addr_bind_handle(dma_statep->handle, NULL, dma_statep->memp,
2244 	    alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2245 	    NULL, &dma_statep->cookie, &ncookie) != DDI_DMA_MAPPED) {
2246 		ddi_dma_mem_free(&dma_statep->accessp);
2247 		dma_statep->accessp = NULL;
2248 		ddi_dma_free_handle(&dma_statep->handle);
2249 		dma_statep->handle = NULL;
2250 		mptsas_log(mpt, CE_WARN, "unable to bind DMA resources.");
2251 		return (DDI_FAILURE);
2252 	}
2253 	return (DDI_SUCCESS);
2254 }
2255 
2256 void
2257 mptsas_dma_free(mptsas_dma_alloc_state_t *dma_statep)
2258 {
2259 	ASSERT(dma_statep != NULL);
2260 	if (dma_statep->handle != NULL) {
2261 		(void) ddi_dma_unbind_handle(dma_statep->handle);
2262 		(void) ddi_dma_mem_free(&dma_statep->accessp);
2263 		ddi_dma_free_handle(&dma_statep->handle);
2264 	}
2265 }
2266 
2267 int
2268 mptsas_do_dma(mptsas_t *mpt, uint32_t size, int var, int (*callback)())
2269 {
2270 	ddi_dma_attr_t		attrs;
2271 	ddi_dma_handle_t	dma_handle;
2272 	caddr_t			memp;
2273 	uint_t			ncookie;
2274 	ddi_dma_cookie_t	cookie;
2275 	ddi_acc_handle_t	accessp;
2276 	size_t			alloc_len;
2277 	int			rval;
2278 
2279 	ASSERT(mutex_owned(&mpt->m_mutex));
2280 
2281 	attrs = mpt->m_msg_dma_attr;
2282 	attrs.dma_attr_sgllen = 1;
2283 	attrs.dma_attr_granular = size;
2284 
2285 	if (ddi_dma_alloc_handle(mpt->m_dip, &attrs,
2286 	    DDI_DMA_SLEEP, NULL, &dma_handle) != DDI_SUCCESS) {
2287 		mptsas_log(mpt, CE_WARN,
2288 		    "unable to allocate dma handle.");
2289 		return (DDI_FAILURE);
2290 	}
2291 
2292 	if (ddi_dma_mem_alloc(dma_handle, size,
2293 	    &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
2294 	    &memp, &alloc_len, &accessp) != DDI_SUCCESS) {
2295 		ddi_dma_free_handle(&dma_handle);
2296 		mptsas_log(mpt, CE_WARN,
2297 		    "unable to allocate request structure.");
2298 		return (DDI_FAILURE);
2299 	}
2300 
2301 	if (ddi_dma_addr_bind_handle(dma_handle, NULL, memp,
2302 	    alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2303 	    NULL, &cookie, &ncookie) != DDI_DMA_MAPPED) {
2304 		(void) ddi_dma_mem_free(&accessp);
2305 		ddi_dma_free_handle(&dma_handle);
2306 		mptsas_log(mpt, CE_WARN, "unable to bind DMA resources.");
2307 		return (DDI_FAILURE);
2308 	}
2309 
2310 	rval = (*callback) (mpt, memp, var, accessp);
2311 
2312 	if ((mptsas_check_dma_handle(dma_handle) != DDI_SUCCESS) ||
2313 	    (mptsas_check_acc_handle(accessp) != DDI_SUCCESS)) {
2314 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
2315 		rval = DDI_FAILURE;
2316 	}
2317 
2318 	if (dma_handle != NULL) {
2319 		(void) ddi_dma_unbind_handle(dma_handle);
2320 		(void) ddi_dma_mem_free(&accessp);
2321 		ddi_dma_free_handle(&dma_handle);
2322 	}
2323 
2324 	return (rval);
2325 
2326 }
2327 
2328 static int
2329 mptsas_alloc_request_frames(mptsas_t *mpt)
2330 {
2331 	ddi_dma_attr_t		frame_dma_attrs;
2332 	caddr_t			memp;
2333 	uint_t			ncookie;
2334 	ddi_dma_cookie_t	cookie;
2335 	size_t			alloc_len;
2336 	size_t			mem_size;
2337 
2338 	/*
2339 	 * The size of the request frame pool is:
2340 	 *   Number of Request Frames * Request Frame Size
2341 	 */
2342 	mem_size = mpt->m_max_requests * mpt->m_req_frame_size;
2343 
2344 	/*
2345 	 * set the DMA attributes.  System Request Message Frames must be
2346 	 * aligned on a 16-byte boundry.
2347 	 */
2348 	frame_dma_attrs = mpt->m_msg_dma_attr;
2349 	frame_dma_attrs.dma_attr_align = 16;
2350 	frame_dma_attrs.dma_attr_sgllen = 1;
2351 
2352 	/*
2353 	 * allocate the request frame pool.
2354 	 */
2355 	if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attrs,
2356 	    DDI_DMA_SLEEP, NULL, &mpt->m_dma_req_frame_hdl) != DDI_SUCCESS) {
2357 		mptsas_log(mpt, CE_WARN,
2358 		    "Unable to allocate dma handle.");
2359 		return (DDI_FAILURE);
2360 	}
2361 
2362 	if (ddi_dma_mem_alloc(mpt->m_dma_req_frame_hdl,
2363 	    mem_size, &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2364 	    NULL, (caddr_t *)&memp, &alloc_len, &mpt->m_acc_req_frame_hdl)
2365 	    != DDI_SUCCESS) {
2366 		ddi_dma_free_handle(&mpt->m_dma_req_frame_hdl);
2367 		mpt->m_dma_req_frame_hdl = NULL;
2368 		mptsas_log(mpt, CE_WARN,
2369 		    "Unable to allocate request frames.");
2370 		return (DDI_FAILURE);
2371 	}
2372 
2373 	if (ddi_dma_addr_bind_handle(mpt->m_dma_req_frame_hdl, NULL,
2374 	    memp, alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2375 	    DDI_DMA_SLEEP, NULL, &cookie, &ncookie) != DDI_DMA_MAPPED) {
2376 		(void) ddi_dma_mem_free(&mpt->m_acc_req_frame_hdl);
2377 		ddi_dma_free_handle(&mpt->m_dma_req_frame_hdl);
2378 		mpt->m_dma_req_frame_hdl = NULL;
2379 		mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources.");
2380 		return (DDI_FAILURE);
2381 	}
2382 
2383 	/*
2384 	 * Store the request frame memory address.  This chip uses this
2385 	 * address to dma to and from the driver's frame.  The second
2386 	 * address is the address mpt uses to fill in the frame.
2387 	 */
2388 	mpt->m_req_frame_dma_addr = cookie.dmac_laddress;
2389 	mpt->m_req_frame = memp;
2390 
2391 	/*
2392 	 * Clear the request frame pool.
2393 	 */
2394 	bzero(mpt->m_req_frame, alloc_len);
2395 
2396 	return (DDI_SUCCESS);
2397 }
2398 
2399 static int
2400 mptsas_alloc_reply_frames(mptsas_t *mpt)
2401 {
2402 	ddi_dma_attr_t		frame_dma_attrs;
2403 	caddr_t			memp;
2404 	uint_t			ncookie;
2405 	ddi_dma_cookie_t	cookie;
2406 	size_t			alloc_len;
2407 	size_t			mem_size;
2408 
2409 	/*
2410 	 * The size of the reply frame pool is:
2411 	 *   Number of Reply Frames * Reply Frame Size
2412 	 */
2413 	mem_size = mpt->m_max_replies * mpt->m_reply_frame_size;
2414 
2415 	/*
2416 	 * set the DMA attributes.   System Reply Message Frames must be
2417 	 * aligned on a 4-byte boundry.  This is the default.
2418 	 */
2419 	frame_dma_attrs = mpt->m_msg_dma_attr;
2420 	frame_dma_attrs.dma_attr_sgllen = 1;
2421 
2422 	/*
2423 	 * allocate the reply frame pool
2424 	 */
2425 	if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attrs,
2426 	    DDI_DMA_SLEEP, NULL, &mpt->m_dma_reply_frame_hdl) != DDI_SUCCESS) {
2427 		mptsas_log(mpt, CE_WARN,
2428 		    "Unable to allocate dma handle.");
2429 		return (DDI_FAILURE);
2430 	}
2431 
2432 	if (ddi_dma_mem_alloc(mpt->m_dma_reply_frame_hdl,
2433 	    mem_size, &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2434 	    NULL, (caddr_t *)&memp, &alloc_len, &mpt->m_acc_reply_frame_hdl)
2435 	    != DDI_SUCCESS) {
2436 		ddi_dma_free_handle(&mpt->m_dma_reply_frame_hdl);
2437 		mpt->m_dma_reply_frame_hdl = NULL;
2438 		mptsas_log(mpt, CE_WARN,
2439 		    "Unable to allocate reply frames.");
2440 		return (DDI_FAILURE);
2441 	}
2442 
2443 	if (ddi_dma_addr_bind_handle(mpt->m_dma_reply_frame_hdl, NULL,
2444 	    memp, alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2445 	    DDI_DMA_SLEEP, NULL, &cookie, &ncookie) != DDI_DMA_MAPPED) {
2446 		(void) ddi_dma_mem_free(&mpt->m_acc_reply_frame_hdl);
2447 		ddi_dma_free_handle(&mpt->m_dma_reply_frame_hdl);
2448 		mpt->m_dma_reply_frame_hdl = NULL;
2449 		mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources.");
2450 		return (DDI_FAILURE);
2451 	}
2452 
2453 	/*
2454 	 * Store the reply frame memory address.  This chip uses this
2455 	 * address to dma to and from the driver's frame.  The second
2456 	 * address is the address mpt uses to process the frame.
2457 	 */
2458 	mpt->m_reply_frame_dma_addr = cookie.dmac_laddress;
2459 	mpt->m_reply_frame = memp;
2460 
2461 	/*
2462 	 * Clear the reply frame pool.
2463 	 */
2464 	bzero(mpt->m_reply_frame, alloc_len);
2465 
2466 	return (DDI_SUCCESS);
2467 }
2468 
2469 static int
2470 mptsas_alloc_free_queue(mptsas_t *mpt)
2471 {
2472 	ddi_dma_attr_t		frame_dma_attrs;
2473 	caddr_t			memp;
2474 	uint_t			ncookie;
2475 	ddi_dma_cookie_t	cookie;
2476 	size_t			alloc_len;
2477 	size_t			mem_size;
2478 
2479 	/*
2480 	 * The reply free queue size is:
2481 	 *   Reply Free Queue Depth * 4
2482 	 * The "4" is the size of one 32 bit address (low part of 64-bit
2483 	 *   address)
2484 	 */
2485 	mem_size = mpt->m_free_queue_depth * 4;
2486 
2487 	/*
2488 	 * set the DMA attributes  The Reply Free Queue must be aligned on a
2489 	 * 16-byte boundry.
2490 	 */
2491 	frame_dma_attrs = mpt->m_msg_dma_attr;
2492 	frame_dma_attrs.dma_attr_align = 16;
2493 	frame_dma_attrs.dma_attr_sgllen = 1;
2494 
2495 	/*
2496 	 * allocate the reply free queue
2497 	 */
2498 	if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attrs,
2499 	    DDI_DMA_SLEEP, NULL, &mpt->m_dma_free_queue_hdl) != DDI_SUCCESS) {
2500 		mptsas_log(mpt, CE_WARN,
2501 		    "Unable to allocate dma handle.");
2502 		return (DDI_FAILURE);
2503 	}
2504 
2505 	if (ddi_dma_mem_alloc(mpt->m_dma_free_queue_hdl,
2506 	    mem_size, &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2507 	    NULL, (caddr_t *)&memp, &alloc_len, &mpt->m_acc_free_queue_hdl)
2508 	    != DDI_SUCCESS) {
2509 		ddi_dma_free_handle(&mpt->m_dma_free_queue_hdl);
2510 		mpt->m_dma_free_queue_hdl = NULL;
2511 		mptsas_log(mpt, CE_WARN,
2512 		    "Unable to allocate free queue.");
2513 		return (DDI_FAILURE);
2514 	}
2515 
2516 	if (ddi_dma_addr_bind_handle(mpt->m_dma_free_queue_hdl, NULL,
2517 	    memp, alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2518 	    DDI_DMA_SLEEP, NULL, &cookie, &ncookie) != DDI_DMA_MAPPED) {
2519 		(void) ddi_dma_mem_free(&mpt->m_acc_free_queue_hdl);
2520 		ddi_dma_free_handle(&mpt->m_dma_free_queue_hdl);
2521 		mpt->m_dma_free_queue_hdl = NULL;
2522 		mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources.");
2523 		return (DDI_FAILURE);
2524 	}
2525 
2526 	/*
2527 	 * Store the reply free queue memory address.  This chip uses this
2528 	 * address to read from the reply free queue.  The second address
2529 	 * is the address mpt uses to manage the queue.
2530 	 */
2531 	mpt->m_free_queue_dma_addr = cookie.dmac_laddress;
2532 	mpt->m_free_queue = memp;
2533 
2534 	/*
2535 	 * Clear the reply free queue memory.
2536 	 */
2537 	bzero(mpt->m_free_queue, alloc_len);
2538 
2539 	return (DDI_SUCCESS);
2540 }
2541 
2542 static int
2543 mptsas_alloc_post_queue(mptsas_t *mpt)
2544 {
2545 	ddi_dma_attr_t		frame_dma_attrs;
2546 	caddr_t			memp;
2547 	uint_t			ncookie;
2548 	ddi_dma_cookie_t	cookie;
2549 	size_t			alloc_len;
2550 	size_t			mem_size;
2551 
2552 	/*
2553 	 * The reply descriptor post queue size is:
2554 	 *   Reply Descriptor Post Queue Depth * 8
2555 	 * The "8" is the size of each descriptor (8 bytes or 64 bits).
2556 	 */
2557 	mem_size = mpt->m_post_queue_depth * 8;
2558 
2559 	/*
2560 	 * set the DMA attributes.  The Reply Descriptor Post Queue must be
2561 	 * aligned on a 16-byte boundry.
2562 	 */
2563 	frame_dma_attrs = mpt->m_msg_dma_attr;
2564 	frame_dma_attrs.dma_attr_align = 16;
2565 	frame_dma_attrs.dma_attr_sgllen = 1;
2566 
2567 	/*
2568 	 * allocate the reply post queue
2569 	 */
2570 	if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attrs,
2571 	    DDI_DMA_SLEEP, NULL, &mpt->m_dma_post_queue_hdl) != DDI_SUCCESS) {
2572 		mptsas_log(mpt, CE_WARN,
2573 		    "Unable to allocate dma handle.");
2574 		return (DDI_FAILURE);
2575 	}
2576 
2577 	if (ddi_dma_mem_alloc(mpt->m_dma_post_queue_hdl,
2578 	    mem_size, &mpt->m_dev_acc_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2579 	    NULL, (caddr_t *)&memp, &alloc_len, &mpt->m_acc_post_queue_hdl)
2580 	    != DDI_SUCCESS) {
2581 		ddi_dma_free_handle(&mpt->m_dma_post_queue_hdl);
2582 		mpt->m_dma_post_queue_hdl = NULL;
2583 		mptsas_log(mpt, CE_WARN,
2584 		    "Unable to allocate post queue.");
2585 		return (DDI_FAILURE);
2586 	}
2587 
2588 	if (ddi_dma_addr_bind_handle(mpt->m_dma_post_queue_hdl, NULL,
2589 	    memp, alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2590 	    DDI_DMA_SLEEP, NULL, &cookie, &ncookie) != DDI_DMA_MAPPED) {
2591 		(void) ddi_dma_mem_free(&mpt->m_acc_post_queue_hdl);
2592 		ddi_dma_free_handle(&mpt->m_dma_post_queue_hdl);
2593 		mpt->m_dma_post_queue_hdl = NULL;
2594 		mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources.");
2595 		return (DDI_FAILURE);
2596 	}
2597 
2598 	/*
2599 	 * Store the reply descriptor post queue memory address.  This chip
2600 	 * uses this address to write to the reply descriptor post queue.  The
2601 	 * second address is the address mpt uses to manage the queue.
2602 	 */
2603 	mpt->m_post_queue_dma_addr = cookie.dmac_laddress;
2604 	mpt->m_post_queue = memp;
2605 
2606 	/*
2607 	 * Clear the reply post queue memory.
2608 	 */
2609 	bzero(mpt->m_post_queue, alloc_len);
2610 
2611 	return (DDI_SUCCESS);
2612 }
2613 
2614 static int
2615 mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd)
2616 {
2617 	mptsas_cache_frames_t	*frames = NULL;
2618 	if (cmd->cmd_extra_frames == NULL) {
2619 		frames = kmem_cache_alloc(mpt->m_cache_frames, KM_NOSLEEP);
2620 		if (frames == NULL) {
2621 			return (DDI_FAILURE);
2622 		}
2623 		cmd->cmd_extra_frames = frames;
2624 	}
2625 	return (DDI_SUCCESS);
2626 }
2627 
2628 static void
2629 mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd)
2630 {
2631 	if (cmd->cmd_extra_frames) {
2632 		kmem_cache_free(mpt->m_cache_frames,
2633 		    (void *)cmd->cmd_extra_frames);
2634 		cmd->cmd_extra_frames = NULL;
2635 	}
2636 }
2637 
2638 static void
2639 mptsas_cfg_fini(mptsas_t *mpt)
2640 {
2641 	NDBG0(("mptsas_cfg_fini"));
2642 	ddi_regs_map_free(&mpt->m_datap);
2643 }
2644 
2645 static void
2646 mptsas_hba_fini(mptsas_t *mpt)
2647 {
2648 	NDBG0(("mptsas_hba_fini"));
2649 
2650 	/*
2651 	 * Disable any bus mastering ability (i.e: DMA) prior to freeing any
2652 	 * allocated DMA resources.
2653 	 */
2654 	if (mpt->m_config_handle != NULL)
2655 		mptsas_disable_bus_master(mpt);
2656 
2657 	/*
2658 	 * Free up any allocated memory
2659 	 */
2660 	if (mpt->m_dma_req_frame_hdl != NULL) {
2661 		(void) ddi_dma_unbind_handle(mpt->m_dma_req_frame_hdl);
2662 		ddi_dma_mem_free(&mpt->m_acc_req_frame_hdl);
2663 		ddi_dma_free_handle(&mpt->m_dma_req_frame_hdl);
2664 		mpt->m_dma_req_frame_hdl = NULL;
2665 	}
2666 
2667 	if (mpt->m_dma_reply_frame_hdl != NULL) {
2668 		(void) ddi_dma_unbind_handle(mpt->m_dma_reply_frame_hdl);
2669 		ddi_dma_mem_free(&mpt->m_acc_reply_frame_hdl);
2670 		ddi_dma_free_handle(&mpt->m_dma_reply_frame_hdl);
2671 		mpt->m_dma_reply_frame_hdl = NULL;
2672 	}
2673 
2674 	if (mpt->m_dma_free_queue_hdl != NULL) {
2675 		(void) ddi_dma_unbind_handle(mpt->m_dma_free_queue_hdl);
2676 		ddi_dma_mem_free(&mpt->m_acc_free_queue_hdl);
2677 		ddi_dma_free_handle(&mpt->m_dma_free_queue_hdl);
2678 		mpt->m_dma_free_queue_hdl = NULL;
2679 	}
2680 
2681 	if (mpt->m_dma_post_queue_hdl != NULL) {
2682 		(void) ddi_dma_unbind_handle(mpt->m_dma_post_queue_hdl);
2683 		ddi_dma_mem_free(&mpt->m_acc_post_queue_hdl);
2684 		ddi_dma_free_handle(&mpt->m_dma_post_queue_hdl);
2685 		mpt->m_dma_post_queue_hdl = NULL;
2686 	}
2687 
2688 	if (mpt->m_replyh_args != NULL) {
2689 		kmem_free(mpt->m_replyh_args, sizeof (m_replyh_arg_t)
2690 		    * mpt->m_max_replies);
2691 	}
2692 }
2693 
2694 static int
2695 mptsas_name_child(dev_info_t *lun_dip, char *name, int len)
2696 {
2697 	int		lun = 0;
2698 	char		*sas_wwn = NULL;
2699 	int		phynum = -1;
2700 	int		reallen = 0;
2701 
2702 	/* Get the target num */
2703 	lun = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip, DDI_PROP_DONTPASS,
2704 	    LUN_PROP, 0);
2705 
2706 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, lun_dip, DDI_PROP_DONTPASS,
2707 	    SCSI_ADDR_PROP_TARGET_PORT, &sas_wwn) == DDI_PROP_SUCCESS) {
2708 		/*
2709 		 * Stick in the address of the form "wWWN,LUN"
2710 		 */
2711 		reallen = snprintf(name, len, "w%s,%x", sas_wwn, lun);
2712 		ddi_prop_free(sas_wwn);
2713 	} else if ((phynum = ddi_prop_get_int(DDI_DEV_T_ANY, lun_dip,
2714 	    DDI_PROP_DONTPASS, "sata-phy", -1)) != -1) {
2715 		/*
2716 		 * Stick in the address of form "pPHY,LUN"
2717 		 */
2718 		reallen = snprintf(name, len, "p%x,%x", phynum, lun);
2719 	} else {
2720 		return (DDI_FAILURE);
2721 	}
2722 
2723 	ASSERT(reallen < len);
2724 	if (reallen >= len) {
2725 		mptsas_log(0, CE_WARN, "!mptsas_get_name: name parameter "
2726 		    "length too small, it needs to be %d bytes", reallen + 1);
2727 	}
2728 	return (DDI_SUCCESS);
2729 }
2730 
2731 /*
2732  * tran_tgt_init(9E) - target device instance initialization
2733  */
2734 static int
2735 mptsas_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
2736     scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
2737 {
2738 #ifndef __lock_lint
2739 	_NOTE(ARGUNUSED(hba_tran))
2740 #endif
2741 
2742 	/*
2743 	 * At this point, the scsi_device structure already exists
2744 	 * and has been initialized.
2745 	 *
2746 	 * Use this function to allocate target-private data structures,
2747 	 * if needed by this HBA.  Add revised flow-control and queue
2748 	 * properties for child here, if desired and if you can tell they
2749 	 * support tagged queueing by now.
2750 	 */
2751 	mptsas_t		*mpt;
2752 	int			lun = sd->sd_address.a_lun;
2753 	mdi_pathinfo_t		*pip = NULL;
2754 	mptsas_tgt_private_t	*tgt_private = NULL;
2755 	mptsas_target_t		*ptgt = NULL;
2756 	char			*psas_wwn = NULL;
2757 	int			phymask = 0;
2758 	uint64_t		sas_wwn = 0;
2759 	mpt = SDEV2MPT(sd);
2760 
2761 	ASSERT(scsi_hba_iport_unit_address(hba_dip) != 0);
2762 
2763 	NDBG0(("mptsas_scsi_tgt_init: hbadip=0x%p tgtdip=0x%p lun=%d",
2764 	    (void *)hba_dip, (void *)tgt_dip, lun));
2765 
2766 	if (ndi_dev_is_persistent_node(tgt_dip) == 0) {
2767 		(void) ndi_merge_node(tgt_dip, mptsas_name_child);
2768 		ddi_set_name_addr(tgt_dip, NULL);
2769 		return (DDI_FAILURE);
2770 	}
2771 	/*
2772 	 * phymask is 0 means the virtual port for RAID
2773 	 */
2774 	phymask = ddi_prop_get_int(DDI_DEV_T_ANY, hba_dip, 0,
2775 	    "phymask", 0);
2776 	if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
2777 		if ((pip = (void *)(sd->sd_private)) == NULL) {
2778 			/*
2779 			 * Very bad news if this occurs. Somehow scsi_vhci has
2780 			 * lost the pathinfo node for this target.
2781 			 */
2782 			return (DDI_NOT_WELL_FORMED);
2783 		}
2784 
2785 		if (mdi_prop_lookup_int(pip, LUN_PROP, &lun) !=
2786 		    DDI_PROP_SUCCESS) {
2787 			mptsas_log(mpt, CE_WARN, "Get lun property failed\n");
2788 			return (DDI_FAILURE);
2789 		}
2790 
2791 		if (mdi_prop_lookup_string(pip, SCSI_ADDR_PROP_TARGET_PORT,
2792 		    &psas_wwn) == MDI_SUCCESS) {
2793 			if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) {
2794 				sas_wwn = 0;
2795 			}
2796 			(void) mdi_prop_free(psas_wwn);
2797 		}
2798 	} else {
2799 		lun = ddi_prop_get_int(DDI_DEV_T_ANY, tgt_dip,
2800 		    DDI_PROP_DONTPASS, LUN_PROP, 0);
2801 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, tgt_dip,
2802 		    DDI_PROP_DONTPASS, SCSI_ADDR_PROP_TARGET_PORT, &psas_wwn) ==
2803 		    DDI_PROP_SUCCESS) {
2804 			if (scsi_wwnstr_to_wwn(psas_wwn, &sas_wwn)) {
2805 				sas_wwn = 0;
2806 			}
2807 			ddi_prop_free(psas_wwn);
2808 		} else {
2809 			sas_wwn = 0;
2810 		}
2811 	}
2812 	ASSERT((sas_wwn != 0) || (phymask != 0));
2813 	mutex_enter(&mpt->m_mutex);
2814 	ptgt = mptsas_hash_search(&mpt->m_active->m_tgttbl, sas_wwn, phymask);
2815 	mutex_exit(&mpt->m_mutex);
2816 	if (ptgt == NULL) {
2817 		mptsas_log(mpt, CE_WARN, "!tgt_init: target doesn't exist or "
2818 		    "gone already! phymask:%x, saswwn %"PRIx64, phymask,
2819 		    sas_wwn);
2820 		return (DDI_FAILURE);
2821 	}
2822 	if (hba_tran->tran_tgt_private == NULL) {
2823 		tgt_private = kmem_zalloc(sizeof (mptsas_tgt_private_t),
2824 		    KM_SLEEP);
2825 		tgt_private->t_lun = lun;
2826 		tgt_private->t_private = ptgt;
2827 		hba_tran->tran_tgt_private = tgt_private;
2828 	}
2829 
2830 	if (mdi_component_is_client(tgt_dip, NULL) == MDI_SUCCESS) {
2831 		return (DDI_SUCCESS);
2832 	}
2833 	mutex_enter(&mpt->m_mutex);
2834 
2835 	if (ptgt->m_deviceinfo &
2836 	    (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
2837 	    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
2838 		uchar_t *inq89 = NULL;
2839 		int inq89_len = 0x238;
2840 		int reallen = 0;
2841 		int rval = 0;
2842 		struct sata_id *sid = NULL;
2843 		char model[SATA_ID_MODEL_LEN + 1];
2844 		char fw[SATA_ID_FW_LEN + 1];
2845 		char *vid, *pid;
2846 		int i;
2847 
2848 		mutex_exit(&mpt->m_mutex);
2849 		/*
2850 		 * According SCSI/ATA Translation -2 (SAT-2) revision 01a
2851 		 * chapter 12.4.2 VPD page 89h includes 512 bytes ATA IDENTIFY
2852 		 * DEVICE data or ATA IDENTIFY PACKET DEVICE data.
2853 		 */
2854 		inq89 = kmem_zalloc(inq89_len, KM_SLEEP);
2855 		rval = mptsas_inquiry(mpt, ptgt, 0, 0x89,
2856 		    inq89, inq89_len, &reallen, 1);
2857 
2858 		if (rval != 0) {
2859 			if (inq89 != NULL) {
2860 				kmem_free(inq89, inq89_len);
2861 			}
2862 
2863 			mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
2864 			    "0x89 for SATA target:%x failed!", ptgt->m_devhdl);
2865 			return (DDI_SUCCESS);
2866 		}
2867 		sid = (void *)(&inq89[60]);
2868 
2869 		swab(sid->ai_model, model, SATA_ID_MODEL_LEN);
2870 		swab(sid->ai_fw, fw, SATA_ID_FW_LEN);
2871 
2872 		model[SATA_ID_MODEL_LEN] = 0;
2873 		fw[SATA_ID_FW_LEN] = 0;
2874 
2875 		/*
2876 		 * split model into into vid/pid
2877 		 */
2878 		for (i = 0, pid = model; i < SATA_ID_MODEL_LEN; i++, pid++)
2879 			if ((*pid == ' ') || (*pid == '\t'))
2880 				break;
2881 		if (i < SATA_ID_MODEL_LEN) {
2882 			vid = model;
2883 			/*
2884 			 * terminate vid, establish pid
2885 			 */
2886 			*pid++ = 0;
2887 		} else {
2888 			/*
2889 			 * vid will stay "ATA     ", the rule is same
2890 			 * as sata framework implementation.
2891 			 */
2892 			vid = NULL;
2893 			/*
2894 			 * model is all pid
2895 			 */
2896 			pid = model;
2897 		}
2898 
2899 		/*
2900 		 * override SCSA "inquiry-*" properties
2901 		 */
2902 		if (vid)
2903 			(void) scsi_device_prop_update_inqstring(sd,
2904 			    INQUIRY_VENDOR_ID, vid, strlen(vid));
2905 		if (pid)
2906 			(void) scsi_device_prop_update_inqstring(sd,
2907 			    INQUIRY_PRODUCT_ID, pid, strlen(pid));
2908 		(void) scsi_device_prop_update_inqstring(sd,
2909 		    INQUIRY_REVISION_ID, fw, strlen(fw));
2910 
2911 		if (inq89 != NULL) {
2912 			kmem_free(inq89, inq89_len);
2913 		}
2914 	} else {
2915 		mutex_exit(&mpt->m_mutex);
2916 	}
2917 
2918 	return (DDI_SUCCESS);
2919 }
2920 /*
2921  * tran_tgt_free(9E) - target device instance deallocation
2922  */
2923 static void
2924 mptsas_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
2925     scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
2926 {
2927 #ifndef __lock_lint
2928 	_NOTE(ARGUNUSED(hba_dip, tgt_dip, hba_tran, sd))
2929 #endif
2930 
2931 	mptsas_tgt_private_t	*tgt_private = hba_tran->tran_tgt_private;
2932 
2933 	if (tgt_private != NULL) {
2934 		kmem_free(tgt_private, sizeof (mptsas_tgt_private_t));
2935 		hba_tran->tran_tgt_private = NULL;
2936 	}
2937 }
2938 
2939 /*
2940  * scsi_pkt handling
2941  *
2942  * Visible to the external world via the transport structure.
2943  */
2944 
2945 /*
2946  * Notes:
2947  *	- transport the command to the addressed SCSI target/lun device
2948  *	- normal operation is to schedule the command to be transported,
2949  *	  and return TRAN_ACCEPT if this is successful.
2950  *	- if NO_INTR, tran_start must poll device for command completion
2951  */
2952 static int
2953 mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt)
2954 {
2955 #ifndef __lock_lint
2956 	_NOTE(ARGUNUSED(ap))
2957 #endif
2958 	mptsas_t	*mpt = PKT2MPT(pkt);
2959 	mptsas_cmd_t	*cmd = PKT2CMD(pkt);
2960 	int		rval;
2961 	mptsas_target_t	*ptgt = cmd->cmd_tgt_addr;
2962 
2963 	NDBG1(("mptsas_scsi_start: pkt=0x%p", (void *)pkt));
2964 	ASSERT(ptgt);
2965 	if (ptgt == NULL)
2966 		return (TRAN_FATAL_ERROR);
2967 
2968 	/*
2969 	 * prepare the pkt before taking mutex.
2970 	 */
2971 	rval = mptsas_prepare_pkt(cmd);
2972 	if (rval != TRAN_ACCEPT) {
2973 		return (rval);
2974 	}
2975 
2976 	/*
2977 	 * Send the command to target/lun, however your HBA requires it.
2978 	 * If busy, return TRAN_BUSY; if there's some other formatting error
2979 	 * in the packet, return TRAN_BADPKT; otherwise, fall through to the
2980 	 * return of TRAN_ACCEPT.
2981 	 *
2982 	 * Remember that access to shared resources, including the mptsas_t
2983 	 * data structure and the HBA hardware registers, must be protected
2984 	 * with mutexes, here and everywhere.
2985 	 *
2986 	 * Also remember that at interrupt time, you'll get an argument
2987 	 * to the interrupt handler which is a pointer to your mptsas_t
2988 	 * structure; you'll have to remember which commands are outstanding
2989 	 * and which scsi_pkt is the currently-running command so the
2990 	 * interrupt handler can refer to the pkt to set completion
2991 	 * status, call the target driver back through pkt_comp, etc.
2992 	 *
2993 	 * If the instance lock is held by other thread, don't spin to wait
2994 	 * for it. Instead, queue the cmd and next time when the instance lock
2995 	 * is not held, accept all the queued cmd. A extra tx_waitq is
2996 	 * introduced to protect the queue.
2997 	 *
2998 	 * The polled cmd will not be queud and accepted as usual.
2999 	 *
3000 	 * Under the tx_waitq mutex, record whether a thread is draining
3001 	 * the tx_waitq.  An IO requesting thread that finds the instance
3002 	 * mutex contended appends to the tx_waitq and while holding the
3003 	 * tx_wait mutex, if the draining flag is not set, sets it and then
3004 	 * proceeds to spin for the instance mutex. This scheme ensures that
3005 	 * the last cmd in a burst be processed.
3006 	 *
3007 	 * we enable this feature only when the helper threads are enabled,
3008 	 * at which we think the loads are heavy.
3009 	 *
3010 	 * per instance mutex m_tx_waitq_mutex is introduced to protect the
3011 	 * m_tx_waitqtail, m_tx_waitq, m_tx_draining.
3012 	 */
3013 
3014 	if (mpt->m_doneq_thread_n) {
3015 		if (mutex_tryenter(&mpt->m_mutex) != 0) {
3016 			rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
3017 			mutex_exit(&mpt->m_mutex);
3018 		} else if (cmd->cmd_pkt_flags & FLAG_NOINTR) {
3019 			mutex_enter(&mpt->m_mutex);
3020 			rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
3021 			mutex_exit(&mpt->m_mutex);
3022 		} else {
3023 			mutex_enter(&mpt->m_tx_waitq_mutex);
3024 			/*
3025 			 * ptgt->m_dr_flag is protected by m_mutex or
3026 			 * m_tx_waitq_mutex. In this case, m_tx_waitq_mutex
3027 			 * is acquired.
3028 			 */
3029 			if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
3030 				if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
3031 					/*
3032 					 * The command should be allowed to
3033 					 * retry by returning TRAN_BUSY to
3034 					 * to stall the I/O's which come from
3035 					 * scsi_vhci since the device/path is
3036 					 * in unstable state now.
3037 					 */
3038 					mutex_exit(&mpt->m_tx_waitq_mutex);
3039 					return (TRAN_BUSY);
3040 				} else {
3041 					/*
3042 					 * The device is offline, just fail the
3043 					 * command by returning
3044 					 * TRAN_FATAL_ERROR.
3045 					 */
3046 					mutex_exit(&mpt->m_tx_waitq_mutex);
3047 					return (TRAN_FATAL_ERROR);
3048 				}
3049 			}
3050 			if (mpt->m_tx_draining) {
3051 				cmd->cmd_flags |= CFLAG_TXQ;
3052 				*mpt->m_tx_waitqtail = cmd;
3053 				mpt->m_tx_waitqtail = &cmd->cmd_linkp;
3054 				mutex_exit(&mpt->m_tx_waitq_mutex);
3055 			} else { /* drain the queue */
3056 				mpt->m_tx_draining = 1;
3057 				mutex_exit(&mpt->m_tx_waitq_mutex);
3058 				mutex_enter(&mpt->m_mutex);
3059 				rval = mptsas_accept_txwq_and_pkt(mpt, cmd);
3060 				mutex_exit(&mpt->m_mutex);
3061 			}
3062 		}
3063 	} else {
3064 		mutex_enter(&mpt->m_mutex);
3065 		/*
3066 		 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex
3067 		 * in this case, m_mutex is acquired.
3068 		 */
3069 		if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
3070 			if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
3071 				/*
3072 				 * commands should be allowed to retry by
3073 				 * returning TRAN_BUSY to stall the I/O's
3074 				 * which come from scsi_vhci since the device/
3075 				 * path is in unstable state now.
3076 				 */
3077 				mutex_exit(&mpt->m_mutex);
3078 				return (TRAN_BUSY);
3079 			} else {
3080 				/*
3081 				 * The device is offline, just fail the
3082 				 * command by returning TRAN_FATAL_ERROR.
3083 				 */
3084 				mutex_exit(&mpt->m_mutex);
3085 				return (TRAN_FATAL_ERROR);
3086 			}
3087 		}
3088 		rval = mptsas_accept_pkt(mpt, cmd);
3089 		mutex_exit(&mpt->m_mutex);
3090 	}
3091 
3092 	return (rval);
3093 }
3094 
3095 /*
3096  * Accept all the queued cmds(if any) before accept the current one.
3097  */
3098 static int
3099 mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd)
3100 {
3101 	int rval;
3102 	mptsas_target_t	*ptgt = cmd->cmd_tgt_addr;
3103 
3104 	ASSERT(mutex_owned(&mpt->m_mutex));
3105 	/*
3106 	 * The call to mptsas_accept_tx_waitq() must always be performed
3107 	 * because that is where mpt->m_tx_draining is cleared.
3108 	 */
3109 	mutex_enter(&mpt->m_tx_waitq_mutex);
3110 	mptsas_accept_tx_waitq(mpt);
3111 	mutex_exit(&mpt->m_tx_waitq_mutex);
3112 	/*
3113 	 * ptgt->m_dr_flag is protected by m_mutex or m_tx_waitq_mutex
3114 	 * in this case, m_mutex is acquired.
3115 	 */
3116 	if (ptgt->m_dr_flag == MPTSAS_DR_INTRANSITION) {
3117 		if (cmd->cmd_pkt_flags & FLAG_NOQUEUE) {
3118 			/*
3119 			 * The command should be allowed to retry by returning
3120 			 * TRAN_BUSY to stall the I/O's which come from
3121 			 * scsi_vhci since the device/path is in unstable state
3122 			 * now.
3123 			 */
3124 			return (TRAN_BUSY);
3125 		} else {
3126 			/*
3127 			 * The device is offline, just fail the command by
3128 			 * return TRAN_FATAL_ERROR.
3129 			 */
3130 			return (TRAN_FATAL_ERROR);
3131 		}
3132 	}
3133 	rval = mptsas_accept_pkt(mpt, cmd);
3134 
3135 	return (rval);
3136 }
3137 
3138 static int
3139 mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *cmd)
3140 {
3141 	int		rval = TRAN_ACCEPT;
3142 	mptsas_target_t	*ptgt = cmd->cmd_tgt_addr;
3143 
3144 	NDBG1(("mptsas_accept_pkt: cmd=0x%p", (void *)cmd));
3145 
3146 	ASSERT(mutex_owned(&mpt->m_mutex));
3147 
3148 	if ((cmd->cmd_flags & CFLAG_PREPARED) == 0) {
3149 		rval = mptsas_prepare_pkt(cmd);
3150 		if (rval != TRAN_ACCEPT) {
3151 			cmd->cmd_flags &= ~CFLAG_TRANFLAG;
3152 			return (rval);
3153 		}
3154 	}
3155 
3156 	/*
3157 	 * reset the throttle if we were draining
3158 	 */
3159 	if ((ptgt->m_t_ncmds == 0) &&
3160 	    (ptgt->m_t_throttle == DRAIN_THROTTLE)) {
3161 		NDBG23(("reset throttle"));
3162 		ASSERT(ptgt->m_reset_delay == 0);
3163 		mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
3164 	}
3165 
3166 	/*
3167 	 * If device handle has already been invalidated, just
3168 	 * fail the command. In theory, command from scsi_vhci
3169 	 * client is impossible send down command with invalid
3170 	 * devhdl since devhdl is set after path offline, target
3171 	 * driver is not suppose to select a offlined path.
3172 	 */
3173 	if (ptgt->m_devhdl == MPTSAS_INVALID_DEVHDL) {
3174 		NDBG20(("rejecting command, it might because invalid devhdl "
3175 		    "request."));
3176 		mptsas_set_pkt_reason(mpt, cmd, CMD_DEV_GONE, STAT_TERMINATED);
3177 		if (cmd->cmd_flags & CFLAG_TXQ) {
3178 			mptsas_doneq_add(mpt, cmd);
3179 			mptsas_doneq_empty(mpt);
3180 			return (rval);
3181 		} else {
3182 			return (TRAN_FATAL_ERROR);
3183 		}
3184 	}
3185 	/*
3186 	 * The first case is the normal case.  mpt gets a command from the
3187 	 * target driver and starts it.
3188 	 * Since SMID 0 is reserved and the TM slot is reserved, the actual max
3189 	 * commands is m_max_requests - 2.
3190 	 */
3191 	if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) &&
3192 	    (ptgt->m_t_throttle > HOLD_THROTTLE) &&
3193 	    (ptgt->m_t_ncmds < ptgt->m_t_throttle) &&
3194 	    (ptgt->m_reset_delay == 0) &&
3195 	    (ptgt->m_t_nwait == 0) &&
3196 	    ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0)) {
3197 		if (mptsas_save_cmd(mpt, cmd) == TRUE) {
3198 			(void) mptsas_start_cmd(mpt, cmd);
3199 		} else {
3200 			mptsas_waitq_add(mpt, cmd);
3201 		}
3202 	} else {
3203 		/*
3204 		 * Add this pkt to the work queue
3205 		 */
3206 		mptsas_waitq_add(mpt, cmd);
3207 
3208 		if (cmd->cmd_pkt_flags & FLAG_NOINTR) {
3209 			(void) mptsas_poll(mpt, cmd, MPTSAS_POLL_TIME);
3210 
3211 			/*
3212 			 * Only flush the doneq if this is not a TM
3213 			 * cmd.  For TM cmds the flushing of the
3214 			 * doneq will be done in those routines.
3215 			 */
3216 			if ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
3217 				mptsas_doneq_empty(mpt);
3218 			}
3219 		}
3220 	}
3221 	return (rval);
3222 }
3223 
3224 int
3225 mptsas_save_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
3226 {
3227 	mptsas_slots_t	*slots;
3228 	int		slot;
3229 	mptsas_target_t	*ptgt = cmd->cmd_tgt_addr;
3230 
3231 	ASSERT(mutex_owned(&mpt->m_mutex));
3232 	slots = mpt->m_active;
3233 
3234 	/*
3235 	 * Account for reserved TM request slot and reserved SMID of 0.
3236 	 */
3237 	ASSERT(slots->m_n_slots == (mpt->m_max_requests - 2));
3238 
3239 	/*
3240 	 * m_tags is equivalent to the SMID when sending requests.  Since the
3241 	 * SMID cannot be 0, start out at one if rolling over past the size
3242 	 * of the request queue depth.  Also, don't use the last SMID, which is
3243 	 * reserved for TM requests.
3244 	 */
3245 	slot = (slots->m_tags)++;
3246 	if (slots->m_tags > slots->m_n_slots) {
3247 		slots->m_tags = 1;
3248 	}
3249 
3250 alloc_tag:
3251 	/* Validate tag, should never fail. */
3252 	if (slots->m_slot[slot] == NULL) {
3253 		/*
3254 		 * Make sure SMID is not using reserved value of 0
3255 		 * and the TM request slot.
3256 		 */
3257 		ASSERT((slot > 0) && (slot <= slots->m_n_slots));
3258 		cmd->cmd_slot = slot;
3259 		slots->m_slot[slot] = cmd;
3260 		mpt->m_ncmds++;
3261 
3262 		/*
3263 		 * only increment per target ncmds if this is not a
3264 		 * command that has no target associated with it (i.e. a
3265 		 * event acknoledgment)
3266 		 */
3267 		if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
3268 			ptgt->m_t_ncmds++;
3269 		}
3270 		cmd->cmd_active_timeout = cmd->cmd_pkt->pkt_time;
3271 
3272 		/*
3273 		 * If initial timout is less than or equal to one tick, bump
3274 		 * the timeout by a tick so that command doesn't timeout before
3275 		 * its allotted time.
3276 		 */
3277 		if (cmd->cmd_active_timeout <= mptsas_scsi_watchdog_tick) {
3278 			cmd->cmd_active_timeout += mptsas_scsi_watchdog_tick;
3279 		}
3280 		return (TRUE);
3281 	} else {
3282 		int i;
3283 
3284 		/*
3285 		 * If slot in use, scan until a free one is found. Don't use 0
3286 		 * or final slot, which is reserved for TM requests.
3287 		 */
3288 		for (i = 0; i < slots->m_n_slots; i++) {
3289 			slot = slots->m_tags;
3290 			if (++(slots->m_tags) > slots->m_n_slots) {
3291 				slots->m_tags = 1;
3292 			}
3293 			if (slots->m_slot[slot] == NULL) {
3294 				NDBG22(("found free slot %d", slot));
3295 				goto alloc_tag;
3296 			}
3297 		}
3298 	}
3299 	return (FALSE);
3300 }
3301 
3302 /*
3303  * prepare the pkt:
3304  * the pkt may have been resubmitted or just reused so
3305  * initialize some fields and do some checks.
3306  */
3307 static int
3308 mptsas_prepare_pkt(mptsas_cmd_t *cmd)
3309 {
3310 	struct scsi_pkt	*pkt = CMD2PKT(cmd);
3311 
3312 	NDBG1(("mptsas_prepare_pkt: cmd=0x%p", (void *)cmd));
3313 
3314 	/*
3315 	 * Reinitialize some fields that need it; the packet may
3316 	 * have been resubmitted
3317 	 */
3318 	pkt->pkt_reason = CMD_CMPLT;
3319 	pkt->pkt_state = 0;
3320 	pkt->pkt_statistics = 0;
3321 	pkt->pkt_resid = 0;
3322 	cmd->cmd_age = 0;
3323 	cmd->cmd_pkt_flags = pkt->pkt_flags;
3324 
3325 	/*
3326 	 * zero status byte.
3327 	 */
3328 	*(pkt->pkt_scbp) = 0;
3329 
3330 	if (cmd->cmd_flags & CFLAG_DMAVALID) {
3331 		pkt->pkt_resid = cmd->cmd_dmacount;
3332 
3333 		/*
3334 		 * consistent packets need to be sync'ed first
3335 		 * (only for data going out)
3336 		 */
3337 		if ((cmd->cmd_flags & CFLAG_CMDIOPB) &&
3338 		    (cmd->cmd_flags & CFLAG_DMASEND)) {
3339 			(void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
3340 			    DDI_DMA_SYNC_FORDEV);
3341 		}
3342 	}
3343 
3344 	cmd->cmd_flags =
3345 	    (cmd->cmd_flags & ~(CFLAG_TRANFLAG)) |
3346 	    CFLAG_PREPARED | CFLAG_IN_TRANSPORT;
3347 
3348 	return (TRAN_ACCEPT);
3349 }
3350 
3351 /*
3352  * tran_init_pkt(9E) - allocate scsi_pkt(9S) for command
3353  *
3354  * One of three possibilities:
3355  *	- allocate scsi_pkt
3356  *	- allocate scsi_pkt and DMA resources
3357  *	- allocate DMA resources to an already-allocated pkt
3358  */
3359 static struct scsi_pkt *
3360 mptsas_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt,
3361     struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags,
3362     int (*callback)(), caddr_t arg)
3363 {
3364 	mptsas_cmd_t		*cmd, *new_cmd;
3365 	mptsas_t		*mpt = ADDR2MPT(ap);
3366 	int			failure = 1;
3367 	uint_t			oldcookiec;
3368 	mptsas_target_t		*ptgt = NULL;
3369 	int			rval;
3370 	mptsas_tgt_private_t	*tgt_private;
3371 	int			kf;
3372 
3373 	kf = (callback == SLEEP_FUNC)? KM_SLEEP: KM_NOSLEEP;
3374 
3375 	tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->
3376 	    tran_tgt_private;
3377 	ASSERT(tgt_private != NULL);
3378 	if (tgt_private == NULL) {
3379 		return (NULL);
3380 	}
3381 	ptgt = tgt_private->t_private;
3382 	ASSERT(ptgt != NULL);
3383 	if (ptgt == NULL)
3384 		return (NULL);
3385 	ap->a_target = ptgt->m_devhdl;
3386 	ap->a_lun = tgt_private->t_lun;
3387 
3388 	ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC);
3389 #ifdef MPTSAS_TEST_EXTRN_ALLOC
3390 	statuslen *= 100; tgtlen *= 4;
3391 #endif
3392 	NDBG3(("mptsas_scsi_init_pkt:\n"
3393 	    "\ttgt=%d in=0x%p bp=0x%p clen=%d slen=%d tlen=%d flags=%x",
3394 	    ap->a_target, (void *)pkt, (void *)bp,
3395 	    cmdlen, statuslen, tgtlen, flags));
3396 
3397 	/*
3398 	 * Allocate the new packet.
3399 	 */
3400 	if (pkt == NULL) {
3401 		ddi_dma_handle_t	save_dma_handle;
3402 		ddi_dma_handle_t	save_arq_dma_handle;
3403 		struct buf		*save_arq_bp;
3404 		ddi_dma_cookie_t	save_arqcookie;
3405 
3406 		cmd = kmem_cache_alloc(mpt->m_kmem_cache, kf);
3407 
3408 		if (cmd) {
3409 			save_dma_handle = cmd->cmd_dmahandle;
3410 			save_arq_dma_handle = cmd->cmd_arqhandle;
3411 			save_arq_bp = cmd->cmd_arq_buf;
3412 			save_arqcookie = cmd->cmd_arqcookie;
3413 			bzero(cmd, sizeof (*cmd) + scsi_pkt_size());
3414 			cmd->cmd_dmahandle = save_dma_handle;
3415 			cmd->cmd_arqhandle = save_arq_dma_handle;
3416 			cmd->cmd_arq_buf = save_arq_bp;
3417 			cmd->cmd_arqcookie = save_arqcookie;
3418 
3419 			pkt = (void *)((uchar_t *)cmd +
3420 			    sizeof (struct mptsas_cmd));
3421 			pkt->pkt_ha_private = (opaque_t)cmd;
3422 			pkt->pkt_address = *ap;
3423 			pkt->pkt_private = (opaque_t)cmd->cmd_pkt_private;
3424 			pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb;
3425 			pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb;
3426 			cmd->cmd_pkt = (struct scsi_pkt *)pkt;
3427 			cmd->cmd_cdblen = (uchar_t)cmdlen;
3428 			cmd->cmd_scblen = statuslen;
3429 			cmd->cmd_rqslen = SENSE_LENGTH;
3430 			cmd->cmd_tgt_addr = ptgt;
3431 			failure = 0;
3432 		}
3433 
3434 		if (failure || (cmdlen > sizeof (cmd->cmd_cdb)) ||
3435 		    (tgtlen > PKT_PRIV_LEN) ||
3436 		    (statuslen > EXTCMDS_STATUS_SIZE)) {
3437 			if (failure == 0) {
3438 				/*
3439 				 * if extern alloc fails, all will be
3440 				 * deallocated, including cmd
3441 				 */
3442 				failure = mptsas_pkt_alloc_extern(mpt, cmd,
3443 				    cmdlen, tgtlen, statuslen, kf);
3444 			}
3445 			if (failure) {
3446 				/*
3447 				 * if extern allocation fails, it will
3448 				 * deallocate the new pkt as well
3449 				 */
3450 				return (NULL);
3451 			}
3452 		}
3453 		new_cmd = cmd;
3454 
3455 	} else {
3456 		cmd = PKT2CMD(pkt);
3457 		new_cmd = NULL;
3458 	}
3459 
3460 
3461 	/* grab cmd->cmd_cookiec here as oldcookiec */
3462 
3463 	oldcookiec = cmd->cmd_cookiec;
3464 
3465 	/*
3466 	 * If the dma was broken up into PARTIAL transfers cmd_nwin will be
3467 	 * greater than 0 and we'll need to grab the next dma window
3468 	 */
3469 	/*
3470 	 * SLM-not doing extra command frame right now; may add later
3471 	 */
3472 
3473 	if (cmd->cmd_nwin > 0) {
3474 
3475 		/*
3476 		 * Make sure we havn't gone past the the total number
3477 		 * of windows
3478 		 */
3479 		if (++cmd->cmd_winindex >= cmd->cmd_nwin) {
3480 			return (NULL);
3481 		}
3482 		if (ddi_dma_getwin(cmd->cmd_dmahandle, cmd->cmd_winindex,
3483 		    &cmd->cmd_dma_offset, &cmd->cmd_dma_len,
3484 		    &cmd->cmd_cookie, &cmd->cmd_cookiec) == DDI_FAILURE) {
3485 			return (NULL);
3486 		}
3487 		goto get_dma_cookies;
3488 	}
3489 
3490 
3491 	if (flags & PKT_XARQ) {
3492 		cmd->cmd_flags |= CFLAG_XARQ;
3493 	}
3494 
3495 	/*
3496 	 * DMA resource allocation.  This version assumes your
3497 	 * HBA has some sort of bus-mastering or onboard DMA capability, with a
3498 	 * scatter-gather list of length MPTSAS_MAX_DMA_SEGS, as given in the
3499 	 * ddi_dma_attr_t structure and passed to scsi_impl_dmaget.
3500 	 */
3501 	if (bp && (bp->b_bcount != 0) &&
3502 	    (cmd->cmd_flags & CFLAG_DMAVALID) == 0) {
3503 
3504 		int	cnt, dma_flags;
3505 		mptti_t	*dmap;		/* ptr to the S/G list */
3506 
3507 		/*
3508 		 * Set up DMA memory and position to the next DMA segment.
3509 		 */
3510 		ASSERT(cmd->cmd_dmahandle != NULL);
3511 
3512 		if (bp->b_flags & B_READ) {
3513 			dma_flags = DDI_DMA_READ;
3514 			cmd->cmd_flags &= ~CFLAG_DMASEND;
3515 		} else {
3516 			dma_flags = DDI_DMA_WRITE;
3517 			cmd->cmd_flags |= CFLAG_DMASEND;
3518 		}
3519 		if (flags & PKT_CONSISTENT) {
3520 			cmd->cmd_flags |= CFLAG_CMDIOPB;
3521 			dma_flags |= DDI_DMA_CONSISTENT;
3522 		}
3523 
3524 		if (flags & PKT_DMA_PARTIAL) {
3525 			dma_flags |= DDI_DMA_PARTIAL;
3526 		}
3527 
3528 		/*
3529 		 * workaround for byte hole issue on psycho and
3530 		 * schizo pre 2.1
3531 		 */
3532 		if ((bp->b_flags & B_READ) && ((bp->b_flags &
3533 		    (B_PAGEIO|B_REMAPPED)) != B_PAGEIO) &&
3534 		    ((uintptr_t)bp->b_un.b_addr & 0x7)) {
3535 			dma_flags |= DDI_DMA_CONSISTENT;
3536 		}
3537 
3538 		rval = ddi_dma_buf_bind_handle(cmd->cmd_dmahandle, bp,
3539 		    dma_flags, callback, arg,
3540 		    &cmd->cmd_cookie, &cmd->cmd_cookiec);
3541 		if (rval == DDI_DMA_PARTIAL_MAP) {
3542 			(void) ddi_dma_numwin(cmd->cmd_dmahandle,
3543 			    &cmd->cmd_nwin);
3544 			cmd->cmd_winindex = 0;
3545 			(void) ddi_dma_getwin(cmd->cmd_dmahandle,
3546 			    cmd->cmd_winindex, &cmd->cmd_dma_offset,
3547 			    &cmd->cmd_dma_len, &cmd->cmd_cookie,
3548 			    &cmd->cmd_cookiec);
3549 		} else if (rval && (rval != DDI_DMA_MAPPED)) {
3550 			switch (rval) {
3551 			case DDI_DMA_NORESOURCES:
3552 				bioerror(bp, 0);
3553 				break;
3554 			case DDI_DMA_BADATTR:
3555 			case DDI_DMA_NOMAPPING:
3556 				bioerror(bp, EFAULT);
3557 				break;
3558 			case DDI_DMA_TOOBIG:
3559 			default:
3560 				bioerror(bp, EINVAL);
3561 				break;
3562 			}
3563 			cmd->cmd_flags &= ~CFLAG_DMAVALID;
3564 			if (new_cmd) {
3565 				mptsas_scsi_destroy_pkt(ap, pkt);
3566 			}
3567 			return ((struct scsi_pkt *)NULL);
3568 		}
3569 
3570 get_dma_cookies:
3571 		cmd->cmd_flags |= CFLAG_DMAVALID;
3572 		ASSERT(cmd->cmd_cookiec > 0);
3573 
3574 		if (cmd->cmd_cookiec > MPTSAS_MAX_CMD_SEGS) {
3575 			mptsas_log(mpt, CE_NOTE, "large cookiec received %d\n",
3576 			    cmd->cmd_cookiec);
3577 			bioerror(bp, EINVAL);
3578 			if (new_cmd) {
3579 				mptsas_scsi_destroy_pkt(ap, pkt);
3580 			}
3581 			return ((struct scsi_pkt *)NULL);
3582 		}
3583 
3584 		/*
3585 		 * Allocate extra SGL buffer if needed.
3586 		 */
3587 		if ((cmd->cmd_cookiec > MPTSAS_MAX_FRAME_SGES64(mpt)) &&
3588 		    (cmd->cmd_extra_frames == NULL)) {
3589 			if (mptsas_alloc_extra_sgl_frame(mpt, cmd) ==
3590 			    DDI_FAILURE) {
3591 				mptsas_log(mpt, CE_WARN, "MPT SGL mem alloc "
3592 				    "failed");
3593 				bioerror(bp, ENOMEM);
3594 				if (new_cmd) {
3595 					mptsas_scsi_destroy_pkt(ap, pkt);
3596 				}
3597 				return ((struct scsi_pkt *)NULL);
3598 			}
3599 		}
3600 
3601 		/*
3602 		 * Always use scatter-gather transfer
3603 		 * Use the loop below to store physical addresses of
3604 		 * DMA segments, from the DMA cookies, into your HBA's
3605 		 * scatter-gather list.
3606 		 * We need to ensure we have enough kmem alloc'd
3607 		 * for the sg entries since we are no longer using an
3608 		 * array inside mptsas_cmd_t.
3609 		 *
3610 		 * We check cmd->cmd_cookiec against oldcookiec so
3611 		 * the scatter-gather list is correctly allocated
3612 		 */
3613 
3614 		if (oldcookiec != cmd->cmd_cookiec) {
3615 			if (cmd->cmd_sg != (mptti_t *)NULL) {
3616 				kmem_free(cmd->cmd_sg, sizeof (mptti_t) *
3617 				    oldcookiec);
3618 				cmd->cmd_sg = NULL;
3619 			}
3620 		}
3621 
3622 		if (cmd->cmd_sg == (mptti_t *)NULL) {
3623 			cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)*
3624 			    cmd->cmd_cookiec), kf);
3625 
3626 			if (cmd->cmd_sg == (mptti_t *)NULL) {
3627 				mptsas_log(mpt, CE_WARN,
3628 				    "unable to kmem_alloc enough memory "
3629 				    "for scatter/gather list");
3630 		/*
3631 		 * if we have an ENOMEM condition we need to behave
3632 		 * the same way as the rest of this routine
3633 		 */
3634 
3635 				bioerror(bp, ENOMEM);
3636 				if (new_cmd) {
3637 					mptsas_scsi_destroy_pkt(ap, pkt);
3638 				}
3639 				return ((struct scsi_pkt *)NULL);
3640 			}
3641 		}
3642 
3643 		dmap = cmd->cmd_sg;
3644 
3645 		ASSERT(cmd->cmd_cookie.dmac_size != 0);
3646 
3647 		/*
3648 		 * store the first segment into the S/G list
3649 		 */
3650 		dmap->count = cmd->cmd_cookie.dmac_size;
3651 		dmap->addr.address64.Low = (uint32_t)
3652 		    (cmd->cmd_cookie.dmac_laddress & 0xffffffffull);
3653 		dmap->addr.address64.High = (uint32_t)
3654 		    (cmd->cmd_cookie.dmac_laddress >> 32);
3655 
3656 		/*
3657 		 * dmacount counts the size of the dma for this window
3658 		 * (if partial dma is being used).  totaldmacount
3659 		 * keeps track of the total amount of dma we have
3660 		 * transferred for all the windows (needed to calculate
3661 		 * the resid value below).
3662 		 */
3663 		cmd->cmd_dmacount = cmd->cmd_cookie.dmac_size;
3664 		cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size;
3665 
3666 		/*
3667 		 * We already stored the first DMA scatter gather segment,
3668 		 * start at 1 if we need to store more.
3669 		 */
3670 		for (cnt = 1; cnt < cmd->cmd_cookiec; cnt++) {
3671 			/*
3672 			 * Get next DMA cookie
3673 			 */
3674 			ddi_dma_nextcookie(cmd->cmd_dmahandle,
3675 			    &cmd->cmd_cookie);
3676 			dmap++;
3677 
3678 			cmd->cmd_dmacount += cmd->cmd_cookie.dmac_size;
3679 			cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size;
3680 
3681 			/*
3682 			 * store the segment parms into the S/G list
3683 			 */
3684 			dmap->count = cmd->cmd_cookie.dmac_size;
3685 			dmap->addr.address64.Low = (uint32_t)
3686 			    (cmd->cmd_cookie.dmac_laddress & 0xffffffffull);
3687 			dmap->addr.address64.High = (uint32_t)
3688 			    (cmd->cmd_cookie.dmac_laddress >> 32);
3689 		}
3690 
3691 		/*
3692 		 * If this was partially allocated we set the resid
3693 		 * the amount of data NOT transferred in this window
3694 		 * If there is only one window, the resid will be 0
3695 		 */
3696 		pkt->pkt_resid = (bp->b_bcount - cmd->cmd_totaldmacount);
3697 		NDBG16(("mptsas_dmaget: cmd_dmacount=%d.", cmd->cmd_dmacount));
3698 	}
3699 	return (pkt);
3700 }
3701 
3702 /*
3703  * tran_destroy_pkt(9E) - scsi_pkt(9s) deallocation
3704  *
3705  * Notes:
3706  *	- also frees DMA resources if allocated
3707  *	- implicit DMA synchonization
3708  */
3709 static void
3710 mptsas_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
3711 {
3712 	mptsas_cmd_t	*cmd = PKT2CMD(pkt);
3713 	mptsas_t	*mpt = ADDR2MPT(ap);
3714 
3715 	NDBG3(("mptsas_scsi_destroy_pkt: target=%d pkt=0x%p",
3716 	    ap->a_target, (void *)pkt));
3717 
3718 	if (cmd->cmd_flags & CFLAG_DMAVALID) {
3719 		(void) ddi_dma_unbind_handle(cmd->cmd_dmahandle);
3720 		cmd->cmd_flags &= ~CFLAG_DMAVALID;
3721 	}
3722 
3723 	if (cmd->cmd_sg) {
3724 		kmem_free(cmd->cmd_sg, sizeof (mptti_t) * cmd->cmd_cookiec);
3725 		cmd->cmd_sg = NULL;
3726 	}
3727 
3728 	mptsas_free_extra_sgl_frame(mpt, cmd);
3729 
3730 	if ((cmd->cmd_flags &
3731 	    (CFLAG_FREE | CFLAG_CDBEXTERN | CFLAG_PRIVEXTERN |
3732 	    CFLAG_SCBEXTERN)) == 0) {
3733 		cmd->cmd_flags = CFLAG_FREE;
3734 		kmem_cache_free(mpt->m_kmem_cache, (void *)cmd);
3735 	} else {
3736 		mptsas_pkt_destroy_extern(mpt, cmd);
3737 	}
3738 }
3739 
3740 /*
3741  * kmem cache constructor and destructor:
3742  * When constructing, we bzero the cmd and allocate the dma handle
3743  * When destructing, just free the dma handle
3744  */
3745 static int
3746 mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags)
3747 {
3748 	mptsas_cmd_t		*cmd = buf;
3749 	mptsas_t		*mpt  = cdrarg;
3750 	struct scsi_address	ap;
3751 	uint_t			cookiec;
3752 	ddi_dma_attr_t		arq_dma_attr;
3753 	int			(*callback)(caddr_t);
3754 
3755 	callback = (kmflags == KM_SLEEP)? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT;
3756 
3757 	NDBG4(("mptsas_kmem_cache_constructor"));
3758 
3759 	ap.a_hba_tran = mpt->m_tran;
3760 	ap.a_target = 0;
3761 	ap.a_lun = 0;
3762 
3763 	/*
3764 	 * allocate a dma handle
3765 	 */
3766 	if ((ddi_dma_alloc_handle(mpt->m_dip, &mpt->m_io_dma_attr, callback,
3767 	    NULL, &cmd->cmd_dmahandle)) != DDI_SUCCESS) {
3768 		cmd->cmd_dmahandle = NULL;
3769 		return (-1);
3770 	}
3771 
3772 	cmd->cmd_arq_buf = scsi_alloc_consistent_buf(&ap, (struct buf *)NULL,
3773 	    SENSE_LENGTH, B_READ, callback, NULL);
3774 	if (cmd->cmd_arq_buf == NULL) {
3775 		ddi_dma_free_handle(&cmd->cmd_dmahandle);
3776 		cmd->cmd_dmahandle = NULL;
3777 		return (-1);
3778 	}
3779 
3780 	/*
3781 	 * allocate a arq handle
3782 	 */
3783 	arq_dma_attr = mpt->m_msg_dma_attr;
3784 	arq_dma_attr.dma_attr_sgllen = 1;
3785 	if ((ddi_dma_alloc_handle(mpt->m_dip, &arq_dma_attr, callback,
3786 	    NULL, &cmd->cmd_arqhandle)) != DDI_SUCCESS) {
3787 		ddi_dma_free_handle(&cmd->cmd_dmahandle);
3788 		scsi_free_consistent_buf(cmd->cmd_arq_buf);
3789 		cmd->cmd_dmahandle = NULL;
3790 		cmd->cmd_arqhandle = NULL;
3791 		return (-1);
3792 	}
3793 
3794 	if (ddi_dma_buf_bind_handle(cmd->cmd_arqhandle,
3795 	    cmd->cmd_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT),
3796 	    callback, NULL, &cmd->cmd_arqcookie, &cookiec) != DDI_SUCCESS) {
3797 		ddi_dma_free_handle(&cmd->cmd_dmahandle);
3798 		ddi_dma_free_handle(&cmd->cmd_arqhandle);
3799 		scsi_free_consistent_buf(cmd->cmd_arq_buf);
3800 		cmd->cmd_dmahandle = NULL;
3801 		cmd->cmd_arqhandle = NULL;
3802 		cmd->cmd_arq_buf = NULL;
3803 		return (-1);
3804 	}
3805 
3806 	return (0);
3807 }
3808 
3809 static void
3810 mptsas_kmem_cache_destructor(void *buf, void *cdrarg)
3811 {
3812 #ifndef __lock_lint
3813 	_NOTE(ARGUNUSED(cdrarg))
3814 #endif
3815 	mptsas_cmd_t	*cmd = buf;
3816 
3817 	NDBG4(("mptsas_kmem_cache_destructor"));
3818 
3819 	if (cmd->cmd_arqhandle) {
3820 		(void) ddi_dma_unbind_handle(cmd->cmd_arqhandle);
3821 		ddi_dma_free_handle(&cmd->cmd_arqhandle);
3822 		cmd->cmd_arqhandle = NULL;
3823 	}
3824 	if (cmd->cmd_arq_buf) {
3825 		scsi_free_consistent_buf(cmd->cmd_arq_buf);
3826 		cmd->cmd_arq_buf = NULL;
3827 	}
3828 	if (cmd->cmd_dmahandle) {
3829 		ddi_dma_free_handle(&cmd->cmd_dmahandle);
3830 		cmd->cmd_dmahandle = NULL;
3831 	}
3832 }
3833 
3834 static int
3835 mptsas_cache_frames_constructor(void *buf, void *cdrarg, int kmflags)
3836 {
3837 	mptsas_cache_frames_t	*p = buf;
3838 	mptsas_t		*mpt = cdrarg;
3839 	ddi_dma_attr_t		frame_dma_attr;
3840 	size_t			mem_size, alloc_len;
3841 	ddi_dma_cookie_t	cookie;
3842 	uint_t			ncookie;
3843 	int (*callback)(caddr_t) = (kmflags == KM_SLEEP)
3844 	    ? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT;
3845 
3846 	frame_dma_attr = mpt->m_msg_dma_attr;
3847 	frame_dma_attr.dma_attr_align = 0x10;
3848 	frame_dma_attr.dma_attr_sgllen = 1;
3849 
3850 	if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attr, callback, NULL,
3851 	    &p->m_dma_hdl) != DDI_SUCCESS) {
3852 		mptsas_log(mpt, CE_WARN, "Unable to allocate dma handle for"
3853 		    " extra SGL.");
3854 		return (DDI_FAILURE);
3855 	}
3856 
3857 	mem_size = (mpt->m_max_request_frames - 1) * mpt->m_req_frame_size;
3858 
3859 	if (ddi_dma_mem_alloc(p->m_dma_hdl, mem_size, &mpt->m_dev_acc_attr,
3860 	    DDI_DMA_CONSISTENT, callback, NULL, (caddr_t *)&p->m_frames_addr,
3861 	    &alloc_len, &p->m_acc_hdl) != DDI_SUCCESS) {
3862 		ddi_dma_free_handle(&p->m_dma_hdl);
3863 		p->m_dma_hdl = NULL;
3864 		mptsas_log(mpt, CE_WARN, "Unable to allocate dma memory for"
3865 		    " extra SGL.");
3866 		return (DDI_FAILURE);
3867 	}
3868 
3869 	if (ddi_dma_addr_bind_handle(p->m_dma_hdl, NULL, p->m_frames_addr,
3870 	    alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, callback, NULL,
3871 	    &cookie, &ncookie) != DDI_DMA_MAPPED) {
3872 		(void) ddi_dma_mem_free(&p->m_acc_hdl);
3873 		ddi_dma_free_handle(&p->m_dma_hdl);
3874 		p->m_dma_hdl = NULL;
3875 		mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources for"
3876 		    " extra SGL");
3877 		return (DDI_FAILURE);
3878 	}
3879 
3880 	/*
3881 	 * Store the SGL memory address.  This chip uses this
3882 	 * address to dma to and from the driver.  The second
3883 	 * address is the address mpt uses to fill in the SGL.
3884 	 */
3885 	p->m_phys_addr = cookie.dmac_address;
3886 
3887 	return (DDI_SUCCESS);
3888 }
3889 
3890 static void
3891 mptsas_cache_frames_destructor(void *buf, void *cdrarg)
3892 {
3893 #ifndef __lock_lint
3894 	_NOTE(ARGUNUSED(cdrarg))
3895 #endif
3896 	mptsas_cache_frames_t	*p = buf;
3897 	if (p->m_dma_hdl != NULL) {
3898 		(void) ddi_dma_unbind_handle(p->m_dma_hdl);
3899 		(void) ddi_dma_mem_free(&p->m_acc_hdl);
3900 		ddi_dma_free_handle(&p->m_dma_hdl);
3901 		p->m_phys_addr = NULL;
3902 		p->m_frames_addr = NULL;
3903 		p->m_dma_hdl = NULL;
3904 		p->m_acc_hdl = NULL;
3905 	}
3906 
3907 }
3908 
3909 /*
3910  * allocate and deallocate external pkt space (ie. not part of mptsas_cmd)
3911  * for non-standard length cdb, pkt_private, status areas
3912  * if allocation fails, then deallocate all external space and the pkt
3913  */
3914 /* ARGSUSED */
3915 static int
3916 mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd,
3917     int cmdlen, int tgtlen, int statuslen, int kf)
3918 {
3919 	caddr_t			cdbp, scbp, tgt;
3920 	int			(*callback)(caddr_t) = (kf == KM_SLEEP) ?
3921 	    DDI_DMA_SLEEP : DDI_DMA_DONTWAIT;
3922 	struct scsi_address	ap;
3923 	size_t			senselength;
3924 	ddi_dma_attr_t		ext_arq_dma_attr;
3925 	uint_t			cookiec;
3926 
3927 	NDBG3(("mptsas_pkt_alloc_extern: "
3928 	    "cmd=0x%p cmdlen=%d tgtlen=%d statuslen=%d kf=%x",
3929 	    (void *)cmd, cmdlen, tgtlen, statuslen, kf));
3930 
3931 	tgt = cdbp = scbp = NULL;
3932 	cmd->cmd_scblen		= statuslen;
3933 	cmd->cmd_privlen	= (uchar_t)tgtlen;
3934 
3935 	if (cmdlen > sizeof (cmd->cmd_cdb)) {
3936 		if ((cdbp = kmem_zalloc((size_t)cmdlen, kf)) == NULL) {
3937 			goto fail;
3938 		}
3939 		cmd->cmd_pkt->pkt_cdbp = (opaque_t)cdbp;
3940 		cmd->cmd_flags |= CFLAG_CDBEXTERN;
3941 	}
3942 	if (tgtlen > PKT_PRIV_LEN) {
3943 		if ((tgt = kmem_zalloc((size_t)tgtlen, kf)) == NULL) {
3944 			goto fail;
3945 		}
3946 		cmd->cmd_flags |= CFLAG_PRIVEXTERN;
3947 		cmd->cmd_pkt->pkt_private = tgt;
3948 	}
3949 	if (statuslen > EXTCMDS_STATUS_SIZE) {
3950 		if ((scbp = kmem_zalloc((size_t)statuslen, kf)) == NULL) {
3951 			goto fail;
3952 		}
3953 		cmd->cmd_flags |= CFLAG_SCBEXTERN;
3954 		cmd->cmd_pkt->pkt_scbp = (opaque_t)scbp;
3955 
3956 		/* allocate sense data buf for DMA */
3957 
3958 		senselength = statuslen - MPTSAS_GET_ITEM_OFF(
3959 		    struct scsi_arq_status, sts_sensedata);
3960 		cmd->cmd_rqslen = (uchar_t)senselength;
3961 
3962 		ap.a_hba_tran = mpt->m_tran;
3963 		ap.a_target = 0;
3964 		ap.a_lun = 0;
3965 
3966 		cmd->cmd_ext_arq_buf = scsi_alloc_consistent_buf(&ap,
3967 		    (struct buf *)NULL, senselength, B_READ,
3968 		    callback, NULL);
3969 
3970 		if (cmd->cmd_ext_arq_buf == NULL) {
3971 			goto fail;
3972 		}
3973 		/*
3974 		 * allocate a extern arq handle and bind the buf
3975 		 */
3976 		ext_arq_dma_attr = mpt->m_msg_dma_attr;
3977 		ext_arq_dma_attr.dma_attr_sgllen = 1;
3978 		if ((ddi_dma_alloc_handle(mpt->m_dip,
3979 		    &ext_arq_dma_attr, callback,
3980 		    NULL, &cmd->cmd_ext_arqhandle)) != DDI_SUCCESS) {
3981 			goto fail;
3982 		}
3983 
3984 		if (ddi_dma_buf_bind_handle(cmd->cmd_ext_arqhandle,
3985 		    cmd->cmd_ext_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT),
3986 		    callback, NULL, &cmd->cmd_ext_arqcookie,
3987 		    &cookiec)
3988 		    != DDI_SUCCESS) {
3989 			goto fail;
3990 		}
3991 		cmd->cmd_flags |= CFLAG_EXTARQBUFVALID;
3992 	}
3993 	return (0);
3994 fail:
3995 	mptsas_pkt_destroy_extern(mpt, cmd);
3996 	return (1);
3997 }
3998 
3999 /*
4000  * deallocate external pkt space and deallocate the pkt
4001  */
4002 static void
4003 mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd)
4004 {
4005 	NDBG3(("mptsas_pkt_destroy_extern: cmd=0x%p", (void *)cmd));
4006 
4007 	if (cmd->cmd_flags & CFLAG_FREE) {
4008 		mptsas_log(mpt, CE_PANIC,
4009 		    "mptsas_pkt_destroy_extern: freeing free packet");
4010 		_NOTE(NOT_REACHED)
4011 		/* NOTREACHED */
4012 	}
4013 	if (cmd->cmd_flags & CFLAG_CDBEXTERN) {
4014 		kmem_free(cmd->cmd_pkt->pkt_cdbp, (size_t)cmd->cmd_cdblen);
4015 	}
4016 	if (cmd->cmd_flags & CFLAG_SCBEXTERN) {
4017 		kmem_free(cmd->cmd_pkt->pkt_scbp, (size_t)cmd->cmd_scblen);
4018 		if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) {
4019 			(void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle);
4020 		}
4021 		if (cmd->cmd_ext_arqhandle) {
4022 			ddi_dma_free_handle(&cmd->cmd_ext_arqhandle);
4023 			cmd->cmd_ext_arqhandle = NULL;
4024 		}
4025 		if (cmd->cmd_ext_arq_buf)
4026 			scsi_free_consistent_buf(cmd->cmd_ext_arq_buf);
4027 	}
4028 	if (cmd->cmd_flags & CFLAG_PRIVEXTERN) {
4029 		kmem_free(cmd->cmd_pkt->pkt_private, (size_t)cmd->cmd_privlen);
4030 	}
4031 	cmd->cmd_flags = CFLAG_FREE;
4032 	kmem_cache_free(mpt->m_kmem_cache, (void *)cmd);
4033 }
4034 
4035 /*
4036  * tran_sync_pkt(9E) - explicit DMA synchronization
4037  */
4038 /*ARGSUSED*/
4039 static void
4040 mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
4041 {
4042 	mptsas_cmd_t	*cmd = PKT2CMD(pkt);
4043 
4044 	NDBG3(("mptsas_scsi_sync_pkt: target=%d, pkt=0x%p",
4045 	    ap->a_target, (void *)pkt));
4046 
4047 	if (cmd->cmd_dmahandle) {
4048 		(void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
4049 		    (cmd->cmd_flags & CFLAG_DMASEND) ?
4050 		    DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU);
4051 	}
4052 }
4053 
4054 /*
4055  * tran_dmafree(9E) - deallocate DMA resources allocated for command
4056  */
4057 /*ARGSUSED*/
4058 static void
4059 mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
4060 {
4061 	mptsas_cmd_t	*cmd = PKT2CMD(pkt);
4062 	mptsas_t	*mpt = ADDR2MPT(ap);
4063 
4064 	NDBG3(("mptsas_scsi_dmafree: target=%d pkt=0x%p",
4065 	    ap->a_target, (void *)pkt));
4066 
4067 	if (cmd->cmd_flags & CFLAG_DMAVALID) {
4068 		(void) ddi_dma_unbind_handle(cmd->cmd_dmahandle);
4069 		cmd->cmd_flags &= ~CFLAG_DMAVALID;
4070 	}
4071 
4072 	if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) {
4073 		(void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle);
4074 		cmd->cmd_flags &= ~CFLAG_EXTARQBUFVALID;
4075 	}
4076 
4077 	mptsas_free_extra_sgl_frame(mpt, cmd);
4078 }
4079 
4080 static void
4081 mptsas_pkt_comp(struct scsi_pkt *pkt, mptsas_cmd_t *cmd)
4082 {
4083 	if ((cmd->cmd_flags & CFLAG_CMDIOPB) &&
4084 	    (!(cmd->cmd_flags & CFLAG_DMASEND))) {
4085 		(void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
4086 		    DDI_DMA_SYNC_FORCPU);
4087 	}
4088 	(*pkt->pkt_comp)(pkt);
4089 }
4090 
4091 static void
4092 mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, uint32_t *control,
4093 	pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl)
4094 {
4095 	uint_t			cookiec;
4096 	mptti_t			*dmap;
4097 	uint32_t		flags;
4098 	pMpi2SGESimple64_t	sge;
4099 	pMpi2SGEChain64_t	sgechain;
4100 	ASSERT(cmd->cmd_flags & CFLAG_DMAVALID);
4101 
4102 	/*
4103 	 * Save the number of entries in the DMA
4104 	 * Scatter/Gather list
4105 	 */
4106 	cookiec = cmd->cmd_cookiec;
4107 
4108 	NDBG1(("mptsas_sge_setup: cookiec=%d", cookiec));
4109 
4110 	/*
4111 	 * Set read/write bit in control.
4112 	 */
4113 	if (cmd->cmd_flags & CFLAG_DMASEND) {
4114 		*control |= MPI2_SCSIIO_CONTROL_WRITE;
4115 	} else {
4116 		*control |= MPI2_SCSIIO_CONTROL_READ;
4117 	}
4118 
4119 	ddi_put32(acc_hdl, &frame->DataLength, cmd->cmd_dmacount);
4120 
4121 	/*
4122 	 * We have 2 cases here.  First where we can fit all the
4123 	 * SG elements into the main frame, and the case
4124 	 * where we can't.
4125 	 * If we have more cookies than we can attach to a frame
4126 	 * we will need to use a chain element to point
4127 	 * a location of memory where the rest of the S/G
4128 	 * elements reside.
4129 	 */
4130 	if (cookiec <= MPTSAS_MAX_FRAME_SGES64(mpt)) {
4131 		dmap = cmd->cmd_sg;
4132 		sge = (pMpi2SGESimple64_t)(&frame->SGL);
4133 		while (cookiec--) {
4134 			ddi_put32(acc_hdl,
4135 			    &sge->Address.Low, dmap->addr.address64.Low);
4136 			ddi_put32(acc_hdl,
4137 			    &sge->Address.High, dmap->addr.address64.High);
4138 			ddi_put32(acc_hdl, &sge->FlagsLength,
4139 			    dmap->count);
4140 			flags = ddi_get32(acc_hdl, &sge->FlagsLength);
4141 			flags |= ((uint32_t)
4142 			    (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4143 			    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4144 			    MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4145 			    MPI2_SGE_FLAGS_SHIFT);
4146 
4147 			/*
4148 			 * If this is the last cookie, we set the flags
4149 			 * to indicate so
4150 			 */
4151 			if (cookiec == 0) {
4152 				flags |=
4153 				    ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT
4154 				    | MPI2_SGE_FLAGS_END_OF_BUFFER
4155 				    | MPI2_SGE_FLAGS_END_OF_LIST) <<
4156 				    MPI2_SGE_FLAGS_SHIFT);
4157 			}
4158 			if (cmd->cmd_flags & CFLAG_DMASEND) {
4159 				flags |= (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4160 				    MPI2_SGE_FLAGS_SHIFT);
4161 			} else {
4162 				flags |= (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4163 				    MPI2_SGE_FLAGS_SHIFT);
4164 			}
4165 			ddi_put32(acc_hdl, &sge->FlagsLength, flags);
4166 			dmap++;
4167 			sge++;
4168 		}
4169 	} else {
4170 		/*
4171 		 * Hereby we start to deal with multiple frames.
4172 		 * The process is as follows:
4173 		 * 1. Determine how many frames are needed for SGL element
4174 		 *    storage; Note that all frames are stored in contiguous
4175 		 *    memory space and in 64-bit DMA mode each element is
4176 		 *    3 double-words (12 bytes) long.
4177 		 * 2. Fill up the main frame. We need to do this separately
4178 		 *    since it contains the SCSI IO request header and needs
4179 		 *    dedicated processing. Note that the last 4 double-words
4180 		 *    of the SCSI IO header is for SGL element storage
4181 		 *    (MPI2_SGE_IO_UNION).
4182 		 * 3. Fill the chain element in the main frame, so the DMA
4183 		 *    engine can use the following frames.
4184 		 * 4. Enter a loop to fill the remaining frames. Note that the
4185 		 *    last frame contains no chain element.  The remaining
4186 		 *    frames go into the mpt SGL buffer allocated on the fly,
4187 		 *    not immediately following the main message frame, as in
4188 		 *    Gen1.
4189 		 * Some restrictions:
4190 		 * 1. For 64-bit DMA, the simple element and chain element
4191 		 *    are both of 3 double-words (12 bytes) in size, even
4192 		 *    though all frames are stored in the first 4G of mem
4193 		 *    range and the higher 32-bits of the address are always 0.
4194 		 * 2. On some controllers (like the 1064/1068), a frame can
4195 		 *    hold SGL elements with the last 1 or 2 double-words
4196 		 *    (4 or 8 bytes) un-used. On these controllers, we should
4197 		 *    recognize that there's not enough room for another SGL
4198 		 *    element and move the sge pointer to the next frame.
4199 		 */
4200 		int		i, j, k, l, frames, sgemax;
4201 		int		temp;
4202 		uint8_t		chainflags;
4203 		uint16_t	chainlength;
4204 		mptsas_cache_frames_t *p;
4205 
4206 		/*
4207 		 * Sgemax is the number of SGE's that will fit
4208 		 * each extra frame and frames is total
4209 		 * number of frames we'll need.  1 sge entry per
4210 		 * frame is reseverd for the chain element thus the -1 below.
4211 		 */
4212 		sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_SGE_SIMPLE64))
4213 		    - 1);
4214 		temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax;
4215 
4216 		/*
4217 		 * A little check to see if we need to round up the number
4218 		 * of frames we need
4219 		 */
4220 		if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp *
4221 		    sgemax) > 1) {
4222 			frames = (temp + 1);
4223 		} else {
4224 			frames = temp;
4225 		}
4226 		dmap = cmd->cmd_sg;
4227 		sge = (pMpi2SGESimple64_t)(&frame->SGL);
4228 
4229 		/*
4230 		 * First fill in the main frame
4231 		 */
4232 		for (j = 1; j < MPTSAS_MAX_FRAME_SGES64(mpt); j++) {
4233 			ddi_put32(acc_hdl, &sge->Address.Low,
4234 			    dmap->addr.address64.Low);
4235 			ddi_put32(acc_hdl, &sge->Address.High,
4236 			    dmap->addr.address64.High);
4237 			ddi_put32(acc_hdl, &sge->FlagsLength, dmap->count);
4238 			flags = ddi_get32(acc_hdl, &sge->FlagsLength);
4239 			flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4240 			    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4241 			    MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4242 			    MPI2_SGE_FLAGS_SHIFT);
4243 
4244 			/*
4245 			 * If this is the last SGE of this frame
4246 			 * we set the end of list flag
4247 			 */
4248 			if (j == (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) {
4249 				flags |= ((uint32_t)
4250 				    (MPI2_SGE_FLAGS_LAST_ELEMENT) <<
4251 				    MPI2_SGE_FLAGS_SHIFT);
4252 			}
4253 			if (cmd->cmd_flags & CFLAG_DMASEND) {
4254 				flags |=
4255 				    (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4256 				    MPI2_SGE_FLAGS_SHIFT);
4257 			} else {
4258 				flags |=
4259 				    (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4260 				    MPI2_SGE_FLAGS_SHIFT);
4261 			}
4262 			ddi_put32(acc_hdl, &sge->FlagsLength, flags);
4263 			dmap++;
4264 			sge++;
4265 		}
4266 
4267 		/*
4268 		 * Fill in the chain element in the main frame.
4269 		 * About calculation on ChainOffset:
4270 		 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes)
4271 		 *    in the end reserved for SGL element storage
4272 		 *    (MPI2_SGE_IO_UNION); we should count it in our
4273 		 *    calculation.  See its definition in the header file.
4274 		 * 2. Constant j is the counter of the current SGL element
4275 		 *    that will be processed, and (j - 1) is the number of
4276 		 *    SGL elements that have been processed (stored in the
4277 		 *    main frame).
4278 		 * 3. ChainOffset value should be in units of double-words (4
4279 		 *    bytes) so the last value should be divided by 4.
4280 		 */
4281 		ddi_put8(acc_hdl, &frame->ChainOffset,
4282 		    (sizeof (MPI2_SCSI_IO_REQUEST) -
4283 		    sizeof (MPI2_SGE_IO_UNION) +
4284 		    (j - 1) * sizeof (MPI2_SGE_SIMPLE64)) >> 2);
4285 		sgechain = (pMpi2SGEChain64_t)sge;
4286 		chainflags = (MPI2_SGE_FLAGS_CHAIN_ELEMENT |
4287 		    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4288 		    MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
4289 		ddi_put8(acc_hdl, &sgechain->Flags, chainflags);
4290 
4291 		/*
4292 		 * The size of the next frame is the accurate size of space
4293 		 * (in bytes) used to store the SGL elements. j is the counter
4294 		 * of SGL elements. (j - 1) is the number of SGL elements that
4295 		 * have been processed (stored in frames).
4296 		 */
4297 		if (frames >= 2) {
4298 			chainlength = mpt->m_req_frame_size /
4299 			    sizeof (MPI2_SGE_SIMPLE64) *
4300 			    sizeof (MPI2_SGE_SIMPLE64);
4301 		} else {
4302 			chainlength = ((cookiec - (j - 1)) *
4303 			    sizeof (MPI2_SGE_SIMPLE64));
4304 		}
4305 
4306 		p = cmd->cmd_extra_frames;
4307 
4308 		ddi_put16(acc_hdl, &sgechain->Length, chainlength);
4309 		ddi_put32(acc_hdl, &sgechain->Address.Low,
4310 		    p->m_phys_addr);
4311 		/* SGL is allocated in the first 4G mem range */
4312 		ddi_put32(acc_hdl, &sgechain->Address.High, 0);
4313 
4314 		/*
4315 		 * If there are more than 2 frames left we have to
4316 		 * fill in the next chain offset to the location of
4317 		 * the chain element in the next frame.
4318 		 * sgemax is the number of simple elements in an extra
4319 		 * frame. Note that the value NextChainOffset should be
4320 		 * in double-words (4 bytes).
4321 		 */
4322 		if (frames >= 2) {
4323 			ddi_put8(acc_hdl, &sgechain->NextChainOffset,
4324 			    (sgemax * sizeof (MPI2_SGE_SIMPLE64)) >> 2);
4325 		} else {
4326 			ddi_put8(acc_hdl, &sgechain->NextChainOffset, 0);
4327 		}
4328 
4329 		/*
4330 		 * Jump to next frame;
4331 		 * Starting here, chain buffers go into the per command SGL.
4332 		 * This buffer is allocated when chain buffers are needed.
4333 		 */
4334 		sge = (pMpi2SGESimple64_t)p->m_frames_addr;
4335 		i = cookiec;
4336 
4337 		/*
4338 		 * Start filling in frames with SGE's.  If we
4339 		 * reach the end of frame and still have SGE's
4340 		 * to fill we need to add a chain element and
4341 		 * use another frame.  j will be our counter
4342 		 * for what cookie we are at and i will be
4343 		 * the total cookiec. k is the current frame
4344 		 */
4345 		for (k = 1; k <= frames; k++) {
4346 			for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) {
4347 
4348 				/*
4349 				 * If we have reached the end of frame
4350 				 * and we have more SGE's to fill in
4351 				 * we have to fill the final entry
4352 				 * with a chain element and then
4353 				 * continue to the next frame
4354 				 */
4355 				if ((l == (sgemax + 1)) && (k != frames)) {
4356 					sgechain = (pMpi2SGEChain64_t)sge;
4357 					j--;
4358 					chainflags = (
4359 					    MPI2_SGE_FLAGS_CHAIN_ELEMENT |
4360 					    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4361 					    MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
4362 					ddi_put8(p->m_acc_hdl,
4363 					    &sgechain->Flags, chainflags);
4364 					/*
4365 					 * k is the frame counter and (k + 1)
4366 					 * is the number of the next frame.
4367 					 * Note that frames are in contiguous
4368 					 * memory space.
4369 					 */
4370 					ddi_put32(p->m_acc_hdl,
4371 					    &sgechain->Address.Low,
4372 					    (p->m_phys_addr +
4373 					    (mpt->m_req_frame_size * k)));
4374 					ddi_put32(p->m_acc_hdl,
4375 					    &sgechain->Address.High, 0);
4376 
4377 					/*
4378 					 * If there are more than 2 frames left
4379 					 * we have to next chain offset to
4380 					 * the location of the chain element
4381 					 * in the next frame and fill in the
4382 					 * length of the next chain
4383 					 */
4384 					if ((frames - k) >= 2) {
4385 						ddi_put8(p->m_acc_hdl,
4386 						    &sgechain->NextChainOffset,
4387 						    (sgemax *
4388 						    sizeof (MPI2_SGE_SIMPLE64))
4389 						    >> 2);
4390 						ddi_put16(p->m_acc_hdl,
4391 						    &sgechain->Length,
4392 						    mpt->m_req_frame_size /
4393 						    sizeof (MPI2_SGE_SIMPLE64) *
4394 						    sizeof (MPI2_SGE_SIMPLE64));
4395 					} else {
4396 						/*
4397 						 * This is the last frame. Set
4398 						 * the NextChainOffset to 0 and
4399 						 * Length is the total size of
4400 						 * all remaining simple elements
4401 						 */
4402 						ddi_put8(p->m_acc_hdl,
4403 						    &sgechain->NextChainOffset,
4404 						    0);
4405 						ddi_put16(p->m_acc_hdl,
4406 						    &sgechain->Length,
4407 						    (cookiec - j) *
4408 						    sizeof (MPI2_SGE_SIMPLE64));
4409 					}
4410 
4411 					/* Jump to the next frame */
4412 					sge = (pMpi2SGESimple64_t)
4413 					    ((char *)p->m_frames_addr +
4414 					    (int)mpt->m_req_frame_size * k);
4415 
4416 					continue;
4417 				}
4418 
4419 				ddi_put32(p->m_acc_hdl,
4420 				    &sge->Address.Low,
4421 				    dmap->addr.address64.Low);
4422 				ddi_put32(p->m_acc_hdl,
4423 				    &sge->Address.High,
4424 				    dmap->addr.address64.High);
4425 				ddi_put32(p->m_acc_hdl,
4426 				    &sge->FlagsLength, dmap->count);
4427 				flags = ddi_get32(p->m_acc_hdl,
4428 				    &sge->FlagsLength);
4429 				flags |= ((uint32_t)(
4430 				    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4431 				    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4432 				    MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4433 				    MPI2_SGE_FLAGS_SHIFT);
4434 
4435 				/*
4436 				 * If we are at the end of the frame and
4437 				 * there is another frame to fill in
4438 				 * we set the last simple element as last
4439 				 * element
4440 				 */
4441 				if ((l == sgemax) && (k != frames)) {
4442 					flags |= ((uint32_t)
4443 					    (MPI2_SGE_FLAGS_LAST_ELEMENT) <<
4444 					    MPI2_SGE_FLAGS_SHIFT);
4445 				}
4446 
4447 				/*
4448 				 * If this is the final cookie we
4449 				 * indicate it by setting the flags
4450 				 */
4451 				if (j == i) {
4452 					flags |= ((uint32_t)
4453 					    (MPI2_SGE_FLAGS_LAST_ELEMENT |
4454 					    MPI2_SGE_FLAGS_END_OF_BUFFER |
4455 					    MPI2_SGE_FLAGS_END_OF_LIST) <<
4456 					    MPI2_SGE_FLAGS_SHIFT);
4457 				}
4458 				if (cmd->cmd_flags & CFLAG_DMASEND) {
4459 					flags |=
4460 					    (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4461 					    MPI2_SGE_FLAGS_SHIFT);
4462 				} else {
4463 					flags |=
4464 					    (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4465 					    MPI2_SGE_FLAGS_SHIFT);
4466 				}
4467 				ddi_put32(p->m_acc_hdl,
4468 				    &sge->FlagsLength, flags);
4469 				dmap++;
4470 				sge++;
4471 			}
4472 		}
4473 
4474 		/*
4475 		 * Sync DMA with the chain buffers that were just created
4476 		 */
4477 		(void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
4478 	}
4479 }
4480 
4481 /*
4482  * Interrupt handling
4483  * Utility routine.  Poll for status of a command sent to HBA
4484  * without interrupts (a FLAG_NOINTR command).
4485  */
4486 int
4487 mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime)
4488 {
4489 	int	rval = TRUE;
4490 
4491 	NDBG5(("mptsas_poll: cmd=0x%p", (void *)poll_cmd));
4492 
4493 	if ((poll_cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
4494 		mptsas_restart_hba(mpt);
4495 	}
4496 
4497 	/*
4498 	 * Wait, using drv_usecwait(), long enough for the command to
4499 	 * reasonably return from the target if the target isn't
4500 	 * "dead".  A polled command may well be sent from scsi_poll, and
4501 	 * there are retries built in to scsi_poll if the transport
4502 	 * accepted the packet (TRAN_ACCEPT).  scsi_poll waits 1 second
4503 	 * and retries the transport up to scsi_poll_busycnt times
4504 	 * (currently 60) if
4505 	 * 1. pkt_reason is CMD_INCOMPLETE and pkt_state is 0, or
4506 	 * 2. pkt_reason is CMD_CMPLT and *pkt_scbp has STATUS_BUSY
4507 	 *
4508 	 * limit the waiting to avoid a hang in the event that the
4509 	 * cmd never gets started but we are still receiving interrupts
4510 	 */
4511 	while (!(poll_cmd->cmd_flags & CFLAG_FINISHED)) {
4512 		if (mptsas_wait_intr(mpt, polltime) == FALSE) {
4513 			NDBG5(("mptsas_poll: command incomplete"));
4514 			rval = FALSE;
4515 			break;
4516 		}
4517 	}
4518 
4519 	if (rval == FALSE) {
4520 
4521 		/*
4522 		 * this isn't supposed to happen, the hba must be wedged
4523 		 * Mark this cmd as a timeout.
4524 		 */
4525 		mptsas_set_pkt_reason(mpt, poll_cmd, CMD_TIMEOUT,
4526 		    (STAT_TIMEOUT|STAT_ABORTED));
4527 
4528 		if (poll_cmd->cmd_queued == FALSE) {
4529 
4530 			NDBG5(("mptsas_poll: not on waitq"));
4531 
4532 			poll_cmd->cmd_pkt->pkt_state |=
4533 			    (STATE_GOT_BUS|STATE_GOT_TARGET|STATE_SENT_CMD);
4534 		} else {
4535 
4536 			/* find and remove it from the waitq */
4537 			NDBG5(("mptsas_poll: delete from waitq"));
4538 			mptsas_waitq_delete(mpt, poll_cmd);
4539 		}
4540 
4541 	}
4542 	mptsas_fma_check(mpt, poll_cmd);
4543 	NDBG5(("mptsas_poll: done"));
4544 	return (rval);
4545 }
4546 
4547 /*
4548  * Used for polling cmds and TM function
4549  */
4550 static int
4551 mptsas_wait_intr(mptsas_t *mpt, int polltime)
4552 {
4553 	int				cnt;
4554 	pMpi2ReplyDescriptorsUnion_t	reply_desc_union;
4555 	uint32_t			int_mask;
4556 
4557 	NDBG5(("mptsas_wait_intr"));
4558 
4559 	mpt->m_polled_intr = 1;
4560 
4561 	/*
4562 	 * Get the current interrupt mask and disable interrupts.  When
4563 	 * re-enabling ints, set mask to saved value.
4564 	 */
4565 	int_mask = ddi_get32(mpt->m_datap, &mpt->m_reg->HostInterruptMask);
4566 	MPTSAS_DISABLE_INTR(mpt);
4567 
4568 	/*
4569 	 * Keep polling for at least (polltime * 1000) seconds
4570 	 */
4571 	for (cnt = 0; cnt < polltime; cnt++) {
4572 		(void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
4573 		    DDI_DMA_SYNC_FORCPU);
4574 
4575 		reply_desc_union = (pMpi2ReplyDescriptorsUnion_t)
4576 		    MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index);
4577 
4578 		if (ddi_get32(mpt->m_acc_post_queue_hdl,
4579 		    &reply_desc_union->Words.Low) == 0xFFFFFFFF ||
4580 		    ddi_get32(mpt->m_acc_post_queue_hdl,
4581 		    &reply_desc_union->Words.High) == 0xFFFFFFFF) {
4582 			drv_usecwait(1000);
4583 			continue;
4584 		}
4585 
4586 		/*
4587 		 * The reply is valid, process it according to its
4588 		 * type.
4589 		 */
4590 		mptsas_process_intr(mpt, reply_desc_union);
4591 
4592 		if (++mpt->m_post_index == mpt->m_post_queue_depth) {
4593 			mpt->m_post_index = 0;
4594 		}
4595 
4596 		/*
4597 		 * Update the global reply index
4598 		 */
4599 		ddi_put32(mpt->m_datap,
4600 		    &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index);
4601 		mpt->m_polled_intr = 0;
4602 
4603 		/*
4604 		 * Re-enable interrupts and quit.
4605 		 */
4606 		ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask,
4607 		    int_mask);
4608 		return (TRUE);
4609 
4610 	}
4611 
4612 	/*
4613 	 * Clear polling flag, re-enable interrupts and quit.
4614 	 */
4615 	mpt->m_polled_intr = 0;
4616 	ddi_put32(mpt->m_datap, &mpt->m_reg->HostInterruptMask, int_mask);
4617 	return (FALSE);
4618 }
4619 
4620 static void
4621 mptsas_handle_scsi_io_success(mptsas_t *mpt,
4622     pMpi2ReplyDescriptorsUnion_t reply_desc)
4623 {
4624 	pMpi2SCSIIOSuccessReplyDescriptor_t	scsi_io_success;
4625 	uint16_t				SMID;
4626 	mptsas_slots_t				*slots = mpt->m_active;
4627 	mptsas_cmd_t				*cmd = NULL;
4628 	struct scsi_pkt				*pkt;
4629 
4630 	ASSERT(mutex_owned(&mpt->m_mutex));
4631 
4632 	scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc;
4633 	SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &scsi_io_success->SMID);
4634 
4635 	/*
4636 	 * This is a success reply so just complete the IO.  First, do a sanity
4637 	 * check on the SMID.  The final slot is used for TM requests, which
4638 	 * would not come into this reply handler.
4639 	 */
4640 	if ((SMID == 0) || (SMID > slots->m_n_slots)) {
4641 		mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n",
4642 		    SMID);
4643 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
4644 		return;
4645 	}
4646 
4647 	cmd = slots->m_slot[SMID];
4648 
4649 	/*
4650 	 * print warning and return if the slot is empty
4651 	 */
4652 	if (cmd == NULL) {
4653 		mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO "
4654 		    "in slot %d", SMID);
4655 		return;
4656 	}
4657 
4658 	pkt = CMD2PKT(cmd);
4659 	pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
4660 	    STATE_GOT_STATUS);
4661 	if (cmd->cmd_flags & CFLAG_DMAVALID) {
4662 		pkt->pkt_state |= STATE_XFERRED_DATA;
4663 	}
4664 	pkt->pkt_resid = 0;
4665 
4666 	if (cmd->cmd_flags & CFLAG_PASSTHRU) {
4667 		cmd->cmd_flags |= CFLAG_FINISHED;
4668 		cv_broadcast(&mpt->m_passthru_cv);
4669 		return;
4670 	} else {
4671 		mptsas_remove_cmd(mpt, cmd);
4672 	}
4673 
4674 	if (cmd->cmd_flags & CFLAG_RETRY) {
4675 		/*
4676 		 * The target returned QFULL or busy, do not add tihs
4677 		 * pkt to the doneq since the hba will retry
4678 		 * this cmd.
4679 		 *
4680 		 * The pkt has already been resubmitted in
4681 		 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error().
4682 		 * Remove this cmd_flag here.
4683 		 */
4684 		cmd->cmd_flags &= ~CFLAG_RETRY;
4685 	} else {
4686 		mptsas_doneq_add(mpt, cmd);
4687 	}
4688 }
4689 
4690 static void
4691 mptsas_handle_address_reply(mptsas_t *mpt,
4692     pMpi2ReplyDescriptorsUnion_t reply_desc)
4693 {
4694 	pMpi2AddressReplyDescriptor_t	address_reply;
4695 	pMPI2DefaultReply_t		reply;
4696 	mptsas_fw_diagnostic_buffer_t	*pBuffer;
4697 	uint32_t			reply_addr;
4698 	uint16_t			SMID, iocstatus, action;
4699 	mptsas_slots_t			*slots = mpt->m_active;
4700 	mptsas_cmd_t			*cmd = NULL;
4701 	uint8_t				function, buffer_type;
4702 	m_replyh_arg_t			*args;
4703 	int				reply_frame_no;
4704 
4705 	ASSERT(mutex_owned(&mpt->m_mutex));
4706 
4707 	address_reply = (pMpi2AddressReplyDescriptor_t)reply_desc;
4708 	reply_addr = ddi_get32(mpt->m_acc_post_queue_hdl,
4709 	    &address_reply->ReplyFrameAddress);
4710 	SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &address_reply->SMID);
4711 
4712 	/*
4713 	 * If reply frame is not in the proper range we should ignore this
4714 	 * message and exit the interrupt handler.
4715 	 */
4716 	if ((reply_addr < mpt->m_reply_frame_dma_addr) ||
4717 	    (reply_addr >= (mpt->m_reply_frame_dma_addr +
4718 	    (mpt->m_reply_frame_size * mpt->m_free_queue_depth))) ||
4719 	    ((reply_addr - mpt->m_reply_frame_dma_addr) %
4720 	    mpt->m_reply_frame_size != 0)) {
4721 		mptsas_log(mpt, CE_WARN, "?Received invalid reply frame "
4722 		    "address 0x%x\n", reply_addr);
4723 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
4724 		return;
4725 	}
4726 
4727 	(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
4728 	    DDI_DMA_SYNC_FORCPU);
4729 	reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame + (reply_addr -
4730 	    mpt->m_reply_frame_dma_addr));
4731 	function = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Function);
4732 
4733 	/*
4734 	 * don't get slot information and command for events since these values
4735 	 * don't exist
4736 	 */
4737 	if ((function != MPI2_FUNCTION_EVENT_NOTIFICATION) &&
4738 	    (function != MPI2_FUNCTION_DIAG_BUFFER_POST)) {
4739 		/*
4740 		 * If this is a raid action reply for system shutdown just exit
4741 		 * because the reply doesn't matter.  Signal that we got the
4742 		 * reply even though it's not really necessary since we're
4743 		 * shutting down.
4744 		 */
4745 		if (function == MPI2_FUNCTION_RAID_ACTION) {
4746 			action = ddi_get16(mpt->m_acc_reply_frame_hdl,
4747 			    &reply->FunctionDependent1);
4748 			if (action ==
4749 			    MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED) {
4750 				cv_broadcast(&mpt->m_fw_diag_cv);
4751 				return;
4752 			}
4753 		}
4754 
4755 		/*
4756 		 * This could be a TM reply, which use the last allocated SMID,
4757 		 * so allow for that.
4758 		 */
4759 		if ((SMID == 0) || (SMID > (slots->m_n_slots + 1))) {
4760 			mptsas_log(mpt, CE_WARN, "?Received invalid SMID of "
4761 			    "%d\n", SMID);
4762 			ddi_fm_service_impact(mpt->m_dip,
4763 			    DDI_SERVICE_UNAFFECTED);
4764 			return;
4765 		}
4766 
4767 		cmd = slots->m_slot[SMID];
4768 
4769 		/*
4770 		 * print warning and return if the slot is empty
4771 		 */
4772 		if (cmd == NULL) {
4773 			mptsas_log(mpt, CE_WARN, "?NULL command for address "
4774 			    "reply in slot %d", SMID);
4775 			return;
4776 		}
4777 		if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
4778 		    (cmd->cmd_flags & CFLAG_CONFIG) ||
4779 		    (cmd->cmd_flags & CFLAG_FW_DIAG)) {
4780 			cmd->cmd_rfm = reply_addr;
4781 			cmd->cmd_flags |= CFLAG_FINISHED;
4782 			cv_broadcast(&mpt->m_passthru_cv);
4783 			cv_broadcast(&mpt->m_config_cv);
4784 			cv_broadcast(&mpt->m_fw_diag_cv);
4785 			return;
4786 		} else if (!(cmd->cmd_flags & CFLAG_FW_CMD)) {
4787 			mptsas_remove_cmd(mpt, cmd);
4788 		}
4789 		NDBG31(("\t\tmptsas_process_intr: slot=%d", SMID));
4790 	}
4791 	/*
4792 	 * Depending on the function, we need to handle
4793 	 * the reply frame (and cmd) differently.
4794 	 */
4795 	switch (function) {
4796 	case MPI2_FUNCTION_SCSI_IO_REQUEST:
4797 		mptsas_check_scsi_io_error(mpt, (pMpi2SCSIIOReply_t)reply, cmd);
4798 		break;
4799 	case MPI2_FUNCTION_SCSI_TASK_MGMT:
4800 		mptsas_check_task_mgt(mpt, (pMpi2SCSIManagementReply_t)reply,
4801 		    cmd);
4802 		break;
4803 	case MPI2_FUNCTION_FW_DOWNLOAD:
4804 		cmd->cmd_flags |= CFLAG_FINISHED;
4805 		cv_signal(&mpt->m_fw_cv);
4806 		break;
4807 	case MPI2_FUNCTION_EVENT_NOTIFICATION:
4808 		reply_frame_no = (reply_addr - mpt->m_reply_frame_dma_addr) /
4809 		    mpt->m_reply_frame_size;
4810 		args = &mpt->m_replyh_args[reply_frame_no];
4811 		args->mpt = (void *)mpt;
4812 		args->rfm = reply_addr;
4813 
4814 		/*
4815 		 * Record the event if its type is enabled in
4816 		 * this mpt instance by ioctl.
4817 		 */
4818 		mptsas_record_event(args);
4819 
4820 		/*
4821 		 * Handle time critical events
4822 		 * NOT_RESPONDING/ADDED only now
4823 		 */
4824 		if (mptsas_handle_event_sync(args) == DDI_SUCCESS) {
4825 			/*
4826 			 * Would not return main process,
4827 			 * just let taskq resolve ack action
4828 			 * and ack would be sent in taskq thread
4829 			 */
4830 			NDBG20(("send mptsas_handle_event_sync success"));
4831 		}
4832 		if ((ddi_taskq_dispatch(mpt->m_event_taskq, mptsas_handle_event,
4833 		    (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) {
4834 			mptsas_log(mpt, CE_WARN, "No memory available"
4835 			"for dispatch taskq");
4836 			/*
4837 			 * Return the reply frame to the free queue.
4838 			 */
4839 			ddi_put32(mpt->m_acc_free_queue_hdl,
4840 			    &((uint32_t *)(void *)
4841 			    mpt->m_free_queue)[mpt->m_free_index], reply_addr);
4842 			(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
4843 			    DDI_DMA_SYNC_FORDEV);
4844 			if (++mpt->m_free_index == mpt->m_free_queue_depth) {
4845 				mpt->m_free_index = 0;
4846 			}
4847 
4848 			ddi_put32(mpt->m_datap,
4849 			    &mpt->m_reg->ReplyFreeHostIndex, mpt->m_free_index);
4850 		}
4851 		return;
4852 	case MPI2_FUNCTION_DIAG_BUFFER_POST:
4853 		/*
4854 		 * If SMID is 0, this implies that the reply is due to a
4855 		 * release function with a status that the buffer has been
4856 		 * released.  Set the buffer flags accordingly.
4857 		 */
4858 		if (SMID == 0) {
4859 			iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
4860 			    &reply->IOCStatus);
4861 			buffer_type = ddi_get8(mpt->m_acc_reply_frame_hdl,
4862 			    &(((pMpi2DiagBufferPostReply_t)reply)->BufferType));
4863 			if (iocstatus == MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED) {
4864 				pBuffer =
4865 				    &mpt->m_fw_diag_buffer_list[buffer_type];
4866 				pBuffer->valid_data = TRUE;
4867 				pBuffer->owned_by_firmware = FALSE;
4868 				pBuffer->immediate = FALSE;
4869 			}
4870 		} else {
4871 			/*
4872 			 * Normal handling of diag post reply with SMID.
4873 			 */
4874 			cmd = slots->m_slot[SMID];
4875 
4876 			/*
4877 			 * print warning and return if the slot is empty
4878 			 */
4879 			if (cmd == NULL) {
4880 				mptsas_log(mpt, CE_WARN, "?NULL command for "
4881 				    "address reply in slot %d", SMID);
4882 				return;
4883 			}
4884 			cmd->cmd_rfm = reply_addr;
4885 			cmd->cmd_flags |= CFLAG_FINISHED;
4886 			cv_broadcast(&mpt->m_fw_diag_cv);
4887 		}
4888 		return;
4889 	default:
4890 		mptsas_log(mpt, CE_WARN, "Unknown function 0x%x ", function);
4891 		break;
4892 	}
4893 
4894 	/*
4895 	 * Return the reply frame to the free queue.
4896 	 */
4897 	ddi_put32(mpt->m_acc_free_queue_hdl,
4898 	    &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
4899 	    reply_addr);
4900 	(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
4901 	    DDI_DMA_SYNC_FORDEV);
4902 	if (++mpt->m_free_index == mpt->m_free_queue_depth) {
4903 		mpt->m_free_index = 0;
4904 	}
4905 	ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
4906 	    mpt->m_free_index);
4907 
4908 	if (cmd->cmd_flags & CFLAG_FW_CMD)
4909 		return;
4910 
4911 	if (cmd->cmd_flags & CFLAG_RETRY) {
4912 		/*
4913 		 * The target returned QFULL or busy, do not add tihs
4914 		 * pkt to the doneq since the hba will retry
4915 		 * this cmd.
4916 		 *
4917 		 * The pkt has already been resubmitted in
4918 		 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error().
4919 		 * Remove this cmd_flag here.
4920 		 */
4921 		cmd->cmd_flags &= ~CFLAG_RETRY;
4922 	} else {
4923 		mptsas_doneq_add(mpt, cmd);
4924 	}
4925 }
4926 
4927 static void
4928 mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply,
4929     mptsas_cmd_t *cmd)
4930 {
4931 	uint8_t			scsi_status, scsi_state;
4932 	uint16_t		ioc_status;
4933 	uint32_t		xferred, sensecount, responsedata, loginfo = 0;
4934 	struct scsi_pkt		*pkt;
4935 	struct scsi_arq_status	*arqstat;
4936 	struct buf		*bp;
4937 	mptsas_target_t		*ptgt = cmd->cmd_tgt_addr;
4938 	uint8_t			*sensedata = NULL;
4939 
4940 	if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) ==
4941 	    (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) {
4942 		bp = cmd->cmd_ext_arq_buf;
4943 	} else {
4944 		bp = cmd->cmd_arq_buf;
4945 	}
4946 
4947 	scsi_status = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIStatus);
4948 	ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus);
4949 	scsi_state = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIState);
4950 	xferred = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->TransferCount);
4951 	sensecount = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->SenseCount);
4952 	responsedata = ddi_get32(mpt->m_acc_reply_frame_hdl,
4953 	    &reply->ResponseInfo);
4954 
4955 	if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
4956 		loginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
4957 		    &reply->IOCLogInfo);
4958 		mptsas_log(mpt, CE_NOTE,
4959 		    "?Log info 0x%x received for target %d.\n"
4960 		    "\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x",
4961 		    loginfo, Tgt(cmd), scsi_status, ioc_status,
4962 		    scsi_state);
4963 	}
4964 
4965 	NDBG31(("\t\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x",
4966 	    scsi_status, ioc_status, scsi_state));
4967 
4968 	pkt = CMD2PKT(cmd);
4969 	*(pkt->pkt_scbp) = scsi_status;
4970 
4971 	if (loginfo == 0x31170000) {
4972 		/*
4973 		 * if loginfo PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY
4974 		 * 0x31170000 comes, that means the device missing delay
4975 		 * is in progressing, the command need retry later.
4976 		 */
4977 		*(pkt->pkt_scbp) = STATUS_BUSY;
4978 		return;
4979 	}
4980 
4981 	if ((scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS) &&
4982 	    ((ioc_status & MPI2_IOCSTATUS_MASK) ==
4983 	    MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE)) {
4984 		pkt->pkt_reason = CMD_INCOMPLETE;
4985 		pkt->pkt_state |= STATE_GOT_BUS;
4986 		if (ptgt->m_reset_delay == 0) {
4987 			mptsas_set_throttle(mpt, ptgt,
4988 			    DRAIN_THROTTLE);
4989 		}
4990 		return;
4991 	}
4992 
4993 	if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) {
4994 		responsedata &= 0x000000FF;
4995 		if (responsedata & MPTSAS_SCSI_RESPONSE_CODE_TLR_OFF) {
4996 			mptsas_log(mpt, CE_NOTE, "Do not support the TLR\n");
4997 			pkt->pkt_reason = CMD_TLR_OFF;
4998 			return;
4999 		}
5000 	}
5001 
5002 
5003 	switch (scsi_status) {
5004 	case MPI2_SCSI_STATUS_CHECK_CONDITION:
5005 		pkt->pkt_resid = (cmd->cmd_dmacount - xferred);
5006 		arqstat = (void*)(pkt->pkt_scbp);
5007 		arqstat->sts_rqpkt_status = *((struct scsi_status *)
5008 		    (pkt->pkt_scbp));
5009 		pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
5010 		    STATE_SENT_CMD | STATE_GOT_STATUS | STATE_ARQ_DONE);
5011 		if (cmd->cmd_flags & CFLAG_XARQ) {
5012 			pkt->pkt_state |= STATE_XARQ_DONE;
5013 		}
5014 		if (pkt->pkt_resid != cmd->cmd_dmacount) {
5015 			pkt->pkt_state |= STATE_XFERRED_DATA;
5016 		}
5017 		arqstat->sts_rqpkt_reason = pkt->pkt_reason;
5018 		arqstat->sts_rqpkt_state  = pkt->pkt_state;
5019 		arqstat->sts_rqpkt_state |= STATE_XFERRED_DATA;
5020 		arqstat->sts_rqpkt_statistics = pkt->pkt_statistics;
5021 		sensedata = (uint8_t *)&arqstat->sts_sensedata;
5022 
5023 		bcopy((uchar_t *)bp->b_un.b_addr, sensedata,
5024 		    ((cmd->cmd_rqslen >= sensecount) ? sensecount :
5025 		    cmd->cmd_rqslen));
5026 		arqstat->sts_rqpkt_resid = (cmd->cmd_rqslen - sensecount);
5027 		cmd->cmd_flags |= CFLAG_CMDARQ;
5028 		/*
5029 		 * Set proper status for pkt if autosense was valid
5030 		 */
5031 		if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
5032 			struct scsi_status zero_status = { 0 };
5033 			arqstat->sts_rqpkt_status = zero_status;
5034 		}
5035 
5036 		/*
5037 		 * ASC=0x47 is parity error
5038 		 * ASC=0x48 is initiator detected error received
5039 		 */
5040 		if ((scsi_sense_key(sensedata) == KEY_ABORTED_COMMAND) &&
5041 		    ((scsi_sense_asc(sensedata) == 0x47) ||
5042 		    (scsi_sense_asc(sensedata) == 0x48))) {
5043 			mptsas_log(mpt, CE_NOTE, "Aborted_command!");
5044 		}
5045 
5046 		/*
5047 		 * ASC/ASCQ=0x3F/0x0E means report_luns data changed
5048 		 * ASC/ASCQ=0x25/0x00 means invalid lun
5049 		 */
5050 		if (((scsi_sense_key(sensedata) == KEY_UNIT_ATTENTION) &&
5051 		    (scsi_sense_asc(sensedata) == 0x3F) &&
5052 		    (scsi_sense_ascq(sensedata) == 0x0E)) ||
5053 		    ((scsi_sense_key(sensedata) == KEY_ILLEGAL_REQUEST) &&
5054 		    (scsi_sense_asc(sensedata) == 0x25) &&
5055 		    (scsi_sense_ascq(sensedata) == 0x00))) {
5056 			mptsas_topo_change_list_t *topo_node = NULL;
5057 
5058 			topo_node = kmem_zalloc(
5059 			    sizeof (mptsas_topo_change_list_t),
5060 			    KM_NOSLEEP);
5061 			if (topo_node == NULL) {
5062 				mptsas_log(mpt, CE_NOTE, "No memory"
5063 				    "resource for handle SAS dynamic"
5064 				    "reconfigure.\n");
5065 				break;
5066 			}
5067 			topo_node->mpt = mpt;
5068 			topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET;
5069 			topo_node->un.phymask = ptgt->m_phymask;
5070 			topo_node->devhdl = ptgt->m_devhdl;
5071 			topo_node->object = (void *)ptgt;
5072 			topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED;
5073 
5074 			if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
5075 			    mptsas_handle_dr,
5076 			    (void *)topo_node,
5077 			    DDI_NOSLEEP)) != DDI_SUCCESS) {
5078 				mptsas_log(mpt, CE_NOTE, "mptsas start taskq"
5079 				    "for handle SAS dynamic reconfigure"
5080 				    "failed. \n");
5081 			}
5082 		}
5083 		break;
5084 	case MPI2_SCSI_STATUS_GOOD:
5085 		switch (ioc_status & MPI2_IOCSTATUS_MASK) {
5086 		case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
5087 			pkt->pkt_reason = CMD_DEV_GONE;
5088 			pkt->pkt_state |= STATE_GOT_BUS;
5089 			if (ptgt->m_reset_delay == 0) {
5090 				mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5091 			}
5092 			NDBG31(("lost disk for target%d, command:%x",
5093 			    Tgt(cmd), pkt->pkt_cdbp[0]));
5094 			break;
5095 		case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
5096 			NDBG31(("data overrun: xferred=%d", xferred));
5097 			NDBG31(("dmacount=%d", cmd->cmd_dmacount));
5098 			pkt->pkt_reason = CMD_DATA_OVR;
5099 			pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET
5100 			    | STATE_SENT_CMD | STATE_GOT_STATUS
5101 			    | STATE_XFERRED_DATA);
5102 			pkt->pkt_resid = 0;
5103 			break;
5104 		case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
5105 		case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
5106 			NDBG31(("data underrun: xferred=%d", xferred));
5107 			NDBG31(("dmacount=%d", cmd->cmd_dmacount));
5108 			pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET
5109 			    | STATE_SENT_CMD | STATE_GOT_STATUS);
5110 			pkt->pkt_resid = (cmd->cmd_dmacount - xferred);
5111 			if (pkt->pkt_resid != cmd->cmd_dmacount) {
5112 				pkt->pkt_state |= STATE_XFERRED_DATA;
5113 			}
5114 			break;
5115 		case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
5116 			mptsas_set_pkt_reason(mpt,
5117 			    cmd, CMD_RESET, STAT_BUS_RESET);
5118 			break;
5119 		case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
5120 		case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
5121 			mptsas_set_pkt_reason(mpt,
5122 			    cmd, CMD_RESET, STAT_DEV_RESET);
5123 			break;
5124 		case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
5125 		case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
5126 			pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET);
5127 			mptsas_set_pkt_reason(mpt,
5128 			    cmd, CMD_TERMINATED, STAT_TERMINATED);
5129 			break;
5130 		case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
5131 		case MPI2_IOCSTATUS_BUSY:
5132 			/*
5133 			 * set throttles to drain
5134 			 */
5135 			ptgt = (mptsas_target_t *)mptsas_hash_traverse(
5136 			    &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
5137 			while (ptgt != NULL) {
5138 				mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5139 
5140 				ptgt = (mptsas_target_t *)mptsas_hash_traverse(
5141 				    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
5142 			}
5143 
5144 			/*
5145 			 * retry command
5146 			 */
5147 			cmd->cmd_flags |= CFLAG_RETRY;
5148 			cmd->cmd_pkt_flags |= FLAG_HEAD;
5149 
5150 			(void) mptsas_accept_pkt(mpt, cmd);
5151 			break;
5152 		default:
5153 			mptsas_log(mpt, CE_WARN,
5154 			    "unknown ioc_status = %x\n", ioc_status);
5155 			mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer "
5156 			    "count = %x, scsi_status = %x", scsi_state,
5157 			    xferred, scsi_status);
5158 			break;
5159 		}
5160 		break;
5161 	case MPI2_SCSI_STATUS_TASK_SET_FULL:
5162 		mptsas_handle_qfull(mpt, cmd);
5163 		break;
5164 	case MPI2_SCSI_STATUS_BUSY:
5165 		NDBG31(("scsi_status busy received"));
5166 		break;
5167 	case MPI2_SCSI_STATUS_RESERVATION_CONFLICT:
5168 		NDBG31(("scsi_status reservation conflict received"));
5169 		break;
5170 	default:
5171 		mptsas_log(mpt, CE_WARN, "scsi_status=%x, ioc_status=%x\n",
5172 		    scsi_status, ioc_status);
5173 		mptsas_log(mpt, CE_WARN,
5174 		    "mptsas_process_intr: invalid scsi status\n");
5175 		break;
5176 	}
5177 }
5178 
5179 static void
5180 mptsas_check_task_mgt(mptsas_t *mpt, pMpi2SCSIManagementReply_t reply,
5181 	mptsas_cmd_t *cmd)
5182 {
5183 	uint8_t		task_type;
5184 	uint16_t	ioc_status;
5185 	uint32_t	log_info;
5186 	uint16_t	dev_handle;
5187 	struct scsi_pkt *pkt = CMD2PKT(cmd);
5188 
5189 	task_type = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->TaskType);
5190 	ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus);
5191 	log_info = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo);
5192 	dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->DevHandle);
5193 
5194 	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
5195 		mptsas_log(mpt, CE_WARN, "mptsas_check_task_mgt: Task 0x%x "
5196 		    "failed. IOCStatus=0x%x IOCLogInfo=0x%x target=%d\n",
5197 		    task_type, ioc_status, log_info, dev_handle);
5198 		pkt->pkt_reason = CMD_INCOMPLETE;
5199 		return;
5200 	}
5201 
5202 	switch (task_type) {
5203 	case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
5204 	case MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET:
5205 	case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK:
5206 	case MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA:
5207 	case MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET:
5208 	case MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION:
5209 		break;
5210 	case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
5211 	case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
5212 	case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
5213 		mptsas_flush_target(mpt, dev_handle, Lun(cmd), task_type);
5214 		break;
5215 	default:
5216 		mptsas_log(mpt, CE_WARN, "Unknown task management type %d.",
5217 		    task_type);
5218 		mptsas_log(mpt, CE_WARN, "ioc status = %x", ioc_status);
5219 		break;
5220 	}
5221 }
5222 
5223 static void
5224 mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg)
5225 {
5226 	mptsas_t			*mpt = arg->mpt;
5227 	uint64_t			t = arg->t;
5228 	mptsas_cmd_t			*cmd;
5229 	struct scsi_pkt			*pkt;
5230 	mptsas_doneq_thread_list_t	*item = &mpt->m_doneq_thread_id[t];
5231 
5232 	mutex_enter(&item->mutex);
5233 	while (item->flag & MPTSAS_DONEQ_THREAD_ACTIVE) {
5234 		if (!item->doneq) {
5235 			cv_wait(&item->cv, &item->mutex);
5236 		}
5237 		pkt = NULL;
5238 		if ((cmd = mptsas_doneq_thread_rm(mpt, t)) != NULL) {
5239 			cmd->cmd_flags |= CFLAG_COMPLETED;
5240 			pkt = CMD2PKT(cmd);
5241 		}
5242 		mutex_exit(&item->mutex);
5243 		if (pkt) {
5244 			mptsas_pkt_comp(pkt, cmd);
5245 		}
5246 		mutex_enter(&item->mutex);
5247 	}
5248 	mutex_exit(&item->mutex);
5249 	mutex_enter(&mpt->m_doneq_mutex);
5250 	mpt->m_doneq_thread_n--;
5251 	cv_broadcast(&mpt->m_doneq_thread_cv);
5252 	mutex_exit(&mpt->m_doneq_mutex);
5253 }
5254 
5255 
5256 /*
5257  * mpt interrupt handler.
5258  */
5259 static uint_t
5260 mptsas_intr(caddr_t arg1, caddr_t arg2)
5261 {
5262 	mptsas_t			*mpt = (void *)arg1;
5263 	pMpi2ReplyDescriptorsUnion_t	reply_desc_union;
5264 	uchar_t				did_reply = FALSE;
5265 
5266 	NDBG1(("mptsas_intr: arg1 0x%p arg2 0x%p", (void *)arg1, (void *)arg2));
5267 
5268 	mutex_enter(&mpt->m_mutex);
5269 
5270 	/*
5271 	 * If interrupts are shared by two channels then check whether this
5272 	 * interrupt is genuinely for this channel by making sure first the
5273 	 * chip is in high power state.
5274 	 */
5275 	if ((mpt->m_options & MPTSAS_OPT_PM) &&
5276 	    (mpt->m_power_level != PM_LEVEL_D0)) {
5277 		mutex_exit(&mpt->m_mutex);
5278 		return (DDI_INTR_UNCLAIMED);
5279 	}
5280 
5281 	/*
5282 	 * If polling, interrupt was triggered by some shared interrupt because
5283 	 * IOC interrupts are disabled during polling, so polling routine will
5284 	 * handle any replies.  Considering this, if polling is happening,
5285 	 * return with interrupt unclaimed.
5286 	 */
5287 	if (mpt->m_polled_intr) {
5288 		mutex_exit(&mpt->m_mutex);
5289 		mptsas_log(mpt, CE_WARN, "mpt_sas: Unclaimed interrupt");
5290 		return (DDI_INTR_UNCLAIMED);
5291 	}
5292 
5293 	/*
5294 	 * Read the istat register.
5295 	 */
5296 	if ((INTPENDING(mpt)) != 0) {
5297 		/*
5298 		 * read fifo until empty.
5299 		 */
5300 #ifndef __lock_lint
5301 		_NOTE(CONSTCOND)
5302 #endif
5303 		while (TRUE) {
5304 			(void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
5305 			    DDI_DMA_SYNC_FORCPU);
5306 			reply_desc_union = (pMpi2ReplyDescriptorsUnion_t)
5307 			    MPTSAS_GET_NEXT_REPLY(mpt, mpt->m_post_index);
5308 
5309 			if (ddi_get32(mpt->m_acc_post_queue_hdl,
5310 			    &reply_desc_union->Words.Low) == 0xFFFFFFFF ||
5311 			    ddi_get32(mpt->m_acc_post_queue_hdl,
5312 			    &reply_desc_union->Words.High) == 0xFFFFFFFF) {
5313 				break;
5314 			}
5315 
5316 			/*
5317 			 * The reply is valid, process it according to its
5318 			 * type.  Also, set a flag for updating the reply index
5319 			 * after they've all been processed.
5320 			 */
5321 			did_reply = TRUE;
5322 
5323 			mptsas_process_intr(mpt, reply_desc_union);
5324 
5325 			/*
5326 			 * Increment post index and roll over if needed.
5327 			 */
5328 			if (++mpt->m_post_index == mpt->m_post_queue_depth) {
5329 				mpt->m_post_index = 0;
5330 			}
5331 		}
5332 
5333 		/*
5334 		 * Update the global reply index if at least one reply was
5335 		 * processed.
5336 		 */
5337 		if (did_reply) {
5338 			ddi_put32(mpt->m_datap,
5339 			    &mpt->m_reg->ReplyPostHostIndex, mpt->m_post_index);
5340 		}
5341 	} else {
5342 		mutex_exit(&mpt->m_mutex);
5343 		return (DDI_INTR_UNCLAIMED);
5344 	}
5345 	NDBG1(("mptsas_intr complete"));
5346 
5347 	/*
5348 	 * If no helper threads are created, process the doneq in ISR. If
5349 	 * helpers are created, use the doneq length as a metric to measure the
5350 	 * load on the interrupt CPU. If it is long enough, which indicates the
5351 	 * load is heavy, then we deliver the IO completions to the helpers.
5352 	 * This measurement has some limitations, although it is simple and
5353 	 * straightforward and works well for most of the cases at present.
5354 	 */
5355 	if (!mpt->m_doneq_thread_n ||
5356 	    (mpt->m_doneq_len <= mpt->m_doneq_length_threshold)) {
5357 		mptsas_doneq_empty(mpt);
5358 	} else {
5359 		mptsas_deliver_doneq_thread(mpt);
5360 	}
5361 
5362 	/*
5363 	 * If there are queued cmd, start them now.
5364 	 */
5365 	if (mpt->m_waitq != NULL) {
5366 		mptsas_restart_waitq(mpt);
5367 	}
5368 
5369 	mutex_exit(&mpt->m_mutex);
5370 	return (DDI_INTR_CLAIMED);
5371 }
5372 
5373 static void
5374 mptsas_process_intr(mptsas_t *mpt,
5375     pMpi2ReplyDescriptorsUnion_t reply_desc_union)
5376 {
5377 	uint8_t	reply_type;
5378 
5379 	ASSERT(mutex_owned(&mpt->m_mutex));
5380 
5381 	/*
5382 	 * The reply is valid, process it according to its
5383 	 * type.  Also, set a flag for updated the reply index
5384 	 * after they've all been processed.
5385 	 */
5386 	reply_type = ddi_get8(mpt->m_acc_post_queue_hdl,
5387 	    &reply_desc_union->Default.ReplyFlags);
5388 	reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
5389 	if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) {
5390 		mptsas_handle_scsi_io_success(mpt, reply_desc_union);
5391 	} else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
5392 		mptsas_handle_address_reply(mpt, reply_desc_union);
5393 	} else {
5394 		mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type);
5395 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5396 	}
5397 
5398 	/*
5399 	 * Clear the reply descriptor for re-use and increment
5400 	 * index.
5401 	 */
5402 	ddi_put64(mpt->m_acc_post_queue_hdl,
5403 	    &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index],
5404 	    0xFFFFFFFFFFFFFFFF);
5405 	(void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
5406 	    DDI_DMA_SYNC_FORDEV);
5407 }
5408 
5409 /*
5410  * handle qfull condition
5411  */
5412 static void
5413 mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd)
5414 {
5415 	mptsas_target_t	*ptgt = cmd->cmd_tgt_addr;
5416 
5417 	if ((++cmd->cmd_qfull_retries > ptgt->m_qfull_retries) ||
5418 	    (ptgt->m_qfull_retries == 0)) {
5419 		/*
5420 		 * We have exhausted the retries on QFULL, or,
5421 		 * the target driver has indicated that it
5422 		 * wants to handle QFULL itself by setting
5423 		 * qfull-retries capability to 0. In either case
5424 		 * we want the target driver's QFULL handling
5425 		 * to kick in. We do this by having pkt_reason
5426 		 * as CMD_CMPLT and pkt_scbp as STATUS_QFULL.
5427 		 */
5428 		mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5429 	} else {
5430 		if (ptgt->m_reset_delay == 0) {
5431 			ptgt->m_t_throttle =
5432 			    max((ptgt->m_t_ncmds - 2), 0);
5433 		}
5434 
5435 		cmd->cmd_pkt_flags |= FLAG_HEAD;
5436 		cmd->cmd_flags &= ~(CFLAG_TRANFLAG);
5437 		cmd->cmd_flags |= CFLAG_RETRY;
5438 
5439 		(void) mptsas_accept_pkt(mpt, cmd);
5440 
5441 		/*
5442 		 * when target gives queue full status with no commands
5443 		 * outstanding (m_t_ncmds == 0), throttle is set to 0
5444 		 * (HOLD_THROTTLE), and the queue full handling start
5445 		 * (see psarc/1994/313); if there are commands outstanding,
5446 		 * throttle is set to (m_t_ncmds - 2)
5447 		 */
5448 		if (ptgt->m_t_throttle == HOLD_THROTTLE) {
5449 			/*
5450 			 * By setting throttle to QFULL_THROTTLE, we
5451 			 * avoid submitting new commands and in
5452 			 * mptsas_restart_cmd find out slots which need
5453 			 * their throttles to be cleared.
5454 			 */
5455 			mptsas_set_throttle(mpt, ptgt, QFULL_THROTTLE);
5456 			if (mpt->m_restart_cmd_timeid == 0) {
5457 				mpt->m_restart_cmd_timeid =
5458 				    timeout(mptsas_restart_cmd, mpt,
5459 				    ptgt->m_qfull_retry_interval);
5460 			}
5461 		}
5462 	}
5463 }
5464 
5465 uint8_t
5466 mptsas_phymask_to_physport(mptsas_t *mpt, uint8_t phymask)
5467 {
5468 	int i;
5469 
5470 	/*
5471 	 * RAID doesn't have valid phymask and physport so we use phymask == 0
5472 	 * and physport == 0xff to indicate that it's RAID.
5473 	 */
5474 	if (phymask == 0) {
5475 		return (0xff);
5476 	}
5477 	for (i = 0; i < 8; i++) {
5478 		if (phymask & (1 << i)) {
5479 			break;
5480 		}
5481 	}
5482 	return (mpt->m_phy_info[i].port_num);
5483 }
5484 uint8_t
5485 mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport)
5486 {
5487 	uint8_t		phy_mask = 0;
5488 	uint8_t		i = 0;
5489 
5490 	NDBG20(("mptsas%d physport_to_phymask enter", mpt->m_instance));
5491 
5492 	ASSERT(mutex_owned(&mpt->m_mutex));
5493 
5494 	/*
5495 	 * If physport is 0xFF, this is a RAID volume.  Use phymask of 0.
5496 	 */
5497 	if (physport == 0xFF) {
5498 		return (0);
5499 	}
5500 
5501 	for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
5502 		if (mpt->m_phy_info[i].attached_devhdl &&
5503 		    (mpt->m_phy_info[i].phy_mask != 0) &&
5504 		    (mpt->m_phy_info[i].port_num == physport)) {
5505 			phy_mask = mpt->m_phy_info[i].phy_mask;
5506 			break;
5507 		}
5508 	}
5509 	NDBG20(("mptsas%d physport_to_phymask:physport :%x phymask :%x, ",
5510 	    mpt->m_instance, physport, phy_mask));
5511 	return (phy_mask);
5512 }
5513 
5514 /*
5515  * mpt free device handle after device gone, by use of passthrough
5516  */
5517 static int
5518 mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl)
5519 {
5520 	Mpi2SasIoUnitControlRequest_t	req;
5521 	Mpi2SasIoUnitControlReply_t	rep;
5522 	int				ret;
5523 
5524 	ASSERT(mutex_owned(&mpt->m_mutex));
5525 
5526 	/*
5527 	 * Need to compose a SAS IO Unit Control request message
5528 	 * and call mptsas_do_passthru() function
5529 	 */
5530 	bzero(&req, sizeof (req));
5531 	bzero(&rep, sizeof (rep));
5532 
5533 	req.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
5534 	req.Operation = MPI2_SAS_OP_REMOVE_DEVICE;
5535 	req.DevHandle = LE_16(devhdl);
5536 
5537 	ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL,
5538 	    sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL);
5539 	if (ret != 0) {
5540 		cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit "
5541 		    "Control error %d", ret);
5542 		return (DDI_FAILURE);
5543 	}
5544 
5545 	/* do passthrough success, check the ioc status */
5546 	if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
5547 		cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit "
5548 		    "Control IOCStatus %d", LE_16(rep.IOCStatus));
5549 		return (DDI_FAILURE);
5550 	}
5551 
5552 	return (DDI_SUCCESS);
5553 }
5554 
5555 static void
5556 mptsas_update_phymask(mptsas_t *mpt)
5557 {
5558 	uint8_t	mask = 0, phy_mask;
5559 	char	*phy_mask_name;
5560 	uint8_t current_port;
5561 	int	i, j;
5562 
5563 	NDBG20(("mptsas%d update phymask ", mpt->m_instance));
5564 
5565 	ASSERT(mutex_owned(&mpt->m_mutex));
5566 
5567 	(void) mptsas_get_sas_io_unit_page(mpt);
5568 
5569 	phy_mask_name = kmem_zalloc(8, KM_SLEEP);
5570 
5571 	for (i = 0; i < mpt->m_num_phys; i++) {
5572 		phy_mask = 0x00;
5573 
5574 		if (mpt->m_phy_info[i].attached_devhdl == 0)
5575 			continue;
5576 
5577 		bzero(phy_mask_name, sizeof (phy_mask_name));
5578 
5579 		current_port = mpt->m_phy_info[i].port_num;
5580 
5581 		if ((mask & (1 << i)) != 0)
5582 			continue;
5583 
5584 		for (j = 0; j < mpt->m_num_phys; j++) {
5585 			if (mpt->m_phy_info[j].attached_devhdl &&
5586 			    (mpt->m_phy_info[j].port_num == current_port)) {
5587 				phy_mask |= (1 << j);
5588 			}
5589 		}
5590 		mask = mask | phy_mask;
5591 
5592 		for (j = 0; j < mpt->m_num_phys; j++) {
5593 			if ((phy_mask >> j) & 0x01) {
5594 				mpt->m_phy_info[j].phy_mask = phy_mask;
5595 			}
5596 		}
5597 
5598 		(void) sprintf(phy_mask_name, "%x", phy_mask);
5599 
5600 		mutex_exit(&mpt->m_mutex);
5601 		/*
5602 		 * register a iport, if the port has already been existed
5603 		 * SCSA will do nothing and just return.
5604 		 */
5605 		(void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name);
5606 		mutex_enter(&mpt->m_mutex);
5607 	}
5608 	kmem_free(phy_mask_name, 8);
5609 	NDBG20(("mptsas%d update phymask return", mpt->m_instance));
5610 }
5611 
5612 /*
5613  * mptsas_handle_dr is a task handler for DR, the DR action includes:
5614  * 1. Directly attched Device Added/Removed.
5615  * 2. Expander Device Added/Removed.
5616  * 3. Indirectly Attached Device Added/Expander.
5617  * 4. LUNs of a existing device status change.
5618  * 5. RAID volume created/deleted.
5619  * 6. Member of RAID volume is released because of RAID deletion.
5620  * 7. Physical disks are removed because of RAID creation.
5621  */
5622 static void
5623 mptsas_handle_dr(void *args) {
5624 	mptsas_topo_change_list_t	*topo_node = NULL;
5625 	mptsas_topo_change_list_t	*save_node = NULL;
5626 	mptsas_t			*mpt;
5627 	dev_info_t			*parent = NULL;
5628 	uint8_t				phymask = 0;
5629 	char				*phy_mask_name;
5630 	uint8_t				flags = 0, physport = 0xff;
5631 	uint8_t				port_update = 0;
5632 	uint_t				event;
5633 
5634 	topo_node = (mptsas_topo_change_list_t *)args;
5635 
5636 	mpt = topo_node->mpt;
5637 	event = topo_node->event;
5638 	flags = topo_node->flags;
5639 
5640 	phy_mask_name = kmem_zalloc(8, KM_SLEEP);
5641 
5642 	NDBG20(("mptsas%d handle_dr enter", mpt->m_instance));
5643 
5644 	switch (event) {
5645 	case MPTSAS_DR_EVENT_RECONFIG_TARGET:
5646 		if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
5647 		    (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE) ||
5648 		    (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) {
5649 			/*
5650 			 * Direct attached or expander attached device added
5651 			 * into system or a Phys Disk that is being unhidden.
5652 			 */
5653 			port_update = 1;
5654 		}
5655 		break;
5656 	case MPTSAS_DR_EVENT_RECONFIG_SMP:
5657 		/*
5658 		 * New expander added into system, it must be the head
5659 		 * of topo_change_list_t
5660 		 */
5661 		port_update = 1;
5662 		break;
5663 	default:
5664 		port_update = 0;
5665 		break;
5666 	}
5667 	/*
5668 	 * All cases port_update == 1 may cause initiator port form change
5669 	 */
5670 	mutex_enter(&mpt->m_mutex);
5671 	if (mpt->m_port_chng && port_update) {
5672 		/*
5673 		 * mpt->m_port_chng flag indicates some PHYs of initiator
5674 		 * port have changed to online. So when expander added or
5675 		 * directly attached device online event come, we force to
5676 		 * update port information by issueing SAS IO Unit Page and
5677 		 * update PHYMASKs.
5678 		 */
5679 		(void) mptsas_update_phymask(mpt);
5680 		mpt->m_port_chng = 0;
5681 
5682 	}
5683 	mutex_exit(&mpt->m_mutex);
5684 	while (topo_node) {
5685 		phymask = 0;
5686 		if (parent == NULL) {
5687 			physport = topo_node->un.physport;
5688 			event = topo_node->event;
5689 			flags = topo_node->flags;
5690 			if (event & (MPTSAS_DR_EVENT_OFFLINE_TARGET |
5691 			    MPTSAS_DR_EVENT_OFFLINE_SMP)) {
5692 				/*
5693 				 * For all offline events, phymask is known
5694 				 */
5695 				phymask = topo_node->un.phymask;
5696 				goto find_parent;
5697 			}
5698 			if (event & MPTSAS_TOPO_FLAG_REMOVE_HANDLE) {
5699 				goto handle_topo_change;
5700 			}
5701 			if (flags & MPTSAS_TOPO_FLAG_LUN_ASSOCIATED) {
5702 				phymask = topo_node->un.phymask;
5703 				goto find_parent;
5704 			}
5705 
5706 			if ((flags ==
5707 			    MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) &&
5708 			    (event == MPTSAS_DR_EVENT_RECONFIG_TARGET)) {
5709 				/*
5710 				 * There is no any field in IR_CONFIG_CHANGE
5711 				 * event indicate physport/phynum, let's get
5712 				 * parent after SAS Device Page0 request.
5713 				 */
5714 				goto handle_topo_change;
5715 			}
5716 
5717 			mutex_enter(&mpt->m_mutex);
5718 			if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
5719 				/*
5720 				 * If the direct attached device added or a
5721 				 * phys disk is being unhidden, argument
5722 				 * physport actually is PHY#, so we have to get
5723 				 * phymask according PHY#.
5724 				 */
5725 				physport = mpt->m_phy_info[physport].port_num;
5726 			}
5727 
5728 			/*
5729 			 * Translate physport to phymask so that we can search
5730 			 * parent dip.
5731 			 */
5732 			phymask = mptsas_physport_to_phymask(mpt,
5733 			    physport);
5734 			mutex_exit(&mpt->m_mutex);
5735 
5736 find_parent:
5737 			bzero(phy_mask_name, 8);
5738 			/*
5739 			 * For RAID topology change node, write the iport name
5740 			 * as v0.
5741 			 */
5742 			if (flags & MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5743 				(void) sprintf(phy_mask_name, "v0");
5744 			} else {
5745 				/*
5746 				 * phymask can bo 0 if the drive has been
5747 				 * pulled by the time an add event is
5748 				 * processed.  If phymask is 0, just skip this
5749 				 * event and continue.
5750 				 */
5751 				if (phymask == 0) {
5752 					mutex_enter(&mpt->m_mutex);
5753 					save_node = topo_node;
5754 					topo_node = topo_node->next;
5755 					ASSERT(save_node);
5756 					kmem_free(save_node,
5757 					    sizeof (mptsas_topo_change_list_t));
5758 					mutex_exit(&mpt->m_mutex);
5759 
5760 					parent = NULL;
5761 					continue;
5762 				}
5763 				(void) sprintf(phy_mask_name, "%x", phymask);
5764 			}
5765 			parent = scsi_hba_iport_find(mpt->m_dip,
5766 			    phy_mask_name);
5767 			if (parent == NULL) {
5768 				mptsas_log(mpt, CE_WARN, "Failed to find an "
5769 				    "iport, should not happen!");
5770 				goto out;
5771 			}
5772 
5773 		}
5774 		ASSERT(parent);
5775 handle_topo_change:
5776 
5777 		mutex_enter(&mpt->m_mutex);
5778 
5779 		mptsas_handle_topo_change(topo_node, parent);
5780 		save_node = topo_node;
5781 		topo_node = topo_node->next;
5782 		ASSERT(save_node);
5783 		kmem_free(save_node, sizeof (mptsas_topo_change_list_t));
5784 		mutex_exit(&mpt->m_mutex);
5785 
5786 		if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
5787 		    (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) ||
5788 		    (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) {
5789 			/*
5790 			 * If direct attached device associated, make sure
5791 			 * reset the parent before start the next one. But
5792 			 * all devices associated with expander shares the
5793 			 * parent.  Also, reset parent if this is for RAID.
5794 			 */
5795 			parent = NULL;
5796 		}
5797 	}
5798 out:
5799 	kmem_free(phy_mask_name, 8);
5800 }
5801 
5802 static void
5803 mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node,
5804     dev_info_t *parent)
5805 {
5806 	mptsas_target_t	*ptgt = NULL;
5807 	mptsas_smp_t	*psmp = NULL;
5808 	mptsas_t	*mpt = (void *)topo_node->mpt;
5809 	uint16_t	devhdl;
5810 	uint64_t	sas_wwn = 0;
5811 	int		rval = 0;
5812 	uint32_t	page_address;
5813 	uint8_t		phy, flags;
5814 	char		*addr = NULL;
5815 	dev_info_t	*lundip;
5816 	int		circ = 0, circ1 = 0;
5817 
5818 	NDBG20(("mptsas%d handle_topo_change enter", mpt->m_instance));
5819 
5820 	ASSERT(mutex_owned(&mpt->m_mutex));
5821 
5822 	switch (topo_node->event) {
5823 	case MPTSAS_DR_EVENT_RECONFIG_TARGET:
5824 	{
5825 		char *phy_mask_name;
5826 		uint8_t phymask = 0;
5827 
5828 		if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5829 			/*
5830 			 * Get latest RAID info.
5831 			 */
5832 			(void) mptsas_get_raid_info(mpt);
5833 			ptgt = mptsas_search_by_devhdl(
5834 			    &mpt->m_active->m_tgttbl, topo_node->devhdl);
5835 			if (ptgt == NULL)
5836 				break;
5837 		} else {
5838 			ptgt = (void *)topo_node->object;
5839 		}
5840 
5841 		if (ptgt == NULL) {
5842 			/*
5843 			 * If a Phys Disk was deleted, RAID info needs to be
5844 			 * updated to reflect the new topology.
5845 			 */
5846 			(void) mptsas_get_raid_info(mpt);
5847 
5848 			/*
5849 			 * Get sas device page 0 by DevHandle to make sure if
5850 			 * SSP/SATA end device exist.
5851 			 */
5852 			page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
5853 			    MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
5854 			    topo_node->devhdl;
5855 
5856 			rval = mptsas_get_target_device_info(mpt, page_address,
5857 			    &devhdl, &ptgt);
5858 			if (rval == DEV_INFO_WRONG_DEVICE_TYPE) {
5859 				mptsas_log(mpt, CE_NOTE,
5860 				    "mptsas_handle_topo_change: target %d is "
5861 				    "not a SAS/SATA device. \n",
5862 				    topo_node->devhdl);
5863 			} else if (rval == DEV_INFO_FAIL_ALLOC) {
5864 				mptsas_log(mpt, CE_NOTE,
5865 				    "mptsas_handle_topo_change: could not "
5866 				    "allocate memory. \n");
5867 			}
5868 			/*
5869 			 * If rval is DEV_INFO_PHYS_DISK than there is nothing
5870 			 * else to do, just leave.
5871 			 */
5872 			if (rval != DEV_INFO_SUCCESS) {
5873 				return;
5874 			}
5875 		}
5876 
5877 		ASSERT(ptgt->m_devhdl == topo_node->devhdl);
5878 
5879 		mutex_exit(&mpt->m_mutex);
5880 		flags = topo_node->flags;
5881 
5882 		if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) {
5883 			phymask = ptgt->m_phymask;
5884 			phy_mask_name = kmem_zalloc(8, KM_SLEEP);
5885 			(void) sprintf(phy_mask_name, "%x", phymask);
5886 			parent = scsi_hba_iport_find(mpt->m_dip,
5887 			    phy_mask_name);
5888 			kmem_free(phy_mask_name, 8);
5889 			if (parent == NULL) {
5890 				mptsas_log(mpt, CE_WARN, "Failed to find a "
5891 				    "iport for PD, should not happen!");
5892 				mutex_enter(&mpt->m_mutex);
5893 				break;
5894 			}
5895 		}
5896 
5897 		if (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5898 			ndi_devi_enter(parent, &circ1);
5899 			(void) mptsas_config_raid(parent, topo_node->devhdl,
5900 			    &lundip);
5901 			ndi_devi_exit(parent, circ1);
5902 		} else {
5903 			/*
5904 			 * hold nexus for bus configure
5905 			 */
5906 			ndi_devi_enter(scsi_vhci_dip, &circ);
5907 			ndi_devi_enter(parent, &circ1);
5908 			rval = mptsas_config_target(parent, ptgt);
5909 			/*
5910 			 * release nexus for bus configure
5911 			 */
5912 			ndi_devi_exit(parent, circ1);
5913 			ndi_devi_exit(scsi_vhci_dip, circ);
5914 
5915 		}
5916 		mutex_enter(&mpt->m_mutex);
5917 
5918 		NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, "
5919 		    "phymask:%x.", mpt->m_instance, ptgt->m_devhdl,
5920 		    ptgt->m_phymask));
5921 		break;
5922 	}
5923 	case MPTSAS_DR_EVENT_OFFLINE_TARGET:
5924 	{
5925 		mptsas_hash_table_t *tgttbl = &mpt->m_active->m_tgttbl;
5926 		devhdl = topo_node->devhdl;
5927 		ptgt = mptsas_search_by_devhdl(tgttbl, devhdl);
5928 		if (ptgt == NULL)
5929 			break;
5930 
5931 		sas_wwn = ptgt->m_sas_wwn;
5932 		phy = ptgt->m_phynum;
5933 
5934 		addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
5935 
5936 		if (sas_wwn) {
5937 			(void) sprintf(addr, "w%016"PRIx64, sas_wwn);
5938 		} else {
5939 			(void) sprintf(addr, "p%x", phy);
5940 		}
5941 		ASSERT(ptgt->m_devhdl == devhdl);
5942 
5943 		if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5944 			/*
5945 			 * Get latest RAID info, if RAID volume status change
5946 			 */
5947 			(void) mptsas_get_raid_info(mpt);
5948 		}
5949 		/*
5950 		 * Abort all outstanding command on the device
5951 		 */
5952 		rval = mptsas_do_scsi_reset(mpt, devhdl);
5953 		if (rval) {
5954 			NDBG20(("mptsas%d handle_topo_change to reset target "
5955 			    "before offline devhdl:%x, phymask:%x, rval:%x",
5956 			    mpt->m_instance, ptgt->m_devhdl, ptgt->m_phymask,
5957 			    rval));
5958 		}
5959 
5960 		mutex_exit(&mpt->m_mutex);
5961 
5962 		ndi_devi_enter(scsi_vhci_dip, &circ);
5963 		ndi_devi_enter(parent, &circ1);
5964 		rval = mptsas_offline_target(parent, addr);
5965 		ndi_devi_exit(parent, circ1);
5966 		ndi_devi_exit(scsi_vhci_dip, circ);
5967 		NDBG20(("mptsas%d handle_topo_change to offline devhdl:%x, "
5968 		    "phymask:%x, rval:%x", mpt->m_instance,
5969 		    ptgt->m_devhdl, ptgt->m_phymask, rval));
5970 
5971 		kmem_free(addr, SCSI_MAXNAMELEN);
5972 
5973 		mutex_enter(&mpt->m_mutex);
5974 		if (rval == DDI_SUCCESS) {
5975 			mptsas_tgt_free(&mpt->m_active->m_tgttbl,
5976 			    ptgt->m_sas_wwn, ptgt->m_phymask);
5977 			ptgt = NULL;
5978 		} else {
5979 			/*
5980 			 * clean DR_INTRANSITION flag to allow I/O down to
5981 			 * PHCI driver since failover finished.
5982 			 * Invalidate the devhdl
5983 			 */
5984 			ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL;
5985 			mutex_enter(&mpt->m_tx_waitq_mutex);
5986 			ptgt->m_dr_flag = MPTSAS_DR_INACTIVE;
5987 			mutex_exit(&mpt->m_tx_waitq_mutex);
5988 		}
5989 
5990 		/*
5991 		 * Send SAS IO Unit Control to free the dev handle
5992 		 */
5993 		flags = topo_node->flags;
5994 		if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
5995 		    (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE)) {
5996 			rval = mptsas_free_devhdl(mpt, devhdl);
5997 
5998 			NDBG20(("mptsas%d handle_topo_change to remove "
5999 			    "devhdl:%x, rval:%x", mpt->m_instance, devhdl,
6000 			    rval));
6001 		}
6002 		break;
6003 	}
6004 	case MPTSAS_TOPO_FLAG_REMOVE_HANDLE:
6005 	{
6006 		devhdl = topo_node->devhdl;
6007 		/*
6008 		 * If this is the remove handle event, do a reset first.
6009 		 */
6010 		if (topo_node->event == MPTSAS_TOPO_FLAG_REMOVE_HANDLE) {
6011 			rval = mptsas_do_scsi_reset(mpt, devhdl);
6012 			if (rval) {
6013 				NDBG20(("mpt%d reset target before remove "
6014 				    "devhdl:%x, rval:%x", mpt->m_instance,
6015 				    devhdl, rval));
6016 			}
6017 		}
6018 
6019 		/*
6020 		 * Send SAS IO Unit Control to free the dev handle
6021 		 */
6022 		rval = mptsas_free_devhdl(mpt, devhdl);
6023 		NDBG20(("mptsas%d handle_topo_change to remove "
6024 		    "devhdl:%x, rval:%x", mpt->m_instance, devhdl,
6025 		    rval));
6026 		break;
6027 	}
6028 	case MPTSAS_DR_EVENT_RECONFIG_SMP:
6029 	{
6030 		mptsas_smp_t smp;
6031 		dev_info_t *smpdip;
6032 		mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl;
6033 
6034 		devhdl = topo_node->devhdl;
6035 
6036 		page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL &
6037 		    MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl;
6038 		rval = mptsas_get_sas_expander_page0(mpt, page_address, &smp);
6039 		if (rval != DDI_SUCCESS) {
6040 			mptsas_log(mpt, CE_WARN, "failed to online smp, "
6041 			    "handle %x", devhdl);
6042 			return;
6043 		}
6044 
6045 		psmp = mptsas_smp_alloc(smptbl, &smp);
6046 		if (psmp == NULL) {
6047 			return;
6048 		}
6049 
6050 		mutex_exit(&mpt->m_mutex);
6051 		ndi_devi_enter(parent, &circ1);
6052 		(void) mptsas_online_smp(parent, psmp, &smpdip);
6053 		ndi_devi_exit(parent, circ1);
6054 		mutex_enter(&mpt->m_mutex);
6055 		break;
6056 	}
6057 	case MPTSAS_DR_EVENT_OFFLINE_SMP:
6058 	{
6059 		mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl;
6060 		devhdl = topo_node->devhdl;
6061 		psmp = mptsas_search_by_devhdl(smptbl, devhdl);
6062 		if (psmp == NULL)
6063 			break;
6064 		/*
6065 		 * The mptsas_smp_t data is released only if the dip is offlined
6066 		 * successfully.
6067 		 */
6068 		mutex_exit(&mpt->m_mutex);
6069 		ndi_devi_enter(parent, &circ1);
6070 		rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE);
6071 		ndi_devi_exit(parent, circ1);
6072 		mutex_enter(&mpt->m_mutex);
6073 		NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, "
6074 		    "rval:%x", mpt->m_instance, psmp->m_devhdl, rval));
6075 		if (rval == DDI_SUCCESS) {
6076 			mptsas_smp_free(smptbl, psmp->m_sasaddr,
6077 			    psmp->m_phymask);
6078 		} else {
6079 			psmp->m_devhdl = MPTSAS_INVALID_DEVHDL;
6080 		}
6081 		break;
6082 	}
6083 	default:
6084 		return;
6085 	}
6086 }
6087 
6088 /*
6089  * Record the event if its type is enabled in mpt instance by ioctl.
6090  */
6091 static void
6092 mptsas_record_event(void *args)
6093 {
6094 	m_replyh_arg_t			*replyh_arg;
6095 	pMpi2EventNotificationReply_t	eventreply;
6096 	uint32_t			event, rfm;
6097 	mptsas_t			*mpt;
6098 	int				i, j;
6099 	uint16_t			event_data_len;
6100 	boolean_t			sendAEN = FALSE;
6101 
6102 	replyh_arg = (m_replyh_arg_t *)args;
6103 	rfm = replyh_arg->rfm;
6104 	mpt = replyh_arg->mpt;
6105 
6106 	eventreply = (pMpi2EventNotificationReply_t)
6107 	    (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr));
6108 	event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
6109 
6110 
6111 	/*
6112 	 * Generate a system event to let anyone who cares know that a
6113 	 * LOG_ENTRY_ADDED event has occurred.  This is sent no matter what the
6114 	 * event mask is set to.
6115 	 */
6116 	if (event == MPI2_EVENT_LOG_ENTRY_ADDED) {
6117 		sendAEN = TRUE;
6118 	}
6119 
6120 	/*
6121 	 * Record the event only if it is not masked.  Determine which dword
6122 	 * and bit of event mask to test.
6123 	 */
6124 	i = (uint8_t)(event / 32);
6125 	j = (uint8_t)(event % 32);
6126 	if ((i < 4) && ((1 << j) & mpt->m_event_mask[i])) {
6127 		i = mpt->m_event_index;
6128 		mpt->m_events[i].Type = event;
6129 		mpt->m_events[i].Number = ++mpt->m_event_number;
6130 		bzero(mpt->m_events[i].Data, MPTSAS_MAX_EVENT_DATA_LENGTH * 4);
6131 		event_data_len = ddi_get16(mpt->m_acc_reply_frame_hdl,
6132 		    &eventreply->EventDataLength);
6133 
6134 		if (event_data_len > 0) {
6135 			/*
6136 			 * Limit data to size in m_event entry
6137 			 */
6138 			if (event_data_len > MPTSAS_MAX_EVENT_DATA_LENGTH) {
6139 				event_data_len = MPTSAS_MAX_EVENT_DATA_LENGTH;
6140 			}
6141 			for (j = 0; j < event_data_len; j++) {
6142 				mpt->m_events[i].Data[j] =
6143 				    ddi_get32(mpt->m_acc_reply_frame_hdl,
6144 				    &(eventreply->EventData[j]));
6145 			}
6146 
6147 			/*
6148 			 * check for index wrap-around
6149 			 */
6150 			if (++i == MPTSAS_EVENT_QUEUE_SIZE) {
6151 				i = 0;
6152 			}
6153 			mpt->m_event_index = (uint8_t)i;
6154 
6155 			/*
6156 			 * Set flag to send the event.
6157 			 */
6158 			sendAEN = TRUE;
6159 		}
6160 	}
6161 
6162 	/*
6163 	 * Generate a system event if flag is set to let anyone who cares know
6164 	 * that an event has occurred.
6165 	 */
6166 	if (sendAEN) {
6167 		(void) ddi_log_sysevent(mpt->m_dip, DDI_VENDOR_LSI, "MPT_SAS",
6168 		    "SAS", NULL, NULL, DDI_NOSLEEP);
6169 	}
6170 }
6171 
6172 #define	SMP_RESET_IN_PROGRESS MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS
6173 /*
6174  * handle sync events from ioc in interrupt
6175  * return value:
6176  * DDI_SUCCESS: The event is handled by this func
6177  * DDI_FAILURE: Event is not handled
6178  */
6179 static int
6180 mptsas_handle_event_sync(void *args)
6181 {
6182 	m_replyh_arg_t			*replyh_arg;
6183 	pMpi2EventNotificationReply_t	eventreply;
6184 	uint32_t			event, rfm;
6185 	mptsas_t			*mpt;
6186 	uint_t				iocstatus;
6187 
6188 	replyh_arg = (m_replyh_arg_t *)args;
6189 	rfm = replyh_arg->rfm;
6190 	mpt = replyh_arg->mpt;
6191 
6192 	ASSERT(mutex_owned(&mpt->m_mutex));
6193 
6194 	eventreply = (pMpi2EventNotificationReply_t)
6195 	    (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr));
6196 	event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
6197 
6198 	if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
6199 	    &eventreply->IOCStatus)) {
6200 		if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
6201 			mptsas_log(mpt, CE_WARN,
6202 			    "!mptsas_handle_event_sync: IOCStatus=0x%x, "
6203 			    "IOCLogInfo=0x%x", iocstatus,
6204 			    ddi_get32(mpt->m_acc_reply_frame_hdl,
6205 			    &eventreply->IOCLogInfo));
6206 		} else {
6207 			mptsas_log(mpt, CE_WARN,
6208 			    "mptsas_handle_event_sync: IOCStatus=0x%x, "
6209 			    "IOCLogInfo=0x%x", iocstatus,
6210 			    ddi_get32(mpt->m_acc_reply_frame_hdl,
6211 			    &eventreply->IOCLogInfo));
6212 		}
6213 	}
6214 
6215 	/*
6216 	 * figure out what kind of event we got and handle accordingly
6217 	 */
6218 	switch (event) {
6219 	case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
6220 	{
6221 		pMpi2EventDataSasTopologyChangeList_t	sas_topo_change_list;
6222 		uint8_t				num_entries, expstatus, phy;
6223 		uint8_t				phystatus, physport, state, i;
6224 		uint8_t				start_phy_num, link_rate;
6225 		uint16_t			dev_handle, reason_code;
6226 		uint16_t			enc_handle, expd_handle;
6227 		char				string[80], curr[80], prev[80];
6228 		mptsas_topo_change_list_t	*topo_head = NULL;
6229 		mptsas_topo_change_list_t	*topo_tail = NULL;
6230 		mptsas_topo_change_list_t	*topo_node = NULL;
6231 		mptsas_target_t			*ptgt;
6232 		mptsas_smp_t			*psmp;
6233 		mptsas_hash_table_t		*tgttbl, *smptbl;
6234 		uint8_t				flags = 0, exp_flag;
6235 
6236 		NDBG20(("mptsas_handle_event_sync: SAS topology change"));
6237 
6238 		tgttbl = &mpt->m_active->m_tgttbl;
6239 		smptbl = &mpt->m_active->m_smptbl;
6240 
6241 		sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t)
6242 		    eventreply->EventData;
6243 
6244 		enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6245 		    &sas_topo_change_list->EnclosureHandle);
6246 		expd_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6247 		    &sas_topo_change_list->ExpanderDevHandle);
6248 		num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
6249 		    &sas_topo_change_list->NumEntries);
6250 		start_phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl,
6251 		    &sas_topo_change_list->StartPhyNum);
6252 		expstatus = ddi_get8(mpt->m_acc_reply_frame_hdl,
6253 		    &sas_topo_change_list->ExpStatus);
6254 		physport = ddi_get8(mpt->m_acc_reply_frame_hdl,
6255 		    &sas_topo_change_list->PhysicalPort);
6256 
6257 		string[0] = 0;
6258 		if (expd_handle) {
6259 			flags = MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED;
6260 			switch (expstatus) {
6261 			case MPI2_EVENT_SAS_TOPO_ES_ADDED:
6262 				(void) sprintf(string, " added");
6263 				/*
6264 				 * New expander device added
6265 				 */
6266 				mpt->m_port_chng = 1;
6267 				topo_node = kmem_zalloc(
6268 				    sizeof (mptsas_topo_change_list_t),
6269 				    KM_SLEEP);
6270 				topo_node->mpt = mpt;
6271 				topo_node->event = MPTSAS_DR_EVENT_RECONFIG_SMP;
6272 				topo_node->un.physport = physport;
6273 				topo_node->devhdl = expd_handle;
6274 				topo_node->flags = flags;
6275 				topo_node->object = NULL;
6276 				if (topo_head == NULL) {
6277 					topo_head = topo_tail = topo_node;
6278 				} else {
6279 					topo_tail->next = topo_node;
6280 					topo_tail = topo_node;
6281 				}
6282 				break;
6283 			case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING:
6284 				(void) sprintf(string, " not responding, "
6285 				    "removed");
6286 				psmp = mptsas_search_by_devhdl(smptbl,
6287 				    expd_handle);
6288 				if (psmp == NULL)
6289 					break;
6290 
6291 				topo_node = kmem_zalloc(
6292 				    sizeof (mptsas_topo_change_list_t),
6293 				    KM_SLEEP);
6294 				topo_node->mpt = mpt;
6295 				topo_node->un.phymask = psmp->m_phymask;
6296 				topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP;
6297 				topo_node->devhdl = expd_handle;
6298 				topo_node->flags = flags;
6299 				topo_node->object = NULL;
6300 				if (topo_head == NULL) {
6301 					topo_head = topo_tail = topo_node;
6302 				} else {
6303 					topo_tail->next = topo_node;
6304 					topo_tail = topo_node;
6305 				}
6306 				break;
6307 			case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
6308 				break;
6309 			case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
6310 				(void) sprintf(string, " not responding, "
6311 				    "delaying removal");
6312 				break;
6313 			default:
6314 				break;
6315 			}
6316 		} else {
6317 			flags = MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE;
6318 		}
6319 
6320 		NDBG20(("SAS TOPOLOGY CHANGE for enclosure %x expander %x%s\n",
6321 		    enc_handle, expd_handle, string));
6322 		for (i = 0; i < num_entries; i++) {
6323 			phy = i + start_phy_num;
6324 			phystatus = ddi_get8(mpt->m_acc_reply_frame_hdl,
6325 			    &sas_topo_change_list->PHY[i].PhyStatus);
6326 			dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6327 			    &sas_topo_change_list->PHY[i].AttachedDevHandle);
6328 			reason_code = phystatus & MPI2_EVENT_SAS_TOPO_RC_MASK;
6329 			/*
6330 			 * Filter out processing of Phy Vacant Status unless
6331 			 * the reason code is "Not Responding".  Process all
6332 			 * other combinations of Phy Status and Reason Codes.
6333 			 */
6334 			if ((phystatus &
6335 			    MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) &&
6336 			    (reason_code !=
6337 			    MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)) {
6338 				continue;
6339 			}
6340 			curr[0] = 0;
6341 			prev[0] = 0;
6342 			string[0] = 0;
6343 			switch (reason_code) {
6344 			case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
6345 			{
6346 				NDBG20(("mptsas%d phy %d physical_port %d "
6347 				    "dev_handle %d added", mpt->m_instance, phy,
6348 				    physport, dev_handle));
6349 				link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl,
6350 				    &sas_topo_change_list->PHY[i].LinkRate);
6351 				state = (link_rate &
6352 				    MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >>
6353 				    MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT;
6354 				switch (state) {
6355 				case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
6356 					(void) sprintf(curr, "is disabled");
6357 					break;
6358 				case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
6359 					(void) sprintf(curr, "is offline, "
6360 					    "failed speed negotiation");
6361 					break;
6362 				case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
6363 					(void) sprintf(curr, "SATA OOB "
6364 					    "complete");
6365 					break;
6366 				case SMP_RESET_IN_PROGRESS:
6367 					(void) sprintf(curr, "SMP reset in "
6368 					    "progress");
6369 					break;
6370 				case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
6371 					(void) sprintf(curr, "is online at "
6372 					    "1.5 Gbps");
6373 					break;
6374 				case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
6375 					(void) sprintf(curr, "is online at 3.0 "
6376 					    "Gbps");
6377 					break;
6378 				case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
6379 					(void) sprintf(curr, "is online at 6.0 "
6380 					    "Gbps");
6381 					break;
6382 				default:
6383 					(void) sprintf(curr, "state is "
6384 					    "unknown");
6385 					break;
6386 				}
6387 				/*
6388 				 * New target device added into the system.
6389 				 * Set association flag according to if an
6390 				 * expander is used or not.
6391 				 */
6392 				exp_flag =
6393 				    MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
6394 				if (flags ==
6395 				    MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) {
6396 					flags = exp_flag;
6397 				}
6398 				topo_node = kmem_zalloc(
6399 				    sizeof (mptsas_topo_change_list_t),
6400 				    KM_SLEEP);
6401 				topo_node->mpt = mpt;
6402 				topo_node->event =
6403 				    MPTSAS_DR_EVENT_RECONFIG_TARGET;
6404 				if (expd_handle == 0) {
6405 					/*
6406 					 * Per MPI 2, if expander dev handle
6407 					 * is 0, it's a directly attached
6408 					 * device. So driver use PHY to decide
6409 					 * which iport is associated
6410 					 */
6411 					physport = phy;
6412 					mpt->m_port_chng = 1;
6413 				}
6414 				topo_node->un.physport = physport;
6415 				topo_node->devhdl = dev_handle;
6416 				topo_node->flags = flags;
6417 				topo_node->object = NULL;
6418 				if (topo_head == NULL) {
6419 					topo_head = topo_tail = topo_node;
6420 				} else {
6421 					topo_tail->next = topo_node;
6422 					topo_tail = topo_node;
6423 				}
6424 				break;
6425 			}
6426 			case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
6427 			{
6428 				NDBG20(("mptsas%d phy %d physical_port %d "
6429 				    "dev_handle %d removed", mpt->m_instance,
6430 				    phy, physport, dev_handle));
6431 				/*
6432 				 * Set association flag according to if an
6433 				 * expander is used or not.
6434 				 */
6435 				exp_flag =
6436 				    MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
6437 				if (flags ==
6438 				    MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) {
6439 					flags = exp_flag;
6440 				}
6441 				/*
6442 				 * Target device is removed from the system
6443 				 * Before the device is really offline from
6444 				 * from system.
6445 				 */
6446 				ptgt = mptsas_search_by_devhdl(tgttbl,
6447 				    dev_handle);
6448 				/*
6449 				 * If ptgt is NULL here, it means that the
6450 				 * DevHandle is not in the hash table.  This is
6451 				 * reasonable sometimes.  For example, if a
6452 				 * disk was pulled, then added, then pulled
6453 				 * again, the disk will not have been put into
6454 				 * the hash table because the add event will
6455 				 * have an invalid phymask.  BUT, this does not
6456 				 * mean that the DevHandle is invalid.  The
6457 				 * controller will still have a valid DevHandle
6458 				 * that must be removed.  To do this, use the
6459 				 * MPTSAS_TOPO_FLAG_REMOVE_HANDLE event.
6460 				 */
6461 				if (ptgt == NULL) {
6462 					topo_node = kmem_zalloc(
6463 					    sizeof (mptsas_topo_change_list_t),
6464 					    KM_SLEEP);
6465 					topo_node->mpt = mpt;
6466 					topo_node->un.phymask = 0;
6467 					topo_node->event =
6468 					    MPTSAS_TOPO_FLAG_REMOVE_HANDLE;
6469 					topo_node->devhdl = dev_handle;
6470 					topo_node->flags = flags;
6471 					topo_node->object = NULL;
6472 					if (topo_head == NULL) {
6473 						topo_head = topo_tail =
6474 						    topo_node;
6475 					} else {
6476 						topo_tail->next = topo_node;
6477 						topo_tail = topo_node;
6478 					}
6479 					break;
6480 				}
6481 
6482 				/*
6483 				 * Update DR flag immediately avoid I/O failure
6484 				 * before failover finish. Pay attention to the
6485 				 * mutex protect, we need grab m_tx_waitq_mutex
6486 				 * during set m_dr_flag because we won't add
6487 				 * the following command into waitq, instead,
6488 				 * we need return TRAN_BUSY in the tran_start
6489 				 * context.
6490 				 */
6491 				mutex_enter(&mpt->m_tx_waitq_mutex);
6492 				ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6493 				mutex_exit(&mpt->m_tx_waitq_mutex);
6494 
6495 				topo_node = kmem_zalloc(
6496 				    sizeof (mptsas_topo_change_list_t),
6497 				    KM_SLEEP);
6498 				topo_node->mpt = mpt;
6499 				topo_node->un.phymask = ptgt->m_phymask;
6500 				topo_node->event =
6501 				    MPTSAS_DR_EVENT_OFFLINE_TARGET;
6502 				topo_node->devhdl = dev_handle;
6503 				topo_node->flags = flags;
6504 				topo_node->object = NULL;
6505 				if (topo_head == NULL) {
6506 					topo_head = topo_tail = topo_node;
6507 				} else {
6508 					topo_tail->next = topo_node;
6509 					topo_tail = topo_node;
6510 				}
6511 
6512 				break;
6513 			}
6514 			case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
6515 				link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl,
6516 				    &sas_topo_change_list->PHY[i].LinkRate);
6517 				state = (link_rate &
6518 				    MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >>
6519 				    MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT;
6520 				switch (state) {
6521 				case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
6522 					(void) sprintf(curr, "is disabled");
6523 					break;
6524 				case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
6525 					(void) sprintf(curr, "is offline, "
6526 					    "failed speed negotiation");
6527 					break;
6528 				case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
6529 					(void) sprintf(curr, "SATA OOB "
6530 					    "complete");
6531 					break;
6532 				case SMP_RESET_IN_PROGRESS:
6533 					(void) sprintf(curr, "SMP reset in "
6534 					    "progress");
6535 					break;
6536 				case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
6537 					(void) sprintf(curr, "is online at "
6538 					    "1.5 Gbps");
6539 					if ((expd_handle == 0) &&
6540 					    (enc_handle == 1)) {
6541 						mpt->m_port_chng = 1;
6542 					}
6543 					break;
6544 				case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
6545 					(void) sprintf(curr, "is online at 3.0 "
6546 					    "Gbps");
6547 					if ((expd_handle == 0) &&
6548 					    (enc_handle == 1)) {
6549 						mpt->m_port_chng = 1;
6550 					}
6551 					break;
6552 				case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
6553 					(void) sprintf(curr, "is online at "
6554 					    "6.0 Gbps");
6555 					if ((expd_handle == 0) &&
6556 					    (enc_handle == 1)) {
6557 						mpt->m_port_chng = 1;
6558 					}
6559 					break;
6560 				default:
6561 					(void) sprintf(curr, "state is "
6562 					    "unknown");
6563 					break;
6564 				}
6565 
6566 				state = (link_rate &
6567 				    MPI2_EVENT_SAS_TOPO_LR_PREV_MASK) >>
6568 				    MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT;
6569 				switch (state) {
6570 				case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
6571 					(void) sprintf(prev, ", was disabled");
6572 					break;
6573 				case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
6574 					(void) sprintf(prev, ", was offline, "
6575 					    "failed speed negotiation");
6576 					break;
6577 				case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
6578 					(void) sprintf(prev, ", was SATA OOB "
6579 					    "complete");
6580 					break;
6581 				case SMP_RESET_IN_PROGRESS:
6582 					(void) sprintf(prev, ", was SMP reset "
6583 					    "in progress");
6584 					break;
6585 				case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
6586 					(void) sprintf(prev, ", was online at "
6587 					    "1.5 Gbps");
6588 					break;
6589 				case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
6590 					(void) sprintf(prev, ", was online at "
6591 					    "3.0 Gbps");
6592 					break;
6593 				case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
6594 					(void) sprintf(prev, ", was online at "
6595 					    "6.0 Gbps");
6596 					break;
6597 				default:
6598 				break;
6599 				}
6600 				(void) sprintf(&string[strlen(string)], "link "
6601 				    "changed, ");
6602 				break;
6603 			case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
6604 				continue;
6605 			case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
6606 				(void) sprintf(&string[strlen(string)],
6607 				    "target not responding, delaying "
6608 				    "removal");
6609 				break;
6610 			}
6611 			NDBG20(("mptsas%d phy %d DevHandle %x, %s%s%s\n",
6612 			    mpt->m_instance, phy, dev_handle, string, curr,
6613 			    prev));
6614 		}
6615 		if (topo_head != NULL) {
6616 			/*
6617 			 * Launch DR taskq to handle topology change
6618 			 */
6619 			if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
6620 			    mptsas_handle_dr, (void *)topo_head,
6621 			    DDI_NOSLEEP)) != DDI_SUCCESS) {
6622 				mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
6623 				    "for handle SAS DR event failed. \n");
6624 			}
6625 		}
6626 		break;
6627 	}
6628 	case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
6629 	{
6630 		Mpi2EventDataIrConfigChangeList_t	*irChangeList;
6631 		mptsas_topo_change_list_t		*topo_head = NULL;
6632 		mptsas_topo_change_list_t		*topo_tail = NULL;
6633 		mptsas_topo_change_list_t		*topo_node = NULL;
6634 		mptsas_target_t				*ptgt;
6635 		mptsas_hash_table_t			*tgttbl;
6636 		uint8_t					num_entries, i, reason;
6637 		uint16_t				volhandle, diskhandle;
6638 
6639 		irChangeList = (pMpi2EventDataIrConfigChangeList_t)
6640 		    eventreply->EventData;
6641 		num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
6642 		    &irChangeList->NumElements);
6643 
6644 		tgttbl = &mpt->m_active->m_tgttbl;
6645 
6646 		NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received",
6647 		    mpt->m_instance));
6648 
6649 		for (i = 0; i < num_entries; i++) {
6650 			reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
6651 			    &irChangeList->ConfigElement[i].ReasonCode);
6652 			volhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6653 			    &irChangeList->ConfigElement[i].VolDevHandle);
6654 			diskhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6655 			    &irChangeList->ConfigElement[i].PhysDiskDevHandle);
6656 
6657 			switch (reason) {
6658 			case MPI2_EVENT_IR_CHANGE_RC_ADDED:
6659 			case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
6660 			{
6661 				NDBG20(("mptsas %d volume added\n",
6662 				    mpt->m_instance));
6663 
6664 				topo_node = kmem_zalloc(
6665 				    sizeof (mptsas_topo_change_list_t),
6666 				    KM_SLEEP);
6667 
6668 				topo_node->mpt = mpt;
6669 				topo_node->event =
6670 				    MPTSAS_DR_EVENT_RECONFIG_TARGET;
6671 				topo_node->un.physport = 0xff;
6672 				topo_node->devhdl = volhandle;
6673 				topo_node->flags =
6674 				    MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
6675 				topo_node->object = NULL;
6676 				if (topo_head == NULL) {
6677 					topo_head = topo_tail = topo_node;
6678 				} else {
6679 					topo_tail->next = topo_node;
6680 					topo_tail = topo_node;
6681 				}
6682 				break;
6683 			}
6684 			case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
6685 			case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
6686 			{
6687 				NDBG20(("mptsas %d volume deleted\n",
6688 				    mpt->m_instance));
6689 				ptgt = mptsas_search_by_devhdl(tgttbl,
6690 				    volhandle);
6691 				if (ptgt == NULL)
6692 					break;
6693 
6694 				/*
6695 				 * Clear any flags related to volume
6696 				 */
6697 				(void) mptsas_delete_volume(mpt, volhandle);
6698 
6699 				/*
6700 				 * Update DR flag immediately avoid I/O failure
6701 				 */
6702 				mutex_enter(&mpt->m_tx_waitq_mutex);
6703 				ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6704 				mutex_exit(&mpt->m_tx_waitq_mutex);
6705 
6706 				topo_node = kmem_zalloc(
6707 				    sizeof (mptsas_topo_change_list_t),
6708 				    KM_SLEEP);
6709 				topo_node->mpt = mpt;
6710 				topo_node->un.phymask = ptgt->m_phymask;
6711 				topo_node->event =
6712 				    MPTSAS_DR_EVENT_OFFLINE_TARGET;
6713 				topo_node->devhdl = volhandle;
6714 				topo_node->flags =
6715 				    MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
6716 				topo_node->object = (void *)ptgt;
6717 				if (topo_head == NULL) {
6718 					topo_head = topo_tail = topo_node;
6719 				} else {
6720 					topo_tail->next = topo_node;
6721 					topo_tail = topo_node;
6722 				}
6723 				break;
6724 			}
6725 			case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
6726 			case MPI2_EVENT_IR_CHANGE_RC_HIDE:
6727 			{
6728 				ptgt = mptsas_search_by_devhdl(tgttbl,
6729 				    diskhandle);
6730 				if (ptgt == NULL)
6731 					break;
6732 
6733 				/*
6734 				 * Update DR flag immediately avoid I/O failure
6735 				 */
6736 				mutex_enter(&mpt->m_tx_waitq_mutex);
6737 				ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6738 				mutex_exit(&mpt->m_tx_waitq_mutex);
6739 
6740 				topo_node = kmem_zalloc(
6741 				    sizeof (mptsas_topo_change_list_t),
6742 				    KM_SLEEP);
6743 				topo_node->mpt = mpt;
6744 				topo_node->un.phymask = ptgt->m_phymask;
6745 				topo_node->event =
6746 				    MPTSAS_DR_EVENT_OFFLINE_TARGET;
6747 				topo_node->devhdl = diskhandle;
6748 				topo_node->flags =
6749 				    MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
6750 				topo_node->object = (void *)ptgt;
6751 				if (topo_head == NULL) {
6752 					topo_head = topo_tail = topo_node;
6753 				} else {
6754 					topo_tail->next = topo_node;
6755 					topo_tail = topo_node;
6756 				}
6757 				break;
6758 			}
6759 			case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
6760 			case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
6761 			{
6762 				/*
6763 				 * The physical drive is released by a IR
6764 				 * volume. But we cannot get the the physport
6765 				 * or phynum from the event data, so we only
6766 				 * can get the physport/phynum after SAS
6767 				 * Device Page0 request for the devhdl.
6768 				 */
6769 				topo_node = kmem_zalloc(
6770 				    sizeof (mptsas_topo_change_list_t),
6771 				    KM_SLEEP);
6772 				topo_node->mpt = mpt;
6773 				topo_node->un.phymask = 0;
6774 				topo_node->event =
6775 				    MPTSAS_DR_EVENT_RECONFIG_TARGET;
6776 				topo_node->devhdl = diskhandle;
6777 				topo_node->flags =
6778 				    MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
6779 				topo_node->object = NULL;
6780 				mpt->m_port_chng = 1;
6781 				if (topo_head == NULL) {
6782 					topo_head = topo_tail = topo_node;
6783 				} else {
6784 					topo_tail->next = topo_node;
6785 					topo_tail = topo_node;
6786 				}
6787 				break;
6788 			}
6789 			default:
6790 				break;
6791 			}
6792 		}
6793 
6794 		if (topo_head != NULL) {
6795 			/*
6796 			 * Launch DR taskq to handle topology change
6797 			 */
6798 			if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
6799 			    mptsas_handle_dr, (void *)topo_head,
6800 			    DDI_NOSLEEP)) != DDI_SUCCESS) {
6801 				mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
6802 				    "for handle SAS DR event failed. \n");
6803 			}
6804 		}
6805 		break;
6806 	}
6807 	default:
6808 		return (DDI_FAILURE);
6809 	}
6810 
6811 	return (DDI_SUCCESS);
6812 }
6813 
6814 /*
6815  * handle events from ioc
6816  */
6817 static void
6818 mptsas_handle_event(void *args)
6819 {
6820 	m_replyh_arg_t			*replyh_arg;
6821 	pMpi2EventNotificationReply_t	eventreply;
6822 	uint32_t			event, iocloginfo, rfm;
6823 	uint32_t			status;
6824 	uint8_t				port;
6825 	mptsas_t			*mpt;
6826 	uint_t				iocstatus;
6827 
6828 	replyh_arg = (m_replyh_arg_t *)args;
6829 	rfm = replyh_arg->rfm;
6830 	mpt = replyh_arg->mpt;
6831 
6832 	mutex_enter(&mpt->m_mutex);
6833 
6834 	eventreply = (pMpi2EventNotificationReply_t)
6835 	    (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr));
6836 	event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
6837 
6838 	if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
6839 	    &eventreply->IOCStatus)) {
6840 		if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
6841 			mptsas_log(mpt, CE_WARN,
6842 			    "!mptsas_handle_event: IOCStatus=0x%x, "
6843 			    "IOCLogInfo=0x%x", iocstatus,
6844 			    ddi_get32(mpt->m_acc_reply_frame_hdl,
6845 			    &eventreply->IOCLogInfo));
6846 		} else {
6847 			mptsas_log(mpt, CE_WARN,
6848 			    "mptsas_handle_event: IOCStatus=0x%x, "
6849 			    "IOCLogInfo=0x%x", iocstatus,
6850 			    ddi_get32(mpt->m_acc_reply_frame_hdl,
6851 			    &eventreply->IOCLogInfo));
6852 		}
6853 	}
6854 
6855 	/*
6856 	 * figure out what kind of event we got and handle accordingly
6857 	 */
6858 	switch (event) {
6859 	case MPI2_EVENT_LOG_ENTRY_ADDED:
6860 		break;
6861 	case MPI2_EVENT_LOG_DATA:
6862 		iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
6863 		    &eventreply->IOCLogInfo);
6864 		NDBG20(("mptsas %d log info %x received.\n", mpt->m_instance,
6865 		    iocloginfo));
6866 		break;
6867 	case MPI2_EVENT_STATE_CHANGE:
6868 		NDBG20(("mptsas%d state change.", mpt->m_instance));
6869 		break;
6870 	case MPI2_EVENT_HARD_RESET_RECEIVED:
6871 		NDBG20(("mptsas%d event change.", mpt->m_instance));
6872 		break;
6873 	case MPI2_EVENT_SAS_DISCOVERY:
6874 	{
6875 		MPI2_EVENT_DATA_SAS_DISCOVERY	*sasdiscovery;
6876 		char				string[80];
6877 		uint8_t				rc;
6878 
6879 		sasdiscovery =
6880 		    (pMpi2EventDataSasDiscovery_t)eventreply->EventData;
6881 
6882 		rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
6883 		    &sasdiscovery->ReasonCode);
6884 		port = ddi_get8(mpt->m_acc_reply_frame_hdl,
6885 		    &sasdiscovery->PhysicalPort);
6886 		status = ddi_get32(mpt->m_acc_reply_frame_hdl,
6887 		    &sasdiscovery->DiscoveryStatus);
6888 
6889 		string[0] = 0;
6890 		switch (rc) {
6891 		case MPI2_EVENT_SAS_DISC_RC_STARTED:
6892 			(void) sprintf(string, "STARTING");
6893 			break;
6894 		case MPI2_EVENT_SAS_DISC_RC_COMPLETED:
6895 			(void) sprintf(string, "COMPLETED");
6896 			break;
6897 		default:
6898 			(void) sprintf(string, "UNKNOWN");
6899 			break;
6900 		}
6901 
6902 		NDBG20(("SAS DISCOVERY is %s for port %d, status %x", string,
6903 		    port, status));
6904 
6905 		break;
6906 	}
6907 	case MPI2_EVENT_EVENT_CHANGE:
6908 		NDBG20(("mptsas%d event change.", mpt->m_instance));
6909 		break;
6910 	case MPI2_EVENT_TASK_SET_FULL:
6911 	{
6912 		pMpi2EventDataTaskSetFull_t	taskfull;
6913 
6914 		taskfull = (pMpi2EventDataTaskSetFull_t)eventreply->EventData;
6915 
6916 		NDBG20(("TASK_SET_FULL received for mptsas%d, depth %d\n",
6917 		    mpt->m_instance,  ddi_get16(mpt->m_acc_reply_frame_hdl,
6918 		    &taskfull->CurrentDepth)));
6919 		break;
6920 	}
6921 	case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
6922 	{
6923 		/*
6924 		 * SAS TOPOLOGY CHANGE LIST Event has already been handled
6925 		 * in mptsas_handle_event_sync() of interrupt context
6926 		 */
6927 		break;
6928 	}
6929 	case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
6930 	{
6931 		pMpi2EventDataSasEnclDevStatusChange_t	encstatus;
6932 		uint8_t					rc;
6933 		char					string[80];
6934 
6935 		encstatus = (pMpi2EventDataSasEnclDevStatusChange_t)
6936 		    eventreply->EventData;
6937 
6938 		rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
6939 		    &encstatus->ReasonCode);
6940 		switch (rc) {
6941 		case MPI2_EVENT_SAS_ENCL_RC_ADDED:
6942 			(void) sprintf(string, "added");
6943 			break;
6944 		case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING:
6945 			(void) sprintf(string, ", not responding");
6946 			break;
6947 		default:
6948 		break;
6949 		}
6950 		NDBG20(("mptsas%d ENCLOSURE STATUS CHANGE for enclosure %x%s\n",
6951 		    mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl,
6952 		    &encstatus->EnclosureHandle), string));
6953 		break;
6954 	}
6955 
6956 	/*
6957 	 * MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE is handled by
6958 	 * mptsas_handle_event_sync,in here just send ack message.
6959 	 */
6960 	case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
6961 	{
6962 		pMpi2EventDataSasDeviceStatusChange_t	statuschange;
6963 		uint8_t					rc;
6964 		uint16_t				devhdl;
6965 		uint64_t				wwn = 0;
6966 		uint32_t				wwn_lo, wwn_hi;
6967 
6968 		statuschange = (pMpi2EventDataSasDeviceStatusChange_t)
6969 		    eventreply->EventData;
6970 		rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
6971 		    &statuschange->ReasonCode);
6972 		wwn_lo = ddi_get32(mpt->m_acc_reply_frame_hdl,
6973 		    (uint32_t *)(void *)&statuschange->SASAddress);
6974 		wwn_hi = ddi_get32(mpt->m_acc_reply_frame_hdl,
6975 		    (uint32_t *)(void *)&statuschange->SASAddress + 1);
6976 		wwn = ((uint64_t)wwn_hi << 32) | wwn_lo;
6977 		devhdl =  ddi_get16(mpt->m_acc_reply_frame_hdl,
6978 		    &statuschange->DevHandle);
6979 
6980 		NDBG13(("MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE wwn is %"PRIx64,
6981 		    wwn));
6982 
6983 		switch (rc) {
6984 		case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6985 			NDBG20(("SMART data received, ASC/ASCQ = %02x/%02x",
6986 			    ddi_get8(mpt->m_acc_reply_frame_hdl,
6987 			    &statuschange->ASC),
6988 			    ddi_get8(mpt->m_acc_reply_frame_hdl,
6989 			    &statuschange->ASCQ)));
6990 			break;
6991 
6992 		case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6993 			NDBG20(("Device not supported"));
6994 			break;
6995 
6996 		case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6997 			NDBG20(("IOC internally generated the Target Reset "
6998 			    "for devhdl:%x", devhdl));
6999 			break;
7000 
7001 		case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET:
7002 			NDBG20(("IOC's internally generated Target Reset "
7003 			    "completed for devhdl:%x", devhdl));
7004 			break;
7005 
7006 		case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7007 			NDBG20(("IOC internally generated Abort Task"));
7008 			break;
7009 
7010 		case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL:
7011 			NDBG20(("IOC's internally generated Abort Task "
7012 			    "completed"));
7013 			break;
7014 
7015 		case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7016 			NDBG20(("IOC internally generated Abort Task Set"));
7017 			break;
7018 
7019 		case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7020 			NDBG20(("IOC internally generated Clear Task Set"));
7021 			break;
7022 
7023 		case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7024 			NDBG20(("IOC internally generated Query Task"));
7025 			break;
7026 
7027 		case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION:
7028 			NDBG20(("Device sent an Asynchronous Notification"));
7029 			break;
7030 
7031 		default:
7032 			break;
7033 		}
7034 		break;
7035 	}
7036 	case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
7037 	{
7038 		/*
7039 		 * IR TOPOLOGY CHANGE LIST Event has already been handled
7040 		 * in mpt_handle_event_sync() of interrupt context
7041 		 */
7042 		break;
7043 	}
7044 	case MPI2_EVENT_IR_OPERATION_STATUS:
7045 	{
7046 		Mpi2EventDataIrOperationStatus_t	*irOpStatus;
7047 		char					reason_str[80];
7048 		uint8_t					rc, percent;
7049 		uint16_t				handle;
7050 
7051 		irOpStatus = (pMpi2EventDataIrOperationStatus_t)
7052 		    eventreply->EventData;
7053 		rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
7054 		    &irOpStatus->RAIDOperation);
7055 		percent = ddi_get8(mpt->m_acc_reply_frame_hdl,
7056 		    &irOpStatus->PercentComplete);
7057 		handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7058 		    &irOpStatus->VolDevHandle);
7059 
7060 		switch (rc) {
7061 			case MPI2_EVENT_IR_RAIDOP_RESYNC:
7062 				(void) sprintf(reason_str, "resync");
7063 				break;
7064 			case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION:
7065 				(void) sprintf(reason_str, "online capacity "
7066 				    "expansion");
7067 				break;
7068 			case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK:
7069 				(void) sprintf(reason_str, "consistency check");
7070 				break;
7071 			default:
7072 				(void) sprintf(reason_str, "unknown reason %x",
7073 				    rc);
7074 		}
7075 
7076 		NDBG20(("mptsas%d raid operational status: (%s)"
7077 		    "\thandle(0x%04x), percent complete(%d)\n",
7078 		    mpt->m_instance, reason_str, handle, percent));
7079 		break;
7080 	}
7081 	case MPI2_EVENT_IR_VOLUME:
7082 	{
7083 		Mpi2EventDataIrVolume_t		*irVolume;
7084 		uint16_t			devhandle;
7085 		uint32_t			state;
7086 		int				config, vol;
7087 		mptsas_slots_t			*slots = mpt->m_active;
7088 		uint8_t				found = FALSE;
7089 
7090 		irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData;
7091 		state = ddi_get32(mpt->m_acc_reply_frame_hdl,
7092 		    &irVolume->NewValue);
7093 		devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7094 		    &irVolume->VolDevHandle);
7095 
7096 		NDBG20(("EVENT_IR_VOLUME event is received"));
7097 
7098 		/*
7099 		 * Get latest RAID info and then find the DevHandle for this
7100 		 * event in the configuration.  If the DevHandle is not found
7101 		 * just exit the event.
7102 		 */
7103 		(void) mptsas_get_raid_info(mpt);
7104 		for (config = 0; config < slots->m_num_raid_configs;
7105 		    config++) {
7106 			for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
7107 				if (slots->m_raidconfig[config].m_raidvol[vol].
7108 				    m_raidhandle == devhandle) {
7109 					found = TRUE;
7110 					break;
7111 				}
7112 			}
7113 		}
7114 		if (!found) {
7115 			break;
7116 		}
7117 
7118 		switch (irVolume->ReasonCode) {
7119 		case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED:
7120 		{
7121 			uint32_t i;
7122 			slots->m_raidconfig[config].m_raidvol[vol].m_settings =
7123 			    state;
7124 
7125 			i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING;
7126 			mptsas_log(mpt, CE_NOTE, " Volume %d settings changed"
7127 			    ", auto-config of hot-swap drives is %s"
7128 			    ", write caching is %s"
7129 			    ", hot-spare pool mask is %02x\n",
7130 			    vol, state &
7131 			    MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE
7132 			    ? "disabled" : "enabled",
7133 			    i == MPI2_RAIDVOL0_SETTING_UNCHANGED
7134 			    ? "controlled by member disks" :
7135 			    i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING
7136 			    ? "disabled" :
7137 			    i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING
7138 			    ? "enabled" :
7139 			    "incorrectly set",
7140 			    (state >> 16) & 0xff);
7141 				break;
7142 		}
7143 		case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED:
7144 		{
7145 			slots->m_raidconfig[config].m_raidvol[vol].m_state =
7146 			    (uint8_t)state;
7147 
7148 			mptsas_log(mpt, CE_NOTE,
7149 			    "Volume %d is now %s\n", vol,
7150 			    state == MPI2_RAID_VOL_STATE_OPTIMAL
7151 			    ? "optimal" :
7152 			    state == MPI2_RAID_VOL_STATE_DEGRADED
7153 			    ? "degraded" :
7154 			    state == MPI2_RAID_VOL_STATE_ONLINE
7155 			    ? "online" :
7156 			    state == MPI2_RAID_VOL_STATE_INITIALIZING
7157 			    ? "initializing" :
7158 			    state == MPI2_RAID_VOL_STATE_FAILED
7159 			    ? "failed" :
7160 			    state == MPI2_RAID_VOL_STATE_MISSING
7161 			    ? "missing" :
7162 			    "state unknown");
7163 			break;
7164 		}
7165 		case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED:
7166 		{
7167 			slots->m_raidconfig[config].m_raidvol[vol].
7168 			    m_statusflags = state;
7169 
7170 			mptsas_log(mpt, CE_NOTE,
7171 			    " Volume %d is now %s%s%s%s%s%s%s%s%s\n",
7172 			    vol,
7173 			    state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED
7174 			    ? ", enabled" : ", disabled",
7175 			    state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED
7176 			    ? ", quiesced" : "",
7177 			    state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
7178 			    ? ", inactive" : ", active",
7179 			    state &
7180 			    MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL
7181 			    ? ", bad block table is full" : "",
7182 			    state &
7183 			    MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
7184 			    ? ", resync in progress" : "",
7185 			    state & MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT
7186 			    ? ", background initialization in progress" : "",
7187 			    state &
7188 			    MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION
7189 			    ? ", capacity expansion in progress" : "",
7190 			    state &
7191 			    MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK
7192 			    ? ", consistency check in progress" : "",
7193 			    state & MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB
7194 			    ? ", data scrub in progress" : "");
7195 			break;
7196 		}
7197 		default:
7198 			break;
7199 		}
7200 		break;
7201 	}
7202 	case MPI2_EVENT_IR_PHYSICAL_DISK:
7203 	{
7204 		Mpi2EventDataIrPhysicalDisk_t	*irPhysDisk;
7205 		uint16_t			devhandle, enchandle, slot;
7206 		uint32_t			status, state;
7207 		uint8_t				physdisknum, reason;
7208 
7209 		irPhysDisk = (Mpi2EventDataIrPhysicalDisk_t *)
7210 		    eventreply->EventData;
7211 		physdisknum = ddi_get8(mpt->m_acc_reply_frame_hdl,
7212 		    &irPhysDisk->PhysDiskNum);
7213 		devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7214 		    &irPhysDisk->PhysDiskDevHandle);
7215 		enchandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7216 		    &irPhysDisk->EnclosureHandle);
7217 		slot = ddi_get16(mpt->m_acc_reply_frame_hdl,
7218 		    &irPhysDisk->Slot);
7219 		state = ddi_get32(mpt->m_acc_reply_frame_hdl,
7220 		    &irPhysDisk->NewValue);
7221 		reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
7222 		    &irPhysDisk->ReasonCode);
7223 
7224 		NDBG20(("EVENT_IR_PHYSICAL_DISK event is received"));
7225 
7226 		switch (reason) {
7227 		case MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED:
7228 			mptsas_log(mpt, CE_NOTE,
7229 			    " PhysDiskNum %d with DevHandle 0x%x in slot %d "
7230 			    "for enclosure with handle 0x%x is now in hot "
7231 			    "spare pool %d",
7232 			    physdisknum, devhandle, slot, enchandle,
7233 			    (state >> 16) & 0xff);
7234 			break;
7235 
7236 		case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED:
7237 			status = state;
7238 			mptsas_log(mpt, CE_NOTE,
7239 			    " PhysDiskNum %d with DevHandle 0x%x in slot %d "
7240 			    "for enclosure with handle 0x%x is now "
7241 			    "%s%s%s%s%s\n", physdisknum, devhandle, slot,
7242 			    enchandle,
7243 			    status & MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME
7244 			    ? ", inactive" : ", active",
7245 			    status & MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
7246 			    ? ", out of sync" : "",
7247 			    status & MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED
7248 			    ? ", quiesced" : "",
7249 			    status &
7250 			    MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED
7251 			    ? ", write cache enabled" : "",
7252 			    status & MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET
7253 			    ? ", capacity expansion target" : "");
7254 			break;
7255 
7256 		case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED:
7257 			mptsas_log(mpt, CE_NOTE,
7258 			    " PhysDiskNum %d with DevHandle 0x%x in slot %d "
7259 			    "for enclosure with handle 0x%x is now %s\n",
7260 			    physdisknum, devhandle, slot, enchandle,
7261 			    state == MPI2_RAID_PD_STATE_OPTIMAL
7262 			    ? "optimal" :
7263 			    state == MPI2_RAID_PD_STATE_REBUILDING
7264 			    ? "rebuilding" :
7265 			    state == MPI2_RAID_PD_STATE_DEGRADED
7266 			    ? "degraded" :
7267 			    state == MPI2_RAID_PD_STATE_HOT_SPARE
7268 			    ? "a hot spare" :
7269 			    state == MPI2_RAID_PD_STATE_ONLINE
7270 			    ? "online" :
7271 			    state == MPI2_RAID_PD_STATE_OFFLINE
7272 			    ? "offline" :
7273 			    state == MPI2_RAID_PD_STATE_NOT_COMPATIBLE
7274 			    ? "not compatible" :
7275 			    state == MPI2_RAID_PD_STATE_NOT_CONFIGURED
7276 			    ? "not configured" :
7277 			    "state unknown");
7278 			break;
7279 		}
7280 		break;
7281 	}
7282 	default:
7283 		NDBG20(("mptsas%d: unknown event %x received",
7284 		    mpt->m_instance, event));
7285 		break;
7286 	}
7287 
7288 	/*
7289 	 * Return the reply frame to the free queue.
7290 	 */
7291 	ddi_put32(mpt->m_acc_free_queue_hdl,
7292 	    &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index], rfm);
7293 	(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
7294 	    DDI_DMA_SYNC_FORDEV);
7295 	if (++mpt->m_free_index == mpt->m_free_queue_depth) {
7296 		mpt->m_free_index = 0;
7297 	}
7298 	ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
7299 	    mpt->m_free_index);
7300 	mutex_exit(&mpt->m_mutex);
7301 }
7302 
7303 /*
7304  * invoked from timeout() to restart qfull cmds with throttle == 0
7305  */
7306 static void
7307 mptsas_restart_cmd(void *arg)
7308 {
7309 	mptsas_t	*mpt = arg;
7310 	mptsas_target_t	*ptgt = NULL;
7311 
7312 	mutex_enter(&mpt->m_mutex);
7313 
7314 	mpt->m_restart_cmd_timeid = 0;
7315 
7316 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
7317 	    MPTSAS_HASH_FIRST);
7318 	while (ptgt != NULL) {
7319 		if (ptgt->m_reset_delay == 0) {
7320 			if (ptgt->m_t_throttle == QFULL_THROTTLE) {
7321 				mptsas_set_throttle(mpt, ptgt,
7322 				    MAX_THROTTLE);
7323 			}
7324 		}
7325 
7326 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
7327 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
7328 	}
7329 	mptsas_restart_hba(mpt);
7330 	mutex_exit(&mpt->m_mutex);
7331 }
7332 
7333 void
7334 mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
7335 {
7336 	int		slot;
7337 	mptsas_slots_t	*slots = mpt->m_active;
7338 	int		t;
7339 	mptsas_target_t	*ptgt = cmd->cmd_tgt_addr;
7340 
7341 	ASSERT(cmd != NULL);
7342 	ASSERT(cmd->cmd_queued == FALSE);
7343 
7344 	/*
7345 	 * Task Management cmds are removed in their own routines.  Also,
7346 	 * we don't want to modify timeout based on TM cmds.
7347 	 */
7348 	if (cmd->cmd_flags & CFLAG_TM_CMD) {
7349 		return;
7350 	}
7351 
7352 	t = Tgt(cmd);
7353 	slot = cmd->cmd_slot;
7354 
7355 	/*
7356 	 * remove the cmd.
7357 	 */
7358 	if (cmd == slots->m_slot[slot]) {
7359 		NDBG31(("mptsas_remove_cmd: removing cmd=0x%p", (void *)cmd));
7360 		slots->m_slot[slot] = NULL;
7361 		mpt->m_ncmds--;
7362 
7363 		/*
7364 		 * only decrement per target ncmds if command
7365 		 * has a target associated with it.
7366 		 */
7367 		if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
7368 			ptgt->m_t_ncmds--;
7369 			/*
7370 			 * reset throttle if we just ran an untagged command
7371 			 * to a tagged target
7372 			 */
7373 			if ((ptgt->m_t_ncmds == 0) &&
7374 			    ((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0)) {
7375 				mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
7376 			}
7377 		}
7378 
7379 	}
7380 
7381 	/*
7382 	 * This is all we need to do for ioc commands.
7383 	 */
7384 	if (cmd->cmd_flags & CFLAG_CMDIOC) {
7385 		mptsas_return_to_pool(mpt, cmd);
7386 		return;
7387 	}
7388 
7389 	/*
7390 	 * Figure out what to set tag Q timeout for...
7391 	 *
7392 	 * Optimize: If we have duplicate's of same timeout
7393 	 * we're using, then we'll use it again until we run
7394 	 * out of duplicates.  This should be the normal case
7395 	 * for block and raw I/O.
7396 	 * If no duplicates, we have to scan through tag que and
7397 	 * find the longest timeout value and use it.  This is
7398 	 * going to take a while...
7399 	 * Add 1 to m_n_slots to account for TM request.
7400 	 */
7401 	if (cmd->cmd_pkt->pkt_time == ptgt->m_timebase) {
7402 		if (--(ptgt->m_dups) == 0) {
7403 			if (ptgt->m_t_ncmds) {
7404 				mptsas_cmd_t *ssp;
7405 				uint_t n = 0;
7406 				ushort_t nslots = (slots->m_n_slots + 1);
7407 				ushort_t i;
7408 				/*
7409 				 * This crude check assumes we don't do
7410 				 * this too often which seems reasonable
7411 				 * for block and raw I/O.
7412 				 */
7413 				for (i = 0; i < nslots; i++) {
7414 					ssp = slots->m_slot[i];
7415 					if (ssp && (Tgt(ssp) == t) &&
7416 					    (ssp->cmd_pkt->pkt_time > n)) {
7417 						n = ssp->cmd_pkt->pkt_time;
7418 						ptgt->m_dups = 1;
7419 					} else if (ssp && (Tgt(ssp) == t) &&
7420 					    (ssp->cmd_pkt->pkt_time == n)) {
7421 						ptgt->m_dups++;
7422 					}
7423 				}
7424 				ptgt->m_timebase = n;
7425 			} else {
7426 				ptgt->m_dups = 0;
7427 				ptgt->m_timebase = 0;
7428 			}
7429 		}
7430 	}
7431 	ptgt->m_timeout = ptgt->m_timebase;
7432 
7433 	ASSERT(cmd != slots->m_slot[cmd->cmd_slot]);
7434 }
7435 
7436 /*
7437  * accept all cmds on the tx_waitq if any and then
7438  * start a fresh request from the top of the device queue.
7439  *
7440  * since there are always cmds queued on the tx_waitq, and rare cmds on
7441  * the instance waitq, so this function should not be invoked in the ISR,
7442  * the mptsas_restart_waitq() is invoked in the ISR instead. otherwise, the
7443  * burden belongs to the IO dispatch CPUs is moved the interrupt CPU.
7444  */
7445 static void
7446 mptsas_restart_hba(mptsas_t *mpt)
7447 {
7448 	ASSERT(mutex_owned(&mpt->m_mutex));
7449 
7450 	mutex_enter(&mpt->m_tx_waitq_mutex);
7451 	if (mpt->m_tx_waitq) {
7452 		mptsas_accept_tx_waitq(mpt);
7453 	}
7454 	mutex_exit(&mpt->m_tx_waitq_mutex);
7455 	mptsas_restart_waitq(mpt);
7456 }
7457 
7458 /*
7459  * start a fresh request from the top of the device queue
7460  */
7461 static void
7462 mptsas_restart_waitq(mptsas_t *mpt)
7463 {
7464 	mptsas_cmd_t	*cmd, *next_cmd;
7465 	mptsas_target_t *ptgt = NULL;
7466 
7467 	NDBG1(("mptsas_restart_waitq: mpt=0x%p", (void *)mpt));
7468 
7469 	ASSERT(mutex_owned(&mpt->m_mutex));
7470 
7471 	/*
7472 	 * If there is a reset delay, don't start any cmds.  Otherwise, start
7473 	 * as many cmds as possible.
7474 	 * Since SMID 0 is reserved and the TM slot is reserved, the actual max
7475 	 * commands is m_max_requests - 2.
7476 	 */
7477 	cmd = mpt->m_waitq;
7478 
7479 	while (cmd != NULL) {
7480 		next_cmd = cmd->cmd_linkp;
7481 		if (cmd->cmd_flags & CFLAG_PASSTHRU) {
7482 			if (mptsas_save_cmd(mpt, cmd) == TRUE) {
7483 				/*
7484 				 * passthru command get slot need
7485 				 * set CFLAG_PREPARED.
7486 				 */
7487 				cmd->cmd_flags |= CFLAG_PREPARED;
7488 				mptsas_waitq_delete(mpt, cmd);
7489 				mptsas_start_passthru(mpt, cmd);
7490 			}
7491 			cmd = next_cmd;
7492 			continue;
7493 		}
7494 		if (cmd->cmd_flags & CFLAG_CONFIG) {
7495 			if (mptsas_save_cmd(mpt, cmd) == TRUE) {
7496 				/*
7497 				 * Send the config page request and delete it
7498 				 * from the waitq.
7499 				 */
7500 				cmd->cmd_flags |= CFLAG_PREPARED;
7501 				mptsas_waitq_delete(mpt, cmd);
7502 				mptsas_start_config_page_access(mpt, cmd);
7503 			}
7504 			cmd = next_cmd;
7505 			continue;
7506 		}
7507 		if (cmd->cmd_flags & CFLAG_FW_DIAG) {
7508 			if (mptsas_save_cmd(mpt, cmd) == TRUE) {
7509 				/*
7510 				 * Send the FW Diag request and delete if from
7511 				 * the waitq.
7512 				 */
7513 				cmd->cmd_flags |= CFLAG_PREPARED;
7514 				mptsas_waitq_delete(mpt, cmd);
7515 				mptsas_start_diag(mpt, cmd);
7516 			}
7517 			cmd = next_cmd;
7518 			continue;
7519 		}
7520 
7521 		ptgt = cmd->cmd_tgt_addr;
7522 		if (ptgt && (ptgt->m_t_throttle == DRAIN_THROTTLE) &&
7523 		    (ptgt->m_t_ncmds == 0)) {
7524 			mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
7525 		}
7526 		if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) &&
7527 		    (ptgt && (ptgt->m_reset_delay == 0)) &&
7528 		    (ptgt && (ptgt->m_t_ncmds <
7529 		    ptgt->m_t_throttle))) {
7530 			if (mptsas_save_cmd(mpt, cmd) == TRUE) {
7531 				mptsas_waitq_delete(mpt, cmd);
7532 				(void) mptsas_start_cmd(mpt, cmd);
7533 			}
7534 		}
7535 		cmd = next_cmd;
7536 	}
7537 }
7538 /*
7539  * Cmds are queued if tran_start() doesn't get the m_mutexlock(no wait).
7540  * Accept all those queued cmds before new cmd is accept so that the
7541  * cmds are sent in order.
7542  */
7543 static void
7544 mptsas_accept_tx_waitq(mptsas_t *mpt)
7545 {
7546 	mptsas_cmd_t *cmd;
7547 
7548 	ASSERT(mutex_owned(&mpt->m_mutex));
7549 	ASSERT(mutex_owned(&mpt->m_tx_waitq_mutex));
7550 
7551 	/*
7552 	 * A Bus Reset could occur at any time and flush the tx_waitq,
7553 	 * so we cannot count on the tx_waitq to contain even one cmd.
7554 	 * And when the m_tx_waitq_mutex is released and run
7555 	 * mptsas_accept_pkt(), the tx_waitq may be flushed.
7556 	 */
7557 	cmd = mpt->m_tx_waitq;
7558 	for (;;) {
7559 		if ((cmd = mpt->m_tx_waitq) == NULL) {
7560 			mpt->m_tx_draining = 0;
7561 			break;
7562 		}
7563 		if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) {
7564 			mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
7565 		}
7566 		cmd->cmd_linkp = NULL;
7567 		mutex_exit(&mpt->m_tx_waitq_mutex);
7568 		if (mptsas_accept_pkt(mpt, cmd) != TRAN_ACCEPT)
7569 			cmn_err(CE_WARN, "mpt: mptsas_accept_tx_waitq: failed "
7570 			    "to accept cmd on queue\n");
7571 		mutex_enter(&mpt->m_tx_waitq_mutex);
7572 	}
7573 }
7574 
7575 
7576 /*
7577  * mpt tag type lookup
7578  */
7579 static char mptsas_tag_lookup[] =
7580 	{0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG};
7581 
7582 static int
7583 mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
7584 {
7585 	struct scsi_pkt		*pkt = CMD2PKT(cmd);
7586 	uint32_t		control = 0;
7587 	int			n;
7588 	caddr_t			mem;
7589 	pMpi2SCSIIORequest_t	io_request;
7590 	ddi_dma_handle_t	dma_hdl = mpt->m_dma_req_frame_hdl;
7591 	ddi_acc_handle_t	acc_hdl = mpt->m_acc_req_frame_hdl;
7592 	mptsas_target_t		*ptgt = cmd->cmd_tgt_addr;
7593 	uint16_t		SMID, io_flags = 0;
7594 	uint32_t		request_desc_low, request_desc_high;
7595 
7596 	NDBG1(("mptsas_start_cmd: cmd=0x%p", (void *)cmd));
7597 
7598 	/*
7599 	 * Set SMID and increment index.  Rollover to 1 instead of 0 if index
7600 	 * is at the max.  0 is an invalid SMID, so we call the first index 1.
7601 	 */
7602 	SMID = cmd->cmd_slot;
7603 
7604 	/*
7605 	 * It is possible for back to back device reset to
7606 	 * happen before the reset delay has expired.  That's
7607 	 * ok, just let the device reset go out on the bus.
7608 	 */
7609 	if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) {
7610 		ASSERT(ptgt->m_reset_delay == 0);
7611 	}
7612 
7613 	/*
7614 	 * if a non-tagged cmd is submitted to an active tagged target
7615 	 * then drain before submitting this cmd; SCSI-2 allows RQSENSE
7616 	 * to be untagged
7617 	 */
7618 	if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) &&
7619 	    (ptgt->m_t_ncmds > 1) &&
7620 	    ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) &&
7621 	    (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) {
7622 		if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) {
7623 			NDBG23(("target=%d, untagged cmd, start draining\n",
7624 			    ptgt->m_devhdl));
7625 
7626 			if (ptgt->m_reset_delay == 0) {
7627 				mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
7628 			}
7629 
7630 			mptsas_remove_cmd(mpt, cmd);
7631 			cmd->cmd_pkt_flags |= FLAG_HEAD;
7632 			mptsas_waitq_add(mpt, cmd);
7633 		}
7634 		return (DDI_FAILURE);
7635 	}
7636 
7637 	/*
7638 	 * Set correct tag bits.
7639 	 */
7640 	if (cmd->cmd_pkt_flags & FLAG_TAGMASK) {
7641 		switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags &
7642 		    FLAG_TAGMASK) >> 12)]) {
7643 		case MSG_SIMPLE_QTAG:
7644 			control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
7645 			break;
7646 		case MSG_HEAD_QTAG:
7647 			control |= MPI2_SCSIIO_CONTROL_HEADOFQ;
7648 			break;
7649 		case MSG_ORDERED_QTAG:
7650 			control |= MPI2_SCSIIO_CONTROL_ORDEREDQ;
7651 			break;
7652 		default:
7653 			mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n");
7654 			break;
7655 		}
7656 	} else {
7657 		if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) {
7658 				ptgt->m_t_throttle = 1;
7659 		}
7660 		control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
7661 	}
7662 
7663 	if (cmd->cmd_pkt_flags & FLAG_TLR) {
7664 		control |= MPI2_SCSIIO_CONTROL_TLR_ON;
7665 	}
7666 
7667 	mem = mpt->m_req_frame + (mpt->m_req_frame_size * SMID);
7668 	io_request = (pMpi2SCSIIORequest_t)mem;
7669 
7670 	bzero(io_request, sizeof (Mpi2SCSIIORequest_t));
7671 	ddi_put8(acc_hdl, &io_request->SGLOffset0, offsetof
7672 	    (MPI2_SCSI_IO_REQUEST, SGL) / 4);
7673 	mptsas_init_std_hdr(acc_hdl, io_request, ptgt->m_devhdl, Lun(cmd), 0,
7674 	    MPI2_FUNCTION_SCSI_IO_REQUEST);
7675 
7676 	(void) ddi_rep_put8(acc_hdl, (uint8_t *)pkt->pkt_cdbp,
7677 	    io_request->CDB.CDB32, cmd->cmd_cdblen, DDI_DEV_AUTOINCR);
7678 
7679 	io_flags = cmd->cmd_cdblen;
7680 	ddi_put16(acc_hdl, &io_request->IoFlags, io_flags);
7681 	/*
7682 	 * setup the Scatter/Gather DMA list for this request
7683 	 */
7684 	if (cmd->cmd_cookiec > 0) {
7685 		mptsas_sge_setup(mpt, cmd, &control, io_request, acc_hdl);
7686 	} else {
7687 		ddi_put32(acc_hdl, &io_request->SGL.MpiSimple.FlagsLength,
7688 		    ((uint32_t)MPI2_SGE_FLAGS_LAST_ELEMENT |
7689 		    MPI2_SGE_FLAGS_END_OF_BUFFER |
7690 		    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
7691 		    MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
7692 	}
7693 
7694 	/*
7695 	 * save ARQ information
7696 	 */
7697 	ddi_put8(acc_hdl, &io_request->SenseBufferLength, cmd->cmd_rqslen);
7698 	if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) ==
7699 	    (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) {
7700 		ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress,
7701 		    cmd->cmd_ext_arqcookie.dmac_address);
7702 	} else {
7703 		ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress,
7704 		    cmd->cmd_arqcookie.dmac_address);
7705 	}
7706 
7707 	ddi_put32(acc_hdl, &io_request->Control, control);
7708 
7709 	NDBG31(("starting message=0x%p, with cmd=0x%p",
7710 	    (void *)(uintptr_t)mpt->m_req_frame_dma_addr, (void *)cmd));
7711 
7712 	(void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
7713 
7714 	/*
7715 	 * Build request descriptor and write it to the request desc post reg.
7716 	 */
7717 	request_desc_low = (SMID << 16) + MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
7718 	request_desc_high = ptgt->m_devhdl << 16;
7719 	MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high);
7720 
7721 	/*
7722 	 * Start timeout.
7723 	 */
7724 #ifdef MPTSAS_TEST
7725 	/*
7726 	 * Temporarily set timebase = 0;  needed for
7727 	 * timeout torture test.
7728 	 */
7729 	if (mptsas_test_timeouts) {
7730 		ptgt->m_timebase = 0;
7731 	}
7732 #endif
7733 	n = pkt->pkt_time - ptgt->m_timebase;
7734 
7735 	if (n == 0) {
7736 		(ptgt->m_dups)++;
7737 		ptgt->m_timeout = ptgt->m_timebase;
7738 	} else if (n > 0) {
7739 		ptgt->m_timeout =
7740 		    ptgt->m_timebase = pkt->pkt_time;
7741 		ptgt->m_dups = 1;
7742 	} else if (n < 0) {
7743 		ptgt->m_timeout = ptgt->m_timebase;
7744 	}
7745 #ifdef MPTSAS_TEST
7746 	/*
7747 	 * Set back to a number higher than
7748 	 * mptsas_scsi_watchdog_tick
7749 	 * so timeouts will happen in mptsas_watchsubr
7750 	 */
7751 	if (mptsas_test_timeouts) {
7752 		ptgt->m_timebase = 60;
7753 	}
7754 #endif
7755 
7756 	if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
7757 	    (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
7758 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
7759 		return (DDI_FAILURE);
7760 	}
7761 	return (DDI_SUCCESS);
7762 }
7763 
7764 /*
7765  * Select a helper thread to handle current doneq
7766  */
7767 static void
7768 mptsas_deliver_doneq_thread(mptsas_t *mpt)
7769 {
7770 	uint64_t			t, i;
7771 	uint32_t			min = 0xffffffff;
7772 	mptsas_doneq_thread_list_t	*item;
7773 
7774 	for (i = 0; i < mpt->m_doneq_thread_n; i++) {
7775 		item = &mpt->m_doneq_thread_id[i];
7776 		/*
7777 		 * If the completed command on help thread[i] less than
7778 		 * doneq_thread_threshold, then pick the thread[i]. Otherwise
7779 		 * pick a thread which has least completed command.
7780 		 */
7781 
7782 		mutex_enter(&item->mutex);
7783 		if (item->len < mpt->m_doneq_thread_threshold) {
7784 			t = i;
7785 			mutex_exit(&item->mutex);
7786 			break;
7787 		}
7788 		if (item->len < min) {
7789 			min = item->len;
7790 			t = i;
7791 		}
7792 		mutex_exit(&item->mutex);
7793 	}
7794 	mutex_enter(&mpt->m_doneq_thread_id[t].mutex);
7795 	mptsas_doneq_mv(mpt, t);
7796 	cv_signal(&mpt->m_doneq_thread_id[t].cv);
7797 	mutex_exit(&mpt->m_doneq_thread_id[t].mutex);
7798 }
7799 
7800 /*
7801  * move the current global doneq to the doneq of thead[t]
7802  */
7803 static void
7804 mptsas_doneq_mv(mptsas_t *mpt, uint64_t t)
7805 {
7806 	mptsas_cmd_t			*cmd;
7807 	mptsas_doneq_thread_list_t	*item = &mpt->m_doneq_thread_id[t];
7808 
7809 	ASSERT(mutex_owned(&item->mutex));
7810 	while ((cmd = mpt->m_doneq) != NULL) {
7811 		if ((mpt->m_doneq = cmd->cmd_linkp) == NULL) {
7812 			mpt->m_donetail = &mpt->m_doneq;
7813 		}
7814 		cmd->cmd_linkp = NULL;
7815 		*item->donetail = cmd;
7816 		item->donetail = &cmd->cmd_linkp;
7817 		mpt->m_doneq_len--;
7818 		item->len++;
7819 	}
7820 }
7821 
7822 void
7823 mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd)
7824 {
7825 	struct scsi_pkt	*pkt = CMD2PKT(cmd);
7826 
7827 	/* Check all acc and dma handles */
7828 	if ((mptsas_check_acc_handle(mpt->m_datap) !=
7829 	    DDI_SUCCESS) ||
7830 	    (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
7831 	    DDI_SUCCESS) ||
7832 	    (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) !=
7833 	    DDI_SUCCESS) ||
7834 	    (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) !=
7835 	    DDI_SUCCESS) ||
7836 	    (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) !=
7837 	    DDI_SUCCESS) ||
7838 	    (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) !=
7839 	    DDI_SUCCESS) ||
7840 	    (mptsas_check_acc_handle(mpt->m_config_handle) !=
7841 	    DDI_SUCCESS)) {
7842 		ddi_fm_service_impact(mpt->m_dip,
7843 		    DDI_SERVICE_UNAFFECTED);
7844 		ddi_fm_acc_err_clear(mpt->m_config_handle,
7845 		    DDI_FME_VER0);
7846 		pkt->pkt_reason = CMD_TRAN_ERR;
7847 		pkt->pkt_statistics = 0;
7848 	}
7849 	if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
7850 	    DDI_SUCCESS) ||
7851 	    (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) !=
7852 	    DDI_SUCCESS) ||
7853 	    (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) !=
7854 	    DDI_SUCCESS) ||
7855 	    (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) !=
7856 	    DDI_SUCCESS) ||
7857 	    (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) !=
7858 	    DDI_SUCCESS)) {
7859 		ddi_fm_service_impact(mpt->m_dip,
7860 		    DDI_SERVICE_UNAFFECTED);
7861 		pkt->pkt_reason = CMD_TRAN_ERR;
7862 		pkt->pkt_statistics = 0;
7863 	}
7864 	if (cmd->cmd_dmahandle &&
7865 	    (mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS)) {
7866 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
7867 		pkt->pkt_reason = CMD_TRAN_ERR;
7868 		pkt->pkt_statistics = 0;
7869 	}
7870 	if ((cmd->cmd_extra_frames &&
7871 	    ((mptsas_check_dma_handle(cmd->cmd_extra_frames->m_dma_hdl) !=
7872 	    DDI_SUCCESS) ||
7873 	    (mptsas_check_acc_handle(cmd->cmd_extra_frames->m_acc_hdl) !=
7874 	    DDI_SUCCESS)))) {
7875 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
7876 		pkt->pkt_reason = CMD_TRAN_ERR;
7877 		pkt->pkt_statistics = 0;
7878 	}
7879 	if (cmd->cmd_arqhandle &&
7880 	    (mptsas_check_dma_handle(cmd->cmd_arqhandle) != DDI_SUCCESS)) {
7881 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
7882 		pkt->pkt_reason = CMD_TRAN_ERR;
7883 		pkt->pkt_statistics = 0;
7884 	}
7885 	if (cmd->cmd_ext_arqhandle &&
7886 	    (mptsas_check_dma_handle(cmd->cmd_ext_arqhandle) != DDI_SUCCESS)) {
7887 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
7888 		pkt->pkt_reason = CMD_TRAN_ERR;
7889 		pkt->pkt_statistics = 0;
7890 	}
7891 }
7892 
7893 /*
7894  * These routines manipulate the queue of commands that
7895  * are waiting for their completion routines to be called.
7896  * The queue is usually in FIFO order but on an MP system
7897  * it's possible for the completion routines to get out
7898  * of order. If that's a problem you need to add a global
7899  * mutex around the code that calls the completion routine
7900  * in the interrupt handler.
7901  */
7902 static void
7903 mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd)
7904 {
7905 	struct scsi_pkt	*pkt = CMD2PKT(cmd);
7906 
7907 	NDBG31(("mptsas_doneq_add: cmd=0x%p", (void *)cmd));
7908 
7909 	ASSERT((cmd->cmd_flags & CFLAG_COMPLETED) == 0);
7910 	cmd->cmd_linkp = NULL;
7911 	cmd->cmd_flags |= CFLAG_FINISHED;
7912 	cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT;
7913 
7914 	mptsas_fma_check(mpt, cmd);
7915 
7916 	/*
7917 	 * only add scsi pkts that have completion routines to
7918 	 * the doneq.  no intr cmds do not have callbacks.
7919 	 */
7920 	if (pkt && (pkt->pkt_comp)) {
7921 		*mpt->m_donetail = cmd;
7922 		mpt->m_donetail = &cmd->cmd_linkp;
7923 		mpt->m_doneq_len++;
7924 	}
7925 }
7926 
7927 static mptsas_cmd_t *
7928 mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t)
7929 {
7930 	mptsas_cmd_t			*cmd;
7931 	mptsas_doneq_thread_list_t	*item = &mpt->m_doneq_thread_id[t];
7932 
7933 	/* pop one off the done queue */
7934 	if ((cmd = item->doneq) != NULL) {
7935 		/* if the queue is now empty fix the tail pointer */
7936 		NDBG31(("mptsas_doneq_thread_rm: cmd=0x%p", (void *)cmd));
7937 		if ((item->doneq = cmd->cmd_linkp) == NULL) {
7938 			item->donetail = &item->doneq;
7939 		}
7940 		cmd->cmd_linkp = NULL;
7941 		item->len--;
7942 	}
7943 	return (cmd);
7944 }
7945 
7946 static void
7947 mptsas_doneq_empty(mptsas_t *mpt)
7948 {
7949 	if (mpt->m_doneq && !mpt->m_in_callback) {
7950 		mptsas_cmd_t	*cmd, *next;
7951 		struct scsi_pkt *pkt;
7952 
7953 		mpt->m_in_callback = 1;
7954 		cmd = mpt->m_doneq;
7955 		mpt->m_doneq = NULL;
7956 		mpt->m_donetail = &mpt->m_doneq;
7957 		mpt->m_doneq_len = 0;
7958 
7959 		mutex_exit(&mpt->m_mutex);
7960 		/*
7961 		 * run the completion routines of all the
7962 		 * completed commands
7963 		 */
7964 		while (cmd != NULL) {
7965 			next = cmd->cmd_linkp;
7966 			cmd->cmd_linkp = NULL;
7967 			/* run this command's completion routine */
7968 			cmd->cmd_flags |= CFLAG_COMPLETED;
7969 			pkt = CMD2PKT(cmd);
7970 			mptsas_pkt_comp(pkt, cmd);
7971 			cmd = next;
7972 		}
7973 		mutex_enter(&mpt->m_mutex);
7974 		mpt->m_in_callback = 0;
7975 	}
7976 }
7977 
7978 /*
7979  * These routines manipulate the target's queue of pending requests
7980  */
7981 void
7982 mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd)
7983 {
7984 	NDBG7(("mptsas_waitq_add: cmd=0x%p", (void *)cmd));
7985 	mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
7986 	cmd->cmd_queued = TRUE;
7987 	if (ptgt)
7988 		ptgt->m_t_nwait++;
7989 	if (cmd->cmd_pkt_flags & FLAG_HEAD) {
7990 		if ((cmd->cmd_linkp = mpt->m_waitq) == NULL) {
7991 			mpt->m_waitqtail = &cmd->cmd_linkp;
7992 		}
7993 		mpt->m_waitq = cmd;
7994 	} else {
7995 		cmd->cmd_linkp = NULL;
7996 		*(mpt->m_waitqtail) = cmd;
7997 		mpt->m_waitqtail = &cmd->cmd_linkp;
7998 	}
7999 }
8000 
8001 static mptsas_cmd_t *
8002 mptsas_waitq_rm(mptsas_t *mpt)
8003 {
8004 	mptsas_cmd_t	*cmd;
8005 	mptsas_target_t *ptgt;
8006 	NDBG7(("mptsas_waitq_rm"));
8007 
8008 	MPTSAS_WAITQ_RM(mpt, cmd);
8009 
8010 	NDBG7(("mptsas_waitq_rm: cmd=0x%p", (void *)cmd));
8011 	if (cmd) {
8012 		ptgt = cmd->cmd_tgt_addr;
8013 		if (ptgt) {
8014 			ptgt->m_t_nwait--;
8015 			ASSERT(ptgt->m_t_nwait >= 0);
8016 		}
8017 	}
8018 	return (cmd);
8019 }
8020 
8021 /*
8022  * remove specified cmd from the middle of the wait queue.
8023  */
8024 static void
8025 mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd)
8026 {
8027 	mptsas_cmd_t	*prevp = mpt->m_waitq;
8028 	mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
8029 
8030 	NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
8031 	    (void *)mpt, (void *)cmd));
8032 	if (ptgt) {
8033 		ptgt->m_t_nwait--;
8034 		ASSERT(ptgt->m_t_nwait >= 0);
8035 	}
8036 
8037 	if (prevp == cmd) {
8038 		if ((mpt->m_waitq = cmd->cmd_linkp) == NULL)
8039 			mpt->m_waitqtail = &mpt->m_waitq;
8040 
8041 		cmd->cmd_linkp = NULL;
8042 		cmd->cmd_queued = FALSE;
8043 		NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
8044 		    (void *)mpt, (void *)cmd));
8045 		return;
8046 	}
8047 
8048 	while (prevp != NULL) {
8049 		if (prevp->cmd_linkp == cmd) {
8050 			if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL)
8051 				mpt->m_waitqtail = &prevp->cmd_linkp;
8052 
8053 			cmd->cmd_linkp = NULL;
8054 			cmd->cmd_queued = FALSE;
8055 			NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
8056 			    (void *)mpt, (void *)cmd));
8057 			return;
8058 		}
8059 		prevp = prevp->cmd_linkp;
8060 	}
8061 	cmn_err(CE_PANIC, "mpt: mptsas_waitq_delete: queue botch");
8062 }
8063 
8064 static mptsas_cmd_t *
8065 mptsas_tx_waitq_rm(mptsas_t *mpt)
8066 {
8067 	mptsas_cmd_t *cmd;
8068 	NDBG7(("mptsas_tx_waitq_rm"));
8069 
8070 	MPTSAS_TX_WAITQ_RM(mpt, cmd);
8071 
8072 	NDBG7(("mptsas_tx_waitq_rm: cmd=0x%p", (void *)cmd));
8073 
8074 	return (cmd);
8075 }
8076 
8077 /*
8078  * remove specified cmd from the middle of the tx_waitq.
8079  */
8080 static void
8081 mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd)
8082 {
8083 	mptsas_cmd_t *prevp = mpt->m_tx_waitq;
8084 
8085 	NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
8086 	    (void *)mpt, (void *)cmd));
8087 
8088 	if (prevp == cmd) {
8089 		if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL)
8090 			mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
8091 
8092 		cmd->cmd_linkp = NULL;
8093 		cmd->cmd_queued = FALSE;
8094 		NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
8095 		    (void *)mpt, (void *)cmd));
8096 		return;
8097 	}
8098 
8099 	while (prevp != NULL) {
8100 		if (prevp->cmd_linkp == cmd) {
8101 			if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL)
8102 				mpt->m_tx_waitqtail = &prevp->cmd_linkp;
8103 
8104 			cmd->cmd_linkp = NULL;
8105 			cmd->cmd_queued = FALSE;
8106 			NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
8107 			    (void *)mpt, (void *)cmd));
8108 			return;
8109 		}
8110 		prevp = prevp->cmd_linkp;
8111 	}
8112 	cmn_err(CE_PANIC, "mpt: mptsas_tx_waitq_delete: queue botch");
8113 }
8114 
8115 /*
8116  * device and bus reset handling
8117  *
8118  * Notes:
8119  *	- RESET_ALL:	reset the controller
8120  *	- RESET_TARGET:	reset the target specified in scsi_address
8121  */
8122 static int
8123 mptsas_scsi_reset(struct scsi_address *ap, int level)
8124 {
8125 	mptsas_t		*mpt = ADDR2MPT(ap);
8126 	int			rval;
8127 	mptsas_tgt_private_t	*tgt_private;
8128 	mptsas_target_t		*ptgt = NULL;
8129 
8130 	tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->tran_tgt_private;
8131 	ptgt = tgt_private->t_private;
8132 	if (ptgt == NULL) {
8133 		return (FALSE);
8134 	}
8135 	NDBG22(("mptsas_scsi_reset: target=%d level=%d", ptgt->m_devhdl,
8136 	    level));
8137 
8138 	mutex_enter(&mpt->m_mutex);
8139 	/*
8140 	 * if we are not in panic set up a reset delay for this target
8141 	 */
8142 	if (!ddi_in_panic()) {
8143 		mptsas_setup_bus_reset_delay(mpt);
8144 	} else {
8145 		drv_usecwait(mpt->m_scsi_reset_delay * 1000);
8146 	}
8147 	rval = mptsas_do_scsi_reset(mpt, ptgt->m_devhdl);
8148 	mutex_exit(&mpt->m_mutex);
8149 
8150 	/*
8151 	 * The transport layer expect to only see TRUE and
8152 	 * FALSE. Therefore, we will adjust the return value
8153 	 * if mptsas_do_scsi_reset returns FAILED.
8154 	 */
8155 	if (rval == FAILED)
8156 		rval = FALSE;
8157 	return (rval);
8158 }
8159 
8160 static int
8161 mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl)
8162 {
8163 	int		rval = FALSE;
8164 	uint8_t		config, disk;
8165 	mptsas_slots_t	*slots = mpt->m_active;
8166 
8167 	ASSERT(mutex_owned(&mpt->m_mutex));
8168 
8169 	if (mptsas_debug_resets) {
8170 		mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d",
8171 		    devhdl);
8172 	}
8173 
8174 	/*
8175 	 * Issue a Target Reset message to the target specified but not to a
8176 	 * disk making up a raid volume.  Just look through the RAID config
8177 	 * Phys Disk list of DevHandles.  If the target's DevHandle is in this
8178 	 * list, then don't reset this target.
8179 	 */
8180 	for (config = 0; config < slots->m_num_raid_configs; config++) {
8181 		for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
8182 			if (devhdl == slots->m_raidconfig[config].
8183 			    m_physdisk_devhdl[disk]) {
8184 				return (TRUE);
8185 			}
8186 		}
8187 	}
8188 
8189 	rval = mptsas_ioc_task_management(mpt,
8190 	    MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, devhdl, 0);
8191 
8192 	mptsas_doneq_empty(mpt);
8193 	return (rval);
8194 }
8195 
8196 static int
8197 mptsas_scsi_reset_notify(struct scsi_address *ap, int flag,
8198 	void (*callback)(caddr_t), caddr_t arg)
8199 {
8200 	mptsas_t	*mpt = ADDR2MPT(ap);
8201 
8202 	NDBG22(("mptsas_scsi_reset_notify: tgt=%d", ap->a_target));
8203 
8204 	return (scsi_hba_reset_notify_setup(ap, flag, callback, arg,
8205 	    &mpt->m_mutex, &mpt->m_reset_notify_listf));
8206 }
8207 
8208 static int
8209 mptsas_get_name(struct scsi_device *sd, char *name, int len)
8210 {
8211 	dev_info_t	*lun_dip = NULL;
8212 
8213 	ASSERT(sd != NULL);
8214 	ASSERT(name != NULL);
8215 	lun_dip = sd->sd_dev;
8216 	ASSERT(lun_dip != NULL);
8217 
8218 	if (mptsas_name_child(lun_dip, name, len) == DDI_SUCCESS) {
8219 		return (1);
8220 	} else {
8221 		return (0);
8222 	}
8223 }
8224 
8225 static int
8226 mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len)
8227 {
8228 	return (mptsas_get_name(sd, name, len));
8229 }
8230 
8231 void
8232 mptsas_set_throttle(mptsas_t *mpt, mptsas_target_t *ptgt, int what)
8233 {
8234 
8235 	NDBG25(("mptsas_set_throttle: throttle=%x", what));
8236 
8237 	/*
8238 	 * if the bus is draining/quiesced, no changes to the throttles
8239 	 * are allowed. Not allowing change of throttles during draining
8240 	 * limits error recovery but will reduce draining time
8241 	 *
8242 	 * all throttles should have been set to HOLD_THROTTLE
8243 	 */
8244 	if (mpt->m_softstate & (MPTSAS_SS_QUIESCED | MPTSAS_SS_DRAINING)) {
8245 		return;
8246 	}
8247 
8248 	if (what == HOLD_THROTTLE) {
8249 		ptgt->m_t_throttle = HOLD_THROTTLE;
8250 	} else if (ptgt->m_reset_delay == 0) {
8251 		ptgt->m_t_throttle = what;
8252 	}
8253 }
8254 
8255 /*
8256  * Clean up from a device reset.
8257  * For the case of target reset, this function clears the waitq of all
8258  * commands for a particular target.   For the case of abort task set, this
8259  * function clears the waitq of all commonds for a particular target/lun.
8260  */
8261 static void
8262 mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype)
8263 {
8264 	mptsas_slots_t	*slots = mpt->m_active;
8265 	mptsas_cmd_t	*cmd, *next_cmd;
8266 	int		slot;
8267 	uchar_t		reason;
8268 	uint_t		stat;
8269 
8270 	NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun));
8271 
8272 	/*
8273 	 * Make sure the I/O Controller has flushed all cmds
8274 	 * that are associated with this target for a target reset
8275 	 * and target/lun for abort task set.
8276 	 * Account for TM requests, which use the last SMID.
8277 	 */
8278 	for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) {
8279 		if ((cmd = slots->m_slot[slot]) == NULL)
8280 			continue;
8281 		reason = CMD_RESET;
8282 		stat = STAT_DEV_RESET;
8283 		switch (tasktype) {
8284 		case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
8285 			if (Tgt(cmd) == target) {
8286 				mptsas_log(mpt, CE_NOTE, "mptsas_flush_target "
8287 				    "discovered non-NULL cmd in slot %d, "
8288 				    "tasktype 0x%x", slot, tasktype);
8289 				mptsas_dump_cmd(mpt, cmd);
8290 				mptsas_remove_cmd(mpt, cmd);
8291 				mptsas_set_pkt_reason(mpt, cmd, reason, stat);
8292 				mptsas_doneq_add(mpt, cmd);
8293 			}
8294 			break;
8295 		case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
8296 			reason = CMD_ABORTED;
8297 			stat = STAT_ABORTED;
8298 			/*FALLTHROUGH*/
8299 		case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
8300 			if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
8301 
8302 				mptsas_log(mpt, CE_NOTE, "mptsas_flush_target "
8303 				    "discovered non-NULL cmd in slot %d, "
8304 				    "tasktype 0x%x", slot, tasktype);
8305 				mptsas_dump_cmd(mpt, cmd);
8306 				mptsas_remove_cmd(mpt, cmd);
8307 				mptsas_set_pkt_reason(mpt, cmd, reason,
8308 				    stat);
8309 				mptsas_doneq_add(mpt, cmd);
8310 			}
8311 			break;
8312 		default:
8313 			break;
8314 		}
8315 	}
8316 
8317 	/*
8318 	 * Flush the waitq and tx_waitq of this target's cmds
8319 	 */
8320 	cmd = mpt->m_waitq;
8321 
8322 	reason = CMD_RESET;
8323 	stat = STAT_DEV_RESET;
8324 
8325 	switch (tasktype) {
8326 	case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
8327 		while (cmd != NULL) {
8328 			next_cmd = cmd->cmd_linkp;
8329 			if (Tgt(cmd) == target) {
8330 				mptsas_waitq_delete(mpt, cmd);
8331 				mptsas_set_pkt_reason(mpt, cmd,
8332 				    reason, stat);
8333 				mptsas_doneq_add(mpt, cmd);
8334 			}
8335 			cmd = next_cmd;
8336 		}
8337 		mutex_enter(&mpt->m_tx_waitq_mutex);
8338 		cmd = mpt->m_tx_waitq;
8339 		while (cmd != NULL) {
8340 			next_cmd = cmd->cmd_linkp;
8341 			if (Tgt(cmd) == target) {
8342 				mptsas_tx_waitq_delete(mpt, cmd);
8343 				mutex_exit(&mpt->m_tx_waitq_mutex);
8344 				mptsas_set_pkt_reason(mpt, cmd,
8345 				    reason, stat);
8346 				mptsas_doneq_add(mpt, cmd);
8347 				mutex_enter(&mpt->m_tx_waitq_mutex);
8348 			}
8349 			cmd = next_cmd;
8350 		}
8351 		mutex_exit(&mpt->m_tx_waitq_mutex);
8352 		break;
8353 	case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
8354 		reason = CMD_ABORTED;
8355 		stat =  STAT_ABORTED;
8356 		/*FALLTHROUGH*/
8357 	case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
8358 		while (cmd != NULL) {
8359 			next_cmd = cmd->cmd_linkp;
8360 			if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
8361 				mptsas_waitq_delete(mpt, cmd);
8362 				mptsas_set_pkt_reason(mpt, cmd,
8363 				    reason, stat);
8364 				mptsas_doneq_add(mpt, cmd);
8365 			}
8366 			cmd = next_cmd;
8367 		}
8368 		mutex_enter(&mpt->m_tx_waitq_mutex);
8369 		cmd = mpt->m_tx_waitq;
8370 		while (cmd != NULL) {
8371 			next_cmd = cmd->cmd_linkp;
8372 			if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
8373 				mptsas_tx_waitq_delete(mpt, cmd);
8374 				mutex_exit(&mpt->m_tx_waitq_mutex);
8375 				mptsas_set_pkt_reason(mpt, cmd,
8376 				    reason, stat);
8377 				mptsas_doneq_add(mpt, cmd);
8378 				mutex_enter(&mpt->m_tx_waitq_mutex);
8379 			}
8380 			cmd = next_cmd;
8381 		}
8382 		mutex_exit(&mpt->m_tx_waitq_mutex);
8383 		break;
8384 	default:
8385 		mptsas_log(mpt, CE_WARN, "Unknown task management type %d.",
8386 		    tasktype);
8387 		break;
8388 	}
8389 }
8390 
8391 /*
8392  * Clean up hba state, abort all outstanding command and commands in waitq
8393  * reset timeout of all targets.
8394  */
8395 static void
8396 mptsas_flush_hba(mptsas_t *mpt)
8397 {
8398 	mptsas_slots_t	*slots = mpt->m_active;
8399 	mptsas_cmd_t	*cmd;
8400 	int		slot;
8401 
8402 	NDBG25(("mptsas_flush_hba"));
8403 
8404 	/*
8405 	 * The I/O Controller should have already sent back
8406 	 * all commands via the scsi I/O reply frame.  Make
8407 	 * sure all commands have been flushed.
8408 	 * Account for TM request, which use the last SMID.
8409 	 */
8410 	for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) {
8411 		if ((cmd = slots->m_slot[slot]) == NULL)
8412 			continue;
8413 
8414 		if (cmd->cmd_flags & CFLAG_CMDIOC) {
8415 			/*
8416 			 * Need to make sure to tell everyone that might be
8417 			 * waiting on this command that it's going to fail.  If
8418 			 * we get here, this command will never timeout because
8419 			 * the active command table is going to be re-allocated,
8420 			 * so there will be nothing to check against a time out.
8421 			 * Instead, mark the command as failed due to reset.
8422 			 */
8423 			mptsas_set_pkt_reason(mpt, cmd, CMD_RESET,
8424 			    STAT_BUS_RESET);
8425 			if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
8426 			    (cmd->cmd_flags & CFLAG_CONFIG) ||
8427 			    (cmd->cmd_flags & CFLAG_FW_DIAG)) {
8428 				cmd->cmd_flags |= CFLAG_FINISHED;
8429 				cv_broadcast(&mpt->m_passthru_cv);
8430 				cv_broadcast(&mpt->m_config_cv);
8431 				cv_broadcast(&mpt->m_fw_diag_cv);
8432 			}
8433 			continue;
8434 		}
8435 
8436 		mptsas_log(mpt, CE_NOTE, "mptsas_flush_hba discovered non-NULL "
8437 		    "cmd in slot %d", slot);
8438 		mptsas_dump_cmd(mpt, cmd);
8439 
8440 		mptsas_remove_cmd(mpt, cmd);
8441 		mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
8442 		mptsas_doneq_add(mpt, cmd);
8443 	}
8444 
8445 	/*
8446 	 * Flush the waitq.
8447 	 */
8448 	while ((cmd = mptsas_waitq_rm(mpt)) != NULL) {
8449 		mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
8450 		if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
8451 		    (cmd->cmd_flags & CFLAG_CONFIG) ||
8452 		    (cmd->cmd_flags & CFLAG_FW_DIAG)) {
8453 			cmd->cmd_flags |= CFLAG_FINISHED;
8454 			cv_broadcast(&mpt->m_passthru_cv);
8455 			cv_broadcast(&mpt->m_config_cv);
8456 			cv_broadcast(&mpt->m_fw_diag_cv);
8457 		} else {
8458 			mptsas_doneq_add(mpt, cmd);
8459 		}
8460 	}
8461 
8462 	/*
8463 	 * Flush the tx_waitq
8464 	 */
8465 	mutex_enter(&mpt->m_tx_waitq_mutex);
8466 	while ((cmd = mptsas_tx_waitq_rm(mpt)) != NULL) {
8467 		mutex_exit(&mpt->m_tx_waitq_mutex);
8468 		mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
8469 		mptsas_doneq_add(mpt, cmd);
8470 		mutex_enter(&mpt->m_tx_waitq_mutex);
8471 	}
8472 	mutex_exit(&mpt->m_tx_waitq_mutex);
8473 }
8474 
8475 /*
8476  * set pkt_reason and OR in pkt_statistics flag
8477  */
8478 static void
8479 mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, uchar_t reason,
8480     uint_t stat)
8481 {
8482 #ifndef __lock_lint
8483 	_NOTE(ARGUNUSED(mpt))
8484 #endif
8485 
8486 	NDBG25(("mptsas_set_pkt_reason: cmd=0x%p reason=%x stat=%x",
8487 	    (void *)cmd, reason, stat));
8488 
8489 	if (cmd) {
8490 		if (cmd->cmd_pkt->pkt_reason == CMD_CMPLT) {
8491 			cmd->cmd_pkt->pkt_reason = reason;
8492 		}
8493 		cmd->cmd_pkt->pkt_statistics |= stat;
8494 	}
8495 }
8496 
8497 static void
8498 mptsas_start_watch_reset_delay()
8499 {
8500 	NDBG22(("mptsas_start_watch_reset_delay"));
8501 
8502 	mutex_enter(&mptsas_global_mutex);
8503 	if (mptsas_reset_watch == NULL && mptsas_timeouts_enabled) {
8504 		mptsas_reset_watch = timeout(mptsas_watch_reset_delay, NULL,
8505 		    drv_usectohz((clock_t)
8506 		    MPTSAS_WATCH_RESET_DELAY_TICK * 1000));
8507 		ASSERT(mptsas_reset_watch != NULL);
8508 	}
8509 	mutex_exit(&mptsas_global_mutex);
8510 }
8511 
8512 static void
8513 mptsas_setup_bus_reset_delay(mptsas_t *mpt)
8514 {
8515 	mptsas_target_t	*ptgt = NULL;
8516 
8517 	NDBG22(("mptsas_setup_bus_reset_delay"));
8518 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
8519 	    MPTSAS_HASH_FIRST);
8520 	while (ptgt != NULL) {
8521 		mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
8522 		ptgt->m_reset_delay = mpt->m_scsi_reset_delay;
8523 
8524 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
8525 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
8526 	}
8527 
8528 	mptsas_start_watch_reset_delay();
8529 }
8530 
8531 /*
8532  * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every
8533  * mpt instance for active reset delays
8534  */
8535 static void
8536 mptsas_watch_reset_delay(void *arg)
8537 {
8538 #ifndef __lock_lint
8539 	_NOTE(ARGUNUSED(arg))
8540 #endif
8541 
8542 	mptsas_t	*mpt;
8543 	int		not_done = 0;
8544 
8545 	NDBG22(("mptsas_watch_reset_delay"));
8546 
8547 	mutex_enter(&mptsas_global_mutex);
8548 	mptsas_reset_watch = 0;
8549 	mutex_exit(&mptsas_global_mutex);
8550 	rw_enter(&mptsas_global_rwlock, RW_READER);
8551 	for (mpt = mptsas_head; mpt != NULL; mpt = mpt->m_next) {
8552 		if (mpt->m_tran == 0) {
8553 			continue;
8554 		}
8555 		mutex_enter(&mpt->m_mutex);
8556 		not_done += mptsas_watch_reset_delay_subr(mpt);
8557 		mutex_exit(&mpt->m_mutex);
8558 	}
8559 	rw_exit(&mptsas_global_rwlock);
8560 
8561 	if (not_done) {
8562 		mptsas_start_watch_reset_delay();
8563 	}
8564 }
8565 
8566 static int
8567 mptsas_watch_reset_delay_subr(mptsas_t *mpt)
8568 {
8569 	int		done = 0;
8570 	int		restart = 0;
8571 	mptsas_target_t	*ptgt = NULL;
8572 
8573 	NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt));
8574 
8575 	ASSERT(mutex_owned(&mpt->m_mutex));
8576 
8577 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
8578 	    MPTSAS_HASH_FIRST);
8579 	while (ptgt != NULL) {
8580 		if (ptgt->m_reset_delay != 0) {
8581 			ptgt->m_reset_delay -=
8582 			    MPTSAS_WATCH_RESET_DELAY_TICK;
8583 			if (ptgt->m_reset_delay <= 0) {
8584 				ptgt->m_reset_delay = 0;
8585 				mptsas_set_throttle(mpt, ptgt,
8586 				    MAX_THROTTLE);
8587 				restart++;
8588 			} else {
8589 				done = -1;
8590 			}
8591 		}
8592 
8593 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
8594 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
8595 	}
8596 
8597 	if (restart > 0) {
8598 		mptsas_restart_hba(mpt);
8599 	}
8600 	return (done);
8601 }
8602 
8603 #ifdef MPTSAS_TEST
8604 static void
8605 mptsas_test_reset(mptsas_t *mpt, int target)
8606 {
8607 	mptsas_target_t    *ptgt = NULL;
8608 
8609 	if (mptsas_rtest == target) {
8610 		if (mptsas_do_scsi_reset(mpt, target) == TRUE) {
8611 			mptsas_rtest = -1;
8612 		}
8613 		if (mptsas_rtest == -1) {
8614 			NDBG22(("mptsas_test_reset success"));
8615 		}
8616 	}
8617 }
8618 #endif
8619 
8620 /*
8621  * abort handling:
8622  *
8623  * Notes:
8624  *	- if pkt is not NULL, abort just that command
8625  *	- if pkt is NULL, abort all outstanding commands for target
8626  */
8627 static int
8628 mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
8629 {
8630 	mptsas_t		*mpt = ADDR2MPT(ap);
8631 	int			rval;
8632 	mptsas_tgt_private_t	*tgt_private;
8633 	int			target, lun;
8634 
8635 	tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->
8636 	    tran_tgt_private;
8637 	ASSERT(tgt_private != NULL);
8638 	target = tgt_private->t_private->m_devhdl;
8639 	lun = tgt_private->t_lun;
8640 
8641 	NDBG23(("mptsas_scsi_abort: target=%d.%d", target, lun));
8642 
8643 	mutex_enter(&mpt->m_mutex);
8644 	rval = mptsas_do_scsi_abort(mpt, target, lun, pkt);
8645 	mutex_exit(&mpt->m_mutex);
8646 	return (rval);
8647 }
8648 
8649 static int
8650 mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, struct scsi_pkt *pkt)
8651 {
8652 	mptsas_cmd_t	*sp = NULL;
8653 	mptsas_slots_t	*slots = mpt->m_active;
8654 	int		rval = FALSE;
8655 
8656 	ASSERT(mutex_owned(&mpt->m_mutex));
8657 
8658 	/*
8659 	 * Abort the command pkt on the target/lun in ap.  If pkt is
8660 	 * NULL, abort all outstanding commands on that target/lun.
8661 	 * If you can abort them, return 1, else return 0.
8662 	 * Each packet that's aborted should be sent back to the target
8663 	 * driver through the callback routine, with pkt_reason set to
8664 	 * CMD_ABORTED.
8665 	 *
8666 	 * abort cmd pkt on HBA hardware; clean out of outstanding
8667 	 * command lists, etc.
8668 	 */
8669 	if (pkt != NULL) {
8670 		/* abort the specified packet */
8671 		sp = PKT2CMD(pkt);
8672 
8673 		if (sp->cmd_queued) {
8674 			NDBG23(("mptsas_do_scsi_abort: queued sp=0x%p aborted",
8675 			    (void *)sp));
8676 			mptsas_waitq_delete(mpt, sp);
8677 			mptsas_set_pkt_reason(mpt, sp, CMD_ABORTED,
8678 			    STAT_ABORTED);
8679 			mptsas_doneq_add(mpt, sp);
8680 			rval = TRUE;
8681 			goto done;
8682 		}
8683 
8684 		/*
8685 		 * Have mpt firmware abort this command
8686 		 */
8687 
8688 		if (slots->m_slot[sp->cmd_slot] != NULL) {
8689 			rval = mptsas_ioc_task_management(mpt,
8690 			    MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, target,
8691 			    lun);
8692 
8693 			/*
8694 			 * The transport layer expects only TRUE and FALSE.
8695 			 * Therefore, if mptsas_ioc_task_management returns
8696 			 * FAILED we will return FALSE.
8697 			 */
8698 			if (rval == FAILED)
8699 				rval = FALSE;
8700 			goto done;
8701 		}
8702 	}
8703 
8704 	/*
8705 	 * If pkt is NULL then abort task set
8706 	 */
8707 	rval = mptsas_ioc_task_management(mpt,
8708 	    MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, target, lun);
8709 
8710 	/*
8711 	 * The transport layer expects only TRUE and FALSE.
8712 	 * Therefore, if mptsas_ioc_task_management returns
8713 	 * FAILED we will return FALSE.
8714 	 */
8715 	if (rval == FAILED)
8716 		rval = FALSE;
8717 
8718 #ifdef MPTSAS_TEST
8719 	if (rval && mptsas_test_stop) {
8720 		debug_enter("mptsas_do_scsi_abort");
8721 	}
8722 #endif
8723 
8724 done:
8725 	mptsas_doneq_empty(mpt);
8726 	return (rval);
8727 }
8728 
8729 /*
8730  * capability handling:
8731  * (*tran_getcap).  Get the capability named, and return its value.
8732  */
8733 static int
8734 mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly)
8735 {
8736 	mptsas_t	*mpt = ADDR2MPT(ap);
8737 	int		ckey;
8738 	int		rval = FALSE;
8739 
8740 	NDBG24(("mptsas_scsi_getcap: target=%d, cap=%s tgtonly=%x",
8741 	    ap->a_target, cap, tgtonly));
8742 
8743 	mutex_enter(&mpt->m_mutex);
8744 
8745 	if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) {
8746 		mutex_exit(&mpt->m_mutex);
8747 		return (UNDEFINED);
8748 	}
8749 
8750 	switch (ckey) {
8751 	case SCSI_CAP_DMA_MAX:
8752 		rval = (int)mpt->m_msg_dma_attr.dma_attr_maxxfer;
8753 		break;
8754 	case SCSI_CAP_ARQ:
8755 		rval = TRUE;
8756 		break;
8757 	case SCSI_CAP_MSG_OUT:
8758 	case SCSI_CAP_PARITY:
8759 	case SCSI_CAP_UNTAGGED_QING:
8760 		rval = TRUE;
8761 		break;
8762 	case SCSI_CAP_TAGGED_QING:
8763 		rval = TRUE;
8764 		break;
8765 	case SCSI_CAP_RESET_NOTIFICATION:
8766 		rval = TRUE;
8767 		break;
8768 	case SCSI_CAP_LINKED_CMDS:
8769 		rval = FALSE;
8770 		break;
8771 	case SCSI_CAP_QFULL_RETRIES:
8772 		rval = ((mptsas_tgt_private_t *)(ap->a_hba_tran->
8773 		    tran_tgt_private))->t_private->m_qfull_retries;
8774 		break;
8775 	case SCSI_CAP_QFULL_RETRY_INTERVAL:
8776 		rval = drv_hztousec(((mptsas_tgt_private_t *)
8777 		    (ap->a_hba_tran->tran_tgt_private))->
8778 		    t_private->m_qfull_retry_interval) / 1000;
8779 		break;
8780 	case SCSI_CAP_CDB_LEN:
8781 		rval = CDB_GROUP4;
8782 		break;
8783 	case SCSI_CAP_INTERCONNECT_TYPE:
8784 		rval = INTERCONNECT_SAS;
8785 		break;
8786 	case SCSI_CAP_TRAN_LAYER_RETRIES:
8787 		if (mpt->m_ioc_capabilities &
8788 		    MPI2_IOCFACTS_CAPABILITY_TLR)
8789 			rval = TRUE;
8790 		else
8791 			rval = FALSE;
8792 		break;
8793 	default:
8794 		rval = UNDEFINED;
8795 		break;
8796 	}
8797 
8798 	NDBG24(("mptsas_scsi_getcap: %s, rval=%x", cap, rval));
8799 
8800 	mutex_exit(&mpt->m_mutex);
8801 	return (rval);
8802 }
8803 
8804 /*
8805  * (*tran_setcap).  Set the capability named to the value given.
8806  */
8807 static int
8808 mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, int tgtonly)
8809 {
8810 	mptsas_t	*mpt = ADDR2MPT(ap);
8811 	int		ckey;
8812 	int		rval = FALSE;
8813 
8814 	NDBG24(("mptsas_scsi_setcap: target=%d, cap=%s value=%x tgtonly=%x",
8815 	    ap->a_target, cap, value, tgtonly));
8816 
8817 	if (!tgtonly) {
8818 		return (rval);
8819 	}
8820 
8821 	mutex_enter(&mpt->m_mutex);
8822 
8823 	if ((mptsas_scsi_capchk(cap, tgtonly, &ckey)) != TRUE) {
8824 		mutex_exit(&mpt->m_mutex);
8825 		return (UNDEFINED);
8826 	}
8827 
8828 	switch (ckey) {
8829 	case SCSI_CAP_DMA_MAX:
8830 	case SCSI_CAP_MSG_OUT:
8831 	case SCSI_CAP_PARITY:
8832 	case SCSI_CAP_INITIATOR_ID:
8833 	case SCSI_CAP_LINKED_CMDS:
8834 	case SCSI_CAP_UNTAGGED_QING:
8835 	case SCSI_CAP_RESET_NOTIFICATION:
8836 		/*
8837 		 * None of these are settable via
8838 		 * the capability interface.
8839 		 */
8840 		break;
8841 	case SCSI_CAP_ARQ:
8842 		/*
8843 		 * We cannot turn off arq so return false if asked to
8844 		 */
8845 		if (value) {
8846 			rval = TRUE;
8847 		} else {
8848 			rval = FALSE;
8849 		}
8850 		break;
8851 	case SCSI_CAP_TAGGED_QING:
8852 		mptsas_set_throttle(mpt, ((mptsas_tgt_private_t *)
8853 		    (ap->a_hba_tran->tran_tgt_private))->t_private,
8854 		    MAX_THROTTLE);
8855 		rval = TRUE;
8856 		break;
8857 	case SCSI_CAP_QFULL_RETRIES:
8858 		((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))->
8859 		    t_private->m_qfull_retries = (uchar_t)value;
8860 		rval = TRUE;
8861 		break;
8862 	case SCSI_CAP_QFULL_RETRY_INTERVAL:
8863 		((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))->
8864 		    t_private->m_qfull_retry_interval =
8865 		    drv_usectohz(value * 1000);
8866 		rval = TRUE;
8867 		break;
8868 	default:
8869 		rval = UNDEFINED;
8870 		break;
8871 	}
8872 	mutex_exit(&mpt->m_mutex);
8873 	return (rval);
8874 }
8875 
8876 /*
8877  * Utility routine for mptsas_ifsetcap/ifgetcap
8878  */
8879 /*ARGSUSED*/
8880 static int
8881 mptsas_scsi_capchk(char *cap, int tgtonly, int *cidxp)
8882 {
8883 	NDBG24(("mptsas_scsi_capchk: cap=%s", cap));
8884 
8885 	if (!cap)
8886 		return (FALSE);
8887 
8888 	*cidxp = scsi_hba_lookup_capstr(cap);
8889 	return (TRUE);
8890 }
8891 
8892 static int
8893 mptsas_alloc_active_slots(mptsas_t *mpt, int flag)
8894 {
8895 	mptsas_slots_t	*old_active = mpt->m_active;
8896 	mptsas_slots_t	*new_active;
8897 	size_t		size;
8898 	int		rval = -1;
8899 
8900 	if (mpt->m_ncmds) {
8901 		NDBG9(("cannot change size of active slots array"));
8902 		return (rval);
8903 	}
8904 
8905 	size = MPTSAS_SLOTS_SIZE(mpt);
8906 	new_active = kmem_zalloc(size, flag);
8907 	if (new_active == NULL) {
8908 		NDBG1(("new active alloc failed"));
8909 	} else {
8910 		/*
8911 		 * Since SMID 0 is reserved and the TM slot is reserved, the
8912 		 * number of slots that can be used at any one time is
8913 		 * m_max_requests - 2.
8914 		 */
8915 		mpt->m_active = new_active;
8916 		mpt->m_active->m_n_slots = (mpt->m_max_requests - 2);
8917 		mpt->m_active->m_size = size;
8918 		mpt->m_active->m_tags = 1;
8919 		if (old_active) {
8920 			kmem_free(old_active, old_active->m_size);
8921 		}
8922 		rval = 0;
8923 	}
8924 
8925 	return (rval);
8926 }
8927 
8928 /*
8929  * Error logging, printing, and debug print routines.
8930  */
8931 static char *mptsas_label = "mpt_sas";
8932 
8933 /*PRINTFLIKE3*/
8934 void
8935 mptsas_log(mptsas_t *mpt, int level, char *fmt, ...)
8936 {
8937 	dev_info_t	*dev;
8938 	va_list		ap;
8939 
8940 	if (mpt) {
8941 		dev = mpt->m_dip;
8942 	} else {
8943 		dev = 0;
8944 	}
8945 
8946 	mutex_enter(&mptsas_log_mutex);
8947 
8948 	va_start(ap, fmt);
8949 	(void) vsprintf(mptsas_log_buf, fmt, ap);
8950 	va_end(ap);
8951 
8952 	if (level == CE_CONT) {
8953 		scsi_log(dev, mptsas_label, level, "%s\n", mptsas_log_buf);
8954 	} else {
8955 		scsi_log(dev, mptsas_label, level, "%s", mptsas_log_buf);
8956 	}
8957 
8958 	mutex_exit(&mptsas_log_mutex);
8959 }
8960 
8961 #ifdef MPTSAS_DEBUG
8962 /*PRINTFLIKE1*/
8963 void
8964 mptsas_printf(char *fmt, ...)
8965 {
8966 	dev_info_t	*dev = 0;
8967 	va_list		ap;
8968 
8969 	mutex_enter(&mptsas_log_mutex);
8970 
8971 	va_start(ap, fmt);
8972 	(void) vsprintf(mptsas_log_buf, fmt, ap);
8973 	va_end(ap);
8974 
8975 #ifdef PROM_PRINTF
8976 	prom_printf("%s:\t%s\n", mptsas_label, mptsas_log_buf);
8977 #else
8978 	scsi_log(dev, mptsas_label, SCSI_DEBUG, "%s\n", mptsas_log_buf);
8979 #endif
8980 	mutex_exit(&mptsas_log_mutex);
8981 }
8982 #endif
8983 
8984 /*
8985  * timeout handling
8986  */
8987 static void
8988 mptsas_watch(void *arg)
8989 {
8990 #ifndef __lock_lint
8991 	_NOTE(ARGUNUSED(arg))
8992 #endif
8993 
8994 	mptsas_t	*mpt;
8995 	uint32_t	doorbell;
8996 
8997 	NDBG30(("mptsas_watch"));
8998 
8999 	rw_enter(&mptsas_global_rwlock, RW_READER);
9000 	for (mpt = mptsas_head; mpt != (mptsas_t *)NULL; mpt = mpt->m_next) {
9001 
9002 		mutex_enter(&mpt->m_mutex);
9003 
9004 		/* Skip device if not powered on */
9005 		if (mpt->m_options & MPTSAS_OPT_PM) {
9006 			if (mpt->m_power_level == PM_LEVEL_D0) {
9007 				(void) pm_busy_component(mpt->m_dip, 0);
9008 				mpt->m_busy = 1;
9009 			} else {
9010 				mutex_exit(&mpt->m_mutex);
9011 				continue;
9012 			}
9013 		}
9014 
9015 		/*
9016 		 * Check if controller is in a FAULT state. If so, reset it.
9017 		 */
9018 		doorbell = ddi_get32(mpt->m_datap, &mpt->m_reg->Doorbell);
9019 		if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
9020 			doorbell &= MPI2_DOORBELL_DATA_MASK;
9021 			mptsas_log(mpt, CE_WARN, "MPT Firmware Fault, "
9022 			    "code: %04x", doorbell);
9023 			if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
9024 				mptsas_log(mpt, CE_WARN, "Reset failed"
9025 				    "after fault was detected");
9026 			}
9027 		}
9028 
9029 		/*
9030 		 * For now, always call mptsas_watchsubr.
9031 		 */
9032 		mptsas_watchsubr(mpt);
9033 
9034 		if (mpt->m_options & MPTSAS_OPT_PM) {
9035 			mpt->m_busy = 0;
9036 			(void) pm_idle_component(mpt->m_dip, 0);
9037 		}
9038 
9039 		mutex_exit(&mpt->m_mutex);
9040 	}
9041 	rw_exit(&mptsas_global_rwlock);
9042 
9043 	mutex_enter(&mptsas_global_mutex);
9044 	if (mptsas_timeouts_enabled)
9045 		mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick);
9046 	mutex_exit(&mptsas_global_mutex);
9047 }
9048 
9049 static void
9050 mptsas_watchsubr(mptsas_t *mpt)
9051 {
9052 	int		i;
9053 	mptsas_cmd_t	*cmd;
9054 	mptsas_target_t	*ptgt = NULL;
9055 
9056 	NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt));
9057 
9058 #ifdef MPTSAS_TEST
9059 	if (mptsas_enable_untagged) {
9060 		mptsas_test_untagged++;
9061 	}
9062 #endif
9063 
9064 	/*
9065 	 * Check for commands stuck in active slot
9066 	 * Account for TM requests, which use the last SMID.
9067 	 */
9068 	for (i = 0; i <= mpt->m_active->m_n_slots; i++) {
9069 		if ((cmd = mpt->m_active->m_slot[i]) != NULL) {
9070 			if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
9071 				cmd->cmd_active_timeout -=
9072 				    mptsas_scsi_watchdog_tick;
9073 				if (cmd->cmd_active_timeout <= 0) {
9074 					/*
9075 					 * There seems to be a command stuck
9076 					 * in the active slot.  Drain throttle.
9077 					 */
9078 					mptsas_set_throttle(mpt,
9079 					    cmd->cmd_tgt_addr,
9080 					    DRAIN_THROTTLE);
9081 				}
9082 			}
9083 			if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
9084 			    (cmd->cmd_flags & CFLAG_CONFIG) ||
9085 			    (cmd->cmd_flags & CFLAG_FW_DIAG)) {
9086 				cmd->cmd_active_timeout -=
9087 				    mptsas_scsi_watchdog_tick;
9088 				if (cmd->cmd_active_timeout <= 0) {
9089 					/*
9090 					 * passthrough command timeout
9091 					 */
9092 					cmd->cmd_flags |= (CFLAG_FINISHED |
9093 					    CFLAG_TIMEOUT);
9094 					cv_broadcast(&mpt->m_passthru_cv);
9095 					cv_broadcast(&mpt->m_config_cv);
9096 					cv_broadcast(&mpt->m_fw_diag_cv);
9097 				}
9098 			}
9099 		}
9100 	}
9101 
9102 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
9103 	    MPTSAS_HASH_FIRST);
9104 	while (ptgt != NULL) {
9105 		/*
9106 		 * If we were draining due to a qfull condition,
9107 		 * go back to full throttle.
9108 		 */
9109 		if ((ptgt->m_t_throttle < MAX_THROTTLE) &&
9110 		    (ptgt->m_t_throttle > HOLD_THROTTLE) &&
9111 		    (ptgt->m_t_ncmds < ptgt->m_t_throttle)) {
9112 			mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9113 			mptsas_restart_hba(mpt);
9114 		}
9115 
9116 		if ((ptgt->m_t_ncmds > 0) &&
9117 		    (ptgt->m_timebase)) {
9118 
9119 			if (ptgt->m_timebase <=
9120 			    mptsas_scsi_watchdog_tick) {
9121 				ptgt->m_timebase +=
9122 				    mptsas_scsi_watchdog_tick;
9123 				ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9124 				    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9125 				continue;
9126 			}
9127 
9128 			ptgt->m_timeout -= mptsas_scsi_watchdog_tick;
9129 
9130 			if (ptgt->m_timeout < 0) {
9131 				mptsas_cmd_timeout(mpt, ptgt->m_devhdl);
9132 				ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9133 				    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9134 				continue;
9135 			}
9136 
9137 			if ((ptgt->m_timeout) <=
9138 			    mptsas_scsi_watchdog_tick) {
9139 				NDBG23(("pending timeout"));
9140 				mptsas_set_throttle(mpt, ptgt,
9141 				    DRAIN_THROTTLE);
9142 			}
9143 		}
9144 
9145 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9146 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9147 	}
9148 }
9149 
9150 /*
9151  * timeout recovery
9152  */
9153 static void
9154 mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl)
9155 {
9156 
9157 	NDBG29(("mptsas_cmd_timeout: target=%d", devhdl));
9158 	mptsas_log(mpt, CE_WARN, "Disconnected command timeout for "
9159 	    "Target %d", devhdl);
9160 
9161 	/*
9162 	 * If the current target is not the target passed in,
9163 	 * try to reset that target.
9164 	 */
9165 	NDBG29(("mptsas_cmd_timeout: device reset"));
9166 	if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) {
9167 		mptsas_log(mpt, CE_WARN, "Target %d reset for command timeout "
9168 		    "recovery failed!", devhdl);
9169 	}
9170 }
9171 
9172 /*
9173  * Device / Hotplug control
9174  */
9175 static int
9176 mptsas_scsi_quiesce(dev_info_t *dip)
9177 {
9178 	mptsas_t	*mpt;
9179 	scsi_hba_tran_t	*tran;
9180 
9181 	tran = ddi_get_driver_private(dip);
9182 	if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
9183 		return (-1);
9184 
9185 	return (mptsas_quiesce_bus(mpt));
9186 }
9187 
9188 static int
9189 mptsas_scsi_unquiesce(dev_info_t *dip)
9190 {
9191 	mptsas_t		*mpt;
9192 	scsi_hba_tran_t	*tran;
9193 
9194 	tran = ddi_get_driver_private(dip);
9195 	if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
9196 		return (-1);
9197 
9198 	return (mptsas_unquiesce_bus(mpt));
9199 }
9200 
9201 static int
9202 mptsas_quiesce_bus(mptsas_t *mpt)
9203 {
9204 	mptsas_target_t	*ptgt = NULL;
9205 
9206 	NDBG28(("mptsas_quiesce_bus"));
9207 	mutex_enter(&mpt->m_mutex);
9208 
9209 	/* Set all the throttles to zero */
9210 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
9211 	    MPTSAS_HASH_FIRST);
9212 	while (ptgt != NULL) {
9213 		mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9214 
9215 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9216 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9217 	}
9218 
9219 	/* If there are any outstanding commands in the queue */
9220 	if (mpt->m_ncmds) {
9221 		mpt->m_softstate |= MPTSAS_SS_DRAINING;
9222 		mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
9223 		    mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000)));
9224 		if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) {
9225 			/*
9226 			 * Quiesce has been interrupted
9227 			 */
9228 			mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
9229 			ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9230 			    &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
9231 			while (ptgt != NULL) {
9232 				mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9233 
9234 				ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9235 				    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9236 			}
9237 			mptsas_restart_hba(mpt);
9238 			if (mpt->m_quiesce_timeid != 0) {
9239 				timeout_id_t tid = mpt->m_quiesce_timeid;
9240 				mpt->m_quiesce_timeid = 0;
9241 				mutex_exit(&mpt->m_mutex);
9242 				(void) untimeout(tid);
9243 				return (-1);
9244 			}
9245 			mutex_exit(&mpt->m_mutex);
9246 			return (-1);
9247 		} else {
9248 			/* Bus has been quiesced */
9249 			ASSERT(mpt->m_quiesce_timeid == 0);
9250 			mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
9251 			mpt->m_softstate |= MPTSAS_SS_QUIESCED;
9252 			mutex_exit(&mpt->m_mutex);
9253 			return (0);
9254 		}
9255 	}
9256 	/* Bus was not busy - QUIESCED */
9257 	mutex_exit(&mpt->m_mutex);
9258 
9259 	return (0);
9260 }
9261 
9262 static int
9263 mptsas_unquiesce_bus(mptsas_t *mpt)
9264 {
9265 	mptsas_target_t	*ptgt = NULL;
9266 
9267 	NDBG28(("mptsas_unquiesce_bus"));
9268 	mutex_enter(&mpt->m_mutex);
9269 	mpt->m_softstate &= ~MPTSAS_SS_QUIESCED;
9270 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
9271 	    MPTSAS_HASH_FIRST);
9272 	while (ptgt != NULL) {
9273 		mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9274 
9275 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9276 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9277 	}
9278 	mptsas_restart_hba(mpt);
9279 	mutex_exit(&mpt->m_mutex);
9280 	return (0);
9281 }
9282 
9283 static void
9284 mptsas_ncmds_checkdrain(void *arg)
9285 {
9286 	mptsas_t	*mpt = arg;
9287 	mptsas_target_t	*ptgt = NULL;
9288 
9289 	mutex_enter(&mpt->m_mutex);
9290 	if (mpt->m_softstate & MPTSAS_SS_DRAINING) {
9291 		mpt->m_quiesce_timeid = 0;
9292 		if (mpt->m_ncmds == 0) {
9293 			/* Command queue has been drained */
9294 			cv_signal(&mpt->m_cv);
9295 		} else {
9296 			/*
9297 			 * The throttle may have been reset because
9298 			 * of a SCSI bus reset
9299 			 */
9300 			ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9301 			    &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
9302 			while (ptgt != NULL) {
9303 				mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9304 
9305 				ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9306 				    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9307 			}
9308 
9309 			mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
9310 			    mpt, (MPTSAS_QUIESCE_TIMEOUT *
9311 			    drv_usectohz(1000000)));
9312 		}
9313 	}
9314 	mutex_exit(&mpt->m_mutex);
9315 }
9316 
9317 static void
9318 mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
9319 {
9320 	int	i;
9321 	uint8_t	*cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp;
9322 	char	buf[128];
9323 
9324 	buf[0] = '\0';
9325 	mptsas_log(mpt, CE_NOTE, "?Cmd (0x%p) dump for Target %d Lun %d:\n",
9326 	    (void *)cmd, Tgt(cmd), Lun(cmd));
9327 	(void) sprintf(&buf[0], "\tcdb=[");
9328 	for (i = 0; i < (int)cmd->cmd_cdblen; i++) {
9329 		(void) sprintf(&buf[strlen(buf)], " 0x%x", *cp++);
9330 	}
9331 	(void) sprintf(&buf[strlen(buf)], " ]");
9332 	mptsas_log(mpt, CE_NOTE, "?%s\n", buf);
9333 	mptsas_log(mpt, CE_NOTE,
9334 	    "?pkt_flags=0x%x pkt_statistics=0x%x pkt_state=0x%x\n",
9335 	    cmd->cmd_pkt->pkt_flags, cmd->cmd_pkt->pkt_statistics,
9336 	    cmd->cmd_pkt->pkt_state);
9337 	mptsas_log(mpt, CE_NOTE, "?pkt_scbp=0x%x cmd_flags=0x%x\n",
9338 	    *(cmd->cmd_pkt->pkt_scbp), cmd->cmd_flags);
9339 }
9340 
9341 static void
9342 mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd)
9343 {
9344 	caddr_t			memp;
9345 	pMPI2RequestHeader_t	request_hdrp;
9346 	struct scsi_pkt		*pkt = cmd->cmd_pkt;
9347 	mptsas_pt_request_t	*pt = pkt->pkt_ha_private;
9348 	uint32_t		request_size, data_size, dataout_size;
9349 	uint32_t		direction;
9350 	ddi_dma_cookie_t	data_cookie;
9351 	ddi_dma_cookie_t	dataout_cookie;
9352 	uint32_t		request_desc_low, request_desc_high = 0;
9353 	uint32_t		i, sense_bufp;
9354 	uint8_t			desc_type;
9355 	uint8_t			*request, function;
9356 	ddi_dma_handle_t	dma_hdl = mpt->m_dma_req_frame_hdl;
9357 	ddi_acc_handle_t	acc_hdl = mpt->m_acc_req_frame_hdl;
9358 
9359 	desc_type = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
9360 
9361 	request = pt->request;
9362 	direction = pt->direction;
9363 	request_size = pt->request_size;
9364 	data_size = pt->data_size;
9365 	dataout_size = pt->dataout_size;
9366 	data_cookie = pt->data_cookie;
9367 	dataout_cookie = pt->dataout_cookie;
9368 
9369 	/*
9370 	 * Store the passthrough message in memory location
9371 	 * corresponding to our slot number
9372 	 */
9373 	memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot);
9374 	request_hdrp = (pMPI2RequestHeader_t)memp;
9375 	bzero(memp, mpt->m_req_frame_size);
9376 
9377 	for (i = 0; i < request_size; i++) {
9378 		bcopy(request + i, memp + i, 1);
9379 	}
9380 
9381 	if (data_size || dataout_size) {
9382 		pMpi2SGESimple64_t	sgep;
9383 		uint32_t		sge_flags;
9384 
9385 		sgep = (pMpi2SGESimple64_t)((uint8_t *)request_hdrp +
9386 		    request_size);
9387 		if (dataout_size) {
9388 
9389 			sge_flags = dataout_size |
9390 			    ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
9391 			    MPI2_SGE_FLAGS_END_OF_BUFFER |
9392 			    MPI2_SGE_FLAGS_HOST_TO_IOC |
9393 			    MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
9394 			    MPI2_SGE_FLAGS_SHIFT);
9395 			ddi_put32(acc_hdl, &sgep->FlagsLength, sge_flags);
9396 			ddi_put32(acc_hdl, &sgep->Address.Low,
9397 			    (uint32_t)(dataout_cookie.dmac_laddress &
9398 			    0xffffffffull));
9399 			ddi_put32(acc_hdl, &sgep->Address.High,
9400 			    (uint32_t)(dataout_cookie.dmac_laddress
9401 			    >> 32));
9402 			sgep++;
9403 		}
9404 		sge_flags = data_size;
9405 		sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
9406 		    MPI2_SGE_FLAGS_LAST_ELEMENT |
9407 		    MPI2_SGE_FLAGS_END_OF_BUFFER |
9408 		    MPI2_SGE_FLAGS_END_OF_LIST |
9409 		    MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
9410 		    MPI2_SGE_FLAGS_SHIFT);
9411 		if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) {
9412 			sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_HOST_TO_IOC) <<
9413 			    MPI2_SGE_FLAGS_SHIFT);
9414 		} else {
9415 			sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_IOC_TO_HOST) <<
9416 			    MPI2_SGE_FLAGS_SHIFT);
9417 		}
9418 		ddi_put32(acc_hdl, &sgep->FlagsLength,
9419 		    sge_flags);
9420 		ddi_put32(acc_hdl, &sgep->Address.Low,
9421 		    (uint32_t)(data_cookie.dmac_laddress &
9422 		    0xffffffffull));
9423 		ddi_put32(acc_hdl, &sgep->Address.High,
9424 		    (uint32_t)(data_cookie.dmac_laddress >> 32));
9425 	}
9426 
9427 	function = request_hdrp->Function;
9428 	if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
9429 	    (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
9430 		pMpi2SCSIIORequest_t	scsi_io_req;
9431 
9432 		scsi_io_req = (pMpi2SCSIIORequest_t)request_hdrp;
9433 		/*
9434 		 * Put SGE for data and data_out buffer at the end of
9435 		 * scsi_io_request message header.(64 bytes in total)
9436 		 * Following above SGEs, the residual space will be
9437 		 * used by sense data.
9438 		 */
9439 		ddi_put8(acc_hdl,
9440 		    &scsi_io_req->SenseBufferLength,
9441 		    (uint8_t)(request_size - 64));
9442 
9443 		sense_bufp = mpt->m_req_frame_dma_addr +
9444 		    (mpt->m_req_frame_size * cmd->cmd_slot);
9445 		sense_bufp += 64;
9446 		ddi_put32(acc_hdl,
9447 		    &scsi_io_req->SenseBufferLowAddress, sense_bufp);
9448 
9449 		/*
9450 		 * Set SGLOffset0 value
9451 		 */
9452 		ddi_put8(acc_hdl, &scsi_io_req->SGLOffset0,
9453 		    offsetof(MPI2_SCSI_IO_REQUEST, SGL) / 4);
9454 
9455 		/*
9456 		 * Setup descriptor info
9457 		 */
9458 		desc_type = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
9459 		request_desc_high = (ddi_get16(acc_hdl,
9460 		    &scsi_io_req->DevHandle) << 16);
9461 	}
9462 
9463 	/*
9464 	 * We must wait till the message has been completed before
9465 	 * beginning the next message so we wait for this one to
9466 	 * finish.
9467 	 */
9468 	(void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
9469 	request_desc_low = (cmd->cmd_slot << 16) + desc_type;
9470 	cmd->cmd_rfm = NULL;
9471 	MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high);
9472 	if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
9473 	    (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
9474 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
9475 	}
9476 }
9477 
9478 
9479 
9480 static int
9481 mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
9482     uint8_t *data, uint32_t request_size, uint32_t reply_size,
9483     uint32_t data_size, uint32_t direction, uint8_t *dataout,
9484     uint32_t dataout_size, short timeout, int mode)
9485 {
9486 	mptsas_pt_request_t		pt;
9487 	mptsas_dma_alloc_state_t	data_dma_state;
9488 	mptsas_dma_alloc_state_t	dataout_dma_state;
9489 	caddr_t				memp;
9490 	mptsas_cmd_t			*cmd = NULL;
9491 	struct scsi_pkt			*pkt;
9492 	uint32_t			reply_len = 0, sense_len = 0;
9493 	pMPI2RequestHeader_t		request_hdrp;
9494 	pMPI2RequestHeader_t		request_msg;
9495 	pMPI2DefaultReply_t		reply_msg;
9496 	Mpi2SCSIIOReply_t		rep_msg;
9497 	int				i, status = 0, pt_flags = 0, rv = 0;
9498 	int				rvalue;
9499 	uint8_t				function;
9500 
9501 	ASSERT(mutex_owned(&mpt->m_mutex));
9502 
9503 	reply_msg = (pMPI2DefaultReply_t)(&rep_msg);
9504 	bzero(reply_msg, sizeof (MPI2_DEFAULT_REPLY));
9505 	request_msg = kmem_zalloc(request_size, KM_SLEEP);
9506 
9507 	mutex_exit(&mpt->m_mutex);
9508 	/*
9509 	 * copy in the request buffer since it could be used by
9510 	 * another thread when the pt request into waitq
9511 	 */
9512 	if (ddi_copyin(request, request_msg, request_size, mode)) {
9513 		mutex_enter(&mpt->m_mutex);
9514 		status = EFAULT;
9515 		mptsas_log(mpt, CE_WARN, "failed to copy request data");
9516 		goto out;
9517 	}
9518 	mutex_enter(&mpt->m_mutex);
9519 
9520 	function = request_msg->Function;
9521 	if (function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
9522 		pMpi2SCSITaskManagementRequest_t	task;
9523 		task = (pMpi2SCSITaskManagementRequest_t)request_msg;
9524 		mptsas_setup_bus_reset_delay(mpt);
9525 		rv = mptsas_ioc_task_management(mpt, task->TaskType,
9526 		    task->DevHandle, (int)task->LUN[1]);
9527 
9528 		if (rv != TRUE) {
9529 			status = EIO;
9530 			mptsas_log(mpt, CE_WARN, "task management failed");
9531 		}
9532 		goto out;
9533 	}
9534 
9535 	if (data_size != 0) {
9536 		data_dma_state.size = data_size;
9537 		if (mptsas_dma_alloc(mpt, &data_dma_state) != DDI_SUCCESS) {
9538 			status = ENOMEM;
9539 			mptsas_log(mpt, CE_WARN, "failed to alloc DMA "
9540 			    "resource");
9541 			goto out;
9542 		}
9543 		pt_flags |= MPTSAS_DATA_ALLOCATED;
9544 		if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) {
9545 			mutex_exit(&mpt->m_mutex);
9546 			for (i = 0; i < data_size; i++) {
9547 				if (ddi_copyin(data + i, (uint8_t *)
9548 				    data_dma_state.memp + i, 1, mode)) {
9549 					mutex_enter(&mpt->m_mutex);
9550 					status = EFAULT;
9551 					mptsas_log(mpt, CE_WARN, "failed to "
9552 					    "copy read data");
9553 					goto out;
9554 				}
9555 			}
9556 			mutex_enter(&mpt->m_mutex);
9557 		}
9558 	}
9559 
9560 	if (dataout_size != 0) {
9561 		dataout_dma_state.size = dataout_size;
9562 		if (mptsas_dma_alloc(mpt, &dataout_dma_state) != DDI_SUCCESS) {
9563 			status = ENOMEM;
9564 			mptsas_log(mpt, CE_WARN, "failed to alloc DMA "
9565 			    "resource");
9566 			goto out;
9567 		}
9568 		pt_flags |= MPTSAS_DATAOUT_ALLOCATED;
9569 		mutex_exit(&mpt->m_mutex);
9570 		for (i = 0; i < dataout_size; i++) {
9571 			if (ddi_copyin(dataout + i, (uint8_t *)
9572 			    dataout_dma_state.memp + i, 1, mode)) {
9573 				mutex_enter(&mpt->m_mutex);
9574 				mptsas_log(mpt, CE_WARN, "failed to copy out"
9575 				    " data");
9576 				status = EFAULT;
9577 				goto out;
9578 			}
9579 		}
9580 		mutex_enter(&mpt->m_mutex);
9581 	}
9582 
9583 	if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
9584 		status = EAGAIN;
9585 		mptsas_log(mpt, CE_NOTE, "event ack command pool is full");
9586 		goto out;
9587 	}
9588 	pt_flags |= MPTSAS_REQUEST_POOL_CMD;
9589 
9590 	bzero((caddr_t)cmd, sizeof (*cmd));
9591 	bzero((caddr_t)pkt, scsi_pkt_size());
9592 	bzero((caddr_t)&pt, sizeof (pt));
9593 
9594 	cmd->ioc_cmd_slot = (uint32_t)(rvalue);
9595 
9596 	pt.request = (uint8_t *)request_msg;
9597 	pt.direction = direction;
9598 	pt.request_size = request_size;
9599 	pt.data_size = data_size;
9600 	pt.dataout_size = dataout_size;
9601 	pt.data_cookie = data_dma_state.cookie;
9602 	pt.dataout_cookie = dataout_dma_state.cookie;
9603 
9604 	/*
9605 	 * Form a blank cmd/pkt to store the acknowledgement message
9606 	 */
9607 	pkt->pkt_cdbp		= (opaque_t)&cmd->cmd_cdb[0];
9608 	pkt->pkt_scbp		= (opaque_t)&cmd->cmd_scb;
9609 	pkt->pkt_ha_private	= (opaque_t)&pt;
9610 	pkt->pkt_flags		= FLAG_HEAD;
9611 	pkt->pkt_time		= timeout;
9612 	cmd->cmd_pkt		= pkt;
9613 	cmd->cmd_flags		= CFLAG_CMDIOC | CFLAG_PASSTHRU;
9614 
9615 	/*
9616 	 * Save the command in a slot
9617 	 */
9618 	if (mptsas_save_cmd(mpt, cmd) == TRUE) {
9619 		/*
9620 		 * Once passthru command get slot, set cmd_flags
9621 		 * CFLAG_PREPARED.
9622 		 */
9623 		cmd->cmd_flags |= CFLAG_PREPARED;
9624 		mptsas_start_passthru(mpt, cmd);
9625 	} else {
9626 		mptsas_waitq_add(mpt, cmd);
9627 	}
9628 
9629 	while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
9630 		cv_wait(&mpt->m_passthru_cv, &mpt->m_mutex);
9631 	}
9632 
9633 	if (cmd->cmd_flags & CFLAG_PREPARED) {
9634 		memp = mpt->m_req_frame + (mpt->m_req_frame_size *
9635 		    cmd->cmd_slot);
9636 		request_hdrp = (pMPI2RequestHeader_t)memp;
9637 	}
9638 
9639 	if (cmd->cmd_flags & CFLAG_TIMEOUT) {
9640 		status = ETIMEDOUT;
9641 		mptsas_log(mpt, CE_WARN, "passthrough command timeout");
9642 		pt_flags |= MPTSAS_CMD_TIMEOUT;
9643 		goto out;
9644 	}
9645 
9646 	if (cmd->cmd_rfm) {
9647 		/*
9648 		 * cmd_rfm is zero means the command reply is a CONTEXT
9649 		 * reply and no PCI Write to post the free reply SMFA
9650 		 * because no reply message frame is used.
9651 		 * cmd_rfm is non-zero means the reply is a ADDRESS
9652 		 * reply and reply message frame is used.
9653 		 */
9654 		pt_flags |= MPTSAS_ADDRESS_REPLY;
9655 		(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
9656 		    DDI_DMA_SYNC_FORCPU);
9657 		reply_msg = (pMPI2DefaultReply_t)
9658 		    (mpt->m_reply_frame + (cmd->cmd_rfm -
9659 		    mpt->m_reply_frame_dma_addr));
9660 	}
9661 
9662 	mptsas_fma_check(mpt, cmd);
9663 	if (pkt->pkt_reason == CMD_TRAN_ERR) {
9664 		status = EAGAIN;
9665 		mptsas_log(mpt, CE_WARN, "passthru fma error");
9666 		goto out;
9667 	}
9668 	if (pkt->pkt_reason == CMD_RESET) {
9669 		status = EAGAIN;
9670 		mptsas_log(mpt, CE_WARN, "ioc reset abort passthru");
9671 		goto out;
9672 	}
9673 
9674 	if (pkt->pkt_reason == CMD_INCOMPLETE) {
9675 		status = EIO;
9676 		mptsas_log(mpt, CE_WARN, "passthrough command incomplete");
9677 		goto out;
9678 	}
9679 
9680 	mutex_exit(&mpt->m_mutex);
9681 	if (cmd->cmd_flags & CFLAG_PREPARED) {
9682 		function = request_hdrp->Function;
9683 		if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
9684 		    (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
9685 			reply_len = sizeof (MPI2_SCSI_IO_REPLY);
9686 			sense_len = reply_size - reply_len;
9687 		} else {
9688 			reply_len = reply_size;
9689 			sense_len = 0;
9690 		}
9691 
9692 		for (i = 0; i < reply_len; i++) {
9693 			if (ddi_copyout((uint8_t *)reply_msg + i, reply + i, 1,
9694 			    mode)) {
9695 				mutex_enter(&mpt->m_mutex);
9696 				status = EFAULT;
9697 				mptsas_log(mpt, CE_WARN, "failed to copy out "
9698 				    "reply data");
9699 				goto out;
9700 			}
9701 		}
9702 		for (i = 0; i < sense_len; i++) {
9703 			if (ddi_copyout((uint8_t *)request_hdrp + 64 + i,
9704 			    reply + reply_len + i, 1, mode)) {
9705 				mutex_enter(&mpt->m_mutex);
9706 				status = EFAULT;
9707 				mptsas_log(mpt, CE_WARN, "failed to copy out "
9708 				    "sense data");
9709 				goto out;
9710 			}
9711 		}
9712 	}
9713 
9714 	if (data_size) {
9715 		if (direction != MPTSAS_PASS_THRU_DIRECTION_WRITE) {
9716 			(void) ddi_dma_sync(data_dma_state.handle, 0, 0,
9717 			    DDI_DMA_SYNC_FORCPU);
9718 			for (i = 0; i < data_size; i++) {
9719 				if (ddi_copyout((uint8_t *)(
9720 				    data_dma_state.memp + i), data + i,  1,
9721 				    mode)) {
9722 					mutex_enter(&mpt->m_mutex);
9723 					status = EFAULT;
9724 					mptsas_log(mpt, CE_WARN, "failed to "
9725 					    "copy out the reply data");
9726 					goto out;
9727 				}
9728 			}
9729 		}
9730 	}
9731 	mutex_enter(&mpt->m_mutex);
9732 out:
9733 	/*
9734 	 * Put the reply frame back on the free queue, increment the free
9735 	 * index, and write the new index to the free index register.  But only
9736 	 * if this reply is an ADDRESS reply.
9737 	 */
9738 	if (pt_flags & MPTSAS_ADDRESS_REPLY) {
9739 		ddi_put32(mpt->m_acc_free_queue_hdl,
9740 		    &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
9741 		    cmd->cmd_rfm);
9742 		(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
9743 		    DDI_DMA_SYNC_FORDEV);
9744 		if (++mpt->m_free_index == mpt->m_free_queue_depth) {
9745 			mpt->m_free_index = 0;
9746 		}
9747 		ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
9748 		    mpt->m_free_index);
9749 	}
9750 	if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
9751 		mptsas_remove_cmd(mpt, cmd);
9752 		pt_flags &= (~MPTSAS_REQUEST_POOL_CMD);
9753 	}
9754 	if (pt_flags & MPTSAS_REQUEST_POOL_CMD)
9755 		mptsas_return_to_pool(mpt, cmd);
9756 	if (pt_flags & MPTSAS_DATA_ALLOCATED) {
9757 		if (mptsas_check_dma_handle(data_dma_state.handle) !=
9758 		    DDI_SUCCESS) {
9759 			ddi_fm_service_impact(mpt->m_dip,
9760 			    DDI_SERVICE_UNAFFECTED);
9761 			status = EFAULT;
9762 		}
9763 		mptsas_dma_free(&data_dma_state);
9764 	}
9765 	if (pt_flags & MPTSAS_DATAOUT_ALLOCATED) {
9766 		if (mptsas_check_dma_handle(dataout_dma_state.handle) !=
9767 		    DDI_SUCCESS) {
9768 			ddi_fm_service_impact(mpt->m_dip,
9769 			    DDI_SERVICE_UNAFFECTED);
9770 			status = EFAULT;
9771 		}
9772 		mptsas_dma_free(&dataout_dma_state);
9773 	}
9774 	if (pt_flags & MPTSAS_CMD_TIMEOUT) {
9775 		if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
9776 			mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed");
9777 		}
9778 	}
9779 	if (request_msg)
9780 		kmem_free(request_msg, request_size);
9781 
9782 	return (status);
9783 }
9784 
9785 static int
9786 mptsas_pass_thru(mptsas_t *mpt, mptsas_pass_thru_t *data, int mode)
9787 {
9788 	/*
9789 	 * If timeout is 0, set timeout to default of 60 seconds.
9790 	 */
9791 	if (data->Timeout == 0) {
9792 		data->Timeout = MPTSAS_PASS_THRU_TIME_DEFAULT;
9793 	}
9794 
9795 	if (((data->DataSize == 0) &&
9796 	    (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_NONE)) ||
9797 	    ((data->DataSize != 0) &&
9798 	    ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_READ) ||
9799 	    (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_WRITE) ||
9800 	    ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) &&
9801 	    (data->DataOutSize != 0))))) {
9802 		if (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) {
9803 			data->DataDirection = MPTSAS_PASS_THRU_DIRECTION_READ;
9804 		} else {
9805 			data->DataOutSize = 0;
9806 		}
9807 		/*
9808 		 * Send passthru request messages
9809 		 */
9810 		return (mptsas_do_passthru(mpt,
9811 		    (uint8_t *)((uintptr_t)data->PtrRequest),
9812 		    (uint8_t *)((uintptr_t)data->PtrReply),
9813 		    (uint8_t *)((uintptr_t)data->PtrData),
9814 		    data->RequestSize, data->ReplySize,
9815 		    data->DataSize, data->DataDirection,
9816 		    (uint8_t *)((uintptr_t)data->PtrDataOut),
9817 		    data->DataOutSize, data->Timeout, mode));
9818 	} else {
9819 		return (EINVAL);
9820 	}
9821 }
9822 
9823 static uint8_t
9824 mptsas_get_fw_diag_buffer_number(mptsas_t *mpt, uint32_t unique_id)
9825 {
9826 	uint8_t	index;
9827 
9828 	for (index = 0; index < MPI2_DIAG_BUF_TYPE_COUNT; index++) {
9829 		if (mpt->m_fw_diag_buffer_list[index].unique_id == unique_id) {
9830 			return (index);
9831 		}
9832 	}
9833 
9834 	return (MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND);
9835 }
9836 
9837 static void
9838 mptsas_start_diag(mptsas_t *mpt, mptsas_cmd_t *cmd)
9839 {
9840 	pMpi2DiagBufferPostRequest_t	pDiag_post_msg;
9841 	pMpi2DiagReleaseRequest_t	pDiag_release_msg;
9842 	struct scsi_pkt			*pkt = cmd->cmd_pkt;
9843 	mptsas_diag_request_t		*diag = pkt->pkt_ha_private;
9844 	uint32_t			request_desc_low, i;
9845 
9846 	ASSERT(mutex_owned(&mpt->m_mutex));
9847 
9848 	/*
9849 	 * Form the diag message depending on the post or release function.
9850 	 */
9851 	if (diag->function == MPI2_FUNCTION_DIAG_BUFFER_POST) {
9852 		pDiag_post_msg = (pMpi2DiagBufferPostRequest_t)
9853 		    (mpt->m_req_frame + (mpt->m_req_frame_size *
9854 		    cmd->cmd_slot));
9855 		bzero(pDiag_post_msg, mpt->m_req_frame_size);
9856 		ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->Function,
9857 		    diag->function);
9858 		ddi_put8(mpt->m_acc_req_frame_hdl, &pDiag_post_msg->BufferType,
9859 		    diag->pBuffer->buffer_type);
9860 		ddi_put8(mpt->m_acc_req_frame_hdl,
9861 		    &pDiag_post_msg->ExtendedType,
9862 		    diag->pBuffer->extended_type);
9863 		ddi_put32(mpt->m_acc_req_frame_hdl,
9864 		    &pDiag_post_msg->BufferLength,
9865 		    diag->pBuffer->buffer_data.size);
9866 		for (i = 0; i < (sizeof (pDiag_post_msg->ProductSpecific) / 4);
9867 		    i++) {
9868 			ddi_put32(mpt->m_acc_req_frame_hdl,
9869 			    &pDiag_post_msg->ProductSpecific[i],
9870 			    diag->pBuffer->product_specific[i]);
9871 		}
9872 		ddi_put32(mpt->m_acc_req_frame_hdl,
9873 		    &pDiag_post_msg->BufferAddress.Low,
9874 		    (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress
9875 		    & 0xffffffffull));
9876 		ddi_put32(mpt->m_acc_req_frame_hdl,
9877 		    &pDiag_post_msg->BufferAddress.High,
9878 		    (uint32_t)(diag->pBuffer->buffer_data.cookie.dmac_laddress
9879 		    >> 32));
9880 	} else {
9881 		pDiag_release_msg = (pMpi2DiagReleaseRequest_t)
9882 		    (mpt->m_req_frame + (mpt->m_req_frame_size *
9883 		    cmd->cmd_slot));
9884 		bzero(pDiag_release_msg, mpt->m_req_frame_size);
9885 		ddi_put8(mpt->m_acc_req_frame_hdl,
9886 		    &pDiag_release_msg->Function, diag->function);
9887 		ddi_put8(mpt->m_acc_req_frame_hdl,
9888 		    &pDiag_release_msg->BufferType,
9889 		    diag->pBuffer->buffer_type);
9890 	}
9891 
9892 	/*
9893 	 * Send the message
9894 	 */
9895 	(void) ddi_dma_sync(mpt->m_dma_req_frame_hdl, 0, 0,
9896 	    DDI_DMA_SYNC_FORDEV);
9897 	request_desc_low = (cmd->cmd_slot << 16) +
9898 	    MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
9899 	cmd->cmd_rfm = NULL;
9900 	MPTSAS_START_CMD(mpt, request_desc_low, 0);
9901 	if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
9902 	    DDI_SUCCESS) ||
9903 	    (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
9904 	    DDI_SUCCESS)) {
9905 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
9906 	}
9907 }
9908 
9909 static int
9910 mptsas_post_fw_diag_buffer(mptsas_t *mpt,
9911     mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code)
9912 {
9913 	mptsas_diag_request_t		diag;
9914 	int				status, slot_num, post_flags = 0;
9915 	mptsas_cmd_t			*cmd = NULL;
9916 	struct scsi_pkt			*pkt;
9917 	pMpi2DiagBufferPostReply_t	reply;
9918 	uint16_t			iocstatus;
9919 	uint32_t			iocloginfo, transfer_length;
9920 
9921 	/*
9922 	 * If buffer is not enabled, just leave.
9923 	 */
9924 	*return_code = MPTSAS_FW_DIAG_ERROR_POST_FAILED;
9925 	if (!pBuffer->enabled) {
9926 		status = DDI_FAILURE;
9927 		goto out;
9928 	}
9929 
9930 	/*
9931 	 * Clear some flags initially.
9932 	 */
9933 	pBuffer->force_release = FALSE;
9934 	pBuffer->valid_data = FALSE;
9935 	pBuffer->owned_by_firmware = FALSE;
9936 
9937 	/*
9938 	 * Get a cmd buffer from the cmd buffer pool
9939 	 */
9940 	if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
9941 		status = DDI_FAILURE;
9942 		mptsas_log(mpt, CE_NOTE, "command pool is full: Post FW Diag");
9943 		goto out;
9944 	}
9945 	post_flags |= MPTSAS_REQUEST_POOL_CMD;
9946 
9947 	bzero((caddr_t)cmd, sizeof (*cmd));
9948 	bzero((caddr_t)pkt, scsi_pkt_size());
9949 
9950 	cmd->ioc_cmd_slot = (uint32_t)(slot_num);
9951 
9952 	diag.pBuffer = pBuffer;
9953 	diag.function = MPI2_FUNCTION_DIAG_BUFFER_POST;
9954 
9955 	/*
9956 	 * Form a blank cmd/pkt to store the acknowledgement message
9957 	 */
9958 	pkt->pkt_ha_private	= (opaque_t)&diag;
9959 	pkt->pkt_flags		= FLAG_HEAD;
9960 	pkt->pkt_time		= 60;
9961 	cmd->cmd_pkt		= pkt;
9962 	cmd->cmd_flags		= CFLAG_CMDIOC | CFLAG_FW_DIAG;
9963 
9964 	/*
9965 	 * Save the command in a slot
9966 	 */
9967 	if (mptsas_save_cmd(mpt, cmd) == TRUE) {
9968 		/*
9969 		 * Once passthru command get slot, set cmd_flags
9970 		 * CFLAG_PREPARED.
9971 		 */
9972 		cmd->cmd_flags |= CFLAG_PREPARED;
9973 		mptsas_start_diag(mpt, cmd);
9974 	} else {
9975 		mptsas_waitq_add(mpt, cmd);
9976 	}
9977 
9978 	while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
9979 		cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex);
9980 	}
9981 
9982 	if (cmd->cmd_flags & CFLAG_TIMEOUT) {
9983 		status = DDI_FAILURE;
9984 		mptsas_log(mpt, CE_WARN, "Post FW Diag command timeout");
9985 		goto out;
9986 	}
9987 
9988 	/*
9989 	 * cmd_rfm points to the reply message if a reply was given.  Check the
9990 	 * IOCStatus to make sure everything went OK with the FW diag request
9991 	 * and set buffer flags.
9992 	 */
9993 	if (cmd->cmd_rfm) {
9994 		post_flags |= MPTSAS_ADDRESS_REPLY;
9995 		(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
9996 		    DDI_DMA_SYNC_FORCPU);
9997 		reply = (pMpi2DiagBufferPostReply_t)(mpt->m_reply_frame +
9998 		    (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr));
9999 
10000 		/*
10001 		 * Get the reply message data
10002 		 */
10003 		iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
10004 		    &reply->IOCStatus);
10005 		iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
10006 		    &reply->IOCLogInfo);
10007 		transfer_length = ddi_get32(mpt->m_acc_reply_frame_hdl,
10008 		    &reply->TransferLength);
10009 
10010 		/*
10011 		 * If post failed quit.
10012 		 */
10013 		if (iocstatus != MPI2_IOCSTATUS_SUCCESS) {
10014 			status = DDI_FAILURE;
10015 			NDBG13(("post FW Diag Buffer failed: IOCStatus=0x%x, "
10016 			    "IOCLogInfo=0x%x, TransferLength=0x%x", iocstatus,
10017 			    iocloginfo, transfer_length));
10018 			goto out;
10019 		}
10020 
10021 		/*
10022 		 * Post was successful.
10023 		 */
10024 		pBuffer->valid_data = TRUE;
10025 		pBuffer->owned_by_firmware = TRUE;
10026 		*return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS;
10027 		status = DDI_SUCCESS;
10028 	}
10029 
10030 out:
10031 	/*
10032 	 * Put the reply frame back on the free queue, increment the free
10033 	 * index, and write the new index to the free index register.  But only
10034 	 * if this reply is an ADDRESS reply.
10035 	 */
10036 	if (post_flags & MPTSAS_ADDRESS_REPLY) {
10037 		ddi_put32(mpt->m_acc_free_queue_hdl,
10038 		    &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
10039 		    cmd->cmd_rfm);
10040 		(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
10041 		    DDI_DMA_SYNC_FORDEV);
10042 		if (++mpt->m_free_index == mpt->m_free_queue_depth) {
10043 			mpt->m_free_index = 0;
10044 		}
10045 		ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
10046 		    mpt->m_free_index);
10047 	}
10048 	if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
10049 		mptsas_remove_cmd(mpt, cmd);
10050 		post_flags &= (~MPTSAS_REQUEST_POOL_CMD);
10051 	}
10052 	if (post_flags & MPTSAS_REQUEST_POOL_CMD) {
10053 		mptsas_return_to_pool(mpt, cmd);
10054 	}
10055 
10056 	return (status);
10057 }
10058 
10059 static int
10060 mptsas_release_fw_diag_buffer(mptsas_t *mpt,
10061     mptsas_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code,
10062     uint32_t diag_type)
10063 {
10064 	mptsas_diag_request_t	diag;
10065 	int			status, slot_num, rel_flags = 0;
10066 	mptsas_cmd_t		*cmd = NULL;
10067 	struct scsi_pkt		*pkt;
10068 	pMpi2DiagReleaseReply_t	reply;
10069 	uint16_t		iocstatus;
10070 	uint32_t		iocloginfo;
10071 
10072 	/*
10073 	 * If buffer is not enabled, just leave.
10074 	 */
10075 	*return_code = MPTSAS_FW_DIAG_ERROR_RELEASE_FAILED;
10076 	if (!pBuffer->enabled) {
10077 		mptsas_log(mpt, CE_NOTE, "This buffer type is not supported "
10078 		    "by the IOC");
10079 		status = DDI_FAILURE;
10080 		goto out;
10081 	}
10082 
10083 	/*
10084 	 * Clear some flags initially.
10085 	 */
10086 	pBuffer->force_release = FALSE;
10087 	pBuffer->valid_data = FALSE;
10088 	pBuffer->owned_by_firmware = FALSE;
10089 
10090 	/*
10091 	 * Get a cmd buffer from the cmd buffer pool
10092 	 */
10093 	if ((slot_num = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
10094 		status = DDI_FAILURE;
10095 		mptsas_log(mpt, CE_NOTE, "command pool is full: Release FW "
10096 		    "Diag");
10097 		goto out;
10098 	}
10099 	rel_flags |= MPTSAS_REQUEST_POOL_CMD;
10100 
10101 	bzero((caddr_t)cmd, sizeof (*cmd));
10102 	bzero((caddr_t)pkt, scsi_pkt_size());
10103 
10104 	cmd->ioc_cmd_slot = (uint32_t)(slot_num);
10105 
10106 	diag.pBuffer = pBuffer;
10107 	diag.function = MPI2_FUNCTION_DIAG_RELEASE;
10108 
10109 	/*
10110 	 * Form a blank cmd/pkt to store the acknowledgement message
10111 	 */
10112 	pkt->pkt_ha_private	= (opaque_t)&diag;
10113 	pkt->pkt_flags		= FLAG_HEAD;
10114 	pkt->pkt_time		= 60;
10115 	cmd->cmd_pkt		= pkt;
10116 	cmd->cmd_flags		= CFLAG_CMDIOC | CFLAG_FW_DIAG;
10117 
10118 	/*
10119 	 * Save the command in a slot
10120 	 */
10121 	if (mptsas_save_cmd(mpt, cmd) == TRUE) {
10122 		/*
10123 		 * Once passthru command get slot, set cmd_flags
10124 		 * CFLAG_PREPARED.
10125 		 */
10126 		cmd->cmd_flags |= CFLAG_PREPARED;
10127 		mptsas_start_diag(mpt, cmd);
10128 	} else {
10129 		mptsas_waitq_add(mpt, cmd);
10130 	}
10131 
10132 	while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
10133 		cv_wait(&mpt->m_fw_diag_cv, &mpt->m_mutex);
10134 	}
10135 
10136 	if (cmd->cmd_flags & CFLAG_TIMEOUT) {
10137 		status = DDI_FAILURE;
10138 		mptsas_log(mpt, CE_WARN, "Release FW Diag command timeout");
10139 		goto out;
10140 	}
10141 
10142 	/*
10143 	 * cmd_rfm points to the reply message if a reply was given.  Check the
10144 	 * IOCStatus to make sure everything went OK with the FW diag request
10145 	 * and set buffer flags.
10146 	 */
10147 	if (cmd->cmd_rfm) {
10148 		rel_flags |= MPTSAS_ADDRESS_REPLY;
10149 		(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
10150 		    DDI_DMA_SYNC_FORCPU);
10151 		reply = (pMpi2DiagReleaseReply_t)(mpt->m_reply_frame +
10152 		    (cmd->cmd_rfm - mpt->m_reply_frame_dma_addr));
10153 
10154 		/*
10155 		 * Get the reply message data
10156 		 */
10157 		iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
10158 		    &reply->IOCStatus);
10159 		iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
10160 		    &reply->IOCLogInfo);
10161 
10162 		/*
10163 		 * If release failed quit.
10164 		 */
10165 		if ((iocstatus != MPI2_IOCSTATUS_SUCCESS) ||
10166 		    pBuffer->owned_by_firmware) {
10167 			status = DDI_FAILURE;
10168 			NDBG13(("release FW Diag Buffer failed: "
10169 			    "IOCStatus=0x%x, IOCLogInfo=0x%x", iocstatus,
10170 			    iocloginfo));
10171 			goto out;
10172 		}
10173 
10174 		/*
10175 		 * Release was successful.
10176 		 */
10177 		*return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS;
10178 		status = DDI_SUCCESS;
10179 
10180 		/*
10181 		 * If this was for an UNREGISTER diag type command, clear the
10182 		 * unique ID.
10183 		 */
10184 		if (diag_type == MPTSAS_FW_DIAG_TYPE_UNREGISTER) {
10185 			pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID;
10186 		}
10187 	}
10188 
10189 out:
10190 	/*
10191 	 * Put the reply frame back on the free queue, increment the free
10192 	 * index, and write the new index to the free index register.  But only
10193 	 * if this reply is an ADDRESS reply.
10194 	 */
10195 	if (rel_flags & MPTSAS_ADDRESS_REPLY) {
10196 		ddi_put32(mpt->m_acc_free_queue_hdl,
10197 		    &((uint32_t *)(void *)mpt->m_free_queue)[mpt->m_free_index],
10198 		    cmd->cmd_rfm);
10199 		(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
10200 		    DDI_DMA_SYNC_FORDEV);
10201 		if (++mpt->m_free_index == mpt->m_free_queue_depth) {
10202 			mpt->m_free_index = 0;
10203 		}
10204 		ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
10205 		    mpt->m_free_index);
10206 	}
10207 	if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
10208 		mptsas_remove_cmd(mpt, cmd);
10209 		rel_flags &= (~MPTSAS_REQUEST_POOL_CMD);
10210 	}
10211 	if (rel_flags & MPTSAS_REQUEST_POOL_CMD) {
10212 		mptsas_return_to_pool(mpt, cmd);
10213 	}
10214 
10215 	return (status);
10216 }
10217 
10218 static int
10219 mptsas_diag_register(mptsas_t *mpt, mptsas_fw_diag_register_t *diag_register,
10220     uint32_t *return_code)
10221 {
10222 	mptsas_fw_diagnostic_buffer_t	*pBuffer;
10223 	uint8_t				extended_type, buffer_type, i;
10224 	uint32_t			buffer_size;
10225 	uint32_t			unique_id;
10226 	int				status;
10227 
10228 	ASSERT(mutex_owned(&mpt->m_mutex));
10229 
10230 	extended_type = diag_register->ExtendedType;
10231 	buffer_type = diag_register->BufferType;
10232 	buffer_size = diag_register->RequestedBufferSize;
10233 	unique_id = diag_register->UniqueId;
10234 
10235 	/*
10236 	 * Check for valid buffer type
10237 	 */
10238 	if (buffer_type >= MPI2_DIAG_BUF_TYPE_COUNT) {
10239 		*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
10240 		return (DDI_FAILURE);
10241 	}
10242 
10243 	/*
10244 	 * Get the current buffer and look up the unique ID.  The unique ID
10245 	 * should not be found.  If it is, the ID is already in use.
10246 	 */
10247 	i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
10248 	pBuffer = &mpt->m_fw_diag_buffer_list[buffer_type];
10249 	if (i != MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
10250 		*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
10251 		return (DDI_FAILURE);
10252 	}
10253 
10254 	/*
10255 	 * The buffer's unique ID should not be registered yet, and the given
10256 	 * unique ID cannot be 0.
10257 	 */
10258 	if ((pBuffer->unique_id != MPTSAS_FW_DIAG_INVALID_UID) ||
10259 	    (unique_id == MPTSAS_FW_DIAG_INVALID_UID)) {
10260 		*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
10261 		return (DDI_FAILURE);
10262 	}
10263 
10264 	/*
10265 	 * If this buffer is already posted as immediate, just change owner.
10266 	 */
10267 	if (pBuffer->immediate && pBuffer->owned_by_firmware &&
10268 	    (pBuffer->unique_id == MPTSAS_FW_DIAG_INVALID_UID)) {
10269 		pBuffer->immediate = FALSE;
10270 		pBuffer->unique_id = unique_id;
10271 		return (DDI_SUCCESS);
10272 	}
10273 
10274 	/*
10275 	 * Post a new buffer after checking if it's enabled.  The DMA buffer
10276 	 * that is allocated will be contiguous (sgl_len = 1).
10277 	 */
10278 	if (!pBuffer->enabled) {
10279 		*return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER;
10280 		return (DDI_FAILURE);
10281 	}
10282 	bzero(&pBuffer->buffer_data, sizeof (mptsas_dma_alloc_state_t));
10283 	pBuffer->buffer_data.size = buffer_size;
10284 	if (mptsas_dma_alloc(mpt, &pBuffer->buffer_data) != DDI_SUCCESS) {
10285 		mptsas_log(mpt, CE_WARN, "failed to alloc DMA resource for "
10286 		    "diag buffer: size = %d bytes", buffer_size);
10287 		*return_code = MPTSAS_FW_DIAG_ERROR_NO_BUFFER;
10288 		return (DDI_FAILURE);
10289 	}
10290 
10291 	/*
10292 	 * Copy the given info to the diag buffer and post the buffer.
10293 	 */
10294 	pBuffer->buffer_type = buffer_type;
10295 	pBuffer->immediate = FALSE;
10296 	if (buffer_type == MPI2_DIAG_BUF_TYPE_TRACE) {
10297 		for (i = 0; i < (sizeof (pBuffer->product_specific) / 4);
10298 		    i++) {
10299 			pBuffer->product_specific[i] =
10300 			    diag_register->ProductSpecific[i];
10301 		}
10302 	}
10303 	pBuffer->extended_type = extended_type;
10304 	pBuffer->unique_id = unique_id;
10305 	status = mptsas_post_fw_diag_buffer(mpt, pBuffer, return_code);
10306 
10307 	if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) !=
10308 	    DDI_SUCCESS) {
10309 		mptsas_log(mpt, CE_WARN, "Check of DMA handle failed in "
10310 		    "mptsas_diag_register.");
10311 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
10312 			status = DDI_FAILURE;
10313 	}
10314 
10315 	/*
10316 	 * In case there was a failure, free the DMA buffer.
10317 	 */
10318 	if (status == DDI_FAILURE) {
10319 		mptsas_dma_free(&pBuffer->buffer_data);
10320 	}
10321 
10322 	return (status);
10323 }
10324 
10325 static int
10326 mptsas_diag_unregister(mptsas_t *mpt,
10327     mptsas_fw_diag_unregister_t *diag_unregister, uint32_t *return_code)
10328 {
10329 	mptsas_fw_diagnostic_buffer_t	*pBuffer;
10330 	uint8_t				i;
10331 	uint32_t			unique_id;
10332 	int				status;
10333 
10334 	ASSERT(mutex_owned(&mpt->m_mutex));
10335 
10336 	unique_id = diag_unregister->UniqueId;
10337 
10338 	/*
10339 	 * Get the current buffer and look up the unique ID.  The unique ID
10340 	 * should be there.
10341 	 */
10342 	i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
10343 	if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
10344 		*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
10345 		return (DDI_FAILURE);
10346 	}
10347 
10348 	pBuffer = &mpt->m_fw_diag_buffer_list[i];
10349 
10350 	/*
10351 	 * Try to release the buffer from FW before freeing it.  If release
10352 	 * fails, don't free the DMA buffer in case FW tries to access it
10353 	 * later.  If buffer is not owned by firmware, can't release it.
10354 	 */
10355 	if (!pBuffer->owned_by_firmware) {
10356 		status = DDI_SUCCESS;
10357 	} else {
10358 		status = mptsas_release_fw_diag_buffer(mpt, pBuffer,
10359 		    return_code, MPTSAS_FW_DIAG_TYPE_UNREGISTER);
10360 	}
10361 
10362 	/*
10363 	 * At this point, return the current status no matter what happens with
10364 	 * the DMA buffer.
10365 	 */
10366 	pBuffer->unique_id = MPTSAS_FW_DIAG_INVALID_UID;
10367 	if (status == DDI_SUCCESS) {
10368 		if (mptsas_check_dma_handle(pBuffer->buffer_data.handle) !=
10369 		    DDI_SUCCESS) {
10370 			mptsas_log(mpt, CE_WARN, "Check of DMA handle failed "
10371 			    "in mptsas_diag_unregister.");
10372 			ddi_fm_service_impact(mpt->m_dip,
10373 			    DDI_SERVICE_UNAFFECTED);
10374 		}
10375 		mptsas_dma_free(&pBuffer->buffer_data);
10376 	}
10377 
10378 	return (status);
10379 }
10380 
10381 static int
10382 mptsas_diag_query(mptsas_t *mpt, mptsas_fw_diag_query_t *diag_query,
10383     uint32_t *return_code)
10384 {
10385 	mptsas_fw_diagnostic_buffer_t	*pBuffer;
10386 	uint8_t				i;
10387 	uint32_t			unique_id;
10388 
10389 	ASSERT(mutex_owned(&mpt->m_mutex));
10390 
10391 	unique_id = diag_query->UniqueId;
10392 
10393 	/*
10394 	 * If ID is valid, query on ID.
10395 	 * If ID is invalid, query on buffer type.
10396 	 */
10397 	if (unique_id == MPTSAS_FW_DIAG_INVALID_UID) {
10398 		i = diag_query->BufferType;
10399 		if (i >= MPI2_DIAG_BUF_TYPE_COUNT) {
10400 			*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
10401 			return (DDI_FAILURE);
10402 		}
10403 	} else {
10404 		i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
10405 		if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
10406 			*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
10407 			return (DDI_FAILURE);
10408 		}
10409 	}
10410 
10411 	/*
10412 	 * Fill query structure with the diag buffer info.
10413 	 */
10414 	pBuffer = &mpt->m_fw_diag_buffer_list[i];
10415 	diag_query->BufferType = pBuffer->buffer_type;
10416 	diag_query->ExtendedType = pBuffer->extended_type;
10417 	if (diag_query->BufferType == MPI2_DIAG_BUF_TYPE_TRACE) {
10418 		for (i = 0; i < (sizeof (diag_query->ProductSpecific) / 4);
10419 		    i++) {
10420 			diag_query->ProductSpecific[i] =
10421 			    pBuffer->product_specific[i];
10422 		}
10423 	}
10424 	diag_query->TotalBufferSize = pBuffer->buffer_data.size;
10425 	diag_query->DriverAddedBufferSize = 0;
10426 	diag_query->UniqueId = pBuffer->unique_id;
10427 	diag_query->ApplicationFlags = 0;
10428 	diag_query->DiagnosticFlags = 0;
10429 
10430 	/*
10431 	 * Set/Clear application flags
10432 	 */
10433 	if (pBuffer->immediate) {
10434 		diag_query->ApplicationFlags &= ~MPTSAS_FW_DIAG_FLAG_APP_OWNED;
10435 	} else {
10436 		diag_query->ApplicationFlags |= MPTSAS_FW_DIAG_FLAG_APP_OWNED;
10437 	}
10438 	if (pBuffer->valid_data || pBuffer->owned_by_firmware) {
10439 		diag_query->ApplicationFlags |=
10440 		    MPTSAS_FW_DIAG_FLAG_BUFFER_VALID;
10441 	} else {
10442 		diag_query->ApplicationFlags &=
10443 		    ~MPTSAS_FW_DIAG_FLAG_BUFFER_VALID;
10444 	}
10445 	if (pBuffer->owned_by_firmware) {
10446 		diag_query->ApplicationFlags |=
10447 		    MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS;
10448 	} else {
10449 		diag_query->ApplicationFlags &=
10450 		    ~MPTSAS_FW_DIAG_FLAG_FW_BUFFER_ACCESS;
10451 	}
10452 
10453 	return (DDI_SUCCESS);
10454 }
10455 
10456 static int
10457 mptsas_diag_read_buffer(mptsas_t *mpt,
10458     mptsas_diag_read_buffer_t *diag_read_buffer, uint8_t *ioctl_buf,
10459     uint32_t *return_code, int ioctl_mode)
10460 {
10461 	mptsas_fw_diagnostic_buffer_t	*pBuffer;
10462 	uint8_t				i, *pData;
10463 	uint32_t			unique_id, byte;
10464 	int				status;
10465 
10466 	ASSERT(mutex_owned(&mpt->m_mutex));
10467 
10468 	unique_id = diag_read_buffer->UniqueId;
10469 
10470 	/*
10471 	 * Get the current buffer and look up the unique ID.  The unique ID
10472 	 * should be there.
10473 	 */
10474 	i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
10475 	if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
10476 		*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
10477 		return (DDI_FAILURE);
10478 	}
10479 
10480 	pBuffer = &mpt->m_fw_diag_buffer_list[i];
10481 
10482 	/*
10483 	 * Make sure requested read is within limits
10484 	 */
10485 	if (diag_read_buffer->StartingOffset + diag_read_buffer->BytesToRead >
10486 	    pBuffer->buffer_data.size) {
10487 		*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
10488 		return (DDI_FAILURE);
10489 	}
10490 
10491 	/*
10492 	 * Copy the requested data from DMA to the diag_read_buffer.  The DMA
10493 	 * buffer that was allocated is one contiguous buffer.
10494 	 */
10495 	pData = (uint8_t *)(pBuffer->buffer_data.memp +
10496 	    diag_read_buffer->StartingOffset);
10497 	(void) ddi_dma_sync(pBuffer->buffer_data.handle, 0, 0,
10498 	    DDI_DMA_SYNC_FORCPU);
10499 	for (byte = 0; byte < diag_read_buffer->BytesToRead; byte++) {
10500 		if (ddi_copyout(pData + byte, ioctl_buf + byte, 1, ioctl_mode)
10501 		    != 0) {
10502 			return (DDI_FAILURE);
10503 		}
10504 	}
10505 	diag_read_buffer->Status = 0;
10506 
10507 	/*
10508 	 * Set or clear the Force Release flag.
10509 	 */
10510 	if (pBuffer->force_release) {
10511 		diag_read_buffer->Flags |= MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE;
10512 	} else {
10513 		diag_read_buffer->Flags &= ~MPTSAS_FW_DIAG_FLAG_FORCE_RELEASE;
10514 	}
10515 
10516 	/*
10517 	 * If buffer is to be reregistered, make sure it's not already owned by
10518 	 * firmware first.
10519 	 */
10520 	status = DDI_SUCCESS;
10521 	if (!pBuffer->owned_by_firmware) {
10522 		if (diag_read_buffer->Flags & MPTSAS_FW_DIAG_FLAG_REREGISTER) {
10523 			status = mptsas_post_fw_diag_buffer(mpt, pBuffer,
10524 			    return_code);
10525 		}
10526 	}
10527 
10528 	return (status);
10529 }
10530 
10531 static int
10532 mptsas_diag_release(mptsas_t *mpt, mptsas_fw_diag_release_t *diag_release,
10533     uint32_t *return_code)
10534 {
10535 	mptsas_fw_diagnostic_buffer_t	*pBuffer;
10536 	uint8_t				i;
10537 	uint32_t			unique_id;
10538 	int				status;
10539 
10540 	ASSERT(mutex_owned(&mpt->m_mutex));
10541 
10542 	unique_id = diag_release->UniqueId;
10543 
10544 	/*
10545 	 * Get the current buffer and look up the unique ID.  The unique ID
10546 	 * should be there.
10547 	 */
10548 	i = mptsas_get_fw_diag_buffer_number(mpt, unique_id);
10549 	if (i == MPTSAS_FW_DIAGNOSTIC_UID_NOT_FOUND) {
10550 		*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_UID;
10551 		return (DDI_FAILURE);
10552 	}
10553 
10554 	pBuffer = &mpt->m_fw_diag_buffer_list[i];
10555 
10556 	/*
10557 	 * If buffer is not owned by firmware, it's already been released.
10558 	 */
10559 	if (!pBuffer->owned_by_firmware) {
10560 		*return_code = MPTSAS_FW_DIAG_ERROR_ALREADY_RELEASED;
10561 		return (DDI_FAILURE);
10562 	}
10563 
10564 	/*
10565 	 * Release the buffer.
10566 	 */
10567 	status = mptsas_release_fw_diag_buffer(mpt, pBuffer, return_code,
10568 	    MPTSAS_FW_DIAG_TYPE_RELEASE);
10569 	return (status);
10570 }
10571 
10572 static int
10573 mptsas_do_diag_action(mptsas_t *mpt, uint32_t action, uint8_t *diag_action,
10574     uint32_t length, uint32_t *return_code, int ioctl_mode)
10575 {
10576 	mptsas_fw_diag_register_t	diag_register;
10577 	mptsas_fw_diag_unregister_t	diag_unregister;
10578 	mptsas_fw_diag_query_t		diag_query;
10579 	mptsas_diag_read_buffer_t	diag_read_buffer;
10580 	mptsas_fw_diag_release_t	diag_release;
10581 	int				status = DDI_SUCCESS;
10582 	uint32_t			original_return_code, read_buf_len;
10583 
10584 	ASSERT(mutex_owned(&mpt->m_mutex));
10585 
10586 	original_return_code = *return_code;
10587 	*return_code = MPTSAS_FW_DIAG_ERROR_SUCCESS;
10588 
10589 	switch (action) {
10590 		case MPTSAS_FW_DIAG_TYPE_REGISTER:
10591 			if (!length) {
10592 				*return_code =
10593 				    MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
10594 				status = DDI_FAILURE;
10595 				break;
10596 			}
10597 			if (ddi_copyin(diag_action, &diag_register,
10598 			    sizeof (diag_register), ioctl_mode) != 0) {
10599 				return (DDI_FAILURE);
10600 			}
10601 			status = mptsas_diag_register(mpt, &diag_register,
10602 			    return_code);
10603 			break;
10604 
10605 		case MPTSAS_FW_DIAG_TYPE_UNREGISTER:
10606 			if (length < sizeof (diag_unregister)) {
10607 				*return_code =
10608 				    MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
10609 				status = DDI_FAILURE;
10610 				break;
10611 			}
10612 			if (ddi_copyin(diag_action, &diag_unregister,
10613 			    sizeof (diag_unregister), ioctl_mode) != 0) {
10614 				return (DDI_FAILURE);
10615 			}
10616 			status = mptsas_diag_unregister(mpt, &diag_unregister,
10617 			    return_code);
10618 			break;
10619 
10620 		case MPTSAS_FW_DIAG_TYPE_QUERY:
10621 			if (length < sizeof (diag_query)) {
10622 				*return_code =
10623 				    MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
10624 				status = DDI_FAILURE;
10625 				break;
10626 			}
10627 			if (ddi_copyin(diag_action, &diag_query,
10628 			    sizeof (diag_query), ioctl_mode) != 0) {
10629 				return (DDI_FAILURE);
10630 			}
10631 			status = mptsas_diag_query(mpt, &diag_query,
10632 			    return_code);
10633 			if (status == DDI_SUCCESS) {
10634 				if (ddi_copyout(&diag_query, diag_action,
10635 				    sizeof (diag_query), ioctl_mode) != 0) {
10636 					return (DDI_FAILURE);
10637 				}
10638 			}
10639 			break;
10640 
10641 		case MPTSAS_FW_DIAG_TYPE_READ_BUFFER:
10642 			if (ddi_copyin(diag_action, &diag_read_buffer,
10643 			    sizeof (diag_read_buffer) - 4, ioctl_mode) != 0) {
10644 				return (DDI_FAILURE);
10645 			}
10646 			read_buf_len = sizeof (diag_read_buffer) -
10647 			    sizeof (diag_read_buffer.DataBuffer) +
10648 			    diag_read_buffer.BytesToRead;
10649 			if (length < read_buf_len) {
10650 				*return_code =
10651 				    MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
10652 				status = DDI_FAILURE;
10653 				break;
10654 			}
10655 			status = mptsas_diag_read_buffer(mpt,
10656 			    &diag_read_buffer, diag_action +
10657 			    sizeof (diag_read_buffer) - 4, return_code,
10658 			    ioctl_mode);
10659 			if (status == DDI_SUCCESS) {
10660 				if (ddi_copyout(&diag_read_buffer, diag_action,
10661 				    sizeof (diag_read_buffer) - 4, ioctl_mode)
10662 				    != 0) {
10663 					return (DDI_FAILURE);
10664 				}
10665 			}
10666 			break;
10667 
10668 		case MPTSAS_FW_DIAG_TYPE_RELEASE:
10669 			if (length < sizeof (diag_release)) {
10670 				*return_code =
10671 				    MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
10672 				status = DDI_FAILURE;
10673 				break;
10674 			}
10675 			if (ddi_copyin(diag_action, &diag_release,
10676 			    sizeof (diag_release), ioctl_mode) != 0) {
10677 				return (DDI_FAILURE);
10678 			}
10679 			status = mptsas_diag_release(mpt, &diag_release,
10680 			    return_code);
10681 			break;
10682 
10683 		default:
10684 			*return_code = MPTSAS_FW_DIAG_ERROR_INVALID_PARAMETER;
10685 			status = DDI_FAILURE;
10686 			break;
10687 	}
10688 
10689 	if ((status == DDI_FAILURE) &&
10690 	    (original_return_code == MPTSAS_FW_DIAG_NEW) &&
10691 	    (*return_code != MPTSAS_FW_DIAG_ERROR_SUCCESS)) {
10692 		status = DDI_SUCCESS;
10693 	}
10694 
10695 	return (status);
10696 }
10697 
10698 static int
10699 mptsas_diag_action(mptsas_t *mpt, mptsas_diag_action_t *user_data, int mode)
10700 {
10701 	int			status;
10702 	mptsas_diag_action_t	driver_data;
10703 
10704 	ASSERT(mutex_owned(&mpt->m_mutex));
10705 
10706 	/*
10707 	 * Copy the user data to a driver data buffer.
10708 	 */
10709 	if (ddi_copyin(user_data, &driver_data, sizeof (mptsas_diag_action_t),
10710 	    mode) == 0) {
10711 		/*
10712 		 * Send diag action request if Action is valid
10713 		 */
10714 		if (driver_data.Action == MPTSAS_FW_DIAG_TYPE_REGISTER ||
10715 		    driver_data.Action == MPTSAS_FW_DIAG_TYPE_UNREGISTER ||
10716 		    driver_data.Action == MPTSAS_FW_DIAG_TYPE_QUERY ||
10717 		    driver_data.Action == MPTSAS_FW_DIAG_TYPE_READ_BUFFER ||
10718 		    driver_data.Action == MPTSAS_FW_DIAG_TYPE_RELEASE) {
10719 			status = mptsas_do_diag_action(mpt, driver_data.Action,
10720 			    (void *)(uintptr_t)driver_data.PtrDiagAction,
10721 			    driver_data.Length, &driver_data.ReturnCode,
10722 			    mode);
10723 			if (status == DDI_SUCCESS) {
10724 				if (ddi_copyout(&driver_data.ReturnCode,
10725 				    &user_data->ReturnCode,
10726 				    sizeof (user_data->ReturnCode), mode)
10727 				    != 0) {
10728 					status = EFAULT;
10729 				} else {
10730 					status = 0;
10731 				}
10732 			} else {
10733 				status = EIO;
10734 			}
10735 		} else {
10736 			status = EINVAL;
10737 		}
10738 	} else {
10739 		status = EFAULT;
10740 	}
10741 
10742 	return (status);
10743 }
10744 
10745 /*
10746  * This routine handles the "event query" ioctl.
10747  */
10748 static int
10749 mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, int mode,
10750     int *rval)
10751 {
10752 	int			status;
10753 	mptsas_event_query_t	driverdata;
10754 	uint8_t			i;
10755 
10756 	driverdata.Entries = MPTSAS_EVENT_QUEUE_SIZE;
10757 
10758 	mutex_enter(&mpt->m_mutex);
10759 	for (i = 0; i < 4; i++) {
10760 		driverdata.Types[i] = mpt->m_event_mask[i];
10761 	}
10762 	mutex_exit(&mpt->m_mutex);
10763 
10764 	if (ddi_copyout(&driverdata, data, sizeof (driverdata), mode) != 0) {
10765 		status = EFAULT;
10766 	} else {
10767 		*rval = MPTIOCTL_STATUS_GOOD;
10768 		status = 0;
10769 	}
10770 
10771 	return (status);
10772 }
10773 
10774 /*
10775  * This routine handles the "event enable" ioctl.
10776  */
10777 static int
10778 mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, int mode,
10779     int *rval)
10780 {
10781 	int			status;
10782 	mptsas_event_enable_t	driverdata;
10783 	uint8_t			i;
10784 
10785 	if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) {
10786 		mutex_enter(&mpt->m_mutex);
10787 		for (i = 0; i < 4; i++) {
10788 			mpt->m_event_mask[i] = driverdata.Types[i];
10789 		}
10790 		mutex_exit(&mpt->m_mutex);
10791 
10792 		*rval = MPTIOCTL_STATUS_GOOD;
10793 		status = 0;
10794 	} else {
10795 		status = EFAULT;
10796 	}
10797 	return (status);
10798 }
10799 
10800 /*
10801  * This routine handles the "event report" ioctl.
10802  */
10803 static int
10804 mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, int mode,
10805     int *rval)
10806 {
10807 	int			status;
10808 	mptsas_event_report_t	driverdata;
10809 
10810 	mutex_enter(&mpt->m_mutex);
10811 
10812 	if (ddi_copyin(&data->Size, &driverdata.Size, sizeof (driverdata.Size),
10813 	    mode) == 0) {
10814 		if (driverdata.Size >= sizeof (mpt->m_events)) {
10815 			if (ddi_copyout(mpt->m_events, data->Events,
10816 			    sizeof (mpt->m_events), mode) != 0) {
10817 				status = EFAULT;
10818 			} else {
10819 				if (driverdata.Size > sizeof (mpt->m_events)) {
10820 					driverdata.Size =
10821 					    sizeof (mpt->m_events);
10822 					if (ddi_copyout(&driverdata.Size,
10823 					    &data->Size,
10824 					    sizeof (driverdata.Size),
10825 					    mode) != 0) {
10826 						status = EFAULT;
10827 					} else {
10828 						*rval = MPTIOCTL_STATUS_GOOD;
10829 						status = 0;
10830 					}
10831 				} else {
10832 					*rval = MPTIOCTL_STATUS_GOOD;
10833 					status = 0;
10834 				}
10835 			}
10836 		} else {
10837 			*rval = MPTIOCTL_STATUS_LEN_TOO_SHORT;
10838 			status = 0;
10839 		}
10840 	} else {
10841 		status = EFAULT;
10842 	}
10843 
10844 	mutex_exit(&mpt->m_mutex);
10845 	return (status);
10846 }
10847 
10848 static void
10849 mptsas_lookup_pci_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data)
10850 {
10851 	int	*reg_data;
10852 	uint_t	reglen;
10853 
10854 	/*
10855 	 * Lookup the 'reg' property and extract the other data
10856 	 */
10857 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip,
10858 	    DDI_PROP_DONTPASS, "reg", &reg_data, &reglen) ==
10859 	    DDI_PROP_SUCCESS) {
10860 		/*
10861 		 * Extract the PCI data from the 'reg' property first DWORD.
10862 		 * The entry looks like the following:
10863 		 * First DWORD:
10864 		 * Bits 0 - 7 8-bit Register number
10865 		 * Bits 8 - 10 3-bit Function number
10866 		 * Bits 11 - 15 5-bit Device number
10867 		 * Bits 16 - 23 8-bit Bus number
10868 		 * Bits 24 - 25 2-bit Address Space type identifier
10869 		 *
10870 		 * Store the device number in PCIDeviceHwId.
10871 		 * Store the function number in MpiPortNumber.
10872 		 * PciInformation stores bus, device, and function together
10873 		 */
10874 		adapter_data->PCIDeviceHwId = (reg_data[0] & 0x0000F800) >> 11;
10875 		adapter_data->MpiPortNumber = (reg_data[0] & 0x00000700) >> 8;
10876 		adapter_data->PciInformation = (reg_data[0] & 0x00FFFF00) >> 8;
10877 		ddi_prop_free((void *)reg_data);
10878 	} else {
10879 		/*
10880 		 * If we can't determine the PCI data then we fill in FF's for
10881 		 * the data to indicate this.
10882 		 */
10883 		adapter_data->PCIDeviceHwId = 0xFFFFFFFF;
10884 		adapter_data->MpiPortNumber = 0xFFFFFFFF;
10885 		adapter_data->PciInformation = 0xFFFFFFFF;
10886 	}
10887 
10888 	/*
10889 	 * Saved in the mpt->m_fwversion
10890 	 */
10891 	adapter_data->MpiFirmwareVersion = mpt->m_fwversion;
10892 }
10893 
10894 static void
10895 mptsas_read_adapter_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data)
10896 {
10897 	char	*driver_verstr = MPTSAS_MOD_STRING;
10898 
10899 	mptsas_lookup_pci_data(mpt, adapter_data);
10900 	adapter_data->AdapterType = MPTIOCTL_ADAPTER_TYPE_SAS2;
10901 	adapter_data->PCIDeviceHwId = (uint32_t)mpt->m_devid;
10902 	adapter_data->PCIDeviceHwRev = (uint32_t)mpt->m_revid;
10903 	adapter_data->SubSystemId = (uint32_t)mpt->m_ssid;
10904 	adapter_data->SubsystemVendorId = (uint32_t)mpt->m_svid;
10905 	(void) strcpy((char *)&adapter_data->DriverVersion[0], driver_verstr);
10906 	adapter_data->BiosVersion = 0;
10907 	(void) mptsas_get_bios_page3(mpt, &adapter_data->BiosVersion);
10908 }
10909 
10910 static void
10911 mptsas_read_pci_info(mptsas_t *mpt, mptsas_pci_info_t *pci_info)
10912 {
10913 	int	*reg_data, i;
10914 	uint_t	reglen;
10915 
10916 	/*
10917 	 * Lookup the 'reg' property and extract the other data
10918 	 */
10919 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip,
10920 	    DDI_PROP_DONTPASS, "reg", &reg_data, &reglen) ==
10921 	    DDI_PROP_SUCCESS) {
10922 		/*
10923 		 * Extract the PCI data from the 'reg' property first DWORD.
10924 		 * The entry looks like the following:
10925 		 * First DWORD:
10926 		 * Bits 8 - 10 3-bit Function number
10927 		 * Bits 11 - 15 5-bit Device number
10928 		 * Bits 16 - 23 8-bit Bus number
10929 		 */
10930 		pci_info->BusNumber = (reg_data[0] & 0x00FF0000) >> 16;
10931 		pci_info->DeviceNumber = (reg_data[0] & 0x0000F800) >> 11;
10932 		pci_info->FunctionNumber = (reg_data[0] & 0x00000700) >> 8;
10933 		ddi_prop_free((void *)reg_data);
10934 	} else {
10935 		/*
10936 		 * If we can't determine the PCI info then we fill in FF's for
10937 		 * the data to indicate this.
10938 		 */
10939 		pci_info->BusNumber = 0xFFFFFFFF;
10940 		pci_info->DeviceNumber = 0xFF;
10941 		pci_info->FunctionNumber = 0xFF;
10942 	}
10943 
10944 	/*
10945 	 * Now get the interrupt vector and the pci header.  The vector can
10946 	 * only be 0 right now.  The header is the first 256 bytes of config
10947 	 * space.
10948 	 */
10949 	pci_info->InterruptVector = 0;
10950 	for (i = 0; i < sizeof (pci_info->PciHeader); i++) {
10951 		pci_info->PciHeader[i] = pci_config_get8(mpt->m_config_handle,
10952 		    i);
10953 	}
10954 }
10955 
10956 static int
10957 mptsas_reg_access(mptsas_t *mpt, mptsas_reg_access_t *data, int mode)
10958 {
10959 	int			status = 0;
10960 	mptsas_reg_access_t	driverdata;
10961 
10962 	mutex_enter(&mpt->m_mutex);
10963 	if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) {
10964 		switch (driverdata.Command) {
10965 			/*
10966 			 * IO access is not supported.
10967 			 */
10968 			case REG_IO_READ:
10969 			case REG_IO_WRITE:
10970 				mptsas_log(mpt, CE_WARN, "IO access is not "
10971 				    "supported.  Use memory access.");
10972 				status = EINVAL;
10973 				break;
10974 
10975 			case REG_MEM_READ:
10976 				driverdata.RegData = ddi_get32(mpt->m_datap,
10977 				    (uint32_t *)(void *)mpt->m_reg +
10978 				    driverdata.RegOffset);
10979 				if (ddi_copyout(&driverdata.RegData,
10980 				    &data->RegData,
10981 				    sizeof (driverdata.RegData), mode) != 0) {
10982 					mptsas_log(mpt, CE_WARN, "Register "
10983 					    "Read Failed");
10984 					status = EFAULT;
10985 				}
10986 				break;
10987 
10988 			case REG_MEM_WRITE:
10989 				ddi_put32(mpt->m_datap,
10990 				    (uint32_t *)(void *)mpt->m_reg +
10991 				    driverdata.RegOffset,
10992 				    driverdata.RegData);
10993 				break;
10994 
10995 			default:
10996 				status = EINVAL;
10997 				break;
10998 		}
10999 	} else {
11000 		status = EFAULT;
11001 	}
11002 
11003 	mutex_exit(&mpt->m_mutex);
11004 	return (status);
11005 }
11006 
11007 static int
11008 mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp,
11009     int *rval)
11010 {
11011 	int			status = 0;
11012 	mptsas_t		*mpt;
11013 	mptsas_update_flash_t	flashdata;
11014 	mptsas_pass_thru_t	passthru_data;
11015 	mptsas_adapter_data_t   adapter_data;
11016 	mptsas_pci_info_t	pci_info;
11017 	int			copylen;
11018 
11019 	*rval = MPTIOCTL_STATUS_GOOD;
11020 	mpt = ddi_get_soft_state(mptsas_state, MINOR2INST(getminor(dev)));
11021 	if (mpt == NULL) {
11022 		return (scsi_hba_ioctl(dev, cmd, data, mode, credp, rval));
11023 	}
11024 	if (secpolicy_sys_config(credp, B_FALSE) != 0) {
11025 		return (EPERM);
11026 	}
11027 
11028 	/* Make sure power level is D0 before accessing registers */
11029 	mutex_enter(&mpt->m_mutex);
11030 	if (mpt->m_options & MPTSAS_OPT_PM) {
11031 		(void) pm_busy_component(mpt->m_dip, 0);
11032 		if (mpt->m_power_level != PM_LEVEL_D0) {
11033 			mutex_exit(&mpt->m_mutex);
11034 			if (pm_raise_power(mpt->m_dip, 0, PM_LEVEL_D0) !=
11035 			    DDI_SUCCESS) {
11036 				mptsas_log(mpt, CE_WARN,
11037 				    "mptsas%d: mptsas_ioctl: Raise power "
11038 				    "request failed.", mpt->m_instance);
11039 				(void) pm_idle_component(mpt->m_dip, 0);
11040 				return (ENXIO);
11041 			}
11042 		} else {
11043 			mutex_exit(&mpt->m_mutex);
11044 		}
11045 	} else {
11046 		mutex_exit(&mpt->m_mutex);
11047 	}
11048 
11049 	switch (cmd) {
11050 		case MPTIOCTL_UPDATE_FLASH:
11051 			if (ddi_copyin((void *)data, &flashdata,
11052 				sizeof (struct mptsas_update_flash), mode)) {
11053 				status = EFAULT;
11054 				break;
11055 			}
11056 
11057 			mutex_enter(&mpt->m_mutex);
11058 			if (mptsas_update_flash(mpt,
11059 			    (caddr_t)(long)flashdata.PtrBuffer,
11060 			    flashdata.ImageSize, flashdata.ImageType, mode)) {
11061 				status = EFAULT;
11062 			}
11063 
11064 			/*
11065 			 * Reset the chip to start using the new
11066 			 * firmware.  Reset if failed also.
11067 			 */
11068 			if (mptsas_restart_ioc(mpt) == DDI_FAILURE) {
11069 				status = EFAULT;
11070 			}
11071 			mutex_exit(&mpt->m_mutex);
11072 			break;
11073 		case MPTIOCTL_PASS_THRU:
11074 			/*
11075 			 * The user has requested to pass through a command to
11076 			 * be executed by the MPT firmware.  Call our routine
11077 			 * which does this.  Only allow one passthru IOCTL at
11078 			 * one time.
11079 			 */
11080 			if (ddi_copyin((void *)data, &passthru_data,
11081 			    sizeof (mptsas_pass_thru_t), mode)) {
11082 				status = EFAULT;
11083 				break;
11084 			}
11085 			mutex_enter(&mpt->m_mutex);
11086 			if (mpt->m_passthru_in_progress) {
11087 				mutex_exit(&mpt->m_mutex);
11088 				return (EBUSY);
11089 			}
11090 			mpt->m_passthru_in_progress = 1;
11091 			status = mptsas_pass_thru(mpt, &passthru_data, mode);
11092 			mpt->m_passthru_in_progress = 0;
11093 			mutex_exit(&mpt->m_mutex);
11094 
11095 			break;
11096 		case MPTIOCTL_GET_ADAPTER_DATA:
11097 			/*
11098 			 * The user has requested to read adapter data.  Call
11099 			 * our routine which does this.
11100 			 */
11101 			bzero(&adapter_data, sizeof (mptsas_adapter_data_t));
11102 			if (ddi_copyin((void *)data, (void *)&adapter_data,
11103 			    sizeof (mptsas_adapter_data_t), mode)) {
11104 				status = EFAULT;
11105 				break;
11106 			}
11107 			if (adapter_data.StructureLength >=
11108 			    sizeof (mptsas_adapter_data_t)) {
11109 				adapter_data.StructureLength = (uint32_t)
11110 				    sizeof (mptsas_adapter_data_t);
11111 				copylen = sizeof (mptsas_adapter_data_t);
11112 				mutex_enter(&mpt->m_mutex);
11113 				mptsas_read_adapter_data(mpt, &adapter_data);
11114 				mutex_exit(&mpt->m_mutex);
11115 			} else {
11116 				adapter_data.StructureLength = (uint32_t)
11117 				    sizeof (mptsas_adapter_data_t);
11118 				copylen = sizeof (adapter_data.StructureLength);
11119 				*rval = MPTIOCTL_STATUS_LEN_TOO_SHORT;
11120 			}
11121 			if (ddi_copyout((void *)(&adapter_data), (void *)data,
11122 			    copylen, mode) != 0) {
11123 				status = EFAULT;
11124 			}
11125 			break;
11126 		case MPTIOCTL_GET_PCI_INFO:
11127 			/*
11128 			 * The user has requested to read pci info.  Call
11129 			 * our routine which does this.
11130 			 */
11131 			bzero(&pci_info, sizeof (mptsas_pci_info_t));
11132 			mutex_enter(&mpt->m_mutex);
11133 			mptsas_read_pci_info(mpt, &pci_info);
11134 			mutex_exit(&mpt->m_mutex);
11135 			if (ddi_copyout((void *)(&pci_info), (void *)data,
11136 			    sizeof (mptsas_pci_info_t), mode) != 0) {
11137 				status = EFAULT;
11138 			}
11139 			break;
11140 		case MPTIOCTL_RESET_ADAPTER:
11141 			mutex_enter(&mpt->m_mutex);
11142 			if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
11143 				mptsas_log(mpt, CE_WARN, "reset adapter IOCTL "
11144 				    "failed");
11145 				status = EFAULT;
11146 			}
11147 			mutex_exit(&mpt->m_mutex);
11148 			break;
11149 		case MPTIOCTL_DIAG_ACTION:
11150 			/*
11151 			 * The user has done a diag buffer action.  Call our
11152 			 * routine which does this.  Only allow one diag action
11153 			 * at one time.
11154 			 */
11155 			mutex_enter(&mpt->m_mutex);
11156 			if (mpt->m_diag_action_in_progress) {
11157 				mutex_exit(&mpt->m_mutex);
11158 				return (EBUSY);
11159 			}
11160 			mpt->m_diag_action_in_progress = 1;
11161 			status = mptsas_diag_action(mpt,
11162 			    (mptsas_diag_action_t *)data, mode);
11163 			mpt->m_diag_action_in_progress = 0;
11164 			mutex_exit(&mpt->m_mutex);
11165 			break;
11166 		case MPTIOCTL_EVENT_QUERY:
11167 			/*
11168 			 * The user has done an event query. Call our routine
11169 			 * which does this.
11170 			 */
11171 			status = mptsas_event_query(mpt,
11172 			    (mptsas_event_query_t *)data, mode, rval);
11173 			break;
11174 		case MPTIOCTL_EVENT_ENABLE:
11175 			/*
11176 			 * The user has done an event enable. Call our routine
11177 			 * which does this.
11178 			 */
11179 			status = mptsas_event_enable(mpt,
11180 			    (mptsas_event_enable_t *)data, mode, rval);
11181 			break;
11182 		case MPTIOCTL_EVENT_REPORT:
11183 			/*
11184 			 * The user has done an event report. Call our routine
11185 			 * which does this.
11186 			 */
11187 			status = mptsas_event_report(mpt,
11188 			    (mptsas_event_report_t *)data, mode, rval);
11189 			break;
11190 		case MPTIOCTL_REG_ACCESS:
11191 			/*
11192 			 * The user has requested register access.  Call our
11193 			 * routine which does this.
11194 			 */
11195 			status = mptsas_reg_access(mpt,
11196 			    (mptsas_reg_access_t *)data, mode);
11197 			break;
11198 		default:
11199 			status = scsi_hba_ioctl(dev, cmd, data, mode, credp,
11200 			    rval);
11201 			break;
11202 	}
11203 
11204 	/*
11205 	 * Report idle status to pm after grace period because
11206 	 * multiple ioctls may be queued and raising power
11207 	 * for every ioctl is time consuming.  If a timeout is
11208 	 * pending for the previous ioctl, cancel the timeout and
11209 	 * report idle status to pm because calls to pm_busy_component(9F)
11210 	 * are stacked.
11211 	 */
11212 	mutex_enter(&mpt->m_mutex);
11213 	if (mpt->m_options & MPTSAS_OPT_PM) {
11214 		if (mpt->m_pm_timeid != 0) {
11215 			timeout_id_t tid = mpt->m_pm_timeid;
11216 			mpt->m_pm_timeid = 0;
11217 			mutex_exit(&mpt->m_mutex);
11218 			(void) untimeout(tid);
11219 			/*
11220 			 * Report idle status for previous ioctl since
11221 			 * calls to pm_busy_component(9F) are stacked.
11222 			 */
11223 			(void) pm_idle_component(mpt->m_dip, 0);
11224 			mutex_enter(&mpt->m_mutex);
11225 		}
11226 		mpt->m_pm_timeid = timeout(mptsas_idle_pm, mpt,
11227 		    drv_usectohz((clock_t)mpt->m_pm_idle_delay * 1000000));
11228 	}
11229 	mutex_exit(&mpt->m_mutex);
11230 
11231 	return (status);
11232 }
11233 
11234 int
11235 mptsas_restart_ioc(mptsas_t *mpt)
11236 {
11237 	int		rval = DDI_SUCCESS;
11238 	mptsas_target_t	*ptgt = NULL;
11239 
11240 	ASSERT(mutex_owned(&mpt->m_mutex));
11241 
11242 	/*
11243 	 * Set all throttles to HOLD
11244 	 */
11245 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11246 	    MPTSAS_HASH_FIRST);
11247 	while (ptgt != NULL) {
11248 		mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
11249 
11250 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11251 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
11252 	}
11253 
11254 	/*
11255 	 * Disable interrupts
11256 	 */
11257 	MPTSAS_DISABLE_INTR(mpt);
11258 
11259 	/*
11260 	 * Abort all commands: outstanding commands, commands in waitq and
11261 	 * tx_waitq.
11262 	 */
11263 	mptsas_flush_hba(mpt);
11264 
11265 	/*
11266 	 * Reinitialize the chip.
11267 	 */
11268 	if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) {
11269 		rval = DDI_FAILURE;
11270 	}
11271 
11272 	/*
11273 	 * Enable interrupts again
11274 	 */
11275 	MPTSAS_ENABLE_INTR(mpt);
11276 
11277 	/*
11278 	 * If mptsas_init_chip was successful, update the driver data.
11279 	 */
11280 	if (rval == DDI_SUCCESS) {
11281 		mptsas_update_driver_data(mpt);
11282 	}
11283 
11284 	/*
11285 	 * Reset the throttles
11286 	 */
11287 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11288 	    MPTSAS_HASH_FIRST);
11289 	while (ptgt != NULL) {
11290 		mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
11291 
11292 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11293 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
11294 	}
11295 
11296 	mptsas_doneq_empty(mpt);
11297 	mptsas_restart_hba(mpt);
11298 
11299 	if (rval != DDI_SUCCESS) {
11300 		mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
11301 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
11302 	}
11303 	return (rval);
11304 }
11305 
11306 int
11307 mptsas_init_chip(mptsas_t *mpt, int first_time)
11308 {
11309 	ddi_dma_cookie_t	cookie;
11310 	uint32_t		i;
11311 	mptsas_slots_t		*new_active;
11312 
11313 	/*
11314 	 * Check to see if the firmware image is valid
11315 	 */
11316 	if (ddi_get32(mpt->m_datap, &mpt->m_reg->HostDiagnostic) &
11317 	    MPI2_DIAG_FLASH_BAD_SIG) {
11318 		mptsas_log(mpt, CE_WARN, "mptsas bad flash signature!");
11319 		goto fail;
11320 	}
11321 
11322 	/*
11323 	 * Reset the chip
11324 	 */
11325 	if (mptsas_ioc_reset(mpt) == MPTSAS_RESET_FAIL) {
11326 		mptsas_log(mpt, CE_WARN, "hard reset failed!");
11327 		goto fail;
11328 	}
11329 
11330 	if (first_time == FALSE) {
11331 		/*
11332 		 * De-allocate buffers before re-allocating them using the
11333 		 * latest IOC facts.
11334 		 */
11335 		mptsas_hba_fini(mpt);
11336 
11337 		/*
11338 		 * Setup configuration space
11339 		 */
11340 		if (mptsas_config_space_init(mpt) == FALSE) {
11341 			mptsas_log(mpt, CE_WARN, "mptsas_config_space_init "
11342 			    "failed!");
11343 			goto fail;
11344 		}
11345 	}
11346 
11347 	/*
11348 	 * IOC facts can change after a diag reset so all buffers that are
11349 	 * based on these numbers must be de-allocated and re-allocated.  Get
11350 	 * new IOC facts each time chip is initialized.
11351 	 */
11352 	if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) {
11353 		mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts failed");
11354 		goto fail;
11355 	}
11356 	/*
11357 	 * Re-allocate active slots here if not the first reset.  Since
11358 	 * m_active could have a different number of slots allocated after a
11359 	 * reset, just de-allocate the old m_active structure and re-allocate a
11360 	 * new one.  Save the tables and IR info from the old m_active.
11361 	 */
11362 	if (first_time == FALSE) {
11363 		new_active = kmem_zalloc(MPTSAS_SLOTS_SIZE(mpt), KM_SLEEP);
11364 		if (new_active == NULL) {
11365 			mptsas_log(mpt, CE_WARN, "Re-alloc of active slots "
11366 			    "failed!");
11367 			goto fail;
11368 		} else {
11369 			new_active->m_n_slots = (mpt->m_max_requests - 2);
11370 			new_active->m_size = MPTSAS_SLOTS_SIZE(mpt);
11371 			new_active->m_tags = 1;
11372 			new_active->m_tgttbl = mpt->m_active->m_tgttbl;
11373 			new_active->m_smptbl = mpt->m_active->m_smptbl;
11374 			new_active->m_num_raid_configs =
11375 			    mpt->m_active->m_num_raid_configs;
11376 			for (i = 0; i < new_active->m_num_raid_configs; i++) {
11377 				new_active->m_raidconfig[i] =
11378 				    mpt->m_active->m_raidconfig[i];
11379 			}
11380 			kmem_free(mpt->m_active, mpt->m_active->m_size);
11381 			mpt->m_active = new_active;
11382 		}
11383 	}
11384 
11385 	/*
11386 	 * Allocate request message frames, reply free queue, reply descriptor
11387 	 * post queue, and reply message frames using latest IOC facts.
11388 	 */
11389 	if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) {
11390 		mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames failed");
11391 		goto fail;
11392 	}
11393 	if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) {
11394 		mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue failed!");
11395 		goto fail;
11396 	}
11397 	if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) {
11398 		mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue failed!");
11399 		goto fail;
11400 	}
11401 	if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) {
11402 		mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames failed!");
11403 		goto fail;
11404 	}
11405 
11406 	/*
11407 	 * Re-Initialize ioc to operational state
11408 	 */
11409 	if (mptsas_ioc_init(mpt) == DDI_FAILURE) {
11410 		mptsas_log(mpt, CE_WARN, "mptsas_ioc_init failed");
11411 		goto fail;
11412 	}
11413 
11414 	mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) *
11415 	    mpt->m_max_replies, KM_SLEEP);
11416 
11417 	/*
11418 	 * Initialize reply post index.  Reply free index is initialized after
11419 	 * the next loop.
11420 	 */
11421 	mpt->m_post_index = 0;
11422 
11423 	/*
11424 	 * Initialize the Reply Free Queue with the physical addresses of our
11425 	 * reply frames.
11426 	 */
11427 	cookie.dmac_address = mpt->m_reply_frame_dma_addr;
11428 	for (i = 0; i < mpt->m_free_queue_depth - 1; i++) {
11429 		ddi_put32(mpt->m_acc_free_queue_hdl,
11430 		    &((uint32_t *)(void *)mpt->m_free_queue)[i],
11431 		    cookie.dmac_address);
11432 		cookie.dmac_address += mpt->m_reply_frame_size;
11433 	}
11434 	(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
11435 	    DDI_DMA_SYNC_FORDEV);
11436 
11437 	/*
11438 	 * Initialize the reply free index to one past the last frame on the
11439 	 * queue.  This will signify that the queue is empty to start with.
11440 	 */
11441 	mpt->m_free_index = i;
11442 	ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, i);
11443 
11444 	/*
11445 	 * Initialize the reply post queue to 0xFFFFFFFF,0xFFFFFFFF's.
11446 	 */
11447 	for (i = 0; i < mpt->m_post_queue_depth; i++) {
11448 		ddi_put64(mpt->m_acc_post_queue_hdl,
11449 		    &((uint64_t *)(void *)mpt->m_post_queue)[i],
11450 		    0xFFFFFFFFFFFFFFFF);
11451 	}
11452 	(void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
11453 	    DDI_DMA_SYNC_FORDEV);
11454 
11455 	/*
11456 	 * Enable ports
11457 	 */
11458 	if (mptsas_ioc_enable_port(mpt) == DDI_FAILURE) {
11459 		mptsas_log(mpt, CE_WARN, "mptsas_ioc_enable_port failed");
11460 		goto fail;
11461 	}
11462 
11463 	/*
11464 	 * First, make sure the HBA is set in "initiator" mode.  Once that
11465 	 * is complete, get the base WWID.
11466 	 */
11467 
11468 	if (first_time == TRUE) {
11469 		if (mptsas_set_initiator_mode(mpt)) {
11470 			mptsas_log(mpt, CE_WARN, "mptsas_set_initiator_mode "
11471 			    "failed!");
11472 			goto fail;
11473 		}
11474 
11475 		if (mptsas_get_manufacture_page5(mpt) == DDI_FAILURE) {
11476 			mptsas_log(mpt, CE_WARN,
11477 			    "mptsas_get_manufacture_page5 failed!");
11478 			goto fail;
11479 		}
11480 	}
11481 
11482 	/*
11483 	 * enable events
11484 	 */
11485 	if (first_time == FALSE) {
11486 		if (mptsas_ioc_enable_event_notification(mpt)) {
11487 			goto fail;
11488 		}
11489 	}
11490 
11491 	/*
11492 	 * We need checks in attach and these.
11493 	 * chip_init is called in mult. places
11494 	 */
11495 
11496 	if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
11497 	    DDI_SUCCESS) ||
11498 	    (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) !=
11499 	    DDI_SUCCESS) ||
11500 	    (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) !=
11501 	    DDI_SUCCESS) ||
11502 	    (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) !=
11503 	    DDI_SUCCESS) ||
11504 	    (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) !=
11505 	    DDI_SUCCESS)) {
11506 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
11507 		goto fail;
11508 	}
11509 
11510 	/* Check all acc handles */
11511 	if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) ||
11512 	    (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
11513 	    DDI_SUCCESS) ||
11514 	    (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) !=
11515 	    DDI_SUCCESS) ||
11516 	    (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) !=
11517 	    DDI_SUCCESS) ||
11518 	    (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) !=
11519 	    DDI_SUCCESS) ||
11520 	    (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) !=
11521 	    DDI_SUCCESS) ||
11522 	    (mptsas_check_acc_handle(mpt->m_config_handle) !=
11523 	    DDI_SUCCESS)) {
11524 		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
11525 		goto fail;
11526 	}
11527 
11528 	return (DDI_SUCCESS);
11529 
11530 fail:
11531 	return (DDI_FAILURE);
11532 }
11533 
11534 static int
11535 mptsas_init_pm(mptsas_t *mpt)
11536 {
11537 	char		pmc_name[16];
11538 	char		*pmc[] = {
11539 				NULL,
11540 				"0=Off (PCI D3 State)",
11541 				"3=On (PCI D0 State)",
11542 				NULL
11543 			};
11544 	uint16_t	pmcsr_stat;
11545 
11546 	/*
11547 	 * If power management is supported by this chip, create
11548 	 * pm-components property for the power management framework
11549 	 */
11550 	(void) sprintf(pmc_name, "NAME=mptsas%d", mpt->m_instance);
11551 	pmc[0] = pmc_name;
11552 	if (ddi_prop_update_string_array(DDI_DEV_T_NONE, mpt->m_dip,
11553 	    "pm-components", pmc, 3) != DDI_PROP_SUCCESS) {
11554 		mpt->m_options &= ~MPTSAS_OPT_PM;
11555 		mptsas_log(mpt, CE_WARN,
11556 		    "mptsas%d: pm-component property creation failed.",
11557 		    mpt->m_instance);
11558 		return (DDI_FAILURE);
11559 	}
11560 
11561 	/*
11562 	 * Power on device.
11563 	 */
11564 	(void) pm_busy_component(mpt->m_dip, 0);
11565 	pmcsr_stat = pci_config_get16(mpt->m_config_handle,
11566 	    mpt->m_pmcsr_offset);
11567 	if ((pmcsr_stat & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_D0) {
11568 		mptsas_log(mpt, CE_WARN, "mptsas%d: Power up the device",
11569 		    mpt->m_instance);
11570 		pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset,
11571 		    PCI_PMCSR_D0);
11572 	}
11573 	if (pm_power_has_changed(mpt->m_dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) {
11574 		mptsas_log(mpt, CE_WARN, "pm_power_has_changed failed");
11575 		return (DDI_FAILURE);
11576 	}
11577 	mpt->m_power_level = PM_LEVEL_D0;
11578 	/*
11579 	 * Set pm idle delay.
11580 	 */
11581 	mpt->m_pm_idle_delay = ddi_prop_get_int(DDI_DEV_T_ANY,
11582 	    mpt->m_dip, 0, "mptsas-pm-idle-delay", MPTSAS_PM_IDLE_TIMEOUT);
11583 
11584 	return (DDI_SUCCESS);
11585 }
11586 
11587 /*
11588  * mptsas_add_intrs:
11589  *
11590  * Register FIXED or MSI interrupts.
11591  */
11592 static int
11593 mptsas_add_intrs(mptsas_t *mpt, int intr_type)
11594 {
11595 	dev_info_t	*dip = mpt->m_dip;
11596 	int		avail, actual, count = 0;
11597 	int		i, flag, ret;
11598 
11599 	NDBG6(("mptsas_add_intrs:interrupt type 0x%x", intr_type));
11600 
11601 	/* Get number of interrupts */
11602 	ret = ddi_intr_get_nintrs(dip, intr_type, &count);
11603 	if ((ret != DDI_SUCCESS) || (count <= 0)) {
11604 		mptsas_log(mpt, CE_WARN, "ddi_intr_get_nintrs() failed, "
11605 		    "ret %d count %d\n", ret, count);
11606 
11607 		return (DDI_FAILURE);
11608 	}
11609 
11610 	/* Get number of available interrupts */
11611 	ret = ddi_intr_get_navail(dip, intr_type, &avail);
11612 	if ((ret != DDI_SUCCESS) || (avail == 0)) {
11613 		mptsas_log(mpt, CE_WARN, "ddi_intr_get_navail() failed, "
11614 		    "ret %d avail %d\n", ret, avail);
11615 
11616 		return (DDI_FAILURE);
11617 	}
11618 
11619 	if (avail < count) {
11620 		mptsas_log(mpt, CE_NOTE, "ddi_intr_get_nvail returned %d, "
11621 		    "navail() returned %d", count, avail);
11622 	}
11623 
11624 	/* Mpt only have one interrupt routine */
11625 	if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) {
11626 		count = 1;
11627 	}
11628 
11629 	/* Allocate an array of interrupt handles */
11630 	mpt->m_intr_size = count * sizeof (ddi_intr_handle_t);
11631 	mpt->m_htable = kmem_alloc(mpt->m_intr_size, KM_SLEEP);
11632 
11633 	flag = DDI_INTR_ALLOC_NORMAL;
11634 
11635 	/* call ddi_intr_alloc() */
11636 	ret = ddi_intr_alloc(dip, mpt->m_htable, intr_type, 0,
11637 	    count, &actual, flag);
11638 
11639 	if ((ret != DDI_SUCCESS) || (actual == 0)) {
11640 		mptsas_log(mpt, CE_WARN, "ddi_intr_alloc() failed, ret %d\n",
11641 		    ret);
11642 		kmem_free(mpt->m_htable, mpt->m_intr_size);
11643 		return (DDI_FAILURE);
11644 	}
11645 
11646 	/* use interrupt count returned or abort? */
11647 	if (actual < count) {
11648 		mptsas_log(mpt, CE_NOTE, "Requested: %d, Received: %d\n",
11649 		    count, actual);
11650 	}
11651 
11652 	mpt->m_intr_cnt = actual;
11653 
11654 	/*
11655 	 * Get priority for first msi, assume remaining are all the same
11656 	 */
11657 	if ((ret = ddi_intr_get_pri(mpt->m_htable[0],
11658 	    &mpt->m_intr_pri)) != DDI_SUCCESS) {
11659 		mptsas_log(mpt, CE_WARN, "ddi_intr_get_pri() failed %d\n", ret);
11660 
11661 		/* Free already allocated intr */
11662 		for (i = 0; i < actual; i++) {
11663 			(void) ddi_intr_free(mpt->m_htable[i]);
11664 		}
11665 
11666 		kmem_free(mpt->m_htable, mpt->m_intr_size);
11667 		return (DDI_FAILURE);
11668 	}
11669 
11670 	/* Test for high level mutex */
11671 	if (mpt->m_intr_pri >= ddi_intr_get_hilevel_pri()) {
11672 		mptsas_log(mpt, CE_WARN, "mptsas_add_intrs: "
11673 		    "Hi level interrupt not supported\n");
11674 
11675 		/* Free already allocated intr */
11676 		for (i = 0; i < actual; i++) {
11677 			(void) ddi_intr_free(mpt->m_htable[i]);
11678 		}
11679 
11680 		kmem_free(mpt->m_htable, mpt->m_intr_size);
11681 		return (DDI_FAILURE);
11682 	}
11683 
11684 	/* Call ddi_intr_add_handler() */
11685 	for (i = 0; i < actual; i++) {
11686 		if ((ret = ddi_intr_add_handler(mpt->m_htable[i], mptsas_intr,
11687 		    (caddr_t)mpt, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) {
11688 			mptsas_log(mpt, CE_WARN, "ddi_intr_add_handler() "
11689 			    "failed %d\n", ret);
11690 
11691 			/* Free already allocated intr */
11692 			for (i = 0; i < actual; i++) {
11693 				(void) ddi_intr_free(mpt->m_htable[i]);
11694 			}
11695 
11696 			kmem_free(mpt->m_htable, mpt->m_intr_size);
11697 			return (DDI_FAILURE);
11698 		}
11699 	}
11700 
11701 	if ((ret = ddi_intr_get_cap(mpt->m_htable[0], &mpt->m_intr_cap))
11702 	    != DDI_SUCCESS) {
11703 		mptsas_log(mpt, CE_WARN, "ddi_intr_get_cap() failed %d\n", ret);
11704 
11705 		/* Free already allocated intr */
11706 		for (i = 0; i < actual; i++) {
11707 			(void) ddi_intr_free(mpt->m_htable[i]);
11708 		}
11709 
11710 		kmem_free(mpt->m_htable, mpt->m_intr_size);
11711 		return (DDI_FAILURE);
11712 	}
11713 
11714 	return (DDI_SUCCESS);
11715 }
11716 
11717 /*
11718  * mptsas_rem_intrs:
11719  *
11720  * Unregister FIXED or MSI interrupts
11721  */
11722 static void
11723 mptsas_rem_intrs(mptsas_t *mpt)
11724 {
11725 	int	i;
11726 
11727 	NDBG6(("mptsas_rem_intrs"));
11728 
11729 	/* Disable all interrupts */
11730 	if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) {
11731 		/* Call ddi_intr_block_disable() */
11732 		(void) ddi_intr_block_disable(mpt->m_htable, mpt->m_intr_cnt);
11733 	} else {
11734 		for (i = 0; i < mpt->m_intr_cnt; i++) {
11735 			(void) ddi_intr_disable(mpt->m_htable[i]);
11736 		}
11737 	}
11738 
11739 	/* Call ddi_intr_remove_handler() */
11740 	for (i = 0; i < mpt->m_intr_cnt; i++) {
11741 		(void) ddi_intr_remove_handler(mpt->m_htable[i]);
11742 		(void) ddi_intr_free(mpt->m_htable[i]);
11743 	}
11744 
11745 	kmem_free(mpt->m_htable, mpt->m_intr_size);
11746 }
11747 
11748 /*
11749  * The IO fault service error handling callback function
11750  */
11751 /*ARGSUSED*/
11752 static int
11753 mptsas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
11754 {
11755 	/*
11756 	 * as the driver can always deal with an error in any dma or
11757 	 * access handle, we can just return the fme_status value.
11758 	 */
11759 	pci_ereport_post(dip, err, NULL);
11760 	return (err->fme_status);
11761 }
11762 
11763 /*
11764  * mptsas_fm_init - initialize fma capabilities and register with IO
11765  *               fault services.
11766  */
11767 static void
11768 mptsas_fm_init(mptsas_t *mpt)
11769 {
11770 	/*
11771 	 * Need to change iblock to priority for new MSI intr
11772 	 */
11773 	ddi_iblock_cookie_t	fm_ibc;
11774 
11775 	/* Only register with IO Fault Services if we have some capability */
11776 	if (mpt->m_fm_capabilities) {
11777 		/* Adjust access and dma attributes for FMA */
11778 		mpt->m_reg_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC;
11779 		mpt->m_msg_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
11780 		mpt->m_io_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
11781 
11782 		/*
11783 		 * Register capabilities with IO Fault Services.
11784 		 * mpt->m_fm_capabilities will be updated to indicate
11785 		 * capabilities actually supported (not requested.)
11786 		 */
11787 		ddi_fm_init(mpt->m_dip, &mpt->m_fm_capabilities, &fm_ibc);
11788 
11789 		/*
11790 		 * Initialize pci ereport capabilities if ereport
11791 		 * capable (should always be.)
11792 		 */
11793 		if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) ||
11794 		    DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
11795 			pci_ereport_setup(mpt->m_dip);
11796 		}
11797 
11798 		/*
11799 		 * Register error callback if error callback capable.
11800 		 */
11801 		if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
11802 			ddi_fm_handler_register(mpt->m_dip,
11803 			    mptsas_fm_error_cb, (void *) mpt);
11804 		}
11805 	}
11806 }
11807 
11808 /*
11809  * mptsas_fm_fini - Releases fma capabilities and un-registers with IO
11810  *               fault services.
11811  *
11812  */
11813 static void
11814 mptsas_fm_fini(mptsas_t *mpt)
11815 {
11816 	/* Only unregister FMA capabilities if registered */
11817 	if (mpt->m_fm_capabilities) {
11818 
11819 		/*
11820 		 * Un-register error callback if error callback capable.
11821 		 */
11822 
11823 		if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
11824 			ddi_fm_handler_unregister(mpt->m_dip);
11825 		}
11826 
11827 		/*
11828 		 * Release any resources allocated by pci_ereport_setup()
11829 		 */
11830 
11831 		if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) ||
11832 		    DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
11833 			pci_ereport_teardown(mpt->m_dip);
11834 		}
11835 
11836 		/* Unregister from IO Fault Services */
11837 		ddi_fm_fini(mpt->m_dip);
11838 
11839 		/* Adjust access and dma attributes for FMA */
11840 		mpt->m_reg_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC;
11841 		mpt->m_msg_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
11842 		mpt->m_io_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
11843 
11844 	}
11845 }
11846 
11847 int
11848 mptsas_check_acc_handle(ddi_acc_handle_t handle)
11849 {
11850 	ddi_fm_error_t	de;
11851 
11852 	if (handle == NULL)
11853 		return (DDI_FAILURE);
11854 	ddi_fm_acc_err_get(handle, &de, DDI_FME_VER0);
11855 	return (de.fme_status);
11856 }
11857 
11858 int
11859 mptsas_check_dma_handle(ddi_dma_handle_t handle)
11860 {
11861 	ddi_fm_error_t	de;
11862 
11863 	if (handle == NULL)
11864 		return (DDI_FAILURE);
11865 	ddi_fm_dma_err_get(handle, &de, DDI_FME_VER0);
11866 	return (de.fme_status);
11867 }
11868 
11869 void
11870 mptsas_fm_ereport(mptsas_t *mpt, char *detail)
11871 {
11872 	uint64_t	ena;
11873 	char		buf[FM_MAX_CLASS];
11874 
11875 	(void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
11876 	ena = fm_ena_generate(0, FM_ENA_FMT1);
11877 	if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities)) {
11878 		ddi_fm_ereport_post(mpt->m_dip, buf, ena, DDI_NOSLEEP,
11879 		    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL);
11880 	}
11881 }
11882 
11883 static int
11884 mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
11885     uint16_t *dev_handle, mptsas_target_t **pptgt)
11886 {
11887 	int		rval;
11888 	uint32_t	dev_info;
11889 	uint64_t	sas_wwn;
11890 	uint8_t		physport, phymask;
11891 	uint8_t		phynum, config, disk;
11892 	mptsas_slots_t	*slots = mpt->m_active;
11893 	uint64_t		devicename;
11894 	mptsas_target_t		*tmp_tgt = NULL;
11895 
11896 	ASSERT(*pptgt == NULL);
11897 
11898 	rval = mptsas_get_sas_device_page0(mpt, page_address, dev_handle,
11899 	    &sas_wwn, &dev_info, &physport, &phynum);
11900 	if (rval != DDI_SUCCESS) {
11901 		rval = DEV_INFO_FAIL_PAGE0;
11902 		return (rval);
11903 	}
11904 
11905 	if ((dev_info & (MPI2_SAS_DEVICE_INFO_SSP_TARGET |
11906 	    MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
11907 	    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) == NULL) {
11908 		rval = DEV_INFO_WRONG_DEVICE_TYPE;
11909 		return (rval);
11910 	}
11911 
11912 	/*
11913 	 * Get SATA Device Name from SAS device page0 for
11914 	 * sata device, if device name doesn't exist, set m_sas_wwn to
11915 	 * 0 for direct attached SATA. For the device behind the expander
11916 	 * we still can use STP address assigned by expander.
11917 	 */
11918 	if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
11919 	    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
11920 		mutex_exit(&mpt->m_mutex);
11921 		/* alloc a tmp_tgt to send the cmd */
11922 		tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target),
11923 		    KM_SLEEP);
11924 		tmp_tgt->m_devhdl = *dev_handle;
11925 		tmp_tgt->m_deviceinfo = dev_info;
11926 		tmp_tgt->m_qfull_retries = QFULL_RETRIES;
11927 		tmp_tgt->m_qfull_retry_interval =
11928 		    drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
11929 		tmp_tgt->m_t_throttle = MAX_THROTTLE;
11930 		devicename = mptsas_get_sata_guid(mpt, tmp_tgt, 0);
11931 		kmem_free(tmp_tgt, sizeof (struct mptsas_target));
11932 		mutex_enter(&mpt->m_mutex);
11933 		if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) {
11934 			sas_wwn = devicename;
11935 		} else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) {
11936 			sas_wwn = 0;
11937 		}
11938 	}
11939 
11940 	/*
11941 	 * Check if the dev handle is for a Phys Disk. If so, set return value
11942 	 * and exit.  Don't add Phys Disks to hash.
11943 	 */
11944 	for (config = 0; config < slots->m_num_raid_configs; config++) {
11945 		for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
11946 			if (*dev_handle == slots->m_raidconfig[config].
11947 			    m_physdisk_devhdl[disk]) {
11948 				rval = DEV_INFO_PHYS_DISK;
11949 				return (rval);
11950 			}
11951 		}
11952 	}
11953 
11954 	phymask = mptsas_physport_to_phymask(mpt, physport);
11955 	*pptgt = mptsas_tgt_alloc(&slots->m_tgttbl, *dev_handle, sas_wwn,
11956 	    dev_info, phymask, phynum);
11957 	if (*pptgt == NULL) {
11958 		mptsas_log(mpt, CE_WARN, "Failed to allocated target"
11959 		    "structure!");
11960 		rval = DEV_INFO_FAIL_ALLOC;
11961 		return (rval);
11962 	}
11963 	return (DEV_INFO_SUCCESS);
11964 }
11965 
11966 uint64_t
11967 mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun)
11968 {
11969 	uint64_t	sata_guid = 0, *pwwn = NULL;
11970 	int		target = ptgt->m_devhdl;
11971 	uchar_t		*inq83 = NULL;
11972 	int		inq83_len = 0xFF;
11973 	uchar_t		*dblk = NULL;
11974 	int		inq83_retry = 3;
11975 	int		rval = DDI_FAILURE;
11976 
11977 	inq83	= kmem_zalloc(inq83_len, KM_SLEEP);
11978 
11979 inq83_retry:
11980 	rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83,
11981 	    inq83_len, NULL, 1);
11982 	if (rval != DDI_SUCCESS) {
11983 		mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
11984 		    "0x83 for target:%x, lun:%x failed!", target, lun);
11985 		goto out;
11986 	}
11987 	/* According to SAT2, the first descriptor is logic unit name */
11988 	dblk = &inq83[4];
11989 	if ((dblk[1] & 0x30) != 0) {
11990 		mptsas_log(mpt, CE_WARN, "!Descriptor is not lun associated.");
11991 		goto out;
11992 	}
11993 	pwwn = (uint64_t *)(void *)(&dblk[4]);
11994 	if ((dblk[4] & 0xf0) == 0x50) {
11995 		sata_guid = BE_64(*pwwn);
11996 		goto out;
11997 	} else if (dblk[4] == 'A') {
11998 		NDBG20(("SATA drive has no NAA format GUID."));
11999 		goto out;
12000 	} else {
12001 		/* The data is not ready, wait and retry */
12002 		inq83_retry--;
12003 		if (inq83_retry <= 0) {
12004 			goto out;
12005 		}
12006 		NDBG20(("The GUID is not ready, retry..."));
12007 		delay(1 * drv_usectohz(1000000));
12008 		goto inq83_retry;
12009 	}
12010 out:
12011 	kmem_free(inq83, inq83_len);
12012 	return (sata_guid);
12013 }
12014 
12015 static int
12016 mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, uchar_t page,
12017     unsigned char *buf, int len, int *reallen, uchar_t evpd)
12018 {
12019 	uchar_t			cdb[CDB_GROUP0];
12020 	struct scsi_address	ap;
12021 	struct buf		*data_bp = NULL;
12022 	int			resid = 0;
12023 	int			ret = DDI_FAILURE;
12024 
12025 	ASSERT(len <= 0xffff);
12026 
12027 	ap.a_target = MPTSAS_INVALID_DEVHDL;
12028 	ap.a_lun = (uchar_t)(lun);
12029 	ap.a_hba_tran = mpt->m_tran;
12030 
12031 	data_bp = scsi_alloc_consistent_buf(&ap,
12032 	    (struct buf *)NULL, len, B_READ, NULL_FUNC, NULL);
12033 	if (data_bp == NULL) {
12034 		return (ret);
12035 	}
12036 	bzero(cdb, CDB_GROUP0);
12037 	cdb[0] = SCMD_INQUIRY;
12038 	cdb[1] = evpd;
12039 	cdb[2] = page;
12040 	cdb[3] = (len & 0xff00) >> 8;
12041 	cdb[4] = (len & 0x00ff);
12042 	cdb[5] = 0;
12043 
12044 	ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP0, data_bp,
12045 	    &resid);
12046 	if (ret == DDI_SUCCESS) {
12047 		if (reallen) {
12048 			*reallen = len - resid;
12049 		}
12050 		bcopy((caddr_t)data_bp->b_un.b_addr, buf, len);
12051 	}
12052 	if (data_bp) {
12053 		scsi_free_consistent_buf(data_bp);
12054 	}
12055 	return (ret);
12056 }
12057 
12058 static int
12059 mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap,
12060     mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp,
12061     int *resid)
12062 {
12063 	struct scsi_pkt		*pktp = NULL;
12064 	scsi_hba_tran_t		*tran_clone = NULL;
12065 	mptsas_tgt_private_t	*tgt_private = NULL;
12066 	int			ret = DDI_FAILURE;
12067 
12068 	/*
12069 	 * scsi_hba_tran_t->tran_tgt_private is used to pass the address
12070 	 * information to scsi_init_pkt, allocate a scsi_hba_tran structure
12071 	 * to simulate the cmds from sd
12072 	 */
12073 	tran_clone = kmem_alloc(
12074 	    sizeof (scsi_hba_tran_t), KM_SLEEP);
12075 	if (tran_clone == NULL) {
12076 		goto out;
12077 	}
12078 	bcopy((caddr_t)mpt->m_tran,
12079 	    (caddr_t)tran_clone, sizeof (scsi_hba_tran_t));
12080 	tgt_private = kmem_alloc(
12081 	    sizeof (mptsas_tgt_private_t), KM_SLEEP);
12082 	if (tgt_private == NULL) {
12083 		goto out;
12084 	}
12085 	tgt_private->t_lun = ap->a_lun;
12086 	tgt_private->t_private = ptgt;
12087 	tran_clone->tran_tgt_private = tgt_private;
12088 	ap->a_hba_tran = tran_clone;
12089 
12090 	pktp = scsi_init_pkt(ap, (struct scsi_pkt *)NULL,
12091 	    data_bp, cdblen, sizeof (struct scsi_arq_status),
12092 	    0, PKT_CONSISTENT, NULL, NULL);
12093 	if (pktp == NULL) {
12094 		goto out;
12095 	}
12096 	bcopy(cdb, pktp->pkt_cdbp, cdblen);
12097 	pktp->pkt_flags = FLAG_NOPARITY;
12098 	if (scsi_poll(pktp) < 0) {
12099 		goto out;
12100 	}
12101 	if (((struct scsi_status *)pktp->pkt_scbp)->sts_chk) {
12102 		goto out;
12103 	}
12104 	if (resid != NULL) {
12105 		*resid = pktp->pkt_resid;
12106 	}
12107 
12108 	ret = DDI_SUCCESS;
12109 out:
12110 	if (pktp) {
12111 		scsi_destroy_pkt(pktp);
12112 	}
12113 	if (tran_clone) {
12114 		kmem_free(tran_clone, sizeof (scsi_hba_tran_t));
12115 	}
12116 	if (tgt_private) {
12117 		kmem_free(tgt_private, sizeof (mptsas_tgt_private_t));
12118 	}
12119 	return (ret);
12120 }
12121 static int
12122 mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, int *lun)
12123 {
12124 	char	*cp = NULL;
12125 	char	*ptr = NULL;
12126 	size_t	s = 0;
12127 	char	*wwid_str = NULL;
12128 	char	*lun_str = NULL;
12129 	long	lunnum;
12130 	long	phyid = -1;
12131 	int	rc = DDI_FAILURE;
12132 
12133 	ptr = name;
12134 	ASSERT(ptr[0] == 'w' || ptr[0] == 'p');
12135 	ptr++;
12136 	if ((cp = strchr(ptr, ',')) == NULL) {
12137 		return (DDI_FAILURE);
12138 	}
12139 
12140 	wwid_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
12141 	s = (uintptr_t)cp - (uintptr_t)ptr;
12142 
12143 	bcopy(ptr, wwid_str, s);
12144 	wwid_str[s] = '\0';
12145 
12146 	ptr = ++cp;
12147 
12148 	if ((cp = strchr(ptr, '\0')) == NULL) {
12149 		goto out;
12150 	}
12151 	lun_str =  kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
12152 	s = (uintptr_t)cp - (uintptr_t)ptr;
12153 
12154 	bcopy(ptr, lun_str, s);
12155 	lun_str[s] = '\0';
12156 
12157 	if (name[0] == 'p') {
12158 		rc = ddi_strtol(wwid_str, NULL, 0x10, &phyid);
12159 	} else {
12160 		rc = scsi_wwnstr_to_wwn(wwid_str, wwid);
12161 	}
12162 	if (rc != DDI_SUCCESS)
12163 		goto out;
12164 
12165 	if (phyid != -1) {
12166 		ASSERT(phyid < 8);
12167 		*phy = (uint8_t)phyid;
12168 	}
12169 	rc = ddi_strtol(lun_str, NULL, 0x10, &lunnum);
12170 	if (rc != 0)
12171 		goto out;
12172 
12173 	*lun = (int)lunnum;
12174 	rc = DDI_SUCCESS;
12175 out:
12176 	if (wwid_str)
12177 		kmem_free(wwid_str, SCSI_MAXNAMELEN);
12178 	if (lun_str)
12179 		kmem_free(lun_str, SCSI_MAXNAMELEN);
12180 
12181 	return (rc);
12182 }
12183 
12184 /*
12185  * mptsas_parse_smp_name() is to parse sas wwn string
12186  * which format is "wWWN"
12187  */
12188 static int
12189 mptsas_parse_smp_name(char *name, uint64_t *wwn)
12190 {
12191 	char	*ptr = name;
12192 
12193 	if (*ptr != 'w') {
12194 		return (DDI_FAILURE);
12195 	}
12196 
12197 	ptr++;
12198 	if (scsi_wwnstr_to_wwn(ptr, wwn)) {
12199 		return (DDI_FAILURE);
12200 	}
12201 	return (DDI_SUCCESS);
12202 }
12203 
12204 static int
12205 mptsas_bus_config(dev_info_t *pdip, uint_t flag,
12206     ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
12207 {
12208 	int		ret = NDI_FAILURE;
12209 	int		circ = 0;
12210 	int		circ1 = 0;
12211 	mptsas_t	*mpt;
12212 	char		*ptr = NULL;
12213 	char		*devnm = NULL;
12214 	uint64_t	wwid = 0;
12215 	uint8_t		phy = 0xFF;
12216 	int		lun = 0;
12217 	uint_t		mflags = flag;
12218 
12219 	if (scsi_hba_iport_unit_address(pdip) == 0) {
12220 		return (DDI_FAILURE);
12221 	}
12222 
12223 	mpt = DIP2MPT(pdip);
12224 	if (!mpt) {
12225 		return (DDI_FAILURE);
12226 	}
12227 
12228 	/*
12229 	 * Hold the nexus across the bus_config
12230 	 */
12231 	ndi_devi_enter(scsi_vhci_dip, &circ);
12232 	ndi_devi_enter(pdip, &circ1);
12233 	switch (op) {
12234 	case BUS_CONFIG_ONE:
12235 		/* parse wwid/target name out of name given */
12236 		if ((ptr = strchr((char *)arg, '@')) == NULL) {
12237 			ret = NDI_FAILURE;
12238 			break;
12239 		}
12240 		ptr++;
12241 		if (strncmp((char *)arg, "smp", 3) == 0) {
12242 			/*
12243 			 * This is a SMP target device
12244 			 */
12245 			ret = mptsas_parse_smp_name(ptr, &wwid);
12246 			if (ret != DDI_SUCCESS) {
12247 				ret = NDI_FAILURE;
12248 				break;
12249 			}
12250 			ret = mptsas_config_smp(pdip, wwid, childp);
12251 		} else if ((ptr[0] == 'w') || (ptr[0] == 'p')) {
12252 			/*
12253 			 * OBP could pass down a non-canonical form
12254 			 * bootpath without LUN part when LUN is 0.
12255 			 * So driver need adjust the string.
12256 			 */
12257 			if (strchr(ptr, ',') == NULL) {
12258 				devnm = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
12259 				(void) sprintf(devnm, "%s,0", (char *)arg);
12260 				ptr = strchr(devnm, '@');
12261 				ptr++;
12262 			}
12263 
12264 			/*
12265 			 * The device path is wWWID format and the device
12266 			 * is not SMP target device.
12267 			 */
12268 			ret = mptsas_parse_address(ptr, &wwid, &phy, &lun);
12269 			if (ret != DDI_SUCCESS) {
12270 				ret = NDI_FAILURE;
12271 				break;
12272 			}
12273 			if (ptr[0] == 'w') {
12274 				ret = mptsas_config_one_addr(pdip, wwid,
12275 				    lun, childp);
12276 			} else if (ptr[0] == 'p') {
12277 				ret = mptsas_config_one_phy(pdip, phy, lun,
12278 				    childp);
12279 			}
12280 		} else {
12281 			ret = NDI_FAILURE;
12282 			break;
12283 		}
12284 
12285 		/*
12286 		 * DDI group instructed us to use this flag.
12287 		 */
12288 		mflags |= NDI_MDI_FALLBACK;
12289 		break;
12290 	case BUS_CONFIG_DRIVER:
12291 	case BUS_CONFIG_ALL:
12292 		mptsas_config_all(pdip);
12293 		ret = NDI_SUCCESS;
12294 		break;
12295 	}
12296 
12297 	if (ret == NDI_SUCCESS) {
12298 		ret = ndi_busop_bus_config(pdip, mflags, op,
12299 		    (devnm == NULL) ? arg : devnm, childp, 0);
12300 	}
12301 
12302 	ndi_devi_exit(pdip, circ1);
12303 	ndi_devi_exit(scsi_vhci_dip, circ);
12304 	if (devnm != NULL)
12305 		kmem_free(devnm, SCSI_MAXNAMELEN);
12306 	return (ret);
12307 }
12308 
12309 static int
12310 mptsas_probe_lun(dev_info_t *pdip, int lun, dev_info_t **dip,
12311     mptsas_target_t *ptgt)
12312 {
12313 	int			rval = DDI_FAILURE;
12314 	struct scsi_inquiry	*sd_inq = NULL;
12315 	mptsas_t		*mpt = DIP2MPT(pdip);
12316 
12317 	sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP);
12318 
12319 	rval = mptsas_inquiry(mpt, ptgt, lun, 0, (uchar_t *)sd_inq,
12320 	    SUN_INQSIZE, 0, (uchar_t)0);
12321 
12322 	if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) {
12323 		rval = mptsas_create_lun(pdip, sd_inq, dip, ptgt, lun);
12324 	} else {
12325 		rval = DDI_FAILURE;
12326 	}
12327 
12328 	kmem_free(sd_inq, SUN_INQSIZE);
12329 	return (rval);
12330 }
12331 
12332 static int
12333 mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
12334     dev_info_t **lundip)
12335 {
12336 	int		rval;
12337 	mptsas_t		*mpt = DIP2MPT(pdip);
12338 	int		phymask;
12339 	mptsas_target_t	*ptgt = NULL;
12340 
12341 	/*
12342 	 * Get the physical port associated to the iport
12343 	 */
12344 	phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
12345 	    "phymask", 0);
12346 
12347 	ptgt = mptsas_wwid_to_ptgt(mpt, phymask, sasaddr);
12348 	if (ptgt == NULL) {
12349 		/*
12350 		 * didn't match any device by searching
12351 		 */
12352 		return (DDI_FAILURE);
12353 	}
12354 	/*
12355 	 * If the LUN already exists and the status is online,
12356 	 * we just return the pointer to dev_info_t directly.
12357 	 * For the mdi_pathinfo node, we'll handle it in
12358 	 * mptsas_create_virt_lun()
12359 	 * TODO should be also in mptsas_handle_dr
12360 	 */
12361 
12362 	*lundip = mptsas_find_child_addr(pdip, sasaddr, lun);
12363 	if (*lundip != NULL) {
12364 		/*
12365 		 * TODO Another senario is, we hotplug the same disk
12366 		 * on the same slot, the devhdl changed, is this
12367 		 * possible?
12368 		 * tgt_private->t_private != ptgt
12369 		 */
12370 		if (sasaddr != ptgt->m_sas_wwn) {
12371 			/*
12372 			 * The device has changed although the devhdl is the
12373 			 * same (Enclosure mapping mode, change drive on the
12374 			 * same slot)
12375 			 */
12376 			return (DDI_FAILURE);
12377 		}
12378 		return (DDI_SUCCESS);
12379 	}
12380 
12381 	if (phymask == 0) {
12382 		/*
12383 		 * Configure IR volume
12384 		 */
12385 		rval =  mptsas_config_raid(pdip, ptgt->m_devhdl, lundip);
12386 		return (rval);
12387 	}
12388 	rval = mptsas_probe_lun(pdip, lun, lundip, ptgt);
12389 
12390 	return (rval);
12391 }
12392 
12393 static int
12394 mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
12395     dev_info_t **lundip)
12396 {
12397 	int		rval;
12398 	mptsas_target_t	*ptgt = NULL;
12399 
12400 	ptgt = mptsas_phy_to_tgt(pdip, phy);
12401 	if (ptgt == NULL) {
12402 		/*
12403 		 * didn't match any device by searching
12404 		 */
12405 		return (DDI_FAILURE);
12406 	}
12407 
12408 	/*
12409 	 * If the LUN already exists and the status is online,
12410 	 * we just return the pointer to dev_info_t directly.
12411 	 * For the mdi_pathinfo node, we'll handle it in
12412 	 * mptsas_create_virt_lun().
12413 	 */
12414 
12415 	*lundip = mptsas_find_child_phy(pdip, phy);
12416 	if (*lundip != NULL) {
12417 		return (DDI_SUCCESS);
12418 	}
12419 
12420 	rval = mptsas_probe_lun(pdip, lun, lundip, ptgt);
12421 
12422 	return (rval);
12423 }
12424 
12425 static int
12426 mptsas_retrieve_lundata(int lun_cnt, uint8_t *buf, uint16_t *lun_num,
12427     uint8_t *lun_addr_type)
12428 {
12429 	uint32_t	lun_idx = 0;
12430 
12431 	ASSERT(lun_num != NULL);
12432 	ASSERT(lun_addr_type != NULL);
12433 
12434 	lun_idx = (lun_cnt + 1) * MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE;
12435 	/* determine report luns addressing type */
12436 	switch (buf[lun_idx] & MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) {
12437 		/*
12438 		 * Vendors in the field have been found to be concatenating
12439 		 * bus/target/lun to equal the complete lun value instead
12440 		 * of switching to flat space addressing
12441 		 */
12442 		/* 00b - peripheral device addressing method */
12443 	case MPTSAS_SCSI_REPORTLUNS_ADDRESS_PERIPHERAL:
12444 		/* FALLTHRU */
12445 		/* 10b - logical unit addressing method */
12446 	case MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT:
12447 		/* FALLTHRU */
12448 		/* 01b - flat space addressing method */
12449 	case MPTSAS_SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE:
12450 		/* byte0 bit0-5=msb lun byte1 bit0-7=lsb lun */
12451 		*lun_addr_type = (buf[lun_idx] &
12452 		    MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) >> 6;
12453 		*lun_num = (buf[lun_idx] & 0x3F) << 8;
12454 		*lun_num |= buf[lun_idx + 1];
12455 		return (DDI_SUCCESS);
12456 	default:
12457 		return (DDI_FAILURE);
12458 	}
12459 }
12460 
12461 static int
12462 mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt)
12463 {
12464 	struct buf		*repluns_bp = NULL;
12465 	struct scsi_address	ap;
12466 	uchar_t			cdb[CDB_GROUP5];
12467 	int			ret = DDI_FAILURE;
12468 	int			retry = 0;
12469 	int			lun_list_len = 0;
12470 	uint16_t		lun_num = 0;
12471 	uint8_t			lun_addr_type = 0;
12472 	uint32_t		lun_cnt = 0;
12473 	uint32_t		lun_total = 0;
12474 	dev_info_t		*cdip = NULL;
12475 	uint16_t		*saved_repluns = NULL;
12476 	char			*buffer = NULL;
12477 	int			buf_len = 128;
12478 	mptsas_t		*mpt = DIP2MPT(pdip);
12479 	uint64_t		sas_wwn = 0;
12480 	uint8_t			phy = 0xFF;
12481 	uint32_t		dev_info = 0;
12482 
12483 	mutex_enter(&mpt->m_mutex);
12484 	sas_wwn = ptgt->m_sas_wwn;
12485 	phy = ptgt->m_phynum;
12486 	dev_info = ptgt->m_deviceinfo;
12487 	mutex_exit(&mpt->m_mutex);
12488 
12489 	if (sas_wwn == 0) {
12490 		/*
12491 		 * It's a SATA without Device Name
12492 		 * So don't try multi-LUNs
12493 		 */
12494 		if (mptsas_find_child_phy(pdip, phy)) {
12495 			return (DDI_SUCCESS);
12496 		} else {
12497 			/*
12498 			 * need configure and create node
12499 			 */
12500 			return (DDI_FAILURE);
12501 		}
12502 	}
12503 
12504 	/*
12505 	 * WWN (SAS address or Device Name exist)
12506 	 */
12507 	if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
12508 	    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
12509 		/*
12510 		 * SATA device with Device Name
12511 		 * So don't try multi-LUNs
12512 		 */
12513 		if (mptsas_find_child_addr(pdip, sas_wwn, 0)) {
12514 			return (DDI_SUCCESS);
12515 		} else {
12516 			return (DDI_FAILURE);
12517 		}
12518 	}
12519 
12520 	do {
12521 		ap.a_target = MPTSAS_INVALID_DEVHDL;
12522 		ap.a_lun = 0;
12523 		ap.a_hba_tran = mpt->m_tran;
12524 		repluns_bp = scsi_alloc_consistent_buf(&ap,
12525 		    (struct buf *)NULL, buf_len, B_READ, NULL_FUNC, NULL);
12526 		if (repluns_bp == NULL) {
12527 			retry++;
12528 			continue;
12529 		}
12530 		bzero(cdb, CDB_GROUP5);
12531 		cdb[0] = SCMD_REPORT_LUNS;
12532 		cdb[6] = (buf_len & 0xff000000) >> 24;
12533 		cdb[7] = (buf_len & 0x00ff0000) >> 16;
12534 		cdb[8] = (buf_len & 0x0000ff00) >> 8;
12535 		cdb[9] = (buf_len & 0x000000ff);
12536 
12537 		ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP5,
12538 		    repluns_bp, NULL);
12539 		if (ret != DDI_SUCCESS) {
12540 			scsi_free_consistent_buf(repluns_bp);
12541 			retry++;
12542 			continue;
12543 		}
12544 		lun_list_len = BE_32(*(int *)((void *)(
12545 		    repluns_bp->b_un.b_addr)));
12546 		if (buf_len >= lun_list_len + 8) {
12547 			ret = DDI_SUCCESS;
12548 			break;
12549 		}
12550 		scsi_free_consistent_buf(repluns_bp);
12551 		buf_len = lun_list_len + 8;
12552 
12553 	} while (retry < 3);
12554 
12555 	if (ret != DDI_SUCCESS)
12556 		return (ret);
12557 	buffer = (char *)repluns_bp->b_un.b_addr;
12558 	/*
12559 	 * find out the number of luns returned by the SCSI ReportLun call
12560 	 * and allocate buffer space
12561 	 */
12562 	lun_total = lun_list_len / MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE;
12563 	saved_repluns = kmem_zalloc(sizeof (uint16_t) * lun_total, KM_SLEEP);
12564 	if (saved_repluns == NULL) {
12565 		scsi_free_consistent_buf(repluns_bp);
12566 		return (DDI_FAILURE);
12567 	}
12568 	for (lun_cnt = 0; lun_cnt < lun_total; lun_cnt++) {
12569 		if (mptsas_retrieve_lundata(lun_cnt, (uint8_t *)(buffer),
12570 		    &lun_num, &lun_addr_type) != DDI_SUCCESS) {
12571 			continue;
12572 		}
12573 		saved_repluns[lun_cnt] = lun_num;
12574 		if (cdip = mptsas_find_child_addr(pdip, sas_wwn, lun_num))
12575 			ret = DDI_SUCCESS;
12576 		else
12577 			ret = mptsas_probe_lun(pdip, lun_num, &cdip,
12578 			    ptgt);
12579 		if ((ret == DDI_SUCCESS) && (cdip != NULL)) {
12580 			(void) ndi_prop_remove(DDI_DEV_T_NONE, cdip,
12581 			    MPTSAS_DEV_GONE);
12582 		}
12583 	}
12584 	mptsas_offline_missed_luns(pdip, saved_repluns, lun_total, ptgt);
12585 	kmem_free(saved_repluns, sizeof (uint16_t) * lun_total);
12586 	scsi_free_consistent_buf(repluns_bp);
12587 	return (DDI_SUCCESS);
12588 }
12589 
12590 static int
12591 mptsas_config_raid(dev_info_t *pdip, uint16_t target, dev_info_t **dip)
12592 {
12593 	int			rval = DDI_FAILURE;
12594 	struct scsi_inquiry	*sd_inq = NULL;
12595 	mptsas_t		*mpt = DIP2MPT(pdip);
12596 	mptsas_target_t		*ptgt = NULL;
12597 
12598 	mutex_enter(&mpt->m_mutex);
12599 	ptgt = mptsas_search_by_devhdl(&mpt->m_active->m_tgttbl, target);
12600 	mutex_exit(&mpt->m_mutex);
12601 	if (ptgt == NULL) {
12602 		mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x "
12603 		    "not found.", target);
12604 		return (rval);
12605 	}
12606 
12607 	sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP);
12608 	rval = mptsas_inquiry(mpt, ptgt, 0, 0, (uchar_t *)sd_inq,
12609 	    SUN_INQSIZE, 0, (uchar_t)0);
12610 
12611 	if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) {
12612 		rval = mptsas_create_phys_lun(pdip, sd_inq, NULL, dip, ptgt,
12613 		    0);
12614 	} else {
12615 		rval = DDI_FAILURE;
12616 	}
12617 
12618 	kmem_free(sd_inq, SUN_INQSIZE);
12619 	return (rval);
12620 }
12621 
12622 /*
12623  * configure all RAID volumes for virtual iport
12624  */
12625 static void
12626 mptsas_config_all_viport(dev_info_t *pdip)
12627 {
12628 	mptsas_t	*mpt = DIP2MPT(pdip);
12629 	int		config, vol;
12630 	int		target;
12631 	dev_info_t	*lundip = NULL;
12632 	mptsas_slots_t	*slots = mpt->m_active;
12633 
12634 	/*
12635 	 * Get latest RAID info and search for any Volume DevHandles.  If any
12636 	 * are found, configure the volume.
12637 	 */
12638 	mutex_enter(&mpt->m_mutex);
12639 	for (config = 0; config < slots->m_num_raid_configs; config++) {
12640 		for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
12641 			if (slots->m_raidconfig[config].m_raidvol[vol].m_israid
12642 			    == 1) {
12643 				target = slots->m_raidconfig[config].
12644 				    m_raidvol[vol].m_raidhandle;
12645 				mutex_exit(&mpt->m_mutex);
12646 				(void) mptsas_config_raid(pdip, target,
12647 				    &lundip);
12648 				mutex_enter(&mpt->m_mutex);
12649 			}
12650 		}
12651 	}
12652 	mutex_exit(&mpt->m_mutex);
12653 }
12654 
12655 static void
12656 mptsas_offline_missed_luns(dev_info_t *pdip, uint16_t *repluns,
12657     int lun_cnt, mptsas_target_t *ptgt)
12658 {
12659 	dev_info_t	*child = NULL, *savechild = NULL;
12660 	mdi_pathinfo_t	*pip = NULL, *savepip = NULL;
12661 	uint64_t	sas_wwn, wwid;
12662 	uint8_t		phy;
12663 	int		lun;
12664 	int		i;
12665 	int		find;
12666 	char		*addr;
12667 	char		*nodename;
12668 	mptsas_t	*mpt = DIP2MPT(pdip);
12669 
12670 	mutex_enter(&mpt->m_mutex);
12671 	wwid = ptgt->m_sas_wwn;
12672 	mutex_exit(&mpt->m_mutex);
12673 
12674 	child = ddi_get_child(pdip);
12675 	while (child) {
12676 		find = 0;
12677 		savechild = child;
12678 		child = ddi_get_next_sibling(child);
12679 
12680 		nodename = ddi_node_name(savechild);
12681 		if (strcmp(nodename, "smp") == 0) {
12682 			continue;
12683 		}
12684 
12685 		addr = ddi_get_name_addr(savechild);
12686 		if (addr == NULL) {
12687 			continue;
12688 		}
12689 
12690 		if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) !=
12691 		    DDI_SUCCESS) {
12692 			continue;
12693 		}
12694 
12695 		if (wwid == sas_wwn) {
12696 			for (i = 0; i < lun_cnt; i++) {
12697 				if (repluns[i] == lun) {
12698 					find = 1;
12699 					break;
12700 				}
12701 			}
12702 		} else {
12703 			continue;
12704 		}
12705 		if (find == 0) {
12706 			/*
12707 			 * The lun has not been there already
12708 			 */
12709 			(void) mptsas_offline_lun(pdip, savechild, NULL,
12710 			    NDI_DEVI_REMOVE);
12711 		}
12712 	}
12713 
12714 	pip = mdi_get_next_client_path(pdip, NULL);
12715 	while (pip) {
12716 		find = 0;
12717 		savepip = pip;
12718 		addr = MDI_PI(pip)->pi_addr;
12719 
12720 		pip = mdi_get_next_client_path(pdip, pip);
12721 
12722 		if (addr == NULL) {
12723 			continue;
12724 		}
12725 
12726 		if (mptsas_parse_address(addr, &sas_wwn, &phy,
12727 		    &lun) != DDI_SUCCESS) {
12728 			continue;
12729 		}
12730 
12731 		if (sas_wwn == wwid) {
12732 			for (i = 0; i < lun_cnt; i++) {
12733 				if (repluns[i] == lun) {
12734 					find = 1;
12735 					break;
12736 				}
12737 			}
12738 		} else {
12739 			continue;
12740 		}
12741 
12742 		if (find == 0) {
12743 			/*
12744 			 * The lun has not been there already
12745 			 */
12746 			(void) mptsas_offline_lun(pdip, NULL, savepip,
12747 			    NDI_DEVI_REMOVE);
12748 		}
12749 	}
12750 }
12751 
12752 void
12753 mptsas_update_hashtab(struct mptsas *mpt)
12754 {
12755 	uint32_t	page_address;
12756 	int		rval = 0;
12757 	uint16_t	dev_handle;
12758 	mptsas_target_t	*ptgt = NULL;
12759 	mptsas_smp_t	smp_node;
12760 
12761 	/*
12762 	 * Get latest RAID info.
12763 	 */
12764 	(void) mptsas_get_raid_info(mpt);
12765 
12766 	dev_handle = mpt->m_smp_devhdl;
12767 	for (; mpt->m_done_traverse_smp == 0; ) {
12768 		page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
12769 		    MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)dev_handle;
12770 		if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node)
12771 		    != DDI_SUCCESS) {
12772 			break;
12773 		}
12774 		mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl;
12775 		(void) mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node);
12776 	}
12777 
12778 	/*
12779 	 * Config target devices
12780 	 */
12781 	dev_handle = mpt->m_dev_handle;
12782 
12783 	/*
12784 	 * Do loop to get sas device page 0 by GetNextHandle till the
12785 	 * the last handle. If the sas device is a SATA/SSP target,
12786 	 * we try to config it.
12787 	 */
12788 	for (; mpt->m_done_traverse_dev == 0; ) {
12789 		ptgt = NULL;
12790 		page_address =
12791 		    (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
12792 		    MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
12793 		    (uint32_t)dev_handle;
12794 		rval = mptsas_get_target_device_info(mpt, page_address,
12795 		    &dev_handle, &ptgt);
12796 		if ((rval == DEV_INFO_FAIL_PAGE0) ||
12797 		    (rval == DEV_INFO_FAIL_ALLOC)) {
12798 			break;
12799 		}
12800 
12801 		mpt->m_dev_handle = dev_handle;
12802 	}
12803 
12804 }
12805 
12806 void
12807 mptsas_invalid_hashtab(mptsas_hash_table_t *hashtab)
12808 {
12809 	mptsas_hash_data_t *data;
12810 	data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST);
12811 	while (data != NULL) {
12812 		data->devhdl = MPTSAS_INVALID_DEVHDL;
12813 		data->device_info = 0;
12814 		/*
12815 		 * For tgttbl, clear dr_flag.
12816 		 */
12817 		data->dr_flag = MPTSAS_DR_INACTIVE;
12818 		data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT);
12819 	}
12820 }
12821 
12822 void
12823 mptsas_update_driver_data(struct mptsas *mpt)
12824 {
12825 	/*
12826 	 * TODO after hard reset, update the driver data structures
12827 	 * 1. update port/phymask mapping table mpt->m_phy_info
12828 	 * 2. invalid all the entries in hash table
12829 	 *    m_devhdl = 0xffff and m_deviceinfo = 0
12830 	 * 3. call sas_device_page/expander_page to update hash table
12831 	 */
12832 	mptsas_update_phymask(mpt);
12833 	/*
12834 	 * Invalid the existing entries
12835 	 */
12836 	mptsas_invalid_hashtab(&mpt->m_active->m_tgttbl);
12837 	mptsas_invalid_hashtab(&mpt->m_active->m_smptbl);
12838 	mpt->m_done_traverse_dev = 0;
12839 	mpt->m_done_traverse_smp = 0;
12840 	mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL;
12841 	mptsas_update_hashtab(mpt);
12842 }
12843 
12844 static void
12845 mptsas_config_all(dev_info_t *pdip)
12846 {
12847 	dev_info_t	*smpdip = NULL;
12848 	mptsas_t	*mpt = DIP2MPT(pdip);
12849 	int		phymask = 0;
12850 	uint8_t		phy_mask;
12851 	mptsas_target_t	*ptgt = NULL;
12852 	mptsas_smp_t	*psmp;
12853 
12854 	/*
12855 	 * Get the phymask associated to the iport
12856 	 */
12857 	phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
12858 	    "phymask", 0);
12859 
12860 	/*
12861 	 * Enumerate RAID volumes here (phymask == 0).
12862 	 */
12863 	if (phymask == 0) {
12864 		mptsas_config_all_viport(pdip);
12865 		return;
12866 	}
12867 
12868 	mutex_enter(&mpt->m_mutex);
12869 
12870 	if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp) {
12871 		mptsas_update_hashtab(mpt);
12872 	}
12873 
12874 	psmp = (mptsas_smp_t *)mptsas_hash_traverse(&mpt->m_active->m_smptbl,
12875 	    MPTSAS_HASH_FIRST);
12876 	while (psmp != NULL) {
12877 		phy_mask = psmp->m_phymask;
12878 		if (phy_mask == phymask) {
12879 			smpdip = NULL;
12880 			mutex_exit(&mpt->m_mutex);
12881 			(void) mptsas_online_smp(pdip, psmp, &smpdip);
12882 			mutex_enter(&mpt->m_mutex);
12883 		}
12884 		psmp = (mptsas_smp_t *)mptsas_hash_traverse(
12885 		    &mpt->m_active->m_smptbl, MPTSAS_HASH_NEXT);
12886 	}
12887 
12888 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
12889 	    MPTSAS_HASH_FIRST);
12890 	while (ptgt != NULL) {
12891 		phy_mask = ptgt->m_phymask;
12892 		if (phy_mask == phymask) {
12893 			mutex_exit(&mpt->m_mutex);
12894 			(void) mptsas_config_target(pdip, ptgt);
12895 			mutex_enter(&mpt->m_mutex);
12896 		}
12897 
12898 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
12899 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
12900 	}
12901 	mutex_exit(&mpt->m_mutex);
12902 }
12903 
12904 static int
12905 mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt)
12906 {
12907 	int		rval = DDI_FAILURE;
12908 	dev_info_t	*tdip;
12909 
12910 	rval = mptsas_config_luns(pdip, ptgt);
12911 	if (rval != DDI_SUCCESS) {
12912 		/*
12913 		 * The return value means the SCMD_REPORT_LUNS
12914 		 * did not execute successfully. The target maybe
12915 		 * doesn't support such command.
12916 		 */
12917 		rval = mptsas_probe_lun(pdip, 0, &tdip, ptgt);
12918 	}
12919 	return (rval);
12920 }
12921 
12922 /*
12923  * Return fail if not all the childs/paths are freed.
12924  * if there is any path under the HBA, the return value will be always fail
12925  * because we didn't call mdi_pi_free for path
12926  */
12927 static int
12928 mptsas_offline_target(dev_info_t *pdip, char *name)
12929 {
12930 	dev_info_t		*child = NULL, *prechild = NULL;
12931 	mdi_pathinfo_t		*pip = NULL, *savepip = NULL;
12932 	int			tmp_rval, rval = DDI_SUCCESS;
12933 	char			*addr, *cp;
12934 	size_t			s;
12935 	mptsas_t		*mpt = DIP2MPT(pdip);
12936 
12937 	child = ddi_get_child(pdip);
12938 	while (child) {
12939 		addr = ddi_get_name_addr(child);
12940 		prechild = child;
12941 		child = ddi_get_next_sibling(child);
12942 
12943 		if (addr == NULL) {
12944 			continue;
12945 		}
12946 		if ((cp = strchr(addr, ',')) == NULL) {
12947 			continue;
12948 		}
12949 
12950 		s = (uintptr_t)cp - (uintptr_t)addr;
12951 
12952 		if (strncmp(addr, name, s) != 0) {
12953 			continue;
12954 		}
12955 
12956 		tmp_rval = mptsas_offline_lun(pdip, prechild, NULL,
12957 		    NDI_DEVI_REMOVE);
12958 		if (tmp_rval != DDI_SUCCESS) {
12959 			rval = DDI_FAILURE;
12960 			if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
12961 			    prechild, MPTSAS_DEV_GONE) !=
12962 			    DDI_PROP_SUCCESS) {
12963 				mptsas_log(mpt, CE_WARN, "mptsas driver "
12964 				    "unable to create property for "
12965 				    "SAS %s (MPTSAS_DEV_GONE)", addr);
12966 			}
12967 		}
12968 	}
12969 
12970 	pip = mdi_get_next_client_path(pdip, NULL);
12971 	while (pip) {
12972 		addr = MDI_PI(pip)->pi_addr;
12973 		savepip = pip;
12974 		pip = mdi_get_next_client_path(pdip, pip);
12975 		if (addr == NULL) {
12976 			continue;
12977 		}
12978 
12979 		if ((cp = strchr(addr, ',')) == NULL) {
12980 			continue;
12981 		}
12982 
12983 		s = (uintptr_t)cp - (uintptr_t)addr;
12984 
12985 		if (strncmp(addr, name, s) != 0) {
12986 			continue;
12987 		}
12988 
12989 		(void) mptsas_offline_lun(pdip, NULL, savepip,
12990 		    NDI_DEVI_REMOVE);
12991 		/*
12992 		 * driver will not invoke mdi_pi_free, so path will not
12993 		 * be freed forever, return DDI_FAILURE.
12994 		 */
12995 		rval = DDI_FAILURE;
12996 	}
12997 	return (rval);
12998 }
12999 
13000 static int
13001 mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
13002     mdi_pathinfo_t *rpip, uint_t flags)
13003 {
13004 	int		rval = DDI_FAILURE;
13005 	char		*devname;
13006 	dev_info_t	*cdip, *parent;
13007 
13008 	if (rpip != NULL) {
13009 		parent = scsi_vhci_dip;
13010 		cdip = mdi_pi_get_client(rpip);
13011 	} else if (rdip != NULL) {
13012 		parent = pdip;
13013 		cdip = rdip;
13014 	} else {
13015 		return (DDI_FAILURE);
13016 	}
13017 
13018 	/*
13019 	 * Make sure node is attached otherwise
13020 	 * it won't have related cache nodes to
13021 	 * clean up.  i_ddi_devi_attached is
13022 	 * similiar to i_ddi_node_state(cdip) >=
13023 	 * DS_ATTACHED.
13024 	 */
13025 	if (i_ddi_devi_attached(cdip)) {
13026 
13027 		/* Get full devname */
13028 		devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
13029 		(void) ddi_deviname(cdip, devname);
13030 		/* Clean cache */
13031 		(void) devfs_clean(parent, devname + 1,
13032 		    DV_CLEAN_FORCE);
13033 		kmem_free(devname, MAXNAMELEN + 1);
13034 	}
13035 	if (rpip != NULL) {
13036 		if (MDI_PI_IS_OFFLINE(rpip)) {
13037 			rval = DDI_SUCCESS;
13038 		} else {
13039 			rval = mdi_pi_offline(rpip, 0);
13040 		}
13041 	} else {
13042 		rval = ndi_devi_offline(cdip, flags);
13043 	}
13044 
13045 	return (rval);
13046 }
13047 
13048 static dev_info_t *
13049 mptsas_find_smp_child(dev_info_t *parent, char *str_wwn)
13050 {
13051 	dev_info_t	*child = NULL;
13052 	char		*smp_wwn = NULL;
13053 
13054 	child = ddi_get_child(parent);
13055 	while (child) {
13056 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
13057 		    DDI_PROP_DONTPASS, SMP_WWN, &smp_wwn)
13058 		    != DDI_SUCCESS) {
13059 			child = ddi_get_next_sibling(child);
13060 			continue;
13061 		}
13062 
13063 		if (strcmp(smp_wwn, str_wwn) == 0) {
13064 			ddi_prop_free(smp_wwn);
13065 			break;
13066 		}
13067 		child = ddi_get_next_sibling(child);
13068 		ddi_prop_free(smp_wwn);
13069 	}
13070 	return (child);
13071 }
13072 
13073 static int
13074 mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags)
13075 {
13076 	int		rval = DDI_FAILURE;
13077 	char		*devname;
13078 	char		wwn_str[MPTSAS_WWN_STRLEN];
13079 	dev_info_t	*cdip;
13080 
13081 	(void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr);
13082 
13083 	cdip = mptsas_find_smp_child(pdip, wwn_str);
13084 
13085 	if (cdip == NULL)
13086 		return (DDI_SUCCESS);
13087 
13088 	/*
13089 	 * Make sure node is attached otherwise
13090 	 * it won't have related cache nodes to
13091 	 * clean up.  i_ddi_devi_attached is
13092 	 * similiar to i_ddi_node_state(cdip) >=
13093 	 * DS_ATTACHED.
13094 	 */
13095 	if (i_ddi_devi_attached(cdip)) {
13096 
13097 		/* Get full devname */
13098 		devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
13099 		(void) ddi_deviname(cdip, devname);
13100 		/* Clean cache */
13101 		(void) devfs_clean(pdip, devname + 1,
13102 		    DV_CLEAN_FORCE);
13103 		kmem_free(devname, MAXNAMELEN + 1);
13104 	}
13105 
13106 	rval = ndi_devi_offline(cdip, flags);
13107 
13108 	return (rval);
13109 }
13110 
13111 static dev_info_t *
13112 mptsas_find_child(dev_info_t *pdip, char *name)
13113 {
13114 	dev_info_t	*child = NULL;
13115 	char		*rname = NULL;
13116 	int		rval = DDI_FAILURE;
13117 
13118 	rname = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13119 
13120 	child = ddi_get_child(pdip);
13121 	while (child) {
13122 		rval = mptsas_name_child(child, rname, SCSI_MAXNAMELEN);
13123 		if (rval != DDI_SUCCESS) {
13124 			child = ddi_get_next_sibling(child);
13125 			bzero(rname, SCSI_MAXNAMELEN);
13126 			continue;
13127 		}
13128 
13129 		if (strcmp(rname, name) == 0) {
13130 			break;
13131 		}
13132 		child = ddi_get_next_sibling(child);
13133 		bzero(rname, SCSI_MAXNAMELEN);
13134 	}
13135 
13136 	kmem_free(rname, SCSI_MAXNAMELEN);
13137 
13138 	return (child);
13139 }
13140 
13141 
13142 static dev_info_t *
13143 mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, int lun)
13144 {
13145 	dev_info_t	*child = NULL;
13146 	char		*name = NULL;
13147 	char		*addr = NULL;
13148 
13149 	name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13150 	addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13151 	(void) sprintf(name, "%016"PRIx64, sasaddr);
13152 	(void) sprintf(addr, "w%s,%x", name, lun);
13153 	child = mptsas_find_child(pdip, addr);
13154 	kmem_free(name, SCSI_MAXNAMELEN);
13155 	kmem_free(addr, SCSI_MAXNAMELEN);
13156 	return (child);
13157 }
13158 
13159 static dev_info_t *
13160 mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy)
13161 {
13162 	dev_info_t	*child;
13163 	char		*addr;
13164 
13165 	addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13166 	(void) sprintf(addr, "p%x,0", phy);
13167 	child = mptsas_find_child(pdip, addr);
13168 	kmem_free(addr, SCSI_MAXNAMELEN);
13169 	return (child);
13170 }
13171 
13172 static mdi_pathinfo_t *
13173 mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy)
13174 {
13175 	mdi_pathinfo_t	*path;
13176 	char		*addr = NULL;
13177 
13178 	addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13179 	(void) sprintf(addr, "p%x,0", phy);
13180 	path = mdi_pi_find(pdip, NULL, addr);
13181 	kmem_free(addr, SCSI_MAXNAMELEN);
13182 	return (path);
13183 }
13184 
13185 static mdi_pathinfo_t *
13186 mptsas_find_path_addr(dev_info_t *parent, uint64_t sasaddr, int lun)
13187 {
13188 	mdi_pathinfo_t	*path;
13189 	char		*name = NULL;
13190 	char		*addr = NULL;
13191 
13192 	name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13193 	addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13194 	(void) sprintf(name, "%016"PRIx64, sasaddr);
13195 	(void) sprintf(addr, "w%s,%x", name, lun);
13196 	path = mdi_pi_find(parent, NULL, addr);
13197 	kmem_free(name, SCSI_MAXNAMELEN);
13198 	kmem_free(addr, SCSI_MAXNAMELEN);
13199 
13200 	return (path);
13201 }
13202 
13203 static int
13204 mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq,
13205     dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun)
13206 {
13207 	int			i = 0;
13208 	uchar_t			*inq83 = NULL;
13209 	int			inq83_len1 = 0xFF;
13210 	int			inq83_len = 0;
13211 	int			rval = DDI_FAILURE;
13212 	ddi_devid_t		devid;
13213 	char			*guid = NULL;
13214 	int			target = ptgt->m_devhdl;
13215 	mdi_pathinfo_t		*pip = NULL;
13216 	mptsas_t		*mpt = DIP2MPT(pdip);
13217 
13218 	/*
13219 	 * For DVD/CD ROM and tape devices and optical
13220 	 * devices, we won't try to enumerate them under
13221 	 * scsi_vhci, so no need to try page83
13222 	 */
13223 	if (sd_inq && (sd_inq->inq_dtype == DTYPE_RODIRECT ||
13224 	    sd_inq->inq_dtype == DTYPE_OPTICAL))
13225 		goto create_lun;
13226 
13227 	/*
13228 	 * The LCA returns good SCSI status, but corrupt page 83 data the first
13229 	 * time it is queried. The solution is to keep trying to request page83
13230 	 * and verify the GUID is not (DDI_NOT_WELL_FORMED) in
13231 	 * mptsas_inq83_retry_timeout seconds. If the timeout expires, driver
13232 	 * give up to get VPD page at this stage and fail the enumeration.
13233 	 */
13234 
13235 	inq83	= kmem_zalloc(inq83_len1, KM_SLEEP);
13236 
13237 	for (i = 0; i < mptsas_inq83_retry_timeout; i++) {
13238 		rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83,
13239 		    inq83_len1, &inq83_len, 1);
13240 		if (rval != 0) {
13241 			mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
13242 			    "0x83 for target:%x, lun:%x failed!", target, lun);
13243 			goto out;
13244 		}
13245 		/*
13246 		 * create DEVID from inquiry data
13247 		 */
13248 		if ((rval = ddi_devid_scsi_encode(
13249 		    DEVID_SCSI_ENCODE_VERSION_LATEST, NULL, (uchar_t *)sd_inq,
13250 		    sizeof (struct scsi_inquiry), NULL, 0, inq83,
13251 		    (size_t)inq83_len, &devid)) == DDI_SUCCESS) {
13252 			/*
13253 			 * extract GUID from DEVID
13254 			 */
13255 			guid = ddi_devid_to_guid(devid);
13256 
13257 			/*
13258 			 * Do not enable MPXIO if the strlen(guid) is greater
13259 			 * than MPTSAS_MAX_GUID_LEN, this constrain would be
13260 			 * handled by framework later.
13261 			 */
13262 			if (guid && (strlen(guid) > MPTSAS_MAX_GUID_LEN)) {
13263 				ddi_devid_free_guid(guid);
13264 				guid = NULL;
13265 				if (mpt->m_mpxio_enable == TRUE) {
13266 					mptsas_log(mpt, CE_NOTE, "!Target:%x, "
13267 					    "lun:%x doesn't have a valid GUID, "
13268 					    "multipathing for this drive is "
13269 					    "not enabled", target, lun);
13270 				}
13271 			}
13272 
13273 			/*
13274 			 * devid no longer needed
13275 			 */
13276 			ddi_devid_free(devid);
13277 			break;
13278 		} else if (rval == DDI_NOT_WELL_FORMED) {
13279 			/*
13280 			 * return value of ddi_devid_scsi_encode equal to
13281 			 * DDI_NOT_WELL_FORMED means DEVID_RETRY, it worth
13282 			 * to retry inquiry page 0x83 and get GUID.
13283 			 */
13284 			NDBG20(("Not well formed devid, retry..."));
13285 			delay(1 * drv_usectohz(1000000));
13286 			continue;
13287 		} else {
13288 			mptsas_log(mpt, CE_WARN, "!Encode devid failed for "
13289 			    "path target:%x, lun:%x", target, lun);
13290 			rval = DDI_FAILURE;
13291 			goto create_lun;
13292 		}
13293 	}
13294 
13295 	if (i == mptsas_inq83_retry_timeout) {
13296 		mptsas_log(mpt, CE_WARN, "!Repeated page83 requests timeout "
13297 		    "for path target:%x, lun:%x", target, lun);
13298 	}
13299 
13300 	rval = DDI_FAILURE;
13301 
13302 create_lun:
13303 	if ((guid != NULL) && (mpt->m_mpxio_enable == TRUE)) {
13304 		rval = mptsas_create_virt_lun(pdip, sd_inq, guid, lun_dip, &pip,
13305 		    ptgt, lun);
13306 	}
13307 	if (rval != DDI_SUCCESS) {
13308 		rval = mptsas_create_phys_lun(pdip, sd_inq, guid, lun_dip,
13309 		    ptgt, lun);
13310 	}
13311 out:
13312 	if (guid != NULL) {
13313 		/*
13314 		 * guid no longer needed
13315 		 */
13316 		ddi_devid_free_guid(guid);
13317 	}
13318 	if (inq83 != NULL)
13319 		kmem_free(inq83, inq83_len1);
13320 	return (rval);
13321 }
13322 
13323 static int
13324 mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *inq, char *guid,
13325     dev_info_t **lun_dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, int lun)
13326 {
13327 	int			target;
13328 	char			*nodename = NULL;
13329 	char			**compatible = NULL;
13330 	int			ncompatible	= 0;
13331 	int			mdi_rtn = MDI_FAILURE;
13332 	int			rval = DDI_FAILURE;
13333 	char			*old_guid = NULL;
13334 	mptsas_t		*mpt = DIP2MPT(pdip);
13335 	char			*lun_addr = NULL;
13336 	char			*wwn_str = NULL;
13337 	char			*component = NULL;
13338 	uint8_t			phy = 0xFF;
13339 	uint64_t		sas_wwn;
13340 	uint32_t		devinfo;
13341 
13342 	mutex_enter(&mpt->m_mutex);
13343 	target = ptgt->m_devhdl;
13344 	sas_wwn = ptgt->m_sas_wwn;
13345 	devinfo = ptgt->m_deviceinfo;
13346 	phy = ptgt->m_phynum;
13347 	mutex_exit(&mpt->m_mutex);
13348 
13349 	if (sas_wwn) {
13350 		*pip = mptsas_find_path_addr(pdip, sas_wwn, lun);
13351 	} else {
13352 		*pip = mptsas_find_path_phy(pdip, phy);
13353 	}
13354 
13355 	if (*pip != NULL) {
13356 		*lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
13357 		ASSERT(*lun_dip != NULL);
13358 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip,
13359 		    (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM),
13360 		    MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) {
13361 			if (strncmp(guid, old_guid, strlen(guid)) == 0) {
13362 				/*
13363 				 * Same path back online again.
13364 				 */
13365 				(void) ddi_prop_free(old_guid);
13366 				if (!MDI_PI_IS_ONLINE(*pip) &&
13367 				    !MDI_PI_IS_STANDBY(*pip)) {
13368 					rval = mdi_pi_online(*pip, 0);
13369 				} else {
13370 					rval = DDI_SUCCESS;
13371 				}
13372 				if (rval != DDI_SUCCESS) {
13373 					mptsas_log(mpt, CE_WARN, "path:target: "
13374 					    "%x, lun:%x online failed!", target,
13375 					    lun);
13376 					*pip = NULL;
13377 					*lun_dip = NULL;
13378 				}
13379 				return (rval);
13380 			} else {
13381 				/*
13382 				 * The GUID of the LUN has changed which maybe
13383 				 * because customer mapped another volume to the
13384 				 * same LUN.
13385 				 */
13386 				mptsas_log(mpt, CE_WARN, "The GUID of the "
13387 				    "target:%x, lun:%x was changed, maybe "
13388 				    "because someone mapped another volume "
13389 				    "to the same LUN", target, lun);
13390 				(void) ddi_prop_free(old_guid);
13391 				if (!MDI_PI_IS_OFFLINE(*pip)) {
13392 					rval = mdi_pi_offline(*pip, 0);
13393 					if (rval != MDI_SUCCESS) {
13394 						mptsas_log(mpt, CE_WARN, "path:"
13395 						    "target:%x, lun:%x offline "
13396 						    "failed!", target, lun);
13397 						*pip = NULL;
13398 						*lun_dip = NULL;
13399 						return (DDI_FAILURE);
13400 					}
13401 				}
13402 				if (mdi_pi_free(*pip, 0) != MDI_SUCCESS) {
13403 					mptsas_log(mpt, CE_WARN, "path:target:"
13404 					    "%x, lun:%x free failed!", target,
13405 					    lun);
13406 					*pip = NULL;
13407 					*lun_dip = NULL;
13408 					return (DDI_FAILURE);
13409 				}
13410 			}
13411 		} else {
13412 			mptsas_log(mpt, CE_WARN, "Can't get client-guid "
13413 			    "property for path:target:%x, lun:%x", target, lun);
13414 			*pip = NULL;
13415 			*lun_dip = NULL;
13416 			return (DDI_FAILURE);
13417 		}
13418 	}
13419 	scsi_hba_nodename_compatible_get(inq, NULL,
13420 	    inq->inq_dtype, NULL, &nodename, &compatible, &ncompatible);
13421 
13422 	/*
13423 	 * if nodename can't be determined then print a message and skip it
13424 	 */
13425 	if (nodename == NULL) {
13426 		mptsas_log(mpt, CE_WARN, "mptsas driver found no compatible "
13427 		    "driver for target%d lun %d dtype:0x%02x", target, lun,
13428 		    inq->inq_dtype);
13429 		return (DDI_FAILURE);
13430 	}
13431 
13432 	wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP);
13433 	/* The property is needed by MPAPI */
13434 	(void) sprintf(wwn_str, "%016"PRIx64, sas_wwn);
13435 
13436 	lun_addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
13437 	if (sas_wwn)
13438 		(void) sprintf(lun_addr, "w%s,%x", wwn_str, lun);
13439 	else
13440 		(void) sprintf(lun_addr, "p%x,%x", phy, lun);
13441 
13442 	mdi_rtn = mdi_pi_alloc_compatible(pdip, nodename,
13443 	    guid, lun_addr, compatible, ncompatible,
13444 	    0, pip);
13445 	if (mdi_rtn == MDI_SUCCESS) {
13446 
13447 		if (mdi_prop_update_string(*pip, MDI_GUID,
13448 		    guid) != DDI_SUCCESS) {
13449 			mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
13450 			    "create property for target %d lun %d (MDI_GUID)",
13451 			    target, lun);
13452 			mdi_rtn = MDI_FAILURE;
13453 			goto virt_create_done;
13454 		}
13455 
13456 		if (mdi_prop_update_int(*pip, LUN_PROP,
13457 		    lun) != DDI_SUCCESS) {
13458 			mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
13459 			    "create property for target %d lun %d (LUN_PROP)",
13460 			    target, lun);
13461 			mdi_rtn = MDI_FAILURE;
13462 			goto virt_create_done;
13463 		}
13464 		if (mdi_prop_update_string_array(*pip, "compatible",
13465 		    compatible, ncompatible) !=
13466 		    DDI_PROP_SUCCESS) {
13467 			mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
13468 			    "create property for target %d lun %d (COMPATIBLE)",
13469 			    target, lun);
13470 			mdi_rtn = MDI_FAILURE;
13471 			goto virt_create_done;
13472 		}
13473 		if (sas_wwn && (mdi_prop_update_string(*pip,
13474 		    SCSI_ADDR_PROP_TARGET_PORT, wwn_str) != DDI_PROP_SUCCESS)) {
13475 			mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
13476 			    "create property for target %d lun %d "
13477 			    "(target-port)", target, lun);
13478 			mdi_rtn = MDI_FAILURE;
13479 			goto virt_create_done;
13480 		} else if ((sas_wwn == 0) && (mdi_prop_update_int(*pip,
13481 		    "sata-phy", phy) != DDI_PROP_SUCCESS)) {
13482 			/*
13483 			 * Direct attached SATA device without DeviceName
13484 			 */
13485 			mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
13486 			    "create property for SAS target %d lun %d "
13487 			    "(sata-phy)", target, lun);
13488 			mdi_rtn = NDI_FAILURE;
13489 			goto virt_create_done;
13490 		}
13491 
13492 		if (inq->inq_dtype == 0) {
13493 			component = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
13494 			/*
13495 			 * set obp path for pathinfo
13496 			 */
13497 			(void) snprintf(component, MAXPATHLEN,
13498 			    "disk@%s", lun_addr);
13499 
13500 			if (mdi_pi_pathname_obp_set(*pip, component) !=
13501 			    DDI_SUCCESS) {
13502 				mptsas_log(mpt, CE_WARN, "mpt_sas driver "
13503 				    "unable to set obp-path for object %s",
13504 				    component);
13505 				mdi_rtn = MDI_FAILURE;
13506 				goto virt_create_done;
13507 			}
13508 		}
13509 
13510 		*lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
13511 		if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
13512 		    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
13513 			if ((ndi_prop_update_int(DDI_DEV_T_NONE, *lun_dip,
13514 			    "pm-capable", 1)) !=
13515 			    DDI_PROP_SUCCESS) {
13516 				mptsas_log(mpt, CE_WARN, "mptsas driver"
13517 				    "failed to create pm-capable "
13518 				    "property, target %d", target);
13519 				mdi_rtn = MDI_FAILURE;
13520 				goto virt_create_done;
13521 			}
13522 		}
13523 		NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr));
13524 		mdi_rtn = mdi_pi_online(*pip, 0);
13525 		if (mdi_rtn == MDI_NOT_SUPPORTED) {
13526 			mdi_rtn = MDI_FAILURE;
13527 		}
13528 virt_create_done:
13529 		if (*pip && mdi_rtn != MDI_SUCCESS) {
13530 			(void) mdi_pi_free(*pip, 0);
13531 			*pip = NULL;
13532 			*lun_dip = NULL;
13533 		}
13534 	}
13535 
13536 	scsi_hba_nodename_compatible_free(nodename, compatible);
13537 	if (lun_addr != NULL) {
13538 		kmem_free(lun_addr, SCSI_MAXNAMELEN);
13539 	}
13540 	if (wwn_str != NULL) {
13541 		kmem_free(wwn_str, MPTSAS_WWN_STRLEN);
13542 	}
13543 	if (component != NULL) {
13544 		kmem_free(component, MAXPATHLEN);
13545 	}
13546 
13547 	return ((mdi_rtn == MDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
13548 }
13549 
13550 static int
13551 mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *inq,
13552     char *guid, dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun)
13553 {
13554 	int			target;
13555 	int			ndi_rtn = NDI_FAILURE;
13556 	uint64_t		be_sas_wwn;
13557 	char			*nodename = NULL;
13558 	char			**compatible = NULL;
13559 	int			ncompatible = 0;
13560 	int			instance = 0;
13561 	mptsas_t		*mpt = DIP2MPT(pdip);
13562 	char			*wwn_str = NULL;
13563 	char			*component = NULL;
13564 	uint8_t			phy = 0xFF;
13565 	uint64_t		sas_wwn;
13566 	uint32_t		devinfo;
13567 
13568 	mutex_enter(&mpt->m_mutex);
13569 	target = ptgt->m_devhdl;
13570 	sas_wwn = ptgt->m_sas_wwn;
13571 	devinfo = ptgt->m_deviceinfo;
13572 	phy = ptgt->m_phynum;
13573 	mutex_exit(&mpt->m_mutex);
13574 
13575 	/*
13576 	 * generate compatible property with binding-set "mpt"
13577 	 */
13578 	scsi_hba_nodename_compatible_get(inq, NULL, inq->inq_dtype, NULL,
13579 	    &nodename, &compatible, &ncompatible);
13580 
13581 	/*
13582 	 * if nodename can't be determined then print a message and skip it
13583 	 */
13584 	if (nodename == NULL) {
13585 		mptsas_log(mpt, CE_WARN, "mptsas found no compatible driver "
13586 		    "for target %d lun %d", target, lun);
13587 		return (DDI_FAILURE);
13588 	}
13589 
13590 	ndi_rtn = ndi_devi_alloc(pdip, nodename,
13591 	    DEVI_SID_NODEID, lun_dip);
13592 
13593 	/*
13594 	 * if lun alloc success, set props
13595 	 */
13596 	if (ndi_rtn == NDI_SUCCESS) {
13597 
13598 		if (ndi_prop_update_int(DDI_DEV_T_NONE,
13599 		    *lun_dip, LUN_PROP, lun) !=
13600 		    DDI_PROP_SUCCESS) {
13601 			mptsas_log(mpt, CE_WARN, "mptsas unable to create "
13602 			    "property for target %d lun %d (LUN_PROP)",
13603 			    target, lun);
13604 			ndi_rtn = NDI_FAILURE;
13605 			goto phys_create_done;
13606 		}
13607 
13608 		if (ndi_prop_update_string_array(DDI_DEV_T_NONE,
13609 		    *lun_dip, "compatible", compatible, ncompatible)
13610 		    != DDI_PROP_SUCCESS) {
13611 			mptsas_log(mpt, CE_WARN, "mptsas unable to create "
13612 			    "property for target %d lun %d (COMPATIBLE)",
13613 			    target, lun);
13614 			ndi_rtn = NDI_FAILURE;
13615 			goto phys_create_done;
13616 		}
13617 
13618 		/*
13619 		 * We need the SAS WWN for non-multipath devices, so
13620 		 * we'll use the same property as that multipathing
13621 		 * devices need to present for MPAPI. If we don't have
13622 		 * a WWN (e.g. parallel SCSI), don't create the prop.
13623 		 */
13624 		wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP);
13625 		(void) sprintf(wwn_str, "%016"PRIx64, sas_wwn);
13626 		if (sas_wwn && ndi_prop_update_string(DDI_DEV_T_NONE,
13627 		    *lun_dip, SCSI_ADDR_PROP_TARGET_PORT, wwn_str)
13628 		    != DDI_PROP_SUCCESS) {
13629 			mptsas_log(mpt, CE_WARN, "mptsas unable to "
13630 			    "create property for SAS target %d lun %d "
13631 			    "(target-port)", target, lun);
13632 			ndi_rtn = NDI_FAILURE;
13633 			goto phys_create_done;
13634 		}
13635 		be_sas_wwn = BE_64(sas_wwn);
13636 		if (sas_wwn && ndi_prop_update_byte_array(
13637 		    DDI_DEV_T_NONE, *lun_dip, "port-wwn",
13638 		    (uchar_t *)&be_sas_wwn, 8) != DDI_PROP_SUCCESS) {
13639 			mptsas_log(mpt, CE_WARN, "mptsas unable to "
13640 			    "create property for SAS target %d lun %d "
13641 			    "(port-wwn)", target, lun);
13642 			ndi_rtn = NDI_FAILURE;
13643 			goto phys_create_done;
13644 		} else if ((sas_wwn == 0) && (ndi_prop_update_int(
13645 		    DDI_DEV_T_NONE, *lun_dip, "sata-phy", phy) !=
13646 		    DDI_PROP_SUCCESS)) {
13647 			/*
13648 			 * Direct attached SATA device without DeviceName
13649 			 */
13650 			mptsas_log(mpt, CE_WARN, "mptsas unable to "
13651 			    "create property for SAS target %d lun %d "
13652 			    "(sata-phy)", target, lun);
13653 			ndi_rtn = NDI_FAILURE;
13654 			goto phys_create_done;
13655 		}
13656 		if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
13657 		    *lun_dip, SAS_PROP) != DDI_PROP_SUCCESS) {
13658 			mptsas_log(mpt, CE_WARN, "mptsas unable to"
13659 			    "create property for SAS target %d lun %d"
13660 			    " (SAS_PROP)", target, lun);
13661 			ndi_rtn = NDI_FAILURE;
13662 			goto phys_create_done;
13663 		}
13664 		if (guid && (ndi_prop_update_string(DDI_DEV_T_NONE,
13665 		    *lun_dip, NDI_GUID, guid) != DDI_SUCCESS)) {
13666 			mptsas_log(mpt, CE_WARN, "mptsas unable "
13667 			    "to create guid property for target %d "
13668 			    "lun %d", target, lun);
13669 			ndi_rtn = NDI_FAILURE;
13670 			goto phys_create_done;
13671 		}
13672 
13673 		/*
13674 		 * if this is a SAS controller, and the target is a SATA
13675 		 * drive, set the 'pm-capable' property for sd and if on
13676 		 * an OPL platform, also check if this is an ATAPI
13677 		 * device.
13678 		 */
13679 		instance = ddi_get_instance(mpt->m_dip);
13680 		if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
13681 		    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
13682 			NDBG2(("mptsas%d: creating pm-capable property, "
13683 			    "target %d", instance, target));
13684 
13685 			if ((ndi_prop_update_int(DDI_DEV_T_NONE,
13686 			    *lun_dip, "pm-capable", 1)) !=
13687 			    DDI_PROP_SUCCESS) {
13688 				mptsas_log(mpt, CE_WARN, "mptsas "
13689 				    "failed to create pm-capable "
13690 				    "property, target %d", target);
13691 				ndi_rtn = NDI_FAILURE;
13692 				goto phys_create_done;
13693 			}
13694 
13695 		}
13696 
13697 		if (inq->inq_dtype == 0) {
13698 			/*
13699 			 * add 'obp-path' properties for devinfo
13700 			 */
13701 			component = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
13702 			if (sas_wwn) {
13703 				(void) snprintf(component, MAXPATHLEN,
13704 				    "disk@w%s,%x", wwn_str, lun);
13705 			} else {
13706 				(void) snprintf(component, MAXPATHLEN,
13707 				    "disk@p%x,%x", phy, lun);
13708 			}
13709 			if (ddi_pathname_obp_set(*lun_dip, component)
13710 			    != DDI_SUCCESS) {
13711 				mptsas_log(mpt, CE_WARN, "mpt_sas driver "
13712 				    "unable to set obp-path for SAS "
13713 				    "object %s", component);
13714 				ndi_rtn = NDI_FAILURE;
13715 				goto phys_create_done;
13716 			}
13717 		}
13718 
13719 phys_create_done:
13720 		/*
13721 		 * If props were setup ok, online the lun
13722 		 */
13723 		if (ndi_rtn == NDI_SUCCESS) {
13724 			/*
13725 			 * Try to online the new node
13726 			 */
13727 			ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH);
13728 		}
13729 
13730 		/*
13731 		 * If success set rtn flag, else unwire alloc'd lun
13732 		 */
13733 		if (ndi_rtn != NDI_SUCCESS) {
13734 			NDBG12(("mptsas driver unable to online "
13735 			    "target %d lun %d", target, lun));
13736 			ndi_prop_remove_all(*lun_dip);
13737 			(void) ndi_devi_free(*lun_dip);
13738 			*lun_dip = NULL;
13739 		}
13740 	}
13741 
13742 	scsi_hba_nodename_compatible_free(nodename, compatible);
13743 
13744 	if (wwn_str != NULL) {
13745 		kmem_free(wwn_str, MPTSAS_WWN_STRLEN);
13746 	}
13747 	if (component != NULL) {
13748 		kmem_free(component, MAXPATHLEN);
13749 	}
13750 
13751 	return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
13752 }
13753 
13754 static int
13755 mptsas_probe_smp(dev_info_t *pdip, uint64_t wwn)
13756 {
13757 	mptsas_t	*mpt = DIP2MPT(pdip);
13758 	struct smp_device smp_sd;
13759 
13760 	/* XXX An HBA driver should not be allocating an smp_device. */
13761 	bzero(&smp_sd, sizeof (struct smp_device));
13762 	smp_sd.smp_sd_address.smp_a_hba_tran = mpt->m_smptran;
13763 	bcopy(&wwn, smp_sd.smp_sd_address.smp_a_wwn, SAS_WWN_BYTE_SIZE);
13764 
13765 	if (smp_probe(&smp_sd) != DDI_PROBE_SUCCESS)
13766 		return (NDI_FAILURE);
13767 	return (NDI_SUCCESS);
13768 }
13769 
13770 static int
13771 mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, dev_info_t **smp_dip)
13772 {
13773 	mptsas_t	*mpt = DIP2MPT(pdip);
13774 	mptsas_smp_t	*psmp = NULL;
13775 	int		rval;
13776 	int		phymask;
13777 
13778 	/*
13779 	 * Get the physical port associated to the iport
13780 	 * PHYMASK TODO
13781 	 */
13782 	phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
13783 	    "phymask", 0);
13784 	/*
13785 	 * Find the smp node in hash table with specified sas address and
13786 	 * physical port
13787 	 */
13788 	psmp = mptsas_wwid_to_psmp(mpt, phymask, sas_wwn);
13789 	if (psmp == NULL) {
13790 		return (DDI_FAILURE);
13791 	}
13792 
13793 	rval = mptsas_online_smp(pdip, psmp, smp_dip);
13794 
13795 	return (rval);
13796 }
13797 
13798 static int
13799 mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
13800     dev_info_t **smp_dip)
13801 {
13802 	char		wwn_str[MPTSAS_WWN_STRLEN];
13803 	int		ndi_rtn = NDI_FAILURE;
13804 	mptsas_t	*mpt = DIP2MPT(pdip);
13805 
13806 	(void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr);
13807 
13808 	/*
13809 	 * Probe smp device, prevent the node of removed device from being
13810 	 * configured succesfully
13811 	 */
13812 	if (mptsas_probe_smp(pdip, smp_node->m_sasaddr) != NDI_SUCCESS) {
13813 		return (DDI_FAILURE);
13814 	}
13815 
13816 	if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) {
13817 		return (DDI_SUCCESS);
13818 	}
13819 
13820 	ndi_rtn = ndi_devi_alloc(pdip, "smp", DEVI_SID_NODEID, smp_dip);
13821 
13822 	/*
13823 	 * if lun alloc success, set props
13824 	 */
13825 	if (ndi_rtn == NDI_SUCCESS) {
13826 		/*
13827 		 * Set the flavor of the child to be SMP flavored
13828 		 */
13829 		ndi_flavor_set(*smp_dip, SCSA_FLAVOR_SMP);
13830 
13831 		if (ndi_prop_update_string(DDI_DEV_T_NONE,
13832 		    *smp_dip, SMP_WWN, wwn_str) !=
13833 		    DDI_PROP_SUCCESS) {
13834 			mptsas_log(mpt, CE_WARN, "mptsas unable to create "
13835 			    "property for smp device %s (sas_wwn)",
13836 			    wwn_str);
13837 			ndi_rtn = NDI_FAILURE;
13838 			goto smp_create_done;
13839 		}
13840 
13841 		if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
13842 		    *smp_dip, SMP_PROP) != DDI_PROP_SUCCESS) {
13843 			mptsas_log(mpt, CE_WARN, "mptsas unable to "
13844 			    "create property for SMP %s (SMP_PROP) ",
13845 			    wwn_str);
13846 			ndi_rtn = NDI_FAILURE;
13847 			goto smp_create_done;
13848 		}
13849 
13850 smp_create_done:
13851 		/*
13852 		 * If props were setup ok, online the lun
13853 		 */
13854 		if (ndi_rtn == NDI_SUCCESS) {
13855 			/*
13856 			 * Try to online the new node
13857 			 */
13858 			ndi_rtn = ndi_devi_online(*smp_dip, NDI_ONLINE_ATTACH);
13859 		}
13860 
13861 		/*
13862 		 * If success set rtn flag, else unwire alloc'd lun
13863 		 */
13864 		if (ndi_rtn != NDI_SUCCESS) {
13865 			NDBG12(("mptsas unable to online "
13866 			    "SMP target %s", wwn_str));
13867 			ndi_prop_remove_all(*smp_dip);
13868 			(void) ndi_devi_free(*smp_dip);
13869 		}
13870 	}
13871 
13872 	return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
13873 }
13874 
13875 /* smp transport routine */
13876 static int mptsas_smp_start(struct smp_pkt *smp_pkt)
13877 {
13878 	uint64_t			wwn;
13879 	Mpi2SmpPassthroughRequest_t	req;
13880 	Mpi2SmpPassthroughReply_t	rep;
13881 	uint32_t			direction = 0;
13882 	mptsas_t			*mpt;
13883 	int				ret;
13884 	uint64_t			tmp64;
13885 
13886 	mpt = (mptsas_t *)smp_pkt->smp_pkt_address->
13887 	    smp_a_hba_tran->smp_tran_hba_private;
13888 
13889 	bcopy(smp_pkt->smp_pkt_address->smp_a_wwn, &wwn, SAS_WWN_BYTE_SIZE);
13890 	/*
13891 	 * Need to compose a SMP request message
13892 	 * and call mptsas_do_passthru() function
13893 	 */
13894 	bzero(&req, sizeof (req));
13895 	bzero(&rep, sizeof (rep));
13896 	req.PassthroughFlags = 0;
13897 	req.PhysicalPort = 0xff;
13898 	req.ChainOffset = 0;
13899 	req.Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
13900 
13901 	if ((smp_pkt->smp_pkt_reqsize & 0xffff0000ul) != 0) {
13902 		smp_pkt->smp_pkt_reason = ERANGE;
13903 		return (DDI_FAILURE);
13904 	}
13905 	req.RequestDataLength = LE_16((uint16_t)(smp_pkt->smp_pkt_reqsize - 4));
13906 
13907 	req.MsgFlags = 0;
13908 	tmp64 = LE_64(wwn);
13909 	bcopy(&tmp64, &req.SASAddress, SAS_WWN_BYTE_SIZE);
13910 	if (smp_pkt->smp_pkt_rspsize > 0) {
13911 		direction |= MPTSAS_PASS_THRU_DIRECTION_READ;
13912 	}
13913 	if (smp_pkt->smp_pkt_reqsize > 0) {
13914 		direction |= MPTSAS_PASS_THRU_DIRECTION_WRITE;
13915 	}
13916 
13917 	mutex_enter(&mpt->m_mutex);
13918 	ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep,
13919 	    (uint8_t *)smp_pkt->smp_pkt_rsp,
13920 	    offsetof(Mpi2SmpPassthroughRequest_t, SGL), sizeof (rep),
13921 	    smp_pkt->smp_pkt_rspsize - 4, direction,
13922 	    (uint8_t *)smp_pkt->smp_pkt_req, smp_pkt->smp_pkt_reqsize - 4,
13923 	    smp_pkt->smp_pkt_timeout, FKIOCTL);
13924 	mutex_exit(&mpt->m_mutex);
13925 	if (ret != 0) {
13926 		cmn_err(CE_WARN, "smp_start do passthru error %d", ret);
13927 		smp_pkt->smp_pkt_reason = (uchar_t)(ret);
13928 		return (DDI_FAILURE);
13929 	}
13930 	/* do passthrough success, check the smp status */
13931 	if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
13932 		switch (LE_16(rep.IOCStatus)) {
13933 		case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
13934 			smp_pkt->smp_pkt_reason = ENODEV;
13935 			break;
13936 		case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN:
13937 			smp_pkt->smp_pkt_reason = EOVERFLOW;
13938 			break;
13939 		case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED:
13940 			smp_pkt->smp_pkt_reason = EIO;
13941 			break;
13942 		default:
13943 			mptsas_log(mpt, CE_NOTE, "smp_start: get unknown ioc"
13944 			    "status:%x", LE_16(rep.IOCStatus));
13945 			smp_pkt->smp_pkt_reason = EIO;
13946 			break;
13947 		}
13948 		return (DDI_FAILURE);
13949 	}
13950 	if (rep.SASStatus != MPI2_SASSTATUS_SUCCESS) {
13951 		mptsas_log(mpt, CE_NOTE, "smp_start: get error SAS status:%x",
13952 		    rep.SASStatus);
13953 		smp_pkt->smp_pkt_reason = EIO;
13954 		return (DDI_FAILURE);
13955 	}
13956 
13957 	return (DDI_SUCCESS);
13958 }
13959 
13960 static void
13961 mptsas_idle_pm(void *arg)
13962 {
13963 	mptsas_t	*mpt = arg;
13964 
13965 	(void) pm_idle_component(mpt->m_dip, 0);
13966 	mutex_enter(&mpt->m_mutex);
13967 	mpt->m_pm_timeid = 0;
13968 	mutex_exit(&mpt->m_mutex);
13969 }
13970 
13971 /*
13972  * If we didn't get a match, we need to get sas page0 for each device, and
13973  * untill we get a match. If failed, return NULL
13974  * TODO should be implemented similar to mptsas_wwid_to_ptgt?
13975  */
13976 static mptsas_target_t *
13977 mptsas_phy_to_tgt(dev_info_t *pdip, uint8_t phy)
13978 {
13979 	int		i, j = 0;
13980 	int		rval = 0;
13981 	uint16_t	cur_handle;
13982 	uint32_t	page_address;
13983 	mptsas_target_t	*ptgt = NULL;
13984 	mptsas_t	*mpt = DIP2MPT(pdip);
13985 	int		phymask;
13986 
13987 	/*
13988 	 * Get the physical port associated to the iport
13989 	 */
13990 	phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
13991 	    "phymask", 0);
13992 
13993 	if (phymask == 0)
13994 		return (NULL);
13995 
13996 	/*
13997 	 * PHY named device must be direct attached and attaches to
13998 	 * narrow port, if the iport is not parent of the device which
13999 	 * we are looking for.
14000 	 */
14001 	for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
14002 		if ((1 << i) & phymask)
14003 			j++;
14004 	}
14005 
14006 	if (j > 1)
14007 		return (NULL);
14008 
14009 	/*
14010 	 * Must be a narrow port and single device attached to the narrow port
14011 	 * So the physical port num of device  which is equal to the iport's
14012 	 * port num is the device what we are looking for.
14013 	 */
14014 
14015 	if (mpt->m_phy_info[phy].phy_mask != phymask)
14016 		return (NULL);
14017 
14018 	mutex_enter(&mpt->m_mutex);
14019 
14020 	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
14021 	    MPTSAS_HASH_FIRST);
14022 	while (ptgt != NULL) {
14023 			if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) {
14024 			mutex_exit(&mpt->m_mutex);
14025 			return (ptgt);
14026 		}
14027 
14028 		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
14029 		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
14030 	}
14031 
14032 	if (mpt->m_done_traverse_dev) {
14033 		mutex_exit(&mpt->m_mutex);
14034 		return (NULL);
14035 	}
14036 
14037 	/* If didn't get a match, come here */
14038 	cur_handle = mpt->m_dev_handle;
14039 	for (; ; ) {
14040 		ptgt = NULL;
14041 		page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
14042 		    MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)cur_handle;
14043 		rval = mptsas_get_target_device_info(mpt, page_address,
14044 		    &cur_handle, &ptgt);
14045 		if ((rval == DEV_INFO_FAIL_PAGE0) ||
14046 		    (rval == DEV_INFO_FAIL_ALLOC)) {
14047 			break;
14048 		}
14049 		if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
14050 		    (rval == DEV_INFO_PHYS_DISK)) {
14051 			continue;
14052 		}
14053 		mpt->m_dev_handle = cur_handle;
14054 
14055 		if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) {
14056 			break;
14057 		}
14058 	}
14059 
14060 	mutex_exit(&mpt->m_mutex);
14061 	return (ptgt);
14062 }
14063 
14064 /*
14065  * The ptgt->m_sas_wwn contains the wwid for each disk.
14066  * For Raid volumes, we need to check m_raidvol[x].m_raidwwid
14067  * If we didn't get a match, we need to get sas page0 for each device, and
14068  * untill we get a match
14069  * If failed, return NULL
14070  */
14071 static mptsas_target_t *
14072 mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask, uint64_t wwid)
14073 {
14074 	int		rval = 0;
14075 	uint16_t	cur_handle;
14076 	uint32_t	page_address;
14077 	mptsas_target_t	*tmp_tgt = NULL;
14078 
14079 	mutex_enter(&mpt->m_mutex);
14080 	tmp_tgt = (struct mptsas_target *)mptsas_hash_search(
14081 	    &mpt->m_active->m_tgttbl, wwid, phymask);
14082 	if (tmp_tgt != NULL) {
14083 		mutex_exit(&mpt->m_mutex);
14084 		return (tmp_tgt);
14085 	}
14086 
14087 	if (phymask == 0) {
14088 		/*
14089 		 * It's IR volume
14090 		 */
14091 		rval = mptsas_get_raid_info(mpt);
14092 		if (rval) {
14093 			tmp_tgt = (struct mptsas_target *)mptsas_hash_search(
14094 			    &mpt->m_active->m_tgttbl, wwid, phymask);
14095 		}
14096 		mutex_exit(&mpt->m_mutex);
14097 		return (tmp_tgt);
14098 	}
14099 
14100 	if (mpt->m_done_traverse_dev) {
14101 		mutex_exit(&mpt->m_mutex);
14102 		return (NULL);
14103 	}
14104 
14105 	/* If didn't get a match, come here */
14106 	cur_handle = mpt->m_dev_handle;
14107 	for (; ; ) {
14108 		tmp_tgt = NULL;
14109 		page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
14110 		    MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle;
14111 		rval = mptsas_get_target_device_info(mpt, page_address,
14112 		    &cur_handle, &tmp_tgt);
14113 		if ((rval == DEV_INFO_FAIL_PAGE0) ||
14114 		    (rval == DEV_INFO_FAIL_ALLOC)) {
14115 			tmp_tgt = NULL;
14116 			break;
14117 		}
14118 		if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
14119 		    (rval == DEV_INFO_PHYS_DISK)) {
14120 			continue;
14121 		}
14122 		mpt->m_dev_handle = cur_handle;
14123 		if ((tmp_tgt->m_sas_wwn) && (tmp_tgt->m_sas_wwn == wwid) &&
14124 		    (tmp_tgt->m_phymask == phymask)) {
14125 			break;
14126 		}
14127 	}
14128 
14129 	mutex_exit(&mpt->m_mutex);
14130 	return (tmp_tgt);
14131 }
14132 
14133 static mptsas_smp_t *
14134 mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask, uint64_t wwid)
14135 {
14136 	int		rval = 0;
14137 	uint16_t	cur_handle;
14138 	uint32_t	page_address;
14139 	mptsas_smp_t	smp_node, *psmp = NULL;
14140 
14141 	mutex_enter(&mpt->m_mutex);
14142 	psmp = (struct mptsas_smp *)mptsas_hash_search(&mpt->m_active->m_smptbl,
14143 	    wwid, phymask);
14144 	if (psmp != NULL) {
14145 		mutex_exit(&mpt->m_mutex);
14146 		return (psmp);
14147 	}
14148 
14149 	if (mpt->m_done_traverse_smp) {
14150 		mutex_exit(&mpt->m_mutex);
14151 		return (NULL);
14152 	}
14153 
14154 	/* If didn't get a match, come here */
14155 	cur_handle = mpt->m_smp_devhdl;
14156 	for (; ; ) {
14157 		psmp = NULL;
14158 		page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
14159 		    MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle;
14160 		rval = mptsas_get_sas_expander_page0(mpt, page_address,
14161 		    &smp_node);
14162 		if (rval != DDI_SUCCESS) {
14163 			break;
14164 		}
14165 		mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl;
14166 		psmp = mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node);
14167 		ASSERT(psmp);
14168 		if ((psmp->m_sasaddr) && (psmp->m_sasaddr == wwid) &&
14169 		    (psmp->m_phymask == phymask)) {
14170 			break;
14171 		}
14172 	}
14173 
14174 	mutex_exit(&mpt->m_mutex);
14175 	return (psmp);
14176 }
14177 
14178 /* helper functions using hash */
14179 
14180 /*
14181  * Can't have duplicate entries for same devhdl,
14182  * if there are invalid entries, the devhdl should be set to 0xffff
14183  */
14184 static void *
14185 mptsas_search_by_devhdl(mptsas_hash_table_t *hashtab, uint16_t devhdl)
14186 {
14187 	mptsas_hash_data_t *data;
14188 
14189 	data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST);
14190 	while (data != NULL) {
14191 		if (data->devhdl == devhdl) {
14192 			break;
14193 		}
14194 		data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT);
14195 	}
14196 	return (data);
14197 }
14198 
14199 mptsas_target_t *
14200 mptsas_tgt_alloc(mptsas_hash_table_t *hashtab, uint16_t devhdl, uint64_t wwid,
14201     uint32_t devinfo, uint8_t phymask, uint8_t phynum)
14202 {
14203 	mptsas_target_t *tmp_tgt = NULL;
14204 
14205 	tmp_tgt = mptsas_hash_search(hashtab, wwid, phymask);
14206 	if (tmp_tgt != NULL) {
14207 		NDBG20(("Hash item already exist"));
14208 		tmp_tgt->m_deviceinfo = devinfo;
14209 		tmp_tgt->m_devhdl = devhdl;
14210 		return (tmp_tgt);
14211 	}
14212 	tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP);
14213 	if (tmp_tgt == NULL) {
14214 		cmn_err(CE_WARN, "Fatal, allocated tgt failed");
14215 		return (NULL);
14216 	}
14217 	tmp_tgt->m_devhdl = devhdl;
14218 	tmp_tgt->m_sas_wwn = wwid;
14219 	tmp_tgt->m_deviceinfo = devinfo;
14220 	tmp_tgt->m_phymask = phymask;
14221 	tmp_tgt->m_phynum = phynum;
14222 	/* Initialized the tgt structure */
14223 	tmp_tgt->m_qfull_retries = QFULL_RETRIES;
14224 	tmp_tgt->m_qfull_retry_interval =
14225 	    drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
14226 	tmp_tgt->m_t_throttle = MAX_THROTTLE;
14227 
14228 	mptsas_hash_add(hashtab, tmp_tgt);
14229 
14230 	return (tmp_tgt);
14231 }
14232 
14233 static void
14234 mptsas_tgt_free(mptsas_hash_table_t *hashtab, uint64_t wwid, uint8_t phymask)
14235 {
14236 	mptsas_target_t *tmp_tgt;
14237 	tmp_tgt = mptsas_hash_rem(hashtab, wwid, phymask);
14238 	if (tmp_tgt == NULL) {
14239 		cmn_err(CE_WARN, "Tgt not found, nothing to free");
14240 	} else {
14241 		kmem_free(tmp_tgt, sizeof (struct mptsas_target));
14242 	}
14243 }
14244 
14245 /*
14246  * Return the entry in the hash table
14247  */
14248 static mptsas_smp_t *
14249 mptsas_smp_alloc(mptsas_hash_table_t *hashtab, mptsas_smp_t *data)
14250 {
14251 	uint64_t key1 = data->m_sasaddr;
14252 	uint8_t key2 = data->m_phymask;
14253 	mptsas_smp_t *ret_data;
14254 
14255 	ret_data = mptsas_hash_search(hashtab, key1, key2);
14256 	if (ret_data != NULL) {
14257 		bcopy(data, ret_data, sizeof (mptsas_smp_t));
14258 		return (ret_data);
14259 	}
14260 
14261 	ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP);
14262 	bcopy(data, ret_data, sizeof (mptsas_smp_t));
14263 	mptsas_hash_add(hashtab, ret_data);
14264 	return (ret_data);
14265 }
14266 
14267 static void
14268 mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid, uint8_t phymask)
14269 {
14270 	mptsas_smp_t *tmp_smp;
14271 	tmp_smp = mptsas_hash_rem(hashtab, wwid, phymask);
14272 	if (tmp_smp == NULL) {
14273 		cmn_err(CE_WARN, "Smp element not found, nothing to free");
14274 	} else {
14275 		kmem_free(tmp_smp, sizeof (struct mptsas_smp));
14276 	}
14277 }
14278 
14279 /*
14280  * Hash operation functions
14281  * key1 is the sas_wwn, key2 is the phymask
14282  */
14283 static void
14284 mptsas_hash_init(mptsas_hash_table_t *hashtab)
14285 {
14286 	if (hashtab == NULL) {
14287 		return;
14288 	}
14289 	bzero(hashtab->head, sizeof (mptsas_hash_node_t) *
14290 	    MPTSAS_HASH_ARRAY_SIZE);
14291 	hashtab->cur = NULL;
14292 	hashtab->line = 0;
14293 }
14294 
14295 static void
14296 mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen)
14297 {
14298 	uint16_t line = 0;
14299 	mptsas_hash_node_t *cur = NULL, *last = NULL;
14300 
14301 	if (hashtab == NULL) {
14302 		return;
14303 	}
14304 	for (line = 0; line < MPTSAS_HASH_ARRAY_SIZE; line++) {
14305 		cur = hashtab->head[line];
14306 		while (cur != NULL) {
14307 			last = cur;
14308 			cur = cur->next;
14309 			kmem_free(last->data, datalen);
14310 			kmem_free(last, sizeof (mptsas_hash_node_t));
14311 		}
14312 	}
14313 }
14314 
14315 /*
14316  * You must guarantee the element doesn't exist in the hash table
14317  * before you call mptsas_hash_add()
14318  */
14319 static void
14320 mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data)
14321 {
14322 	uint64_t key1 = ((mptsas_hash_data_t *)data)->key1;
14323 	uint8_t	key2 = ((mptsas_hash_data_t *)data)->key2;
14324 	mptsas_hash_node_t **head = NULL;
14325 	mptsas_hash_node_t *node = NULL;
14326 
14327 	if (hashtab == NULL) {
14328 		return;
14329 	}
14330 	ASSERT(mptsas_hash_search(hashtab, key1, key2) == NULL);
14331 	node = kmem_zalloc(sizeof (mptsas_hash_node_t), KM_NOSLEEP);
14332 	node->data = data;
14333 
14334 	head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]);
14335 	if (*head == NULL) {
14336 		*head = node;
14337 	} else {
14338 		node->next = *head;
14339 		*head = node;
14340 	}
14341 }
14342 
14343 static void *
14344 mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1, uint8_t key2)
14345 {
14346 	mptsas_hash_node_t **head = NULL;
14347 	mptsas_hash_node_t *last = NULL, *cur = NULL;
14348 	mptsas_hash_data_t *data;
14349 	if (hashtab == NULL) {
14350 		return (NULL);
14351 	}
14352 	head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]);
14353 	cur = *head;
14354 	while (cur != NULL) {
14355 		data = cur->data;
14356 		if ((data->key1 == key1) && (data->key2 == key2)) {
14357 			if (last == NULL) {
14358 				(*head) = cur->next;
14359 			} else {
14360 				last->next = cur->next;
14361 			}
14362 			kmem_free(cur, sizeof (mptsas_hash_node_t));
14363 			return (data);
14364 		} else {
14365 			last = cur;
14366 			cur = cur->next;
14367 		}
14368 	}
14369 	return (NULL);
14370 }
14371 
14372 static void *
14373 mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1, uint8_t key2)
14374 {
14375 	mptsas_hash_node_t *cur = NULL;
14376 	mptsas_hash_data_t *data;
14377 	if (hashtab == NULL) {
14378 		return (NULL);
14379 	}
14380 	cur = hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE];
14381 	while (cur != NULL) {
14382 		data = cur->data;
14383 		if ((data->key1 == key1) && (data->key2 == key2)) {
14384 			return (data);
14385 		} else {
14386 			cur = cur->next;
14387 		}
14388 	}
14389 	return (NULL);
14390 }
14391 
14392 static void *
14393 mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos)
14394 {
14395 	mptsas_hash_node_t *this = NULL;
14396 
14397 	if (hashtab == NULL) {
14398 		return (NULL);
14399 	}
14400 
14401 	if (pos == MPTSAS_HASH_FIRST) {
14402 		hashtab->line = 0;
14403 		hashtab->cur = NULL;
14404 		this = hashtab->head[0];
14405 	} else {
14406 		if (hashtab->cur == NULL) {
14407 			return (NULL);
14408 		} else {
14409 			this = hashtab->cur->next;
14410 		}
14411 	}
14412 
14413 	while (this == NULL) {
14414 		hashtab->line++;
14415 		if (hashtab->line >= MPTSAS_HASH_ARRAY_SIZE) {
14416 			/* the traverse reaches the end */
14417 			hashtab->cur = NULL;
14418 			return (NULL);
14419 		} else {
14420 			this = hashtab->head[hashtab->line];
14421 		}
14422 	}
14423 	hashtab->cur = this;
14424 	return (this->data);
14425 }
14426