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