mptsas.c revision 9907:98086c85a8f7
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 */
107static int mptsas_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
108static int mptsas_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
109static int mptsas_power(dev_info_t *dip, int component, int level);
110
111/*
112 * cb_ops function
113 */
114static int mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode,
115	cred_t *credp, int *rval);
116#ifndef	__sparc
117static int mptsas_quiesce(dev_info_t *devi);
118#endif	/* __sparc */
119
120/*
121 * Resource initilaization for hardware
122 */
123static void mptsas_setup_cmd_reg(mptsas_t *mpt);
124static void mptsas_disable_bus_master(mptsas_t *mpt);
125static void mptsas_hba_fini(mptsas_t *mpt);
126static void mptsas_cfg_fini(mptsas_t *mptsas_blkp);
127static int mptsas_alloc_request_frames(mptsas_t *mpt);
128static int mptsas_alloc_reply_frames(mptsas_t *mpt);
129static int mptsas_alloc_free_queue(mptsas_t *mpt);
130static int mptsas_alloc_post_queue(mptsas_t *mpt);
131static int mptsas_alloc_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd);
132static void mptsas_free_extra_sgl_frame(mptsas_t *mpt, mptsas_cmd_t *cmd);
133
134/*
135 * SCSA function prototypes
136 */
137static int mptsas_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt);
138static int mptsas_scsi_reset(struct scsi_address *ap, int level);
139static int mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt);
140static int mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly);
141static int mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value,
142    int tgtonly);
143static void mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt);
144static 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);
147static void mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt);
148static void mptsas_scsi_destroy_pkt(struct scsi_address *ap,
149    struct scsi_pkt *pkt);
150static 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);
152static 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);
154static int mptsas_scsi_reset_notify(struct scsi_address *ap, int flag,
155    void (*callback)(caddr_t), caddr_t arg);
156static int mptsas_get_name(struct scsi_device *sd, char *name, int len);
157static int mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len);
158static int mptsas_scsi_quiesce(dev_info_t *dip);
159static int mptsas_scsi_unquiesce(dev_info_t *dip);
160static 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 */
166static int mptsas_smp_start(struct smp_pkt *smp_pkt);
167static int mptsas_getcap(struct sas_addr *ap, char *cap);
168static int mptsas_capchk(char *cap, int tgtonly, int *cidxp);
169
170/*
171 * internal function prototypes.
172 */
173static int mptsas_quiesce_bus(mptsas_t *mpt);
174static int mptsas_unquiesce_bus(mptsas_t *mpt);
175
176static int mptsas_alloc_handshake_msg(mptsas_t *mpt, size_t alloc_size);
177static void mptsas_free_handshake_msg(mptsas_t *mpt);
178
179static void mptsas_ncmds_checkdrain(void *arg);
180
181static int mptsas_prepare_pkt(mptsas_cmd_t *cmd);
182static int mptsas_accept_pkt(mptsas_t *mpt, mptsas_cmd_t *sp);
183static int mptsas_accept_txwq_and_pkt(mptsas_t *mpt, mptsas_cmd_t *sp);
184static void mptsas_accept_tx_waitq(mptsas_t *mpt);
185
186static int mptsas_do_detach(dev_info_t *dev);
187static int mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl);
188static int mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun,
189    struct scsi_pkt *pkt);
190
191static void mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd);
192static void mptsas_handle_event(void *args);
193static int mptsas_handle_event_sync(void *args);
194static void mptsas_handle_dr(void *args);
195static void mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node,
196    dev_info_t *pdip);
197
198static void mptsas_restart_cmd(void *);
199
200static void mptsas_flush_hba(mptsas_t *mpt);
201static void mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun,
202	uint8_t tasktype);
203static void mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd,
204    uchar_t reason, uint_t stat);
205
206static uint_t mptsas_intr(caddr_t arg1, caddr_t arg2);
207static void mptsas_process_intr(mptsas_t *mpt,
208    pMpi2ReplyDescriptorsUnion_t reply_desc_union);
209static void mptsas_handle_scsi_io_success(mptsas_t *mpt,
210    pMpi2ReplyDescriptorsUnion_t reply_desc);
211static void mptsas_handle_address_reply(mptsas_t *mpt,
212    pMpi2ReplyDescriptorsUnion_t reply_desc);
213static int mptsas_wait_intr(mptsas_t *mpt, int polltime);
214static 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
217static void mptsas_watch(void *arg);
218static void mptsas_watchsubr(mptsas_t *mpt);
219static void mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl);
220
221static void mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd);
222static 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);
226static int mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl);
227
228static int mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd,
229    int cmdlen, int tgtlen, int statuslen, int kf);
230static void mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd);
231
232static int mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags);
233static void mptsas_kmem_cache_destructor(void *buf, void *cdrarg);
234
235static int mptsas_cache_frames_constructor(void *buf, void *cdrarg,
236    int kmflags);
237static void mptsas_cache_frames_destructor(void *buf, void *cdrarg);
238
239static void mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply,
240    mptsas_cmd_t *cmd);
241static void mptsas_check_task_mgt(mptsas_t *mpt,
242    pMpi2SCSIManagementReply_t reply, mptsas_cmd_t *cmd);
243static 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
247static int mptsas_alloc_active_slots(mptsas_t *mpt, int flag);
248static int mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
249
250static void mptsas_restart_hba(mptsas_t *mpt);
251static void mptsas_restart_waitq(mptsas_t *mpt);
252
253static void mptsas_deliver_doneq_thread(mptsas_t *mpt);
254static void mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd);
255static void mptsas_doneq_mv(mptsas_t *mpt, uint64_t t);
256
257static mptsas_cmd_t *mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t);
258static void mptsas_doneq_empty(mptsas_t *mpt);
259static void mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg);
260
261static mptsas_cmd_t *mptsas_waitq_rm(mptsas_t *mpt);
262static void mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd);
263static mptsas_cmd_t *mptsas_tx_waitq_rm(mptsas_t *mpt);
264static void mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd);
265
266
267static void mptsas_start_watch_reset_delay();
268static void mptsas_setup_bus_reset_delay(mptsas_t *mpt);
269static void mptsas_watch_reset_delay(void *arg);
270static int mptsas_watch_reset_delay_subr(mptsas_t *mpt);
271
272/*
273 * helper functions
274 */
275static void mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd);
276
277static dev_info_t *mptsas_find_child(dev_info_t *pdip, char *name);
278static dev_info_t *mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy);
279static dev_info_t *mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr,
280    int lun);
281static mdi_pathinfo_t *mptsas_find_path_addr(dev_info_t *pdip, uint64_t sasaddr,
282    int lun);
283static mdi_pathinfo_t *mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy);
284static dev_info_t *mptsas_find_smp_child(dev_info_t *pdip, char *str_wwn);
285
286static int mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy,
287    int *lun);
288static int mptsas_parse_smp_name(char *name, uint64_t *wwn);
289
290static mptsas_target_t *mptsas_phy_to_tgt(dev_info_t *pdip, uint8_t phy);
291static mptsas_target_t *mptsas_wwid_to_ptgt(mptsas_t *mpt, int port,
292    uint64_t wwid);
293static mptsas_smp_t *mptsas_wwid_to_psmp(mptsas_t *mpt, int port,
294    uint64_t wwid);
295
296static 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
299static int mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
300    uint16_t *handle, mptsas_target_t **pptgt);
301static void mptsas_update_phymask(mptsas_t *mpt);
302
303/*
304 * Enumeration / DR functions
305 */
306static void mptsas_config_all(dev_info_t *pdip);
307static int mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
308    dev_info_t **lundip);
309static int mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
310    dev_info_t **lundip);
311
312static int mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt);
313static int mptsas_offline_target(dev_info_t *pdip, char *name);
314
315static int mptsas_config_raid(dev_info_t *pdip, uint16_t target,
316    dev_info_t **dip);
317
318static int mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt);
319static int mptsas_probe_lun(dev_info_t *pdip, int lun,
320    dev_info_t **dip, mptsas_target_t *ptgt);
321
322static 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
325static 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);
327static 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
331static void mptsas_offline_missed_luns(dev_info_t *pdip,
332    uint16_t *repluns, int lun_cnt, mptsas_target_t *ptgt);
333static int mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
334    mdi_pathinfo_t *rpip, uint_t flags);
335
336static int mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn,
337    dev_info_t **smp_dip);
338static int mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
339    uint_t flags);
340
341static int mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data,
342    int mode, int *rval);
343static int mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data,
344    int mode, int *rval);
345static int mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data,
346    int mode, int *rval);
347static void mptsas_record_event(void *args);
348
349static void mptsas_hash_init(mptsas_hash_table_t *hashtab);
350static void mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen);
351static void mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data);
352static void * mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1,
353    uint8_t key2);
354static void * mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1,
355    uint8_t key2);
356static void * mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos);
357
358mptsas_target_t *mptsas_tgt_alloc(mptsas_hash_table_t *, uint16_t, uint64_t,
359    uint32_t, uint8_t, uint8_t);
360static mptsas_smp_t *mptsas_smp_alloc(mptsas_hash_table_t *hashtab,
361    mptsas_smp_t *data);
362static void mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid,
363    uint8_t physport);
364static void mptsas_tgt_free(mptsas_hash_table_t *, uint64_t, uint8_t);
365static void * mptsas_search_by_devhdl(mptsas_hash_table_t *, uint16_t);
366static 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 */
372static void mptsas_idle_pm(void *arg);
373static 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 */
380boolean_t mptsas_enable_msi = B_TRUE;
381
382static int mptsas_add_intrs(mptsas_t *, int);
383static void mptsas_rem_intrs(mptsas_t *);
384
385/*
386 * FMA Prototypes
387 */
388static void mptsas_fm_init(mptsas_t *mpt);
389static void mptsas_fm_fini(mptsas_t *mpt);
390static int mptsas_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *);
391
392extern 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 */
399extern 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 */
405int 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 */
412ddi_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 */
431ddi_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
446ddi_device_acc_attr_t mptsas_dev_attr = {
447	DDI_DEVICE_ATTR_V0,
448	DDI_STRUCTURE_LE_ACC,
449	DDI_STRICTORDER_ACC
450};
451
452static 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
473static 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.16"
494#define	CDATE "MPTSAS was compiled on "__DATE__
495/* LINTED E_STATIC_UNUSED */
496static char *MPTWASCOMPILEDON = CDATE;
497
498static 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
504static 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)
518uint32_t mptsas_debug_flags = 0;
519#endif	/* defined(MPTSAS_DEBUG) */
520uint32_t mptsas_debug_resets = 0;
521
522static kmutex_t		mptsas_global_mutex;
523static void		*mptsas_state;		/* soft	state ptr */
524static krwlock_t	mptsas_global_rwlock;
525
526static kmutex_t		mptsas_log_mutex;
527static char		mptsas_log_buf[256];
528_NOTE(MUTEX_PROTECTS_DATA(mptsas_log_mutex, mptsas_log_buf))
529
530static mptsas_t *mptsas_head, *mptsas_tail;
531static clock_t mptsas_scsi_watchdog_tick;
532static clock_t mptsas_tick;
533static timeout_id_t mptsas_reset_watch;
534static timeout_id_t mptsas_timeout_id;
535static 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
548void 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 */
556int
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 */
595int
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 */
617int
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
628static int
629mptsas_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 becasue 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 becasue 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 becasue 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 becasue 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 */
776static int
777mptsas_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
1084intr_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, SCSI_HBA_CANSLEEP);
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
1397fail:
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
1491static int
1492mptsas_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
1615static int
1616mptsas_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 */
1639static int
1640mptsas_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
1659static int
1660mptsas_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
1902static int
1903mptsas_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
1943static void
1944mptsas_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
1955static int
1956mptsas_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 */
2031int
2032mptsas_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
2144static void
2145mptsas_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
2159static void
2160mptsas_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
2173int
2174mptsas_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
2216void
2217mptsas_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
2227int
2228mptsas_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
2288static int
2289mptsas_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
2359static int
2360mptsas_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
2429static int
2430mptsas_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
2502static int
2503mptsas_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
2574static int
2575mptsas_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
2588static void
2589mptsas_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
2598static void
2599mptsas_cfg_fini(mptsas_t *mpt)
2600{
2601	NDBG0(("mptsas_cfg_fini"));
2602	ddi_regs_map_free(&mpt->m_datap);
2603}
2604
2605static void
2606mptsas_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
2654static int
2655mptsas_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	    "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%016s,%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 */
2694static int
2695mptsas_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, "target-port", &psas_wwn) ==
2752		    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, "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_hba_prop_update_inqstring(sd,
2864			    INQUIRY_VENDOR_ID, vid, strlen(vid));
2865		if (pid)
2866			(void) scsi_hba_prop_update_inqstring(sd,
2867			    INQUIRY_PRODUCT_ID, pid, strlen(pid));
2868		(void) scsi_hba_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 */
2883static void
2884mptsas_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 */
2912static int
2913mptsas_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 */
3058static int
3059mptsas_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
3098static int
3099mptsas_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
3184int
3185mptsas_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
3210alloc_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		return (TRUE);
3233	} else {
3234		int i;
3235
3236		/*
3237		 * If slot in use, scan until a free one is found. Don't use 0
3238		 * or final slot, which is reserved for TM requests.
3239		 */
3240		for (i = 0; i < slots->m_n_slots; i++) {
3241			slot = slots->m_tags;
3242			if (++(slots->m_tags) > slots->m_n_slots) {
3243				slots->m_tags = 1;
3244			}
3245			if (slots->m_slot[slot] == NULL) {
3246				NDBG22(("found free slot %d", slot));
3247				goto alloc_tag;
3248			}
3249		}
3250	}
3251	return (FALSE);
3252}
3253
3254/*
3255 * prepare the pkt:
3256 * the pkt may have been resubmitted or just reused so
3257 * initialize some fields and do some checks.
3258 */
3259static int
3260mptsas_prepare_pkt(mptsas_cmd_t *cmd)
3261{
3262	struct scsi_pkt	*pkt = CMD2PKT(cmd);
3263
3264	NDBG1(("mptsas_prepare_pkt: cmd=0x%p", (void *)cmd));
3265
3266	/*
3267	 * Reinitialize some fields that need it; the packet may
3268	 * have been resubmitted
3269	 */
3270	pkt->pkt_reason = CMD_CMPLT;
3271	pkt->pkt_state = 0;
3272	pkt->pkt_statistics = 0;
3273	pkt->pkt_resid = 0;
3274	cmd->cmd_age = 0;
3275	cmd->cmd_pkt_flags = pkt->pkt_flags;
3276
3277	/*
3278	 * zero status byte.
3279	 */
3280	*(pkt->pkt_scbp) = 0;
3281
3282	if (cmd->cmd_flags & CFLAG_DMAVALID) {
3283		pkt->pkt_resid = cmd->cmd_dmacount;
3284
3285		/*
3286		 * consistent packets need to be sync'ed first
3287		 * (only for data going out)
3288		 */
3289		if ((cmd->cmd_flags & CFLAG_CMDIOPB) &&
3290		    (cmd->cmd_flags & CFLAG_DMASEND)) {
3291			(void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
3292			    DDI_DMA_SYNC_FORDEV);
3293		}
3294	}
3295
3296	cmd->cmd_flags =
3297	    (cmd->cmd_flags & ~(CFLAG_TRANFLAG)) |
3298	    CFLAG_PREPARED | CFLAG_IN_TRANSPORT;
3299
3300	return (TRAN_ACCEPT);
3301}
3302
3303/*
3304 * tran_init_pkt(9E) - allocate scsi_pkt(9S) for command
3305 *
3306 * One of three possibilities:
3307 *	- allocate scsi_pkt
3308 *	- allocate scsi_pkt and DMA resources
3309 *	- allocate DMA resources to an already-allocated pkt
3310 */
3311static struct scsi_pkt *
3312mptsas_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt,
3313    struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags,
3314    int (*callback)(), caddr_t arg)
3315{
3316	mptsas_cmd_t		*cmd, *new_cmd;
3317	mptsas_t		*mpt = ADDR2MPT(ap);
3318	int			failure = 1;
3319	uint_t			oldcookiec;
3320	mptsas_target_t		*ptgt = NULL;
3321	int			rval;
3322	mptsas_tgt_private_t	*tgt_private;
3323	int			kf;
3324
3325	kf = (callback == SLEEP_FUNC)? KM_SLEEP: KM_NOSLEEP;
3326
3327	tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->
3328	    tran_tgt_private;
3329	ASSERT(tgt_private != NULL);
3330	if (tgt_private == NULL) {
3331		return (NULL);
3332	}
3333	ptgt = tgt_private->t_private;
3334	ASSERT(ptgt != NULL);
3335	if (ptgt == NULL)
3336		return (NULL);
3337	ap->a_target = ptgt->m_devhdl;
3338	ap->a_lun = tgt_private->t_lun;
3339
3340	ASSERT(callback == NULL_FUNC || callback == SLEEP_FUNC);
3341#ifdef MPTSAS_TEST_EXTRN_ALLOC
3342	statuslen *= 100; tgtlen *= 4;
3343#endif
3344	NDBG3(("mptsas_scsi_init_pkt:\n"
3345	    "\ttgt=%d in=0x%p bp=0x%p clen=%d slen=%d tlen=%d flags=%x",
3346	    ap->a_target, (void *)pkt, (void *)bp,
3347	    cmdlen, statuslen, tgtlen, flags));
3348
3349	/*
3350	 * Allocate the new packet.
3351	 */
3352	if (pkt == NULL) {
3353		ddi_dma_handle_t	save_dma_handle;
3354		ddi_dma_handle_t	save_arq_dma_handle;
3355		struct buf		*save_arq_bp;
3356		ddi_dma_cookie_t	save_arqcookie;
3357
3358		cmd = kmem_cache_alloc(mpt->m_kmem_cache, kf);
3359
3360		if (cmd) {
3361			save_dma_handle = cmd->cmd_dmahandle;
3362			save_arq_dma_handle = cmd->cmd_arqhandle;
3363			save_arq_bp = cmd->cmd_arq_buf;
3364			save_arqcookie = cmd->cmd_arqcookie;
3365			bzero(cmd, sizeof (*cmd) + scsi_pkt_size());
3366			cmd->cmd_dmahandle = save_dma_handle;
3367			cmd->cmd_arqhandle = save_arq_dma_handle;
3368			cmd->cmd_arq_buf = save_arq_bp;
3369			cmd->cmd_arqcookie = save_arqcookie;
3370
3371			pkt = (void *)((uchar_t *)cmd +
3372			    sizeof (struct mptsas_cmd));
3373			pkt->pkt_ha_private = (opaque_t)cmd;
3374			pkt->pkt_address = *ap;
3375			pkt->pkt_private = (opaque_t)cmd->cmd_pkt_private;
3376			pkt->pkt_scbp = (opaque_t)&cmd->cmd_scb;
3377			pkt->pkt_cdbp = (opaque_t)&cmd->cmd_cdb;
3378			cmd->cmd_pkt = (struct scsi_pkt *)pkt;
3379			cmd->cmd_cdblen = (uchar_t)cmdlen;
3380			cmd->cmd_scblen = statuslen;
3381			cmd->cmd_rqslen = SENSE_LENGTH;
3382			cmd->cmd_tgt_addr = ptgt;
3383			failure = 0;
3384		}
3385
3386		if (failure || (cmdlen > sizeof (cmd->cmd_cdb)) ||
3387		    (tgtlen > PKT_PRIV_LEN) ||
3388		    (statuslen > EXTCMDS_STATUS_SIZE)) {
3389			if (failure == 0) {
3390				/*
3391				 * if extern alloc fails, all will be
3392				 * deallocated, including cmd
3393				 */
3394				failure = mptsas_pkt_alloc_extern(mpt, cmd,
3395				    cmdlen, tgtlen, statuslen, kf);
3396			}
3397			if (failure) {
3398				/*
3399				 * if extern allocation fails, it will
3400				 * deallocate the new pkt as well
3401				 */
3402				return (NULL);
3403			}
3404		}
3405		new_cmd = cmd;
3406
3407	} else {
3408		cmd = PKT2CMD(pkt);
3409		new_cmd = NULL;
3410	}
3411
3412
3413	/* grab cmd->cmd_cookiec here as oldcookiec */
3414
3415	oldcookiec = cmd->cmd_cookiec;
3416
3417	/*
3418	 * If the dma was broken up into PARTIAL transfers cmd_nwin will be
3419	 * greater than 0 and we'll need to grab the next dma window
3420	 */
3421	/*
3422	 * SLM-not doing extra command frame right now; may add later
3423	 */
3424
3425	if (cmd->cmd_nwin > 0) {
3426
3427		/*
3428		 * Make sure we havn't gone past the the total number
3429		 * of windows
3430		 */
3431		if (++cmd->cmd_winindex >= cmd->cmd_nwin) {
3432			return (NULL);
3433		}
3434		if (ddi_dma_getwin(cmd->cmd_dmahandle, cmd->cmd_winindex,
3435		    &cmd->cmd_dma_offset, &cmd->cmd_dma_len,
3436		    &cmd->cmd_cookie, &cmd->cmd_cookiec) == DDI_FAILURE) {
3437			return (NULL);
3438		}
3439		goto get_dma_cookies;
3440	}
3441
3442
3443	if (flags & PKT_XARQ) {
3444		cmd->cmd_flags |= CFLAG_XARQ;
3445	}
3446
3447	/*
3448	 * DMA resource allocation.  This version assumes your
3449	 * HBA has some sort of bus-mastering or onboard DMA capability, with a
3450	 * scatter-gather list of length MPTSAS_MAX_DMA_SEGS, as given in the
3451	 * ddi_dma_attr_t structure and passed to scsi_impl_dmaget.
3452	 */
3453	if (bp && (bp->b_bcount != 0) &&
3454	    (cmd->cmd_flags & CFLAG_DMAVALID) == 0) {
3455
3456		int	cnt, dma_flags;
3457		mptti_t	*dmap;		/* ptr to the S/G list */
3458
3459		/*
3460		 * Set up DMA memory and position to the next DMA segment.
3461		 */
3462		ASSERT(cmd->cmd_dmahandle != NULL);
3463
3464		if (bp->b_flags & B_READ) {
3465			dma_flags = DDI_DMA_READ;
3466			cmd->cmd_flags &= ~CFLAG_DMASEND;
3467		} else {
3468			dma_flags = DDI_DMA_WRITE;
3469			cmd->cmd_flags |= CFLAG_DMASEND;
3470		}
3471		if (flags & PKT_CONSISTENT) {
3472			cmd->cmd_flags |= CFLAG_CMDIOPB;
3473			dma_flags |= DDI_DMA_CONSISTENT;
3474		}
3475
3476		if (flags & PKT_DMA_PARTIAL) {
3477			dma_flags |= DDI_DMA_PARTIAL;
3478		}
3479
3480		/*
3481		 * workaround for byte hole issue on psycho and
3482		 * schizo pre 2.1
3483		 */
3484		if ((bp->b_flags & B_READ) && ((bp->b_flags &
3485		    (B_PAGEIO|B_REMAPPED)) != B_PAGEIO) &&
3486		    ((uintptr_t)bp->b_un.b_addr & 0x7)) {
3487			dma_flags |= DDI_DMA_CONSISTENT;
3488		}
3489
3490		rval = ddi_dma_buf_bind_handle(cmd->cmd_dmahandle, bp,
3491		    dma_flags, callback, arg,
3492		    &cmd->cmd_cookie, &cmd->cmd_cookiec);
3493		if (rval == DDI_DMA_PARTIAL_MAP) {
3494			(void) ddi_dma_numwin(cmd->cmd_dmahandle,
3495			    &cmd->cmd_nwin);
3496			cmd->cmd_winindex = 0;
3497			(void) ddi_dma_getwin(cmd->cmd_dmahandle,
3498			    cmd->cmd_winindex, &cmd->cmd_dma_offset,
3499			    &cmd->cmd_dma_len, &cmd->cmd_cookie,
3500			    &cmd->cmd_cookiec);
3501		} else if (rval && (rval != DDI_DMA_MAPPED)) {
3502			switch (rval) {
3503			case DDI_DMA_NORESOURCES:
3504				bioerror(bp, 0);
3505				break;
3506			case DDI_DMA_BADATTR:
3507			case DDI_DMA_NOMAPPING:
3508				bioerror(bp, EFAULT);
3509				break;
3510			case DDI_DMA_TOOBIG:
3511			default:
3512				bioerror(bp, EINVAL);
3513				break;
3514			}
3515			cmd->cmd_flags &= ~CFLAG_DMAVALID;
3516			if (new_cmd) {
3517				mptsas_scsi_destroy_pkt(ap, pkt);
3518			}
3519			return ((struct scsi_pkt *)NULL);
3520		}
3521
3522get_dma_cookies:
3523		cmd->cmd_flags |= CFLAG_DMAVALID;
3524		ASSERT(cmd->cmd_cookiec > 0);
3525
3526		if (cmd->cmd_cookiec > MPTSAS_MAX_CMD_SEGS) {
3527			mptsas_log(mpt, CE_NOTE, "large cookiec received %d\n",
3528			    cmd->cmd_cookiec);
3529			bioerror(bp, EINVAL);
3530			if (new_cmd) {
3531				mptsas_scsi_destroy_pkt(ap, pkt);
3532			}
3533			return ((struct scsi_pkt *)NULL);
3534		}
3535
3536		/*
3537		 * Allocate extra SGL buffer if needed.
3538		 */
3539		if ((cmd->cmd_cookiec > MPTSAS_MAX_FRAME_SGES64(mpt)) &&
3540		    (cmd->cmd_extra_frames == NULL)) {
3541			if (mptsas_alloc_extra_sgl_frame(mpt, cmd) ==
3542			    DDI_FAILURE) {
3543				mptsas_log(mpt, CE_WARN, "MPT SGL mem alloc "
3544				    "failed");
3545				bioerror(bp, ENOMEM);
3546				if (new_cmd) {
3547					mptsas_scsi_destroy_pkt(ap, pkt);
3548				}
3549				return ((struct scsi_pkt *)NULL);
3550			}
3551		}
3552
3553		/*
3554		 * Always use scatter-gather transfer
3555		 * Use the loop below to store physical addresses of
3556		 * DMA segments, from the DMA cookies, into your HBA's
3557		 * scatter-gather list.
3558		 * We need to ensure we have enough kmem alloc'd
3559		 * for the sg entries since we are no longer using an
3560		 * array inside mptsas_cmd_t.
3561		 *
3562		 * We check cmd->cmd_cookiec against oldcookiec so
3563		 * the scatter-gather list is correctly allocated
3564		 */
3565
3566		if (oldcookiec != cmd->cmd_cookiec) {
3567			if (cmd->cmd_sg != (mptti_t *)NULL) {
3568				kmem_free(cmd->cmd_sg, sizeof (mptti_t) *
3569				    oldcookiec);
3570				cmd->cmd_sg = NULL;
3571			}
3572		}
3573
3574		if (cmd->cmd_sg == (mptti_t *)NULL) {
3575			cmd->cmd_sg = kmem_alloc((size_t)(sizeof (mptti_t)*
3576			    cmd->cmd_cookiec), kf);
3577
3578			if (cmd->cmd_sg == (mptti_t *)NULL) {
3579				mptsas_log(mpt, CE_WARN,
3580				    "unable to kmem_alloc enough memory "
3581				    "for scatter/gather list");
3582		/*
3583		 * if we have an ENOMEM condition we need to behave
3584		 * the same way as the rest of this routine
3585		 */
3586
3587				bioerror(bp, ENOMEM);
3588				if (new_cmd) {
3589					mptsas_scsi_destroy_pkt(ap, pkt);
3590				}
3591				return ((struct scsi_pkt *)NULL);
3592			}
3593		}
3594
3595		dmap = cmd->cmd_sg;
3596
3597		ASSERT(cmd->cmd_cookie.dmac_size != 0);
3598
3599		/*
3600		 * store the first segment into the S/G list
3601		 */
3602		dmap->count = cmd->cmd_cookie.dmac_size;
3603		dmap->addr.address64.Low = (uint32_t)
3604		    (cmd->cmd_cookie.dmac_laddress & 0xffffffffull);
3605		dmap->addr.address64.High = (uint32_t)
3606		    (cmd->cmd_cookie.dmac_laddress >> 32);
3607
3608		/*
3609		 * dmacount counts the size of the dma for this window
3610		 * (if partial dma is being used).  totaldmacount
3611		 * keeps track of the total amount of dma we have
3612		 * transferred for all the windows (needed to calculate
3613		 * the resid value below).
3614		 */
3615		cmd->cmd_dmacount = cmd->cmd_cookie.dmac_size;
3616		cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size;
3617
3618		/*
3619		 * We already stored the first DMA scatter gather segment,
3620		 * start at 1 if we need to store more.
3621		 */
3622		for (cnt = 1; cnt < cmd->cmd_cookiec; cnt++) {
3623			/*
3624			 * Get next DMA cookie
3625			 */
3626			ddi_dma_nextcookie(cmd->cmd_dmahandle,
3627			    &cmd->cmd_cookie);
3628			dmap++;
3629
3630			cmd->cmd_dmacount += cmd->cmd_cookie.dmac_size;
3631			cmd->cmd_totaldmacount += cmd->cmd_cookie.dmac_size;
3632
3633			/*
3634			 * store the segment parms into the S/G list
3635			 */
3636			dmap->count = cmd->cmd_cookie.dmac_size;
3637			dmap->addr.address64.Low = (uint32_t)
3638			    (cmd->cmd_cookie.dmac_laddress & 0xffffffffull);
3639			dmap->addr.address64.High = (uint32_t)
3640			    (cmd->cmd_cookie.dmac_laddress >> 32);
3641		}
3642
3643		/*
3644		 * If this was partially allocated we set the resid
3645		 * the amount of data NOT transferred in this window
3646		 * If there is only one window, the resid will be 0
3647		 */
3648		pkt->pkt_resid = (bp->b_bcount - cmd->cmd_totaldmacount);
3649		NDBG16(("mptsas_dmaget: cmd_dmacount=%d.", cmd->cmd_dmacount));
3650	}
3651	return (pkt);
3652}
3653
3654/*
3655 * tran_destroy_pkt(9E) - scsi_pkt(9s) deallocation
3656 *
3657 * Notes:
3658 *	- also frees DMA resources if allocated
3659 *	- implicit DMA synchonization
3660 */
3661static void
3662mptsas_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
3663{
3664	mptsas_cmd_t	*cmd = PKT2CMD(pkt);
3665	mptsas_t	*mpt = ADDR2MPT(ap);
3666
3667	NDBG3(("mptsas_scsi_destroy_pkt: target=%d pkt=0x%p",
3668	    ap->a_target, (void *)pkt));
3669
3670	if (cmd->cmd_flags & CFLAG_DMAVALID) {
3671		(void) ddi_dma_unbind_handle(cmd->cmd_dmahandle);
3672		cmd->cmd_flags &= ~CFLAG_DMAVALID;
3673	}
3674
3675	if (cmd->cmd_sg) {
3676		kmem_free(cmd->cmd_sg, sizeof (mptti_t) * cmd->cmd_cookiec);
3677		cmd->cmd_sg = NULL;
3678	}
3679
3680	mptsas_free_extra_sgl_frame(mpt, cmd);
3681
3682	if ((cmd->cmd_flags &
3683	    (CFLAG_FREE | CFLAG_CDBEXTERN | CFLAG_PRIVEXTERN |
3684	    CFLAG_SCBEXTERN)) == 0) {
3685		cmd->cmd_flags = CFLAG_FREE;
3686		kmem_cache_free(mpt->m_kmem_cache, (void *)cmd);
3687	} else {
3688		mptsas_pkt_destroy_extern(mpt, cmd);
3689	}
3690}
3691
3692/*
3693 * kmem cache constructor and destructor:
3694 * When constructing, we bzero the cmd and allocate the dma handle
3695 * When destructing, just free the dma handle
3696 */
3697static int
3698mptsas_kmem_cache_constructor(void *buf, void *cdrarg, int kmflags)
3699{
3700	mptsas_cmd_t		*cmd = buf;
3701	mptsas_t		*mpt  = cdrarg;
3702	struct scsi_address	ap;
3703	uint_t			cookiec;
3704	ddi_dma_attr_t		arq_dma_attr;
3705	int			(*callback)(caddr_t);
3706
3707	callback = (kmflags == KM_SLEEP)? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT;
3708
3709	NDBG4(("mptsas_kmem_cache_constructor"));
3710
3711	ap.a_hba_tran = mpt->m_tran;
3712	ap.a_target = 0;
3713	ap.a_lun = 0;
3714
3715	/*
3716	 * allocate a dma handle
3717	 */
3718	if ((ddi_dma_alloc_handle(mpt->m_dip, &mpt->m_io_dma_attr, callback,
3719	    NULL, &cmd->cmd_dmahandle)) != DDI_SUCCESS) {
3720		cmd->cmd_dmahandle = NULL;
3721		return (-1);
3722	}
3723
3724	cmd->cmd_arq_buf = scsi_alloc_consistent_buf(&ap, (struct buf *)NULL,
3725	    SENSE_LENGTH, B_READ, callback, NULL);
3726	if (cmd->cmd_arq_buf == NULL) {
3727		ddi_dma_free_handle(&cmd->cmd_dmahandle);
3728		cmd->cmd_dmahandle = NULL;
3729		return (-1);
3730	}
3731
3732	/*
3733	 * allocate a arq handle
3734	 */
3735	arq_dma_attr = mpt->m_msg_dma_attr;
3736	arq_dma_attr.dma_attr_sgllen = 1;
3737	if ((ddi_dma_alloc_handle(mpt->m_dip, &arq_dma_attr, callback,
3738	    NULL, &cmd->cmd_arqhandle)) != DDI_SUCCESS) {
3739		ddi_dma_free_handle(&cmd->cmd_dmahandle);
3740		scsi_free_consistent_buf(cmd->cmd_arq_buf);
3741		cmd->cmd_dmahandle = NULL;
3742		cmd->cmd_arqhandle = NULL;
3743		return (-1);
3744	}
3745
3746	if (ddi_dma_buf_bind_handle(cmd->cmd_arqhandle,
3747	    cmd->cmd_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT),
3748	    callback, NULL, &cmd->cmd_arqcookie, &cookiec) != DDI_SUCCESS) {
3749		ddi_dma_free_handle(&cmd->cmd_dmahandle);
3750		ddi_dma_free_handle(&cmd->cmd_arqhandle);
3751		scsi_free_consistent_buf(cmd->cmd_arq_buf);
3752		cmd->cmd_dmahandle = NULL;
3753		cmd->cmd_arqhandle = NULL;
3754		cmd->cmd_arq_buf = NULL;
3755		return (-1);
3756	}
3757
3758	return (0);
3759}
3760
3761static void
3762mptsas_kmem_cache_destructor(void *buf, void *cdrarg)
3763{
3764#ifndef __lock_lint
3765	_NOTE(ARGUNUSED(cdrarg))
3766#endif
3767	mptsas_cmd_t	*cmd = buf;
3768
3769	NDBG4(("mptsas_kmem_cache_destructor"));
3770
3771	if (cmd->cmd_arqhandle) {
3772		(void) ddi_dma_unbind_handle(cmd->cmd_arqhandle);
3773		ddi_dma_free_handle(&cmd->cmd_arqhandle);
3774		cmd->cmd_arqhandle = NULL;
3775	}
3776	if (cmd->cmd_arq_buf) {
3777		scsi_free_consistent_buf(cmd->cmd_arq_buf);
3778		cmd->cmd_arq_buf = NULL;
3779	}
3780	if (cmd->cmd_dmahandle) {
3781		ddi_dma_free_handle(&cmd->cmd_dmahandle);
3782		cmd->cmd_dmahandle = NULL;
3783	}
3784}
3785
3786static int
3787mptsas_cache_frames_constructor(void *buf, void *cdrarg, int kmflags)
3788{
3789	mptsas_cache_frames_t	*p = buf;
3790	mptsas_t		*mpt = cdrarg;
3791	ddi_dma_attr_t		frame_dma_attr;
3792	size_t			mem_size, alloc_len;
3793	ddi_dma_cookie_t	cookie;
3794	uint_t			ncookie;
3795	int (*callback)(caddr_t) = (kmflags == KM_SLEEP)
3796	    ? DDI_DMA_SLEEP: DDI_DMA_DONTWAIT;
3797
3798	frame_dma_attr = mpt->m_msg_dma_attr;
3799	frame_dma_attr.dma_attr_align = 0x10;
3800	frame_dma_attr.dma_attr_sgllen = 1;
3801
3802	if (ddi_dma_alloc_handle(mpt->m_dip, &frame_dma_attr, callback, NULL,
3803	    &p->m_dma_hdl) != DDI_SUCCESS) {
3804		mptsas_log(mpt, CE_WARN, "Unable to allocate dma handle for"
3805		    " extra SGL.");
3806		return (DDI_FAILURE);
3807	}
3808
3809	mem_size = (mpt->m_max_request_frames - 1) * mpt->m_req_frame_size;
3810
3811	if (ddi_dma_mem_alloc(p->m_dma_hdl, mem_size, &mpt->m_dev_acc_attr,
3812	    DDI_DMA_CONSISTENT, callback, NULL, (caddr_t *)&p->m_frames_addr,
3813	    &alloc_len, &p->m_acc_hdl) != DDI_SUCCESS) {
3814		ddi_dma_free_handle(&p->m_dma_hdl);
3815		p->m_dma_hdl = NULL;
3816		mptsas_log(mpt, CE_WARN, "Unable to allocate dma memory for"
3817		    " extra SGL.");
3818		return (DDI_FAILURE);
3819	}
3820
3821	if (ddi_dma_addr_bind_handle(p->m_dma_hdl, NULL, p->m_frames_addr,
3822	    alloc_len, DDI_DMA_RDWR | DDI_DMA_CONSISTENT, callback, NULL,
3823	    &cookie, &ncookie) != DDI_DMA_MAPPED) {
3824		(void) ddi_dma_mem_free(&p->m_acc_hdl);
3825		ddi_dma_free_handle(&p->m_dma_hdl);
3826		p->m_dma_hdl = NULL;
3827		mptsas_log(mpt, CE_WARN, "Unable to bind DMA resources for"
3828		    " extra SGL");
3829		return (DDI_FAILURE);
3830	}
3831
3832	/*
3833	 * Store the SGL memory address.  This chip uses this
3834	 * address to dma to and from the driver.  The second
3835	 * address is the address mpt uses to fill in the SGL.
3836	 */
3837	p->m_phys_addr = cookie.dmac_address;
3838
3839	return (DDI_SUCCESS);
3840}
3841
3842static void
3843mptsas_cache_frames_destructor(void *buf, void *cdrarg)
3844{
3845#ifndef __lock_lint
3846	_NOTE(ARGUNUSED(cdrarg))
3847#endif
3848	mptsas_cache_frames_t	*p = buf;
3849	if (p->m_dma_hdl != NULL) {
3850		(void) ddi_dma_unbind_handle(p->m_dma_hdl);
3851		(void) ddi_dma_mem_free(&p->m_acc_hdl);
3852		ddi_dma_free_handle(&p->m_dma_hdl);
3853		p->m_phys_addr = NULL;
3854		p->m_frames_addr = NULL;
3855		p->m_dma_hdl = NULL;
3856		p->m_acc_hdl = NULL;
3857	}
3858
3859}
3860
3861/*
3862 * allocate and deallocate external pkt space (ie. not part of mptsas_cmd)
3863 * for non-standard length cdb, pkt_private, status areas
3864 * if allocation fails, then deallocate all external space and the pkt
3865 */
3866/* ARGSUSED */
3867static int
3868mptsas_pkt_alloc_extern(mptsas_t *mpt, mptsas_cmd_t *cmd,
3869    int cmdlen, int tgtlen, int statuslen, int kf)
3870{
3871	caddr_t			cdbp, scbp, tgt;
3872	int			(*callback)(caddr_t) = (kf == KM_SLEEP) ?
3873	    DDI_DMA_SLEEP : DDI_DMA_DONTWAIT;
3874	struct scsi_address	ap;
3875	size_t			senselength;
3876	ddi_dma_attr_t		ext_arq_dma_attr;
3877	uint_t			cookiec;
3878
3879	NDBG3(("mptsas_pkt_alloc_extern: "
3880	    "cmd=0x%p cmdlen=%d tgtlen=%d statuslen=%d kf=%x",
3881	    (void *)cmd, cmdlen, tgtlen, statuslen, kf));
3882
3883	tgt = cdbp = scbp = NULL;
3884	cmd->cmd_scblen		= statuslen;
3885	cmd->cmd_privlen	= (uchar_t)tgtlen;
3886
3887	if (cmdlen > sizeof (cmd->cmd_cdb)) {
3888		if ((cdbp = kmem_zalloc((size_t)cmdlen, kf)) == NULL) {
3889			goto fail;
3890		}
3891		cmd->cmd_pkt->pkt_cdbp = (opaque_t)cdbp;
3892		cmd->cmd_flags |= CFLAG_CDBEXTERN;
3893	}
3894	if (tgtlen > PKT_PRIV_LEN) {
3895		if ((tgt = kmem_zalloc((size_t)tgtlen, kf)) == NULL) {
3896			goto fail;
3897		}
3898		cmd->cmd_flags |= CFLAG_PRIVEXTERN;
3899		cmd->cmd_pkt->pkt_private = tgt;
3900	}
3901	if (statuslen > EXTCMDS_STATUS_SIZE) {
3902		if ((scbp = kmem_zalloc((size_t)statuslen, kf)) == NULL) {
3903			goto fail;
3904		}
3905		cmd->cmd_flags |= CFLAG_SCBEXTERN;
3906		cmd->cmd_pkt->pkt_scbp = (opaque_t)scbp;
3907
3908		/* allocate sense data buf for DMA */
3909
3910		senselength = statuslen - MPTSAS_GET_ITEM_OFF(
3911		    struct scsi_arq_status, sts_sensedata);
3912		cmd->cmd_rqslen = (uchar_t)senselength;
3913
3914		ap.a_hba_tran = mpt->m_tran;
3915		ap.a_target = 0;
3916		ap.a_lun = 0;
3917
3918		cmd->cmd_ext_arq_buf = scsi_alloc_consistent_buf(&ap,
3919		    (struct buf *)NULL, senselength, B_READ,
3920		    callback, NULL);
3921
3922		if (cmd->cmd_ext_arq_buf == NULL) {
3923			goto fail;
3924		}
3925		/*
3926		 * allocate a extern arq handle and bind the buf
3927		 */
3928		ext_arq_dma_attr = mpt->m_msg_dma_attr;
3929		ext_arq_dma_attr.dma_attr_sgllen = 1;
3930		if ((ddi_dma_alloc_handle(mpt->m_dip,
3931		    &ext_arq_dma_attr, callback,
3932		    NULL, &cmd->cmd_ext_arqhandle)) != DDI_SUCCESS) {
3933			goto fail;
3934		}
3935
3936		if (ddi_dma_buf_bind_handle(cmd->cmd_ext_arqhandle,
3937		    cmd->cmd_ext_arq_buf, (DDI_DMA_READ | DDI_DMA_CONSISTENT),
3938		    callback, NULL, &cmd->cmd_ext_arqcookie,
3939		    &cookiec)
3940		    != DDI_SUCCESS) {
3941			goto fail;
3942		}
3943		cmd->cmd_flags |= CFLAG_EXTARQBUFVALID;
3944	}
3945	return (0);
3946fail:
3947	mptsas_pkt_destroy_extern(mpt, cmd);
3948	return (1);
3949}
3950
3951/*
3952 * deallocate external pkt space and deallocate the pkt
3953 */
3954static void
3955mptsas_pkt_destroy_extern(mptsas_t *mpt, mptsas_cmd_t *cmd)
3956{
3957	NDBG3(("mptsas_pkt_destroy_extern: cmd=0x%p", (void *)cmd));
3958
3959	if (cmd->cmd_flags & CFLAG_FREE) {
3960		mptsas_log(mpt, CE_PANIC,
3961		    "mptsas_pkt_destroy_extern: freeing free packet");
3962		_NOTE(NOT_REACHED)
3963		/* NOTREACHED */
3964	}
3965	if (cmd->cmd_flags & CFLAG_CDBEXTERN) {
3966		kmem_free(cmd->cmd_pkt->pkt_cdbp, (size_t)cmd->cmd_cdblen);
3967	}
3968	if (cmd->cmd_flags & CFLAG_SCBEXTERN) {
3969		kmem_free(cmd->cmd_pkt->pkt_scbp, (size_t)cmd->cmd_scblen);
3970		if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) {
3971			(void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle);
3972		}
3973		if (cmd->cmd_ext_arqhandle) {
3974			ddi_dma_free_handle(&cmd->cmd_ext_arqhandle);
3975			cmd->cmd_ext_arqhandle = NULL;
3976		}
3977		if (cmd->cmd_ext_arq_buf)
3978			scsi_free_consistent_buf(cmd->cmd_ext_arq_buf);
3979	}
3980	if (cmd->cmd_flags & CFLAG_PRIVEXTERN) {
3981		kmem_free(cmd->cmd_pkt->pkt_private, (size_t)cmd->cmd_privlen);
3982	}
3983	cmd->cmd_flags = CFLAG_FREE;
3984	kmem_cache_free(mpt->m_kmem_cache, (void *)cmd);
3985}
3986
3987/*
3988 * tran_sync_pkt(9E) - explicit DMA synchronization
3989 */
3990/*ARGSUSED*/
3991static void
3992mptsas_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
3993{
3994	mptsas_cmd_t	*cmd = PKT2CMD(pkt);
3995
3996	NDBG3(("mptsas_scsi_sync_pkt: target=%d, pkt=0x%p",
3997	    ap->a_target, (void *)pkt));
3998
3999	if (cmd->cmd_dmahandle) {
4000		(void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
4001		    (cmd->cmd_flags & CFLAG_DMASEND) ?
4002		    DDI_DMA_SYNC_FORDEV : DDI_DMA_SYNC_FORCPU);
4003	}
4004}
4005
4006/*
4007 * tran_dmafree(9E) - deallocate DMA resources allocated for command
4008 */
4009/*ARGSUSED*/
4010static void
4011mptsas_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
4012{
4013	mptsas_cmd_t	*cmd = PKT2CMD(pkt);
4014	mptsas_t	*mpt = ADDR2MPT(ap);
4015
4016	NDBG3(("mptsas_scsi_dmafree: target=%d pkt=0x%p",
4017	    ap->a_target, (void *)pkt));
4018
4019	if (cmd->cmd_flags & CFLAG_DMAVALID) {
4020		(void) ddi_dma_unbind_handle(cmd->cmd_dmahandle);
4021		cmd->cmd_flags &= ~CFLAG_DMAVALID;
4022	}
4023
4024	if (cmd->cmd_flags & CFLAG_EXTARQBUFVALID) {
4025		(void) ddi_dma_unbind_handle(cmd->cmd_ext_arqhandle);
4026		cmd->cmd_flags &= ~CFLAG_EXTARQBUFVALID;
4027	}
4028
4029	mptsas_free_extra_sgl_frame(mpt, cmd);
4030}
4031
4032static void
4033mptsas_pkt_comp(struct scsi_pkt *pkt, mptsas_cmd_t *cmd)
4034{
4035	if ((cmd->cmd_flags & CFLAG_CMDIOPB) &&
4036	    (!(cmd->cmd_flags & CFLAG_DMASEND))) {
4037		(void) ddi_dma_sync(cmd->cmd_dmahandle, 0, 0,
4038		    DDI_DMA_SYNC_FORCPU);
4039	}
4040	(*pkt->pkt_comp)(pkt);
4041}
4042
4043static void
4044mptsas_sge_setup(mptsas_t *mpt, mptsas_cmd_t *cmd, uint32_t *control,
4045	pMpi2SCSIIORequest_t frame, ddi_acc_handle_t acc_hdl)
4046{
4047	uint_t			cookiec;
4048	mptti_t			*dmap;
4049	uint32_t		flags;
4050	pMpi2SGESimple64_t	sge;
4051	pMpi2SGEChain64_t	sgechain;
4052	ASSERT(cmd->cmd_flags & CFLAG_DMAVALID);
4053
4054	/*
4055	 * Save the number of entries in the DMA
4056	 * Scatter/Gather list
4057	 */
4058	cookiec = cmd->cmd_cookiec;
4059
4060	NDBG1(("mptsas_sge_setup: cookiec=%d", cookiec));
4061
4062	/*
4063	 * Set read/write bit in control.
4064	 */
4065	if (cmd->cmd_flags & CFLAG_DMASEND) {
4066		*control |= MPI2_SCSIIO_CONTROL_WRITE;
4067	} else {
4068		*control |= MPI2_SCSIIO_CONTROL_READ;
4069	}
4070
4071	ddi_put32(acc_hdl, &frame->DataLength, cmd->cmd_dmacount);
4072
4073	/*
4074	 * We have 2 cases here.  First where we can fit all the
4075	 * SG elements into the main frame, and the case
4076	 * where we can't.
4077	 * If we have more cookies than we can attach to a frame
4078	 * we will need to use a chain element to point
4079	 * a location of memory where the rest of the S/G
4080	 * elements reside.
4081	 */
4082	if (cookiec <= MPTSAS_MAX_FRAME_SGES64(mpt)) {
4083		dmap = cmd->cmd_sg;
4084		sge = (pMpi2SGESimple64_t)(&frame->SGL);
4085		while (cookiec--) {
4086			ddi_put32(acc_hdl,
4087			    &sge->Address.Low, dmap->addr.address64.Low);
4088			ddi_put32(acc_hdl,
4089			    &sge->Address.High, dmap->addr.address64.High);
4090			ddi_put32(acc_hdl, &sge->FlagsLength,
4091			    dmap->count);
4092			flags = ddi_get32(acc_hdl, &sge->FlagsLength);
4093			flags |= ((uint32_t)
4094			    (MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4095			    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4096			    MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4097			    MPI2_SGE_FLAGS_SHIFT);
4098
4099			/*
4100			 * If this is the last cookie, we set the flags
4101			 * to indicate so
4102			 */
4103			if (cookiec == 0) {
4104				flags |=
4105				    ((uint32_t)(MPI2_SGE_FLAGS_LAST_ELEMENT
4106				    | MPI2_SGE_FLAGS_END_OF_BUFFER
4107				    | MPI2_SGE_FLAGS_END_OF_LIST) <<
4108				    MPI2_SGE_FLAGS_SHIFT);
4109			}
4110			if (cmd->cmd_flags & CFLAG_DMASEND) {
4111				flags |= (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4112				    MPI2_SGE_FLAGS_SHIFT);
4113			} else {
4114				flags |= (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4115				    MPI2_SGE_FLAGS_SHIFT);
4116			}
4117			ddi_put32(acc_hdl, &sge->FlagsLength, flags);
4118			dmap++;
4119			sge++;
4120		}
4121	} else {
4122		/*
4123		 * Hereby we start to deal with multiple frames.
4124		 * The process is as follows:
4125		 * 1. Determine how many frames are needed for SGL element
4126		 *    storage; Note that all frames are stored in contiguous
4127		 *    memory space and in 64-bit DMA mode each element is
4128		 *    3 double-words (12 bytes) long.
4129		 * 2. Fill up the main frame. We need to do this separately
4130		 *    since it contains the SCSI IO request header and needs
4131		 *    dedicated processing. Note that the last 4 double-words
4132		 *    of the SCSI IO header is for SGL element storage
4133		 *    (MPI2_SGE_IO_UNION).
4134		 * 3. Fill the chain element in the main frame, so the DMA
4135		 *    engine can use the following frames.
4136		 * 4. Enter a loop to fill the remaining frames. Note that the
4137		 *    last frame contains no chain element.  The remaining
4138		 *    frames go into the mpt SGL buffer allocated on the fly,
4139		 *    not immediately following the main message frame, as in
4140		 *    Gen1.
4141		 * Some restrictions:
4142		 * 1. For 64-bit DMA, the simple element and chain element
4143		 *    are both of 3 double-words (12 bytes) in size, even
4144		 *    though all frames are stored in the first 4G of mem
4145		 *    range and the higher 32-bits of the address are always 0.
4146		 * 2. On some controllers (like the 1064/1068), a frame can
4147		 *    hold SGL elements with the last 1 or 2 double-words
4148		 *    (4 or 8 bytes) un-used. On these controllers, we should
4149		 *    recognize that there's not enough room for another SGL
4150		 *    element and move the sge pointer to the next frame.
4151		 */
4152		int		i, j, k, l, frames, sgemax;
4153		int		temp;
4154		uint8_t		chainflags;
4155		uint16_t	chainlength;
4156		mptsas_cache_frames_t *p;
4157
4158		/*
4159		 * Sgemax is the number of SGE's that will fit
4160		 * each extra frame and frames is total
4161		 * number of frames we'll need.  1 sge entry per
4162		 * frame is reseverd for the chain element thus the -1 below.
4163		 */
4164		sgemax = ((mpt->m_req_frame_size / sizeof (MPI2_SGE_SIMPLE64))
4165		    - 1);
4166		temp = (cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) / sgemax;
4167
4168		/*
4169		 * A little check to see if we need to round up the number
4170		 * of frames we need
4171		 */
4172		if ((cookiec - (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) - (temp *
4173		    sgemax) > 1) {
4174			frames = (temp + 1);
4175		} else {
4176			frames = temp;
4177		}
4178		dmap = cmd->cmd_sg;
4179		sge = (pMpi2SGESimple64_t)(&frame->SGL);
4180
4181		/*
4182		 * First fill in the main frame
4183		 */
4184		for (j = 1; j < MPTSAS_MAX_FRAME_SGES64(mpt); j++) {
4185			ddi_put32(acc_hdl, &sge->Address.Low,
4186			    dmap->addr.address64.Low);
4187			ddi_put32(acc_hdl, &sge->Address.High,
4188			    dmap->addr.address64.High);
4189			ddi_put32(acc_hdl, &sge->FlagsLength, dmap->count);
4190			flags = ddi_get32(acc_hdl, &sge->FlagsLength);
4191			flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4192			    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4193			    MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4194			    MPI2_SGE_FLAGS_SHIFT);
4195
4196			/*
4197			 * If this is the last SGE of this frame
4198			 * we set the end of list flag
4199			 */
4200			if (j == (MPTSAS_MAX_FRAME_SGES64(mpt) - 1)) {
4201				flags |= ((uint32_t)
4202				    (MPI2_SGE_FLAGS_LAST_ELEMENT) <<
4203				    MPI2_SGE_FLAGS_SHIFT);
4204			}
4205			if (cmd->cmd_flags & CFLAG_DMASEND) {
4206				flags |=
4207				    (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4208				    MPI2_SGE_FLAGS_SHIFT);
4209			} else {
4210				flags |=
4211				    (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4212				    MPI2_SGE_FLAGS_SHIFT);
4213			}
4214			ddi_put32(acc_hdl, &sge->FlagsLength, flags);
4215			dmap++;
4216			sge++;
4217		}
4218
4219		/*
4220		 * Fill in the chain element in the main frame.
4221		 * About calculation on ChainOffset:
4222		 * 1. Struct msg_scsi_io_request has 4 double-words (16 bytes)
4223		 *    in the end reserved for SGL element storage
4224		 *    (MPI2_SGE_IO_UNION); we should count it in our
4225		 *    calculation.  See its definition in the header file.
4226		 * 2. Constant j is the counter of the current SGL element
4227		 *    that will be processed, and (j - 1) is the number of
4228		 *    SGL elements that have been processed (stored in the
4229		 *    main frame).
4230		 * 3. ChainOffset value should be in units of double-words (4
4231		 *    bytes) so the last value should be divided by 4.
4232		 */
4233		ddi_put8(acc_hdl, &frame->ChainOffset,
4234		    (sizeof (MPI2_SCSI_IO_REQUEST) -
4235		    sizeof (MPI2_SGE_IO_UNION) +
4236		    (j - 1) * sizeof (MPI2_SGE_SIMPLE64)) >> 2);
4237		sgechain = (pMpi2SGEChain64_t)sge;
4238		chainflags = (MPI2_SGE_FLAGS_CHAIN_ELEMENT |
4239		    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4240		    MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
4241		ddi_put8(acc_hdl, &sgechain->Flags, chainflags);
4242
4243		/*
4244		 * The size of the next frame is the accurate size of space
4245		 * (in bytes) used to store the SGL elements. j is the counter
4246		 * of SGL elements. (j - 1) is the number of SGL elements that
4247		 * have been processed (stored in frames).
4248		 */
4249		if (frames >= 2) {
4250			chainlength = mpt->m_req_frame_size /
4251			    sizeof (MPI2_SGE_SIMPLE64) *
4252			    sizeof (MPI2_SGE_SIMPLE64);
4253		} else {
4254			chainlength = ((cookiec - (j - 1)) *
4255			    sizeof (MPI2_SGE_SIMPLE64));
4256		}
4257
4258		p = cmd->cmd_extra_frames;
4259
4260		ddi_put16(acc_hdl, &sgechain->Length, chainlength);
4261		ddi_put32(acc_hdl, &sgechain->Address.Low,
4262		    p->m_phys_addr);
4263		/* SGL is allocated in the first 4G mem range */
4264		ddi_put32(acc_hdl, &sgechain->Address.High, 0);
4265
4266		/*
4267		 * If there are more than 2 frames left we have to
4268		 * fill in the next chain offset to the location of
4269		 * the chain element in the next frame.
4270		 * sgemax is the number of simple elements in an extra
4271		 * frame. Note that the value NextChainOffset should be
4272		 * in double-words (4 bytes).
4273		 */
4274		if (frames >= 2) {
4275			ddi_put8(acc_hdl, &sgechain->NextChainOffset,
4276			    (sgemax * sizeof (MPI2_SGE_SIMPLE64)) >> 2);
4277		} else {
4278			ddi_put8(acc_hdl, &sgechain->NextChainOffset, 0);
4279		}
4280
4281		/*
4282		 * Jump to next frame;
4283		 * Starting here, chain buffers go into the per command SGL.
4284		 * This buffer is allocated when chain buffers are needed.
4285		 */
4286		sge = (pMpi2SGESimple64_t)p->m_frames_addr;
4287		i = cookiec;
4288
4289		/*
4290		 * Start filling in frames with SGE's.  If we
4291		 * reach the end of frame and still have SGE's
4292		 * to fill we need to add a chain element and
4293		 * use another frame.  j will be our counter
4294		 * for what cookie we are at and i will be
4295		 * the total cookiec. k is the current frame
4296		 */
4297		for (k = 1; k <= frames; k++) {
4298			for (l = 1; (l <= (sgemax + 1)) && (j <= i); j++, l++) {
4299
4300				/*
4301				 * If we have reached the end of frame
4302				 * and we have more SGE's to fill in
4303				 * we have to fill the final entry
4304				 * with a chain element and then
4305				 * continue to the next frame
4306				 */
4307				if ((l == (sgemax + 1)) && (k != frames)) {
4308					sgechain = (pMpi2SGEChain64_t)sge;
4309					j--;
4310					chainflags = (
4311					    MPI2_SGE_FLAGS_CHAIN_ELEMENT |
4312					    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4313					    MPI2_SGE_FLAGS_64_BIT_ADDRESSING);
4314					ddi_put8(p->m_acc_hdl,
4315					    &sgechain->Flags, chainflags);
4316					/*
4317					 * k is the frame counter and (k + 1)
4318					 * is the number of the next frame.
4319					 * Note that frames are in contiguous
4320					 * memory space.
4321					 */
4322					ddi_put32(p->m_acc_hdl,
4323					    &sgechain->Address.Low,
4324					    (p->m_phys_addr +
4325					    (mpt->m_req_frame_size * k)));
4326					ddi_put32(p->m_acc_hdl,
4327					    &sgechain->Address.High, 0);
4328
4329					/*
4330					 * If there are more than 2 frames left
4331					 * we have to next chain offset to
4332					 * the location of the chain element
4333					 * in the next frame and fill in the
4334					 * length of the next chain
4335					 */
4336					if ((frames - k) >= 2) {
4337						ddi_put8(p->m_acc_hdl,
4338						    &sgechain->NextChainOffset,
4339						    (sgemax *
4340						    sizeof (MPI2_SGE_SIMPLE64))
4341						    >> 2);
4342						ddi_put16(p->m_acc_hdl,
4343						    &sgechain->Length,
4344						    mpt->m_req_frame_size /
4345						    sizeof (MPI2_SGE_SIMPLE64) *
4346						    sizeof (MPI2_SGE_SIMPLE64));
4347					} else {
4348						/*
4349						 * This is the last frame. Set
4350						 * the NextChainOffset to 0 and
4351						 * Length is the total size of
4352						 * all remaining simple elements
4353						 */
4354						ddi_put8(p->m_acc_hdl,
4355						    &sgechain->NextChainOffset,
4356						    0);
4357						ddi_put16(p->m_acc_hdl,
4358						    &sgechain->Length,
4359						    (cookiec - j) *
4360						    sizeof (MPI2_SGE_SIMPLE64));
4361					}
4362
4363					/* Jump to the next frame */
4364					sge = (pMpi2SGESimple64_t)
4365					    ((char *)p->m_frames_addr +
4366					    (int)mpt->m_req_frame_size * k);
4367
4368					continue;
4369				}
4370
4371				ddi_put32(p->m_acc_hdl,
4372				    &sge->Address.Low,
4373				    dmap->addr.address64.Low);
4374				ddi_put32(p->m_acc_hdl,
4375				    &sge->Address.High,
4376				    dmap->addr.address64.High);
4377				ddi_put32(p->m_acc_hdl,
4378				    &sge->FlagsLength, dmap->count);
4379				flags = ddi_get32(p->m_acc_hdl,
4380				    &sge->FlagsLength);
4381				flags |= ((uint32_t)(
4382				    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
4383				    MPI2_SGE_FLAGS_SYSTEM_ADDRESS |
4384				    MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
4385				    MPI2_SGE_FLAGS_SHIFT);
4386
4387				/*
4388				 * If we are at the end of the frame and
4389				 * there is another frame to fill in
4390				 * we set the last simple element as last
4391				 * element
4392				 */
4393				if ((l == sgemax) && (k != frames)) {
4394					flags |= ((uint32_t)
4395					    (MPI2_SGE_FLAGS_LAST_ELEMENT) <<
4396					    MPI2_SGE_FLAGS_SHIFT);
4397				}
4398
4399				/*
4400				 * If this is the final cookie we
4401				 * indicate it by setting the flags
4402				 */
4403				if (j == i) {
4404					flags |= ((uint32_t)
4405					    (MPI2_SGE_FLAGS_LAST_ELEMENT |
4406					    MPI2_SGE_FLAGS_END_OF_BUFFER |
4407					    MPI2_SGE_FLAGS_END_OF_LIST) <<
4408					    MPI2_SGE_FLAGS_SHIFT);
4409				}
4410				if (cmd->cmd_flags & CFLAG_DMASEND) {
4411					flags |=
4412					    (MPI2_SGE_FLAGS_HOST_TO_IOC <<
4413					    MPI2_SGE_FLAGS_SHIFT);
4414				} else {
4415					flags |=
4416					    (MPI2_SGE_FLAGS_IOC_TO_HOST <<
4417					    MPI2_SGE_FLAGS_SHIFT);
4418				}
4419				ddi_put32(p->m_acc_hdl,
4420				    &sge->FlagsLength, flags);
4421				dmap++;
4422				sge++;
4423			}
4424		}
4425
4426		/*
4427		 * Sync DMA with the chain buffers that were just created
4428		 */
4429		(void) ddi_dma_sync(p->m_dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
4430	}
4431}
4432
4433/*
4434 * Interrupt handling
4435 * Utility routine.  Poll for status of a command sent to HBA
4436 * without interrupts (a FLAG_NOINTR command).
4437 */
4438int
4439mptsas_poll(mptsas_t *mpt, mptsas_cmd_t *poll_cmd, int polltime)
4440{
4441	int	rval = TRUE;
4442
4443	NDBG5(("mptsas_poll: cmd=0x%p", (void *)poll_cmd));
4444
4445	if ((poll_cmd->cmd_flags & CFLAG_TM_CMD) == 0) {
4446		mptsas_restart_hba(mpt);
4447	}
4448
4449	/*
4450	 * Wait, using drv_usecwait(), long enough for the command to
4451	 * reasonably return from the target if the target isn't
4452	 * "dead".  A polled command may well be sent from scsi_poll, and
4453	 * there are retries built in to scsi_poll if the transport
4454	 * accepted the packet (TRAN_ACCEPT).  scsi_poll waits 1 second
4455	 * and retries the transport up to scsi_poll_busycnt times
4456	 * (currently 60) if
4457	 * 1. pkt_reason is CMD_INCOMPLETE and pkt_state is 0, or
4458	 * 2. pkt_reason is CMD_CMPLT and *pkt_scbp has STATUS_BUSY
4459	 *
4460	 * limit the waiting to avoid a hang in the event that the
4461	 * cmd never gets started but we are still receiving interrupts
4462	 */
4463	while (!(poll_cmd->cmd_flags & CFLAG_FINISHED)) {
4464		if (mptsas_wait_intr(mpt, polltime) == FALSE) {
4465			NDBG5(("mptsas_poll: command incomplete"));
4466			rval = FALSE;
4467			break;
4468		}
4469	}
4470
4471	if (rval == FALSE) {
4472
4473		/*
4474		 * this isn't supposed to happen, the hba must be wedged
4475		 * Mark this cmd as a timeout.
4476		 */
4477		mptsas_set_pkt_reason(mpt, poll_cmd, CMD_TIMEOUT,
4478		    (STAT_TIMEOUT|STAT_ABORTED));
4479
4480		if (poll_cmd->cmd_queued == FALSE) {
4481
4482			NDBG5(("mptsas_poll: not on waitq"));
4483
4484			poll_cmd->cmd_pkt->pkt_state |=
4485			    (STATE_GOT_BUS|STATE_GOT_TARGET|STATE_SENT_CMD);
4486		} else {
4487
4488			/* find and remove it from the waitq */
4489			NDBG5(("mptsas_poll: delete from waitq"));
4490			mptsas_waitq_delete(mpt, poll_cmd);
4491		}
4492
4493	}
4494	mptsas_fma_check(mpt, poll_cmd);
4495	NDBG5(("mptsas_poll: done"));
4496	return (rval);
4497}
4498
4499/*
4500 * Used for polling cmds and TM function
4501 */
4502static int
4503mptsas_wait_intr(mptsas_t *mpt, int polltime)
4504{
4505	int				cnt;
4506	uint32_t			reply_index;
4507	pMpi2ReplyDescriptorsUnion_t	reply_desc_union;
4508
4509	NDBG5(("mptsas_wait_intr"));
4510
4511	/*
4512	 * Keep polling for at least (polltime * 1000) seconds
4513	 */
4514	reply_index = mpt->m_post_index;
4515	for (cnt = 0; cnt < polltime; cnt++) {
4516		reply_desc_union = (pMpi2ReplyDescriptorsUnion_t)
4517		    MPTSAS_GET_NEXT_REPLY(mpt, reply_index);
4518
4519		if (ddi_get32(mpt->m_acc_post_queue_hdl,
4520		    &reply_desc_union->Words.Low) == 0xFFFFFFFF ||
4521		    ddi_get32(mpt->m_acc_post_queue_hdl,
4522		    &reply_desc_union->Words.High) == 0xFFFFFFFF) {
4523			drv_usecwait(1000);
4524			continue;
4525		}
4526		mpt->m_polled_intr = 1;
4527		/*
4528		 * The reply is valid, process it according to its
4529		 * type.  Also, set a flag for updated the reply index
4530		 * after they've all been processed.
4531		 */
4532		mptsas_process_intr(mpt, reply_desc_union);
4533
4534		if (++reply_index == mpt->m_post_queue_depth) {
4535			reply_index = 0;
4536		}
4537		/*
4538		 * Update the global reply index
4539		 */
4540		mpt->m_post_index = reply_index;
4541		ddi_put32(mpt->m_datap,
4542		    &mpt->m_reg->ReplyPostHostIndex, reply_index);
4543
4544		return (TRUE);
4545
4546	}
4547	return (FALSE);
4548}
4549
4550static void
4551mptsas_handle_scsi_io_success(mptsas_t *mpt,
4552    pMpi2ReplyDescriptorsUnion_t reply_desc)
4553{
4554	pMpi2SCSIIOSuccessReplyDescriptor_t	scsi_io_success;
4555	uint16_t				SMID;
4556	mptsas_slots_t				*slots = mpt->m_active;
4557	mptsas_cmd_t				*cmd = NULL;
4558	struct scsi_pkt				*pkt;
4559
4560	ASSERT(mutex_owned(&mpt->m_mutex));
4561
4562	scsi_io_success = (pMpi2SCSIIOSuccessReplyDescriptor_t)reply_desc;
4563	SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &scsi_io_success->SMID);
4564
4565	/*
4566	 * This is a success reply so just complete the IO.  First, do a sanity
4567	 * check on the SMID.  The final slot is used for TM requests, which
4568	 * would not come into this reply handler.
4569	 */
4570	if ((SMID == 0) || (SMID > slots->m_n_slots)) {
4571		mptsas_log(mpt, CE_WARN, "?Received invalid SMID of %d\n",
4572		    SMID);
4573		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
4574		return;
4575	}
4576
4577	cmd = slots->m_slot[SMID];
4578
4579	/*
4580	 * print warning and return if the slot is empty
4581	 */
4582	if (cmd == NULL) {
4583		mptsas_log(mpt, CE_WARN, "?NULL command for successful SCSI IO "
4584		    "in slot %d", SMID);
4585		return;
4586	}
4587
4588	pkt = CMD2PKT(cmd);
4589	pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET | STATE_SENT_CMD |
4590	    STATE_GOT_STATUS);
4591	if (cmd->cmd_flags & CFLAG_DMAVALID) {
4592		pkt->pkt_state |= STATE_XFERRED_DATA;
4593	}
4594	pkt->pkt_resid = 0;
4595
4596	if (cmd->cmd_flags & CFLAG_PASSTHRU) {
4597		cmd->cmd_flags |= CFLAG_FINISHED;
4598		cv_broadcast(&mpt->m_passthru_cv);
4599		return;
4600	} else {
4601		mptsas_remove_cmd(mpt, cmd);
4602	}
4603
4604	if (cmd->cmd_flags & CFLAG_RETRY) {
4605		/*
4606		 * The target returned QFULL or busy, do not add tihs
4607		 * pkt to the doneq since the hba will retry
4608		 * this cmd.
4609		 *
4610		 * The pkt has already been resubmitted in
4611		 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error().
4612		 * Remove this cmd_flag here.
4613		 */
4614		cmd->cmd_flags &= ~CFLAG_RETRY;
4615	} else {
4616		mptsas_doneq_add(mpt, cmd);
4617	}
4618}
4619
4620static void
4621mptsas_handle_address_reply(mptsas_t *mpt,
4622    pMpi2ReplyDescriptorsUnion_t reply_desc)
4623{
4624	pMpi2AddressReplyDescriptor_t	address_reply;
4625	pMPI2DefaultReply_t		reply;
4626	uint32_t			reply_addr, reply_index;
4627	uint16_t			SMID;
4628	mptsas_slots_t			*slots = mpt->m_active;
4629	mptsas_cmd_t			*cmd = NULL;
4630	uint8_t				function;
4631	m_replyh_arg_t			*args;
4632	int				reply_frame_no;
4633
4634	ASSERT(mutex_owned(&mpt->m_mutex));
4635
4636	address_reply = (pMpi2AddressReplyDescriptor_t)reply_desc;
4637	reply_addr = ddi_get32(mpt->m_acc_post_queue_hdl,
4638	    &address_reply->ReplyFrameAddress);
4639	SMID = ddi_get16(mpt->m_acc_post_queue_hdl, &address_reply->SMID);
4640
4641	/*
4642	 * If reply frame is not in the proper range we should ignore this
4643	 * message and exit the interrupt handler.
4644	 */
4645	if ((reply_addr < mpt->m_reply_frame_dma_addr) ||
4646	    (reply_addr >= (mpt->m_reply_frame_dma_addr +
4647	    (mpt->m_reply_frame_size * mpt->m_free_queue_depth))) ||
4648	    ((reply_addr - mpt->m_reply_frame_dma_addr) %
4649	    mpt->m_reply_frame_size != 0)) {
4650		mptsas_log(mpt, CE_WARN, "?Received invalid reply frame "
4651		    "address 0x%x\n", reply_addr);
4652		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
4653		return;
4654	}
4655
4656	(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
4657	    DDI_DMA_SYNC_FORCPU);
4658	reply = (pMPI2DefaultReply_t)(mpt->m_reply_frame + (reply_addr -
4659	    mpt->m_reply_frame_dma_addr));
4660	function = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->Function);
4661
4662	/*
4663	 * don't get slot information and command for events since these values
4664	 * don't exist
4665	 */
4666	if (function != MPI2_FUNCTION_EVENT_NOTIFICATION) {
4667		/*
4668		 * This could be a TM reply, which use the last allocated SMID,
4669		 * so allow for that.
4670		 */
4671		if ((SMID == 0) || (SMID > (slots->m_n_slots + 1))) {
4672			mptsas_log(mpt, CE_WARN, "?Received invalid SMID of "
4673			    "%d\n", SMID);
4674			ddi_fm_service_impact(mpt->m_dip,
4675			    DDI_SERVICE_UNAFFECTED);
4676			return;
4677		}
4678
4679		cmd = slots->m_slot[SMID];
4680
4681		/*
4682		 * print warning and return if the slot is empty
4683		 */
4684		if (cmd == NULL) {
4685			mptsas_log(mpt, CE_WARN, "?NULL command for address "
4686			    "reply in slot %d", SMID);
4687			return;
4688		}
4689		if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
4690		    (cmd->cmd_flags & CFLAG_CONFIG)) {
4691			cmd->cmd_rfm = reply_addr;
4692			cmd->cmd_flags |= CFLAG_FINISHED;
4693			cv_broadcast(&mpt->m_passthru_cv);
4694			cv_broadcast(&mpt->m_config_cv);
4695			return;
4696		} else if (!(cmd->cmd_flags & CFLAG_FW_CMD)) {
4697			mptsas_remove_cmd(mpt, cmd);
4698		}
4699		NDBG31(("\t\tmptsas_process_intr: slot=%d", SMID));
4700	}
4701	/*
4702	 * Depending on the function, we need to handle
4703	 * the reply frame (and cmd) differently.
4704	 */
4705	switch (function) {
4706	case MPI2_FUNCTION_SCSI_IO_REQUEST:
4707		mptsas_check_scsi_io_error(mpt, (pMpi2SCSIIOReply_t)reply, cmd);
4708		break;
4709	case MPI2_FUNCTION_SCSI_TASK_MGMT:
4710		mptsas_check_task_mgt(mpt, (pMpi2SCSIManagementReply_t)reply,
4711		    cmd);
4712		break;
4713	case MPI2_FUNCTION_FW_DOWNLOAD:
4714		cmd->cmd_flags |= CFLAG_FINISHED;
4715		cv_signal(&mpt->m_fw_cv);
4716		break;
4717	case MPI2_FUNCTION_EVENT_NOTIFICATION:
4718		reply_frame_no = (reply_addr - mpt->m_reply_frame_dma_addr) /
4719		    mpt->m_reply_frame_size;
4720		args = &mpt->m_replyh_args[reply_frame_no];
4721		args->mpt = (void *)mpt;
4722		args->rfm = reply_addr;
4723
4724		/*
4725		 * Record the event if its type is enabled in
4726		 * this mpt instance by ioctl.
4727		 */
4728		mptsas_record_event(args);
4729
4730		/*
4731		 * Handle time critical events
4732		 * NOT_RESPONDING/ADDED only now
4733		 */
4734		if (mptsas_handle_event_sync(args) == DDI_SUCCESS) {
4735			/*
4736			 * Would not return main process,
4737			 * just let taskq resolve ack action
4738			 * and ack would be sent in taskq thread
4739			 */
4740			NDBG20(("send mptsas_handle_event_sync success"));
4741		}
4742		if ((ddi_taskq_dispatch(mpt->m_event_taskq, mptsas_handle_event,
4743		    (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) {
4744			mptsas_log(mpt, CE_WARN, "No memory available"
4745			"for dispatch taskq");
4746			/*
4747			 * Return the reply frame to the free queue.
4748			 */
4749			reply_index = mpt->m_free_index;
4750			ddi_put32(mpt->m_acc_free_queue_hdl,
4751			    &((uint32_t *)(void *)
4752			    mpt->m_free_queue)[reply_index], reply_addr);
4753			(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
4754			    DDI_DMA_SYNC_FORDEV);
4755			if (++reply_index == mpt->m_free_queue_depth) {
4756				reply_index = 0;
4757			}
4758			mpt->m_free_index = reply_index;
4759
4760			ddi_put32(mpt->m_datap,
4761			    &mpt->m_reg->ReplyFreeHostIndex, reply_index);
4762		}
4763		return;
4764	default:
4765		mptsas_log(mpt, CE_WARN, "Unknown function 0x%x ", function);
4766		break;
4767	}
4768
4769	/*
4770	 * Return the reply frame to the free queue.
4771	 */
4772	reply_index = mpt->m_free_index;
4773	ddi_put32(mpt->m_acc_free_queue_hdl,
4774	    &((uint32_t *)(void *)mpt->m_free_queue)[reply_index],
4775	    reply_addr);
4776	(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
4777	    DDI_DMA_SYNC_FORDEV);
4778	if (++reply_index == mpt->m_free_queue_depth) {
4779		reply_index = 0;
4780	}
4781	mpt->m_free_index = reply_index;
4782	ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, reply_index);
4783
4784	if (cmd->cmd_flags & CFLAG_FW_CMD)
4785		return;
4786
4787	if (cmd->cmd_flags & CFLAG_RETRY) {
4788		/*
4789		 * The target returned QFULL or busy, do not add tihs
4790		 * pkt to the doneq since the hba will retry
4791		 * this cmd.
4792		 *
4793		 * The pkt has already been resubmitted in
4794		 * mptsas_handle_qfull() or in mptsas_check_scsi_io_error().
4795		 * Remove this cmd_flag here.
4796		 */
4797		cmd->cmd_flags &= ~CFLAG_RETRY;
4798	} else {
4799		struct scsi_pkt *pkt = CMD2PKT(cmd);
4800
4801		ASSERT((cmd->cmd_flags & CFLAG_COMPLETED) == 0);
4802		cmd->cmd_linkp = NULL;
4803		cmd->cmd_flags |= CFLAG_FINISHED;
4804		cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT;
4805
4806		if (pkt && pkt->pkt_comp) {
4807			cmd->cmd_flags |= CFLAG_COMPLETED;
4808			mutex_exit(&mpt->m_mutex);
4809			mptsas_pkt_comp(pkt, cmd);
4810			mutex_enter(&mpt->m_mutex);
4811		}
4812	}
4813}
4814
4815static void
4816mptsas_check_scsi_io_error(mptsas_t *mpt, pMpi2SCSIIOReply_t reply,
4817    mptsas_cmd_t *cmd)
4818{
4819	uint8_t			scsi_status, scsi_state;
4820	uint16_t		ioc_status;
4821	uint32_t		xferred, sensecount, loginfo = 0;
4822	struct scsi_pkt		*pkt;
4823	struct scsi_arq_status	*arqstat;
4824	struct buf		*bp;
4825	mptsas_target_t		*ptgt = cmd->cmd_tgt_addr;
4826	uint8_t			*sensedata = NULL;
4827
4828	if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) ==
4829	    (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) {
4830		bp = cmd->cmd_ext_arq_buf;
4831	} else {
4832		bp = cmd->cmd_arq_buf;
4833	}
4834
4835	scsi_status = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIStatus);
4836	ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus);
4837	scsi_state = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->SCSIState);
4838	xferred = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->TransferCount);
4839	sensecount = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->SenseCount);
4840
4841	if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
4842		loginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
4843		    &reply->IOCLogInfo);
4844		mptsas_log(mpt, CE_NOTE,
4845		    "?Log info 0x%x received for target %d.\n"
4846		    "\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x",
4847		    loginfo, Tgt(cmd), scsi_status, ioc_status,
4848		    scsi_state);
4849	}
4850
4851	NDBG31(("\t\tscsi_status=0x%x, ioc_status=0x%x, scsi_state=0x%x",
4852	    scsi_status, ioc_status, scsi_state));
4853
4854	pkt = CMD2PKT(cmd);
4855	*(pkt->pkt_scbp) = scsi_status;
4856
4857	if (loginfo == 0x31170000) {
4858		/*
4859		 * if loginfo PL_LOGINFO_CODE_IO_DEVICE_MISSING_DELAY_RETRY
4860		 * 0x31170000 comes, that means the device missing delay
4861		 * is in progressing, the command need retry later.
4862		 */
4863		*(pkt->pkt_scbp) = STATUS_BUSY;
4864		return;
4865	}
4866
4867	if ((scsi_state & MPI2_SCSI_STATE_NO_SCSI_STATUS) &&
4868	    ((ioc_status & MPI2_IOCSTATUS_MASK) ==
4869	    MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE)) {
4870		pkt->pkt_reason = CMD_INCOMPLETE;
4871		pkt->pkt_state |= STATE_GOT_BUS;
4872		if (ptgt->m_reset_delay == 0) {
4873			mptsas_set_throttle(mpt, ptgt,
4874			    DRAIN_THROTTLE);
4875		}
4876		return;
4877	}
4878
4879	switch (scsi_status) {
4880	case MPI2_SCSI_STATUS_CHECK_CONDITION:
4881		pkt->pkt_resid = (cmd->cmd_dmacount - xferred);
4882		arqstat = (void*)(pkt->pkt_scbp);
4883		arqstat->sts_rqpkt_status = *((struct scsi_status *)
4884		    (pkt->pkt_scbp));
4885		pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET |
4886		    STATE_SENT_CMD | STATE_GOT_STATUS | STATE_ARQ_DONE);
4887		if (cmd->cmd_flags & CFLAG_XARQ) {
4888			pkt->pkt_state |= STATE_XARQ_DONE;
4889		}
4890		if (pkt->pkt_resid != cmd->cmd_dmacount) {
4891			pkt->pkt_state |= STATE_XFERRED_DATA;
4892		}
4893		arqstat->sts_rqpkt_reason = pkt->pkt_reason;
4894		arqstat->sts_rqpkt_state  = pkt->pkt_state;
4895		arqstat->sts_rqpkt_state |= STATE_XFERRED_DATA;
4896		arqstat->sts_rqpkt_statistics = pkt->pkt_statistics;
4897		sensedata = (uint8_t *)&arqstat->sts_sensedata;
4898
4899		bcopy((uchar_t *)bp->b_un.b_addr, sensedata,
4900		    ((cmd->cmd_rqslen >= sensecount) ? sensecount :
4901		    cmd->cmd_rqslen));
4902		arqstat->sts_rqpkt_resid = (cmd->cmd_rqslen - sensecount);
4903		cmd->cmd_flags |= CFLAG_CMDARQ;
4904		/*
4905		 * Set proper status for pkt if autosense was valid
4906		 */
4907		if (scsi_state & MPI2_SCSI_STATE_AUTOSENSE_VALID) {
4908			struct scsi_status zero_status = { 0 };
4909			arqstat->sts_rqpkt_status = zero_status;
4910		}
4911
4912		/*
4913		 * ASC=0x47 is parity error
4914		 * ASC=0x48 is initiator detected error received
4915		 */
4916		if ((scsi_sense_key(sensedata) == KEY_ABORTED_COMMAND) &&
4917		    ((scsi_sense_asc(sensedata) == 0x47) ||
4918		    (scsi_sense_asc(sensedata) == 0x48))) {
4919			mptsas_log(mpt, CE_NOTE, "Aborted_command!");
4920		}
4921
4922		/*
4923		 * ASC/ASCQ=0x3F/0x0E means report_luns data changed
4924		 * ASC/ASCQ=0x25/0x00 means invalid lun
4925		 */
4926		if (((scsi_sense_key(sensedata) == KEY_UNIT_ATTENTION) &&
4927		    (scsi_sense_asc(sensedata) == 0x3F) &&
4928		    (scsi_sense_ascq(sensedata) == 0x0E)) ||
4929		    ((scsi_sense_key(sensedata) == KEY_ILLEGAL_REQUEST) &&
4930		    (scsi_sense_asc(sensedata) == 0x25) &&
4931		    (scsi_sense_ascq(sensedata) == 0x00))) {
4932			mptsas_topo_change_list_t *topo_node = NULL;
4933
4934			topo_node = kmem_zalloc(
4935			    sizeof (mptsas_topo_change_list_t),
4936			    KM_NOSLEEP);
4937			if (topo_node == NULL) {
4938				mptsas_log(mpt, CE_NOTE, "No memory"
4939				    "resource for handle SAS dynamic"
4940				    "reconfigure.\n");
4941				break;
4942			}
4943			topo_node->mpt = mpt;
4944			topo_node->event = MPTSAS_DR_EVENT_RECONFIG_TARGET;
4945			topo_node->un.phymask = ptgt->m_phymask;
4946			topo_node->devhdl = ptgt->m_devhdl;
4947			topo_node->object = (void *)ptgt;
4948			topo_node->flags = MPTSAS_TOPO_FLAG_LUN_ASSOCIATED;
4949
4950			if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
4951			    mptsas_handle_dr,
4952			    (void *)topo_node,
4953			    DDI_NOSLEEP)) != DDI_SUCCESS) {
4954				mptsas_log(mpt, CE_NOTE, "mptsas start taskq"
4955				    "for handle SAS dynamic reconfigure"
4956				    "failed. \n");
4957			}
4958		}
4959		break;
4960	case MPI2_SCSI_STATUS_GOOD:
4961		switch (ioc_status & MPI2_IOCSTATUS_MASK) {
4962		case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
4963			pkt->pkt_reason = CMD_DEV_GONE;
4964			pkt->pkt_state |= STATE_GOT_BUS;
4965			if (ptgt->m_reset_delay == 0) {
4966				mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
4967			}
4968			NDBG31(("lost disk for target%d, command:%x",
4969			    Tgt(cmd), pkt->pkt_cdbp[0]));
4970			break;
4971		case MPI2_IOCSTATUS_SCSI_DATA_OVERRUN:
4972			NDBG31(("data overrun: xferred=%d", xferred));
4973			NDBG31(("dmacount=%d", cmd->cmd_dmacount));
4974			pkt->pkt_reason = CMD_DATA_OVR;
4975			pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET
4976			    | STATE_SENT_CMD | STATE_GOT_STATUS
4977			    | STATE_XFERRED_DATA);
4978			pkt->pkt_resid = 0;
4979			break;
4980		case MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
4981		case MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN:
4982			NDBG31(("data underrun: xferred=%d", xferred));
4983			NDBG31(("dmacount=%d", cmd->cmd_dmacount));
4984			pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET
4985			    | STATE_SENT_CMD | STATE_GOT_STATUS);
4986			pkt->pkt_resid = (cmd->cmd_dmacount - xferred);
4987			if (pkt->pkt_resid != cmd->cmd_dmacount) {
4988				pkt->pkt_state |= STATE_XFERRED_DATA;
4989			}
4990			break;
4991		case MPI2_IOCSTATUS_SCSI_TASK_TERMINATED:
4992			mptsas_set_pkt_reason(mpt,
4993			    cmd, CMD_RESET, STAT_BUS_RESET);
4994			break;
4995		case MPI2_IOCSTATUS_SCSI_IOC_TERMINATED:
4996		case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
4997			mptsas_set_pkt_reason(mpt,
4998			    cmd, CMD_RESET, STAT_DEV_RESET);
4999			break;
5000		case MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR:
5001		case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
5002			pkt->pkt_state |= (STATE_GOT_BUS | STATE_GOT_TARGET);
5003			mptsas_set_pkt_reason(mpt,
5004			    cmd, CMD_TERMINATED, STAT_TERMINATED);
5005			break;
5006		case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES:
5007		case MPI2_IOCSTATUS_BUSY:
5008			/*
5009			 * set throttles to drain
5010			 */
5011			ptgt = (mptsas_target_t *)mptsas_hash_traverse(
5012			    &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
5013			while (ptgt != NULL) {
5014				mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5015
5016				ptgt = (mptsas_target_t *)mptsas_hash_traverse(
5017				    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
5018			}
5019
5020			/*
5021			 * retry command
5022			 */
5023			cmd->cmd_flags |= CFLAG_RETRY;
5024			cmd->cmd_pkt_flags |= FLAG_HEAD;
5025
5026			(void) mptsas_accept_pkt(mpt, cmd);
5027			break;
5028		default:
5029			mptsas_log(mpt, CE_WARN,
5030			    "unknown ioc_status = %x\n", ioc_status);
5031			mptsas_log(mpt, CE_CONT, "scsi_state = %x, transfer "
5032			    "count = %x, scsi_status = %x", scsi_state,
5033			    xferred, scsi_status);
5034			break;
5035		}
5036		break;
5037	case MPI2_SCSI_STATUS_TASK_SET_FULL:
5038		mptsas_handle_qfull(mpt, cmd);
5039		break;
5040	case MPI2_SCSI_STATUS_BUSY:
5041		NDBG31(("scsi_status busy received"));
5042		break;
5043	case MPI2_SCSI_STATUS_RESERVATION_CONFLICT:
5044		NDBG31(("scsi_status reservation conflict received"));
5045		break;
5046	default:
5047		mptsas_log(mpt, CE_WARN, "scsi_status=%x, ioc_status=%x\n",
5048		    scsi_status, ioc_status);
5049		mptsas_log(mpt, CE_WARN,
5050		    "mptsas_process_intr: invalid scsi status\n");
5051		break;
5052	}
5053}
5054
5055static void
5056mptsas_check_task_mgt(mptsas_t *mpt, pMpi2SCSIManagementReply_t reply,
5057	mptsas_cmd_t *cmd)
5058{
5059	uint8_t		task_type;
5060	uint16_t	ioc_status;
5061	uint32_t	log_info;
5062	uint16_t	dev_handle;
5063	struct scsi_pkt *pkt = CMD2PKT(cmd);
5064
5065	task_type = ddi_get8(mpt->m_acc_reply_frame_hdl, &reply->TaskType);
5066	ioc_status = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->IOCStatus);
5067	log_info = ddi_get32(mpt->m_acc_reply_frame_hdl, &reply->IOCLogInfo);
5068	dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl, &reply->DevHandle);
5069
5070	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
5071		mptsas_log(mpt, CE_WARN, "mptsas_check_task_mgt: Task 0x%x "
5072		    "failed. IOCStatus=0x%x IOCLogInfo=0x%x target=%d\n",
5073		    task_type, ioc_status, log_info, dev_handle);
5074		pkt->pkt_reason = CMD_INCOMPLETE;
5075		return;
5076	}
5077
5078	switch (task_type) {
5079	case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
5080	case MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET:
5081	case MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK:
5082	case MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA:
5083	case MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET:
5084	case MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION:
5085		break;
5086	case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
5087	case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
5088	case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
5089		mptsas_flush_target(mpt, dev_handle, Lun(cmd), task_type);
5090		break;
5091	default:
5092		mptsas_log(mpt, CE_WARN, "Unknown task management type %d.",
5093		    task_type);
5094		mptsas_log(mpt, CE_WARN, "ioc status = %x", ioc_status);
5095		break;
5096	}
5097}
5098
5099static void
5100mptsas_doneq_thread(mptsas_doneq_thread_arg_t *arg)
5101{
5102	mptsas_t			*mpt = arg->mpt;
5103	uint64_t			t = arg->t;
5104	mptsas_cmd_t			*cmd;
5105	struct scsi_pkt			*pkt;
5106	mptsas_doneq_thread_list_t	*item = &mpt->m_doneq_thread_id[t];
5107
5108	mutex_enter(&item->mutex);
5109	while (item->flag & MPTSAS_DONEQ_THREAD_ACTIVE) {
5110		if (!item->doneq) {
5111			cv_wait(&item->cv, &item->mutex);
5112		}
5113		pkt = NULL;
5114		if ((cmd = mptsas_doneq_thread_rm(mpt, t)) != NULL) {
5115			cmd->cmd_flags |= CFLAG_COMPLETED;
5116			pkt = CMD2PKT(cmd);
5117		}
5118		mutex_exit(&item->mutex);
5119		if (pkt) {
5120			mptsas_pkt_comp(pkt, cmd);
5121		}
5122		mutex_enter(&item->mutex);
5123	}
5124	mutex_exit(&item->mutex);
5125	mutex_enter(&mpt->m_doneq_mutex);
5126	mpt->m_doneq_thread_n--;
5127	cv_broadcast(&mpt->m_doneq_thread_cv);
5128	mutex_exit(&mpt->m_doneq_mutex);
5129}
5130
5131
5132/*
5133 * mpt interrupt handler.
5134 */
5135static uint_t
5136mptsas_intr(caddr_t arg1, caddr_t arg2)
5137{
5138	mptsas_t			*mpt = (void *)arg1;
5139	uint32_t			reply_index;
5140	pMpi2ReplyDescriptorsUnion_t	reply_desc_union;
5141	uchar_t				did_reply = FALSE;
5142
5143	NDBG1(("mptsas_intr: arg1 0x%p arg2 0x%p", (void *)arg1, (void *)arg2));
5144
5145	mutex_enter(&mpt->m_mutex);
5146
5147	/*
5148	 * If interrupts are shared by two channels then
5149	 * check whether this interrupt is genuinely for this
5150	 * channel by making sure first the chip is in high
5151	 * power state.
5152	 */
5153	if ((mpt->m_options & MPTSAS_OPT_PM) &&
5154	    (mpt->m_power_level != PM_LEVEL_D0)) {
5155		mutex_exit(&mpt->m_mutex);
5156		return (DDI_INTR_UNCLAIMED);
5157	}
5158
5159	/*
5160	 * Save the current reply post host index value.
5161	 */
5162	reply_index = mpt->m_post_index;
5163
5164	/*
5165	 * Read the istat register.
5166	 */
5167	if ((INTPENDING(mpt)) != 0) {
5168		/*
5169		 * read fifo until empty.
5170		 */
5171		(void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
5172		    DDI_DMA_SYNC_FORCPU);
5173#ifndef __lock_lint
5174		_NOTE(CONSTCOND)
5175#endif
5176		while (TRUE) {
5177			reply_desc_union = (pMpi2ReplyDescriptorsUnion_t)
5178			    MPTSAS_GET_NEXT_REPLY(mpt, reply_index);
5179
5180			if (ddi_get32(mpt->m_acc_post_queue_hdl,
5181			    &reply_desc_union->Words.Low) == 0xFFFFFFFF ||
5182			    ddi_get32(mpt->m_acc_post_queue_hdl,
5183			    &reply_desc_union->Words.High) == 0xFFFFFFFF) {
5184				break;
5185			}
5186
5187			/*
5188			 * The reply is valid, process it according to its
5189			 * type.  Also, set a flag for updated the reply index
5190			 * after they've all been processed.
5191			 */
5192			did_reply = TRUE;
5193
5194			mptsas_process_intr(mpt, reply_desc_union);
5195
5196			if (++reply_index == mpt->m_post_queue_depth) {
5197				reply_index = 0;
5198			}
5199			mpt->m_post_index = reply_index;
5200		}
5201
5202		/*
5203		 * Update the global reply index if at least one reply was
5204		 * processed.
5205		 */
5206		if (did_reply) {
5207			ddi_put32(mpt->m_datap,
5208			    &mpt->m_reg->ReplyPostHostIndex, reply_index);
5209		}
5210	} else {
5211		if (mpt->m_polled_intr) {
5212			mpt->m_polled_intr = 0;
5213			mutex_exit(&mpt->m_mutex);
5214			return (DDI_INTR_CLAIMED);
5215		}
5216		mutex_exit(&mpt->m_mutex);
5217		return (DDI_INTR_UNCLAIMED);
5218	}
5219	NDBG1(("mptsas_intr complete"));
5220
5221	/*
5222	 * If no helper threads are created, process the doneq in ISR.
5223	 * If helpers are created, use the doneq length as a metric to
5224	 * measure the load on the interrupt CPU. If it is long enough,
5225	 * which indicates the load is heavy, then we deliver the IO
5226	 * completions to the helpers.
5227	 * this measurement has some limitations although, it is simple
5228	 * and straightforward and works well for most of the cases at
5229	 * present.
5230	 */
5231
5232	if (!mpt->m_doneq_thread_n ||
5233	    (mpt->m_doneq_len <= mpt->m_doneq_length_threshold)) {
5234		mptsas_doneq_empty(mpt);
5235	} else {
5236		mptsas_deliver_doneq_thread(mpt);
5237	}
5238
5239	/*
5240	 * If there are queued cmd, start them now.
5241	 */
5242	if (mpt->m_waitq != NULL) {
5243		mptsas_restart_waitq(mpt);
5244	}
5245
5246	if (mpt->m_polled_intr) {
5247		mpt->m_polled_intr = 0;
5248	}
5249
5250	mutex_exit(&mpt->m_mutex);
5251	return (DDI_INTR_CLAIMED);
5252}
5253
5254static void
5255mptsas_process_intr(mptsas_t *mpt,
5256    pMpi2ReplyDescriptorsUnion_t reply_desc_union)
5257{
5258	uint8_t	reply_type;
5259
5260	ASSERT(mutex_owned(&mpt->m_mutex));
5261
5262	/*
5263	 * The reply is valid, process it according to its
5264	 * type.  Also, set a flag for updated the reply index
5265	 * after they've all been processed.
5266	 */
5267	reply_type = ddi_get8(mpt->m_acc_post_queue_hdl,
5268	    &reply_desc_union->Default.ReplyFlags);
5269	reply_type &= MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK;
5270	if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) {
5271		mptsas_handle_scsi_io_success(mpt, reply_desc_union);
5272	} else if (reply_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
5273		mptsas_handle_address_reply(mpt, reply_desc_union);
5274	} else {
5275		mptsas_log(mpt, CE_WARN, "?Bad reply type %x", reply_type);
5276		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
5277	}
5278
5279	/*
5280	 * Clear the reply descriptor for re-use and increment
5281	 * index.
5282	 */
5283	ddi_put64(mpt->m_acc_post_queue_hdl,
5284	    &((uint64_t *)(void *)mpt->m_post_queue)[mpt->m_post_index],
5285	    0xFFFFFFFFFFFFFFFF);
5286	(void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
5287	    DDI_DMA_SYNC_FORDEV);
5288}
5289
5290/*
5291 * handle qfull condition
5292 */
5293static void
5294mptsas_handle_qfull(mptsas_t *mpt, mptsas_cmd_t *cmd)
5295{
5296	mptsas_target_t	*ptgt = cmd->cmd_tgt_addr;
5297
5298	if ((++cmd->cmd_qfull_retries > ptgt->m_qfull_retries) ||
5299	    (ptgt->m_qfull_retries == 0)) {
5300		/*
5301		 * We have exhausted the retries on QFULL, or,
5302		 * the target driver has indicated that it
5303		 * wants to handle QFULL itself by setting
5304		 * qfull-retries capability to 0. In either case
5305		 * we want the target driver's QFULL handling
5306		 * to kick in. We do this by having pkt_reason
5307		 * as CMD_CMPLT and pkt_scbp as STATUS_QFULL.
5308		 */
5309		mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
5310	} else {
5311		if (ptgt->m_reset_delay == 0) {
5312			ptgt->m_t_throttle =
5313			    max((ptgt->m_t_ncmds - 2), 0);
5314		}
5315
5316		cmd->cmd_pkt_flags |= FLAG_HEAD;
5317		cmd->cmd_flags &= ~(CFLAG_TRANFLAG);
5318		cmd->cmd_flags |= CFLAG_RETRY;
5319
5320		(void) mptsas_accept_pkt(mpt, cmd);
5321
5322		/*
5323		 * when target gives queue full status with no commands
5324		 * outstanding (m_t_ncmds == 0), throttle is set to 0
5325		 * (HOLD_THROTTLE), and the queue full handling start
5326		 * (see psarc/1994/313); if there are commands outstanding,
5327		 * throttle is set to (m_t_ncmds - 2)
5328		 */
5329		if (ptgt->m_t_throttle == HOLD_THROTTLE) {
5330			/*
5331			 * By setting throttle to QFULL_THROTTLE, we
5332			 * avoid submitting new commands and in
5333			 * mptsas_restart_cmd find out slots which need
5334			 * their throttles to be cleared.
5335			 */
5336			mptsas_set_throttle(mpt, ptgt, QFULL_THROTTLE);
5337			if (mpt->m_restart_cmd_timeid == 0) {
5338				mpt->m_restart_cmd_timeid =
5339				    timeout(mptsas_restart_cmd, mpt,
5340				    ptgt->m_qfull_retry_interval);
5341			}
5342		}
5343	}
5344}
5345
5346uint8_t
5347mptsas_phymask_to_physport(mptsas_t *mpt, uint8_t phymask)
5348{
5349	int i;
5350
5351	/*
5352	 * RAID doesn't have valid phymask and physport so we use phymask == 0
5353	 * and physport == 0xff to indicate that it's RAID.
5354	 */
5355	if (phymask == 0) {
5356		return (0xff);
5357	}
5358	for (i = 0; i < 8; i++) {
5359		if (phymask & (1 << i)) {
5360			break;
5361		}
5362	}
5363	return (mpt->m_phy_info[i].port_num);
5364}
5365uint8_t
5366mptsas_physport_to_phymask(mptsas_t *mpt, uint8_t physport)
5367{
5368	uint8_t		phy_mask = 0;
5369	uint8_t		i = 0;
5370
5371	NDBG20(("mptsas%d physport_to_phymask enter", mpt->m_instance));
5372
5373	ASSERT(mutex_owned(&mpt->m_mutex));
5374
5375	/*
5376	 * If physport is 0xFF, this is a RAID volume.  Use phymask of 0.
5377	 */
5378	if (physport == 0xFF) {
5379		return (0);
5380	}
5381
5382	for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
5383		if (mpt->m_phy_info[i].attached_devhdl &&
5384		    (mpt->m_phy_info[i].phy_mask != 0) &&
5385		    (mpt->m_phy_info[i].port_num == physport)) {
5386			phy_mask = mpt->m_phy_info[i].phy_mask;
5387			break;
5388		}
5389	}
5390	NDBG20(("mptsas%d physport_to_phymask:physport :%x phymask :%x, ",
5391	    mpt->m_instance, physport, phy_mask));
5392	return (phy_mask);
5393}
5394
5395/*
5396 * mpt free device handle after device gone, by use of passthrough
5397 */
5398static int
5399mptsas_free_devhdl(mptsas_t *mpt, uint16_t devhdl)
5400{
5401	Mpi2SasIoUnitControlRequest_t	req;
5402	Mpi2SasIoUnitControlReply_t	rep;
5403	int				ret;
5404
5405	ASSERT(mutex_owned(&mpt->m_mutex));
5406
5407	/*
5408	 * Need to compose a SAS IO Unit Control request message
5409	 * and call mptsas_do_passthru() function
5410	 */
5411	bzero(&req, sizeof (req));
5412	bzero(&rep, sizeof (rep));
5413
5414	req.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
5415	req.Operation = MPI2_SAS_OP_REMOVE_DEVICE;
5416	req.DevHandle = LE_16(devhdl);
5417
5418	ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep, NULL,
5419	    sizeof (req), sizeof (rep), NULL, 0, NULL, 0, 60, FKIOCTL);
5420	if (ret != 0) {
5421		cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit "
5422		    "Control error %d", ret);
5423		return (DDI_FAILURE);
5424	}
5425
5426	/* do passthrough success, check the ioc status */
5427	if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
5428		cmn_err(CE_WARN, "mptsas_free_devhdl: passthru SAS IO Unit "
5429		    "Control IOCStatus %d", LE_16(rep.IOCStatus));
5430		return (DDI_FAILURE);
5431	}
5432
5433	return (DDI_SUCCESS);
5434}
5435
5436static void
5437mptsas_update_phymask(mptsas_t *mpt)
5438{
5439	uint8_t	mask = 0, phy_mask;
5440	char	*phy_mask_name;
5441	uint8_t current_port;
5442	int	i, j;
5443
5444	NDBG20(("mptsas%d update phymask ", mpt->m_instance));
5445
5446	ASSERT(mutex_owned(&mpt->m_mutex));
5447
5448	(void) mptsas_get_sas_io_unit_page(mpt);
5449
5450	phy_mask_name = kmem_zalloc(8, KM_SLEEP);
5451
5452	for (i = 0; i < mpt->m_num_phys; i++) {
5453		phy_mask = 0x00;
5454
5455		if (mpt->m_phy_info[i].attached_devhdl == 0)
5456			continue;
5457
5458		bzero(phy_mask_name, sizeof (phy_mask_name));
5459
5460		current_port = mpt->m_phy_info[i].port_num;
5461
5462		if ((mask & (1 << i)) != 0)
5463			continue;
5464
5465		for (j = 0; j < mpt->m_num_phys; j++) {
5466			if (mpt->m_phy_info[j].attached_devhdl &&
5467			    (mpt->m_phy_info[j].port_num == current_port)) {
5468				phy_mask |= (1 << j);
5469			}
5470		}
5471		mask = mask | phy_mask;
5472
5473		for (j = 0; j < mpt->m_num_phys; j++) {
5474			if ((phy_mask >> j) & 0x01) {
5475				mpt->m_phy_info[j].phy_mask = phy_mask;
5476			}
5477		}
5478
5479		(void) sprintf(phy_mask_name, "%x", phy_mask);
5480
5481		mutex_exit(&mpt->m_mutex);
5482		/*
5483		 * register a iport, if the port has already been existed
5484		 * SCSA will do nothing and just return.
5485		 */
5486		(void) scsi_hba_iport_register(mpt->m_dip, phy_mask_name);
5487		mutex_enter(&mpt->m_mutex);
5488	}
5489	kmem_free(phy_mask_name, 8);
5490	NDBG20(("mptsas%d update phymask return", mpt->m_instance));
5491}
5492
5493/*
5494 * mptsas_handle_dr is a task handler for DR, the DR action includes:
5495 * 1. Directly attched Device Added/Removed.
5496 * 2. Expander Device Added/Removed.
5497 * 3. Indirectly Attached Device Added/Expander.
5498 * 4. LUNs of a existing device status change.
5499 * 5. RAID volume created/deleted.
5500 * 6. Member of RAID volume is released because of RAID deletion.
5501 * 7. Physical disks are removed because of RAID creation.
5502 */
5503static void
5504mptsas_handle_dr(void *args) {
5505	mptsas_topo_change_list_t	*topo_node = NULL;
5506	mptsas_topo_change_list_t	*save_node = NULL;
5507	mptsas_t			*mpt;
5508	dev_info_t			*parent = NULL;
5509	uint8_t				phymask = 0;
5510	char				*phy_mask_name;
5511	uint8_t				flags = 0, physport = 0xff;
5512	uint8_t				port_update = 0;
5513	uint_t				event;
5514
5515	topo_node = (mptsas_topo_change_list_t *)args;
5516
5517	mpt = topo_node->mpt;
5518	event = topo_node->event;
5519	flags = topo_node->flags;
5520
5521	phy_mask_name = kmem_zalloc(8, KM_SLEEP);
5522
5523	NDBG20(("mptsas%d handle_dr enter", mpt->m_instance));
5524
5525	switch (event) {
5526	case MPTSAS_DR_EVENT_RECONFIG_TARGET:
5527		if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
5528		    (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE) ||
5529		    (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED)) {
5530			/*
5531			 * Direct attached or expander attached device added
5532			 * into system or a Phys Disk that is being unhidden.
5533			 */
5534			port_update = 1;
5535		}
5536		break;
5537	case MPTSAS_DR_EVENT_RECONFIG_SMP:
5538		/*
5539		 * New expander added into system, it must be the head
5540		 * of topo_change_list_t
5541		 */
5542		port_update = 1;
5543		break;
5544	default:
5545		port_update = 0;
5546		break;
5547	}
5548	/*
5549	 * All cases port_update == 1 may cause initiator port form change
5550	 */
5551	mutex_enter(&mpt->m_mutex);
5552	if (mpt->m_port_chng && port_update) {
5553		/*
5554		 * mpt->m_port_chng flag indicates some PHYs of initiator
5555		 * port have changed to online. So when expander added or
5556		 * directly attached device online event come, we force to
5557		 * update port information by issueing SAS IO Unit Page and
5558		 * update PHYMASKs.
5559		 */
5560		(void) mptsas_update_phymask(mpt);
5561		mpt->m_port_chng = 0;
5562
5563	}
5564	mutex_exit(&mpt->m_mutex);
5565	while (topo_node) {
5566		phymask = 0;
5567		if (parent == NULL) {
5568			physport = topo_node->un.physport;
5569			event = topo_node->event;
5570			flags = topo_node->flags;
5571			if (event & (MPTSAS_DR_EVENT_OFFLINE_TARGET |
5572			    MPTSAS_DR_EVENT_OFFLINE_SMP)) {
5573				/*
5574				 * For all offline events, phymask is known
5575				 */
5576				phymask = topo_node->un.phymask;
5577				goto find_parent;
5578			}
5579			if (event & MPTSAS_TOPO_FLAG_REMOVE_HANDLE) {
5580				goto handle_topo_change;
5581			}
5582			if (flags & MPTSAS_TOPO_FLAG_LUN_ASSOCIATED) {
5583				phymask = topo_node->un.phymask;
5584				goto find_parent;
5585			}
5586
5587			if ((flags ==
5588			    MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) &&
5589			    (event == MPTSAS_DR_EVENT_RECONFIG_TARGET)) {
5590				/*
5591				 * There is no any field in IR_CONFIG_CHANGE
5592				 * event indicate physport/phynum, let's get
5593				 * parent after SAS Device Page0 request.
5594				 */
5595				goto handle_topo_change;
5596			}
5597
5598			mutex_enter(&mpt->m_mutex);
5599			if (flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) {
5600				/*
5601				 * If the direct attached device added or a
5602				 * phys disk is being unhidden, argument
5603				 * physport actually is PHY#, so we have to get
5604				 * phymask according PHY#.
5605				 */
5606				physport = mpt->m_phy_info[physport].port_num;
5607			}
5608
5609			/*
5610			 * Translate physport to phymask so that we can search
5611			 * parent dip.
5612			 */
5613			phymask = mptsas_physport_to_phymask(mpt,
5614			    physport);
5615			mutex_exit(&mpt->m_mutex);
5616
5617find_parent:
5618			bzero(phy_mask_name, 8);
5619			/*
5620			 * For RAID topology change node, write the iport name
5621			 * as v0.
5622			 */
5623			if (flags & MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5624				(void) sprintf(phy_mask_name, "v0");
5625			} else {
5626				/*
5627				 * phymask can bo 0 if the drive has been
5628				 * pulled by the time an add event is
5629				 * processed.  If phymask is 0, just skip this
5630				 * event and continue.
5631				 */
5632				if (phymask == 0) {
5633					mutex_enter(&mpt->m_mutex);
5634					save_node = topo_node;
5635					topo_node = topo_node->next;
5636					ASSERT(save_node);
5637					kmem_free(save_node,
5638					    sizeof (mptsas_topo_change_list_t));
5639					mutex_exit(&mpt->m_mutex);
5640
5641					parent = NULL;
5642					continue;
5643				}
5644				(void) sprintf(phy_mask_name, "%x", phymask);
5645			}
5646			parent = scsi_hba_iport_find(mpt->m_dip,
5647			    phy_mask_name);
5648			if (parent == NULL) {
5649				mptsas_log(mpt, CE_WARN, "Failed to find a "
5650				    "iport, should not happen!");
5651				goto out;
5652			}
5653
5654		}
5655		ASSERT(parent);
5656handle_topo_change:
5657
5658		mutex_enter(&mpt->m_mutex);
5659
5660		mptsas_handle_topo_change(topo_node, parent);
5661		save_node = topo_node;
5662		topo_node = topo_node->next;
5663		ASSERT(save_node);
5664		kmem_free(save_node, sizeof (mptsas_topo_change_list_t));
5665		mutex_exit(&mpt->m_mutex);
5666
5667		if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
5668		    (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) ||
5669		    (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED)) {
5670			/*
5671			 * If direct attached device associated, make sure
5672			 * reset the parent before start the next one. But
5673			 * all devices associated with expander shares the
5674			 * parent.  Also, reset parent if this is for RAID.
5675			 */
5676			parent = NULL;
5677		}
5678	}
5679out:
5680	kmem_free(phy_mask_name, 8);
5681}
5682
5683static void
5684mptsas_handle_topo_change(mptsas_topo_change_list_t *topo_node,
5685    dev_info_t *parent)
5686{
5687	mptsas_target_t	*ptgt = NULL;
5688	mptsas_smp_t	*psmp = NULL;
5689	mptsas_t	*mpt = (void *)topo_node->mpt;
5690	uint16_t	devhdl;
5691	uint64_t	sas_wwn = 0;
5692	int		rval = 0;
5693	uint32_t	page_address;
5694	uint8_t		phy, flags;
5695	char		*addr = NULL;
5696	dev_info_t	*lundip;
5697	int		circ = 0, circ1 = 0;
5698
5699	NDBG20(("mptsas%d handle_topo_change enter", mpt->m_instance));
5700
5701	ASSERT(mutex_owned(&mpt->m_mutex));
5702
5703	switch (topo_node->event) {
5704	case MPTSAS_DR_EVENT_RECONFIG_TARGET:
5705	{
5706		char *phy_mask_name;
5707		uint8_t phymask = 0;
5708
5709		if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5710			/*
5711			 * Get latest RAID info.
5712			 */
5713			(void) mptsas_get_raid_info(mpt);
5714			ptgt = mptsas_search_by_devhdl(
5715			    &mpt->m_active->m_tgttbl, topo_node->devhdl);
5716			if (ptgt == NULL)
5717				break;
5718		} else {
5719			ptgt = (void *)topo_node->object;
5720		}
5721
5722		if (ptgt == NULL) {
5723			/*
5724			 * Get sas device page 0 by DevHandle to make sure if
5725			 * SSP/SATA end device exist.
5726			 */
5727			page_address = (MPI2_SAS_DEVICE_PGAD_FORM_HANDLE &
5728			    MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
5729			    topo_node->devhdl;
5730
5731			rval = mptsas_get_target_device_info(mpt, page_address,
5732			    &devhdl, &ptgt);
5733			if (rval == DEV_INFO_WRONG_DEVICE_TYPE) {
5734				mptsas_log(mpt, CE_NOTE,
5735				    "mptsas_handle_topo_change: target %d is "
5736				    "not a SAS/SATA device. \n",
5737				    topo_node->devhdl);
5738			} else if (rval == DEV_INFO_FAIL_ALLOC) {
5739				mptsas_log(mpt, CE_NOTE,
5740				    "mptsas_handle_topo_change: could not "
5741				    "allocate memory. \n");
5742			}
5743			/*
5744			 * If rval is DEV_INFO_PHYS_DISK than there is nothing
5745			 * else to do, just leave.
5746			 */
5747			if (rval != DEV_INFO_SUCCESS) {
5748				return;
5749			}
5750		}
5751
5752		ASSERT(ptgt->m_devhdl == topo_node->devhdl);
5753
5754		mutex_exit(&mpt->m_mutex);
5755		flags = topo_node->flags;
5756
5757		if (flags == MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED) {
5758			phymask = ptgt->m_phymask;
5759			phy_mask_name = kmem_zalloc(8, KM_SLEEP);
5760			(void) sprintf(phy_mask_name, "%x", phymask);
5761			parent = scsi_hba_iport_find(mpt->m_dip,
5762			    phy_mask_name);
5763			kmem_free(phy_mask_name, 8);
5764			if (parent == NULL) {
5765				mptsas_log(mpt, CE_WARN, "Failed to find a "
5766				    "iport for PD, should not happen!");
5767				mutex_enter(&mpt->m_mutex);
5768				break;
5769			}
5770		}
5771
5772		if (flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5773			ndi_devi_enter(parent, &circ1);
5774			(void) mptsas_config_raid(parent, topo_node->devhdl,
5775			    &lundip);
5776			ndi_devi_exit(parent, circ1);
5777		} else {
5778			/*
5779			 * hold nexus for bus configure
5780			 */
5781			ndi_devi_enter(scsi_vhci_dip, &circ);
5782			ndi_devi_enter(parent, &circ1);
5783			rval = mptsas_config_target(parent, ptgt);
5784			/*
5785			 * release nexus for bus configure
5786			 */
5787			ndi_devi_exit(parent, circ1);
5788			ndi_devi_exit(scsi_vhci_dip, circ);
5789
5790		}
5791		mutex_enter(&mpt->m_mutex);
5792
5793		NDBG20(("mptsas%d handle_topo_change to online devhdl:%x, "
5794		    "phymask:%x.", mpt->m_instance, ptgt->m_devhdl,
5795		    ptgt->m_phymask));
5796		break;
5797	}
5798	case MPTSAS_DR_EVENT_OFFLINE_TARGET:
5799	{
5800		mptsas_hash_table_t *tgttbl = &mpt->m_active->m_tgttbl;
5801		devhdl = topo_node->devhdl;
5802		ptgt = mptsas_search_by_devhdl(tgttbl, devhdl);
5803		if (ptgt == NULL)
5804			break;
5805
5806		sas_wwn = ptgt->m_sas_wwn;
5807		phy = ptgt->m_phynum;
5808
5809		addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
5810
5811		if (sas_wwn) {
5812			(void) sprintf(addr, "w%016"PRIx64, sas_wwn);
5813		} else {
5814			(void) sprintf(addr, "p%x", phy);
5815		}
5816		ASSERT(ptgt->m_devhdl == devhdl);
5817
5818		if (topo_node->flags == MPTSAS_TOPO_FLAG_RAID_ASSOCIATED) {
5819			/*
5820			 * Get latest RAID info, if RAID volume status change
5821			 */
5822			(void) mptsas_get_raid_info(mpt);
5823		}
5824		/*
5825		 * Abort all outstanding command on the device
5826		 */
5827		rval = mptsas_do_scsi_reset(mpt, devhdl);
5828		if (rval) {
5829			NDBG20(("mptsas%d handle_topo_change to reset target "
5830			    "before offline devhdl:%x, phymask:%x, rval:%x",
5831			    mpt->m_instance, ptgt->m_devhdl, ptgt->m_phymask,
5832			    rval));
5833		}
5834
5835		mutex_exit(&mpt->m_mutex);
5836
5837		ndi_devi_enter(scsi_vhci_dip, &circ);
5838		ndi_devi_enter(parent, &circ1);
5839		rval = mptsas_offline_target(parent, addr);
5840		ndi_devi_exit(parent, circ1);
5841		ndi_devi_exit(scsi_vhci_dip, circ);
5842		NDBG20(("mptsas%d handle_topo_change to offine devhdl:%x, "
5843		    "phymask:%x, rval:%x", mpt->m_instance,
5844		    ptgt->m_devhdl, ptgt->m_phymask, rval));
5845
5846		kmem_free(addr, SCSI_MAXNAMELEN);
5847
5848		mutex_enter(&mpt->m_mutex);
5849		if (rval == DDI_SUCCESS) {
5850			mptsas_tgt_free(&mpt->m_active->m_tgttbl,
5851			    ptgt->m_sas_wwn, ptgt->m_phymask);
5852			ptgt = NULL;
5853		} else {
5854			/*
5855			 * clean DR_INTRANSITION flag to allow I/O down to
5856			 * PHCI driver since failover finished.
5857			 * Invalidate the devhdl
5858			 */
5859			ptgt->m_devhdl = MPTSAS_INVALID_DEVHDL;
5860			mutex_enter(&mpt->m_tx_waitq_mutex);
5861			ptgt->m_dr_flag = MPTSAS_DR_INACTIVE;
5862			mutex_exit(&mpt->m_tx_waitq_mutex);
5863		}
5864
5865		/*
5866		 * Send SAS IO Unit Control to free the dev handle
5867		 */
5868		flags = topo_node->flags;
5869		if ((flags == MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE) ||
5870		    (flags == MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE)) {
5871			rval = mptsas_free_devhdl(mpt, devhdl);
5872
5873			NDBG20(("mptsas%d handle_topo_change to remove "
5874			    "devhdl:%x, rval:%x", mpt->m_instance, devhdl,
5875			    rval));
5876		}
5877		break;
5878	}
5879	case MPTSAS_TOPO_FLAG_REMOVE_HANDLE:
5880	{
5881		devhdl = topo_node->devhdl;
5882		/*
5883		 * If this is the remove handle event, do a reset first.
5884		 */
5885		if (topo_node->event == MPTSAS_TOPO_FLAG_REMOVE_HANDLE) {
5886			rval = mptsas_do_scsi_reset(mpt, devhdl);
5887			if (rval) {
5888				NDBG20(("mpt%d reset target before remove "
5889				    "devhdl:%x, rval:%x", mpt->m_instance,
5890				    devhdl, rval));
5891			}
5892		}
5893
5894		/*
5895		 * Send SAS IO Unit Control to free the dev handle
5896		 */
5897		rval = mptsas_free_devhdl(mpt, devhdl);
5898		NDBG20(("mptsas%d handle_topo_change to remove "
5899		    "devhdl:%x, rval:%x", mpt->m_instance, devhdl,
5900		    rval));
5901		break;
5902	}
5903	case MPTSAS_DR_EVENT_RECONFIG_SMP:
5904	{
5905		mptsas_smp_t smp;
5906		dev_info_t *smpdip;
5907		mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl;
5908
5909		devhdl = topo_node->devhdl;
5910
5911		page_address = (MPI2_SAS_EXPAND_PGAD_FORM_HNDL &
5912		    MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)devhdl;
5913		rval = mptsas_get_sas_expander_page0(mpt, page_address, &smp);
5914		if (rval != DDI_SUCCESS) {
5915			mptsas_log(mpt, CE_WARN, "failed to online smp, "
5916			    "handle %x", devhdl);
5917			return;
5918		}
5919
5920		psmp = mptsas_smp_alloc(smptbl, &smp);
5921		if (psmp == NULL) {
5922			return;
5923		}
5924
5925		mutex_exit(&mpt->m_mutex);
5926		ndi_devi_enter(parent, &circ1);
5927		(void) mptsas_online_smp(parent, psmp, &smpdip);
5928		ndi_devi_exit(parent, circ1);
5929		mutex_enter(&mpt->m_mutex);
5930		break;
5931	}
5932	case MPTSAS_DR_EVENT_OFFLINE_SMP:
5933	{
5934		mptsas_hash_table_t *smptbl = &mpt->m_active->m_smptbl;
5935		devhdl = topo_node->devhdl;
5936		psmp = mptsas_search_by_devhdl(smptbl, devhdl);
5937		if (psmp == NULL)
5938			break;
5939		/*
5940		 * The mptsas_smp_t data is released only if the dip is offlined
5941		 * successfully.
5942		 */
5943		mutex_exit(&mpt->m_mutex);
5944		ndi_devi_enter(parent, &circ1);
5945		rval = mptsas_offline_smp(parent, psmp, NDI_DEVI_REMOVE);
5946		ndi_devi_exit(parent, circ1);
5947		mutex_enter(&mpt->m_mutex);
5948		NDBG20(("mptsas%d handle_topo_change to remove devhdl:%x, "
5949		    "rval:%x", mpt->m_instance, psmp->m_devhdl, rval));
5950		if (rval == DDI_SUCCESS) {
5951			mptsas_smp_free(smptbl, psmp->m_sasaddr,
5952			    psmp->m_phymask);
5953		} else {
5954			psmp->m_devhdl = MPTSAS_INVALID_DEVHDL;
5955		}
5956		break;
5957	}
5958	default:
5959		return;
5960	}
5961}
5962
5963/*
5964 * Record the event if its type is enabled in mpt instance by ioctl.
5965 */
5966static void
5967mptsas_record_event(void *args)
5968{
5969	m_replyh_arg_t			*replyh_arg;
5970	pMpi2EventNotificationReply_t	eventreply;
5971	uint32_t			event, rfm;
5972	mptsas_t			*mpt;
5973	int				i, j;
5974	uint16_t			event_data_len;
5975	boolean_t			sendAEN = FALSE;
5976
5977	replyh_arg = (m_replyh_arg_t *)args;
5978	rfm = replyh_arg->rfm;
5979	mpt = replyh_arg->mpt;
5980
5981	eventreply = (pMpi2EventNotificationReply_t)
5982	    (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr));
5983	event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
5984
5985
5986	/*
5987	 * Generate a system event to let anyone who cares know that a
5988	 * LOG_ENTRY_ADDED event has occurred.  This is sent no matter what the
5989	 * event mask is set to.
5990	 */
5991	if (event == MPI2_EVENT_LOG_ENTRY_ADDED) {
5992		sendAEN = TRUE;
5993	}
5994
5995	/*
5996	 * Record the event only if it is not masked.  Determine which dword
5997	 * and bit of event mask to test.
5998	 */
5999	i = (uint8_t)(event / 32);
6000	j = (uint8_t)(event % 32);
6001	if ((i < 4) && ((1 << j) & mpt->m_event_mask[i])) {
6002		i = mpt->m_event_number;
6003		mpt->m_events[i].Type = event;
6004		mpt->m_events[i].Number = ++mpt->m_event_number;
6005		bzero(mpt->m_events[i].Data, MPTSAS_MAX_EVENT_DATA_LENGTH * 4);
6006		event_data_len = ddi_get16(mpt->m_acc_reply_frame_hdl,
6007		    &eventreply->EventDataLength);
6008
6009		if (event_data_len > 0) {
6010			/*
6011			 * Limit data to size in m_event entry
6012			 */
6013			if (event_data_len > MPTSAS_MAX_EVENT_DATA_LENGTH) {
6014				event_data_len = MPTSAS_MAX_EVENT_DATA_LENGTH;
6015			}
6016			for (j = 0; j < event_data_len; j++) {
6017				mpt->m_events[i].Data[j] =
6018				    ddi_get32(mpt->m_acc_reply_frame_hdl,
6019				    &(eventreply->EventData[j]));
6020			}
6021
6022			/*
6023			 * check for index wrap-around
6024			 */
6025			if (++i == MPTSAS_EVENT_QUEUE_SIZE) {
6026				i = 0;
6027			}
6028			mpt->m_event_number = i;
6029
6030			/*
6031			 * Set flag to send the event.
6032			 */
6033			sendAEN = TRUE;
6034		}
6035	}
6036
6037	/*
6038	 * Generate a system event if flag is set to let anyone who cares know
6039	 * that an event has occurred.
6040	 */
6041	if (sendAEN) {
6042		(void) ddi_log_sysevent(mpt->m_dip, DDI_VENDOR_LSI, "MPT_SAS",
6043		    "SAS", NULL, NULL, DDI_NOSLEEP);
6044	}
6045}
6046
6047#define	SMP_RESET_IN_PROGRESS MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS
6048/*
6049 * handle sync events from ioc in interrupt
6050 * return value:
6051 * DDI_SUCCESS: The event is handled by this func
6052 * DDI_FAILURE: Event is not handled
6053 */
6054static int
6055mptsas_handle_event_sync(void *args)
6056{
6057	m_replyh_arg_t			*replyh_arg;
6058	pMpi2EventNotificationReply_t	eventreply;
6059	uint32_t			event, rfm;
6060	mptsas_t			*mpt;
6061	uint_t				iocstatus;
6062
6063	replyh_arg = (m_replyh_arg_t *)args;
6064	rfm = replyh_arg->rfm;
6065	mpt = replyh_arg->mpt;
6066
6067	ASSERT(mutex_owned(&mpt->m_mutex));
6068
6069	eventreply = (pMpi2EventNotificationReply_t)
6070	    (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr));
6071	event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
6072
6073	if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
6074	    &eventreply->IOCStatus)) {
6075		if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
6076			mptsas_log(mpt, CE_WARN,
6077			    "!mptsas_handle_event_sync: IOCStatus=0x%x, "
6078			    "IOCLogInfo=0x%x", iocstatus,
6079			    ddi_get32(mpt->m_acc_reply_frame_hdl,
6080			    &eventreply->IOCLogInfo));
6081		} else {
6082			mptsas_log(mpt, CE_WARN,
6083			    "mptsas_handle_event_sync: IOCStatus=0x%x, "
6084			    "IOCLogInfo=0x%x", iocstatus,
6085			    ddi_get32(mpt->m_acc_reply_frame_hdl,
6086			    &eventreply->IOCLogInfo));
6087		}
6088	}
6089
6090	/*
6091	 * figure out what kind of event we got and handle accordingly
6092	 */
6093	switch (event) {
6094	case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
6095	{
6096		pMpi2EventDataSasTopologyChangeList_t	sas_topo_change_list;
6097		uint8_t				num_entries, expstatus, phy;
6098		uint8_t				phystatus, physport, state, i;
6099		uint8_t				start_phy_num, link_rate;
6100		uint16_t			dev_handle;
6101		uint16_t			enc_handle, expd_handle;
6102		char				string[80], curr[80], prev[80];
6103		mptsas_topo_change_list_t	*topo_head = NULL;
6104		mptsas_topo_change_list_t	*topo_tail = NULL;
6105		mptsas_topo_change_list_t	*topo_node = NULL;
6106		mptsas_target_t			*ptgt;
6107		mptsas_smp_t			*psmp;
6108		mptsas_hash_table_t		*tgttbl, *smptbl;
6109		uint8_t				flags = 0, exp_flag;
6110
6111		NDBG20(("mptsas_handle_event_sync: SAS topology change"));
6112
6113		tgttbl = &mpt->m_active->m_tgttbl;
6114		smptbl = &mpt->m_active->m_smptbl;
6115
6116		sas_topo_change_list = (pMpi2EventDataSasTopologyChangeList_t)
6117		    eventreply->EventData;
6118
6119		enc_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6120		    &sas_topo_change_list->EnclosureHandle);
6121		expd_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6122		    &sas_topo_change_list->ExpanderDevHandle);
6123		num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
6124		    &sas_topo_change_list->NumEntries);
6125		start_phy_num = ddi_get8(mpt->m_acc_reply_frame_hdl,
6126		    &sas_topo_change_list->StartPhyNum);
6127		expstatus = ddi_get8(mpt->m_acc_reply_frame_hdl,
6128		    &sas_topo_change_list->ExpStatus);
6129		physport = ddi_get8(mpt->m_acc_reply_frame_hdl,
6130		    &sas_topo_change_list->PhysicalPort);
6131
6132		string[0] = 0;
6133		if (expd_handle) {
6134			flags = MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED;
6135			switch (expstatus) {
6136			case MPI2_EVENT_SAS_TOPO_ES_ADDED:
6137				(void) sprintf(string, " added");
6138				/*
6139				 * New expander device added
6140				 */
6141				mpt->m_port_chng = 1;
6142				topo_node = kmem_zalloc(
6143				    sizeof (mptsas_topo_change_list_t),
6144				    KM_SLEEP);
6145				topo_node->mpt = mpt;
6146				topo_node->event = MPTSAS_DR_EVENT_RECONFIG_SMP;
6147				topo_node->un.physport = physport;
6148				topo_node->devhdl = expd_handle;
6149				topo_node->flags = flags;
6150				topo_node->object = NULL;
6151				if (topo_head == NULL) {
6152					topo_head = topo_tail = topo_node;
6153				} else {
6154					topo_tail->next = topo_node;
6155					topo_tail = topo_node;
6156				}
6157				break;
6158			case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING:
6159				(void) sprintf(string, " not responding, "
6160				    "removed");
6161				psmp = mptsas_search_by_devhdl(smptbl,
6162				    expd_handle);
6163				if (psmp == NULL)
6164					break;
6165
6166				topo_node = kmem_zalloc(
6167				    sizeof (mptsas_topo_change_list_t),
6168				    KM_SLEEP);
6169				topo_node->mpt = mpt;
6170				topo_node->un.phymask = psmp->m_phymask;
6171				topo_node->event = MPTSAS_DR_EVENT_OFFLINE_SMP;
6172				topo_node->devhdl = expd_handle;
6173				topo_node->flags = flags;
6174				topo_node->object = NULL;
6175				if (topo_head == NULL) {
6176					topo_head = topo_tail = topo_node;
6177				} else {
6178					topo_tail->next = topo_node;
6179					topo_tail = topo_node;
6180				}
6181				break;
6182			case MPI2_EVENT_SAS_TOPO_ES_RESPONDING:
6183				break;
6184			case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING:
6185				(void) sprintf(string, " not responding, "
6186				    "delaying removal");
6187				break;
6188			default:
6189				break;
6190			}
6191		} else {
6192			flags = MPTSAS_TOPO_FLAG_DIRECT_ATTACHED_DEVICE;
6193		}
6194
6195		NDBG20(("SAS TOPOLOGY CHANGE for enclosure %x expander %x%s\n",
6196		    enc_handle, expd_handle, string));
6197		for (i = 0; i < num_entries; i++) {
6198			phy = i + start_phy_num;
6199			phystatus = ddi_get8(mpt->m_acc_reply_frame_hdl,
6200			    &sas_topo_change_list->PHY[i].PhyStatus);
6201			dev_handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6202			    &sas_topo_change_list->PHY[i].AttachedDevHandle);
6203			if (phystatus & MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) {
6204				continue;
6205			}
6206			curr[0] = 0;
6207			prev[0] = 0;
6208			string[0] = 0;
6209			switch (phystatus & MPI2_EVENT_SAS_TOPO_RC_MASK) {
6210			case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED:
6211			{
6212				NDBG20(("mptsas%d phy %d physical_port %d "
6213				    "dev_handle %d added", mpt->m_instance, phy,
6214				    physport, dev_handle));
6215				link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl,
6216				    &sas_topo_change_list->PHY[i].LinkRate);
6217				state = (link_rate &
6218				    MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >>
6219				    MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT;
6220				switch (state) {
6221				case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
6222					(void) sprintf(curr, "is disabled");
6223					break;
6224				case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
6225					(void) sprintf(curr, "is offline, "
6226					    "failed speed negotiation");
6227					break;
6228				case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
6229					(void) sprintf(curr, "SATA OOB "
6230					    "complete");
6231					break;
6232				case SMP_RESET_IN_PROGRESS:
6233					(void) sprintf(curr, "SMP reset in "
6234					    "progress");
6235					break;
6236				case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
6237					(void) sprintf(curr, "is online at "
6238					    "1.5 Gbps");
6239					break;
6240				case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
6241					(void) sprintf(curr, "is online at 3.0 "
6242					    "Gbps");
6243					break;
6244				case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
6245					(void) sprintf(curr, "is online at 6.0 "
6246					    "Gbps");
6247					break;
6248				default:
6249					(void) sprintf(curr, "state is "
6250					    "unknown");
6251					break;
6252				}
6253				/*
6254				 * New target device added into the system.
6255				 * Set association flag according to if an
6256				 * expander is used or not.
6257				 */
6258				exp_flag =
6259				    MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
6260				if (flags ==
6261				    MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) {
6262					flags = exp_flag;
6263				}
6264				topo_node = kmem_zalloc(
6265				    sizeof (mptsas_topo_change_list_t),
6266				    KM_SLEEP);
6267				topo_node->mpt = mpt;
6268				topo_node->event =
6269				    MPTSAS_DR_EVENT_RECONFIG_TARGET;
6270				if (expd_handle == 0) {
6271					/*
6272					 * Per MPI 2, if expander dev handle
6273					 * is 0, it's a directly attached
6274					 * device. So driver use PHY to decide
6275					 * which iport is associated
6276					 */
6277					physport = phy;
6278					mpt->m_port_chng = 1;
6279				}
6280				topo_node->un.physport = physport;
6281				topo_node->devhdl = dev_handle;
6282				topo_node->flags = flags;
6283				topo_node->object = NULL;
6284				if (topo_head == NULL) {
6285					topo_head = topo_tail = topo_node;
6286				} else {
6287					topo_tail->next = topo_node;
6288					topo_tail = topo_node;
6289				}
6290				break;
6291			}
6292			case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING:
6293			{
6294				NDBG20(("mptsas%d phy %d physical_port %d "
6295				    "dev_handle %d removed", mpt->m_instance,
6296				    phy, physport, dev_handle));
6297				/*
6298				 * Set association flag according to if an
6299				 * expander is used or not.
6300				 */
6301				exp_flag =
6302				    MPTSAS_TOPO_FLAG_EXPANDER_ATTACHED_DEVICE;
6303				if (flags ==
6304				    MPTSAS_TOPO_FLAG_EXPANDER_ASSOCIATED) {
6305					flags = exp_flag;
6306				}
6307				/*
6308				 * Target device is removed from the system
6309				 * Before the device is really offline from
6310				 * from system.
6311				 */
6312				ptgt = mptsas_search_by_devhdl(tgttbl,
6313				    dev_handle);
6314				/*
6315				 * If ptgt is NULL here, it means that the
6316				 * DevHandle is not in the hash table.  This is
6317				 * reasonable sometimes.  For example, if a
6318				 * disk was pulled, then added, then pulled
6319				 * again, the disk will not have been put into
6320				 * the hash table because the add event will
6321				 * have an invalid phymask.  BUT, this does not
6322				 * mean that the DevHandle is invalid.  The
6323				 * controller will still have a valid DevHandle
6324				 * that must be removed.  To do this, use the
6325				 * MPTSAS_TOPO_FLAG_REMOVE_HANDLE event.
6326				 */
6327				if (ptgt == NULL) {
6328					topo_node = kmem_zalloc(
6329					    sizeof (mptsas_topo_change_list_t),
6330					    KM_SLEEP);
6331					topo_node->mpt = mpt;
6332					topo_node->un.phymask = 0;
6333					topo_node->event =
6334					    MPTSAS_TOPO_FLAG_REMOVE_HANDLE;
6335					topo_node->devhdl = dev_handle;
6336					topo_node->flags = flags;
6337					topo_node->object = NULL;
6338					if (topo_head == NULL) {
6339						topo_head = topo_tail =
6340						    topo_node;
6341					} else {
6342						topo_tail->next = topo_node;
6343						topo_tail = topo_node;
6344					}
6345					break;
6346				}
6347
6348				/*
6349				 * Update DR flag immediately avoid I/O failure
6350				 * before failover finish. Pay attention to the
6351				 * mutex protect, we need grab m_tx_waitq_mutex
6352				 * during set m_dr_flag because we won't add
6353				 * the following command into waitq, instead,
6354				 * we need return TRAN_BUSY in the tran_start
6355				 * context.
6356				 */
6357				mutex_enter(&mpt->m_tx_waitq_mutex);
6358				ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6359				mutex_exit(&mpt->m_tx_waitq_mutex);
6360
6361				topo_node = kmem_zalloc(
6362				    sizeof (mptsas_topo_change_list_t),
6363				    KM_SLEEP);
6364				topo_node->mpt = mpt;
6365				topo_node->un.phymask = ptgt->m_phymask;
6366				topo_node->event =
6367				    MPTSAS_DR_EVENT_OFFLINE_TARGET;
6368				topo_node->devhdl = dev_handle;
6369				topo_node->flags = flags;
6370				topo_node->object = NULL;
6371				if (topo_head == NULL) {
6372					topo_head = topo_tail = topo_node;
6373				} else {
6374					topo_tail->next = topo_node;
6375					topo_tail = topo_node;
6376				}
6377
6378				break;
6379			}
6380			case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
6381				link_rate = ddi_get8(mpt->m_acc_reply_frame_hdl,
6382				    &sas_topo_change_list->PHY[i].LinkRate);
6383				state = (link_rate &
6384				    MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >>
6385				    MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT;
6386				switch (state) {
6387				case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
6388					(void) sprintf(curr, "is disabled");
6389					break;
6390				case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
6391					(void) sprintf(curr, "is offline, "
6392					    "failed speed negotiation");
6393					break;
6394				case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
6395					(void) sprintf(curr, "SATA OOB "
6396					    "complete");
6397					break;
6398				case SMP_RESET_IN_PROGRESS:
6399					(void) sprintf(curr, "SMP reset in "
6400					    "progress");
6401					break;
6402				case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
6403					(void) sprintf(curr, "is online at "
6404					    "1.5 Gbps");
6405					if ((expd_handle == 0) &&
6406					    (enc_handle == 1)) {
6407						mpt->m_port_chng = 1;
6408					}
6409					break;
6410				case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
6411					(void) sprintf(curr, "is online at 3.0 "
6412					    "Gbps");
6413					if ((expd_handle == 0) &&
6414					    (enc_handle == 1)) {
6415						mpt->m_port_chng = 1;
6416					}
6417					break;
6418				case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
6419					(void) sprintf(curr, "is online at "
6420					    "6.0 Gbps");
6421					if ((expd_handle == 0) &&
6422					    (enc_handle == 1)) {
6423						mpt->m_port_chng = 1;
6424					}
6425					break;
6426				default:
6427					(void) sprintf(curr, "state is "
6428					    "unknown");
6429					break;
6430				}
6431
6432				state = (link_rate &
6433				    MPI2_EVENT_SAS_TOPO_LR_PREV_MASK) >>
6434				    MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT;
6435				switch (state) {
6436				case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED:
6437					(void) sprintf(prev, ", was disabled");
6438					break;
6439				case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED:
6440					(void) sprintf(prev, ", was offline, "
6441					    "failed speed negotiation");
6442					break;
6443				case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE:
6444					(void) sprintf(prev, ", was SATA OOB "
6445					    "complete");
6446					break;
6447				case SMP_RESET_IN_PROGRESS:
6448					(void) sprintf(prev, ", was SMP reset "
6449					    "in progress");
6450					break;
6451				case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5:
6452					(void) sprintf(prev, ", was online at "
6453					    "1.5 Gbps");
6454					break;
6455				case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0:
6456					(void) sprintf(prev, ", was online at "
6457					    "3.0 Gbps");
6458					break;
6459				case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0:
6460					(void) sprintf(prev, ", was online at "
6461					    "6.0 Gbps");
6462					break;
6463				default:
6464				break;
6465				}
6466				(void) sprintf(&string[strlen(string)], "link "
6467				    "changed, ");
6468				break;
6469			case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE:
6470				continue;
6471			case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING:
6472				(void) sprintf(&string[strlen(string)],
6473				    "target not responding, delaying "
6474				    "removal");
6475				break;
6476			}
6477			NDBG20(("mptsas%d phy %d DevHandle %x, %s%s%s\n",
6478			    mpt->m_instance, phy, dev_handle, string, curr,
6479			    prev));
6480		}
6481		if (topo_head != NULL) {
6482			/*
6483			 * Launch DR taskq to handle topology change
6484			 */
6485			if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
6486			    mptsas_handle_dr, (void *)topo_head,
6487			    DDI_NOSLEEP)) != DDI_SUCCESS) {
6488				mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
6489				    "for handle SAS DR event failed. \n");
6490			}
6491		}
6492		break;
6493	}
6494	case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
6495	{
6496		Mpi2EventDataIrConfigChangeList_t	*irChangeList;
6497		mptsas_topo_change_list_t		*topo_head = NULL;
6498		mptsas_topo_change_list_t		*topo_tail = NULL;
6499		mptsas_topo_change_list_t		*topo_node = NULL;
6500		mptsas_target_t				*ptgt;
6501		mptsas_hash_table_t			*tgttbl;
6502		uint8_t					num_entries, i, reason;
6503		uint16_t				volhandle, diskhandle;
6504
6505		irChangeList = (pMpi2EventDataIrConfigChangeList_t)
6506		    eventreply->EventData;
6507		num_entries = ddi_get8(mpt->m_acc_reply_frame_hdl,
6508		    &irChangeList->NumElements);
6509
6510		tgttbl = &mpt->m_active->m_tgttbl;
6511
6512		NDBG20(("mptsas%d IR_CONFIGURATION_CHANGE_LIST event received",
6513		    mpt->m_instance));
6514
6515		for (i = 0; i < num_entries; i++) {
6516			reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
6517			    &irChangeList->ConfigElement[i].ReasonCode);
6518			volhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6519			    &irChangeList->ConfigElement[i].VolDevHandle);
6520			diskhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6521			    &irChangeList->ConfigElement[i].PhysDiskDevHandle);
6522
6523			switch (reason) {
6524			case MPI2_EVENT_IR_CHANGE_RC_ADDED:
6525			case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
6526			{
6527				NDBG20(("mptsas %d volume added\n",
6528				    mpt->m_instance));
6529
6530				topo_node = kmem_zalloc(
6531				    sizeof (mptsas_topo_change_list_t),
6532				    KM_SLEEP);
6533
6534				topo_node->mpt = mpt;
6535				topo_node->event =
6536				    MPTSAS_DR_EVENT_RECONFIG_TARGET;
6537				topo_node->un.physport = 0xff;
6538				topo_node->devhdl = volhandle;
6539				topo_node->flags =
6540				    MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
6541				topo_node->object = NULL;
6542				if (topo_head == NULL) {
6543					topo_head = topo_tail = topo_node;
6544				} else {
6545					topo_tail->next = topo_node;
6546					topo_tail = topo_node;
6547				}
6548				break;
6549			}
6550			case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
6551			case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
6552			{
6553				NDBG20(("mptsas %d volume deleted\n",
6554				    mpt->m_instance));
6555				ptgt = mptsas_search_by_devhdl(tgttbl,
6556				    volhandle);
6557				if (ptgt == NULL)
6558					break;
6559
6560				/*
6561				 * Clear any flags related to volume
6562				 */
6563				(void) mptsas_delete_volume(mpt, volhandle);
6564
6565				/*
6566				 * Update DR flag immediately avoid I/O failure
6567				 */
6568				mutex_enter(&mpt->m_tx_waitq_mutex);
6569				ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6570				mutex_exit(&mpt->m_tx_waitq_mutex);
6571
6572				topo_node = kmem_zalloc(
6573				    sizeof (mptsas_topo_change_list_t),
6574				    KM_SLEEP);
6575				topo_node->mpt = mpt;
6576				topo_node->un.phymask = ptgt->m_phymask;
6577				topo_node->event =
6578				    MPTSAS_DR_EVENT_OFFLINE_TARGET;
6579				topo_node->devhdl = volhandle;
6580				topo_node->flags =
6581				    MPTSAS_TOPO_FLAG_RAID_ASSOCIATED;
6582				topo_node->object = (void *)ptgt;
6583				if (topo_head == NULL) {
6584					topo_head = topo_tail = topo_node;
6585				} else {
6586					topo_tail->next = topo_node;
6587					topo_tail = topo_node;
6588				}
6589				break;
6590			}
6591			case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
6592			case MPI2_EVENT_IR_CHANGE_RC_HIDE:
6593			{
6594				ptgt = mptsas_search_by_devhdl(tgttbl,
6595				    diskhandle);
6596				if (ptgt == NULL)
6597					break;
6598
6599				/*
6600				 * Update DR flag immediately avoid I/O failure
6601				 */
6602				mutex_enter(&mpt->m_tx_waitq_mutex);
6603				ptgt->m_dr_flag = MPTSAS_DR_INTRANSITION;
6604				mutex_exit(&mpt->m_tx_waitq_mutex);
6605
6606				topo_node = kmem_zalloc(
6607				    sizeof (mptsas_topo_change_list_t),
6608				    KM_SLEEP);
6609				topo_node->mpt = mpt;
6610				topo_node->un.phymask = ptgt->m_phymask;
6611				topo_node->event =
6612				    MPTSAS_DR_EVENT_OFFLINE_TARGET;
6613				topo_node->devhdl = diskhandle;
6614				topo_node->flags =
6615				    MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
6616				topo_node->object = (void *)ptgt;
6617				if (topo_head == NULL) {
6618					topo_head = topo_tail = topo_node;
6619				} else {
6620					topo_tail->next = topo_node;
6621					topo_tail = topo_node;
6622				}
6623				break;
6624			}
6625			case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
6626			case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
6627			{
6628				/*
6629				 * The physical drive is released by a IR
6630				 * volume. But we cannot get the the physport
6631				 * or phynum from the event data, so we only
6632				 * can get the physport/phynum after SAS
6633				 * Device Page0 request for the devhdl.
6634				 */
6635				topo_node = kmem_zalloc(
6636				    sizeof (mptsas_topo_change_list_t),
6637				    KM_SLEEP);
6638				topo_node->mpt = mpt;
6639				topo_node->un.phymask = 0;
6640				topo_node->event =
6641				    MPTSAS_DR_EVENT_RECONFIG_TARGET;
6642				topo_node->devhdl = diskhandle;
6643				topo_node->flags =
6644				    MPTSAS_TOPO_FLAG_RAID_PHYSDRV_ASSOCIATED;
6645				topo_node->object = NULL;
6646				mpt->m_port_chng = 1;
6647				if (topo_head == NULL) {
6648					topo_head = topo_tail = topo_node;
6649				} else {
6650					topo_tail->next = topo_node;
6651					topo_tail = topo_node;
6652				}
6653				break;
6654			}
6655			default:
6656				break;
6657			}
6658		}
6659
6660		if (topo_head != NULL) {
6661			/*
6662			 * Launch DR taskq to handle topology change
6663			 */
6664			if ((ddi_taskq_dispatch(mpt->m_dr_taskq,
6665			    mptsas_handle_dr, (void *)topo_head,
6666			    DDI_NOSLEEP)) != DDI_SUCCESS) {
6667				mptsas_log(mpt, CE_NOTE, "mptsas start taskq "
6668				    "for handle SAS DR event failed. \n");
6669			}
6670		}
6671		break;
6672	}
6673	default:
6674		return (DDI_FAILURE);
6675	}
6676
6677	return (DDI_SUCCESS);
6678}
6679
6680/*
6681 * handle events from ioc
6682 */
6683static void
6684mptsas_handle_event(void *args)
6685{
6686	m_replyh_arg_t			*replyh_arg;
6687	pMpi2EventNotificationReply_t	eventreply;
6688	uint32_t			event, iocloginfo, rfm;
6689	uint32_t			status, reply_index;
6690	uint8_t				port;
6691	mptsas_t			*mpt;
6692	uint_t				iocstatus;
6693
6694	replyh_arg = (m_replyh_arg_t *)args;
6695	rfm = replyh_arg->rfm;
6696	mpt = replyh_arg->mpt;
6697
6698	mutex_enter(&mpt->m_mutex);
6699
6700	eventreply = (pMpi2EventNotificationReply_t)
6701	    (mpt->m_reply_frame + (rfm - mpt->m_reply_frame_dma_addr));
6702	event = ddi_get16(mpt->m_acc_reply_frame_hdl, &eventreply->Event);
6703
6704	if (iocstatus = ddi_get16(mpt->m_acc_reply_frame_hdl,
6705	    &eventreply->IOCStatus)) {
6706		if (iocstatus == MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
6707			mptsas_log(mpt, CE_WARN,
6708			    "!mptsas_handle_event: IOCStatus=0x%x, "
6709			    "IOCLogInfo=0x%x", iocstatus,
6710			    ddi_get32(mpt->m_acc_reply_frame_hdl,
6711			    &eventreply->IOCLogInfo));
6712		} else {
6713			mptsas_log(mpt, CE_WARN,
6714			    "mptsas_handle_event: IOCStatus=0x%x, "
6715			    "IOCLogInfo=0x%x", iocstatus,
6716			    ddi_get32(mpt->m_acc_reply_frame_hdl,
6717			    &eventreply->IOCLogInfo));
6718		}
6719	}
6720
6721	/*
6722	 * figure out what kind of event we got and handle accordingly
6723	 */
6724	switch (event) {
6725	case MPI2_EVENT_LOG_ENTRY_ADDED:
6726		break;
6727	case MPI2_EVENT_LOG_DATA:
6728		iocloginfo = ddi_get32(mpt->m_acc_reply_frame_hdl,
6729		    &eventreply->IOCLogInfo);
6730		NDBG20(("mptsas %d log info %x received.\n", mpt->m_instance,
6731		    iocloginfo));
6732		break;
6733	case MPI2_EVENT_STATE_CHANGE:
6734		NDBG20(("mptsas%d state change.", mpt->m_instance));
6735		break;
6736	case MPI2_EVENT_HARD_RESET_RECEIVED:
6737		NDBG20(("mptsas%d event change.", mpt->m_instance));
6738		break;
6739	case MPI2_EVENT_SAS_DISCOVERY:
6740	{
6741		MPI2_EVENT_DATA_SAS_DISCOVERY	*sasdiscovery;
6742		char				string[80];
6743		uint8_t				rc;
6744
6745		sasdiscovery =
6746		    (pMpi2EventDataSasDiscovery_t)eventreply->EventData;
6747
6748		rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
6749		    &sasdiscovery->ReasonCode);
6750		port = ddi_get8(mpt->m_acc_reply_frame_hdl,
6751		    &sasdiscovery->PhysicalPort);
6752		status = ddi_get32(mpt->m_acc_reply_frame_hdl,
6753		    &sasdiscovery->DiscoveryStatus);
6754
6755		string[0] = 0;
6756		switch (rc) {
6757		case MPI2_EVENT_SAS_DISC_RC_STARTED:
6758			(void) sprintf(string, "STARTING");
6759			break;
6760		case MPI2_EVENT_SAS_DISC_RC_COMPLETED:
6761			(void) sprintf(string, "COMPLETED");
6762			break;
6763		default:
6764			(void) sprintf(string, "UNKNOWN");
6765			break;
6766		}
6767
6768		NDBG20(("SAS DISCOVERY is %s for port %d, status %x", string,
6769		    port, status));
6770
6771		break;
6772	}
6773	case MPI2_EVENT_EVENT_CHANGE:
6774		NDBG20(("mptsas%d event change.", mpt->m_instance));
6775		break;
6776	case MPI2_EVENT_TASK_SET_FULL:
6777	{
6778		pMpi2EventDataTaskSetFull_t	taskfull;
6779
6780		taskfull = (pMpi2EventDataTaskSetFull_t)eventreply->EventData;
6781
6782		NDBG20(("TASK_SET_FULL received for mptsas%d, depth %d\n",
6783		    mpt->m_instance,  ddi_get16(mpt->m_acc_reply_frame_hdl,
6784		    &taskfull->CurrentDepth)));
6785		break;
6786	}
6787	case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
6788	{
6789		/*
6790		 * SAS TOPOLOGY CHANGE LIST Event has already been handled
6791		 * in mptsas_handle_event_sync() of interrupt context
6792		 */
6793		break;
6794	}
6795	case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
6796	{
6797		pMpi2EventDataSasEnclDevStatusChange_t	encstatus;
6798		uint8_t					rc;
6799		char					string[80];
6800
6801		encstatus = (pMpi2EventDataSasEnclDevStatusChange_t)
6802		    eventreply->EventData;
6803
6804		rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
6805		    &encstatus->ReasonCode);
6806		switch (rc) {
6807		case MPI2_EVENT_SAS_ENCL_RC_ADDED:
6808			(void) sprintf(string, "added");
6809			break;
6810		case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING:
6811			(void) sprintf(string, ", not responding");
6812			break;
6813		default:
6814		break;
6815		}
6816		NDBG20(("mptsas%d ENCLOSURE STATUS CHANGE for enclosure %x%s\n",
6817		    mpt->m_instance, ddi_get16(mpt->m_acc_reply_frame_hdl,
6818		    &encstatus->EnclosureHandle), string));
6819		break;
6820	}
6821
6822	/*
6823	 * MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE is handled by
6824	 * mptsas_handle_event_sync,in here just send ack message.
6825	 */
6826	case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
6827	{
6828		pMpi2EventDataSasDeviceStatusChange_t	statuschange;
6829		uint8_t					rc;
6830		uint16_t				devhdl;
6831		uint64_t				wwn = 0;
6832		uint32_t				wwn_lo, wwn_hi;
6833
6834		statuschange = (pMpi2EventDataSasDeviceStatusChange_t)
6835		    eventreply->EventData;
6836		rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
6837		    &statuschange->ReasonCode);
6838		wwn_lo = ddi_get32(mpt->m_acc_reply_frame_hdl,
6839		    (uint32_t *)(void *)&statuschange->SASAddress);
6840		wwn_hi = ddi_get32(mpt->m_acc_reply_frame_hdl,
6841		    (uint32_t *)(void *)&statuschange->SASAddress + 1);
6842		wwn = ((uint64_t)wwn_hi << 32) | wwn_lo;
6843		devhdl =  ddi_get16(mpt->m_acc_reply_frame_hdl,
6844		    &statuschange->DevHandle);
6845
6846		NDBG13(("MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE wwn is %"PRIx64,
6847		    wwn));
6848
6849		switch (rc) {
6850		case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6851			NDBG20(("SMART data received, ASC/ASCQ = %02x/%02x",
6852			    ddi_get8(mpt->m_acc_reply_frame_hdl,
6853			    &statuschange->ASC),
6854			    ddi_get8(mpt->m_acc_reply_frame_hdl,
6855			    &statuschange->ASCQ)));
6856			break;
6857
6858		case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6859			NDBG20(("Device not supported"));
6860			break;
6861
6862		case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6863			NDBG20(("IOC internally generated the Target Reset "
6864			    "for devhdl:%x", devhdl));
6865			break;
6866
6867		case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET:
6868			NDBG20(("IOC's internally generated Target Reset "
6869			    "completed for devhdl:%x", devhdl));
6870			break;
6871
6872		case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6873			NDBG20(("IOC internally generated Abort Task"));
6874			break;
6875
6876		case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL:
6877			NDBG20(("IOC's internally generated Abort Task "
6878			    "completed"));
6879			break;
6880
6881		case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6882			NDBG20(("IOC internally generated Abort Task Set"));
6883			break;
6884
6885		case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6886			NDBG20(("IOC internally generated Clear Task Set"));
6887			break;
6888
6889		case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6890			NDBG20(("IOC internally generated Query Task"));
6891			break;
6892
6893		case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION:
6894			NDBG20(("Device sent an Asynchronous Notification"));
6895			break;
6896
6897		default:
6898			break;
6899		}
6900		break;
6901	}
6902	case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
6903	{
6904		/*
6905		 * IR TOPOLOGY CHANGE LIST Event has already been handled
6906		 * in mpt_handle_event_sync() of interrupt context
6907		 */
6908		break;
6909	}
6910	case MPI2_EVENT_IR_OPERATION_STATUS:
6911	{
6912		Mpi2EventDataIrOperationStatus_t	*irOpStatus;
6913		char					reason_str[80];
6914		uint8_t					rc, percent;
6915		uint16_t				handle;
6916
6917		irOpStatus = (pMpi2EventDataIrOperationStatus_t)
6918		    eventreply->EventData;
6919		rc = ddi_get8(mpt->m_acc_reply_frame_hdl,
6920		    &irOpStatus->RAIDOperation);
6921		percent = ddi_get8(mpt->m_acc_reply_frame_hdl,
6922		    &irOpStatus->PercentComplete);
6923		handle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6924		    &irOpStatus->VolDevHandle);
6925
6926		switch (rc) {
6927			case MPI2_EVENT_IR_RAIDOP_RESYNC:
6928				(void) sprintf(reason_str, "resync");
6929				break;
6930			case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION:
6931				(void) sprintf(reason_str, "online capacity "
6932				    "expansion");
6933				break;
6934			case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK:
6935				(void) sprintf(reason_str, "consistency check");
6936				break;
6937			default:
6938				(void) sprintf(reason_str, "unknown reason %x",
6939				    rc);
6940		}
6941
6942		NDBG20(("mptsas%d raid operational status: (%s)"
6943		    "\thandle(0x%04x), percent complete(%d)\n",
6944		    mpt->m_instance, reason_str, handle, percent));
6945		break;
6946	}
6947	case MPI2_EVENT_IR_VOLUME:
6948	{
6949		Mpi2EventDataIrVolume_t		*irVolume;
6950		uint16_t			devhandle;
6951		uint32_t			state;
6952		int				config, vol;
6953		mptsas_slots_t			*slots = mpt->m_active;
6954		uint8_t				found = FALSE;
6955
6956		irVolume = (pMpi2EventDataIrVolume_t)eventreply->EventData;
6957		state = ddi_get32(mpt->m_acc_reply_frame_hdl,
6958		    &irVolume->NewValue);
6959		devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
6960		    &irVolume->VolDevHandle);
6961
6962		NDBG20(("EVENT_IR_VOLUME event is received"));
6963
6964		/*
6965		 * Get latest RAID info and then find the DevHandle for this
6966		 * event in the configuration.  If the DevHandle is not found
6967		 * just exit the event.
6968		 */
6969		(void) mptsas_get_raid_info(mpt);
6970		for (config = 0; config < slots->m_num_raid_configs;
6971		    config++) {
6972			for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
6973				if (slots->m_raidconfig[config].m_raidvol[vol].
6974				    m_raidhandle == devhandle) {
6975					found = TRUE;
6976					break;
6977				}
6978			}
6979		}
6980		if (!found) {
6981			break;
6982		}
6983
6984		switch (irVolume->ReasonCode) {
6985		case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED:
6986		{
6987			uint32_t i;
6988			slots->m_raidconfig[config].m_raidvol[vol].m_settings =
6989			    state;
6990
6991			i = state & MPI2_RAIDVOL0_SETTING_MASK_WRITE_CACHING;
6992			mptsas_log(mpt, CE_NOTE, " Volume %d settings changed"
6993			    ", auto-config of hot-swap drives is %s"
6994			    ", write caching is %s"
6995			    ", hot-spare pool mask is %02x\n",
6996			    vol, state &
6997			    MPI2_RAIDVOL0_SETTING_AUTO_CONFIG_HSWAP_DISABLE
6998			    ? "disabled" : "enabled",
6999			    i == MPI2_RAIDVOL0_SETTING_UNCHANGED
7000			    ? "controlled by member disks" :
7001			    i == MPI2_RAIDVOL0_SETTING_DISABLE_WRITE_CACHING
7002			    ? "disabled" :
7003			    i == MPI2_RAIDVOL0_SETTING_ENABLE_WRITE_CACHING
7004			    ? "enabled" :
7005			    "incorrectly set",
7006			    (state >> 16) & 0xff);
7007				break;
7008		}
7009		case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED:
7010		{
7011			slots->m_raidconfig[config].m_raidvol[vol].m_state =
7012			    (uint8_t)state;
7013
7014			mptsas_log(mpt, CE_NOTE,
7015			    "Volume %d is now %s\n", vol,
7016			    state == MPI2_RAID_VOL_STATE_OPTIMAL
7017			    ? "optimal" :
7018			    state == MPI2_RAID_VOL_STATE_DEGRADED
7019			    ? "degraded" :
7020			    state == MPI2_RAID_VOL_STATE_ONLINE
7021			    ? "online" :
7022			    state == MPI2_RAID_VOL_STATE_INITIALIZING
7023			    ? "initializing" :
7024			    state == MPI2_RAID_VOL_STATE_FAILED
7025			    ? "failed" :
7026			    state == MPI2_RAID_VOL_STATE_MISSING
7027			    ? "missing" :
7028			    "state unknown");
7029			break;
7030		}
7031		case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED:
7032		{
7033			slots->m_raidconfig[config].m_raidvol[vol].
7034			    m_statusflags = state;
7035
7036			mptsas_log(mpt, CE_NOTE,
7037			    " Volume %d is now %s%s%s%s%s%s%s%s%s\n",
7038			    vol,
7039			    state & MPI2_RAIDVOL0_STATUS_FLAG_ENABLED
7040			    ? ", enabled" : ", disabled",
7041			    state & MPI2_RAIDVOL0_STATUS_FLAG_QUIESCED
7042			    ? ", quiesced" : "",
7043			    state & MPI2_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
7044			    ? ", inactive" : ", active",
7045			    state &
7046			    MPI2_RAIDVOL0_STATUS_FLAG_BAD_BLOCK_TABLE_FULL
7047			    ? ", bad block table is full" : "",
7048			    state &
7049			    MPI2_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
7050			    ? ", resync in progress" : "",
7051			    state & MPI2_RAIDVOL0_STATUS_FLAG_BACKGROUND_INIT
7052			    ? ", background initialization in progress" : "",
7053			    state &
7054			    MPI2_RAIDVOL0_STATUS_FLAG_CAPACITY_EXPANSION
7055			    ? ", capacity expansion in progress" : "",
7056			    state &
7057			    MPI2_RAIDVOL0_STATUS_FLAG_CONSISTENCY_CHECK
7058			    ? ", consistency check in progress" : "",
7059			    state & MPI2_RAIDVOL0_STATUS_FLAG_DATA_SCRUB
7060			    ? ", data scrub in progress" : "");
7061			break;
7062		}
7063		default:
7064			break;
7065		}
7066		break;
7067	}
7068	case MPI2_EVENT_IR_PHYSICAL_DISK:
7069	{
7070		Mpi2EventDataIrPhysicalDisk_t	*irPhysDisk;
7071		uint16_t			devhandle, enchandle, slot;
7072		uint32_t			status, state;
7073		uint8_t				physdisknum, reason;
7074
7075		irPhysDisk = (Mpi2EventDataIrPhysicalDisk_t *)
7076		    eventreply->EventData;
7077		physdisknum = ddi_get8(mpt->m_acc_reply_frame_hdl,
7078		    &irPhysDisk->PhysDiskNum);
7079		devhandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7080		    &irPhysDisk->PhysDiskDevHandle);
7081		enchandle = ddi_get16(mpt->m_acc_reply_frame_hdl,
7082		    &irPhysDisk->EnclosureHandle);
7083		slot = ddi_get16(mpt->m_acc_reply_frame_hdl,
7084		    &irPhysDisk->Slot);
7085		state = ddi_get32(mpt->m_acc_reply_frame_hdl,
7086		    &irPhysDisk->NewValue);
7087		reason = ddi_get8(mpt->m_acc_reply_frame_hdl,
7088		    &irPhysDisk->ReasonCode);
7089
7090		NDBG20(("EVENT_IR_PHYSICAL_DISK event is received"));
7091
7092		switch (reason) {
7093		case MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED:
7094			mptsas_log(mpt, CE_NOTE,
7095			    " PhysDiskNum %d with DevHandle 0x%x in slot %d "
7096			    "for enclosure with handle 0x%x is now in hot "
7097			    "spare pool %d",
7098			    physdisknum, devhandle, slot, enchandle,
7099			    (state >> 16) & 0xff);
7100			break;
7101
7102		case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED:
7103			status = state;
7104			mptsas_log(mpt, CE_NOTE,
7105			    " PhysDiskNum %d with DevHandle 0x%x in slot %d "
7106			    "for enclosure with handle 0x%x is now "
7107			    "%s%s%s%s%s\n", physdisknum, devhandle, slot,
7108			    enchandle,
7109			    status & MPI2_PHYSDISK0_STATUS_FLAG_INACTIVE_VOLUME
7110			    ? ", inactive" : ", active",
7111			    status & MPI2_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
7112			    ? ", out of sync" : "",
7113			    status & MPI2_PHYSDISK0_STATUS_FLAG_QUIESCED
7114			    ? ", quiesced" : "",
7115			    status &
7116			    MPI2_PHYSDISK0_STATUS_FLAG_WRITE_CACHE_ENABLED
7117			    ? ", write cache enabled" : "",
7118			    status & MPI2_PHYSDISK0_STATUS_FLAG_OCE_TARGET
7119			    ? ", capacity expansion target" : "");
7120			break;
7121
7122		case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED:
7123			mptsas_log(mpt, CE_NOTE,
7124			    " PhysDiskNum %d with DevHandle 0x%x in slot %d "
7125			    "for enclosure with handle 0x%x is now %s\n",
7126			    physdisknum, devhandle, slot, enchandle,
7127			    state == MPI2_RAID_PD_STATE_OPTIMAL
7128			    ? "optimal" :
7129			    state == MPI2_RAID_PD_STATE_REBUILDING
7130			    ? "rebuilding" :
7131			    state == MPI2_RAID_PD_STATE_DEGRADED
7132			    ? "degraded" :
7133			    state == MPI2_RAID_PD_STATE_HOT_SPARE
7134			    ? "a hot spare" :
7135			    state == MPI2_RAID_PD_STATE_ONLINE
7136			    ? "online" :
7137			    state == MPI2_RAID_PD_STATE_OFFLINE
7138			    ? "offline" :
7139			    state == MPI2_RAID_PD_STATE_NOT_COMPATIBLE
7140			    ? "not compatible" :
7141			    state == MPI2_RAID_PD_STATE_NOT_CONFIGURED
7142			    ? "not configured" :
7143			    "state unknown");
7144			break;
7145		}
7146		break;
7147	}
7148	default:
7149		mptsas_log(mpt, CE_NOTE, "mptsas%d: unknown event %x received",
7150		    mpt->m_instance, event);
7151		break;
7152	}
7153
7154	/*
7155	 * Return the reply frame to the free queue.
7156	 */
7157	reply_index = mpt->m_free_index;
7158	ddi_put32(mpt->m_acc_free_queue_hdl,
7159	    &((uint32_t *)(void *)mpt->m_free_queue)[reply_index], rfm);
7160	(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
7161	    DDI_DMA_SYNC_FORDEV);
7162	if (++reply_index == mpt->m_free_queue_depth) {
7163		reply_index = 0;
7164	}
7165	mpt->m_free_index = reply_index;
7166	ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, reply_index);
7167	mutex_exit(&mpt->m_mutex);
7168}
7169
7170/*
7171 * invoked from timeout() to restart qfull cmds with throttle == 0
7172 */
7173static void
7174mptsas_restart_cmd(void *arg)
7175{
7176	mptsas_t	*mpt = arg;
7177	mptsas_target_t	*ptgt = NULL;
7178
7179	mutex_enter(&mpt->m_mutex);
7180
7181	mpt->m_restart_cmd_timeid = 0;
7182
7183	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
7184	    MPTSAS_HASH_FIRST);
7185	while (ptgt != NULL) {
7186		if (ptgt->m_reset_delay == 0) {
7187			if (ptgt->m_t_throttle == QFULL_THROTTLE) {
7188				mptsas_set_throttle(mpt, ptgt,
7189				    MAX_THROTTLE);
7190			}
7191		}
7192
7193		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
7194		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
7195	}
7196	mptsas_restart_hba(mpt);
7197	mutex_exit(&mpt->m_mutex);
7198}
7199
7200void
7201mptsas_remove_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
7202{
7203	int		slot;
7204	mptsas_slots_t	*slots = mpt->m_active;
7205	int		t;
7206	mptsas_target_t	*ptgt = cmd->cmd_tgt_addr;
7207
7208	ASSERT(cmd != NULL);
7209	ASSERT(cmd->cmd_queued == FALSE);
7210
7211	/*
7212	 * Task Management cmds are removed in their own routines.  Also,
7213	 * we don't want to modify timeout based on TM cmds.
7214	 */
7215	if (cmd->cmd_flags & CFLAG_TM_CMD) {
7216		return;
7217	}
7218
7219	t = Tgt(cmd);
7220	slot = cmd->cmd_slot;
7221
7222	/*
7223	 * remove the cmd.
7224	 */
7225	if (cmd == slots->m_slot[slot]) {
7226		NDBG31(("mptsas_remove_cmd: removing cmd=0x%p", (void *)cmd));
7227		slots->m_slot[slot] = NULL;
7228		mpt->m_ncmds--;
7229
7230		/*
7231		 * only decrement per target ncmds if command
7232		 * has a target associated with it.
7233		 */
7234		if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
7235			ptgt->m_t_ncmds--;
7236			/*
7237			 * reset throttle if we just ran an untagged command
7238			 * to a tagged target
7239			 */
7240			if ((ptgt->m_t_ncmds == 0) &&
7241			    ((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0)) {
7242				mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
7243			}
7244		}
7245
7246	}
7247
7248	/*
7249	 * This is all we need to do for ioc commands.
7250	 */
7251	if (cmd->cmd_flags & CFLAG_CMDIOC) {
7252		mptsas_return_to_pool(mpt, cmd);
7253		return;
7254	}
7255
7256	/*
7257	 * Figure out what to set tag Q timeout for...
7258	 *
7259	 * Optimize: If we have duplicate's of same timeout
7260	 * we're using, then we'll use it again until we run
7261	 * out of duplicates.  This should be the normal case
7262	 * for block and raw I/O.
7263	 * If no duplicates, we have to scan through tag que and
7264	 * find the longest timeout value and use it.  This is
7265	 * going to take a while...
7266	 * Add 1 to m_n_slots to account for TM request.
7267	 */
7268	if (cmd->cmd_pkt->pkt_time == ptgt->m_timebase) {
7269		if (--(ptgt->m_dups) == 0) {
7270			if (ptgt->m_t_ncmds) {
7271				mptsas_cmd_t *ssp;
7272				uint_t n = 0;
7273				ushort_t nslots = (slots->m_n_slots + 1);
7274				ushort_t i;
7275				/*
7276				 * This crude check assumes we don't do
7277				 * this too often which seems reasonable
7278				 * for block and raw I/O.
7279				 */
7280				for (i = 0; i < nslots; i++) {
7281					ssp = slots->m_slot[i];
7282					if (ssp && (Tgt(ssp) == t) &&
7283					    (ssp->cmd_pkt->pkt_time > n)) {
7284						n = ssp->cmd_pkt->pkt_time;
7285						ptgt->m_dups = 1;
7286					} else if (ssp && (Tgt(ssp) == t) &&
7287					    (ssp->cmd_pkt->pkt_time == n)) {
7288						ptgt->m_dups++;
7289					}
7290				}
7291				ptgt->m_timebase = n;
7292			} else {
7293				ptgt->m_dups = 0;
7294				ptgt->m_timebase = 0;
7295			}
7296		}
7297	}
7298	ptgt->m_timeout = ptgt->m_timebase;
7299
7300	ASSERT(cmd != slots->m_slot[cmd->cmd_slot]);
7301}
7302
7303/*
7304 * accept all cmds on the tx_waitq if any and then
7305 * start a fresh request from the top of the device queue.
7306 *
7307 * since there are always cmds queued on the tx_waitq, and rare cmds on
7308 * the instance waitq, so this function should not be invoked in the ISR,
7309 * the mptsas_restart_waitq() is invoked in the ISR instead. otherwise, the
7310 * burden belongs to the IO dispatch CPUs is moved the interrupt CPU.
7311 */
7312static void
7313mptsas_restart_hba(mptsas_t *mpt)
7314{
7315	ASSERT(mutex_owned(&mpt->m_mutex));
7316
7317	mutex_enter(&mpt->m_tx_waitq_mutex);
7318	if (mpt->m_tx_waitq) {
7319		mptsas_accept_tx_waitq(mpt);
7320	}
7321	mutex_exit(&mpt->m_tx_waitq_mutex);
7322	mptsas_restart_waitq(mpt);
7323}
7324
7325/*
7326 * start a fresh request from the top of the device queue
7327 */
7328static void
7329mptsas_restart_waitq(mptsas_t *mpt)
7330{
7331	mptsas_cmd_t	*cmd, *next_cmd;
7332	mptsas_target_t *ptgt = NULL;
7333
7334	NDBG1(("mptsas_restart_waitq: mpt=0x%p", (void *)mpt));
7335
7336	ASSERT(mutex_owned(&mpt->m_mutex));
7337
7338	/*
7339	 * If there is a reset delay, don't start any cmds.  Otherwise, start
7340	 * as many cmds as possible.
7341	 * Since SMID 0 is reserved and the TM slot is reserved, the actual max
7342	 * commands is m_max_requests - 2.
7343	 */
7344	cmd = mpt->m_waitq;
7345
7346	while (cmd != NULL) {
7347		next_cmd = cmd->cmd_linkp;
7348		if (cmd->cmd_flags & CFLAG_PASSTHRU) {
7349			if (mptsas_save_cmd(mpt, cmd) == TRUE) {
7350				/*
7351				 * passthru command get slot need
7352				 * set CFLAG_PREPARED.
7353				 */
7354				cmd->cmd_flags |= CFLAG_PREPARED;
7355				mptsas_waitq_delete(mpt, cmd);
7356				mptsas_start_passthru(mpt, cmd);
7357			}
7358			cmd = next_cmd;
7359			continue;
7360		}
7361		if (cmd->cmd_flags & CFLAG_CONFIG) {
7362			if (mptsas_save_cmd(mpt, cmd) == TRUE) {
7363				/*
7364				 * Send the config page request and delete it
7365				 * from the waitq.
7366				 */
7367				cmd->cmd_flags |= CFLAG_PREPARED;
7368				mptsas_waitq_delete(mpt, cmd);
7369				mptsas_start_config_page_access(mpt, cmd);
7370			}
7371			cmd = next_cmd;
7372			continue;
7373		}
7374
7375		ptgt = cmd->cmd_tgt_addr;
7376		if (ptgt && (ptgt->m_t_throttle == DRAIN_THROTTLE) &&
7377		    (ptgt->m_t_ncmds == 0)) {
7378			mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
7379		}
7380		if ((mpt->m_ncmds <= (mpt->m_max_requests - 2)) &&
7381		    (ptgt && (ptgt->m_reset_delay == 0)) &&
7382		    (ptgt && (ptgt->m_t_ncmds <
7383		    ptgt->m_t_throttle))) {
7384			if (mptsas_save_cmd(mpt, cmd) == TRUE) {
7385				mptsas_waitq_delete(mpt, cmd);
7386				(void) mptsas_start_cmd(mpt, cmd);
7387			}
7388		}
7389		cmd = next_cmd;
7390	}
7391}
7392/*
7393 * Cmds are queued if tran_start() doesn't get the m_mutexlock(no wait).
7394 * Accept all those queued cmds before new cmd is accept so that the
7395 * cmds are sent in order.
7396 */
7397static void
7398mptsas_accept_tx_waitq(mptsas_t *mpt)
7399{
7400	mptsas_cmd_t *cmd;
7401
7402	ASSERT(mutex_owned(&mpt->m_mutex));
7403	ASSERT(mutex_owned(&mpt->m_tx_waitq_mutex));
7404
7405	/*
7406	 * A Bus Reset could occur at any time and flush the tx_waitq,
7407	 * so we cannot count on the tx_waitq to contain even one cmd.
7408	 * And when the m_tx_waitq_mutex is released and run
7409	 * mptsas_accept_pkt(), the tx_waitq may be flushed.
7410	 */
7411	cmd = mpt->m_tx_waitq;
7412	for (;;) {
7413		if ((cmd = mpt->m_tx_waitq) == NULL) {
7414			mpt->m_tx_draining = 0;
7415			break;
7416		}
7417		if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL) {
7418			mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
7419		}
7420		cmd->cmd_linkp = NULL;
7421		mutex_exit(&mpt->m_tx_waitq_mutex);
7422		if (mptsas_accept_pkt(mpt, cmd) != TRAN_ACCEPT)
7423			cmn_err(CE_WARN, "mpt: mptsas_accept_tx_waitq: failed "
7424			    "to accept cmd on queue\n");
7425		mutex_enter(&mpt->m_tx_waitq_mutex);
7426	}
7427}
7428
7429
7430/*
7431 * mpt tag type lookup
7432 */
7433static char mptsas_tag_lookup[] =
7434	{0, MSG_HEAD_QTAG, MSG_ORDERED_QTAG, 0, MSG_SIMPLE_QTAG};
7435
7436static int
7437mptsas_start_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
7438{
7439	struct scsi_pkt		*pkt = CMD2PKT(cmd);
7440	uint32_t		control = 0;
7441	int			n;
7442	caddr_t			mem;
7443	pMpi2SCSIIORequest_t	io_request;
7444	ddi_dma_handle_t	dma_hdl = mpt->m_dma_req_frame_hdl;
7445	ddi_acc_handle_t	acc_hdl = mpt->m_acc_req_frame_hdl;
7446	mptsas_target_t		*ptgt = cmd->cmd_tgt_addr;
7447	uint16_t		SMID, io_flags = 0;
7448	uint32_t		request_desc_low, request_desc_high;
7449
7450	NDBG1(("mptsas_start_cmd: cmd=0x%p", (void *)cmd));
7451
7452	/*
7453	 * Set SMID and increment index.  Rollover to 1 instead of 0 if index
7454	 * is at the max.  0 is an invalid SMID, so we call the first index 1.
7455	 */
7456	SMID = cmd->cmd_slot;
7457
7458	/*
7459	 * It is possible for back to back device reset to
7460	 * happen before the reset delay has expired.  That's
7461	 * ok, just let the device reset go out on the bus.
7462	 */
7463	if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) {
7464		ASSERT(ptgt->m_reset_delay == 0);
7465	}
7466
7467	/*
7468	 * if a non-tagged cmd is submitted to an active tagged target
7469	 * then drain before submitting this cmd; SCSI-2 allows RQSENSE
7470	 * to be untagged
7471	 */
7472	if (((cmd->cmd_pkt_flags & FLAG_TAGMASK) == 0) &&
7473	    (ptgt->m_t_ncmds > 1) &&
7474	    ((cmd->cmd_flags & CFLAG_TM_CMD) == 0) &&
7475	    (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE)) {
7476		if ((cmd->cmd_pkt_flags & FLAG_NOINTR) == 0) {
7477			NDBG23(("target=%d, untagged cmd, start draining\n",
7478			    ptgt->m_devhdl));
7479
7480			if (ptgt->m_reset_delay == 0) {
7481				mptsas_set_throttle(mpt, ptgt, DRAIN_THROTTLE);
7482			}
7483
7484			mptsas_remove_cmd(mpt, cmd);
7485			cmd->cmd_pkt_flags |= FLAG_HEAD;
7486			mptsas_waitq_add(mpt, cmd);
7487		}
7488		return (DDI_FAILURE);
7489	}
7490
7491	/*
7492	 * Set correct tag bits.
7493	 */
7494	if (cmd->cmd_pkt_flags & FLAG_TAGMASK) {
7495		switch (mptsas_tag_lookup[((cmd->cmd_pkt_flags &
7496		    FLAG_TAGMASK) >> 12)]) {
7497		case MSG_SIMPLE_QTAG:
7498			control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
7499			break;
7500		case MSG_HEAD_QTAG:
7501			control |= MPI2_SCSIIO_CONTROL_HEADOFQ;
7502			break;
7503		case MSG_ORDERED_QTAG:
7504			control |= MPI2_SCSIIO_CONTROL_ORDEREDQ;
7505			break;
7506		default:
7507			mptsas_log(mpt, CE_WARN, "mpt: Invalid tag type\n");
7508			break;
7509		}
7510	} else {
7511		if (*(cmd->cmd_pkt->pkt_cdbp) != SCMD_REQUEST_SENSE) {
7512				ptgt->m_t_throttle = 1;
7513		}
7514		control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
7515	}
7516
7517	mem = mpt->m_req_frame + (mpt->m_req_frame_size * SMID);
7518	io_request = (pMpi2SCSIIORequest_t)mem;
7519
7520	bzero(io_request, sizeof (Mpi2SCSIIORequest_t));
7521	ddi_put8(acc_hdl, &io_request->SGLOffset0, offsetof
7522	    (MPI2_SCSI_IO_REQUEST, SGL) / 4);
7523	mptsas_init_std_hdr(acc_hdl, io_request, ptgt->m_devhdl, Lun(cmd), 0,
7524	    MPI2_FUNCTION_SCSI_IO_REQUEST);
7525
7526	(void) ddi_rep_put8(acc_hdl, (uint8_t *)pkt->pkt_cdbp,
7527	    io_request->CDB.CDB32, cmd->cmd_cdblen, DDI_DEV_AUTOINCR);
7528
7529	io_flags = cmd->cmd_cdblen;
7530	ddi_put16(acc_hdl, &io_request->IoFlags, io_flags);
7531	/*
7532	 * setup the Scatter/Gather DMA list for this request
7533	 */
7534	if (cmd->cmd_cookiec > 0) {
7535		mptsas_sge_setup(mpt, cmd, &control, io_request, acc_hdl);
7536	} else {
7537		ddi_put32(acc_hdl, &io_request->SGL.MpiSimple.FlagsLength,
7538		    ((uint32_t)MPI2_SGE_FLAGS_LAST_ELEMENT |
7539		    MPI2_SGE_FLAGS_END_OF_BUFFER |
7540		    MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
7541		    MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT);
7542	}
7543
7544	/*
7545	 * save ARQ information
7546	 */
7547	ddi_put8(acc_hdl, &io_request->SenseBufferLength, cmd->cmd_rqslen);
7548	if ((cmd->cmd_flags & (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) ==
7549	    (CFLAG_SCBEXTERN | CFLAG_EXTARQBUFVALID)) {
7550		ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress,
7551		    cmd->cmd_ext_arqcookie.dmac_address);
7552	} else {
7553		ddi_put32(acc_hdl, &io_request->SenseBufferLowAddress,
7554		    cmd->cmd_arqcookie.dmac_address);
7555	}
7556
7557	ddi_put32(acc_hdl, &io_request->Control, control);
7558
7559	NDBG31(("starting message=0x%p, with cmd=0x%p",
7560	    (void *)(uintptr_t)mpt->m_req_frame_dma_addr, (void *)cmd));
7561
7562	(void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
7563
7564	/*
7565	 * Build request descriptor and write it to the request desc post reg.
7566	 */
7567	request_desc_low = (SMID << 16) + MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
7568	request_desc_high = ptgt->m_devhdl << 16;
7569	MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high);
7570
7571	/*
7572	 * Start timeout.
7573	 */
7574#ifdef MPTSAS_TEST
7575	/*
7576	 * Temporarily set timebase = 0;  needed for
7577	 * timeout torture test.
7578	 */
7579	if (mptsas_test_timeouts) {
7580		ptgt->m_timebase = 0;
7581	}
7582#endif
7583	n = pkt->pkt_time - ptgt->m_timebase;
7584
7585	if (n == 0) {
7586		(ptgt->m_dups)++;
7587		ptgt->m_timeout = ptgt->m_timebase;
7588	} else if (n > 0) {
7589		ptgt->m_timeout =
7590		    ptgt->m_timebase = pkt->pkt_time;
7591		ptgt->m_dups = 1;
7592	} else if (n < 0) {
7593		ptgt->m_timeout = ptgt->m_timebase;
7594	}
7595#ifdef MPTSAS_TEST
7596	/*
7597	 * Set back to a number higher than
7598	 * mptsas_scsi_watchdog_tick
7599	 * so timeouts will happen in mptsas_watchsubr
7600	 */
7601	if (mptsas_test_timeouts) {
7602		ptgt->m_timebase = 60;
7603	}
7604#endif
7605
7606	if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
7607	    (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
7608		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
7609		return (DDI_FAILURE);
7610	}
7611	return (DDI_SUCCESS);
7612}
7613
7614/*
7615 * Select a helper thread to handle current doneq
7616 */
7617static void
7618mptsas_deliver_doneq_thread(mptsas_t *mpt)
7619{
7620	uint64_t			t, i;
7621	uint32_t			min = 0xffffffff;
7622	mptsas_doneq_thread_list_t	*item;
7623
7624	for (i = 0; i < mpt->m_doneq_thread_n; i++) {
7625		item = &mpt->m_doneq_thread_id[i];
7626		/*
7627		 * If the completed command on help thread[i] less than
7628		 * doneq_thread_threshold, then pick the thread[i]. Otherwise
7629		 * pick a thread which has least completed command.
7630		 */
7631
7632		mutex_enter(&item->mutex);
7633		if (item->len < mpt->m_doneq_thread_threshold) {
7634			t = i;
7635			mutex_exit(&item->mutex);
7636			break;
7637		}
7638		if (item->len < min) {
7639			min = item->len;
7640			t = i;
7641		}
7642		mutex_exit(&item->mutex);
7643	}
7644	mutex_enter(&mpt->m_doneq_thread_id[t].mutex);
7645	mptsas_doneq_mv(mpt, t);
7646	cv_signal(&mpt->m_doneq_thread_id[t].cv);
7647	mutex_exit(&mpt->m_doneq_thread_id[t].mutex);
7648}
7649
7650/*
7651 * move the current global doneq to the doneq of thead[t]
7652 */
7653static void
7654mptsas_doneq_mv(mptsas_t *mpt, uint64_t t)
7655{
7656	mptsas_cmd_t			*cmd;
7657	mptsas_doneq_thread_list_t	*item = &mpt->m_doneq_thread_id[t];
7658
7659	ASSERT(mutex_owned(&item->mutex));
7660	while ((cmd = mpt->m_doneq) != NULL) {
7661		if ((mpt->m_doneq = cmd->cmd_linkp) == NULL) {
7662			mpt->m_donetail = &mpt->m_doneq;
7663		}
7664		cmd->cmd_linkp = NULL;
7665		*item->donetail = cmd;
7666		item->donetail = &cmd->cmd_linkp;
7667		mpt->m_doneq_len--;
7668		item->len++;
7669	}
7670}
7671
7672void
7673mptsas_fma_check(mptsas_t *mpt, mptsas_cmd_t *cmd)
7674{
7675	struct scsi_pkt	*pkt = CMD2PKT(cmd);
7676
7677	/* Check all acc and dma handles */
7678	if ((mptsas_check_acc_handle(mpt->m_datap) !=
7679	    DDI_SUCCESS) ||
7680	    (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
7681	    DDI_SUCCESS) ||
7682	    (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) !=
7683	    DDI_SUCCESS) ||
7684	    (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) !=
7685	    DDI_SUCCESS) ||
7686	    (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) !=
7687	    DDI_SUCCESS) ||
7688	    (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) !=
7689	    DDI_SUCCESS) ||
7690	    (mptsas_check_acc_handle(mpt->m_config_handle) !=
7691	    DDI_SUCCESS)) {
7692		ddi_fm_service_impact(mpt->m_dip,
7693		    DDI_SERVICE_UNAFFECTED);
7694		ddi_fm_acc_err_clear(mpt->m_config_handle,
7695		    DDI_FME_VER0);
7696		pkt->pkt_reason = CMD_TRAN_ERR;
7697		pkt->pkt_statistics = 0;
7698	}
7699	if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
7700	    DDI_SUCCESS) ||
7701	    (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) !=
7702	    DDI_SUCCESS) ||
7703	    (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) !=
7704	    DDI_SUCCESS) ||
7705	    (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) !=
7706	    DDI_SUCCESS) ||
7707	    (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) !=
7708	    DDI_SUCCESS)) {
7709		ddi_fm_service_impact(mpt->m_dip,
7710		    DDI_SERVICE_UNAFFECTED);
7711		pkt->pkt_reason = CMD_TRAN_ERR;
7712		pkt->pkt_statistics = 0;
7713	}
7714	if (cmd->cmd_dmahandle &&
7715	    (mptsas_check_dma_handle(cmd->cmd_dmahandle) != DDI_SUCCESS)) {
7716		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
7717		pkt->pkt_reason = CMD_TRAN_ERR;
7718		pkt->pkt_statistics = 0;
7719	}
7720	if ((cmd->cmd_extra_frames &&
7721	    ((mptsas_check_dma_handle(cmd->cmd_extra_frames->m_dma_hdl) !=
7722	    DDI_SUCCESS) ||
7723	    (mptsas_check_acc_handle(cmd->cmd_extra_frames->m_acc_hdl) !=
7724	    DDI_SUCCESS)))) {
7725		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
7726		pkt->pkt_reason = CMD_TRAN_ERR;
7727		pkt->pkt_statistics = 0;
7728	}
7729	if (cmd->cmd_arqhandle &&
7730	    (mptsas_check_dma_handle(cmd->cmd_arqhandle) != 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_ext_arqhandle &&
7736	    (mptsas_check_dma_handle(cmd->cmd_ext_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}
7742
7743/*
7744 * These routines manipulate the queue of commands that
7745 * are waiting for their completion routines to be called.
7746 * The queue is usually in FIFO order but on an MP system
7747 * it's possible for the completion routines to get out
7748 * of order. If that's a problem you need to add a global
7749 * mutex around the code that calls the completion routine
7750 * in the interrupt handler.
7751 */
7752static void
7753mptsas_doneq_add(mptsas_t *mpt, mptsas_cmd_t *cmd)
7754{
7755	struct scsi_pkt	*pkt = CMD2PKT(cmd);
7756
7757	NDBG31(("mptsas_doneq_add: cmd=0x%p", (void *)cmd));
7758
7759	ASSERT((cmd->cmd_flags & CFLAG_COMPLETED) == 0);
7760	cmd->cmd_linkp = NULL;
7761	cmd->cmd_flags |= CFLAG_FINISHED;
7762	cmd->cmd_flags &= ~CFLAG_IN_TRANSPORT;
7763
7764	mptsas_fma_check(mpt, cmd);
7765
7766	/*
7767	 * only add scsi pkts that have completion routines to
7768	 * the doneq.  no intr cmds do not have callbacks.
7769	 * run the callback on an ARQ pkt immediately.  This
7770	 * frees the ARQ for other check conditions.
7771	 */
7772	if (pkt->pkt_comp && !(cmd->cmd_flags & CFLAG_CMDARQ)) {
7773		*mpt->m_donetail = cmd;
7774		mpt->m_donetail = &cmd->cmd_linkp;
7775		mpt->m_doneq_len++;
7776	} else if (pkt->pkt_comp && (cmd->cmd_flags & CFLAG_CMDARQ)) {
7777		cmd->cmd_flags |= CFLAG_COMPLETED;
7778		mutex_exit(&mpt->m_mutex);
7779		mptsas_pkt_comp(pkt, cmd);
7780		mutex_enter(&mpt->m_mutex);
7781	}
7782}
7783
7784static mptsas_cmd_t *
7785mptsas_doneq_thread_rm(mptsas_t *mpt, uint64_t t)
7786{
7787	mptsas_cmd_t			*cmd;
7788	mptsas_doneq_thread_list_t	*item = &mpt->m_doneq_thread_id[t];
7789
7790	/* pop one off the done queue */
7791	if ((cmd = item->doneq) != NULL) {
7792		/* if the queue is now empty fix the tail pointer */
7793		NDBG31(("mptsas_doneq_thread_rm: cmd=0x%p", (void *)cmd));
7794		if ((item->doneq = cmd->cmd_linkp) == NULL) {
7795			item->donetail = &item->doneq;
7796		}
7797		cmd->cmd_linkp = NULL;
7798		item->len--;
7799	}
7800	return (cmd);
7801}
7802
7803static void
7804mptsas_doneq_empty(mptsas_t *mpt)
7805{
7806	if (mpt->m_doneq && !mpt->m_in_callback) {
7807		mptsas_cmd_t	*cmd, *next;
7808		struct scsi_pkt *pkt;
7809
7810		mpt->m_in_callback = 1;
7811		cmd = mpt->m_doneq;
7812		mpt->m_doneq = NULL;
7813		mpt->m_donetail = &mpt->m_doneq;
7814		mpt->m_doneq_len = 0;
7815
7816		mutex_exit(&mpt->m_mutex);
7817		/*
7818		 * run the completion routines of all the
7819		 * completed commands
7820		 */
7821		while (cmd != NULL) {
7822			next = cmd->cmd_linkp;
7823			cmd->cmd_linkp = NULL;
7824			/* run this command's completion routine */
7825			cmd->cmd_flags |= CFLAG_COMPLETED;
7826			pkt = CMD2PKT(cmd);
7827			mptsas_pkt_comp(pkt, cmd);
7828			cmd = next;
7829		}
7830		mutex_enter(&mpt->m_mutex);
7831		mpt->m_in_callback = 0;
7832	}
7833}
7834
7835/*
7836 * These routines manipulate the target's queue of pending requests
7837 */
7838void
7839mptsas_waitq_add(mptsas_t *mpt, mptsas_cmd_t *cmd)
7840{
7841	NDBG7(("mptsas_waitq_add: cmd=0x%p", (void *)cmd));
7842	mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
7843	cmd->cmd_queued = TRUE;
7844	if (ptgt)
7845		ptgt->m_t_nwait++;
7846	if (cmd->cmd_pkt_flags & FLAG_HEAD) {
7847		if ((cmd->cmd_linkp = mpt->m_waitq) == NULL) {
7848			mpt->m_waitqtail = &cmd->cmd_linkp;
7849		}
7850		mpt->m_waitq = cmd;
7851	} else {
7852		cmd->cmd_linkp = NULL;
7853		*(mpt->m_waitqtail) = cmd;
7854		mpt->m_waitqtail = &cmd->cmd_linkp;
7855	}
7856}
7857
7858static mptsas_cmd_t *
7859mptsas_waitq_rm(mptsas_t *mpt)
7860{
7861	mptsas_cmd_t	*cmd;
7862	mptsas_target_t *ptgt;
7863	NDBG7(("mptsas_waitq_rm"));
7864
7865	MPTSAS_WAITQ_RM(mpt, cmd);
7866
7867	NDBG7(("mptsas_waitq_rm: cmd=0x%p", (void *)cmd));
7868	if (cmd) {
7869		ptgt = cmd->cmd_tgt_addr;
7870		if (ptgt) {
7871			ptgt->m_t_nwait--;
7872			ASSERT(ptgt->m_t_nwait >= 0);
7873		}
7874	}
7875	return (cmd);
7876}
7877
7878/*
7879 * remove specified cmd from the middle of the wait queue.
7880 */
7881static void
7882mptsas_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd)
7883{
7884	mptsas_cmd_t	*prevp = mpt->m_waitq;
7885	mptsas_target_t *ptgt = cmd->cmd_tgt_addr;
7886
7887	NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
7888	    (void *)mpt, (void *)cmd));
7889	if (ptgt) {
7890		ptgt->m_t_nwait--;
7891		ASSERT(ptgt->m_t_nwait >= 0);
7892	}
7893
7894	if (prevp == cmd) {
7895		if ((mpt->m_waitq = cmd->cmd_linkp) == NULL)
7896			mpt->m_waitqtail = &mpt->m_waitq;
7897
7898		cmd->cmd_linkp = NULL;
7899		cmd->cmd_queued = FALSE;
7900		NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
7901		    (void *)mpt, (void *)cmd));
7902		return;
7903	}
7904
7905	while (prevp != NULL) {
7906		if (prevp->cmd_linkp == cmd) {
7907			if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL)
7908				mpt->m_waitqtail = &prevp->cmd_linkp;
7909
7910			cmd->cmd_linkp = NULL;
7911			cmd->cmd_queued = FALSE;
7912			NDBG7(("mptsas_waitq_delete: mpt=0x%p cmd=0x%p",
7913			    (void *)mpt, (void *)cmd));
7914			return;
7915		}
7916		prevp = prevp->cmd_linkp;
7917	}
7918	cmn_err(CE_PANIC, "mpt: mptsas_waitq_delete: queue botch");
7919}
7920
7921static mptsas_cmd_t *
7922mptsas_tx_waitq_rm(mptsas_t *mpt)
7923{
7924	mptsas_cmd_t *cmd;
7925	NDBG7(("mptsas_tx_waitq_rm"));
7926
7927	MPTSAS_TX_WAITQ_RM(mpt, cmd);
7928
7929	NDBG7(("mptsas_tx_waitq_rm: cmd=0x%p", (void *)cmd));
7930
7931	return (cmd);
7932}
7933
7934/*
7935 * remove specified cmd from the middle of the tx_waitq.
7936 */
7937static void
7938mptsas_tx_waitq_delete(mptsas_t *mpt, mptsas_cmd_t *cmd)
7939{
7940	mptsas_cmd_t *prevp = mpt->m_tx_waitq;
7941
7942	NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
7943	    (void *)mpt, (void *)cmd));
7944
7945	if (prevp == cmd) {
7946		if ((mpt->m_tx_waitq = cmd->cmd_linkp) == NULL)
7947			mpt->m_tx_waitqtail = &mpt->m_tx_waitq;
7948
7949		cmd->cmd_linkp = NULL;
7950		cmd->cmd_queued = FALSE;
7951		NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
7952		    (void *)mpt, (void *)cmd));
7953		return;
7954	}
7955
7956	while (prevp != NULL) {
7957		if (prevp->cmd_linkp == cmd) {
7958			if ((prevp->cmd_linkp = cmd->cmd_linkp) == NULL)
7959				mpt->m_tx_waitqtail = &prevp->cmd_linkp;
7960
7961			cmd->cmd_linkp = NULL;
7962			cmd->cmd_queued = FALSE;
7963			NDBG7(("mptsas_tx_waitq_delete: mpt=0x%p cmd=0x%p",
7964			    (void *)mpt, (void *)cmd));
7965			return;
7966		}
7967		prevp = prevp->cmd_linkp;
7968	}
7969	cmn_err(CE_PANIC, "mpt: mptsas_tx_waitq_delete: queue botch");
7970}
7971
7972/*
7973 * device and bus reset handling
7974 *
7975 * Notes:
7976 *	- RESET_ALL:	reset the controller
7977 *	- RESET_TARGET:	reset the target specified in scsi_address
7978 */
7979static int
7980mptsas_scsi_reset(struct scsi_address *ap, int level)
7981{
7982	mptsas_t		*mpt = ADDR2MPT(ap);
7983	int			rval;
7984	mptsas_tgt_private_t	*tgt_private;
7985	mptsas_target_t		*ptgt = NULL;
7986
7987	tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->tran_tgt_private;
7988	ptgt = tgt_private->t_private;
7989	if (ptgt == NULL) {
7990		return (FALSE);
7991	}
7992	NDBG22(("mptsas_scsi_reset: target=%d level=%d", ptgt->m_devhdl,
7993	    level));
7994
7995	mutex_enter(&mpt->m_mutex);
7996	/*
7997	 * if we are not in panic set up a reset delay for this target
7998	 */
7999	if (!ddi_in_panic()) {
8000		mptsas_setup_bus_reset_delay(mpt);
8001	} else {
8002		drv_usecwait(mpt->m_scsi_reset_delay * 1000);
8003	}
8004	rval = mptsas_do_scsi_reset(mpt, ptgt->m_devhdl);
8005	mutex_exit(&mpt->m_mutex);
8006
8007	/*
8008	 * The transport layer expect to only see TRUE and
8009	 * FALSE. Therefore, we will adjust the return value
8010	 * if mptsas_do_scsi_reset returns FAILED.
8011	 */
8012	if (rval == FAILED)
8013		rval = FALSE;
8014	return (rval);
8015}
8016
8017static int
8018mptsas_do_scsi_reset(mptsas_t *mpt, uint16_t devhdl)
8019{
8020	int		rval = FALSE;
8021	uint8_t		config, disk;
8022	mptsas_slots_t	*slots = mpt->m_active;
8023
8024	ASSERT(mutex_owned(&mpt->m_mutex));
8025
8026	if (mptsas_debug_resets) {
8027		mptsas_log(mpt, CE_WARN, "mptsas_do_scsi_reset: target=%d",
8028		    devhdl);
8029	}
8030
8031	/*
8032	 * Issue a Target Reset message to the target specified but not to a
8033	 * disk making up a raid volume.  Just look through the RAID config
8034	 * Phys Disk list of DevHandles.  If the target's DevHandle is in this
8035	 * list, then don't reset this target.
8036	 */
8037	for (config = 0; config < slots->m_num_raid_configs; config++) {
8038		for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
8039			if (devhdl == slots->m_raidconfig[config].
8040			    m_physdisk_devhdl[disk]) {
8041				return (TRUE);
8042			}
8043		}
8044	}
8045
8046	rval = mptsas_ioc_task_management(mpt,
8047	    MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, devhdl, 0);
8048
8049	mptsas_doneq_empty(mpt);
8050	return (rval);
8051}
8052
8053static int
8054mptsas_scsi_reset_notify(struct scsi_address *ap, int flag,
8055	void (*callback)(caddr_t), caddr_t arg)
8056{
8057	mptsas_t	*mpt = ADDR2MPT(ap);
8058
8059	NDBG22(("mptsas_scsi_reset_notify: tgt=%d", ap->a_target));
8060
8061	return (scsi_hba_reset_notify_setup(ap, flag, callback, arg,
8062	    &mpt->m_mutex, &mpt->m_reset_notify_listf));
8063}
8064
8065static int
8066mptsas_get_name(struct scsi_device *sd, char *name, int len)
8067{
8068	dev_info_t	*lun_dip = NULL;
8069
8070	ASSERT(sd != NULL);
8071	ASSERT(name != NULL);
8072	lun_dip = sd->sd_dev;
8073	ASSERT(lun_dip != NULL);
8074
8075	if (mptsas_name_child(lun_dip, name, len) == DDI_SUCCESS) {
8076		return (1);
8077	} else {
8078		return (0);
8079	}
8080}
8081
8082static int
8083mptsas_get_bus_addr(struct scsi_device *sd, char *name, int len)
8084{
8085	return (mptsas_get_name(sd, name, len));
8086}
8087
8088void
8089mptsas_set_throttle(mptsas_t *mpt, mptsas_target_t *ptgt, int what)
8090{
8091
8092	NDBG25(("mptsas_set_throttle: throttle=%x", what));
8093
8094	/*
8095	 * if the bus is draining/quiesced, no changes to the throttles
8096	 * are allowed. Not allowing change of throttles during draining
8097	 * limits error recovery but will reduce draining time
8098	 *
8099	 * all throttles should have been set to HOLD_THROTTLE
8100	 */
8101	if (mpt->m_softstate & (MPTSAS_SS_QUIESCED | MPTSAS_SS_DRAINING)) {
8102		return;
8103	}
8104
8105	if (what == HOLD_THROTTLE) {
8106		ptgt->m_t_throttle = HOLD_THROTTLE;
8107	} else if (ptgt->m_reset_delay == 0) {
8108		ptgt->m_t_throttle = what;
8109	}
8110}
8111
8112/*
8113 * Clean up from a device reset.
8114 * For the case of target reset, this function clears the waitq of all
8115 * commands for a particular target.   For the case of abort task set, this
8116 * function clears the waitq of all commonds for a particular target/lun.
8117 */
8118static void
8119mptsas_flush_target(mptsas_t *mpt, ushort_t target, int lun, uint8_t tasktype)
8120{
8121	mptsas_slots_t	*slots = mpt->m_active;
8122	mptsas_cmd_t	*cmd, *next_cmd;
8123	int		slot;
8124	uchar_t		reason;
8125	uint_t		stat;
8126
8127	NDBG25(("mptsas_flush_target: target=%d lun=%d", target, lun));
8128
8129	/*
8130	 * Make sure the I/O Controller has flushed all cmds
8131	 * that are associated with this target for a target reset
8132	 * and target/lun for abort task set.
8133	 * Account for TM requests, which use the last SMID.
8134	 */
8135	for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) {
8136		if ((cmd = slots->m_slot[slot]) == NULL)
8137			continue;
8138		reason = CMD_RESET;
8139		stat = STAT_DEV_RESET;
8140		switch (tasktype) {
8141		case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
8142			if (Tgt(cmd) == target) {
8143				mptsas_log(mpt, CE_NOTE, "mptsas_flush_target "
8144				    "discovered non-NULL cmd in slot %d, "
8145				    "tasktype 0x%x", slot, tasktype);
8146				mptsas_dump_cmd(mpt, cmd);
8147				mptsas_remove_cmd(mpt, cmd);
8148				mptsas_set_pkt_reason(mpt, cmd, reason, stat);
8149				mptsas_doneq_add(mpt, cmd);
8150			}
8151			break;
8152		case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
8153			reason = CMD_ABORTED;
8154			stat = STAT_ABORTED;
8155			/*FALLTHROUGH*/
8156		case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
8157			if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
8158
8159				mptsas_log(mpt, CE_NOTE, "mptsas_flush_target "
8160				    "discovered non-NULL cmd in slot %d, "
8161				    "tasktype 0x%x", slot, tasktype);
8162				mptsas_dump_cmd(mpt, cmd);
8163				mptsas_remove_cmd(mpt, cmd);
8164				mptsas_set_pkt_reason(mpt, cmd, reason,
8165				    stat);
8166				mptsas_doneq_add(mpt, cmd);
8167			}
8168			break;
8169		default:
8170			break;
8171		}
8172	}
8173
8174	/*
8175	 * Flush the waitq and tx_waitq of this target's cmds
8176	 */
8177	cmd = mpt->m_waitq;
8178
8179	reason = CMD_RESET;
8180	stat = STAT_DEV_RESET;
8181
8182	switch (tasktype) {
8183	case MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
8184		while (cmd != NULL) {
8185			next_cmd = cmd->cmd_linkp;
8186			if (Tgt(cmd) == target) {
8187				mptsas_waitq_delete(mpt, cmd);
8188				mptsas_set_pkt_reason(mpt, cmd,
8189				    reason, stat);
8190				mptsas_doneq_add(mpt, cmd);
8191			}
8192			cmd = next_cmd;
8193		}
8194		mutex_enter(&mpt->m_tx_waitq_mutex);
8195		cmd = mpt->m_tx_waitq;
8196		while (cmd != NULL) {
8197			next_cmd = cmd->cmd_linkp;
8198			if (Tgt(cmd) == target) {
8199				mptsas_tx_waitq_delete(mpt, cmd);
8200				mutex_exit(&mpt->m_tx_waitq_mutex);
8201				mptsas_set_pkt_reason(mpt, cmd,
8202				    reason, stat);
8203				mptsas_doneq_add(mpt, cmd);
8204				mutex_enter(&mpt->m_tx_waitq_mutex);
8205			}
8206			cmd = next_cmd;
8207		}
8208		mutex_exit(&mpt->m_tx_waitq_mutex);
8209		break;
8210	case MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET:
8211		reason = CMD_ABORTED;
8212		stat =  STAT_ABORTED;
8213		/*FALLTHROUGH*/
8214	case MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET:
8215		while (cmd != NULL) {
8216			next_cmd = cmd->cmd_linkp;
8217			if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
8218				mptsas_waitq_delete(mpt, cmd);
8219				mptsas_set_pkt_reason(mpt, cmd,
8220				    reason, stat);
8221				mptsas_doneq_add(mpt, cmd);
8222			}
8223			cmd = next_cmd;
8224		}
8225		mutex_enter(&mpt->m_tx_waitq_mutex);
8226		cmd = mpt->m_tx_waitq;
8227		while (cmd != NULL) {
8228			next_cmd = cmd->cmd_linkp;
8229			if ((Tgt(cmd) == target) && (Lun(cmd) == lun)) {
8230				mptsas_tx_waitq_delete(mpt, cmd);
8231				mutex_exit(&mpt->m_tx_waitq_mutex);
8232				mptsas_set_pkt_reason(mpt, cmd,
8233				    reason, stat);
8234				mptsas_doneq_add(mpt, cmd);
8235				mutex_enter(&mpt->m_tx_waitq_mutex);
8236			}
8237			cmd = next_cmd;
8238		}
8239		mutex_exit(&mpt->m_tx_waitq_mutex);
8240		break;
8241	default:
8242		mptsas_log(mpt, CE_WARN, "Unknown task management type %d.",
8243		    tasktype);
8244		break;
8245	}
8246}
8247
8248/*
8249 * Clean up hba state, abort all outstanding command and commands in waitq
8250 * reset timeout of all targets.
8251 */
8252static void
8253mptsas_flush_hba(mptsas_t *mpt)
8254{
8255	mptsas_slots_t	*slots = mpt->m_active;
8256	mptsas_cmd_t	*cmd;
8257	int		slot;
8258
8259	NDBG25(("mptsas_flush_hba"));
8260
8261	/*
8262	 * The I/O Controller should have already sent back
8263	 * all commands via the scsi I/O reply frame.  Make
8264	 * sure all commands have been flushed.
8265	 * Account for TM request, which use the last SMID.
8266	 */
8267	for (slot = 0; slot <= mpt->m_active->m_n_slots; slot++) {
8268		if ((cmd = slots->m_slot[slot]) == NULL)
8269			continue;
8270
8271		if (cmd->cmd_flags & CFLAG_CMDIOC)
8272			continue;
8273
8274		mptsas_log(mpt, CE_NOTE, "mptsas_flush_hba discovered non-NULL "
8275		    "cmd in slot %d", slot);
8276		mptsas_dump_cmd(mpt, cmd);
8277
8278		mptsas_remove_cmd(mpt, cmd);
8279		mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
8280		mptsas_doneq_add(mpt, cmd);
8281	}
8282
8283	/*
8284	 * Flush the waitq.
8285	 */
8286	while ((cmd = mptsas_waitq_rm(mpt)) != NULL) {
8287		mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
8288		if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
8289		    (cmd->cmd_flags & CFLAG_CONFIG)) {
8290			cmd->cmd_flags |= CFLAG_FINISHED;
8291			cv_broadcast(&mpt->m_passthru_cv);
8292			cv_broadcast(&mpt->m_config_cv);
8293		} else {
8294			mptsas_doneq_add(mpt, cmd);
8295		}
8296	}
8297
8298	/*
8299	 * Flush the tx_waitq
8300	 */
8301	mutex_enter(&mpt->m_tx_waitq_mutex);
8302	while ((cmd = mptsas_tx_waitq_rm(mpt)) != NULL) {
8303		mutex_exit(&mpt->m_tx_waitq_mutex);
8304		mptsas_set_pkt_reason(mpt, cmd, CMD_RESET, STAT_BUS_RESET);
8305		mptsas_doneq_add(mpt, cmd);
8306		mutex_enter(&mpt->m_tx_waitq_mutex);
8307	}
8308	mutex_exit(&mpt->m_tx_waitq_mutex);
8309}
8310
8311/*
8312 * set pkt_reason and OR in pkt_statistics flag
8313 */
8314static void
8315mptsas_set_pkt_reason(mptsas_t *mpt, mptsas_cmd_t *cmd, uchar_t reason,
8316    uint_t stat)
8317{
8318#ifndef __lock_lint
8319	_NOTE(ARGUNUSED(mpt))
8320#endif
8321
8322	NDBG25(("mptsas_set_pkt_reason: cmd=0x%p reason=%x stat=%x",
8323	    (void *)cmd, reason, stat));
8324
8325	if (cmd) {
8326		if (cmd->cmd_pkt->pkt_reason == CMD_CMPLT) {
8327			cmd->cmd_pkt->pkt_reason = reason;
8328		}
8329		cmd->cmd_pkt->pkt_statistics |= stat;
8330	}
8331}
8332
8333static void
8334mptsas_start_watch_reset_delay()
8335{
8336	NDBG22(("mptsas_start_watch_reset_delay"));
8337
8338	mutex_enter(&mptsas_global_mutex);
8339	if (mptsas_reset_watch == NULL && mptsas_timeouts_enabled) {
8340		mptsas_reset_watch = timeout(mptsas_watch_reset_delay, NULL,
8341		    drv_usectohz((clock_t)
8342		    MPTSAS_WATCH_RESET_DELAY_TICK * 1000));
8343		ASSERT(mptsas_reset_watch != NULL);
8344	}
8345	mutex_exit(&mptsas_global_mutex);
8346}
8347
8348static void
8349mptsas_setup_bus_reset_delay(mptsas_t *mpt)
8350{
8351	mptsas_target_t	*ptgt = NULL;
8352
8353	NDBG22(("mptsas_setup_bus_reset_delay"));
8354	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
8355	    MPTSAS_HASH_FIRST);
8356	while (ptgt != NULL) {
8357		mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
8358		ptgt->m_reset_delay = mpt->m_scsi_reset_delay;
8359
8360		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
8361		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
8362	}
8363
8364	mptsas_start_watch_reset_delay();
8365}
8366
8367/*
8368 * mptsas_watch_reset_delay(_subr) is invoked by timeout() and checks every
8369 * mpt instance for active reset delays
8370 */
8371static void
8372mptsas_watch_reset_delay(void *arg)
8373{
8374#ifndef __lock_lint
8375	_NOTE(ARGUNUSED(arg))
8376#endif
8377
8378	mptsas_t	*mpt;
8379	int		not_done = 0;
8380
8381	NDBG22(("mptsas_watch_reset_delay"));
8382
8383	mutex_enter(&mptsas_global_mutex);
8384	mptsas_reset_watch = 0;
8385	mutex_exit(&mptsas_global_mutex);
8386	rw_enter(&mptsas_global_rwlock, RW_READER);
8387	for (mpt = mptsas_head; mpt != NULL; mpt = mpt->m_next) {
8388		if (mpt->m_tran == 0) {
8389			continue;
8390		}
8391		mutex_enter(&mpt->m_mutex);
8392		not_done += mptsas_watch_reset_delay_subr(mpt);
8393		mutex_exit(&mpt->m_mutex);
8394	}
8395	rw_exit(&mptsas_global_rwlock);
8396
8397	if (not_done) {
8398		mptsas_start_watch_reset_delay();
8399	}
8400}
8401
8402static int
8403mptsas_watch_reset_delay_subr(mptsas_t *mpt)
8404{
8405	int		done = 0;
8406	int		restart = 0;
8407	mptsas_target_t	*ptgt = NULL;
8408
8409	NDBG22(("mptsas_watch_reset_delay_subr: mpt=0x%p", (void *)mpt));
8410
8411	ASSERT(mutex_owned(&mpt->m_mutex));
8412
8413	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
8414	    MPTSAS_HASH_FIRST);
8415	while (ptgt != NULL) {
8416		if (ptgt->m_reset_delay != 0) {
8417			ptgt->m_reset_delay -=
8418			    MPTSAS_WATCH_RESET_DELAY_TICK;
8419			if (ptgt->m_reset_delay <= 0) {
8420				ptgt->m_reset_delay = 0;
8421				mptsas_set_throttle(mpt, ptgt,
8422				    MAX_THROTTLE);
8423				restart++;
8424			} else {
8425				done = -1;
8426			}
8427		}
8428
8429		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
8430		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
8431	}
8432
8433	if (restart > 0) {
8434		mptsas_restart_hba(mpt);
8435	}
8436	return (done);
8437}
8438
8439#ifdef MPTSAS_TEST
8440static void
8441mptsas_test_reset(mptsas_t *mpt, int target)
8442{
8443	mptsas_target_t    *ptgt = NULL;
8444
8445	if (mptsas_rtest == target) {
8446		if (mptsas_do_scsi_reset(mpt, target) == TRUE) {
8447			mptsas_rtest = -1;
8448		}
8449		if (mptsas_rtest == -1) {
8450			NDBG22(("mptsas_test_reset success"));
8451		}
8452	}
8453}
8454#endif
8455
8456/*
8457 * abort handling:
8458 *
8459 * Notes:
8460 *	- if pkt is not NULL, abort just that command
8461 *	- if pkt is NULL, abort all outstanding commands for target
8462 */
8463static int
8464mptsas_scsi_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
8465{
8466	mptsas_t		*mpt = ADDR2MPT(ap);
8467	int			rval;
8468	mptsas_tgt_private_t	*tgt_private;
8469	int			target, lun;
8470
8471	tgt_private = (mptsas_tgt_private_t *)ap->a_hba_tran->
8472	    tran_tgt_private;
8473	ASSERT(tgt_private != NULL);
8474	target = tgt_private->t_private->m_devhdl;
8475	lun = tgt_private->t_lun;
8476
8477	NDBG23(("mptsas_scsi_abort: target=%d.%d", target, lun));
8478
8479	mutex_enter(&mpt->m_mutex);
8480	rval = mptsas_do_scsi_abort(mpt, target, lun, pkt);
8481	mutex_exit(&mpt->m_mutex);
8482	return (rval);
8483}
8484
8485static int
8486mptsas_do_scsi_abort(mptsas_t *mpt, int target, int lun, struct scsi_pkt *pkt)
8487{
8488	mptsas_cmd_t	*sp = NULL;
8489	mptsas_slots_t	*slots = mpt->m_active;
8490	int		rval = FALSE;
8491
8492	ASSERT(mutex_owned(&mpt->m_mutex));
8493
8494	/*
8495	 * Abort the command pkt on the target/lun in ap.  If pkt is
8496	 * NULL, abort all outstanding commands on that target/lun.
8497	 * If you can abort them, return 1, else return 0.
8498	 * Each packet that's aborted should be sent back to the target
8499	 * driver through the callback routine, with pkt_reason set to
8500	 * CMD_ABORTED.
8501	 *
8502	 * abort cmd pkt on HBA hardware; clean out of outstanding
8503	 * command lists, etc.
8504	 */
8505	if (pkt != NULL) {
8506		/* abort the specified packet */
8507		sp = PKT2CMD(pkt);
8508
8509		if (sp->cmd_queued) {
8510			NDBG23(("mptsas_do_scsi_abort: queued sp=0x%p aborted",
8511			    (void *)sp));
8512			mptsas_waitq_delete(mpt, sp);
8513			mptsas_set_pkt_reason(mpt, sp, CMD_ABORTED,
8514			    STAT_ABORTED);
8515			mptsas_doneq_add(mpt, sp);
8516			rval = TRUE;
8517			goto done;
8518		}
8519
8520		/*
8521		 * Have mpt firmware abort this command
8522		 */
8523
8524		if (slots->m_slot[sp->cmd_slot] != NULL) {
8525			rval = mptsas_ioc_task_management(mpt,
8526			    MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, target,
8527			    lun);
8528
8529			/*
8530			 * The transport layer expects only TRUE and FALSE.
8531			 * Therefore, if mptsas_ioc_task_management returns
8532			 * FAILED we will return FALSE.
8533			 */
8534			if (rval == FAILED)
8535				rval = FALSE;
8536			goto done;
8537		}
8538	}
8539
8540	/*
8541	 * If pkt is NULL then abort task set
8542	 */
8543	rval = mptsas_ioc_task_management(mpt,
8544	    MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET, target, lun);
8545
8546	/*
8547	 * The transport layer expects only TRUE and FALSE.
8548	 * Therefore, if mptsas_ioc_task_management returns
8549	 * FAILED we will return FALSE.
8550	 */
8551	if (rval == FAILED)
8552		rval = FALSE;
8553
8554#ifdef MPTSAS_TEST
8555	if (rval && mptsas_test_stop) {
8556		debug_enter("mptsas_do_scsi_abort");
8557	}
8558#endif
8559
8560done:
8561	mptsas_doneq_empty(mpt);
8562	return (rval);
8563}
8564
8565/*
8566 * capability handling:
8567 * (*tran_getcap).  Get the capability named, and return its value.
8568 */
8569static int
8570mptsas_scsi_getcap(struct scsi_address *ap, char *cap, int tgtonly)
8571{
8572	mptsas_t	*mpt = ADDR2MPT(ap);
8573	int		ckey;
8574	int		rval = FALSE;
8575
8576	NDBG24(("mptsas_scsi_getcap: target=%d, cap=%s tgtonly=%x",
8577	    ap->a_target, cap, tgtonly));
8578
8579	mutex_enter(&mpt->m_mutex);
8580
8581	if ((mptsas_capchk(cap, tgtonly, &ckey)) != TRUE) {
8582		mutex_exit(&mpt->m_mutex);
8583		return (UNDEFINED);
8584	}
8585
8586	switch (ckey) {
8587	case SCSI_CAP_DMA_MAX:
8588		rval = (int)mpt->m_msg_dma_attr.dma_attr_maxxfer;
8589		break;
8590	case SCSI_CAP_ARQ:
8591		rval = TRUE;
8592		break;
8593	case SCSI_CAP_MSG_OUT:
8594	case SCSI_CAP_PARITY:
8595	case SCSI_CAP_UNTAGGED_QING:
8596		rval = TRUE;
8597		break;
8598	case SCSI_CAP_TAGGED_QING:
8599		rval = TRUE;
8600		break;
8601	case SCSI_CAP_RESET_NOTIFICATION:
8602		rval = TRUE;
8603		break;
8604	case SCSI_CAP_LINKED_CMDS:
8605		rval = FALSE;
8606		break;
8607	case SCSI_CAP_QFULL_RETRIES:
8608		rval = ((mptsas_tgt_private_t *)(ap->a_hba_tran->
8609		    tran_tgt_private))->t_private->m_qfull_retries;
8610		break;
8611	case SCSI_CAP_QFULL_RETRY_INTERVAL:
8612		rval = drv_hztousec(((mptsas_tgt_private_t *)
8613		    (ap->a_hba_tran->tran_tgt_private))->
8614		    t_private->m_qfull_retry_interval) / 1000;
8615		break;
8616	case SCSI_CAP_CDB_LEN:
8617		rval = CDB_GROUP4;
8618		break;
8619	case SCSI_CAP_INTERCONNECT_TYPE:
8620		rval = INTERCONNECT_SAS;
8621		break;
8622	default:
8623		rval = UNDEFINED;
8624		break;
8625	}
8626
8627	NDBG24(("mptsas_scsi_getcap: %s, rval=%x", cap, rval));
8628
8629	mutex_exit(&mpt->m_mutex);
8630	return (rval);
8631}
8632
8633/*
8634 * (*tran_setcap).  Set the capability named to the value given.
8635 */
8636static int
8637mptsas_scsi_setcap(struct scsi_address *ap, char *cap, int value, int tgtonly)
8638{
8639	mptsas_t	*mpt = ADDR2MPT(ap);
8640	int		ckey;
8641	int		rval = FALSE;
8642
8643	NDBG24(("mptsas_scsi_setcap: target=%d, cap=%s value=%x tgtonly=%x",
8644	    ap->a_target, cap, value, tgtonly));
8645
8646	if (!tgtonly) {
8647		return (rval);
8648	}
8649
8650	mutex_enter(&mpt->m_mutex);
8651
8652	if ((mptsas_capchk(cap, tgtonly, &ckey)) != TRUE) {
8653		mutex_exit(&mpt->m_mutex);
8654		return (UNDEFINED);
8655	}
8656
8657	switch (ckey) {
8658	case SCSI_CAP_DMA_MAX:
8659	case SCSI_CAP_MSG_OUT:
8660	case SCSI_CAP_PARITY:
8661	case SCSI_CAP_INITIATOR_ID:
8662	case SCSI_CAP_LINKED_CMDS:
8663	case SCSI_CAP_UNTAGGED_QING:
8664	case SCSI_CAP_RESET_NOTIFICATION:
8665		/*
8666		 * None of these are settable via
8667		 * the capability interface.
8668		 */
8669		break;
8670	case SCSI_CAP_ARQ:
8671		/*
8672		 * We cannot turn off arq so return false if asked to
8673		 */
8674		if (value) {
8675			rval = TRUE;
8676		} else {
8677			rval = FALSE;
8678		}
8679		break;
8680	case SCSI_CAP_TAGGED_QING:
8681		mptsas_set_throttle(mpt, ((mptsas_tgt_private_t *)
8682		    (ap->a_hba_tran->tran_tgt_private))->t_private,
8683		    MAX_THROTTLE);
8684		rval = TRUE;
8685		break;
8686	case SCSI_CAP_QFULL_RETRIES:
8687		((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))->
8688		    t_private->m_qfull_retries = (uchar_t)value;
8689		rval = TRUE;
8690		break;
8691	case SCSI_CAP_QFULL_RETRY_INTERVAL:
8692		((mptsas_tgt_private_t *)(ap->a_hba_tran->tran_tgt_private))->
8693		    t_private->m_qfull_retry_interval =
8694		    drv_usectohz(value * 1000);
8695		rval = TRUE;
8696		break;
8697	default:
8698		rval = UNDEFINED;
8699		break;
8700	}
8701	mutex_exit(&mpt->m_mutex);
8702	return (rval);
8703}
8704
8705/*
8706 * Utility routine for mptsas_ifsetcap/ifgetcap
8707 */
8708/*ARGSUSED*/
8709static int
8710mptsas_capchk(char *cap, int tgtonly, int *cidxp)
8711{
8712	NDBG24(("mptsas_capchk: cap=%s", cap));
8713
8714	if (!cap)
8715		return (FALSE);
8716
8717	*cidxp = scsi_hba_lookup_capstr(cap);
8718	return (TRUE);
8719}
8720
8721static int
8722mptsas_alloc_active_slots(mptsas_t *mpt, int flag)
8723{
8724	mptsas_slots_t	*old_active = mpt->m_active;
8725	mptsas_slots_t	*new_active;
8726	size_t		size;
8727	int		rval = -1;
8728
8729	if (mpt->m_ncmds) {
8730		NDBG9(("cannot change size of active slots array"));
8731		return (rval);
8732	}
8733
8734	size = MPTSAS_SLOTS_SIZE(mpt);
8735	new_active = kmem_zalloc(size, flag);
8736	if (new_active == NULL) {
8737		NDBG1(("new active alloc failed"));
8738	} else {
8739		/*
8740		 * Since SMID 0 is reserved and the TM slot is reserved, the
8741		 * number of slots that can be used at any one time is
8742		 * m_max_requests - 2.
8743		 */
8744		mpt->m_active = new_active;
8745		mpt->m_active->m_n_slots = (mpt->m_max_requests - 2);
8746		mpt->m_active->m_size = size;
8747		mpt->m_active->m_tags = 1;
8748		if (old_active) {
8749			kmem_free(old_active, old_active->m_size);
8750		}
8751		rval = 0;
8752	}
8753
8754	return (rval);
8755}
8756
8757/*
8758 * Error logging, printing, and debug print routines.
8759 */
8760static char *mptsas_label = "mpt_sas";
8761
8762/*PRINTFLIKE3*/
8763void
8764mptsas_log(mptsas_t *mpt, int level, char *fmt, ...)
8765{
8766	dev_info_t	*dev;
8767	va_list		ap;
8768
8769	if (mpt) {
8770		dev = mpt->m_dip;
8771	} else {
8772		dev = 0;
8773	}
8774
8775	mutex_enter(&mptsas_log_mutex);
8776
8777	va_start(ap, fmt);
8778	(void) vsprintf(mptsas_log_buf, fmt, ap);
8779	va_end(ap);
8780
8781	if (level == CE_CONT) {
8782		scsi_log(dev, mptsas_label, level, "%s\n", mptsas_log_buf);
8783	} else {
8784		scsi_log(dev, mptsas_label, level, "%s", mptsas_log_buf);
8785	}
8786
8787	mutex_exit(&mptsas_log_mutex);
8788}
8789
8790#ifdef MPTSAS_DEBUG
8791/*PRINTFLIKE1*/
8792void
8793mptsas_printf(char *fmt, ...)
8794{
8795	dev_info_t	*dev = 0;
8796	va_list		ap;
8797
8798	mutex_enter(&mptsas_log_mutex);
8799
8800	va_start(ap, fmt);
8801	(void) vsprintf(mptsas_log_buf, fmt, ap);
8802	va_end(ap);
8803
8804#ifdef PROM_PRINTF
8805	prom_printf("%s:\t%s\n", mptsas_label, mptsas_log_buf);
8806#else
8807	scsi_log(dev, mptsas_label, SCSI_DEBUG, "%s\n", mptsas_log_buf);
8808#endif
8809	mutex_exit(&mptsas_log_mutex);
8810}
8811#endif
8812
8813/*
8814 * timeout handling
8815 */
8816static void
8817mptsas_watch(void *arg)
8818{
8819#ifndef __lock_lint
8820	_NOTE(ARGUNUSED(arg))
8821#endif
8822
8823	mptsas_t	*mpt;
8824
8825	NDBG30(("mptsas_watch"));
8826
8827	rw_enter(&mptsas_global_rwlock, RW_READER);
8828	for (mpt = mptsas_head; mpt != (mptsas_t *)NULL; mpt = mpt->m_next) {
8829
8830		mutex_enter(&mpt->m_mutex);
8831
8832		/* Skip device if not powered on */
8833		if (mpt->m_options & MPTSAS_OPT_PM) {
8834			if (mpt->m_power_level == PM_LEVEL_D0) {
8835				(void) pm_busy_component(mpt->m_dip, 0);
8836				mpt->m_busy = 1;
8837			} else {
8838				mutex_exit(&mpt->m_mutex);
8839				continue;
8840			}
8841		}
8842
8843		/*
8844		 * For now, always call mptsas_watchsubr.
8845		 */
8846		mptsas_watchsubr(mpt);
8847
8848		if (mpt->m_options & MPTSAS_OPT_PM) {
8849			mpt->m_busy = 0;
8850			(void) pm_idle_component(mpt->m_dip, 0);
8851		}
8852
8853		mutex_exit(&mpt->m_mutex);
8854	}
8855	rw_exit(&mptsas_global_rwlock);
8856
8857	mutex_enter(&mptsas_global_mutex);
8858	if (mptsas_timeouts_enabled)
8859		mptsas_timeout_id = timeout(mptsas_watch, NULL, mptsas_tick);
8860	mutex_exit(&mptsas_global_mutex);
8861}
8862
8863static void
8864mptsas_watchsubr(mptsas_t *mpt)
8865{
8866	int		i;
8867	mptsas_cmd_t	*cmd;
8868	mptsas_target_t	*ptgt = NULL;
8869
8870	NDBG30(("mptsas_watchsubr: mpt=0x%p", (void *)mpt));
8871
8872#ifdef MPTSAS_TEST
8873	if (mptsas_enable_untagged) {
8874		mptsas_test_untagged++;
8875	}
8876#endif
8877
8878	/*
8879	 * Check for commands stuck in active slot
8880	 * Account for TM requests, which use the last SMID.
8881	 */
8882	for (i = 0; i <= mpt->m_active->m_n_slots; i++) {
8883		if ((cmd = mpt->m_active->m_slot[i]) != NULL) {
8884			if ((cmd->cmd_flags & CFLAG_CMDIOC) == 0) {
8885				cmd->cmd_active_timeout -=
8886				    mptsas_scsi_watchdog_tick;
8887				if (cmd->cmd_active_timeout <= 0) {
8888					/*
8889					 * There seems to be a command stuck
8890					 * in the active slot.  Drain throttle.
8891					 */
8892					mptsas_set_throttle(mpt,
8893					    cmd->cmd_tgt_addr,
8894					    DRAIN_THROTTLE);
8895				}
8896			}
8897			if ((cmd->cmd_flags & CFLAG_PASSTHRU) ||
8898			    (cmd->cmd_flags & CFLAG_CONFIG)) {
8899				cmd->cmd_active_timeout -=
8900				    mptsas_scsi_watchdog_tick;
8901				if (cmd->cmd_active_timeout <= 0) {
8902					/*
8903					 * passthrough command timeout
8904					 */
8905					cmd->cmd_flags |= (CFLAG_FINISHED |
8906					    CFLAG_TIMEOUT);
8907					cv_broadcast(&mpt->m_passthru_cv);
8908					cv_broadcast(&mpt->m_config_cv);
8909				}
8910			}
8911		}
8912	}
8913
8914	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
8915	    MPTSAS_HASH_FIRST);
8916	while (ptgt != NULL) {
8917		/*
8918		 * If we were draining due to a qfull condition,
8919		 * go back to full throttle.
8920		 */
8921		if ((ptgt->m_t_throttle < MAX_THROTTLE) &&
8922		    (ptgt->m_t_throttle > HOLD_THROTTLE) &&
8923		    (ptgt->m_t_ncmds < ptgt->m_t_throttle)) {
8924			mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
8925			mptsas_restart_hba(mpt);
8926		}
8927
8928		if ((ptgt->m_t_ncmds > 0) &&
8929		    (ptgt->m_timebase)) {
8930
8931			if (ptgt->m_timebase <=
8932			    mptsas_scsi_watchdog_tick) {
8933				ptgt->m_timebase +=
8934				    mptsas_scsi_watchdog_tick;
8935				ptgt = (mptsas_target_t *)mptsas_hash_traverse(
8936				    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
8937				continue;
8938			}
8939
8940			ptgt->m_timeout -= mptsas_scsi_watchdog_tick;
8941
8942			if (ptgt->m_timeout < 0) {
8943				mptsas_cmd_timeout(mpt, ptgt->m_devhdl);
8944				ptgt = (mptsas_target_t *)mptsas_hash_traverse(
8945				    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
8946				continue;
8947			}
8948
8949			if ((ptgt->m_timeout) <=
8950			    mptsas_scsi_watchdog_tick) {
8951				NDBG23(("pending timeout"));
8952				mptsas_set_throttle(mpt, ptgt,
8953				    DRAIN_THROTTLE);
8954			}
8955		}
8956
8957		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
8958		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
8959	}
8960}
8961
8962/*
8963 * timeout recovery
8964 */
8965static void
8966mptsas_cmd_timeout(mptsas_t *mpt, uint16_t devhdl)
8967{
8968
8969	NDBG29(("mptsas_cmd_timeout: target=%d", devhdl));
8970	mptsas_log(mpt, CE_WARN, "Disconnected command timeout for "
8971	    "Target %d", devhdl);
8972
8973	/*
8974	 * If the current target is not the target passed in,
8975	 * try to reset that target.
8976	 */
8977	NDBG29(("mptsas_cmd_timeout: device reset"));
8978	if (mptsas_do_scsi_reset(mpt, devhdl) != TRUE) {
8979		mptsas_log(mpt, CE_WARN, "Target %d reset for command timeout "
8980		    "recovery failed!", devhdl);
8981	}
8982}
8983
8984/*
8985 * Device / Hotplug control
8986 */
8987static int
8988mptsas_scsi_quiesce(dev_info_t *dip)
8989{
8990	mptsas_t	*mpt;
8991	scsi_hba_tran_t	*tran;
8992
8993	tran = ddi_get_driver_private(dip);
8994	if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
8995		return (-1);
8996
8997	return (mptsas_quiesce_bus(mpt));
8998}
8999
9000static int
9001mptsas_scsi_unquiesce(dev_info_t *dip)
9002{
9003	mptsas_t		*mpt;
9004	scsi_hba_tran_t	*tran;
9005
9006	tran = ddi_get_driver_private(dip);
9007	if (tran == NULL || (mpt = TRAN2MPT(tran)) == NULL)
9008		return (-1);
9009
9010	return (mptsas_unquiesce_bus(mpt));
9011}
9012
9013static int
9014mptsas_quiesce_bus(mptsas_t *mpt)
9015{
9016	mptsas_target_t	*ptgt = NULL;
9017
9018	NDBG28(("mptsas_quiesce_bus"));
9019	mutex_enter(&mpt->m_mutex);
9020
9021	/* Set all the throttles to zero */
9022	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
9023	    MPTSAS_HASH_FIRST);
9024	while (ptgt != NULL) {
9025		mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9026
9027		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9028		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9029	}
9030
9031	/* If there are any outstanding commands in the queue */
9032	if (mpt->m_ncmds) {
9033		mpt->m_softstate |= MPTSAS_SS_DRAINING;
9034		mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
9035		    mpt, (MPTSAS_QUIESCE_TIMEOUT * drv_usectohz(1000000)));
9036		if (cv_wait_sig(&mpt->m_cv, &mpt->m_mutex) == 0) {
9037			/*
9038			 * Quiesce has been interrupted
9039			 */
9040			mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
9041			ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9042			    &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
9043			while (ptgt != NULL) {
9044				mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9045
9046				ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9047				    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9048			}
9049			mptsas_restart_hba(mpt);
9050			if (mpt->m_quiesce_timeid != 0) {
9051				timeout_id_t tid = mpt->m_quiesce_timeid;
9052				mpt->m_quiesce_timeid = 0;
9053				mutex_exit(&mpt->m_mutex);
9054				(void) untimeout(tid);
9055				return (-1);
9056			}
9057			mutex_exit(&mpt->m_mutex);
9058			return (-1);
9059		} else {
9060			/* Bus has been quiesced */
9061			ASSERT(mpt->m_quiesce_timeid == 0);
9062			mpt->m_softstate &= ~MPTSAS_SS_DRAINING;
9063			mpt->m_softstate |= MPTSAS_SS_QUIESCED;
9064			mutex_exit(&mpt->m_mutex);
9065			return (0);
9066		}
9067	}
9068	/* Bus was not busy - QUIESCED */
9069	mutex_exit(&mpt->m_mutex);
9070
9071	return (0);
9072}
9073
9074static int
9075mptsas_unquiesce_bus(mptsas_t *mpt)
9076{
9077	mptsas_target_t	*ptgt = NULL;
9078
9079	NDBG28(("mptsas_unquiesce_bus"));
9080	mutex_enter(&mpt->m_mutex);
9081	mpt->m_softstate &= ~MPTSAS_SS_QUIESCED;
9082	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
9083	    MPTSAS_HASH_FIRST);
9084	while (ptgt != NULL) {
9085		mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
9086
9087		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9088		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9089	}
9090	mptsas_restart_hba(mpt);
9091	mutex_exit(&mpt->m_mutex);
9092	return (0);
9093}
9094
9095static void
9096mptsas_ncmds_checkdrain(void *arg)
9097{
9098	mptsas_t	*mpt = arg;
9099	mptsas_target_t	*ptgt = NULL;
9100
9101	mutex_enter(&mpt->m_mutex);
9102	if (mpt->m_softstate & MPTSAS_SS_DRAINING) {
9103		mpt->m_quiesce_timeid = 0;
9104		if (mpt->m_ncmds == 0) {
9105			/* Command queue has been drained */
9106			cv_signal(&mpt->m_cv);
9107		} else {
9108			/*
9109			 * The throttle may have been reset because
9110			 * of a SCSI bus reset
9111			 */
9112			ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9113			    &mpt->m_active->m_tgttbl, MPTSAS_HASH_FIRST);
9114			while (ptgt != NULL) {
9115				mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
9116
9117				ptgt = (mptsas_target_t *)mptsas_hash_traverse(
9118				    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
9119			}
9120
9121			mpt->m_quiesce_timeid = timeout(mptsas_ncmds_checkdrain,
9122			    mpt, (MPTSAS_QUIESCE_TIMEOUT *
9123			    drv_usectohz(1000000)));
9124		}
9125	}
9126	mutex_exit(&mpt->m_mutex);
9127}
9128
9129static void
9130mptsas_dump_cmd(mptsas_t *mpt, mptsas_cmd_t *cmd)
9131{
9132	int	i;
9133	uint8_t	*cp = (uchar_t *)cmd->cmd_pkt->pkt_cdbp;
9134	char	buf[128];
9135
9136	buf[0] = '\0';
9137	mptsas_log(mpt, CE_NOTE, "?Cmd (0x%p) dump for Target %d Lun %d:\n",
9138	    (void *)cmd, Tgt(cmd), Lun(cmd));
9139	(void) sprintf(&buf[0], "\tcdb=[");
9140	for (i = 0; i < (int)cmd->cmd_cdblen; i++) {
9141		(void) sprintf(&buf[strlen(buf)], " 0x%x", *cp++);
9142	}
9143	(void) sprintf(&buf[strlen(buf)], " ]");
9144	mptsas_log(mpt, CE_NOTE, "?%s\n", buf);
9145	mptsas_log(mpt, CE_NOTE,
9146	    "?pkt_flags=0x%x pkt_statistics=0x%x pkt_state=0x%x\n",
9147	    cmd->cmd_pkt->pkt_flags, cmd->cmd_pkt->pkt_statistics,
9148	    cmd->cmd_pkt->pkt_state);
9149	mptsas_log(mpt, CE_NOTE, "?pkt_scbp=0x%x cmd_flags=0x%x\n",
9150	    *(cmd->cmd_pkt->pkt_scbp), cmd->cmd_flags);
9151}
9152
9153static void
9154mptsas_start_passthru(mptsas_t *mpt, mptsas_cmd_t *cmd)
9155{
9156	caddr_t			memp;
9157	pMPI2RequestHeader_t	request_hdrp;
9158	struct scsi_pkt		*pkt = cmd->cmd_pkt;
9159	mptsas_pt_request_t	*pt = pkt->pkt_ha_private;
9160	uint32_t		request_size, data_size, dataout_size;
9161	uint32_t		direction;
9162	ddi_dma_cookie_t	data_cookie;
9163	ddi_dma_cookie_t	dataout_cookie;
9164	uint32_t		request_desc_low, request_desc_high = 0;
9165	uint32_t		i, sense_bufp;
9166	uint8_t			desc_type;
9167	uint8_t			*request, function;
9168	ddi_dma_handle_t	dma_hdl = mpt->m_dma_req_frame_hdl;
9169	ddi_acc_handle_t	acc_hdl = mpt->m_acc_req_frame_hdl;
9170
9171	desc_type = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
9172
9173	request = pt->request;
9174	direction = pt->direction;
9175	request_size = pt->request_size;
9176	data_size = pt->data_size;
9177	dataout_size = pt->dataout_size;
9178	data_cookie = pt->data_cookie;
9179	dataout_cookie = pt->dataout_cookie;
9180
9181	/*
9182	 * Store the passthrough message in memory location
9183	 * corresponding to our slot number
9184	 */
9185	memp = mpt->m_req_frame + (mpt->m_req_frame_size * cmd->cmd_slot);
9186	request_hdrp = (pMPI2RequestHeader_t)memp;
9187	bzero(memp, mpt->m_req_frame_size);
9188
9189	for (i = 0; i < request_size; i++) {
9190		bcopy(request + i, memp + i, 1);
9191	}
9192
9193	if (data_size || dataout_size) {
9194		pMpi2SGESimple64_t	sgep;
9195		uint32_t		sge_flags;
9196
9197		sgep = (pMpi2SGESimple64_t)((uint8_t *)request_hdrp +
9198		    request_size);
9199		if (dataout_size) {
9200
9201			sge_flags = dataout_size |
9202			    ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
9203			    MPI2_SGE_FLAGS_END_OF_BUFFER |
9204			    MPI2_SGE_FLAGS_HOST_TO_IOC |
9205			    MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
9206			    MPI2_SGE_FLAGS_SHIFT);
9207			ddi_put32(acc_hdl, &sgep->FlagsLength, sge_flags);
9208			ddi_put32(acc_hdl, &sgep->Address.Low,
9209			    (uint32_t)(dataout_cookie.dmac_laddress &
9210			    0xffffffffull));
9211			ddi_put32(acc_hdl, &sgep->Address.High,
9212			    (uint32_t)(dataout_cookie.dmac_laddress
9213			    >> 32));
9214			sgep++;
9215		}
9216		sge_flags = data_size;
9217		sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_SIMPLE_ELEMENT |
9218		    MPI2_SGE_FLAGS_LAST_ELEMENT |
9219		    MPI2_SGE_FLAGS_END_OF_BUFFER |
9220		    MPI2_SGE_FLAGS_END_OF_LIST |
9221		    MPI2_SGE_FLAGS_64_BIT_ADDRESSING) <<
9222		    MPI2_SGE_FLAGS_SHIFT);
9223		if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) {
9224			sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_HOST_TO_IOC) <<
9225			    MPI2_SGE_FLAGS_SHIFT);
9226		} else {
9227			sge_flags |= ((uint32_t)(MPI2_SGE_FLAGS_IOC_TO_HOST) <<
9228			    MPI2_SGE_FLAGS_SHIFT);
9229		}
9230		ddi_put32(acc_hdl, &sgep->FlagsLength,
9231		    sge_flags);
9232		ddi_put32(acc_hdl, &sgep->Address.Low,
9233		    (uint32_t)(data_cookie.dmac_laddress &
9234		    0xffffffffull));
9235		ddi_put32(acc_hdl, &sgep->Address.High,
9236		    (uint32_t)(data_cookie.dmac_laddress >> 32));
9237	}
9238
9239	function = request_hdrp->Function;
9240	if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
9241	    (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
9242		pMpi2SCSIIORequest_t	scsi_io_req;
9243
9244		scsi_io_req = (pMpi2SCSIIORequest_t)request_hdrp;
9245		/*
9246		 * Put SGE for data and data_out buffer at the end of
9247		 * scsi_io_request message header.(64 bytes in total)
9248		 * Following above SGEs, the residual space will be
9249		 * used by sense data.
9250		 */
9251		ddi_put8(acc_hdl,
9252		    &scsi_io_req->SenseBufferLength,
9253		    (uint8_t)(request_size - 64));
9254
9255		sense_bufp = mpt->m_req_frame_dma_addr +
9256		    (mpt->m_req_frame_size * cmd->cmd_slot);
9257		sense_bufp += 64;
9258		ddi_put32(acc_hdl,
9259		    &scsi_io_req->SenseBufferLowAddress, sense_bufp);
9260
9261		/*
9262		 * Set SGLOffset0 value
9263		 */
9264		ddi_put8(acc_hdl, &scsi_io_req->SGLOffset0,
9265		    offsetof(MPI2_SCSI_IO_REQUEST, SGL) / 4);
9266
9267		/*
9268		 * Setup descriptor info
9269		 */
9270		desc_type = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
9271		request_desc_high = (ddi_get16(acc_hdl,
9272		    &scsi_io_req->DevHandle) << 16);
9273	}
9274
9275	/*
9276	 * We must wait till the message has been completed before
9277	 * beginning the next message so we wait for this one to
9278	 * finish.
9279	 */
9280	(void) ddi_dma_sync(dma_hdl, 0, 0, DDI_DMA_SYNC_FORDEV);
9281	request_desc_low = (cmd->cmd_slot << 16) + desc_type;
9282	cmd->cmd_rfm = NULL;
9283	MPTSAS_START_CMD(mpt, request_desc_low, request_desc_high);
9284	if ((mptsas_check_dma_handle(dma_hdl) != DDI_SUCCESS) ||
9285	    (mptsas_check_acc_handle(acc_hdl) != DDI_SUCCESS)) {
9286		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
9287	}
9288}
9289
9290
9291
9292static int
9293mptsas_do_passthru(mptsas_t *mpt, uint8_t *request, uint8_t *reply,
9294    uint8_t *data, uint32_t request_size, uint32_t reply_size,
9295    uint32_t data_size, uint32_t direction, uint8_t *dataout,
9296    uint32_t dataout_size, short timeout, int mode)
9297{
9298	mptsas_pt_request_t		pt;
9299	mptsas_dma_alloc_state_t	data_dma_state;
9300	mptsas_dma_alloc_state_t	dataout_dma_state;
9301	caddr_t				memp;
9302	mptsas_cmd_t			*cmd = NULL;
9303	struct scsi_pkt			*pkt;
9304	uint32_t			reply_len = 0, sense_len = 0;
9305	pMPI2RequestHeader_t		request_hdrp;
9306	pMPI2RequestHeader_t		request_msg;
9307	pMPI2DefaultReply_t		reply_msg;
9308	Mpi2SCSIIOReply_t		rep_msg;
9309	int				i, status = 0, pt_flags = 0, rv = 0;
9310	int				rvalue;
9311	uint32_t			reply_index;
9312	uint8_t				function;
9313
9314	ASSERT(mutex_owned(&mpt->m_mutex));
9315
9316	reply_msg = (pMPI2DefaultReply_t)(&rep_msg);
9317	bzero(reply_msg, sizeof (MPI2_DEFAULT_REPLY));
9318	request_msg = kmem_zalloc(request_size, KM_SLEEP);
9319
9320	mutex_exit(&mpt->m_mutex);
9321	/*
9322	 * copy in the request buffer since it could be used by
9323	 * another thread when the pt request into waitq
9324	 */
9325	if (ddi_copyin(request, request_msg, request_size, mode)) {
9326		mutex_enter(&mpt->m_mutex);
9327		status = EFAULT;
9328		mptsas_log(mpt, CE_WARN, "failed to copy request data");
9329		goto out;
9330	}
9331	mutex_enter(&mpt->m_mutex);
9332
9333	function = request_msg->Function;
9334	if (function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
9335		pMpi2SCSITaskManagementRequest_t	task;
9336		task = (pMpi2SCSITaskManagementRequest_t)request_msg;
9337		mptsas_setup_bus_reset_delay(mpt);
9338		rv = mptsas_ioc_task_management(mpt, task->TaskType,
9339		    task->DevHandle, (int)task->LUN[1]);
9340
9341		if (rv != TRUE) {
9342			status = EIO;
9343			mptsas_log(mpt, CE_WARN, "task management failed");
9344		}
9345		goto out;
9346	}
9347
9348	if (data_size != 0) {
9349		data_dma_state.size = data_size;
9350		if (mptsas_passthru_dma_alloc(mpt, &data_dma_state) !=
9351		    DDI_SUCCESS) {
9352			status = ENOMEM;
9353			mptsas_log(mpt, CE_WARN, "failed to alloc DMA "
9354			    "resource");
9355			goto out;
9356		}
9357		pt_flags |= MPTSAS_DATA_ALLOCATED;
9358		if (direction == MPTSAS_PASS_THRU_DIRECTION_WRITE) {
9359			mutex_exit(&mpt->m_mutex);
9360			for (i = 0; i < data_size; i++) {
9361				if (ddi_copyin(data + i, (uint8_t *)
9362				    data_dma_state.memp + i, 1, mode)) {
9363					mutex_enter(&mpt->m_mutex);
9364					status = EFAULT;
9365					mptsas_log(mpt, CE_WARN, "failed to "
9366					    "copy read data");
9367					goto out;
9368				}
9369			}
9370			mutex_enter(&mpt->m_mutex);
9371		}
9372	}
9373
9374	if (dataout_size != 0) {
9375		dataout_dma_state.size = dataout_size;
9376		if (mptsas_passthru_dma_alloc(mpt, &dataout_dma_state) !=
9377		    DDI_SUCCESS) {
9378			status = ENOMEM;
9379			mptsas_log(mpt, CE_WARN, "failed to alloc DMA "
9380			    "resource");
9381			goto out;
9382		}
9383		pt_flags |= MPTSAS_DATAOUT_ALLOCATED;
9384		mutex_exit(&mpt->m_mutex);
9385		for (i = 0; i < dataout_size; i++) {
9386			if (ddi_copyin(dataout + i, (uint8_t *)
9387			    dataout_dma_state.memp + i, 1, mode)) {
9388				mutex_enter(&mpt->m_mutex);
9389				mptsas_log(mpt, CE_WARN, "failed to copy out"
9390				    " data");
9391				status = EFAULT;
9392				goto out;
9393			}
9394		}
9395		mutex_enter(&mpt->m_mutex);
9396	}
9397
9398	if ((rvalue = (mptsas_request_from_pool(mpt, &cmd, &pkt))) == -1) {
9399		status = EAGAIN;
9400		mptsas_log(mpt, CE_NOTE, "event ack command pool is full");
9401		goto out;
9402	}
9403	pt_flags |= MPTSAS_REQUEST_POOL_CMD;
9404
9405	bzero((caddr_t)cmd, sizeof (*cmd));
9406	bzero((caddr_t)pkt, scsi_pkt_size());
9407	bzero((caddr_t)&pt, sizeof (pt));
9408
9409	cmd->ioc_cmd_slot = (uint32_t)(rvalue);
9410
9411	pt.request = (uint8_t *)request_msg;
9412	pt.direction = direction;
9413	pt.request_size = request_size;
9414	pt.data_size = data_size;
9415	pt.dataout_size = dataout_size;
9416	pt.data_cookie = data_dma_state.cookie;
9417	pt.dataout_cookie = dataout_dma_state.cookie;
9418
9419	/*
9420	 * Form a blank cmd/pkt to store the acknowledgement message
9421	 */
9422	pkt->pkt_cdbp		= (opaque_t)&cmd->cmd_cdb[0];
9423	pkt->pkt_scbp		= (opaque_t)&cmd->cmd_scb;
9424	pkt->pkt_ha_private	= (opaque_t)&pt;
9425	pkt->pkt_flags		= FLAG_HEAD;
9426	pkt->pkt_time		= timeout;
9427	cmd->cmd_pkt		= pkt;
9428	cmd->cmd_flags		= CFLAG_CMDIOC | CFLAG_PASSTHRU;
9429
9430	/*
9431	 * Save the command in a slot
9432	 */
9433	if (mptsas_save_cmd(mpt, cmd) == TRUE) {
9434		/*
9435		 * Once passthru command get slot, set cmd_flags
9436		 * CFLAG_PREPARED.
9437		 */
9438		cmd->cmd_flags |= CFLAG_PREPARED;
9439		mptsas_start_passthru(mpt, cmd);
9440	} else {
9441		mptsas_waitq_add(mpt, cmd);
9442	}
9443
9444	while ((cmd->cmd_flags & CFLAG_FINISHED) == 0) {
9445		cv_wait(&mpt->m_passthru_cv, &mpt->m_mutex);
9446	}
9447
9448	if (cmd->cmd_flags & CFLAG_PREPARED) {
9449		memp = mpt->m_req_frame + (mpt->m_req_frame_size *
9450		    cmd->cmd_slot);
9451		request_hdrp = (pMPI2RequestHeader_t)memp;
9452	}
9453
9454	if (cmd->cmd_flags & CFLAG_TIMEOUT) {
9455		status = ETIMEDOUT;
9456		mptsas_log(mpt, CE_WARN, "passthrough command timeout");
9457		pt_flags |= MPTSAS_CMD_TIMEOUT;
9458		goto out;
9459	}
9460
9461	if (cmd->cmd_rfm) {
9462		/*
9463		 * cmd_rfm is zero means the command reply is a CONTEXT
9464		 * reply and no PCI Write to post the free reply SMFA
9465		 * because no reply message frame is used.
9466		 * cmd_rfm is non-zero means the reply is a ADDRESS
9467		 * reply and reply message frame is used.
9468		 */
9469		pt_flags |= MPTSAS_ADDRESS_REPLY;
9470		(void) ddi_dma_sync(mpt->m_dma_reply_frame_hdl, 0, 0,
9471		    DDI_DMA_SYNC_FORCPU);
9472		reply_msg = (pMPI2DefaultReply_t)
9473		    (mpt->m_reply_frame + (cmd->cmd_rfm -
9474		    mpt->m_reply_frame_dma_addr));
9475	}
9476
9477	mptsas_fma_check(mpt, cmd);
9478	if (pkt->pkt_reason == CMD_TRAN_ERR) {
9479		status = EAGAIN;
9480		mptsas_log(mpt, CE_WARN, "passthru fma error");
9481		goto out;
9482	}
9483	if (pkt->pkt_reason == CMD_RESET) {
9484		status = EAGAIN;
9485		mptsas_log(mpt, CE_WARN, "ioc reset abort passthru");
9486		goto out;
9487	}
9488
9489	if (pkt->pkt_reason == CMD_INCOMPLETE) {
9490		status = EIO;
9491		mptsas_log(mpt, CE_WARN, "passthrough command incomplete");
9492		goto out;
9493	}
9494
9495	mutex_exit(&mpt->m_mutex);
9496	if (cmd->cmd_flags & CFLAG_PREPARED) {
9497		function = request_hdrp->Function;
9498		if ((function == MPI2_FUNCTION_SCSI_IO_REQUEST) ||
9499		    (function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
9500			reply_len = sizeof (MPI2_SCSI_IO_REPLY);
9501			sense_len = reply_size - reply_len;
9502		} else {
9503			reply_len = reply_size;
9504			sense_len = 0;
9505		}
9506
9507		for (i = 0; i < reply_len; i++) {
9508			if (ddi_copyout((uint8_t *)reply_msg + i, reply + i, 1,
9509			    mode)) {
9510				mutex_enter(&mpt->m_mutex);
9511				status = EFAULT;
9512				mptsas_log(mpt, CE_WARN, "failed to copy out "
9513				    "reply data");
9514				goto out;
9515			}
9516		}
9517		for (i = 0; i < sense_len; i++) {
9518			if (ddi_copyout((uint8_t *)request_hdrp + 64 + i,
9519			    reply + reply_len + i, 1, mode)) {
9520				mutex_enter(&mpt->m_mutex);
9521				status = EFAULT;
9522				mptsas_log(mpt, CE_WARN, "failed to copy out "
9523				    "sense data");
9524				goto out;
9525			}
9526		}
9527	}
9528
9529	if (data_size) {
9530		if (direction != MPTSAS_PASS_THRU_DIRECTION_WRITE) {
9531			(void) ddi_dma_sync(data_dma_state.handle, 0, 0,
9532			    DDI_DMA_SYNC_FORCPU);
9533			for (i = 0; i < data_size; i++) {
9534				if (ddi_copyout((uint8_t *)(
9535				    data_dma_state.memp + i), data + i,  1,
9536				    mode)) {
9537					mutex_enter(&mpt->m_mutex);
9538					status = EFAULT;
9539					mptsas_log(mpt, CE_WARN, "failed to "
9540					    "copy out the reply data");
9541					goto out;
9542				}
9543			}
9544		}
9545	}
9546	mutex_enter(&mpt->m_mutex);
9547out:
9548	/*
9549	 * Put the reply frame back on the free queue, increment the free
9550	 * index, and write the new index to the free index register.  But only
9551	 * if this reply is an ADDRESS reply.
9552	 */
9553	if (pt_flags & MPTSAS_ADDRESS_REPLY) {
9554		reply_index = mpt->m_free_index;
9555		ddi_put32(mpt->m_acc_free_queue_hdl,
9556		    &((uint32_t *)(void *)mpt->m_free_queue)[reply_index],
9557		    cmd->cmd_rfm);
9558		(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
9559		    DDI_DMA_SYNC_FORDEV);
9560		if (++reply_index == mpt->m_free_queue_depth) {
9561			reply_index = 0;
9562		}
9563		mpt->m_free_index = reply_index;
9564		ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex,
9565		    reply_index);
9566	}
9567	if (cmd && (cmd->cmd_flags & CFLAG_PREPARED)) {
9568		mptsas_remove_cmd(mpt, cmd);
9569		pt_flags &= (~MPTSAS_REQUEST_POOL_CMD);
9570	}
9571	if (pt_flags & MPTSAS_REQUEST_POOL_CMD)
9572		mptsas_return_to_pool(mpt, cmd);
9573	if (pt_flags & MPTSAS_DATA_ALLOCATED) {
9574		if (mptsas_check_dma_handle(data_dma_state.handle) !=
9575		    DDI_SUCCESS) {
9576			ddi_fm_service_impact(mpt->m_dip,
9577			    DDI_SERVICE_UNAFFECTED);
9578			status = EFAULT;
9579		}
9580		mptsas_passthru_dma_free(&data_dma_state);
9581	}
9582	if (pt_flags & MPTSAS_DATAOUT_ALLOCATED) {
9583		if (mptsas_check_dma_handle(dataout_dma_state.handle) !=
9584		    DDI_SUCCESS) {
9585			ddi_fm_service_impact(mpt->m_dip,
9586			    DDI_SERVICE_UNAFFECTED);
9587			status = EFAULT;
9588		}
9589		mptsas_passthru_dma_free(&dataout_dma_state);
9590	}
9591	if (pt_flags & MPTSAS_CMD_TIMEOUT) {
9592		if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
9593			mptsas_log(mpt, CE_WARN, "mptsas_restart_ioc failed");
9594		}
9595	}
9596	if (request_msg)
9597		kmem_free(request_msg, request_size);
9598
9599	return (status);
9600}
9601
9602static int
9603mptsas_pass_thru(mptsas_t *mpt, mptsas_pass_thru_t *data, int mode)
9604{
9605	/*
9606	 * If timeout is 0, set timeout to default of 60 seconds.
9607	 */
9608	if (data->Timeout == 0) {
9609		data->Timeout = MPTSAS_PASS_THRU_TIME_DEFAULT;
9610	}
9611
9612	if (((data->DataSize == 0) &&
9613	    (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_NONE)) ||
9614	    ((data->DataSize != 0) &&
9615	    ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_READ) ||
9616	    (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_WRITE) ||
9617	    ((data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) &&
9618	    (data->DataOutSize != 0))))) {
9619		if (data->DataDirection == MPTSAS_PASS_THRU_DIRECTION_BOTH) {
9620			data->DataDirection = MPTSAS_PASS_THRU_DIRECTION_READ;
9621		} else {
9622			data->DataOutSize = 0;
9623		}
9624		/*
9625		 * Send passthru request messages
9626		 */
9627		return (mptsas_do_passthru(mpt,
9628		    (uint8_t *)((uintptr_t)data->PtrRequest),
9629		    (uint8_t *)((uintptr_t)data->PtrReply),
9630		    (uint8_t *)((uintptr_t)data->PtrData),
9631		    data->RequestSize, data->ReplySize,
9632		    data->DataSize, data->DataDirection,
9633		    (uint8_t *)((uintptr_t)data->PtrDataOut),
9634		    data->DataOutSize, data->Timeout, mode));
9635	} else {
9636		return (EINVAL);
9637	}
9638}
9639
9640/*
9641 * This routine handles the "event query" ioctl.
9642 */
9643static int
9644mptsas_event_query(mptsas_t *mpt, mptsas_event_query_t *data, int mode,
9645    int *rval)
9646{
9647	int			status;
9648	mptsas_event_query_t	driverdata;
9649	uint8_t			i;
9650
9651	driverdata.Entries = MPTSAS_EVENT_QUEUE_SIZE;
9652
9653	mutex_enter(&mpt->m_mutex);
9654	for (i = 0; i < 4; i++) {
9655		driverdata.Types[i] = mpt->m_event_mask[i];
9656	}
9657	mutex_exit(&mpt->m_mutex);
9658
9659	if (ddi_copyout(&driverdata, data, sizeof (driverdata), mode) != 0) {
9660		status = EFAULT;
9661	} else {
9662		*rval = MPTIOCTL_STATUS_GOOD;
9663		status = 0;
9664	}
9665
9666	return (status);
9667}
9668
9669/*
9670 * This routine handles the "event enable" ioctl.
9671 */
9672static int
9673mptsas_event_enable(mptsas_t *mpt, mptsas_event_enable_t *data, int mode,
9674    int *rval)
9675{
9676	int			status;
9677	mptsas_event_enable_t	driverdata;
9678	uint8_t			i;
9679
9680	if (ddi_copyin(data, &driverdata, sizeof (driverdata), mode) == 0) {
9681		mutex_enter(&mpt->m_mutex);
9682		for (i = 0; i < 4; i++) {
9683			mpt->m_event_mask[i] = driverdata.Types[i];
9684		}
9685		mutex_exit(&mpt->m_mutex);
9686
9687		*rval = MPTIOCTL_STATUS_GOOD;
9688		status = 0;
9689	} else {
9690		status = EFAULT;
9691	}
9692	return (status);
9693}
9694
9695/*
9696 * This routine handles the "event report" ioctl.
9697 */
9698static int
9699mptsas_event_report(mptsas_t *mpt, mptsas_event_report_t *data, int mode,
9700    int *rval)
9701{
9702	int			status;
9703	mptsas_event_report_t	driverdata;
9704
9705	mutex_enter(&mpt->m_mutex);
9706
9707	if (ddi_copyin(&data->Size, &driverdata.Size, sizeof (driverdata.Size),
9708	    mode) == 0) {
9709		if (driverdata.Size >= sizeof (mpt->m_events)) {
9710			if (ddi_copyout(mpt->m_events, data->Events,
9711			    sizeof (mpt->m_events), mode) != 0) {
9712				status = EFAULT;
9713			} else {
9714				if (driverdata.Size > sizeof (mpt->m_events)) {
9715					driverdata.Size =
9716					    sizeof (mpt->m_events);
9717					if (ddi_copyout(&driverdata.Size,
9718					    &data->Size,
9719					    sizeof (driverdata.Size),
9720					    mode) != 0) {
9721						status = EFAULT;
9722					} else {
9723						*rval = MPTIOCTL_STATUS_GOOD;
9724						status = 0;
9725					}
9726				} else {
9727					*rval = MPTIOCTL_STATUS_GOOD;
9728					status = 0;
9729				}
9730			}
9731		} else {
9732			*rval = MPTIOCTL_STATUS_LEN_TOO_SHORT;
9733			status = 0;
9734		}
9735	} else {
9736		status = EFAULT;
9737	}
9738
9739	mutex_exit(&mpt->m_mutex);
9740	return (status);
9741}
9742
9743static void
9744mptsas_lookup_pci_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data)
9745{
9746	int	*reg_data;
9747	uint_t	reglen;
9748	char	*fw_rev;
9749
9750	/*
9751	 * Lookup the 'reg' property and extract the other data
9752	 */
9753	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip,
9754	    DDI_PROP_DONTPASS, "reg", &reg_data, &reglen) ==
9755	    DDI_PROP_SUCCESS) {
9756		/*
9757		 * Extract the PCI data from the 'reg' property first DWORD.
9758		 * The entry looks like the following:
9759		 * First DWORD:
9760		 * Bits 0 - 7 8-bit Register number
9761		 * Bits 8 - 10 3-bit Function number
9762		 * Bits 11 - 15 5-bit Device number
9763		 * Bits 16 - 23 8-bit Bus number
9764		 * Bits 24 - 25 2-bit Address Space type identifier
9765		 *
9766		 * Store the device number in PCIDeviceHwId.
9767		 * Store the function number in MpiPortNumber.
9768		 * PciInformation stores bus, device, and function together
9769		 */
9770		adapter_data->PCIDeviceHwId = (reg_data[0] & 0x0000F800) >> 11;
9771		adapter_data->MpiPortNumber = (reg_data[0] & 0x00000700) >> 8;
9772		adapter_data->PciInformation = (reg_data[0] & 0x00FFFF00) >> 8;
9773		ddi_prop_free((void *)reg_data);
9774	} else {
9775		/*
9776		 * If we can't determine the PCI data then we fill in FF's for
9777		 * the data to indicate this.
9778		 */
9779		adapter_data->PCIDeviceHwId = 0xFFFFFFFF;
9780		adapter_data->MpiPortNumber = 0xFFFFFFFF;
9781		adapter_data->PciInformation = 0xFFFFFFFF;
9782	}
9783
9784	/*
9785	 * Lookup the 'firmware-version' property and extract the data
9786	 */
9787	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, mpt->m_dip,
9788	    DDI_PROP_DONTPASS, "firmware-version", &fw_rev) ==
9789	    DDI_PROP_SUCCESS) {
9790		/*
9791		 * Version is a string of 4 bytes which fits into the DWORD
9792		 */
9793		(void) strcpy((char *)&adapter_data->MpiFirmwareVersion,
9794		    fw_rev);
9795		ddi_prop_free(fw_rev);
9796	} else {
9797		/*
9798		 * If we can't determine the PCI data then we fill in FF's for
9799		 * the data to indicate this.
9800		 */
9801		adapter_data->MpiFirmwareVersion = 0xFFFFFFFF;
9802	}
9803}
9804
9805static void
9806mptsas_read_adapter_data(mptsas_t *mpt, mptsas_adapter_data_t *adapter_data)
9807{
9808	char	*driver_verstr = MPTSAS_MOD_STRING;
9809
9810	mptsas_lookup_pci_data(mpt, adapter_data);
9811	adapter_data->AdapterType = MPTIOCTL_ADAPTER_TYPE_SAS2;
9812	adapter_data->PCIDeviceHwId = (uint32_t)mpt->m_devid;
9813	adapter_data->SubSystemId = (uint32_t)mpt->m_ssid;
9814	adapter_data->SubsystemVendorId = (uint32_t)mpt->m_svid;
9815	(void) strcpy((char *)&adapter_data->DriverVersion[0], driver_verstr);
9816}
9817
9818static void
9819mptsas_read_pci_info(mptsas_t *mpt, mptsas_pci_info_t *pci_info)
9820{
9821	int	*reg_data, i;
9822	uint_t	reglen;
9823
9824	/*
9825	 * Lookup the 'reg' property and extract the other data
9826	 */
9827	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, mpt->m_dip,
9828	    DDI_PROP_DONTPASS, "reg", &reg_data, &reglen) ==
9829	    DDI_PROP_SUCCESS) {
9830		/*
9831		 * Extract the PCI data from the 'reg' property first DWORD.
9832		 * The entry looks like the following:
9833		 * First DWORD:
9834		 * Bits 8 - 10 3-bit Function number
9835		 * Bits 11 - 15 5-bit Device number
9836		 * Bits 16 - 23 8-bit Bus number
9837		 */
9838		pci_info->BusNumber = (reg_data[0] & 0x00FF0000) >> 16;
9839		pci_info->DeviceNumber = (reg_data[0] & 0x0000F800) >> 11;
9840		pci_info->FunctionNumber = (reg_data[0] & 0x00000700) >> 8;
9841		ddi_prop_free((void *)reg_data);
9842	} else {
9843		/*
9844		 * If we can't determine the PCI info then we fill in FF's for
9845		 * the data to indicate this.
9846		 */
9847		pci_info->BusNumber = 0xFFFFFFFF;
9848		pci_info->DeviceNumber = 0xFF;
9849		pci_info->FunctionNumber = 0xFF;
9850	}
9851
9852	/*
9853	 * Now get the interrupt vector and the pci header.  The vector can
9854	 * only be 0 right now.  The header is the first 256 bytes of config
9855	 * space.
9856	 */
9857	pci_info->InterruptVector = 0;
9858	for (i = 0; i < sizeof (pci_info->PciHeader); i++) {
9859		pci_info->PciHeader[i] = pci_config_get8(mpt->m_config_handle,
9860		    i);
9861	}
9862}
9863
9864static int
9865mptsas_ioctl(dev_t dev, int cmd, intptr_t data, int mode, cred_t *credp,
9866    int *rval)
9867{
9868	int			status = 0;
9869	mptsas_t		*mpt;
9870	mptsas_update_flash_t	flashdata;
9871	mptsas_pass_thru_t	passthru_data;
9872	mptsas_adapter_data_t   adapter_data;
9873	mptsas_pci_info_t	pci_info;
9874	int			copylen;
9875
9876	*rval = MPTIOCTL_STATUS_GOOD;
9877	mpt = ddi_get_soft_state(mptsas_state, MINOR2INST(getminor(dev)));
9878	if (mpt == NULL) {
9879		return (scsi_hba_ioctl(dev, cmd, data, mode, credp, rval));
9880	}
9881	if (secpolicy_sys_config(credp, B_FALSE) != 0) {
9882		return (EPERM);
9883	}
9884
9885	/* Make sure power level is D0 before accessing registers */
9886	mutex_enter(&mpt->m_mutex);
9887	if (mpt->m_options & MPTSAS_OPT_PM) {
9888		(void) pm_busy_component(mpt->m_dip, 0);
9889		if (mpt->m_power_level != PM_LEVEL_D0) {
9890			mutex_exit(&mpt->m_mutex);
9891			if (pm_raise_power(mpt->m_dip, 0, PM_LEVEL_D0) !=
9892			    DDI_SUCCESS) {
9893				mptsas_log(mpt, CE_WARN,
9894				    "mptsas%d: mptsas_ioctl: Raise power "
9895				    "request failed.", mpt->m_instance);
9896				(void) pm_idle_component(mpt->m_dip, 0);
9897				return (ENXIO);
9898			}
9899		} else {
9900			mutex_exit(&mpt->m_mutex);
9901		}
9902	} else {
9903		mutex_exit(&mpt->m_mutex);
9904	}
9905
9906	switch (cmd) {
9907		case MPTIOCTL_UPDATE_FLASH:
9908			if (ddi_copyin((void *)data, &flashdata,
9909				sizeof (struct mptsas_update_flash), mode)) {
9910				status = EFAULT;
9911				break;
9912			}
9913
9914			mutex_enter(&mpt->m_mutex);
9915			if (mptsas_update_flash(mpt,
9916			    (caddr_t)(long)flashdata.PtrBuffer,
9917			    flashdata.ImageSize, flashdata.ImageType, mode)) {
9918				status = EFAULT;
9919			}
9920
9921			/*
9922			 * Reset the chip to start using the new
9923			 * firmware.  Reset if failed also.
9924			 */
9925			if (mptsas_restart_ioc(mpt) == DDI_FAILURE) {
9926				status = EFAULT;
9927			}
9928			mutex_exit(&mpt->m_mutex);
9929			break;
9930		case MPTIOCTL_PASS_THRU:
9931			/*
9932			 * The user has requested to pass through a command to
9933			 * be executed by the MPT firmware.  Call our routine
9934			 * which does this.  Only allow one passthru IOCTL at
9935			 * one time.
9936			 */
9937			if (ddi_copyin((void *)data, &passthru_data,
9938			    sizeof (mptsas_pass_thru_t), mode)) {
9939				status = EFAULT;
9940				break;
9941			}
9942			mutex_enter(&mpt->m_mutex);
9943			if (mpt->m_passthru_in_progress)
9944				return (EBUSY);
9945			mpt->m_passthru_in_progress = 1;
9946			status = mptsas_pass_thru(mpt, &passthru_data, mode);
9947			mpt->m_passthru_in_progress = 0;
9948			mutex_exit(&mpt->m_mutex);
9949
9950			break;
9951		case MPTIOCTL_GET_ADAPTER_DATA:
9952			/*
9953			 * The user has requested to read adapter data.  Call
9954			 * our routine which does this.
9955			 */
9956			bzero(&adapter_data, sizeof (mptsas_adapter_data_t));
9957			if (ddi_copyin((void *)data, (void *)&adapter_data,
9958			    sizeof (mptsas_adapter_data_t), mode)) {
9959				status = EFAULT;
9960				break;
9961			}
9962			if (adapter_data.StructureLength >=
9963			    sizeof (mptsas_adapter_data_t)) {
9964				adapter_data.StructureLength = (uint32_t)
9965				    sizeof (mptsas_adapter_data_t);
9966				copylen = sizeof (mptsas_adapter_data_t);
9967				mutex_enter(&mpt->m_mutex);
9968				mptsas_read_adapter_data(mpt, &adapter_data);
9969				mutex_exit(&mpt->m_mutex);
9970			} else {
9971				adapter_data.StructureLength = (uint32_t)
9972				    sizeof (mptsas_adapter_data_t);
9973				copylen = sizeof (adapter_data.StructureLength);
9974				*rval = MPTIOCTL_STATUS_LEN_TOO_SHORT;
9975			}
9976			if (ddi_copyout((void *)(&adapter_data), (void *)data,
9977			    copylen, mode) != 0) {
9978				status = EFAULT;
9979			}
9980			break;
9981		case MPTIOCTL_GET_PCI_INFO:
9982			/*
9983			 * The user has requested to read pci info.  Call
9984			 * our routine which does this.
9985			 */
9986			bzero(&pci_info, sizeof (mptsas_pci_info_t));
9987			mutex_enter(&mpt->m_mutex);
9988			mptsas_read_pci_info(mpt, &pci_info);
9989			mutex_exit(&mpt->m_mutex);
9990			if (ddi_copyout((void *)(&pci_info), (void *)data,
9991			    sizeof (mptsas_pci_info_t), mode) != 0) {
9992				status = EFAULT;
9993			}
9994			break;
9995		case MPTIOCTL_RESET_ADAPTER:
9996			mutex_enter(&mpt->m_mutex);
9997			if ((mptsas_restart_ioc(mpt)) == DDI_FAILURE) {
9998				mptsas_log(mpt, CE_WARN, "reset adapter IOCTL "
9999				    "failed");
10000				status = EFAULT;
10001			}
10002			mutex_exit(&mpt->m_mutex);
10003			break;
10004		case MPTIOCTL_EVENT_QUERY:
10005			/*
10006			 * The user has done an event query. Call our routine
10007			 * which does this.
10008			 */
10009			status = mptsas_event_query(mpt,
10010			    (mptsas_event_query_t *)data, mode, rval);
10011			break;
10012		case MPTIOCTL_EVENT_ENABLE:
10013			/*
10014			 * The user has done an event enable. Call our routine
10015			 * which does this.
10016			 */
10017			status = mptsas_event_enable(mpt,
10018			    (mptsas_event_enable_t *)data, mode, rval);
10019			break;
10020		case MPTIOCTL_EVENT_REPORT:
10021			/*
10022			 * The user has done an event report. Call our routine
10023			 * which does this.
10024			 */
10025			status = mptsas_event_report(mpt,
10026			    (mptsas_event_report_t *)data, mode, rval);
10027			break;
10028		default:
10029			status = scsi_hba_ioctl(dev, cmd, data, mode, credp,
10030			    rval);
10031			break;
10032	}
10033
10034	/*
10035	 * Report idle status to pm after grace period because
10036	 * multiple ioctls may be queued and raising power
10037	 * for every ioctl is time consuming.  If a timeout is
10038	 * pending for the previous ioctl, cancel the timeout and
10039	 * report idle status to pm because calls to pm_busy_component(9F)
10040	 * are stacked.
10041	 */
10042	mutex_enter(&mpt->m_mutex);
10043	if (mpt->m_options & MPTSAS_OPT_PM) {
10044		if (mpt->m_pm_timeid != 0) {
10045			timeout_id_t tid = mpt->m_pm_timeid;
10046			mpt->m_pm_timeid = 0;
10047			mutex_exit(&mpt->m_mutex);
10048			(void) untimeout(tid);
10049			/*
10050			 * Report idle status for previous ioctl since
10051			 * calls to pm_busy_component(9F) are stacked.
10052			 */
10053			(void) pm_idle_component(mpt->m_dip, 0);
10054			mutex_enter(&mpt->m_mutex);
10055		}
10056		mpt->m_pm_timeid = timeout(mptsas_idle_pm, mpt,
10057		    drv_usectohz((clock_t)mpt->m_pm_idle_delay * 1000000));
10058	}
10059	mutex_exit(&mpt->m_mutex);
10060
10061	return (status);
10062}
10063
10064int
10065mptsas_restart_ioc(mptsas_t *mpt) {
10066	int		rval = DDI_SUCCESS;
10067	mptsas_target_t	*ptgt = NULL;
10068
10069	ASSERT(mutex_owned(&mpt->m_mutex));
10070
10071	/*
10072	 * Set all throttles to HOLD
10073	 */
10074	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
10075	    MPTSAS_HASH_FIRST);
10076	while (ptgt != NULL) {
10077		mptsas_set_throttle(mpt, ptgt, HOLD_THROTTLE);
10078
10079		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
10080		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
10081	}
10082
10083	/*
10084	 * Disable interrupts
10085	 */
10086	MPTSAS_DISABLE_INTR(mpt);
10087
10088	/*
10089	 * Abort all commands: outstanding commands, commands in waitq and
10090	 * tx_waitq.
10091	 */
10092	mptsas_flush_hba(mpt);
10093
10094	/*
10095	 * Reinitialize the chip.
10096	 */
10097	if (mptsas_init_chip(mpt, FALSE) == DDI_FAILURE) {
10098		rval = DDI_FAILURE;
10099	}
10100
10101	/*
10102	 * Enable interrupts again
10103	 */
10104	MPTSAS_ENABLE_INTR(mpt);
10105
10106	/*
10107	 * If mptsas_init_chip was successful, update the driver data.
10108	 */
10109	if (rval == DDI_SUCCESS) {
10110		mptsas_update_driver_data(mpt);
10111	}
10112
10113	/*
10114	 * Reset the throttles
10115	 */
10116	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
10117	    MPTSAS_HASH_FIRST);
10118	while (ptgt != NULL) {
10119		mptsas_set_throttle(mpt, ptgt, MAX_THROTTLE);
10120
10121		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
10122		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
10123	}
10124
10125	mptsas_doneq_empty(mpt);
10126
10127	if (rval != DDI_SUCCESS) {
10128		mptsas_fm_ereport(mpt, DDI_FM_DEVICE_NO_RESPONSE);
10129		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_LOST);
10130	}
10131	return (rval);
10132}
10133
10134int
10135mptsas_init_chip(mptsas_t *mpt, int first_time)
10136{
10137	ddi_dma_cookie_t	cookie;
10138	uint32_t		i;
10139
10140	if (first_time == FALSE) {
10141		/*
10142		 * Setup configuration space
10143		 */
10144		if (mptsas_config_space_init(mpt) == FALSE) {
10145			mptsas_log(mpt, CE_WARN, "mptsas_config_space_init "
10146			    "failed!");
10147			goto fail;
10148		}
10149	}
10150
10151	/*
10152	 * Check to see if the firmware image is valid
10153	 */
10154	if (ddi_get32(mpt->m_datap, &mpt->m_reg->HostDiagnostic) &
10155	    MPI2_DIAG_FLASH_BAD_SIG) {
10156		mptsas_log(mpt, CE_WARN, "mptsas bad flash signature!");
10157		goto fail;
10158	}
10159
10160	/*
10161	 * Reset the chip
10162	 */
10163	if (mptsas_ioc_reset(mpt) == MPTSAS_RESET_FAIL) {
10164		mptsas_log(mpt, CE_WARN, "hard reset failed!");
10165		return (DDI_FAILURE);
10166	}
10167	/*
10168	 * Do some initilization only needed during attach
10169	 */
10170	if (first_time) {
10171		/*
10172		 * Get ioc facts from adapter
10173		 */
10174		if (mptsas_ioc_get_facts(mpt) == DDI_FAILURE) {
10175			mptsas_log(mpt, CE_WARN, "mptsas_ioc_get_facts "
10176			    "failed");
10177			goto fail;
10178		}
10179
10180		/*
10181		 * Allocate request message frames
10182		 */
10183		if (mptsas_alloc_request_frames(mpt) == DDI_FAILURE) {
10184			mptsas_log(mpt, CE_WARN, "mptsas_alloc_request_frames "
10185			    "failed");
10186			goto fail;
10187		}
10188		/*
10189		 * Allocate reply free queue
10190		 */
10191		if (mptsas_alloc_free_queue(mpt) == DDI_FAILURE) {
10192			mptsas_log(mpt, CE_WARN, "mptsas_alloc_free_queue "
10193			    "failed!");
10194			goto fail;
10195		}
10196		/*
10197		 * Allocate reply descriptor post queue
10198		 */
10199		if (mptsas_alloc_post_queue(mpt) == DDI_FAILURE) {
10200			mptsas_log(mpt, CE_WARN, "mptsas_alloc_post_queue "
10201			    "failed!");
10202			goto fail;
10203		}
10204		/*
10205		 * Allocate reply message frames
10206		 */
10207		if (mptsas_alloc_reply_frames(mpt) == DDI_FAILURE) {
10208			mptsas_log(mpt, CE_WARN, "mptsas_alloc_reply_frames "
10209			    "failed!");
10210			goto fail;
10211		}
10212	}
10213
10214	/*
10215	 * Re-Initialize ioc to operational state
10216	 */
10217	if (mptsas_ioc_init(mpt) == DDI_FAILURE) {
10218		mptsas_log(mpt, CE_WARN, "mptsas_ioc_init failed");
10219		goto fail;
10220	}
10221
10222	mpt->m_replyh_args = kmem_zalloc(sizeof (m_replyh_arg_t) *
10223	    mpt->m_max_replies, KM_SLEEP);
10224
10225	/*
10226	 * Initialize reply post index and request index.  Reply free index is
10227	 * initialized after the next loop.  m_tags must only be initialized if
10228	 * this is not the first time because m_active is not allocated if this
10229	 * is the first time.
10230	 */
10231	mpt->m_post_index = 0;
10232	if (!first_time) {
10233		mpt->m_active->m_tags = 1;
10234	}
10235
10236	/*
10237	 * Initialize the Reply Free Queue with the physical addresses of our
10238	 * reply frames.
10239	 */
10240	cookie.dmac_address = mpt->m_reply_frame_dma_addr;
10241	for (i = 0; i < mpt->m_free_queue_depth - 1; i++) {
10242		ddi_put32(mpt->m_acc_free_queue_hdl,
10243		    &((uint32_t *)(void *)mpt->m_free_queue)[i],
10244		    cookie.dmac_address);
10245		cookie.dmac_address += mpt->m_reply_frame_size;
10246	}
10247	(void) ddi_dma_sync(mpt->m_dma_free_queue_hdl, 0, 0,
10248	    DDI_DMA_SYNC_FORDEV);
10249
10250	/*
10251	 * Initialize the reply free index to one past the last frame on the
10252	 * queue.  This will signify that the queue is empty to start with.
10253	 */
10254	mpt->m_free_index = i;
10255	ddi_put32(mpt->m_datap, &mpt->m_reg->ReplyFreeHostIndex, i);
10256
10257	/*
10258	 * Initialize the reply post queue to 0xFFFFFFFF,0xFFFFFFFF's.
10259	 */
10260	for (i = 0; i < mpt->m_post_queue_depth; i++) {
10261		ddi_put64(mpt->m_acc_post_queue_hdl,
10262		    &((uint64_t *)(void *)mpt->m_post_queue)[i],
10263		    0xFFFFFFFFFFFFFFFF);
10264	}
10265	(void) ddi_dma_sync(mpt->m_dma_post_queue_hdl, 0, 0,
10266	    DDI_DMA_SYNC_FORDEV);
10267
10268	/*
10269	 * Enable ports
10270	 */
10271	if (mptsas_ioc_enable_port(mpt) == DDI_FAILURE) {
10272		mptsas_log(mpt, CE_WARN, "mptsas_ioc_enable_port failed");
10273		goto fail;
10274	}
10275
10276	/*
10277	 * First, make sure the HBA is set in "initiator" mode.  Once that
10278	 * is complete, get the base WWID.
10279	 */
10280
10281	if (first_time) {
10282		if (mptsas_set_initiator_mode(mpt)) {
10283			mptsas_log(mpt, CE_WARN, "mptsas_set_initiator_mode "
10284			    "failed!");
10285			goto fail;
10286		}
10287
10288		if (mptsas_get_manufacture_page5(mpt) == DDI_FAILURE) {
10289			mptsas_log(mpt, CE_WARN,
10290			    "mptsas_get_manufacture_page5 failed!");
10291			goto fail;
10292		}
10293	}
10294
10295	/*
10296	 * enable events
10297	 */
10298	if (first_time != TRUE) {
10299		if (mptsas_ioc_enable_event_notification(mpt)) {
10300			goto fail;
10301		}
10302	}
10303
10304	/*
10305	 * We need checks in attach and these.
10306	 * chip_init is called in mult. places
10307	 */
10308
10309	if ((mptsas_check_dma_handle(mpt->m_dma_req_frame_hdl) !=
10310	    DDI_SUCCESS) ||
10311	    (mptsas_check_dma_handle(mpt->m_dma_reply_frame_hdl) !=
10312	    DDI_SUCCESS) ||
10313	    (mptsas_check_dma_handle(mpt->m_dma_free_queue_hdl) !=
10314	    DDI_SUCCESS) ||
10315	    (mptsas_check_dma_handle(mpt->m_dma_post_queue_hdl) !=
10316	    DDI_SUCCESS) ||
10317	    (mptsas_check_dma_handle(mpt->m_hshk_dma_hdl) !=
10318	    DDI_SUCCESS)) {
10319		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
10320		goto fail;
10321	}
10322
10323	/* Check all acc handles */
10324	if ((mptsas_check_acc_handle(mpt->m_datap) != DDI_SUCCESS) ||
10325	    (mptsas_check_acc_handle(mpt->m_acc_req_frame_hdl) !=
10326	    DDI_SUCCESS) ||
10327	    (mptsas_check_acc_handle(mpt->m_acc_reply_frame_hdl) !=
10328	    DDI_SUCCESS) ||
10329	    (mptsas_check_acc_handle(mpt->m_acc_free_queue_hdl) !=
10330	    DDI_SUCCESS) ||
10331	    (mptsas_check_acc_handle(mpt->m_acc_post_queue_hdl) !=
10332	    DDI_SUCCESS) ||
10333	    (mptsas_check_acc_handle(mpt->m_hshk_acc_hdl) !=
10334	    DDI_SUCCESS) ||
10335	    (mptsas_check_acc_handle(mpt->m_config_handle) !=
10336	    DDI_SUCCESS)) {
10337		ddi_fm_service_impact(mpt->m_dip, DDI_SERVICE_UNAFFECTED);
10338		goto fail;
10339	}
10340
10341	return (DDI_SUCCESS);
10342
10343fail:
10344	return (DDI_FAILURE);
10345}
10346
10347static int
10348mptsas_init_pm(mptsas_t *mpt)
10349{
10350	char		pmc_name[16];
10351	char		*pmc[] = {
10352				NULL,
10353				"0=Off (PCI D3 State)",
10354				"3=On (PCI D0 State)",
10355				NULL
10356			};
10357	uint16_t	pmcsr_stat;
10358
10359	/*
10360	 * If power management is supported by this chip, create
10361	 * pm-components property for the power management framework
10362	 */
10363	(void) sprintf(pmc_name, "NAME=mptsas%d", mpt->m_instance);
10364	pmc[0] = pmc_name;
10365	if (ddi_prop_update_string_array(DDI_DEV_T_NONE, mpt->m_dip,
10366	    "pm-components", pmc, 3) != DDI_PROP_SUCCESS) {
10367		mpt->m_options &= ~MPTSAS_OPT_PM;
10368		mptsas_log(mpt, CE_WARN,
10369		    "mptsas%d: pm-component property creation failed.",
10370		    mpt->m_instance);
10371		return (DDI_FAILURE);
10372	}
10373
10374	/*
10375	 * Power on device.
10376	 */
10377	(void) pm_busy_component(mpt->m_dip, 0);
10378	pmcsr_stat = pci_config_get16(mpt->m_config_handle,
10379	    mpt->m_pmcsr_offset);
10380	if ((pmcsr_stat & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_D0) {
10381		mptsas_log(mpt, CE_WARN, "mptsas%d: Power up the device",
10382		    mpt->m_instance);
10383		pci_config_put16(mpt->m_config_handle, mpt->m_pmcsr_offset,
10384		    PCI_PMCSR_D0);
10385	}
10386	if (pm_power_has_changed(mpt->m_dip, 0, PM_LEVEL_D0) != DDI_SUCCESS) {
10387		mptsas_log(mpt, CE_WARN, "pm_power_has_changed failed");
10388		return (DDI_FAILURE);
10389	}
10390	mpt->m_power_level = PM_LEVEL_D0;
10391	/*
10392	 * Set pm idle delay.
10393	 */
10394	mpt->m_pm_idle_delay = ddi_prop_get_int(DDI_DEV_T_ANY,
10395	    mpt->m_dip, 0, "mptsas-pm-idle-delay", MPTSAS_PM_IDLE_TIMEOUT);
10396
10397	return (DDI_SUCCESS);
10398}
10399
10400/*
10401 * mptsas_add_intrs:
10402 *
10403 * Register FIXED or MSI interrupts.
10404 */
10405static int
10406mptsas_add_intrs(mptsas_t *mpt, int intr_type)
10407{
10408	dev_info_t	*dip = mpt->m_dip;
10409	int		avail, actual, count = 0;
10410	int		i, flag, ret;
10411
10412	NDBG6(("mptsas_add_intrs:interrupt type 0x%x", intr_type));
10413
10414	/* Get number of interrupts */
10415	ret = ddi_intr_get_nintrs(dip, intr_type, &count);
10416	if ((ret != DDI_SUCCESS) || (count <= 0)) {
10417		mptsas_log(mpt, CE_WARN, "ddi_intr_get_nintrs() failed, "
10418		    "ret %d count %d\n", ret, count);
10419
10420		return (DDI_FAILURE);
10421	}
10422
10423	/* Get number of available interrupts */
10424	ret = ddi_intr_get_navail(dip, intr_type, &avail);
10425	if ((ret != DDI_SUCCESS) || (avail == 0)) {
10426		mptsas_log(mpt, CE_WARN, "ddi_intr_get_navail() failed, "
10427		    "ret %d avail %d\n", ret, avail);
10428
10429		return (DDI_FAILURE);
10430	}
10431
10432	if (avail < count) {
10433		mptsas_log(mpt, CE_NOTE, "ddi_intr_get_nvail returned %d, "
10434		    "navail() returned %d", count, avail);
10435	}
10436
10437	/* Mpt only have one interrupt routine */
10438	if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) {
10439		count = 1;
10440	}
10441
10442	/* Allocate an array of interrupt handles */
10443	mpt->m_intr_size = count * sizeof (ddi_intr_handle_t);
10444	mpt->m_htable = kmem_alloc(mpt->m_intr_size, KM_SLEEP);
10445
10446	flag = DDI_INTR_ALLOC_NORMAL;
10447
10448	/* call ddi_intr_alloc() */
10449	ret = ddi_intr_alloc(dip, mpt->m_htable, intr_type, 0,
10450	    count, &actual, flag);
10451
10452	if ((ret != DDI_SUCCESS) || (actual == 0)) {
10453		mptsas_log(mpt, CE_WARN, "ddi_intr_alloc() failed, ret %d\n",
10454		    ret);
10455		kmem_free(mpt->m_htable, mpt->m_intr_size);
10456		return (DDI_FAILURE);
10457	}
10458
10459	/* use interrupt count returned or abort? */
10460	if (actual < count) {
10461		mptsas_log(mpt, CE_NOTE, "Requested: %d, Received: %d\n",
10462		    count, actual);
10463	}
10464
10465	mpt->m_intr_cnt = actual;
10466
10467	/*
10468	 * Get priority for first msi, assume remaining are all the same
10469	 */
10470	if ((ret = ddi_intr_get_pri(mpt->m_htable[0],
10471	    &mpt->m_intr_pri)) != DDI_SUCCESS) {
10472		mptsas_log(mpt, CE_WARN, "ddi_intr_get_pri() failed %d\n", ret);
10473
10474		/* Free already allocated intr */
10475		for (i = 0; i < actual; i++) {
10476			(void) ddi_intr_free(mpt->m_htable[i]);
10477		}
10478
10479		kmem_free(mpt->m_htable, mpt->m_intr_size);
10480		return (DDI_FAILURE);
10481	}
10482
10483	/* Test for high level mutex */
10484	if (mpt->m_intr_pri >= ddi_intr_get_hilevel_pri()) {
10485		mptsas_log(mpt, CE_WARN, "mptsas_add_intrs: "
10486		    "Hi level interrupt not supported\n");
10487
10488		/* Free already allocated intr */
10489		for (i = 0; i < actual; i++) {
10490			(void) ddi_intr_free(mpt->m_htable[i]);
10491		}
10492
10493		kmem_free(mpt->m_htable, mpt->m_intr_size);
10494		return (DDI_FAILURE);
10495	}
10496
10497	/* Call ddi_intr_add_handler() */
10498	for (i = 0; i < actual; i++) {
10499		if ((ret = ddi_intr_add_handler(mpt->m_htable[i], mptsas_intr,
10500		    (caddr_t)mpt, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) {
10501			mptsas_log(mpt, CE_WARN, "ddi_intr_add_handler() "
10502			    "failed %d\n", ret);
10503
10504			/* Free already allocated intr */
10505			for (i = 0; i < actual; i++) {
10506				(void) ddi_intr_free(mpt->m_htable[i]);
10507			}
10508
10509			kmem_free(mpt->m_htable, mpt->m_intr_size);
10510			return (DDI_FAILURE);
10511		}
10512	}
10513
10514	if ((ret = ddi_intr_get_cap(mpt->m_htable[0], &mpt->m_intr_cap))
10515	    != DDI_SUCCESS) {
10516		mptsas_log(mpt, CE_WARN, "ddi_intr_get_cap() failed %d\n", ret);
10517
10518		/* Free already allocated intr */
10519		for (i = 0; i < actual; i++) {
10520			(void) ddi_intr_free(mpt->m_htable[i]);
10521		}
10522
10523		kmem_free(mpt->m_htable, mpt->m_intr_size);
10524		return (DDI_FAILURE);
10525	}
10526
10527	return (DDI_SUCCESS);
10528}
10529
10530/*
10531 * mptsas_rem_intrs:
10532 *
10533 * Unregister FIXED or MSI interrupts
10534 */
10535static void
10536mptsas_rem_intrs(mptsas_t *mpt)
10537{
10538	int	i;
10539
10540	NDBG6(("mptsas_rem_intrs"));
10541
10542	/* Disable all interrupts */
10543	if (mpt->m_intr_cap & DDI_INTR_FLAG_BLOCK) {
10544		/* Call ddi_intr_block_disable() */
10545		(void) ddi_intr_block_disable(mpt->m_htable, mpt->m_intr_cnt);
10546	} else {
10547		for (i = 0; i < mpt->m_intr_cnt; i++) {
10548			(void) ddi_intr_disable(mpt->m_htable[i]);
10549		}
10550	}
10551
10552	/* Call ddi_intr_remove_handler() */
10553	for (i = 0; i < mpt->m_intr_cnt; i++) {
10554		(void) ddi_intr_remove_handler(mpt->m_htable[i]);
10555		(void) ddi_intr_free(mpt->m_htable[i]);
10556	}
10557
10558	kmem_free(mpt->m_htable, mpt->m_intr_size);
10559}
10560
10561/*
10562 * The IO fault service error handling callback function
10563 */
10564/*ARGSUSED*/
10565static int
10566mptsas_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
10567{
10568	/*
10569	 * as the driver can always deal with an error in any dma or
10570	 * access handle, we can just return the fme_status value.
10571	 */
10572	pci_ereport_post(dip, err, NULL);
10573	return (err->fme_status);
10574}
10575
10576/*
10577 * mptsas_fm_init - initialize fma capabilities and register with IO
10578 *               fault services.
10579 */
10580static void
10581mptsas_fm_init(mptsas_t *mpt)
10582{
10583	/*
10584	 * Need to change iblock to priority for new MSI intr
10585	 */
10586	ddi_iblock_cookie_t	fm_ibc;
10587
10588	/* Only register with IO Fault Services if we have some capability */
10589	if (mpt->m_fm_capabilities) {
10590		/* Adjust access and dma attributes for FMA */
10591		mpt->m_dev_acc_attr.devacc_attr_access |= DDI_FLAGERR_ACC;
10592		mpt->m_msg_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
10593		mpt->m_io_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
10594
10595		/*
10596		 * Register capabilities with IO Fault Services.
10597		 * mpt->m_fm_capabilities will be updated to indicate
10598		 * capabilities actually supported (not requested.)
10599		 */
10600		ddi_fm_init(mpt->m_dip, &mpt->m_fm_capabilities, &fm_ibc);
10601
10602		/*
10603		 * Initialize pci ereport capabilities if ereport
10604		 * capable (should always be.)
10605		 */
10606		if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) ||
10607		    DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
10608			pci_ereport_setup(mpt->m_dip);
10609		}
10610
10611		/*
10612		 * Register error callback if error callback capable.
10613		 */
10614		if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
10615			ddi_fm_handler_register(mpt->m_dip,
10616			    mptsas_fm_error_cb, (void *) mpt);
10617		}
10618	}
10619}
10620
10621/*
10622 * mptsas_fm_fini - Releases fma capabilities and un-registers with IO
10623 *               fault services.
10624 *
10625 */
10626static void
10627mptsas_fm_fini(mptsas_t *mpt)
10628{
10629	/* Only unregister FMA capabilities if registered */
10630	if (mpt->m_fm_capabilities) {
10631
10632		/*
10633		 * Un-register error callback if error callback capable.
10634		 */
10635
10636		if (DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
10637			ddi_fm_handler_unregister(mpt->m_dip);
10638		}
10639
10640		/*
10641		 * Release any resources allocated by pci_ereport_setup()
10642		 */
10643
10644		if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities) ||
10645		    DDI_FM_ERRCB_CAP(mpt->m_fm_capabilities)) {
10646			pci_ereport_teardown(mpt->m_dip);
10647		}
10648
10649		/* Unregister from IO Fault Services */
10650		ddi_fm_fini(mpt->m_dip);
10651
10652		/* Adjust access and dma attributes for FMA */
10653		mpt->m_dev_acc_attr.devacc_attr_access &= ~DDI_FLAGERR_ACC;
10654		mpt->m_msg_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
10655		mpt->m_io_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
10656
10657	}
10658}
10659
10660int
10661mptsas_check_acc_handle(ddi_acc_handle_t handle)
10662{
10663	ddi_fm_error_t	de;
10664
10665	if (handle == NULL)
10666		return (DDI_FAILURE);
10667	ddi_fm_acc_err_get(handle, &de, DDI_FME_VER0);
10668	return (de.fme_status);
10669}
10670
10671int
10672mptsas_check_dma_handle(ddi_dma_handle_t handle)
10673{
10674	ddi_fm_error_t	de;
10675
10676	if (handle == NULL)
10677		return (DDI_FAILURE);
10678	ddi_fm_dma_err_get(handle, &de, DDI_FME_VER0);
10679	return (de.fme_status);
10680}
10681
10682void
10683mptsas_fm_ereport(mptsas_t *mpt, char *detail)
10684{
10685	uint64_t	ena;
10686	char		buf[FM_MAX_CLASS];
10687
10688	(void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
10689	ena = fm_ena_generate(0, FM_ENA_FMT1);
10690	if (DDI_FM_EREPORT_CAP(mpt->m_fm_capabilities)) {
10691		ddi_fm_ereport_post(mpt->m_dip, buf, ena, DDI_NOSLEEP,
10692		    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERS0, NULL);
10693	}
10694}
10695
10696static int
10697mptsas_get_target_device_info(mptsas_t *mpt, uint32_t page_address,
10698    uint16_t *dev_handle, mptsas_target_t **pptgt)
10699{
10700	int		rval;
10701	uint32_t	dev_info;
10702	uint64_t	sas_wwn;
10703	uint8_t		physport, phymask;
10704	uint8_t		phynum, config, disk;
10705	mptsas_slots_t	*slots = mpt->m_active;
10706	uint64_t		devicename;
10707	mptsas_target_t		*tmp_tgt = NULL;
10708
10709	ASSERT(*pptgt == NULL);
10710
10711	rval = mptsas_get_sas_device_page0(mpt, page_address, dev_handle,
10712	    &sas_wwn, &dev_info, &physport, &phynum);
10713	if (rval != DDI_SUCCESS) {
10714		rval = DEV_INFO_FAIL_PAGE0;
10715		return (rval);
10716	}
10717
10718	if ((dev_info & (MPI2_SAS_DEVICE_INFO_SSP_TARGET |
10719	    MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
10720	    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) == NULL) {
10721		rval = DEV_INFO_WRONG_DEVICE_TYPE;
10722		return (rval);
10723	}
10724
10725	/*
10726	 * Get SATA Device Name from SAS device page0 for
10727	 * sata device, if device name doesn't exist, set m_sas_wwn to
10728	 * 0 for direct attached SATA. For the device behind the expander
10729	 * we still can use STP address assigned by expander.
10730	 */
10731	if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
10732	    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
10733		mutex_exit(&mpt->m_mutex);
10734		/* alloc a tmp_tgt to send the cmd */
10735		tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target),
10736		    KM_SLEEP);
10737		tmp_tgt->m_devhdl = *dev_handle;
10738		tmp_tgt->m_deviceinfo = dev_info;
10739		tmp_tgt->m_qfull_retries = QFULL_RETRIES;
10740		tmp_tgt->m_qfull_retry_interval =
10741		    drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
10742		tmp_tgt->m_t_throttle = MAX_THROTTLE;
10743		devicename = mptsas_get_sata_guid(mpt, tmp_tgt, 0);
10744		kmem_free(tmp_tgt, sizeof (struct mptsas_target));
10745		mutex_enter(&mpt->m_mutex);
10746		if (devicename != 0 && (((devicename >> 56) & 0xf0) == 0x50)) {
10747			sas_wwn = devicename;
10748		} else if (dev_info & MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH) {
10749			sas_wwn = 0;
10750		}
10751	}
10752
10753	/*
10754	 * Check if the dev handle is for a Phys Disk. If so, set return value
10755	 * and exit.  Don't add Phys Disks to hash.
10756	 */
10757	for (config = 0; config < slots->m_num_raid_configs; config++) {
10758		for (disk = 0; disk < MPTSAS_MAX_DISKS_IN_CONFIG; disk++) {
10759			if (*dev_handle == slots->m_raidconfig[config].
10760			    m_physdisk_devhdl[disk]) {
10761				rval = DEV_INFO_PHYS_DISK;
10762				return (rval);
10763			}
10764		}
10765	}
10766
10767	phymask = mptsas_physport_to_phymask(mpt, physport);
10768	*pptgt = mptsas_tgt_alloc(&slots->m_tgttbl, *dev_handle, sas_wwn,
10769	    dev_info, phymask, phynum);
10770	if (*pptgt == NULL) {
10771		mptsas_log(mpt, CE_WARN, "Failed to allocated target"
10772		    "structure!");
10773		rval = DEV_INFO_FAIL_ALLOC;
10774		return (rval);
10775	}
10776	return (DEV_INFO_SUCCESS);
10777}
10778
10779uint64_t
10780mptsas_get_sata_guid(mptsas_t *mpt, mptsas_target_t *ptgt, int lun)
10781{
10782	uint64_t	sata_guid = 0, *pwwn = NULL;
10783	int		target = ptgt->m_devhdl;
10784	uchar_t		*inq83 = NULL;
10785	int		inq83_len = 0xFF;
10786	uchar_t		*dblk = NULL;
10787	int		inq83_retry = 3;
10788	int		rval = DDI_FAILURE;
10789
10790	inq83	= kmem_zalloc(inq83_len, KM_SLEEP);
10791
10792inq83_retry:
10793	rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83,
10794	    inq83_len, NULL, 1);
10795	if (rval != DDI_SUCCESS) {
10796		mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
10797		    "0x83 for target:%x, lun:%x failed!", target, lun);
10798		goto out;
10799	}
10800	/* According to SAT2, the first descriptor is logic unit name */
10801	dblk = &inq83[4];
10802	if ((dblk[1] & 0x30) != 0) {
10803		mptsas_log(mpt, CE_WARN, "!Descriptor is not lun associated.");
10804		goto out;
10805	}
10806	pwwn = (uint64_t *)(void *)(&dblk[4]);
10807	if ((dblk[4] & 0xf0) == 0x50) {
10808		sata_guid = BE_64(*pwwn);
10809		goto out;
10810	} else if (dblk[4] == 'A') {
10811		NDBG20(("SATA drive has no NAA format GUID."));
10812		goto out;
10813	} else {
10814		/* The data is not ready, wait and retry */
10815		inq83_retry--;
10816		if (inq83_retry <= 0) {
10817			goto out;
10818		}
10819		NDBG20(("The GUID is not ready, retry..."));
10820		delay(1 * drv_usectohz(1000000));
10821		goto inq83_retry;
10822	}
10823out:
10824	kmem_free(inq83, inq83_len);
10825	return (sata_guid);
10826}
10827static int
10828mptsas_inquiry(mptsas_t *mpt, mptsas_target_t *ptgt, int lun, uchar_t page,
10829    unsigned char *buf, int len, int *reallen, uchar_t evpd)
10830{
10831	uchar_t			cdb[CDB_GROUP0];
10832	struct scsi_address	ap;
10833	struct buf		*data_bp = NULL;
10834	int			resid = 0;
10835	int			ret = DDI_FAILURE;
10836
10837	ASSERT(len <= 0xffff);
10838
10839	ap.a_target = MPTSAS_INVALID_DEVHDL;
10840	ap.a_lun = (uchar_t)(lun);
10841	ap.a_hba_tran = mpt->m_tran;
10842
10843	data_bp = scsi_alloc_consistent_buf(&ap,
10844	    (struct buf *)NULL, len, B_READ, NULL_FUNC, NULL);
10845	if (data_bp == NULL) {
10846		return (ret);
10847	}
10848	bzero(cdb, CDB_GROUP0);
10849	cdb[0] = SCMD_INQUIRY;
10850	cdb[1] = evpd;
10851	cdb[2] = page;
10852	cdb[3] = (len & 0xff00) >> 8;
10853	cdb[4] = (len & 0x00ff);
10854	cdb[5] = 0;
10855
10856	ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP0, data_bp,
10857	    &resid);
10858	if (ret == DDI_SUCCESS) {
10859		if (reallen) {
10860			*reallen = len - resid;
10861		}
10862		bcopy((caddr_t)data_bp->b_un.b_addr, buf, len);
10863	}
10864	if (data_bp) {
10865		scsi_free_consistent_buf(data_bp);
10866	}
10867	return (ret);
10868}
10869
10870static int
10871mptsas_send_scsi_cmd(mptsas_t *mpt, struct scsi_address *ap,
10872    mptsas_target_t *ptgt, uchar_t *cdb, int cdblen, struct buf *data_bp,
10873    int *resid)
10874{
10875	struct scsi_pkt		*pktp = NULL;
10876	scsi_hba_tran_t		*tran_clone = NULL;
10877	mptsas_tgt_private_t	*tgt_private = NULL;
10878	int			ret = DDI_FAILURE;
10879
10880	/*
10881	 * scsi_hba_tran_t->tran_tgt_private is used to pass the address
10882	 * information to scsi_init_pkt, allocate a scsi_hba_tran structure
10883	 * to simulate the cmds from sd
10884	 */
10885	tran_clone = kmem_alloc(
10886	    sizeof (scsi_hba_tran_t), KM_SLEEP);
10887	if (tran_clone == NULL) {
10888		goto out;
10889	}
10890	bcopy((caddr_t)mpt->m_tran,
10891	    (caddr_t)tran_clone, sizeof (scsi_hba_tran_t));
10892	tgt_private = kmem_alloc(
10893	    sizeof (mptsas_tgt_private_t), KM_SLEEP);
10894	if (tgt_private == NULL) {
10895		goto out;
10896	}
10897	tgt_private->t_lun = ap->a_lun;
10898	tgt_private->t_private = ptgt;
10899	tran_clone->tran_tgt_private = tgt_private;
10900	ap->a_hba_tran = tran_clone;
10901
10902	pktp = scsi_init_pkt(ap, (struct scsi_pkt *)NULL,
10903	    data_bp, cdblen, sizeof (struct scsi_arq_status),
10904	    0, PKT_CONSISTENT, NULL, NULL);
10905	if (pktp == NULL) {
10906		goto out;
10907	}
10908	bcopy(cdb, pktp->pkt_cdbp, cdblen);
10909	pktp->pkt_flags = FLAG_NOPARITY;
10910	if (scsi_poll(pktp) < 0) {
10911		goto out;
10912	}
10913	if (((struct scsi_status *)pktp->pkt_scbp)->sts_chk) {
10914		goto out;
10915	}
10916	if (resid != NULL) {
10917		*resid = pktp->pkt_resid;
10918	}
10919
10920	ret = DDI_SUCCESS;
10921out:
10922	if (pktp) {
10923		scsi_destroy_pkt(pktp);
10924	}
10925	if (tran_clone) {
10926		kmem_free(tran_clone, sizeof (scsi_hba_tran_t));
10927	}
10928	if (tgt_private) {
10929		kmem_free(tgt_private, sizeof (mptsas_tgt_private_t));
10930	}
10931	return (ret);
10932}
10933static int
10934mptsas_parse_address(char *name, uint64_t *wwid, uint8_t *phy, int *lun)
10935{
10936	char	*cp = NULL;
10937	char	*ptr = NULL;
10938	size_t	s = 0;
10939	char	*wwid_str = NULL;
10940	char	*lun_str = NULL;
10941	long	lunnum;
10942	long	phyid = -1;
10943	int	rc = DDI_FAILURE;
10944
10945	ptr = name;
10946	ASSERT(ptr[0] == 'w' || ptr[0] == 'p');
10947	ptr++;
10948	if ((cp = strchr(ptr, ',')) == NULL) {
10949		return (DDI_FAILURE);
10950	}
10951
10952	wwid_str = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
10953	s = (uintptr_t)cp - (uintptr_t)ptr;
10954
10955	bcopy(ptr, wwid_str, s);
10956	wwid_str[s] = '\0';
10957
10958	ptr = ++cp;
10959
10960	if ((cp = strchr(ptr, '\0')) == NULL) {
10961		goto out;
10962	}
10963	lun_str =  kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
10964	s = (uintptr_t)cp - (uintptr_t)ptr;
10965
10966	bcopy(ptr, lun_str, s);
10967	lun_str[s] = '\0';
10968
10969	if (name[0] == 'p') {
10970		rc = ddi_strtol(wwid_str, NULL, 0x10, &phyid);
10971	} else {
10972		rc = scsi_wwnstr_to_wwn(wwid_str, wwid);
10973	}
10974	if (rc != DDI_SUCCESS)
10975		goto out;
10976
10977	if (phyid != -1) {
10978		ASSERT(phyid < 8);
10979		*phy = (uint8_t)phyid;
10980	}
10981	rc = ddi_strtol(lun_str, NULL, 0x10, &lunnum);
10982	if (rc != 0)
10983		goto out;
10984
10985	*lun = (int)lunnum;
10986	rc = DDI_SUCCESS;
10987out:
10988	if (wwid_str)
10989		kmem_free(wwid_str, SCSI_MAXNAMELEN);
10990	if (lun_str)
10991		kmem_free(lun_str, SCSI_MAXNAMELEN);
10992
10993	return (rc);
10994}
10995
10996/*
10997 * mptsas_parse_smp_name() is to parse sas wwn string
10998 * which format is "wWWN"
10999 */
11000static int
11001mptsas_parse_smp_name(char *name, uint64_t *wwn)
11002{
11003	char	*ptr = name;
11004
11005	if (*ptr != 'w') {
11006		return (DDI_FAILURE);
11007	}
11008
11009	ptr++;
11010	if (scsi_wwnstr_to_wwn(ptr, wwn)) {
11011		return (DDI_FAILURE);
11012	}
11013	return (DDI_SUCCESS);
11014}
11015
11016static int
11017mptsas_bus_config(dev_info_t *pdip, uint_t flag,
11018    ddi_bus_config_op_t op, void *arg, dev_info_t **childp)
11019{
11020	int		ret = NDI_FAILURE;
11021	int		circ = 0;
11022	int		circ1 = 0;
11023	mptsas_t	*mpt;
11024	char		*ptr = NULL;
11025	char		*devnm = NULL;
11026	uint64_t	wwid = 0;
11027	uint8_t		phy = 0xFF;
11028	int		lun = 0;
11029	uint_t		mflags = flag;
11030
11031	if (scsi_hba_iport_unit_address(pdip) == 0) {
11032		return (DDI_FAILURE);
11033	}
11034
11035	mpt = DIP2MPT(pdip);
11036	if (!mpt) {
11037		return (DDI_FAILURE);
11038	}
11039
11040	/*
11041	 * Hold the nexus across the bus_config
11042	 */
11043	ndi_devi_enter(scsi_vhci_dip, &circ);
11044	ndi_devi_enter(pdip, &circ1);
11045	switch (op) {
11046	case BUS_CONFIG_ONE:
11047		/* parse wwid/target name out of name given */
11048		if ((ptr = strchr((char *)arg, '@')) == NULL) {
11049			ret = NDI_FAILURE;
11050			break;
11051		}
11052		ptr++;
11053		if (strncmp((char *)arg, "smp", 3) == 0) {
11054			/*
11055			 * This is a SMP target device
11056			 */
11057			ret = mptsas_parse_smp_name(ptr, &wwid);
11058			if (ret != DDI_SUCCESS) {
11059				ret = NDI_FAILURE;
11060				break;
11061			}
11062			ret = mptsas_config_smp(pdip, wwid, childp);
11063		} else if ((ptr[0] == 'w') || (ptr[0] == 'p')) {
11064			/*
11065			 * OBP could pass down a non-canonical form
11066			 * bootpath without LUN part when LUN is 0.
11067			 * So driver need adjust the string.
11068			 */
11069			if (strchr(ptr, ',') == NULL) {
11070				devnm = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
11071				(void) sprintf(devnm, "%s,0", (char *)arg);
11072				ptr = strchr(devnm, '@');
11073				ptr++;
11074			}
11075
11076			/*
11077			 * The device path is wWWID format and the device
11078			 * is not SMP target device.
11079			 */
11080			ret = mptsas_parse_address(ptr, &wwid, &phy, &lun);
11081			if (ret != DDI_SUCCESS) {
11082				ret = NDI_FAILURE;
11083				break;
11084			}
11085			if (ptr[0] == 'w') {
11086				ret = mptsas_config_one_addr(pdip, wwid,
11087				    lun, childp);
11088			} else if (ptr[0] == 'p') {
11089				ret = mptsas_config_one_phy(pdip, phy, lun,
11090				    childp);
11091			}
11092		} else {
11093			ret = NDI_FAILURE;
11094			break;
11095		}
11096
11097		/*
11098		 * DDI group instructed us to use this flag.
11099		 */
11100		mflags |= NDI_MDI_FALLBACK;
11101		break;
11102	case BUS_CONFIG_DRIVER:
11103	case BUS_CONFIG_ALL:
11104		mptsas_config_all(pdip);
11105		ret = NDI_SUCCESS;
11106		break;
11107	}
11108
11109	if (ret == NDI_SUCCESS) {
11110		ret = ndi_busop_bus_config(pdip, mflags, op,
11111		    (devnm == NULL) ? arg : devnm, childp, 0);
11112	}
11113
11114	ndi_devi_exit(pdip, circ1);
11115	ndi_devi_exit(scsi_vhci_dip, circ);
11116	if (devnm != NULL)
11117		kmem_free(devnm, SCSI_MAXNAMELEN);
11118	return (ret);
11119}
11120
11121static int
11122mptsas_probe_lun(dev_info_t *pdip, int lun, dev_info_t **dip,
11123    mptsas_target_t *ptgt)
11124{
11125	int			rval = DDI_FAILURE;
11126	struct scsi_inquiry	*sd_inq = NULL;
11127	mptsas_t		*mpt = DIP2MPT(pdip);
11128
11129	sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP);
11130
11131	rval = mptsas_inquiry(mpt, ptgt, lun, 0, (uchar_t *)sd_inq,
11132	    SUN_INQSIZE, 0, (uchar_t)0);
11133
11134	if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) {
11135		rval = mptsas_create_lun(pdip, sd_inq, dip, ptgt, lun);
11136	} else {
11137		rval = DDI_FAILURE;
11138	}
11139out:
11140	kmem_free(sd_inq, SUN_INQSIZE);
11141	return (rval);
11142}
11143
11144static int
11145mptsas_config_one_addr(dev_info_t *pdip, uint64_t sasaddr, int lun,
11146    dev_info_t **lundip)
11147{
11148	int		rval;
11149	mptsas_t		*mpt = DIP2MPT(pdip);
11150	int		phymask;
11151	mptsas_target_t	*ptgt = NULL;
11152
11153	/*
11154	 * Get the physical port associated to the iport
11155	 */
11156	phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
11157	    "phymask", 0);
11158
11159	ptgt = mptsas_wwid_to_ptgt(mpt, phymask, sasaddr);
11160	if (ptgt == NULL) {
11161		/*
11162		 * didn't match any device by searching
11163		 */
11164		return (DDI_FAILURE);
11165	}
11166	/*
11167	 * If the LUN already exists and the status is online,
11168	 * we just return the pointer to dev_info_t directly.
11169	 * For the mdi_pathinfo node, we'll handle it in
11170	 * mptsas_create_virt_lun()
11171	 * TODO should be also in mptsas_handle_dr
11172	 */
11173
11174	*lundip = mptsas_find_child_addr(pdip, sasaddr, lun);
11175	if (*lundip != NULL) {
11176		/*
11177		 * TODO Another senario is, we hotplug the same disk
11178		 * on the same slot, the devhdl changed, is this
11179		 * possible?
11180		 * tgt_private->t_private != ptgt
11181		 */
11182		if (sasaddr != ptgt->m_sas_wwn) {
11183			/*
11184			 * The device has changed although the devhdl is the
11185			 * same (Enclosure mapping mode, change drive on the
11186			 * same slot)
11187			 */
11188			return (DDI_FAILURE);
11189		}
11190		return (DDI_SUCCESS);
11191	}
11192
11193	if (phymask == 0) {
11194		/*
11195		 * Configure IR volume
11196		 */
11197		rval =  mptsas_config_raid(pdip, ptgt->m_devhdl, lundip);
11198		return (rval);
11199	}
11200	rval = mptsas_probe_lun(pdip, lun, lundip, ptgt);
11201
11202	return (rval);
11203}
11204
11205static int
11206mptsas_config_one_phy(dev_info_t *pdip, uint8_t phy, int lun,
11207    dev_info_t **lundip)
11208{
11209	int		rval;
11210	mptsas_target_t	*ptgt = NULL;
11211
11212	ptgt = mptsas_phy_to_tgt(pdip, phy);
11213	if (ptgt == NULL) {
11214		/*
11215		 * didn't match any device by searching
11216		 */
11217		return (DDI_FAILURE);
11218	}
11219
11220	/*
11221	 * If the LUN already exists and the status is online,
11222	 * we just return the pointer to dev_info_t directly.
11223	 * For the mdi_pathinfo node, we'll handle it in
11224	 * mptsas_create_virt_lun().
11225	 */
11226
11227	*lundip = mptsas_find_child_phy(pdip, phy);
11228	if (*lundip != NULL) {
11229		return (DDI_SUCCESS);
11230	}
11231
11232	rval = mptsas_probe_lun(pdip, lun, lundip, ptgt);
11233
11234	return (rval);
11235}
11236
11237static int
11238mptsas_retrieve_lundata(int lun_cnt, uint8_t *buf, uint16_t *lun_num,
11239    uint8_t *lun_addr_type)
11240{
11241	uint32_t	lun_idx = 0;
11242
11243	ASSERT(lun_num != NULL);
11244	ASSERT(lun_addr_type != NULL);
11245
11246	lun_idx = (lun_cnt + 1) * MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE;
11247	/* determine report luns addressing type */
11248	switch (buf[lun_idx] & MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) {
11249		/*
11250		 * Vendors in the field have been found to be concatenating
11251		 * bus/target/lun to equal the complete lun value instead
11252		 * of switching to flat space addressing
11253		 */
11254		/* 00b - peripheral device addressing method */
11255	case MPTSAS_SCSI_REPORTLUNS_ADDRESS_PERIPHERAL:
11256		/* FALLTHRU */
11257		/* 10b - logical unit addressing method */
11258	case MPTSAS_SCSI_REPORTLUNS_ADDRESS_LOGICAL_UNIT:
11259		/* FALLTHRU */
11260		/* 01b - flat space addressing method */
11261	case MPTSAS_SCSI_REPORTLUNS_ADDRESS_FLAT_SPACE:
11262		/* byte0 bit0-5=msb lun byte1 bit0-7=lsb lun */
11263		*lun_addr_type = (buf[lun_idx] &
11264		    MPTSAS_SCSI_REPORTLUNS_ADDRESS_MASK) >> 6;
11265		*lun_num = (buf[lun_idx] & 0x3F) << 8;
11266		*lun_num |= buf[lun_idx + 1];
11267		return (DDI_SUCCESS);
11268	default:
11269		return (DDI_FAILURE);
11270	}
11271}
11272
11273static int
11274mptsas_config_luns(dev_info_t *pdip, mptsas_target_t *ptgt)
11275{
11276	struct buf		*repluns_bp = NULL;
11277	struct scsi_address	ap;
11278	uchar_t			cdb[CDB_GROUP5];
11279	int			ret = DDI_FAILURE;
11280	int			retry = 0;
11281	int			lun_list_len = 0;
11282	uint16_t		lun_num = 0;
11283	uint8_t			lun_addr_type = 0;
11284	uint32_t		lun_cnt = 0;
11285	uint32_t		lun_total = 0;
11286	dev_info_t		*cdip = NULL;
11287	uint16_t		*saved_repluns = NULL;
11288	char			*buffer = NULL;
11289	int			buf_len = 128;
11290	mptsas_t		*mpt = DIP2MPT(pdip);
11291	uint64_t		sas_wwn = 0;
11292	uint8_t			phy = 0xFF;
11293	uint32_t		dev_info = 0;
11294
11295	mutex_enter(&mpt->m_mutex);
11296	sas_wwn = ptgt->m_sas_wwn;
11297	phy = ptgt->m_phynum;
11298	dev_info = ptgt->m_deviceinfo;
11299	mutex_exit(&mpt->m_mutex);
11300
11301	if (sas_wwn == 0) {
11302		/*
11303		 * It's a SATA without Device Name
11304		 * So don't try multi-LUNs
11305		 */
11306		if (mptsas_find_child_phy(pdip, phy)) {
11307			return (DDI_SUCCESS);
11308		} else {
11309			/*
11310			 * need configure and create node
11311			 */
11312			return (DDI_FAILURE);
11313		}
11314	}
11315
11316	/*
11317	 * WWN (SAS address or Device Name exist)
11318	 */
11319	if (dev_info & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
11320	    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
11321		/*
11322		 * SATA device with Device Name
11323		 * So don't try multi-LUNs
11324		 */
11325		if (mptsas_find_child_addr(pdip, sas_wwn, 0)) {
11326			return (DDI_SUCCESS);
11327		} else {
11328			return (DDI_FAILURE);
11329		}
11330	}
11331
11332	do {
11333		ap.a_target = MPTSAS_INVALID_DEVHDL;
11334		ap.a_lun = 0;
11335		ap.a_hba_tran = mpt->m_tran;
11336		repluns_bp = scsi_alloc_consistent_buf(&ap,
11337		    (struct buf *)NULL, buf_len, B_READ, NULL_FUNC, NULL);
11338		if (repluns_bp == NULL) {
11339			retry++;
11340			continue;
11341		}
11342		bzero(cdb, CDB_GROUP5);
11343		cdb[0] = SCMD_REPORT_LUNS;
11344		cdb[6] = (buf_len & 0xff000000) >> 24;
11345		cdb[7] = (buf_len & 0x00ff0000) >> 16;
11346		cdb[8] = (buf_len & 0x0000ff00) >> 8;
11347		cdb[9] = (buf_len & 0x000000ff);
11348
11349		ret = mptsas_send_scsi_cmd(mpt, &ap, ptgt, &cdb[0], CDB_GROUP5,
11350		    repluns_bp, NULL);
11351		if (ret != DDI_SUCCESS) {
11352			scsi_free_consistent_buf(repluns_bp);
11353			retry++;
11354			continue;
11355		}
11356		lun_list_len = BE_32(*(int *)((void *)(
11357		    repluns_bp->b_un.b_addr)));
11358		if (buf_len >= lun_list_len + 8) {
11359			ret = DDI_SUCCESS;
11360			break;
11361		}
11362		scsi_free_consistent_buf(repluns_bp);
11363		buf_len = lun_list_len + 8;
11364
11365	} while (retry < 3);
11366
11367	if (ret != DDI_SUCCESS)
11368		return (ret);
11369	buffer = (char *)repluns_bp->b_un.b_addr;
11370	/*
11371	 * find out the number of luns returned by the SCSI ReportLun call
11372	 * and allocate buffer space
11373	 */
11374	lun_total = lun_list_len / MPTSAS_SCSI_REPORTLUNS_ADDRESS_SIZE;
11375	saved_repluns = kmem_zalloc(sizeof (uint16_t) * lun_total, KM_SLEEP);
11376	if (saved_repluns == NULL) {
11377		scsi_free_consistent_buf(repluns_bp);
11378		return (DDI_FAILURE);
11379	}
11380	for (lun_cnt = 0; lun_cnt < lun_total; lun_cnt++) {
11381		if (mptsas_retrieve_lundata(lun_cnt, (uint8_t *)(buffer),
11382		    &lun_num, &lun_addr_type) != DDI_SUCCESS) {
11383			continue;
11384		}
11385		saved_repluns[lun_cnt] = lun_num;
11386		if (cdip = mptsas_find_child_addr(pdip, sas_wwn, lun_num))
11387			ret = DDI_SUCCESS;
11388		else
11389			ret = mptsas_probe_lun(pdip, lun_num, &cdip,
11390			    ptgt);
11391		if ((ret == DDI_SUCCESS) && (cdip != NULL)) {
11392			(void) ndi_prop_remove(DDI_DEV_T_NONE, cdip,
11393			    MPTSAS_DEV_GONE);
11394		}
11395	}
11396	mptsas_offline_missed_luns(pdip, saved_repluns, lun_total, ptgt);
11397	kmem_free(saved_repluns, sizeof (uint16_t) * lun_total);
11398	scsi_free_consistent_buf(repluns_bp);
11399	return (DDI_SUCCESS);
11400}
11401
11402static int
11403mptsas_config_raid(dev_info_t *pdip, uint16_t target, dev_info_t **dip)
11404{
11405	int			rval = DDI_FAILURE;
11406	struct scsi_inquiry	*sd_inq = NULL;
11407	mptsas_t		*mpt = DIP2MPT(pdip);
11408	mptsas_target_t		*ptgt = NULL;
11409
11410	mutex_enter(&mpt->m_mutex);
11411	ptgt = mptsas_search_by_devhdl(&mpt->m_active->m_tgttbl, target);
11412	mutex_exit(&mpt->m_mutex);
11413	if (ptgt == NULL) {
11414		mptsas_log(mpt, CE_WARN, "Volume with VolDevHandle of 0x%x "
11415		    "not found.", target);
11416		return (rval);
11417	}
11418
11419	sd_inq = (struct scsi_inquiry *)kmem_alloc(SUN_INQSIZE, KM_SLEEP);
11420	rval = mptsas_inquiry(mpt, ptgt, 0, 0, (uchar_t *)sd_inq,
11421	    SUN_INQSIZE, 0, (uchar_t)0);
11422
11423	if ((rval == DDI_SUCCESS) && MPTSAS_VALID_LUN(sd_inq)) {
11424		rval = mptsas_create_phys_lun(pdip, sd_inq, NULL, dip, ptgt,
11425		    0);
11426	} else {
11427		rval = DDI_FAILURE;
11428	}
11429
11430out:
11431	kmem_free(sd_inq, SUN_INQSIZE);
11432	return (rval);
11433}
11434
11435/*
11436 * configure all RAID volumes for virtual iport
11437 */
11438static void
11439mptsas_config_all_viport(dev_info_t *pdip)
11440{
11441	mptsas_t	*mpt = DIP2MPT(pdip);
11442	int		config, vol;
11443	int		target;
11444	dev_info_t	*lundip = NULL;
11445	mptsas_slots_t	*slots = mpt->m_active;
11446
11447	/*
11448	 * Get latest RAID info and search for any Volume DevHandles.  If any
11449	 * are found, configure the volume.
11450	 */
11451	mutex_enter(&mpt->m_mutex);
11452	for (config = 0; config < slots->m_num_raid_configs; config++) {
11453		for (vol = 0; vol < MPTSAS_MAX_RAIDVOLS; vol++) {
11454			if (slots->m_raidconfig[config].m_raidvol[vol].m_israid
11455			    == 1) {
11456				target = slots->m_raidconfig[config].
11457				    m_raidvol[vol].m_raidhandle;
11458				mutex_exit(&mpt->m_mutex);
11459				(void) mptsas_config_raid(pdip, target,
11460				    &lundip);
11461				mutex_enter(&mpt->m_mutex);
11462			}
11463		}
11464	}
11465	mutex_exit(&mpt->m_mutex);
11466}
11467
11468static void
11469mptsas_offline_missed_luns(dev_info_t *pdip, uint16_t *repluns,
11470    int lun_cnt, mptsas_target_t *ptgt)
11471{
11472	dev_info_t	*child = NULL, *savechild = NULL;
11473	mdi_pathinfo_t	*pip = NULL, *savepip = NULL;
11474	uint64_t	sas_wwn, wwid;
11475	uint8_t		phy;
11476	int		lun;
11477	int		i;
11478	int		find;
11479	char		*addr;
11480	char		*nodename;
11481	mptsas_t	*mpt = DIP2MPT(pdip);
11482
11483	mutex_enter(&mpt->m_mutex);
11484	wwid = ptgt->m_sas_wwn;
11485	mutex_exit(&mpt->m_mutex);
11486
11487	child = ddi_get_child(pdip);
11488	while (child) {
11489		find = 0;
11490		savechild = child;
11491		child = ddi_get_next_sibling(child);
11492
11493		nodename = ddi_node_name(savechild);
11494		if (strcmp(nodename, "smp") == 0) {
11495			continue;
11496		}
11497
11498		addr = ddi_get_name_addr(savechild);
11499		if (addr == NULL) {
11500			continue;
11501		}
11502
11503		if (mptsas_parse_address(addr, &sas_wwn, &phy, &lun) !=
11504		    DDI_SUCCESS) {
11505			continue;
11506		}
11507
11508		if (wwid == sas_wwn) {
11509			for (i = 0; i < lun_cnt; i++) {
11510				if (repluns[i] == lun) {
11511					find = 1;
11512					break;
11513				}
11514			}
11515		} else {
11516			continue;
11517		}
11518		if (find == 0) {
11519			/*
11520			 * The lun has not been there already
11521			 */
11522			(void) mptsas_offline_lun(pdip, savechild, NULL,
11523			    NDI_DEVI_REMOVE);
11524		}
11525	}
11526
11527	pip = mdi_get_next_client_path(pdip, NULL);
11528	while (pip) {
11529		find = 0;
11530		savepip = pip;
11531		addr = MDI_PI(pip)->pi_addr;
11532
11533		pip = mdi_get_next_client_path(pdip, pip);
11534
11535		if (addr == NULL) {
11536			continue;
11537		}
11538
11539		if (mptsas_parse_address(addr, &sas_wwn, &phy,
11540		    &lun) != DDI_SUCCESS) {
11541			continue;
11542		}
11543
11544		if (sas_wwn == wwid) {
11545			for (i = 0; i < lun_cnt; i++) {
11546				if (repluns[i] == lun) {
11547					find = 1;
11548					break;
11549				}
11550			}
11551		} else {
11552			continue;
11553		}
11554
11555		if (find == 0) {
11556			/*
11557			 * The lun has not been there already
11558			 */
11559			(void) mptsas_offline_lun(pdip, NULL, savepip,
11560			    NDI_DEVI_REMOVE);
11561		}
11562	}
11563}
11564
11565void
11566mptsas_update_hashtab(struct mptsas *mpt)
11567{
11568	uint32_t	page_address;
11569	int		rval = 0;
11570	uint16_t	dev_handle;
11571	mptsas_target_t	*ptgt = NULL;
11572	mptsas_smp_t	smp_node;
11573
11574	/*
11575	 * Get latest RAID info.
11576	 */
11577	(void) mptsas_get_raid_info(mpt);
11578
11579	dev_handle = mpt->m_smp_devhdl;
11580	for (; mpt->m_done_traverse_smp == 0; ) {
11581		page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
11582		    MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)dev_handle;
11583		if (mptsas_get_sas_expander_page0(mpt, page_address, &smp_node)
11584		    != DDI_SUCCESS) {
11585			break;
11586		}
11587		mpt->m_smp_devhdl = dev_handle = smp_node.m_devhdl;
11588		(void) mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node);
11589	}
11590
11591	/*
11592	 * Config target devices
11593	 */
11594	dev_handle = mpt->m_dev_handle;
11595
11596	/*
11597	 * Do loop to get sas device page 0 by GetNextHandle till the
11598	 * the last handle. If the sas device is a SATA/SSP target,
11599	 * we try to config it.
11600	 */
11601	for (; mpt->m_done_traverse_dev == 0; ) {
11602		ptgt = NULL;
11603		page_address =
11604		    (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
11605		    MPI2_SAS_DEVICE_PGAD_FORM_MASK) |
11606		    (uint32_t)dev_handle;
11607		rval = mptsas_get_target_device_info(mpt, page_address,
11608		    &dev_handle, &ptgt);
11609		if ((rval == DEV_INFO_FAIL_PAGE0) ||
11610		    (rval == DEV_INFO_FAIL_ALLOC)) {
11611			break;
11612		}
11613
11614		mpt->m_dev_handle = dev_handle;
11615	}
11616
11617}
11618
11619void
11620mptsas_invalid_hashtab(mptsas_hash_table_t *hashtab)
11621{
11622	mptsas_hash_data_t *data;
11623	data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST);
11624	while (data != NULL) {
11625		data->devhdl = MPTSAS_INVALID_DEVHDL;
11626		data->device_info = 0;
11627		/*
11628		 * For tgttbl, clear dr_flag.
11629		 */
11630		data->dr_flag = MPTSAS_DR_INACTIVE;
11631		data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT);
11632	}
11633}
11634
11635void
11636mptsas_update_driver_data(struct mptsas *mpt)
11637{
11638	/*
11639	 * TODO after hard reset, update the driver data structures
11640	 * 1. update port/phymask mapping table mpt->m_phy_info
11641	 * 2. invalid all the entries in hash table
11642	 *    m_devhdl = 0xffff and m_deviceinfo = 0
11643	 * 3. call sas_device_page/expander_page to update hash table
11644	 */
11645	mptsas_update_phymask(mpt);
11646	/*
11647	 * Invalid the existing entries
11648	 */
11649	mptsas_invalid_hashtab(&mpt->m_active->m_tgttbl);
11650	mptsas_invalid_hashtab(&mpt->m_active->m_smptbl);
11651	mpt->m_done_traverse_dev = 0;
11652	mpt->m_done_traverse_smp = 0;
11653	mpt->m_dev_handle = mpt->m_smp_devhdl = MPTSAS_INVALID_DEVHDL;
11654	mptsas_update_hashtab(mpt);
11655}
11656
11657static void
11658mptsas_config_all(dev_info_t *pdip)
11659{
11660	dev_info_t	*smpdip = NULL;
11661	mptsas_t	*mpt = DIP2MPT(pdip);
11662	int		phymask = 0;
11663	uint8_t		phy_mask;
11664	mptsas_target_t	*ptgt = NULL;
11665	mptsas_smp_t	*psmp;
11666
11667	/*
11668	 * Get the phymask associated to the iport
11669	 */
11670	phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
11671	    "phymask", 0);
11672
11673	/*
11674	 * Enumerate RAID volumes here (phymask == 0).
11675	 */
11676	if (phymask == 0) {
11677		mptsas_config_all_viport(pdip);
11678		return;
11679	}
11680
11681	mutex_enter(&mpt->m_mutex);
11682
11683	if (!mpt->m_done_traverse_dev || !mpt->m_done_traverse_smp) {
11684		mptsas_update_hashtab(mpt);
11685	}
11686
11687	psmp = (mptsas_smp_t *)mptsas_hash_traverse(&mpt->m_active->m_smptbl,
11688	    MPTSAS_HASH_FIRST);
11689	while (psmp != NULL) {
11690		phy_mask = psmp->m_phymask;
11691		if (phy_mask == phymask) {
11692			smpdip = NULL;
11693			mutex_exit(&mpt->m_mutex);
11694			(void) mptsas_online_smp(pdip, psmp, &smpdip);
11695			mutex_enter(&mpt->m_mutex);
11696		}
11697		psmp = (mptsas_smp_t *)mptsas_hash_traverse(
11698		    &mpt->m_active->m_smptbl, MPTSAS_HASH_NEXT);
11699	}
11700
11701	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
11702	    MPTSAS_HASH_FIRST);
11703	while (ptgt != NULL) {
11704		phy_mask = ptgt->m_phymask;
11705		if (phy_mask == phymask) {
11706			mutex_exit(&mpt->m_mutex);
11707			(void) mptsas_config_target(pdip, ptgt);
11708			mutex_enter(&mpt->m_mutex);
11709		}
11710
11711		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
11712		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
11713	}
11714	mutex_exit(&mpt->m_mutex);
11715}
11716
11717static int
11718mptsas_config_target(dev_info_t *pdip, mptsas_target_t *ptgt)
11719{
11720	int		rval = DDI_FAILURE;
11721	dev_info_t	*tdip;
11722
11723	rval = mptsas_config_luns(pdip, ptgt);
11724	if (rval != DDI_SUCCESS) {
11725		/*
11726		 * The return value means the SCMD_REPORT_LUNS
11727		 * did not execute successfully. The target maybe
11728		 * doesn't support such command.
11729		 */
11730		rval = mptsas_probe_lun(pdip, 0, &tdip, ptgt);
11731	}
11732	return (rval);
11733}
11734
11735/*
11736 * Return fail if not all the childs/paths are freed.
11737 * if there is any path under the HBA, the return value will be always fail
11738 * because we didn't call mdi_pi_free for path
11739 */
11740static int
11741mptsas_offline_target(dev_info_t *pdip, char *name)
11742{
11743	dev_info_t		*child = NULL, *prechild = NULL;
11744	mdi_pathinfo_t		*pip = NULL, *savepip = NULL;
11745	int			tmp_rval, rval = DDI_SUCCESS;
11746	char			*addr, *cp;
11747	size_t			s;
11748	mptsas_t		*mpt = DIP2MPT(pdip);
11749
11750	child = ddi_get_child(pdip);
11751	while (child) {
11752		addr = ddi_get_name_addr(child);
11753		prechild = child;
11754		child = ddi_get_next_sibling(child);
11755
11756		if (addr == NULL) {
11757			continue;
11758		}
11759		if ((cp = strchr(addr, ',')) == NULL) {
11760			continue;
11761		}
11762
11763		s = (uintptr_t)cp - (uintptr_t)addr;
11764
11765		if (strncmp(addr, name, s) != 0) {
11766			continue;
11767		}
11768
11769		tmp_rval = mptsas_offline_lun(pdip, prechild, NULL,
11770		    NDI_DEVI_REMOVE);
11771		if (tmp_rval != DDI_SUCCESS) {
11772			rval = DDI_FAILURE;
11773			if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
11774			    prechild, MPTSAS_DEV_GONE) !=
11775			    DDI_PROP_SUCCESS) {
11776				mptsas_log(mpt, CE_WARN, "mptsas driver "
11777				    "unable to create property for "
11778				    "SAS %s (MPTSAS_DEV_GONE)", addr);
11779			}
11780		}
11781	}
11782
11783	pip = mdi_get_next_client_path(pdip, NULL);
11784	while (pip) {
11785		addr = MDI_PI(pip)->pi_addr;
11786		savepip = pip;
11787		pip = mdi_get_next_client_path(pdip, pip);
11788		if (addr == NULL) {
11789			continue;
11790		}
11791
11792		if ((cp = strchr(addr, ',')) == NULL) {
11793			continue;
11794		}
11795
11796		s = (uintptr_t)cp - (uintptr_t)addr;
11797
11798		if (strncmp(addr, name, s) != 0) {
11799			continue;
11800		}
11801
11802		(void) mptsas_offline_lun(pdip, NULL, savepip,
11803		    NDI_DEVI_REMOVE);
11804		/*
11805		 * driver will not invoke mdi_pi_free, so path will not
11806		 * be freed forever, return DDI_FAILURE.
11807		 */
11808		rval = DDI_FAILURE;
11809	}
11810	return (rval);
11811}
11812
11813static int
11814mptsas_offline_lun(dev_info_t *pdip, dev_info_t *rdip,
11815    mdi_pathinfo_t *rpip, uint_t flags)
11816{
11817	int		rval = DDI_FAILURE;
11818	char		*devname;
11819	dev_info_t	*cdip, *parent;
11820
11821	if (rpip != NULL) {
11822		parent = scsi_vhci_dip;
11823		cdip = mdi_pi_get_client(rpip);
11824	} else if (rdip != NULL) {
11825		parent = pdip;
11826		cdip = rdip;
11827	} else {
11828		return (DDI_FAILURE);
11829	}
11830
11831	/*
11832	 * Make sure node is attached otherwise
11833	 * it won't have related cache nodes to
11834	 * clean up.  i_ddi_devi_attached is
11835	 * similiar to i_ddi_node_state(cdip) >=
11836	 * DS_ATTACHED.
11837	 */
11838	if (i_ddi_devi_attached(cdip)) {
11839
11840		/* Get full devname */
11841		devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
11842		(void) ddi_deviname(cdip, devname);
11843		/* Clean cache */
11844		(void) devfs_clean(parent, devname + 1,
11845		    DV_CLEAN_FORCE);
11846		kmem_free(devname, MAXNAMELEN + 1);
11847	}
11848	if (rpip != NULL) {
11849		if (MDI_PI_IS_OFFLINE(rpip)) {
11850			rval = DDI_SUCCESS;
11851		} else {
11852			rval = mdi_pi_offline(rpip, 0);
11853		}
11854	} else {
11855		rval = ndi_devi_offline(cdip, flags);
11856	}
11857
11858	return (rval);
11859}
11860
11861static dev_info_t *
11862mptsas_find_smp_child(dev_info_t *parent, char *str_wwn)
11863{
11864	dev_info_t	*child = NULL;
11865	char		*smp_wwn = NULL;
11866
11867	child = ddi_get_child(parent);
11868	while (child) {
11869		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
11870		    DDI_PROP_DONTPASS, SMP_WWN, &smp_wwn)
11871		    != DDI_SUCCESS) {
11872			child = ddi_get_next_sibling(child);
11873			continue;
11874		}
11875
11876		if (strcmp(smp_wwn, str_wwn) == 0) {
11877			ddi_prop_free(smp_wwn);
11878			break;
11879		}
11880		child = ddi_get_next_sibling(child);
11881		ddi_prop_free(smp_wwn);
11882	}
11883	return (child);
11884}
11885
11886static int
11887mptsas_offline_smp(dev_info_t *pdip, mptsas_smp_t *smp_node, uint_t flags)
11888{
11889	int		rval = DDI_FAILURE;
11890	char		*devname;
11891	char		wwn_str[MPTSAS_WWN_STRLEN];
11892	dev_info_t	*cdip;
11893
11894	(void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr);
11895
11896	cdip = mptsas_find_smp_child(pdip, wwn_str);
11897
11898	if (cdip == NULL)
11899		return (DDI_SUCCESS);
11900
11901	/*
11902	 * Make sure node is attached otherwise
11903	 * it won't have related cache nodes to
11904	 * clean up.  i_ddi_devi_attached is
11905	 * similiar to i_ddi_node_state(cdip) >=
11906	 * DS_ATTACHED.
11907	 */
11908	if (i_ddi_devi_attached(cdip)) {
11909
11910		/* Get full devname */
11911		devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP);
11912		(void) ddi_deviname(cdip, devname);
11913		/* Clean cache */
11914		(void) devfs_clean(pdip, devname + 1,
11915		    DV_CLEAN_FORCE);
11916		kmem_free(devname, MAXNAMELEN + 1);
11917	}
11918
11919	rval = ndi_devi_offline(cdip, flags);
11920
11921	return (rval);
11922}
11923
11924static dev_info_t *
11925mptsas_find_child(dev_info_t *pdip, char *name)
11926{
11927	dev_info_t	*child = NULL;
11928	char		*rname = NULL;
11929	int		rval = DDI_FAILURE;
11930
11931	rname = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
11932
11933	child = ddi_get_child(pdip);
11934	while (child) {
11935		rval = mptsas_name_child(child, rname, SCSI_MAXNAMELEN);
11936		if (rval != DDI_SUCCESS) {
11937			child = ddi_get_next_sibling(child);
11938			bzero(rname, SCSI_MAXNAMELEN);
11939			continue;
11940		}
11941
11942		if (strcmp(rname, name) == 0) {
11943			break;
11944		}
11945		child = ddi_get_next_sibling(child);
11946		bzero(rname, SCSI_MAXNAMELEN);
11947	}
11948
11949	kmem_free(rname, SCSI_MAXNAMELEN);
11950
11951	return (child);
11952}
11953
11954
11955static dev_info_t *
11956mptsas_find_child_addr(dev_info_t *pdip, uint64_t sasaddr, int lun)
11957{
11958	dev_info_t	*child = NULL;
11959	char		*name = NULL;
11960	char		*addr = NULL;
11961
11962	name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
11963	addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
11964	(void) sprintf(name, "%016"PRIx64, sasaddr);
11965	(void) sprintf(addr, "w%s,%x", name, lun);
11966	child = mptsas_find_child(pdip, addr);
11967	kmem_free(name, SCSI_MAXNAMELEN);
11968	kmem_free(addr, SCSI_MAXNAMELEN);
11969	return (child);
11970}
11971
11972static dev_info_t *
11973mptsas_find_child_phy(dev_info_t *pdip, uint8_t phy)
11974{
11975	dev_info_t	*child;
11976	char		*addr;
11977
11978	addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
11979	(void) sprintf(addr, "p%x,0", phy);
11980	child = mptsas_find_child(pdip, addr);
11981	kmem_free(addr, SCSI_MAXNAMELEN);
11982	return (child);
11983}
11984
11985static mdi_pathinfo_t *
11986mptsas_find_path_phy(dev_info_t *pdip, uint8_t phy)
11987{
11988	mdi_pathinfo_t	*path;
11989	char		*addr = NULL;
11990
11991	addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
11992	(void) sprintf(addr, "p%x,0", phy);
11993	path = mdi_pi_find(pdip, NULL, addr);
11994	kmem_free(addr, SCSI_MAXNAMELEN);
11995	return (path);
11996}
11997
11998static mdi_pathinfo_t *
11999mptsas_find_path_addr(dev_info_t *parent, uint64_t sasaddr, int lun)
12000{
12001	mdi_pathinfo_t	*path;
12002	char		*name = NULL;
12003	char		*addr = NULL;
12004
12005	name = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
12006	addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
12007	(void) sprintf(name, "%016"PRIx64, sasaddr);
12008	(void) sprintf(addr, "w%s,%x", name, lun);
12009	path = mdi_pi_find(parent, NULL, addr);
12010	kmem_free(name, SCSI_MAXNAMELEN);
12011	kmem_free(addr, SCSI_MAXNAMELEN);
12012
12013	return (path);
12014}
12015
12016static int
12017mptsas_create_lun(dev_info_t *pdip, struct scsi_inquiry *sd_inq,
12018    dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun)
12019{
12020	int			i = 0;
12021	uchar_t			*inq83 = NULL;
12022	int			inq83_len1 = 0xFF;
12023	int			inq83_len = 0;
12024	int			rval = DDI_FAILURE;
12025	ddi_devid_t		devid;
12026	char			*guid = NULL;
12027	int			target = ptgt->m_devhdl;
12028	mdi_pathinfo_t		*pip = NULL;
12029	mptsas_t		*mpt = DIP2MPT(pdip);
12030
12031	/*
12032	 * For DVD/CD ROM and tape devices and optical
12033	 * devices, we won't try to enumerate them under
12034	 * scsi_vhci, so no need to try page83
12035	 */
12036	if (sd_inq && (sd_inq->inq_dtype == DTYPE_RODIRECT ||
12037	    sd_inq->inq_dtype == DTYPE_OPTICAL))
12038		goto create_lun;
12039
12040	/*
12041	 * The LCA returns good SCSI status, but corrupt page 83 data the first
12042	 * time it is queried. The solution is to keep trying to request page83
12043	 * and verify the GUID is not (DDI_NOT_WELL_FORMED) in
12044	 * mptsas_inq83_retry_timeout seconds. If the timeout expires, driver
12045	 * give up to get VPD page at this stage and fail the enumeration.
12046	 */
12047
12048	inq83	= kmem_zalloc(inq83_len1, KM_SLEEP);
12049
12050	for (i = 0; i < mptsas_inq83_retry_timeout; i++) {
12051		rval = mptsas_inquiry(mpt, ptgt, lun, 0x83, inq83,
12052		    inq83_len1, &inq83_len, 1);
12053		if (rval != 0) {
12054			mptsas_log(mpt, CE_WARN, "!mptsas request inquiry page "
12055			    "0x83 for target:%x, lun:%x failed!", target, lun);
12056			goto out;
12057		}
12058		/*
12059		 * create DEVID from inquiry data
12060		 */
12061		if ((rval = ddi_devid_scsi_encode(
12062		    DEVID_SCSI_ENCODE_VERSION_LATEST, NULL, (uchar_t *)sd_inq,
12063		    sizeof (struct scsi_inquiry), NULL, 0, inq83,
12064		    (size_t)inq83_len, &devid)) == DDI_SUCCESS) {
12065			/*
12066			 * extract GUID from DEVID
12067			 */
12068			guid = ddi_devid_to_guid(devid);
12069
12070			/*
12071			 * Do not enable MPXIO if the strlen(guid) is greater
12072			 * than MPTSAS_MAX_GUID_LEN, this constrain would be
12073			 * handled by framework later.
12074			 */
12075			if (guid && (strlen(guid) > MPTSAS_MAX_GUID_LEN)) {
12076				ddi_devid_free_guid(guid);
12077				guid = NULL;
12078				if (mpt->m_mpxio_enable == TRUE) {
12079					mptsas_log(mpt, CE_NOTE, "!Target:%x, "
12080					    "lun:%x doesn't have a valid GUID, "
12081					    "multipathing for this drive is "
12082					    "not enabled", target, lun);
12083				}
12084			}
12085
12086			/*
12087			 * devid no longer needed
12088			 */
12089			ddi_devid_free(devid);
12090			break;
12091		} else if (rval == DDI_NOT_WELL_FORMED) {
12092			/*
12093			 * return value of ddi_devid_scsi_encode equal to
12094			 * DDI_NOT_WELL_FORMED means DEVID_RETRY, it worth
12095			 * to retry inquiry page 0x83 and get GUID.
12096			 */
12097			NDBG20(("Not well formed devid, retry..."));
12098			delay(1 * drv_usectohz(1000000));
12099			continue;
12100		} else {
12101			mptsas_log(mpt, CE_WARN, "!Encode devid failed for "
12102			    "path target:%x, lun:%x", target, lun);
12103			rval = DDI_FAILURE;
12104			goto create_lun;
12105		}
12106	}
12107
12108	if (i == mptsas_inq83_retry_timeout) {
12109		mptsas_log(mpt, CE_WARN, "!Repeated page83 requests timeout "
12110		    "for path target:%x, lun:%x", target, lun);
12111	}
12112
12113	rval = DDI_FAILURE;
12114
12115create_lun:
12116	if ((guid != NULL) && (mpt->m_mpxio_enable == TRUE)) {
12117		rval = mptsas_create_virt_lun(pdip, sd_inq, guid, lun_dip, &pip,
12118		    ptgt, lun);
12119	}
12120	if (rval != DDI_SUCCESS) {
12121		rval = mptsas_create_phys_lun(pdip, sd_inq, guid, lun_dip,
12122		    ptgt, lun);
12123	}
12124out:
12125	if (guid != NULL) {
12126		/*
12127		 * guid no longer needed
12128		 */
12129		ddi_devid_free_guid(guid);
12130	}
12131	if (inq83 != NULL)
12132		kmem_free(inq83, inq83_len1);
12133	return (rval);
12134}
12135
12136static int
12137mptsas_create_virt_lun(dev_info_t *pdip, struct scsi_inquiry *inq, char *guid,
12138    dev_info_t **lun_dip, mdi_pathinfo_t **pip, mptsas_target_t *ptgt, int lun)
12139{
12140	int			target;
12141	char			*nodename = NULL;
12142	char			**compatible = NULL;
12143	int			ncompatible	= 0;
12144	int			mdi_rtn = MDI_FAILURE;
12145	int			rval = DDI_FAILURE;
12146	char			*old_guid = NULL;
12147	mptsas_t		*mpt = DIP2MPT(pdip);
12148	char			*lun_addr = NULL;
12149	char			*wwn_str = NULL;
12150	char			*component = NULL;
12151	uint8_t			phy = 0xFF;
12152	uint64_t		sas_wwn;
12153	uint32_t		devinfo;
12154
12155	mutex_enter(&mpt->m_mutex);
12156	target = ptgt->m_devhdl;
12157	sas_wwn = ptgt->m_sas_wwn;
12158	devinfo = ptgt->m_deviceinfo;
12159	phy = ptgt->m_phynum;
12160	mutex_exit(&mpt->m_mutex);
12161
12162	if (sas_wwn) {
12163		*pip = mptsas_find_path_addr(pdip, sas_wwn, lun);
12164	} else {
12165		*pip = mptsas_find_path_phy(pdip, phy);
12166	}
12167
12168	if (*pip != NULL) {
12169		*lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
12170		ASSERT(*lun_dip != NULL);
12171		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, *lun_dip,
12172		    (DDI_PROP_DONTPASS | DDI_PROP_NOTPROM),
12173		    MDI_CLIENT_GUID_PROP, &old_guid) == DDI_SUCCESS) {
12174			if (strncmp(guid, old_guid, strlen(guid)) == 0) {
12175				/*
12176				 * Same path back online again.
12177				 */
12178				(void) ddi_prop_free(old_guid);
12179				if (!MDI_PI_IS_ONLINE(*pip) &&
12180				    !MDI_PI_IS_STANDBY(*pip)) {
12181					rval = mdi_pi_online(*pip, 0);
12182				} else {
12183					rval = DDI_SUCCESS;
12184				}
12185				if (rval != DDI_SUCCESS) {
12186					mptsas_log(mpt, CE_WARN, "path:target: "
12187					    "%x, lun:%x online failed!", target,
12188					    lun);
12189					*pip = NULL;
12190					*lun_dip = NULL;
12191				}
12192				return (rval);
12193			} else {
12194				/*
12195				 * The GUID of the LUN has changed which maybe
12196				 * because customer mapped another volume to the
12197				 * same LUN.
12198				 */
12199				mptsas_log(mpt, CE_WARN, "The GUID of the "
12200				    "target:%x, lun:%x was changed, maybe "
12201				    "because someone mapped another volume "
12202				    "to the same LUN", target, lun);
12203				(void) ddi_prop_free(old_guid);
12204				if (!MDI_PI_IS_OFFLINE(*pip)) {
12205					rval = mdi_pi_offline(*pip, 0);
12206					if (rval != MDI_SUCCESS) {
12207						mptsas_log(mpt, CE_WARN, "path:"
12208						    "target:%x, lun:%x offline "
12209						    "failed!", target, lun);
12210						*pip = NULL;
12211						*lun_dip = NULL;
12212						return (DDI_FAILURE);
12213					}
12214				}
12215				if (mdi_pi_free(*pip, 0) != MDI_SUCCESS) {
12216					mptsas_log(mpt, CE_WARN, "path:target:"
12217					    "%x, lun:%x free failed!", target,
12218					    lun);
12219					*pip = NULL;
12220					*lun_dip = NULL;
12221					return (DDI_FAILURE);
12222				}
12223			}
12224		} else {
12225			mptsas_log(mpt, CE_WARN, "Can't get client-guid "
12226			    "property for path:target:%x, lun:%x", target, lun);
12227			*pip = NULL;
12228			*lun_dip = NULL;
12229			return (DDI_FAILURE);
12230		}
12231	}
12232	scsi_hba_nodename_compatible_get(inq, NULL,
12233	    inq->inq_dtype, NULL, &nodename, &compatible, &ncompatible);
12234
12235	/*
12236	 * if nodename can't be determined then print a message and skip it
12237	 */
12238	if (nodename == NULL) {
12239		mptsas_log(mpt, CE_WARN, "mptsas driver found no compatible "
12240		    "driver for target%d lun %d dtype:0x%02x", target, lun,
12241		    inq->inq_dtype);
12242		return (DDI_FAILURE);
12243	}
12244
12245	wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP);
12246	/* The property is needed by MPAPI */
12247	(void) sprintf(wwn_str, "%016"PRIx64, sas_wwn);
12248
12249	lun_addr = kmem_zalloc(SCSI_MAXNAMELEN, KM_SLEEP);
12250	if (sas_wwn)
12251		(void) sprintf(lun_addr, "w%s,%x", wwn_str, lun);
12252	else
12253		(void) sprintf(lun_addr, "p%x,%x", phy, lun);
12254
12255	mdi_rtn = mdi_pi_alloc_compatible(pdip, nodename,
12256	    guid, lun_addr, compatible, ncompatible,
12257	    0, pip);
12258	if (mdi_rtn == MDI_SUCCESS) {
12259
12260		if (mdi_prop_update_string(*pip, MDI_GUID,
12261		    guid) != DDI_SUCCESS) {
12262			mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
12263			    "create property for target %d lun %d (MDI_GUID)",
12264			    target, lun);
12265			mdi_rtn = MDI_FAILURE;
12266			goto virt_create_done;
12267		}
12268
12269		if (mdi_prop_update_int(*pip, LUN_PROP,
12270		    lun) != DDI_SUCCESS) {
12271			mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
12272			    "create property for target %d lun %d (LUN_PROP)",
12273			    target, lun);
12274			mdi_rtn = MDI_FAILURE;
12275			goto virt_create_done;
12276		}
12277		if (mdi_prop_update_string_array(*pip, "compatible",
12278		    compatible, ncompatible) !=
12279		    DDI_PROP_SUCCESS) {
12280			mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
12281			    "create property for target %d lun %d (COMPATIBLE)",
12282			    target, lun);
12283			mdi_rtn = MDI_FAILURE;
12284			goto virt_create_done;
12285		}
12286		if (sas_wwn && (mdi_prop_update_string(*pip, "target-port",
12287		    wwn_str) != DDI_PROP_SUCCESS)) {
12288			mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
12289			    "create property for target %d lun %d "
12290			    "(target-port)", target, lun);
12291			mdi_rtn = MDI_FAILURE;
12292			goto virt_create_done;
12293		} else if ((sas_wwn == 0) && (mdi_prop_update_int(*pip,
12294		    "sata-phy", phy) != DDI_PROP_SUCCESS)) {
12295			/*
12296			 * Direct attached SATA device without DeviceName
12297			 */
12298			mptsas_log(mpt, CE_WARN, "mptsas driver unable to "
12299			    "create property for SAS target %d lun %d "
12300			    "(sata-phy)", target, lun);
12301			mdi_rtn = NDI_FAILURE;
12302			goto virt_create_done;
12303		}
12304
12305		if (inq->inq_dtype == 0) {
12306			component = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
12307			/*
12308			 * set obp path for pathinfo
12309			 */
12310			(void) snprintf(component, MAXPATHLEN,
12311			    "disk@%s", lun_addr);
12312
12313			if (mdi_pi_pathname_obp_set(*pip, component) !=
12314			    DDI_SUCCESS) {
12315				mptsas_log(mpt, CE_WARN, "mpt_sas driver "
12316				    "unable to set obp-path for object %s",
12317				    component);
12318				mdi_rtn = MDI_FAILURE;
12319				goto virt_create_done;
12320			}
12321		}
12322
12323		*lun_dip = MDI_PI(*pip)->pi_client->ct_dip;
12324		if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
12325		    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
12326			if ((ndi_prop_update_int(DDI_DEV_T_NONE, *lun_dip,
12327			    "pm-capable", 1)) !=
12328			    DDI_PROP_SUCCESS) {
12329				mptsas_log(mpt, CE_WARN, "mptsas driver"
12330				    "failed to create pm-capable "
12331				    "property, target %d", target);
12332				mdi_rtn = MDI_FAILURE;
12333				goto virt_create_done;
12334			}
12335		}
12336		NDBG20(("new path:%s onlining,", MDI_PI(*pip)->pi_addr));
12337		mdi_rtn = mdi_pi_online(*pip, 0);
12338		if (mdi_rtn == MDI_NOT_SUPPORTED) {
12339			mdi_rtn = MDI_FAILURE;
12340		}
12341virt_create_done:
12342		if (*pip && mdi_rtn != MDI_SUCCESS) {
12343			(void) mdi_pi_free(*pip, 0);
12344			*pip = NULL;
12345			*lun_dip = NULL;
12346		}
12347	}
12348
12349	scsi_hba_nodename_compatible_free(nodename, compatible);
12350	if (lun_addr != NULL) {
12351		kmem_free(lun_addr, SCSI_MAXNAMELEN);
12352	}
12353	if (wwn_str != NULL) {
12354		kmem_free(wwn_str, MPTSAS_WWN_STRLEN);
12355	}
12356	if (component != NULL) {
12357		kmem_free(component, MAXPATHLEN);
12358	}
12359
12360	return ((mdi_rtn == MDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
12361}
12362
12363static int
12364mptsas_create_phys_lun(dev_info_t *pdip, struct scsi_inquiry *inq,
12365    char *guid, dev_info_t **lun_dip, mptsas_target_t *ptgt, int lun)
12366{
12367	int			target;
12368	int			ndi_rtn = NDI_FAILURE;
12369	uint64_t		be_sas_wwn;
12370	char			*nodename = NULL;
12371	char			**compatible = NULL;
12372	int			ncompatible = 0;
12373	int			instance = 0;
12374	mptsas_t		*mpt = DIP2MPT(pdip);
12375	char			*wwn_str = NULL;
12376	char			*component = NULL;
12377	uint8_t			phy = 0xFF;
12378	uint64_t		sas_wwn;
12379	uint32_t		devinfo;
12380
12381	mutex_enter(&mpt->m_mutex);
12382	target = ptgt->m_devhdl;
12383	sas_wwn = ptgt->m_sas_wwn;
12384	devinfo = ptgt->m_deviceinfo;
12385	phy = ptgt->m_phynum;
12386	mutex_exit(&mpt->m_mutex);
12387
12388	/*
12389	 * generate compatible property with binding-set "mpt"
12390	 */
12391	scsi_hba_nodename_compatible_get(inq, NULL, inq->inq_dtype, NULL,
12392	    &nodename, &compatible, &ncompatible);
12393
12394	/*
12395	 * if nodename can't be determined then print a message and skip it
12396	 */
12397	if (nodename == NULL) {
12398		mptsas_log(mpt, CE_WARN, "mptsas found no comptible driver "
12399		    "for target %d lun %d", target, lun);
12400		return (DDI_FAILURE);
12401	}
12402
12403	ndi_rtn = ndi_devi_alloc(pdip, nodename,
12404	    DEVI_SID_NODEID, lun_dip);
12405
12406	/*
12407	 * if lun alloc success, set props
12408	 */
12409	if (ndi_rtn == NDI_SUCCESS) {
12410
12411		if (ndi_prop_update_int(DDI_DEV_T_NONE,
12412		    *lun_dip, LUN_PROP, lun) !=
12413		    DDI_PROP_SUCCESS) {
12414			mptsas_log(mpt, CE_WARN, "mptsas unable to create "
12415			    "property for target %d lun %d (LUN_PROP)",
12416			    target, lun);
12417			ndi_rtn = NDI_FAILURE;
12418			goto phys_create_done;
12419		}
12420
12421		if (ndi_prop_update_string_array(DDI_DEV_T_NONE,
12422		    *lun_dip, "compatible", compatible, ncompatible)
12423		    != DDI_PROP_SUCCESS) {
12424			mptsas_log(mpt, CE_WARN, "mptsas unable to create "
12425			    "property for target %d lun %d (COMPATIBLE)",
12426			    target, lun);
12427			ndi_rtn = NDI_FAILURE;
12428			goto phys_create_done;
12429		}
12430
12431		/*
12432		 * We need the SAS WWN for non-multipath devices, so
12433		 * we'll use the same property as that multipathing
12434		 * devices need to present for MPAPI. If we don't have
12435		 * a WWN (e.g. parallel SCSI), don't create the prop.
12436		 */
12437		wwn_str = kmem_zalloc(MPTSAS_WWN_STRLEN, KM_SLEEP);
12438		(void) sprintf(wwn_str, "%016"PRIx64, sas_wwn);
12439		if (sas_wwn && ndi_prop_update_string(DDI_DEV_T_NONE,
12440		    *lun_dip, "target-port", wwn_str)
12441		    != DDI_PROP_SUCCESS) {
12442			mptsas_log(mpt, CE_WARN, "mptsas unable to "
12443			    "create property for SAS target %d lun %d "
12444			    "(target-port)", target, lun);
12445			ndi_rtn = NDI_FAILURE;
12446			goto phys_create_done;
12447		}
12448		be_sas_wwn = BE_64(sas_wwn);
12449		if (sas_wwn && ndi_prop_update_byte_array(
12450		    DDI_DEV_T_NONE, *lun_dip, "port-wwn",
12451		    (uchar_t *)&be_sas_wwn, 8) != DDI_PROP_SUCCESS) {
12452			mptsas_log(mpt, CE_WARN, "mptsas unable to "
12453			    "create property for SAS target %d lun %d "
12454			    "(port-wwn)", target, lun);
12455			ndi_rtn = NDI_FAILURE;
12456			goto phys_create_done;
12457		} else if ((sas_wwn == 0) && (ndi_prop_update_int(
12458		    DDI_DEV_T_NONE, *lun_dip, "sata-phy", phy) !=
12459		    DDI_PROP_SUCCESS)) {
12460			/*
12461			 * Direct attached SATA device without DeviceName
12462			 */
12463			mptsas_log(mpt, CE_WARN, "mptsas unable to "
12464			    "create property for SAS target %d lun %d "
12465			    "(sata-phy)", target, lun);
12466			ndi_rtn = NDI_FAILURE;
12467			goto phys_create_done;
12468		}
12469		if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
12470		    *lun_dip, SAS_PROP) != DDI_PROP_SUCCESS) {
12471			mptsas_log(mpt, CE_WARN, "mptsas unable to"
12472			    "create property for SAS target %d lun %d"
12473			    " (SAS_PROP)", target, lun);
12474			ndi_rtn = NDI_FAILURE;
12475			goto phys_create_done;
12476		}
12477		if (guid && (ndi_prop_update_string(DDI_DEV_T_NONE,
12478		    *lun_dip, NDI_GUID, guid) != DDI_SUCCESS)) {
12479			mptsas_log(mpt, CE_WARN, "mptsas unable "
12480			    "to create guid property for target %d "
12481			    "lun %d", target, lun);
12482			ndi_rtn = NDI_FAILURE;
12483			goto phys_create_done;
12484		}
12485
12486		/*
12487		 * if this is a SAS controller, and the target is a SATA
12488		 * drive, set the 'pm-capable' property for sd and if on
12489		 * an OPL platform, also check if this is an ATAPI
12490		 * device.
12491		 */
12492		instance = ddi_get_instance(mpt->m_dip);
12493		if (devinfo & (MPI2_SAS_DEVICE_INFO_SATA_DEVICE |
12494		    MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE)) {
12495			NDBG2(("mptsas%d: creating pm-capable property, "
12496			    "target %d", instance, target));
12497
12498			if ((ndi_prop_update_int(DDI_DEV_T_NONE,
12499			    *lun_dip, "pm-capable", 1)) !=
12500			    DDI_PROP_SUCCESS) {
12501				mptsas_log(mpt, CE_WARN, "mptsas "
12502				    "failed to create pm-capable "
12503				    "property, target %d", target);
12504				ndi_rtn = NDI_FAILURE;
12505				goto phys_create_done;
12506			}
12507
12508		}
12509
12510		if (inq->inq_dtype == 0) {
12511			/*
12512			 * add 'obp-path' properties for devinfo
12513			 */
12514			component = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
12515			if (sas_wwn) {
12516				(void) snprintf(component, MAXPATHLEN,
12517				    "disk@w%s,%x", wwn_str, lun);
12518			} else {
12519				(void) snprintf(component, MAXPATHLEN,
12520				    "disk@p%x,%x", phy, lun);
12521			}
12522			if (ddi_pathname_obp_set(*lun_dip, component)
12523			    != DDI_SUCCESS) {
12524				mptsas_log(mpt, CE_WARN, "mpt_sas driver "
12525				    "unable to set obp-path for SAS "
12526				    "object %s", component);
12527				ndi_rtn = NDI_FAILURE;
12528				goto phys_create_done;
12529			}
12530		}
12531
12532phys_create_done:
12533		/*
12534		 * If props were setup ok, online the lun
12535		 */
12536		if (ndi_rtn == NDI_SUCCESS) {
12537			/*
12538			 * Try to online the new node
12539			 */
12540			ndi_rtn = ndi_devi_online(*lun_dip, NDI_ONLINE_ATTACH);
12541		}
12542
12543		/*
12544		 * If success set rtn flag, else unwire alloc'd lun
12545		 */
12546		if (ndi_rtn != NDI_SUCCESS) {
12547			NDBG12(("mptsas driver unable to online "
12548			    "target %d lun %d", target, lun));
12549			ndi_prop_remove_all(*lun_dip);
12550			(void) ndi_devi_free(*lun_dip);
12551			*lun_dip = NULL;
12552		}
12553	}
12554
12555	scsi_hba_nodename_compatible_free(nodename, compatible);
12556
12557	if (wwn_str != NULL) {
12558		kmem_free(wwn_str, MPTSAS_WWN_STRLEN);
12559	}
12560	if (component != NULL) {
12561		kmem_free(component, MAXPATHLEN);
12562	}
12563
12564	return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
12565}
12566
12567static int
12568mptsas_probe_smp(dev_info_t *pdip, uint64_t wwn)
12569{
12570	struct smp_device smp;
12571
12572	bzero(&smp, sizeof (struct smp_device));
12573	smp.smp_addr.a_hba_tran = ndi_flavorv_get(pdip, SCSA_FLAVOR_SMP);
12574	bcopy(&wwn, smp.smp_addr.a_wwn, SAS_WWN_BYTE_SIZE);
12575
12576	if (sas_hba_probe_smp(&smp) != DDI_PROBE_SUCCESS) {
12577		return (NDI_FAILURE);
12578	}
12579	return (NDI_SUCCESS);
12580}
12581
12582static int
12583mptsas_config_smp(dev_info_t *pdip, uint64_t sas_wwn, dev_info_t **smp_dip)
12584{
12585	mptsas_t	*mpt = DIP2MPT(pdip);
12586	mptsas_smp_t	*psmp = NULL;
12587	int		rval;
12588	int		phymask;
12589
12590	/*
12591	 * Get the physical port associated to the iport
12592	 * PHYMASK TODO
12593	 */
12594	phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
12595	    "phymask", 0);
12596	/*
12597	 * Find the smp node in hash table with specified sas address and
12598	 * physical port
12599	 */
12600	psmp = mptsas_wwid_to_psmp(mpt, phymask, sas_wwn);
12601	if (psmp == NULL) {
12602		return (DDI_FAILURE);
12603	}
12604
12605	rval = mptsas_online_smp(pdip, psmp, smp_dip);
12606
12607	return (rval);
12608}
12609
12610static int
12611mptsas_online_smp(dev_info_t *pdip, mptsas_smp_t *smp_node,
12612    dev_info_t **smp_dip)
12613{
12614	char		wwn_str[MPTSAS_WWN_STRLEN];
12615	int		ndi_rtn = NDI_FAILURE;
12616	mptsas_t	*mpt = DIP2MPT(pdip);
12617
12618	(void) sprintf(wwn_str, "%"PRIx64, smp_node->m_sasaddr);
12619
12620	/*
12621	 * Probe smp device, prevent the node of removed device from being
12622	 * configured succesfully
12623	 */
12624	if (mptsas_probe_smp(pdip, smp_node->m_sasaddr) != NDI_SUCCESS) {
12625		return (DDI_FAILURE);
12626	}
12627
12628	if ((*smp_dip = mptsas_find_smp_child(pdip, wwn_str)) != NULL) {
12629		return (DDI_SUCCESS);
12630	}
12631
12632	ndi_rtn = ndi_devi_alloc(pdip, "smp", DEVI_SID_NODEID, smp_dip);
12633
12634	/*
12635	 * if lun alloc success, set props
12636	 */
12637	if (ndi_rtn == NDI_SUCCESS) {
12638		/*
12639		 * Set the flavor of the child to be SMP flavored
12640		 */
12641		ndi_flavor_set(*smp_dip, SCSA_FLAVOR_SMP);
12642
12643		if (ndi_prop_update_string(DDI_DEV_T_NONE,
12644		    *smp_dip, SMP_WWN, wwn_str) !=
12645		    DDI_PROP_SUCCESS) {
12646			mptsas_log(mpt, CE_WARN, "mptsas unable to create "
12647			    "property for smp device %s (sas_wwn)",
12648			    wwn_str);
12649			ndi_rtn = NDI_FAILURE;
12650			goto smp_create_done;
12651		}
12652
12653		if (ndi_prop_create_boolean(DDI_DEV_T_NONE,
12654		    *smp_dip, SMP_PROP) != DDI_PROP_SUCCESS) {
12655			mptsas_log(mpt, CE_WARN, "mptsas unable to "
12656			    "create property for SMP %s (SMP_PROP) ",
12657			    wwn_str);
12658			ndi_rtn = NDI_FAILURE;
12659			goto smp_create_done;
12660		}
12661
12662smp_create_done:
12663		/*
12664		 * If props were setup ok, online the lun
12665		 */
12666		if (ndi_rtn == NDI_SUCCESS) {
12667			/*
12668			 * Try to online the new node
12669			 */
12670			ndi_rtn = ndi_devi_online(*smp_dip, NDI_ONLINE_ATTACH);
12671		}
12672
12673		/*
12674		 * If success set rtn flag, else unwire alloc'd lun
12675		 */
12676		if (ndi_rtn != NDI_SUCCESS) {
12677			NDBG12(("mptsas unable to online "
12678			    "SMP target %s", wwn_str));
12679			ndi_prop_remove_all(*smp_dip);
12680			(void) ndi_devi_free(*smp_dip);
12681		}
12682	}
12683
12684	return ((ndi_rtn == NDI_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE);
12685}
12686
12687/*ARGSUSED*/
12688static int mptsas_getcap(struct sas_addr *ap, char *cap)
12689{
12690	int	ckey = -1;
12691	int	ret = EINVAL;
12692
12693	ckey = sas_hba_lookup_capstr(cap);
12694	if (ckey == -1)
12695		return (EINVAL);
12696
12697	switch (ckey) {
12698	case SAS_CAP_SMP_CRC:
12699		/*
12700		 * mpt controller support generate CRC for
12701		 * SMP passthrough frame and handle CRC by
12702		 * IOC itself.
12703		 */
12704		ret = 0;
12705		break;
12706	default:
12707		ret = EINVAL;
12708		break;
12709	}
12710	return (ret);
12711}
12712
12713/* smp transport routine */
12714static int mptsas_smp_start(struct smp_pkt *pktp)
12715{
12716	uint64_t			wwn;
12717	Mpi2SmpPassthroughRequest_t	req;
12718	Mpi2SmpPassthroughReply_t	rep;
12719	uint32_t			direction = 0;
12720	mptsas_t			*mpt;
12721	int				ret;
12722	uint64_t			tmp64;
12723
12724	mpt = (mptsas_t *)pktp->pkt_address->a_hba_tran->tran_hba_private;
12725
12726	bcopy(pktp->pkt_address->a_wwn, &wwn, SAS_WWN_BYTE_SIZE);
12727	/*
12728	 * Need to compose a SMP request message
12729	 * and call mptsas_do_passthru() function
12730	 */
12731	bzero(&req, sizeof (req));
12732	bzero(&rep, sizeof (rep));
12733	req.PassthroughFlags = 0;
12734	req.PhysicalPort = 0xff;
12735	req.ChainOffset = 0;
12736	req.Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
12737
12738	if ((pktp->pkt_reqsize & 0xffff0000ul) != 0) {
12739		pktp->pkt_reason = ERANGE;
12740		return (DDI_FAILURE);
12741	}
12742	req.RequestDataLength = LE_16((uint16_t)(pktp->pkt_reqsize - 4));
12743
12744	req.MsgFlags = 0;
12745	tmp64 = LE_64(wwn);
12746	bcopy(&tmp64, &req.SASAddress, SAS_WWN_BYTE_SIZE);
12747	if (pktp->pkt_rspsize > 0) {
12748		direction |= MPTSAS_PASS_THRU_DIRECTION_READ;
12749	}
12750	if (pktp->pkt_reqsize > 0) {
12751		direction |= MPTSAS_PASS_THRU_DIRECTION_WRITE;
12752	}
12753
12754	mutex_enter(&mpt->m_mutex);
12755	ret = mptsas_do_passthru(mpt, (uint8_t *)&req, (uint8_t *)&rep,
12756	    (uint8_t *)pktp->pkt_rsp, offsetof(Mpi2SmpPassthroughRequest_t,
12757	    SGL), sizeof (rep), pktp->pkt_rspsize - 4, direction,
12758	    (uint8_t *)pktp->pkt_req, pktp->pkt_reqsize - 4,
12759	    pktp->pkt_timeout, FKIOCTL);
12760	mutex_exit(&mpt->m_mutex);
12761	if (ret != 0) {
12762		cmn_err(CE_WARN, "smp_start do passthru error %d", ret);
12763		pktp->pkt_reason = (uchar_t)(ret);
12764		return (DDI_FAILURE);
12765	}
12766	/* do passthrough success, check the smp status */
12767	if (LE_16(rep.IOCStatus) != MPI2_IOCSTATUS_SUCCESS) {
12768		switch (LE_16(rep.IOCStatus)) {
12769		case MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
12770			pktp->pkt_reason = ENODEV;
12771			break;
12772		case MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN:
12773			pktp->pkt_reason = EOVERFLOW;
12774			break;
12775		case MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED:
12776			pktp->pkt_reason = EIO;
12777			break;
12778		default:
12779			mptsas_log(mpt, CE_NOTE, "smp_start: get unknown ioc"
12780			    "status:%x", LE_16(rep.IOCStatus));
12781			pktp->pkt_reason = EIO;
12782			break;
12783		}
12784		return (DDI_FAILURE);
12785	}
12786	if (rep.SASStatus != MPI2_SASSTATUS_SUCCESS) {
12787		mptsas_log(mpt, CE_NOTE, "smp_start: get error SAS status:%x",
12788		    rep.SASStatus);
12789		pktp->pkt_reason = EIO;
12790		return (DDI_FAILURE);
12791	}
12792
12793	return (DDI_SUCCESS);
12794}
12795
12796static void
12797mptsas_idle_pm(void *arg)
12798{
12799	mptsas_t	*mpt = arg;
12800
12801	(void) pm_idle_component(mpt->m_dip, 0);
12802	mutex_enter(&mpt->m_mutex);
12803	mpt->m_pm_timeid = 0;
12804	mutex_exit(&mpt->m_mutex);
12805}
12806
12807/*
12808 * If we didn't get a match, we need to get sas page0 for each device, and
12809 * untill we get a match. If failed, return NULL
12810 * TODO should be implemented similar to mptsas_wwid_to_ptgt?
12811 */
12812static mptsas_target_t *
12813mptsas_phy_to_tgt(dev_info_t *pdip, uint8_t phy)
12814{
12815	int		i, j = 0;
12816	int		rval = 0;
12817	uint16_t	cur_handle;
12818	uint32_t	page_address;
12819	mptsas_target_t	*ptgt = NULL;
12820	mptsas_t	*mpt = DIP2MPT(pdip);
12821	int		phymask;
12822
12823	/*
12824	 * Get the physical port associated to the iport
12825	 */
12826	phymask = ddi_prop_get_int(DDI_DEV_T_ANY, pdip, 0,
12827	    "phymask", 0);
12828
12829	if (phymask == 0)
12830		return (NULL);
12831
12832	/*
12833	 * PHY named device must be direct attached and attaches to
12834	 * narrow port, if the iport is not parent of the device which
12835	 * we are looking for.
12836	 */
12837	for (i = 0; i < MPTSAS_MAX_PHYS; i++) {
12838		if ((1 << i) & phymask)
12839			j++;
12840	}
12841
12842	if (j > 1)
12843		return (NULL);
12844
12845	/*
12846	 * Must be a narrow port and single device attached to the narrow port
12847	 * So the physical port num of device  which is equal to the iport's
12848	 * port num is the device what we are looking for.
12849	 */
12850
12851	if (mpt->m_phy_info[phy].phy_mask != phymask)
12852		return (NULL);
12853
12854	mutex_enter(&mpt->m_mutex);
12855
12856	ptgt = (mptsas_target_t *)mptsas_hash_traverse(&mpt->m_active->m_tgttbl,
12857	    MPTSAS_HASH_FIRST);
12858	while (ptgt != NULL) {
12859			if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) {
12860			mutex_exit(&mpt->m_mutex);
12861			return (ptgt);
12862		}
12863
12864		ptgt = (mptsas_target_t *)mptsas_hash_traverse(
12865		    &mpt->m_active->m_tgttbl, MPTSAS_HASH_NEXT);
12866	}
12867
12868	if (mpt->m_done_traverse_dev) {
12869		mutex_exit(&mpt->m_mutex);
12870		return (NULL);
12871	}
12872
12873	/* If didn't get a match, come here */
12874	cur_handle = mpt->m_dev_handle;
12875	for (; ; ) {
12876		ptgt = NULL;
12877		page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
12878		    MPI2_SAS_DEVICE_PGAD_FORM_MASK) | (uint32_t)cur_handle;
12879		rval = mptsas_get_target_device_info(mpt, page_address,
12880		    &cur_handle, &ptgt);
12881		if ((rval == DEV_INFO_FAIL_PAGE0) ||
12882		    (rval == DEV_INFO_FAIL_ALLOC)) {
12883			break;
12884		}
12885		if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
12886		    (rval == DEV_INFO_PHYS_DISK)) {
12887			continue;
12888		}
12889		mpt->m_dev_handle = cur_handle;
12890
12891		if ((ptgt->m_sas_wwn == 0) && (ptgt->m_phynum == phy)) {
12892			break;
12893		}
12894	}
12895
12896	mutex_exit(&mpt->m_mutex);
12897	return (ptgt);
12898}
12899
12900/*
12901 * The ptgt->m_sas_wwn contains the wwid for each disk.
12902 * For Raid volumes, we need to check m_raidvol[x].m_raidwwid
12903 * If we didn't get a match, we need to get sas page0 for each device, and
12904 * untill we get a match
12905 * If failed, return NULL
12906 */
12907static mptsas_target_t *
12908mptsas_wwid_to_ptgt(mptsas_t *mpt, int phymask, uint64_t wwid)
12909{
12910	int		rval = 0;
12911	uint16_t	cur_handle;
12912	uint32_t	page_address;
12913	mptsas_target_t	*tmp_tgt = NULL;
12914
12915	mutex_enter(&mpt->m_mutex);
12916	tmp_tgt = (struct mptsas_target *)mptsas_hash_search(
12917	    &mpt->m_active->m_tgttbl, wwid, phymask);
12918	if (tmp_tgt != NULL) {
12919		mutex_exit(&mpt->m_mutex);
12920		return (tmp_tgt);
12921	}
12922
12923	if (phymask == 0) {
12924		/*
12925		 * It's IR volume
12926		 */
12927		rval = mptsas_get_raid_info(mpt);
12928		if (rval) {
12929			tmp_tgt = (struct mptsas_target *)mptsas_hash_search(
12930			    &mpt->m_active->m_tgttbl, wwid, phymask);
12931		}
12932		mutex_exit(&mpt->m_mutex);
12933		return (tmp_tgt);
12934	}
12935
12936	if (mpt->m_done_traverse_dev) {
12937		mutex_exit(&mpt->m_mutex);
12938		return (NULL);
12939	}
12940
12941	/* If didn't get a match, come here */
12942	cur_handle = mpt->m_dev_handle;
12943	for (; ; ) {
12944		tmp_tgt = NULL;
12945		page_address = (MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE &
12946		    MPI2_SAS_DEVICE_PGAD_FORM_MASK) | cur_handle;
12947		rval = mptsas_get_target_device_info(mpt, page_address,
12948		    &cur_handle, &tmp_tgt);
12949		if ((rval == DEV_INFO_FAIL_PAGE0) ||
12950		    (rval == DEV_INFO_FAIL_ALLOC)) {
12951			tmp_tgt = NULL;
12952			break;
12953		}
12954		if ((rval == DEV_INFO_WRONG_DEVICE_TYPE) ||
12955		    (rval == DEV_INFO_PHYS_DISK)) {
12956			continue;
12957		}
12958		mpt->m_dev_handle = cur_handle;
12959		if ((tmp_tgt->m_sas_wwn) && (tmp_tgt->m_sas_wwn == wwid) &&
12960		    (tmp_tgt->m_phymask == phymask)) {
12961			break;
12962		}
12963	}
12964
12965	mutex_exit(&mpt->m_mutex);
12966	return (tmp_tgt);
12967}
12968
12969static mptsas_smp_t *
12970mptsas_wwid_to_psmp(mptsas_t *mpt, int phymask, uint64_t wwid)
12971{
12972	int		rval = 0;
12973	uint16_t	cur_handle;
12974	uint32_t	page_address;
12975	mptsas_smp_t	smp_node, *psmp = NULL;
12976
12977	mutex_enter(&mpt->m_mutex);
12978	psmp = (struct mptsas_smp *)mptsas_hash_search(&mpt->m_active->m_smptbl,
12979	    wwid, phymask);
12980	if (psmp != NULL) {
12981		mutex_exit(&mpt->m_mutex);
12982		return (psmp);
12983	}
12984
12985	if (mpt->m_done_traverse_smp) {
12986		mutex_exit(&mpt->m_mutex);
12987		return (NULL);
12988	}
12989
12990	/* If didn't get a match, come here */
12991	cur_handle = mpt->m_smp_devhdl;
12992	for (; ; ) {
12993		psmp = NULL;
12994		page_address = (MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL &
12995		    MPI2_SAS_EXPAND_PGAD_FORM_MASK) | (uint32_t)cur_handle;
12996		rval = mptsas_get_sas_expander_page0(mpt, page_address,
12997		    &smp_node);
12998		if (rval != DDI_SUCCESS) {
12999			break;
13000		}
13001		mpt->m_smp_devhdl = cur_handle = smp_node.m_devhdl;
13002		psmp = mptsas_smp_alloc(&mpt->m_active->m_smptbl, &smp_node);
13003		ASSERT(psmp);
13004		if ((psmp->m_sasaddr) && (psmp->m_sasaddr == wwid) &&
13005		    (psmp->m_phymask == phymask)) {
13006			break;
13007		}
13008	}
13009
13010	mutex_exit(&mpt->m_mutex);
13011	return (psmp);
13012}
13013
13014/* helper functions using hash */
13015
13016/*
13017 * Can't have duplicate entries for same devhdl,
13018 * if there are invalid entries, the devhdl should be set to 0xffff
13019 */
13020static void *
13021mptsas_search_by_devhdl(mptsas_hash_table_t *hashtab, uint16_t devhdl)
13022{
13023	mptsas_hash_data_t *data;
13024
13025	data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_FIRST);
13026	while (data != NULL) {
13027		if (data->devhdl == devhdl) {
13028			break;
13029		}
13030		data = mptsas_hash_traverse(hashtab, MPTSAS_HASH_NEXT);
13031	}
13032	return (data);
13033}
13034
13035mptsas_target_t *
13036mptsas_tgt_alloc(mptsas_hash_table_t *hashtab, uint16_t devhdl, uint64_t wwid,
13037    uint32_t devinfo, uint8_t phymask, uint8_t phynum)
13038{
13039	mptsas_target_t *tmp_tgt = NULL;
13040
13041	tmp_tgt = mptsas_hash_search(hashtab, wwid, phymask);
13042	if (tmp_tgt != NULL) {
13043		NDBG20(("Hash item already exist"));
13044		tmp_tgt->m_deviceinfo = devinfo;
13045		tmp_tgt->m_devhdl = devhdl;
13046		return (tmp_tgt);
13047	}
13048	tmp_tgt = kmem_zalloc(sizeof (struct mptsas_target), KM_SLEEP);
13049	if (tmp_tgt == NULL) {
13050		cmn_err(CE_WARN, "Fatal, allocated tgt failed");
13051		return (NULL);
13052	}
13053	tmp_tgt->m_devhdl = devhdl;
13054	tmp_tgt->m_sas_wwn = wwid;
13055	tmp_tgt->m_deviceinfo = devinfo;
13056	tmp_tgt->m_phymask = phymask;
13057	tmp_tgt->m_phynum = phynum;
13058	/* Initialized the tgt structure */
13059	tmp_tgt->m_qfull_retries = QFULL_RETRIES;
13060	tmp_tgt->m_qfull_retry_interval =
13061	    drv_usectohz(QFULL_RETRY_INTERVAL * 1000);
13062	tmp_tgt->m_t_throttle = MAX_THROTTLE;
13063
13064	mptsas_hash_add(hashtab, tmp_tgt);
13065
13066	return (tmp_tgt);
13067}
13068
13069static void
13070mptsas_tgt_free(mptsas_hash_table_t *hashtab, uint64_t wwid, uint8_t phymask)
13071{
13072	mptsas_target_t *tmp_tgt;
13073	tmp_tgt = mptsas_hash_rem(hashtab, wwid, phymask);
13074	if (tmp_tgt == NULL) {
13075		cmn_err(CE_WARN, "Tgt not found, nothing to free");
13076	} else {
13077		kmem_free(tmp_tgt, sizeof (struct mptsas_target));
13078	}
13079}
13080
13081/*
13082 * Return the entry in the hash table
13083 */
13084static mptsas_smp_t *
13085mptsas_smp_alloc(mptsas_hash_table_t *hashtab, mptsas_smp_t *data)
13086{
13087	uint64_t key1 = data->m_sasaddr;
13088	uint8_t key2 = data->m_phymask;
13089	mptsas_smp_t *ret_data;
13090
13091	ret_data = mptsas_hash_search(hashtab, key1, key2);
13092	if (ret_data != NULL) {
13093		bcopy(data, ret_data, sizeof (mptsas_smp_t));
13094		return (ret_data);
13095	}
13096
13097	ret_data = kmem_alloc(sizeof (mptsas_smp_t), KM_SLEEP);
13098	bcopy(data, ret_data, sizeof (mptsas_smp_t));
13099	mptsas_hash_add(hashtab, ret_data);
13100	return (ret_data);
13101}
13102
13103static void
13104mptsas_smp_free(mptsas_hash_table_t *hashtab, uint64_t wwid, uint8_t phymask)
13105{
13106	mptsas_smp_t *tmp_smp;
13107	tmp_smp = mptsas_hash_rem(hashtab, wwid, phymask);
13108	if (tmp_smp == NULL) {
13109		cmn_err(CE_WARN, "Smp element not found, nothing to free");
13110	} else {
13111		kmem_free(tmp_smp, sizeof (struct mptsas_smp));
13112	}
13113}
13114
13115/*
13116 * Hash operation functions
13117 * key1 is the sas_wwn, key2 is the phymask
13118 */
13119static void
13120mptsas_hash_init(mptsas_hash_table_t *hashtab)
13121{
13122	if (hashtab == NULL) {
13123		return;
13124	}
13125	bzero(hashtab->head, sizeof (mptsas_hash_node_t) *
13126	    MPTSAS_HASH_ARRAY_SIZE);
13127	hashtab->cur = NULL;
13128	hashtab->line = 0;
13129}
13130
13131static void
13132mptsas_hash_uninit(mptsas_hash_table_t *hashtab, size_t datalen)
13133{
13134	uint16_t line = 0;
13135	mptsas_hash_node_t *cur = NULL, *last = NULL;
13136
13137	if (hashtab == NULL) {
13138		return;
13139	}
13140	for (line = 0; line < MPTSAS_HASH_ARRAY_SIZE; line++) {
13141		cur = hashtab->head[line];
13142		while (cur != NULL) {
13143			last = cur;
13144			cur = cur->next;
13145			kmem_free(last->data, datalen);
13146			kmem_free(last, sizeof (mptsas_hash_node_t));
13147		}
13148	}
13149}
13150
13151/*
13152 * You must guarantee the element doesn't exist in the hash table
13153 * before you call mptsas_hash_add()
13154 */
13155static void
13156mptsas_hash_add(mptsas_hash_table_t *hashtab, void *data)
13157{
13158	uint64_t key1 = ((mptsas_hash_data_t *)data)->key1;
13159	uint8_t	key2 = ((mptsas_hash_data_t *)data)->key2;
13160	mptsas_hash_node_t **head = NULL;
13161	mptsas_hash_node_t *node = NULL;
13162
13163	if (hashtab == NULL) {
13164		return;
13165	}
13166	ASSERT(mptsas_hash_search(hashtab, key1, key2) == NULL);
13167	node = kmem_zalloc(sizeof (mptsas_hash_node_t), KM_NOSLEEP);
13168	node->data = data;
13169
13170	head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]);
13171	if (*head == NULL) {
13172		*head = node;
13173	} else {
13174		node->next = *head;
13175		*head = node;
13176	}
13177}
13178
13179static void *
13180mptsas_hash_rem(mptsas_hash_table_t *hashtab, uint64_t key1, uint8_t key2)
13181{
13182	mptsas_hash_node_t **head = NULL;
13183	mptsas_hash_node_t *last = NULL, *cur = NULL;
13184	mptsas_hash_data_t *data;
13185	if (hashtab == NULL) {
13186		return (NULL);
13187	}
13188	head = &(hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE]);
13189	cur = *head;
13190	while (cur != NULL) {
13191		data = cur->data;
13192		if ((data->key1 == key1) && (data->key2 == key2)) {
13193			if (last == NULL) {
13194				(*head) = cur->next;
13195			} else {
13196				last->next = cur->next;
13197			}
13198			kmem_free(cur, sizeof (mptsas_hash_node_t));
13199			return (data);
13200		} else {
13201			last = cur;
13202			cur = cur->next;
13203		}
13204	}
13205	return (NULL);
13206}
13207
13208static void *
13209mptsas_hash_search(mptsas_hash_table_t *hashtab, uint64_t key1, uint8_t key2)
13210{
13211	mptsas_hash_node_t *cur = NULL;
13212	mptsas_hash_data_t *data;
13213	if (hashtab == NULL) {
13214		return (NULL);
13215	}
13216	cur = hashtab->head[key1 % MPTSAS_HASH_ARRAY_SIZE];
13217	while (cur != NULL) {
13218		data = cur->data;
13219		if ((data->key1 == key1) && (data->key2 == key2)) {
13220			return (data);
13221		} else {
13222			cur = cur->next;
13223		}
13224	}
13225	return (NULL);
13226}
13227
13228static void *
13229mptsas_hash_traverse(mptsas_hash_table_t *hashtab, int pos)
13230{
13231	mptsas_hash_node_t *this = NULL;
13232
13233	if (hashtab == NULL) {
13234		return (NULL);
13235	}
13236
13237	if (pos == MPTSAS_HASH_FIRST) {
13238		hashtab->line = 0;
13239		hashtab->cur = NULL;
13240		this = hashtab->head[0];
13241	} else {
13242		if (hashtab->cur == NULL) {
13243			return (NULL);
13244		} else {
13245			this = hashtab->cur->next;
13246		}
13247	}
13248
13249	while (this == NULL) {
13250		hashtab->line++;
13251		if (hashtab->line >= MPTSAS_HASH_ARRAY_SIZE) {
13252			/* the traverse reaches the end */
13253			hashtab->cur = NULL;
13254			return (NULL);
13255		} else {
13256			this = hashtab->head[hashtab->line];
13257		}
13258	}
13259	hashtab->cur = this;
13260	return (this->data);
13261}
13262