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