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