nv_sata.c revision 7152:4575049c1ae7
1178479Sjb/*
2178479Sjb * CDDL HEADER START
3178479Sjb *
4178479Sjb * The contents of this file are subject to the terms of the
5178479Sjb * Common Development and Distribution License (the "License").
6178479Sjb * You may not use this file except in compliance with the License.
7178479Sjb *
8178479Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9178479Sjb * or http://www.opensolaris.org/os/licensing.
10178479Sjb * See the License for the specific language governing permissions
11178479Sjb * and limitations under the License.
12178479Sjb *
13178479Sjb * When distributing Covered Code, include this CDDL HEADER in each
14178479Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15178479Sjb * If applicable, add the following below this CDDL HEADER, with the
16178479Sjb * fields enclosed by brackets "[]" replaced with your own identifying
17178479Sjb * information: Portions Copyright [yyyy] [name of copyright owner]
18178479Sjb *
19178479Sjb * CDDL HEADER END
20178479Sjb */
21178479Sjb
22178479Sjb/*
23178573Sjb * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24178479Sjb * Use is subject to license terms.
25178479Sjb */
26178479Sjb
27178479Sjb#pragma ident	"%Z%%M%	%I%	%E% SMI"
28178479Sjb
29178479Sjb/*
30178479Sjb *
31178479Sjb * nv_sata is a combo SATA HBA driver for ck804/mcp55 based chipsets.
32178479Sjb *
33178573Sjb * NCQ
34178479Sjb * ---
35178573Sjb *
36178573Sjb * A portion of the NCQ is in place, but is incomplete.  NCQ is disabled
37178573Sjb * and is likely to be revisited in the future.
38178479Sjb *
39178479Sjb *
40178479Sjb * Power Management
41178573Sjb * ----------------
42178479Sjb *
43178573Sjb * Normally power management would be responsible for ensuring the device
44178479Sjb * is quiescent and then changing power states to the device, such as
45178479Sjb * powering down parts or all of the device.  mcp55/ck804 is unique in
46178479Sjb * that it is only available as part of a larger southbridge chipset, so
47178479Sjb * removing power to the device isn't possible.  Switches to control
48178479Sjb * power management states D0/D3 in the PCI configuration space appear to
49178479Sjb * be supported but changes to these states are apparently are ignored.
50178573Sjb * The only further PM that the driver _could_ do is shut down the PHY,
51178479Sjb * but in order to deliver the first rev of the driver sooner than later,
52178573Sjb * that will be deferred until some future phase.
53178573Sjb *
54211554Srpaulo * Since the driver currently will not directly change any power state to
55211554Srpaulo * the device, no power() entry point will be required.  However, it is
56211554Srpaulo * possible that in ACPI power state S3, aka suspend to RAM, that power
57178573Sjb * can be removed to the device, and the driver cannot rely on BIOS to
58178479Sjb * have reset any state.  For the time being, there is no known
59178479Sjb * non-default configurations that need to be programmed.  This judgement
60178479Sjb * is based on the port of the legacy ata driver not having any such
61178479Sjb * functionality and based on conversations with the PM team.  If such a
62178479Sjb * restoration is later deemed necessary it can be incorporated into the
63178479Sjb * DDI_RESUME processing.
64178479Sjb *
65178479Sjb */
66178479Sjb
67178479Sjb#include <sys/scsi/scsi.h>
68178479Sjb#include <sys/pci.h>
69178479Sjb#include <sys/byteorder.h>
70178479Sjb#include <sys/sata/sata_hba.h>
71178479Sjb#include <sys/sata/adapters/nv_sata/nv_sata.h>
72178479Sjb#include <sys/disp.h>
73178479Sjb#include <sys/note.h>
74178479Sjb#include <sys/promif.h>
75178479Sjb
76178479Sjb
77178479Sjb/*
78178479Sjb * Function prototypes for driver entry points
79178479Sjb */
80178479Sjbstatic int nv_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
81178479Sjbstatic int nv_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
82178479Sjbstatic int nv_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd,
83178479Sjb    void *arg, void **result);
84178479Sjb
85178479Sjb/*
86178479Sjb * Function prototypes for entry points from sata service module
87178479Sjb * These functions are distinguished from other local functions
88178479Sjb * by the prefix "nv_sata_"
89178479Sjb */
90178479Sjbstatic int nv_sata_start(dev_info_t *dip, sata_pkt_t *spkt);
91178479Sjbstatic int nv_sata_abort(dev_info_t *dip, sata_pkt_t *spkt, int);
92178479Sjbstatic int nv_sata_reset(dev_info_t *dip, sata_device_t *sd);
93178479Sjbstatic int nv_sata_activate(dev_info_t *dip, sata_device_t *sd);
94178479Sjbstatic int nv_sata_deactivate(dev_info_t *dip, sata_device_t *sd);
95178479Sjb
96178479Sjb/*
97178479Sjb * Local function prototypes
98178479Sjb */
99178479Sjbstatic uint_t mcp55_intr(caddr_t arg1, caddr_t arg2);
100178479Sjbstatic uint_t mcp04_intr(caddr_t arg1, caddr_t arg2);
101178479Sjbstatic int nv_add_legacy_intrs(nv_ctl_t *nvc);
102178479Sjb#ifdef NV_MSI_SUPPORTED
103178479Sjbstatic int nv_add_msi_intrs(nv_ctl_t *nvc);
104178479Sjb#endif
105178479Sjbstatic void nv_rem_intrs(nv_ctl_t *nvc);
106178479Sjbstatic int nv_start_common(nv_port_t *nvp, sata_pkt_t *spkt);
107178479Sjbstatic int nv_start_nodata(nv_port_t *nvp, int slot);
108178479Sjbstatic void nv_intr_nodata(nv_port_t *nvp, nv_slot_t *spkt);
109178479Sjbstatic int nv_start_pio_in(nv_port_t *nvp, int slot);
110178479Sjbstatic int nv_start_pio_out(nv_port_t *nvp, int slot);
111178479Sjbstatic void nv_intr_pio_in(nv_port_t *nvp, nv_slot_t *spkt);
112178479Sjbstatic void nv_intr_pio_out(nv_port_t *nvp, nv_slot_t *spkt);
113178479Sjbstatic int nv_start_pkt_pio(nv_port_t *nvp, int slot);
114178479Sjbstatic void nv_intr_pkt_pio(nv_port_t *nvp, nv_slot_t *nv_slotp);
115178479Sjbstatic int nv_start_dma(nv_port_t *nvp, int slot);
116178479Sjbstatic void nv_intr_dma(nv_port_t *nvp, struct nv_slot *spkt);
117178479Sjbstatic void nv_log(uint_t flag, nv_ctl_t *nvc, nv_port_t *nvp, char *fmt, ...);
118178479Sjbstatic void nv_uninit_ctl(nv_ctl_t *nvc);
119178479Sjbstatic void mcp55_reg_init(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle);
120178479Sjbstatic void mcp04_reg_init(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle);
121178479Sjbstatic void nv_uninit_port(nv_port_t *nvp);
122178479Sjbstatic int nv_init_port(nv_port_t *nvp);
123178479Sjbstatic int nv_init_ctl(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle);
124178479Sjbstatic int mcp55_packet_complete_intr(nv_ctl_t *nvc, nv_port_t *nvp);
125178479Sjb#ifdef NCQ
126178479Sjbstatic int mcp55_dma_setup_intr(nv_ctl_t *nvc, nv_port_t *nvp);
127178479Sjb#endif
128178479Sjbstatic void nv_start_dma_engine(nv_port_t *nvp, int slot);
129178479Sjbstatic void nv_port_state_change(nv_port_t *nvp, int event, uint8_t addr_type,
130178479Sjb    int state);
131178479Sjbstatic boolean_t nv_check_link(uint32_t sstatus);
132178479Sjbstatic void nv_common_reg_init(nv_ctl_t *nvc);
133178479Sjbstatic void mcp04_intr_process(nv_ctl_t *nvc, uint8_t intr_status);
134178479Sjbstatic void nv_reset(nv_port_t *nvp);
135178479Sjbstatic void nv_complete_io(nv_port_t *nvp,  sata_pkt_t *spkt, int slot);
136178479Sjbstatic void nv_timeout(void *);
137178479Sjbstatic int nv_poll_wait(nv_port_t *nvp, sata_pkt_t *spkt);
138178479Sjbstatic void nv_cmn_err(int ce, nv_ctl_t *nvc, nv_port_t *nvp, char *fmt, ...);
139178479Sjbstatic void nv_read_signature(nv_port_t *nvp);
140178479Sjbstatic void mcp55_set_intr(nv_port_t *nvp, int flag);
141178479Sjbstatic void mcp04_set_intr(nv_port_t *nvp, int flag);
142178479Sjbstatic void nv_resume(nv_port_t *nvp);
143178479Sjbstatic void nv_suspend(nv_port_t *nvp);
144178479Sjbstatic int nv_start_sync(nv_port_t *nvp, sata_pkt_t *spkt);
145178479Sjbstatic int nv_abort_active(nv_port_t *nvp, sata_pkt_t *spkt, int abort_reason);
146178479Sjbstatic void nv_copy_registers(nv_port_t *nvp, sata_device_t *sd,
147178479Sjb    sata_pkt_t *spkt);
148178479Sjbstatic void nv_report_add_remove(nv_port_t *nvp, int flags);
149178479Sjbstatic int nv_start_async(nv_port_t *nvp, sata_pkt_t *spkt);
150178479Sjbstatic int nv_wait3(nv_port_t *nvp, uchar_t onbits1, uchar_t offbits1,
151178479Sjb    uchar_t failure_onbits2, uchar_t failure_offbits2,
152178479Sjb    uchar_t failure_onbits3, uchar_t failure_offbits3,
153178479Sjb    uint_t timeout_usec, int type_wait);
154178479Sjbstatic int nv_wait(nv_port_t *nvp, uchar_t onbits, uchar_t offbits,
155178479Sjb    uint_t timeout_usec, int type_wait);
156178479Sjbstatic int nv_start_rqsense_pio(nv_port_t *nvp, nv_slot_t *nv_slotp);
157178479Sjb
158178479Sjb
159178479Sjb/*
160178479Sjb * DMA attributes for the data buffer for x86.  dma_attr_burstsizes is unused.
161178479Sjb * Verify if needed if ported to other ISA.
162178479Sjb */
163178479Sjbstatic ddi_dma_attr_t buffer_dma_attr = {
164178479Sjb	DMA_ATTR_V0,		/* dma_attr_version */
165178479Sjb	0,			/* dma_attr_addr_lo: lowest bus address */
166178479Sjb	0xffffffffull,		/* dma_attr_addr_hi: */
167178479Sjb	NV_BM_64K_BOUNDARY - 1,	/* dma_attr_count_max i.e for one cookie */
168178479Sjb	4,			/* dma_attr_align */
169178479Sjb	1,			/* dma_attr_burstsizes. */
170178479Sjb	1,			/* dma_attr_minxfer */
171178479Sjb	0xffffffffull,		/* dma_attr_max xfer including all cookies */
172178479Sjb	0xffffffffull,		/* dma_attr_seg */
173178479Sjb	NV_DMA_NSEGS,		/* dma_attr_sgllen */
174178479Sjb	512,			/* dma_attr_granular */
175178479Sjb	0,			/* dma_attr_flags */
176178479Sjb};
177178479Sjb
178178479Sjb
179178479Sjb/*
180178479Sjb * DMA attributes for PRD tables
181178479Sjb */
182178479Sjbddi_dma_attr_t nv_prd_dma_attr = {
183178479Sjb	DMA_ATTR_V0,		/* dma_attr_version */
184178479Sjb	0,			/* dma_attr_addr_lo */
185178479Sjb	0xffffffffull,		/* dma_attr_addr_hi */
186178479Sjb	NV_BM_64K_BOUNDARY - 1,	/* dma_attr_count_max */
187178479Sjb	4,			/* dma_attr_align */
188178479Sjb	1,			/* dma_attr_burstsizes */
189178479Sjb	1,			/* dma_attr_minxfer */
190178479Sjb	NV_BM_64K_BOUNDARY,	/* dma_attr_maxxfer */
191178479Sjb	NV_BM_64K_BOUNDARY - 1,	/* dma_attr_seg */
192178479Sjb	1,			/* dma_attr_sgllen */
193178479Sjb	1,			/* dma_attr_granular */
194178479Sjb	0			/* dma_attr_flags */
195178479Sjb};
196178479Sjb
197178479Sjb/*
198178479Sjb * Device access attributes
199178479Sjb */
200178479Sjbstatic ddi_device_acc_attr_t accattr = {
201178479Sjb    DDI_DEVICE_ATTR_V0,
202178479Sjb    DDI_STRUCTURE_LE_ACC,
203178479Sjb    DDI_STRICTORDER_ACC
204178479Sjb};
205178479Sjb
206178479Sjb
207178479Sjbstatic struct dev_ops nv_dev_ops = {
208178479Sjb	DEVO_REV,		/* devo_rev */
209178479Sjb	0,			/* refcnt  */
210178479Sjb	nv_getinfo,		/* info */
211178479Sjb	nulldev,		/* identify */
212178479Sjb	nulldev,		/* probe */
213178479Sjb	nv_attach,		/* attach */
214178479Sjb	nv_detach,		/* detach */
215178479Sjb	nodev,			/* no reset */
216178479Sjb	(struct cb_ops *)0,	/* driver operations */
217178479Sjb	NULL,			/* bus operations */
218178479Sjb	NULL			/* power */
219178479Sjb};
220178479Sjb
221178479Sjb
222178479Sjb/*
223178479Sjb * Request Sense CDB for ATAPI
224178479Sjb */
225178479Sjbstatic const uint8_t nv_rqsense_cdb[16] = {
226178479Sjb	SCMD_REQUEST_SENSE,
227178479Sjb	0,
228178479Sjb	0,
229178479Sjb	0,
230178573Sjb	SATA_ATAPI_MIN_RQSENSE_LEN,
231178573Sjb	0,
232178573Sjb	0, 0, 0, 0, 0, 0, 0, 0, 0, 0	/* pad out to max CDB length */
233178573Sjb};
234178573Sjb
235178573Sjb
236178573Sjbstatic sata_tran_hotplug_ops_t nv_hotplug_ops;
237178479Sjb
238178479Sjbextern struct mod_ops mod_driverops;
239178479Sjb
240178479Sjbstatic  struct modldrv modldrv = {
241178573Sjb	&mod_driverops,	/* driverops */
242178573Sjb	"Nvidia ck804/mcp55 HBA v%I%",
243178573Sjb	&nv_dev_ops,	/* driver ops */
244178573Sjb};
245178573Sjb
246178573Sjbstatic  struct modlinkage modlinkage = {
247178479Sjb	MODREV_1,
248178479Sjb	&modldrv,
249178479Sjb	NULL
250178479Sjb};
251178479Sjb
252178479Sjb
253178479Sjb/*
254178479Sjb * wait between checks of reg status
255178479Sjb */
256178479Sjbint nv_usec_delay = NV_WAIT_REG_CHECK;
257178479Sjb
258178479Sjb/*
259178479Sjb * The following is needed for nv_vcmn_err()
260178479Sjb */
261178479Sjbstatic kmutex_t nv_log_mutex; /* protects nv_log_buf */
262178479Sjbstatic char nv_log_buf[NV_STRING_512];
263178479Sjbint nv_debug_flags = NVDBG_ALWAYS;
264178479Sjbint nv_log_to_console = B_FALSE;
265178479Sjb
266178479Sjbint nv_log_delay = 0;
267178479Sjbint nv_prom_print = B_FALSE;
268178479Sjb
269178479Sjb/*
270178479Sjb * for debugging
271178479Sjb */
272178479Sjb#ifdef DEBUG
273178479Sjbint ncq_commands = 0;
274178479Sjbint non_ncq_commands = 0;
275178479Sjb#endif
276178479Sjb
277178479Sjb/*
278178479Sjb * Opaque state pointer to be initialized by ddi_soft_state_init()
279178479Sjb */
280178479Sjbstatic void *nv_statep	= NULL;
281178479Sjb
282178479Sjb
283178479Sjbstatic sata_tran_hotplug_ops_t nv_hotplug_ops = {
284178479Sjb	SATA_TRAN_HOTPLUG_OPS_REV_1,	/* structure version */
285178479Sjb	nv_sata_activate,	/* activate port. cfgadm -c connect */
286178479Sjb	nv_sata_deactivate	/* deactivate port. cfgadm -c disconnect */
287178479Sjb};
288178479Sjb
289178479Sjb
290178479Sjb/*
291178479Sjb *  nv module initialization
292178479Sjb */
293178479Sjbint
294178479Sjb_init(void)
295178479Sjb{
296178479Sjb	int	error;
297178479Sjb
298178479Sjb	error = ddi_soft_state_init(&nv_statep, sizeof (nv_ctl_t), 0);
299178479Sjb
300178479Sjb	if (error != 0) {
301178479Sjb
302178479Sjb		return (error);
303178479Sjb	}
304178479Sjb
305178479Sjb	mutex_init(&nv_log_mutex, NULL, MUTEX_DRIVER, NULL);
306178479Sjb
307178479Sjb	if ((error = sata_hba_init(&modlinkage)) != 0) {
308178479Sjb		ddi_soft_state_fini(&nv_statep);
309178479Sjb		mutex_destroy(&nv_log_mutex);
310178479Sjb
311178479Sjb		return (error);
312178479Sjb	}
313178479Sjb
314178479Sjb	error = mod_install(&modlinkage);
315178479Sjb	if (error != 0) {
316178479Sjb		sata_hba_fini(&modlinkage);
317178479Sjb		ddi_soft_state_fini(&nv_statep);
318178479Sjb		mutex_destroy(&nv_log_mutex);
319178479Sjb
320178479Sjb		return (error);
321178479Sjb	}
322178479Sjb
323178479Sjb	return (error);
324178479Sjb}
325178479Sjb
326178479Sjb
327178479Sjb/*
328178479Sjb * nv module uninitialize
329178479Sjb */
330178479Sjbint
331178479Sjb_fini(void)
332178479Sjb{
333178479Sjb	int	error;
334178479Sjb
335178479Sjb	error = mod_remove(&modlinkage);
336178479Sjb
337178479Sjb	if (error != 0) {
338178479Sjb		return (error);
339178479Sjb	}
340178479Sjb
341178479Sjb	/*
342178479Sjb	 * remove the resources allocated in _init()
343178479Sjb	 */
344178479Sjb	mutex_destroy(&nv_log_mutex);
345178479Sjb	sata_hba_fini(&modlinkage);
346178479Sjb	ddi_soft_state_fini(&nv_statep);
347178479Sjb
348178479Sjb	return (error);
349178479Sjb}
350178479Sjb
351178479Sjb
352178479Sjb/*
353178479Sjb * nv _info entry point
354178479Sjb */
355178479Sjbint
356178479Sjb_info(struct modinfo *modinfop)
357178479Sjb{
358178479Sjb	return (mod_info(&modlinkage, modinfop));
359178479Sjb}
360178479Sjb
361178479Sjb
362178479Sjb/*
363178479Sjb * these wrappers for ddi_{get,put}8 are for observability
364178479Sjb * with dtrace
365178479Sjb */
366178479Sjb#ifdef DEBUG
367178479Sjb
368178479Sjbstatic void
369178479Sjbnv_put8(ddi_acc_handle_t handle, uint8_t *dev_addr, uint8_t value)
370178479Sjb{
371178479Sjb	ddi_put8(handle, dev_addr, value);
372178479Sjb}
373178479Sjb
374178479Sjbstatic void
375178479Sjbnv_put32(ddi_acc_handle_t handle, uint32_t *dev_addr, uint32_t value)
376178479Sjb{
377178479Sjb	ddi_put32(handle, dev_addr, value);
378178479Sjb}
379178479Sjb
380178479Sjbstatic uint32_t
381178479Sjbnv_get32(ddi_acc_handle_t handle, uint32_t *dev_addr)
382178479Sjb{
383178479Sjb	return (ddi_get32(handle, dev_addr));
384178479Sjb}
385178479Sjb
386178479Sjbstatic void
387178479Sjbnv_put16(ddi_acc_handle_t handle, uint16_t *dev_addr, uint16_t value)
388178479Sjb{
389178479Sjb	ddi_put16(handle, dev_addr, value);
390178479Sjb}
391178479Sjb
392178479Sjbstatic uint16_t
393178479Sjbnv_get16(ddi_acc_handle_t handle, uint16_t *dev_addr)
394178479Sjb{
395178479Sjb	return (ddi_get16(handle, dev_addr));
396178479Sjb}
397178479Sjb
398178479Sjbstatic uint8_t
399178479Sjbnv_get8(ddi_acc_handle_t handle, uint8_t *dev_addr)
400178479Sjb{
401178479Sjb	return (ddi_get8(handle, dev_addr));
402178479Sjb}
403178479Sjb
404178479Sjb#else
405178479Sjb
406178479Sjb#define	nv_put8 ddi_put8
407178479Sjb#define	nv_put32 ddi_put32
408178479Sjb#define	nv_get32 ddi_get32
409178479Sjb#define	nv_put16 ddi_put16
410178479Sjb#define	nv_get16 ddi_get16
411178479Sjb#define	nv_get8 ddi_get8
412178479Sjb
413178479Sjb#endif
414178479Sjb
415178479Sjb
416178479Sjb/*
417178479Sjb * Driver attach
418178573Sjb */
419178573Sjbstatic int
420178573Sjbnv_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
421178573Sjb{
422178573Sjb	int status, attach_state, intr_types, bar, i, command;
423178573Sjb	int inst = ddi_get_instance(dip);
424178573Sjb	ddi_acc_handle_t pci_conf_handle;
425178573Sjb	nv_ctl_t *nvc;
426178573Sjb	uint8_t subclass;
427178573Sjb	uint32_t reg32;
428178479Sjb
429178479Sjb	switch (cmd) {
430178479Sjb
431178479Sjb	case DDI_ATTACH:
432178479Sjb
433178479Sjb		NVLOG((NVDBG_INIT, NULL, NULL,
434178479Sjb		    "nv_attach(): DDI_ATTACH inst %d", inst));
435178479Sjb
436178479Sjb		attach_state = ATTACH_PROGRESS_NONE;
437178479Sjb
438178479Sjb		status = ddi_soft_state_zalloc(nv_statep, inst);
439178479Sjb
440178573Sjb		if (status != DDI_SUCCESS) {
441178479Sjb			break;
442178479Sjb		}
443178479Sjb
444178479Sjb		nvc = ddi_get_soft_state(nv_statep, inst);
445178479Sjb
446178479Sjb		nvc->nvc_dip = dip;
447178479Sjb
448178479Sjb		attach_state |= ATTACH_PROGRESS_STATEP_ALLOC;
449178479Sjb
450178479Sjb		if (pci_config_setup(dip, &pci_conf_handle) == DDI_SUCCESS) {
451178479Sjb			nvc->nvc_revid = pci_config_get8(pci_conf_handle,
452178479Sjb			    PCI_CONF_REVID);
453178479Sjb			NVLOG((NVDBG_INIT, NULL, NULL,
454178479Sjb			    "inst %d: silicon revid is %x nv_debug_flags=%x",
455178479Sjb			    inst, nvc->nvc_revid, nv_debug_flags));
456178479Sjb		} else {
457178479Sjb			break;
458178479Sjb		}
459178479Sjb
460178479Sjb		attach_state |= ATTACH_PROGRESS_CONF_HANDLE;
461178479Sjb
462178479Sjb		/*
463178479Sjb		 * If a device is attached after a suspend/resume, sometimes
464178479Sjb		 * the command register is zero, as it might not be set by
465178479Sjb		 * BIOS or a parent.  Set it again here.
466178479Sjb		 */
467178479Sjb		command = pci_config_get16(pci_conf_handle, PCI_CONF_COMM);
468178479Sjb
469178479Sjb		if (command == 0) {
470178479Sjb			cmn_err(CE_WARN, "nv_sata%d: restoring PCI command"
471178479Sjb			    " register", inst);
472178479Sjb			pci_config_put16(pci_conf_handle, PCI_CONF_COMM,
473178479Sjb			    PCI_COMM_IO|PCI_COMM_MAE|PCI_COMM_ME);
474178479Sjb		}
475178479Sjb
476178479Sjb		subclass = pci_config_get8(pci_conf_handle, PCI_CONF_SUBCLASS);
477178479Sjb
478178479Sjb		if (subclass & PCI_MASS_RAID) {
479178479Sjb			cmn_err(CE_WARN,
480178479Sjb			    "attach failed: RAID mode not supported");
481178479Sjb			break;
482178479Sjb		}
483178479Sjb
484178479Sjb		/*
485178479Sjb		 * the 6 bars of the controller are:
486178479Sjb		 * 0: port 0 task file
487178479Sjb		 * 1: port 0 status
488178479Sjb		 * 2: port 1 task file
489178479Sjb		 * 3: port 1 status
490178479Sjb		 * 4: bus master for both ports
491178479Sjb		 * 5: extended registers for SATA features
492178479Sjb		 */
493178479Sjb		for (bar = 0; bar < 6; bar++) {
494178479Sjb			status = ddi_regs_map_setup(dip, bar + 1,
495178479Sjb			    (caddr_t *)&nvc->nvc_bar_addr[bar], 0, 0, &accattr,
496178479Sjb			    &nvc->nvc_bar_hdl[bar]);
497178479Sjb
498178479Sjb			if (status != DDI_SUCCESS) {
499178479Sjb				NVLOG((NVDBG_INIT, nvc, NULL,
500178479Sjb				    "ddi_regs_map_setup failure for bar"
501178479Sjb				    " %d status = %d", bar, status));
502178479Sjb				break;
503178479Sjb			}
504178479Sjb		}
505178479Sjb
506178479Sjb		attach_state |= ATTACH_PROGRESS_BARS;
507178479Sjb
508178479Sjb		/*
509178479Sjb		 * initialize controller and driver core
510178479Sjb		 */
511178479Sjb		status = nv_init_ctl(nvc, pci_conf_handle);
512178479Sjb
513178479Sjb		if (status == NV_FAILURE) {
514178479Sjb			NVLOG((NVDBG_INIT, nvc, NULL, "nv_init_ctl failed"));
515178479Sjb
516178479Sjb			break;
517178479Sjb		}
518178573Sjb
519178479Sjb		attach_state |= ATTACH_PROGRESS_CTL_SETUP;
520178573Sjb
521178479Sjb		/*
522178479Sjb		 * initialize mutexes
523178573Sjb		 */
524178573Sjb		mutex_init(&nvc->nvc_mutex, NULL, MUTEX_DRIVER,
525178573Sjb		    DDI_INTR_PRI(nvc->nvc_intr_pri));
526178479Sjb
527178573Sjb		attach_state |= ATTACH_PROGRESS_MUTEX_INIT;
528178573Sjb
529178573Sjb		/*
530178573Sjb		 * get supported interrupt types
531178573Sjb		 */
532178573Sjb		if (ddi_intr_get_supported_types(dip, &intr_types) !=
533178573Sjb		    DDI_SUCCESS) {
534178573Sjb			nv_cmn_err(CE_WARN, nvc, NULL,
535178573Sjb			    "!ddi_intr_get_supported_types failed");
536178479Sjb			NVLOG((NVDBG_INIT, nvc, NULL,
537178479Sjb			    "interrupt supported types failed"));
538178479Sjb
539178479Sjb			break;
540178479Sjb		}
541178479Sjb
542178479Sjb		NVLOG((NVDBG_INIT, nvc, NULL,
543178479Sjb		    "ddi_intr_get_supported_types() returned: 0x%x",
544178479Sjb		    intr_types));
545178479Sjb
546178479Sjb#ifdef NV_MSI_SUPPORTED
547178479Sjb		if (intr_types & DDI_INTR_TYPE_MSI) {
548178479Sjb			NVLOG((NVDBG_INIT, nvc, NULL,
549178479Sjb			    "using MSI interrupt type"));
550178479Sjb
551178479Sjb			/*
552178479Sjb			 * Try MSI first, but fall back to legacy if MSI
553178479Sjb			 * attach fails
554178479Sjb			 */
555178479Sjb			if (nv_add_msi_intrs(nvc) == DDI_SUCCESS) {
556178479Sjb				nvc->nvc_intr_type = DDI_INTR_TYPE_MSI;
557178479Sjb				attach_state |= ATTACH_PROGRESS_INTR_ADDED;
558178479Sjb				NVLOG((NVDBG_INIT, nvc, NULL,
559178479Sjb				    "MSI interrupt setup done"));
560178479Sjb			} else {
561178479Sjb				nv_cmn_err(CE_CONT, nvc, NULL,
562178479Sjb				    "!MSI registration failed "
563178479Sjb				    "will try Legacy interrupts");
564178479Sjb			}
565178479Sjb		}
566178479Sjb#endif
567178479Sjb
568178479Sjb		/*
569178479Sjb		 * Either the MSI interrupt setup has failed or only
570178479Sjb		 * the fixed interrupts are available on the system.
571178479Sjb		 */
572178479Sjb		if (!(attach_state & ATTACH_PROGRESS_INTR_ADDED) &&
573178479Sjb		    (intr_types & DDI_INTR_TYPE_FIXED)) {
574178479Sjb
575178479Sjb			NVLOG((NVDBG_INIT, nvc, NULL,
576178479Sjb			    "using Legacy interrupt type"));
577178479Sjb
578178479Sjb			if (nv_add_legacy_intrs(nvc) == DDI_SUCCESS) {
579178479Sjb				nvc->nvc_intr_type = DDI_INTR_TYPE_FIXED;
580178479Sjb				attach_state |= ATTACH_PROGRESS_INTR_ADDED;
581178479Sjb				NVLOG((NVDBG_INIT, nvc, NULL,
582178479Sjb				    "Legacy interrupt setup done"));
583178479Sjb			} else {
584178479Sjb				nv_cmn_err(CE_WARN, nvc, NULL,
585178479Sjb				    "!legacy interrupt setup failed");
586178479Sjb				NVLOG((NVDBG_INIT, nvc, NULL,
587178479Sjb				    "legacy interrupt setup failed"));
588178479Sjb				break;
589178479Sjb			}
590178479Sjb		}
591178479Sjb
592178479Sjb		if (!(attach_state & ATTACH_PROGRESS_INTR_ADDED)) {
593178479Sjb			NVLOG((NVDBG_INIT, nvc, NULL,
594178479Sjb			    "no interrupts registered"));
595178479Sjb			break;
596178479Sjb		}
597178479Sjb
598178479Sjb		/*
599178479Sjb		 * attach to sata module
600178479Sjb		 */
601178479Sjb		if (sata_hba_attach(nvc->nvc_dip,
602178479Sjb		    &nvc->nvc_sata_hba_tran,
603178479Sjb		    DDI_ATTACH) != DDI_SUCCESS) {
604178479Sjb			attach_state |= ATTACH_PROGRESS_SATA_MODULE;
605178479Sjb
606178479Sjb			break;
607178479Sjb		}
608178479Sjb
609178479Sjb		pci_config_teardown(&pci_conf_handle);
610178479Sjb
611178479Sjb		NVLOG((NVDBG_INIT, nvc, NULL, "nv_attach DDI_SUCCESS"));
612178479Sjb
613178479Sjb		return (DDI_SUCCESS);
614178479Sjb
615178479Sjb	case DDI_RESUME:
616178479Sjb
617178479Sjb		nvc = ddi_get_soft_state(nv_statep, inst);
618178479Sjb
619178479Sjb		NVLOG((NVDBG_INIT, nvc, NULL,
620178479Sjb		    "nv_attach(): DDI_RESUME inst %d", inst));
621178479Sjb
622178479Sjb		if (pci_config_setup(dip, &pci_conf_handle) != DDI_SUCCESS) {
623178479Sjb			return (DDI_FAILURE);
624178479Sjb		}
625178479Sjb
626178479Sjb		/*
627178479Sjb		 * If a device is attached after a suspend/resume, sometimes
628178479Sjb		 * the command register is zero, as it might not be set by
629178479Sjb		 * BIOS or a parent.  Set it again here.
630178479Sjb		 */
631178479Sjb		command = pci_config_get16(pci_conf_handle, PCI_CONF_COMM);
632178479Sjb
633178479Sjb		if (command == 0) {
634178479Sjb			pci_config_put16(pci_conf_handle, PCI_CONF_COMM,
635178479Sjb			    PCI_COMM_IO|PCI_COMM_MAE|PCI_COMM_ME);
636178479Sjb		}
637178479Sjb
638178479Sjb		/*
639178479Sjb		 * Need to set bit 2 to 1 at config offset 0x50
640178479Sjb		 * to enable access to the bar5 registers.
641178479Sjb		 */
642178479Sjb		reg32 = pci_config_get32(pci_conf_handle, NV_SATA_CFG_20);
643178479Sjb
644178479Sjb		if ((reg32 & NV_BAR5_SPACE_EN) != NV_BAR5_SPACE_EN) {
645178479Sjb			pci_config_put32(pci_conf_handle, NV_SATA_CFG_20,
646178479Sjb			    reg32 | NV_BAR5_SPACE_EN);
647178479Sjb		}
648178479Sjb
649178479Sjb		nvc->nvc_state &= ~NV_CTRL_SUSPEND;
650178479Sjb
651178479Sjb		for (i = 0; i < NV_MAX_PORTS(nvc); i++) {
652178479Sjb			nv_resume(&(nvc->nvc_port[i]));
653178479Sjb		}
654178479Sjb
655178479Sjb		pci_config_teardown(&pci_conf_handle);
656178479Sjb
657178479Sjb		return (DDI_SUCCESS);
658178479Sjb
659178479Sjb	default:
660178479Sjb		return (DDI_FAILURE);
661178479Sjb	}
662178479Sjb
663178479Sjb
664178479Sjb	/*
665178479Sjb	 * DDI_ATTACH failure path starts here
666178573Sjb	 */
667178479Sjb
668178573Sjb	if (attach_state & ATTACH_PROGRESS_INTR_ADDED) {
669178479Sjb		nv_rem_intrs(nvc);
670178479Sjb	}
671178573Sjb
672178573Sjb	if (attach_state & ATTACH_PROGRESS_SATA_MODULE) {
673178573Sjb		/*
674178479Sjb		 * Remove timers
675178573Sjb		 */
676178573Sjb		int port = 0;
677178573Sjb		nv_port_t *nvp;
678178573Sjb
679178573Sjb		for (; port < NV_MAX_PORTS(nvc); port++) {
680178573Sjb			nvp = &(nvc->nvc_port[port]);
681178573Sjb			if (nvp->nvp_timeout_id != 0) {
682178573Sjb				(void) untimeout(nvp->nvp_timeout_id);
683178573Sjb			}
684178479Sjb		}
685178479Sjb	}
686178479Sjb
687178479Sjb	if (attach_state & ATTACH_PROGRESS_MUTEX_INIT) {
688178479Sjb		mutex_destroy(&nvc->nvc_mutex);
689178479Sjb	}
690178479Sjb
691178479Sjb	if (attach_state & ATTACH_PROGRESS_CTL_SETUP) {
692178479Sjb		nv_uninit_ctl(nvc);
693178479Sjb	}
694178479Sjb
695178479Sjb	if (attach_state & ATTACH_PROGRESS_BARS) {
696178479Sjb		while (--bar >= 0) {
697178479Sjb			ddi_regs_map_free(&nvc->nvc_bar_hdl[bar]);
698178479Sjb		}
699178479Sjb	}
700178479Sjb
701178479Sjb	if (attach_state & ATTACH_PROGRESS_STATEP_ALLOC) {
702178479Sjb		ddi_soft_state_free(nv_statep, inst);
703178479Sjb	}
704178479Sjb
705178479Sjb	if (attach_state & ATTACH_PROGRESS_CONF_HANDLE) {
706178479Sjb		pci_config_teardown(&pci_conf_handle);
707178479Sjb	}
708178479Sjb
709178479Sjb	cmn_err(CE_WARN, "nv_sata%d attach failed", inst);
710178479Sjb
711178479Sjb	return (DDI_FAILURE);
712178479Sjb}
713178479Sjb
714178479Sjb
715178479Sjbstatic int
716178479Sjbnv_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
717178479Sjb{
718178479Sjb	int i, port, inst = ddi_get_instance(dip);
719178479Sjb	nv_ctl_t *nvc;
720178479Sjb	nv_port_t *nvp;
721178479Sjb
722178479Sjb	nvc = ddi_get_soft_state(nv_statep, inst);
723178479Sjb
724178479Sjb	switch (cmd) {
725178479Sjb
726178479Sjb	case DDI_DETACH:
727178479Sjb
728178479Sjb		NVLOG((NVDBG_INIT, nvc, NULL, "nv_detach: DDI_DETACH"));
729178479Sjb
730178479Sjb		/*
731178479Sjb		 * Remove interrupts
732178479Sjb		 */
733178479Sjb		nv_rem_intrs(nvc);
734178479Sjb
735178479Sjb		/*
736178479Sjb		 * Remove timers
737178479Sjb		 */
738178479Sjb		for (port = 0; port < NV_MAX_PORTS(nvc); port++) {
739178479Sjb			nvp = &(nvc->nvc_port[port]);
740178479Sjb			if (nvp->nvp_timeout_id != 0) {
741178479Sjb				(void) untimeout(nvp->nvp_timeout_id);
742178479Sjb			}
743178479Sjb		}
744178479Sjb
745178479Sjb		/*
746178479Sjb		 * Remove maps
747178479Sjb		 */
748178479Sjb		for (i = 0; i < 6; i++) {
749178479Sjb			ddi_regs_map_free(&nvc->nvc_bar_hdl[i]);
750178479Sjb		}
751178479Sjb
752178479Sjb		/*
753178479Sjb		 * Destroy mutexes
754178479Sjb		 */
755178479Sjb		mutex_destroy(&nvc->nvc_mutex);
756178479Sjb
757178479Sjb		/*
758178479Sjb		 * Uninitialize the controller
759178479Sjb		 */
760178479Sjb		nv_uninit_ctl(nvc);
761178479Sjb
762178479Sjb		/*
763178479Sjb		 * unregister from the sata module
764178479Sjb		 */
765178479Sjb		(void) sata_hba_detach(nvc->nvc_dip, DDI_DETACH);
766178479Sjb
767178479Sjb		/*
768178479Sjb		 * Free soft state
769178479Sjb		 */
770178479Sjb		ddi_soft_state_free(nv_statep, inst);
771178479Sjb
772178479Sjb		return (DDI_SUCCESS);
773178479Sjb
774178479Sjb	case DDI_SUSPEND:
775178479Sjb		/*
776178479Sjb		 * The PM functions for suspend and resume are incomplete
777178479Sjb		 * and need additional work.  It may or may not work in
778178479Sjb		 * the current state.
779178479Sjb		 */
780178479Sjb		NVLOG((NVDBG_INIT, nvc, NULL, "nv_detach: DDI_SUSPEND"));
781178479Sjb
782178479Sjb		for (i = 0; i < NV_MAX_PORTS(nvc); i++) {
783178479Sjb			nv_suspend(&(nvc->nvc_port[i]));
784178479Sjb		}
785178479Sjb
786178479Sjb		nvc->nvc_state |= NV_CTRL_SUSPEND;
787178479Sjb
788178479Sjb		return (DDI_SUCCESS);
789178479Sjb
790178479Sjb	default:
791178479Sjb		return (DDI_FAILURE);
792178479Sjb	}
793178479Sjb}
794178479Sjb
795178479Sjb
796178479Sjb/*ARGSUSED*/
797178479Sjbstatic int
798178479Sjbnv_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
799178573Sjb{
800178573Sjb	nv_ctl_t *nvc;
801178573Sjb	int instance;
802178573Sjb	dev_t dev;
803178573Sjb
804178573Sjb	dev = (dev_t)arg;
805178573Sjb	instance = getminor(dev);
806178573Sjb
807178573Sjb	switch (infocmd) {
808178573Sjb	case DDI_INFO_DEVT2DEVINFO:
809178573Sjb		nvc = ddi_get_soft_state(nv_statep,  instance);
810178573Sjb		if (nvc != NULL) {
811178573Sjb			*result = nvc->nvc_dip;
812178573Sjb			return (DDI_SUCCESS);
813178573Sjb		} else {
814178573Sjb			*result = NULL;
815178573Sjb			return (DDI_FAILURE);
816178573Sjb		}
817178573Sjb	case DDI_INFO_DEVT2INSTANCE:
818178573Sjb		*(int *)result = instance;
819178573Sjb		break;
820178573Sjb	default:
821178573Sjb		break;
822178573Sjb	}
823178573Sjb	return (DDI_SUCCESS);
824178573Sjb}
825178573Sjb
826178573Sjb
827178573Sjb/*
828178573Sjb * Called by sata module to probe a port.  Port and device state
829178573Sjb * are not changed here... only reported back to the sata module.
830178573Sjb *
831178573Sjb * If probe confirms a device is present for the first time, it will
832178573Sjb * initiate a device reset, then probe will be called again and the
833178573Sjb * signature will be check.  If the signature is valid, data structures
834178573Sjb * will be initialized.
835178479Sjb */
836178573Sjbstatic int
837178573Sjbnv_sata_probe(dev_info_t *dip, sata_device_t *sd)
838178479Sjb{
839178479Sjb	nv_ctl_t *nvc = ddi_get_soft_state(nv_statep, ddi_get_instance(dip));
840178479Sjb	uint8_t cport = sd->satadev_addr.cport;
841178479Sjb	uint8_t pmport = sd->satadev_addr.pmport;
842178479Sjb	uint8_t qual = sd->satadev_addr.qual;
843178479Sjb	clock_t nv_lbolt = ddi_get_lbolt();
844178479Sjb	nv_port_t *nvp;
845178479Sjb
846178479Sjb	if (cport >= NV_MAX_PORTS(nvc)) {
847178479Sjb		sd->satadev_type = SATA_DTYPE_NONE;
848178479Sjb		sd->satadev_state = SATA_STATE_UNKNOWN;
849178479Sjb
850178479Sjb		return (SATA_FAILURE);
851178479Sjb	}
852178479Sjb
853178479Sjb	ASSERT(nvc->nvc_port != NULL);
854178479Sjb	nvp = &(nvc->nvc_port[cport]);
855178479Sjb	ASSERT(nvp != NULL);
856178479Sjb
857178479Sjb	NVLOG((NVDBG_PROBE, nvc, nvp,
858178479Sjb	    "nv_sata_probe: enter cport: 0x%x, pmport: 0x%x, "
859178479Sjb	    "qual: 0x%x", cport, pmport, qual));
860178479Sjb
861178479Sjb	mutex_enter(&nvp->nvp_mutex);
862178479Sjb
863178479Sjb	/*
864178479Sjb	 * This check seems to be done in the SATA module.
865178479Sjb	 * It may not be required here
866178479Sjb	 */
867178479Sjb	if (nvp->nvp_state & NV_PORT_INACTIVE) {
868178479Sjb		nv_cmn_err(CE_WARN, nvc, nvp,
869178479Sjb		    "port inactive.  Use cfgadm to activate");
870178479Sjb		sd->satadev_type = SATA_DTYPE_UNKNOWN;
871178479Sjb		sd->satadev_state = SATA_PSTATE_SHUTDOWN;
872178479Sjb		mutex_exit(&nvp->nvp_mutex);
873184696Srodrigc
874178479Sjb		return (SATA_FAILURE);
875178479Sjb	}
876184696Srodrigc
877184696Srodrigc	if (qual == SATA_ADDR_PMPORT) {
878178479Sjb		sd->satadev_type = SATA_DTYPE_NONE;
879184696Srodrigc		sd->satadev_state = SATA_STATE_UNKNOWN;
880178479Sjb		mutex_exit(&nvp->nvp_mutex);
881178479Sjb		nv_cmn_err(CE_WARN, nvc, nvp,
882184696Srodrigc		    "controller does not support port multiplier");
883184696Srodrigc
884178479Sjb		return (SATA_FAILURE);
885184696Srodrigc	}
886178479Sjb
887178479Sjb	sd->satadev_state = SATA_PSTATE_PWRON;
888178479Sjb
889178479Sjb	nv_copy_registers(nvp, sd, NULL);
890178479Sjb
891178479Sjb	/*
892178479Sjb	 * determine link status
893178479Sjb	 */
894178479Sjb	if (nv_check_link(sd->satadev_scr.sstatus) == B_FALSE) {
895178479Sjb		uint8_t det;
896178479Sjb
897178479Sjb		/*
898178479Sjb		 * Reset will cause the link to go down for a short period of
899178479Sjb		 * time.  If link is lost for less than 2 seconds ignore it
900178479Sjb		 * so that the reset can progress.
901178479Sjb		 */
902178479Sjb		if (nvp->nvp_state & NV_PORT_RESET_PROBE) {
903178479Sjb
904178479Sjb			if (nvp->nvp_link_lost_time == 0) {
905178479Sjb				nvp->nvp_link_lost_time = nv_lbolt;
906178479Sjb			}
907178479Sjb
908178479Sjb			if (TICK_TO_SEC(nv_lbolt -
909178479Sjb			    nvp->nvp_link_lost_time) < NV_LINK_LOST_OK) {
910178479Sjb				NVLOG((NVDBG_ALWAYS, nvp->nvp_ctlp, nvp,
911178479Sjb				    "probe: intermittent link lost while"
912178479Sjb				    " resetting"));
913178479Sjb				/*
914178479Sjb				 * fake status of link so that probe continues
915178479Sjb				 */
916178479Sjb				SSTATUS_SET_IPM(sd->satadev_scr.sstatus,
917178479Sjb				    SSTATUS_IPM_ACTIVE);
918178479Sjb				SSTATUS_SET_DET(sd->satadev_scr.sstatus,
919184696Srodrigc				    SSTATUS_DET_DEVPRE_PHYCOM);
920184696Srodrigc				sd->satadev_type = SATA_DTYPE_UNKNOWN;
921184696Srodrigc				mutex_exit(&nvp->nvp_mutex);
922184696Srodrigc
923184696Srodrigc				return (SATA_SUCCESS);
924184696Srodrigc			} else {
925184696Srodrigc				nvp->nvp_state &=
926184696Srodrigc				    ~(NV_PORT_RESET_PROBE|NV_PORT_RESET);
927184696Srodrigc			}
928184696Srodrigc		}
929184696Srodrigc
930178479Sjb		/*
931178479Sjb		 * no link, so tear down port and abort all active packets
932178479Sjb		 */
933178479Sjb
934178479Sjb		det = (sd->satadev_scr.sstatus & SSTATUS_DET) >>
935178479Sjb		    SSTATUS_DET_SHIFT;
936178479Sjb
937178479Sjb		switch (det) {
938184696Srodrigc		case SSTATUS_DET_NODEV:
939184696Srodrigc		case SSTATUS_DET_PHYOFFLINE:
940184696Srodrigc			sd->satadev_type = SATA_DTYPE_NONE;
941184696Srodrigc			break;
942184696Srodrigc		default:
943184696Srodrigc			sd->satadev_type = SATA_DTYPE_UNKNOWN;
944184696Srodrigc			break;
945184696Srodrigc		}
946184696Srodrigc
947184696Srodrigc		NVLOG((NVDBG_PROBE, nvp->nvp_ctlp, nvp,
948178479Sjb		    "probe: link lost invoking nv_abort_active"));
949178479Sjb
950178479Sjb		(void) nv_abort_active(nvp, NULL, SATA_PKT_TIMEOUT);
951178479Sjb		nv_uninit_port(nvp);
952178479Sjb
953178479Sjb		mutex_exit(&nvp->nvp_mutex);
954178479Sjb
955178479Sjb		return (SATA_SUCCESS);
956178479Sjb	} else {
957178479Sjb		nvp->nvp_link_lost_time = 0;
958178479Sjb	}
959178479Sjb
960178479Sjb	/*
961178479Sjb	 * A device is present so clear hotremoved flag
962178479Sjb	 */
963178479Sjb	nvp->nvp_state &= ~NV_PORT_HOTREMOVED;
964178479Sjb
965178479Sjb	/*
966178573Sjb	 * If the signature was acquired previously there is no need to
967178479Sjb	 * do it again.
968178573Sjb	 */
969178479Sjb	if (nvp->nvp_signature != 0) {
970178479Sjb		NVLOG((NVDBG_PROBE, nvp->nvp_ctlp, nvp,
971178479Sjb		    "probe: signature acquired previously"));
972178479Sjb		sd->satadev_type = nvp->nvp_type;
973178479Sjb		mutex_exit(&nvp->nvp_mutex);
974178479Sjb
975178479Sjb		return (SATA_SUCCESS);
976178479Sjb	}
977178479Sjb
978178573Sjb	/*
979178479Sjb	 * If NV_PORT_RESET is not set, this is the first time through
980178479Sjb	 * so perform reset and return.
981178479Sjb	 */
982178479Sjb	if ((nvp->nvp_state & NV_PORT_RESET) == 0) {
983178479Sjb		NVLOG((NVDBG_PROBE, nvp->nvp_ctlp, nvp,
984178479Sjb		    "probe: first reset to get sig"));
985178479Sjb		nvp->nvp_state |= NV_PORT_RESET_PROBE;
986178479Sjb		nv_reset(nvp);
987178479Sjb		sd->satadev_type = nvp->nvp_type = SATA_DTYPE_UNKNOWN;
988178479Sjb		nvp->nvp_probe_time = nv_lbolt;
989178479Sjb		mutex_exit(&nvp->nvp_mutex);
990178479Sjb
991178479Sjb		return (SATA_SUCCESS);
992178479Sjb	}
993178479Sjb
994178479Sjb	/*
995178479Sjb	 * Reset was done previously.  see if the signature is
996178479Sjb	 * available.
997178479Sjb	 */
998178479Sjb	nv_read_signature(nvp);
999178479Sjb	sd->satadev_type = nvp->nvp_type;
1000178479Sjb
1001178479Sjb	/*
1002178573Sjb	 * Some drives may require additional resets to get a
1003178573Sjb	 * valid signature.  If a drive was not just powered up, the signature
1004178479Sjb	 * should arrive within half a second of reset.  Therefore if more
1005178479Sjb	 * than 5 seconds has elapsed while waiting for a signature, reset
1006178573Sjb	 * again.  These extra resets do not appear to create problems when
1007178573Sjb	 * the drive is spinning up for more than this reset period.
1008178573Sjb	 */
1009178479Sjb	if (nvp->nvp_signature == 0) {
1010178479Sjb		if (TICK_TO_SEC(nv_lbolt - nvp->nvp_reset_time) > 5) {
1011178479Sjb			NVLOG((NVDBG_PROBE, nvc, nvp, "additional reset"
1012178479Sjb			    " during signature acquisition"));
1013178573Sjb			nv_reset(nvp);
1014178573Sjb		}
1015178479Sjb
1016178479Sjb		mutex_exit(&nvp->nvp_mutex);
1017178479Sjb
1018178479Sjb		return (SATA_SUCCESS);
1019178479Sjb	}
1020178573Sjb
1021178573Sjb	NVLOG((NVDBG_PROBE, nvc, nvp, "signature acquired after %d ms",
1022178479Sjb	    TICK_TO_MSEC(nv_lbolt - nvp->nvp_probe_time)));
1023178479Sjb
1024178479Sjb	/*
1025178479Sjb	 * nv_sata only deals with ATA disks and ATAPI CD/DVDs so far.  If
1026178479Sjb	 * it is not either of those, then just return.
1027178479Sjb	 */
1028178573Sjb	if ((nvp->nvp_type != SATA_DTYPE_ATADISK) &&
1029178573Sjb	    (nvp->nvp_type != SATA_DTYPE_ATAPICD)) {
1030178479Sjb		NVLOG((NVDBG_PROBE, nvc, nvp, "Driver currently handles only"
1031178573Sjb		    " disks/CDs/DVDs.  Signature acquired was %X",
1032178573Sjb		    nvp->nvp_signature));
1033178573Sjb		mutex_exit(&nvp->nvp_mutex);
1034178479Sjb
1035178479Sjb		return (SATA_SUCCESS);
1036178479Sjb	}
1037178573Sjb
1038178573Sjb	/*
1039178479Sjb	 * make sure structures are initialized
1040178479Sjb	 */
1041178479Sjb	if (nv_init_port(nvp) == NV_SUCCESS) {
1042178479Sjb		NVLOG((NVDBG_PROBE, nvc, nvp,
1043178479Sjb		    "device detected and set up at port %d", cport));
1044178479Sjb		mutex_exit(&nvp->nvp_mutex);
1045178479Sjb
1046178479Sjb		return (SATA_SUCCESS);
1047178573Sjb	} else {
1048178479Sjb		nv_cmn_err(CE_WARN, nvc, nvp, "failed to set up data "
1049178479Sjb		    "structures for port %d", cport);
1050178479Sjb		mutex_exit(&nvp->nvp_mutex);
1051178479Sjb
1052178479Sjb		return (SATA_FAILURE);
1053178479Sjb	}
1054178479Sjb	/*NOTREACHED*/
1055178479Sjb}
1056178573Sjb
1057178479Sjb
1058178479Sjb/*
1059178479Sjb * Called by sata module to start a new command.
1060178479Sjb */
1061178479Sjbstatic int
1062178573Sjbnv_sata_start(dev_info_t *dip, sata_pkt_t *spkt)
1063178479Sjb{
1064178479Sjb	int cport = spkt->satapkt_device.satadev_addr.cport;
1065178479Sjb	nv_ctl_t *nvc = ddi_get_soft_state(nv_statep, ddi_get_instance(dip));
1066178479Sjb	nv_port_t *nvp = &(nvc->nvc_port[cport]);
1067178479Sjb	int ret;
1068178479Sjb
1069178479Sjb	NVLOG((NVDBG_ENTRY, nvc, nvp, "nv_sata_start: opmode: 0x%x cmd=%x",
1070178479Sjb	    spkt->satapkt_op_mode, spkt->satapkt_cmd.satacmd_cmd_reg));
1071178479Sjb
1072178479Sjb	mutex_enter(&nvp->nvp_mutex);
1073178479Sjb
1074178479Sjb	/*
1075178479Sjb	 * hotremoved is an intermediate state where the link was lost,
1076178479Sjb	 * but the hotplug event has not yet been processed by the sata
1077178479Sjb	 * module.  Fail the request.
1078178479Sjb	 */
1079178479Sjb	if (nvp->nvp_state & NV_PORT_HOTREMOVED) {
1080178479Sjb		spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1081178479Sjb		spkt->satapkt_device.satadev_state = SATA_STATE_UNKNOWN;
1082178479Sjb		NVLOG((NVDBG_ERRS, nvc, nvp,
1083178479Sjb		    "nv_sata_start: NV_PORT_HOTREMOVED"));
1084178479Sjb		nv_copy_registers(nvp, &spkt->satapkt_device, NULL);
1085178479Sjb		mutex_exit(&nvp->nvp_mutex);
1086178479Sjb
1087178479Sjb		return (SATA_TRAN_PORT_ERROR);
1088178479Sjb	}
1089178479Sjb
1090178479Sjb	if (nvp->nvp_state & NV_PORT_RESET) {
1091178479Sjb		NVLOG((NVDBG_ERRS, nvc, nvp,
1092178479Sjb		    "still waiting for reset completion"));
1093178479Sjb		spkt->satapkt_reason = SATA_PKT_BUSY;
1094178479Sjb		mutex_exit(&nvp->nvp_mutex);
1095178479Sjb
1096178479Sjb		/*
1097178479Sjb		 * If in panic, timeouts do not occur, so fake one
1098178479Sjb		 * so that the signature can be acquired to complete
1099178479Sjb		 * the reset handling.
1100178479Sjb		 */
1101178479Sjb		if (ddi_in_panic()) {
1102178479Sjb			nv_timeout(nvp);
1103178479Sjb		}
1104178479Sjb
1105178479Sjb		return (SATA_TRAN_BUSY);
1106178479Sjb	}
1107178479Sjb
1108178479Sjb	if (nvp->nvp_type == SATA_DTYPE_NONE) {
1109178479Sjb		spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1110178479Sjb		NVLOG((NVDBG_ERRS, nvc, nvp,
1111178479Sjb		    "nv_sata_start: SATA_DTYPE_NONE"));
1112178479Sjb		nv_copy_registers(nvp, &spkt->satapkt_device, NULL);
1113178479Sjb		mutex_exit(&nvp->nvp_mutex);
1114178479Sjb
1115178479Sjb		return (SATA_TRAN_PORT_ERROR);
1116178479Sjb	}
1117178479Sjb
1118178479Sjb	if (spkt->satapkt_device.satadev_type == SATA_DTYPE_PMULT) {
1119178479Sjb		ASSERT(nvp->nvp_type == SATA_DTYPE_PMULT);
1120178479Sjb		nv_cmn_err(CE_WARN, nvc, nvp,
1121178479Sjb		    "port multipliers not supported by controller");
1122178479Sjb		spkt->satapkt_reason = SATA_PKT_CMD_UNSUPPORTED;
1123178479Sjb		mutex_exit(&nvp->nvp_mutex);
1124178479Sjb
1125178479Sjb		return (SATA_TRAN_CMD_UNSUPPORTED);
1126178479Sjb	}
1127178479Sjb
1128178479Sjb	if ((nvp->nvp_state & NV_PORT_INIT) == 0) {
1129178479Sjb		spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1130178479Sjb		NVLOG((NVDBG_ERRS, nvc, nvp,
1131178479Sjb		    "nv_sata_start: port not yet initialized"));
1132178479Sjb		nv_copy_registers(nvp, &spkt->satapkt_device, NULL);
1133178479Sjb		mutex_exit(&nvp->nvp_mutex);
1134178479Sjb
1135178479Sjb		return (SATA_TRAN_PORT_ERROR);
1136178479Sjb	}
1137178479Sjb
1138178479Sjb	if (nvp->nvp_state & NV_PORT_INACTIVE) {
1139178479Sjb		spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1140178479Sjb		NVLOG((NVDBG_ERRS, nvc, nvp,
1141178479Sjb		    "nv_sata_start: NV_PORT_INACTIVE"));
1142178479Sjb		nv_copy_registers(nvp, &spkt->satapkt_device, NULL);
1143178479Sjb		mutex_exit(&nvp->nvp_mutex);
1144178479Sjb
1145178479Sjb		return (SATA_TRAN_PORT_ERROR);
1146178479Sjb	}
1147178479Sjb
1148178479Sjb	if (nvp->nvp_state & NV_PORT_FAILED) {
1149178479Sjb		spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1150178479Sjb		NVLOG((NVDBG_ERRS, nvc, nvp,
1151178479Sjb		    "nv_sata_start: NV_PORT_FAILED state"));
1152178479Sjb		nv_copy_registers(nvp, &spkt->satapkt_device, NULL);
1153178479Sjb		mutex_exit(&nvp->nvp_mutex);
1154178479Sjb
1155178479Sjb		return (SATA_TRAN_PORT_ERROR);
1156178479Sjb	}
1157178573Sjb
1158178573Sjb	/*
1159178573Sjb	 * after a device reset, and then when sata module restore processing
1160178573Sjb	 * is complete, the sata module will set sata_clear_dev_reset which
1161178573Sjb	 * indicates that restore processing has completed and normal
1162178573Sjb	 * non-restore related commands should be processed.
1163178573Sjb	 */
1164178479Sjb	if (spkt->satapkt_cmd.satacmd_flags.sata_clear_dev_reset) {
1165178479Sjb		nvp->nvp_state &= ~NV_PORT_RESTORE;
1166178479Sjb		NVLOG((NVDBG_ENTRY, nvc, nvp,
1167178479Sjb		    "nv_sata_start: clearing NV_PORT_RESTORE"));
1168178479Sjb	}
1169178479Sjb
1170178479Sjb	/*
1171178573Sjb	 * if the device was recently reset as indicated by NV_PORT_RESTORE,
1172178573Sjb	 * only allow commands which restore device state.  The sata module
1173178573Sjb	 * marks such commands with with sata_ignore_dev_reset.
1174178573Sjb	 *
1175178573Sjb	 * during coredump, nv_reset is called and but then the restore
1176178573Sjb	 * doesn't happen.  For now, workaround by ignoring the wait for
1177178573Sjb	 * restore if the system is panicing.
1178178479Sjb	 */
1179178479Sjb	if ((nvp->nvp_state & NV_PORT_RESTORE) &&
1180178573Sjb	    !(spkt->satapkt_cmd.satacmd_flags.sata_ignore_dev_reset) &&
1181178479Sjb	    (ddi_in_panic() == 0)) {
1182178479Sjb		spkt->satapkt_reason = SATA_PKT_BUSY;
1183178479Sjb		NVLOG((NVDBG_ENTRY, nvc, nvp,
1184178479Sjb		    "nv_sata_start: waiting for restore "));
1185178479Sjb		mutex_exit(&nvp->nvp_mutex);
1186178479Sjb
1187178479Sjb		return (SATA_TRAN_BUSY);
1188178479Sjb	}
1189178479Sjb
1190178479Sjb	if (nvp->nvp_state & NV_PORT_ABORTING) {
1191178479Sjb		spkt->satapkt_reason = SATA_PKT_BUSY;
1192178479Sjb		NVLOG((NVDBG_ERRS, nvc, nvp,
1193178479Sjb		    "nv_sata_start: NV_PORT_ABORTING"));
1194178479Sjb		mutex_exit(&nvp->nvp_mutex);
1195178479Sjb
1196178479Sjb		return (SATA_TRAN_BUSY);
1197178479Sjb	}
1198178479Sjb
1199178479Sjb	if (spkt->satapkt_op_mode &
1200178479Sjb	    (SATA_OPMODE_POLLING|SATA_OPMODE_SYNCH)) {
1201178479Sjb
1202178479Sjb		ret = nv_start_sync(nvp, spkt);
1203178479Sjb
1204178479Sjb		mutex_exit(&nvp->nvp_mutex);
1205178479Sjb
1206178479Sjb		return (ret);
1207178479Sjb	}
1208178479Sjb
1209178479Sjb	/*
1210178479Sjb	 * start command asynchronous command
1211178479Sjb	 */
1212178479Sjb	ret = nv_start_async(nvp, spkt);
1213178479Sjb
1214178479Sjb	mutex_exit(&nvp->nvp_mutex);
1215178479Sjb
1216178479Sjb	return (ret);
1217178479Sjb}
1218178479Sjb
1219178479Sjb
1220178479Sjb/*
1221178479Sjb * SATA_OPMODE_POLLING implies the driver is in a
1222178479Sjb * synchronous mode, and SATA_OPMODE_SYNCH is also set.
1223178479Sjb * If only SATA_OPMODE_SYNCH is set, the driver can use
1224178479Sjb * interrupts and sleep wait on a cv.
1225178479Sjb *
1226178479Sjb * If SATA_OPMODE_POLLING is set, the driver can't use
1227178479Sjb * interrupts and must busy wait and simulate the
1228178479Sjb * interrupts by waiting for BSY to be cleared.
1229178479Sjb *
1230178479Sjb * Synchronous mode has to return BUSY if there are
1231178479Sjb * any other commands already on the drive.
1232178479Sjb */
1233178479Sjbstatic int
1234178479Sjbnv_start_sync(nv_port_t *nvp, sata_pkt_t *spkt)
1235178479Sjb{
1236178479Sjb	nv_ctl_t *nvc = nvp->nvp_ctlp;
1237178479Sjb	int ret;
1238178479Sjb
1239178479Sjb	NVLOG((NVDBG_SYNC, nvp->nvp_ctlp, nvp, "nv_sata_satapkt_sync: entry"));
1240178479Sjb
1241178479Sjb	if (nvp->nvp_ncq_run != 0 || nvp->nvp_non_ncq_run != 0) {
1242178479Sjb		spkt->satapkt_reason = SATA_PKT_BUSY;
1243178479Sjb		NVLOG((NVDBG_SYNC, nvp->nvp_ctlp, nvp,
1244178479Sjb		    "nv_sata_satapkt_sync: device is busy, sync cmd rejected"
1245178479Sjb		    "ncq_run: %d non_ncq_run: %d  spkt: %p",
1246178479Sjb		    nvp->nvp_ncq_run, nvp->nvp_non_ncq_run,
1247178479Sjb		    (&(nvp->nvp_slot[0]))->nvslot_spkt));
1248178479Sjb
1249178479Sjb		return (SATA_TRAN_BUSY);
1250178479Sjb	}
1251178479Sjb
1252178479Sjb	/*
1253178479Sjb	 * if SYNC but not POLL, verify that this is not on interrupt thread.
1254178479Sjb	 */
1255178479Sjb	if (!(spkt->satapkt_op_mode & SATA_OPMODE_POLLING) &&
1256178479Sjb	    servicing_interrupt()) {
1257178479Sjb		spkt->satapkt_reason = SATA_PKT_BUSY;
1258178479Sjb		NVLOG((NVDBG_SYNC, nvp->nvp_ctlp, nvp,
1259178479Sjb		    "SYNC mode not allowed during interrupt"));
1260178479Sjb
1261178479Sjb		return (SATA_TRAN_BUSY);
1262178479Sjb
1263178479Sjb	}
1264178479Sjb
1265178479Sjb	/*
1266178479Sjb	 * disable interrupt generation if in polled mode
1267178479Sjb	 */
1268178479Sjb	if (spkt->satapkt_op_mode & SATA_OPMODE_POLLING) {
1269178479Sjb		(*(nvc->nvc_set_intr))(nvp, NV_INTR_DISABLE);
1270178479Sjb	}
1271178479Sjb
1272178479Sjb	if ((ret = nv_start_common(nvp, spkt)) != SATA_TRAN_ACCEPTED) {
1273178479Sjb		if (spkt->satapkt_op_mode & SATA_OPMODE_POLLING) {
1274178479Sjb			(*(nvc->nvc_set_intr))(nvp, NV_INTR_ENABLE);
1275178479Sjb		}
1276178479Sjb
1277178479Sjb		return (ret);
1278178479Sjb	}
1279178479Sjb
1280178479Sjb	if (spkt->satapkt_op_mode & SATA_OPMODE_POLLING) {
1281178479Sjb		mutex_exit(&nvp->nvp_mutex);
1282178479Sjb		ret = nv_poll_wait(nvp, spkt);
1283178479Sjb		mutex_enter(&nvp->nvp_mutex);
1284178479Sjb
1285178479Sjb		(*(nvc->nvc_set_intr))(nvp, NV_INTR_ENABLE);
1286178479Sjb
1287178479Sjb		NVLOG((NVDBG_SYNC, nvp->nvp_ctlp, nvp, "nv_sata_satapkt_sync:"
1288178479Sjb		    " done % reason %d", ret));
1289178479Sjb
1290178479Sjb		return (ret);
1291178479Sjb	}
1292178479Sjb
1293178479Sjb	/*
1294178479Sjb	 * non-polling synchronous mode handling.  The interrupt will signal
1295178479Sjb	 * when the IO is completed.
1296178479Sjb	 */
1297178479Sjb	cv_wait(&nvp->nvp_poll_cv, &nvp->nvp_mutex);
1298178479Sjb
1299178479Sjb	if (spkt->satapkt_reason != SATA_PKT_COMPLETED) {
1300178479Sjb
1301178479Sjb		spkt->satapkt_reason = SATA_PKT_TIMEOUT;
1302178479Sjb	}
1303178479Sjb
1304178479Sjb	NVLOG((NVDBG_SYNC, nvp->nvp_ctlp, nvp, "nv_sata_satapkt_sync:"
1305178479Sjb	    " done % reason %d", spkt->satapkt_reason));
1306178479Sjb
1307178479Sjb	return (SATA_TRAN_ACCEPTED);
1308178479Sjb}
1309178479Sjb
1310178479Sjb
1311178479Sjbstatic int
1312178479Sjbnv_poll_wait(nv_port_t *nvp, sata_pkt_t *spkt)
1313178479Sjb{
1314178479Sjb	int ret;
1315178479Sjb	nv_ctl_t *nvc = nvp->nvp_ctlp;
1316178479Sjb#if ! defined(__lock_lint)
1317178479Sjb	nv_slot_t *nv_slotp = &(nvp->nvp_slot[0]); /* not NCQ aware */
1318178479Sjb#endif
1319178479Sjb
1320178479Sjb	NVLOG((NVDBG_SYNC, nvc, nvp, "nv_poll_wait: enter"));
1321178479Sjb
1322178479Sjb	for (;;) {
1323178479Sjb
1324178479Sjb		NV_DELAY_NSEC(400);
1325178479Sjb
1326178479Sjb		NVLOG((NVDBG_SYNC, nvc, nvp, "nv_poll_wait: before nv_wait"));
1327178479Sjb		if (nv_wait(nvp, 0, SATA_STATUS_BSY,
1328178479Sjb		    NV_SEC2USEC(spkt->satapkt_time), NV_NOSLEEP) == B_FALSE) {
1329178479Sjb			mutex_enter(&nvp->nvp_mutex);
1330178479Sjb			spkt->satapkt_reason = SATA_PKT_TIMEOUT;
1331178479Sjb			nv_copy_registers(nvp, &spkt->satapkt_device, spkt);
1332178479Sjb			nv_reset(nvp);
1333178479Sjb			nv_complete_io(nvp, spkt, 0);
1334178479Sjb			mutex_exit(&nvp->nvp_mutex);
1335178479Sjb			NVLOG((NVDBG_SYNC, nvc, nvp, "nv_poll_wait: "
1336178479Sjb			    "SATA_STATUS_BSY"));
1337178479Sjb
1338178479Sjb			return (SATA_TRAN_ACCEPTED);
1339178479Sjb		}
1340178479Sjb
1341178479Sjb		NVLOG((NVDBG_SYNC, nvc, nvp, "nv_poll_wait: before nvc_intr"));
1342178479Sjb
1343178479Sjb		/*
1344178479Sjb		 * Simulate interrupt.
1345178479Sjb		 */
1346178479Sjb		ret = (*(nvc->nvc_interrupt))((caddr_t)nvc, NULL);
1347178479Sjb		NVLOG((NVDBG_SYNC, nvc, nvp, "nv_poll_wait: after nvc_intr"));
1348178479Sjb
1349178479Sjb		if (ret != DDI_INTR_CLAIMED) {
1350178479Sjb			NVLOG((NVDBG_SYNC, nvc, nvp, "nv_poll_wait:"
1351178479Sjb			    " unclaimed -- resetting"));
1352178479Sjb			mutex_enter(&nvp->nvp_mutex);
1353178479Sjb			nv_copy_registers(nvp, &spkt->satapkt_device, spkt);
1354178479Sjb			nv_reset(nvp);
1355178479Sjb			spkt->satapkt_reason = SATA_PKT_TIMEOUT;
1356178479Sjb			nv_complete_io(nvp, spkt, 0);
1357178479Sjb			mutex_exit(&nvp->nvp_mutex);
1358178479Sjb
1359178479Sjb			return (SATA_TRAN_ACCEPTED);
1360178479Sjb		}
1361178479Sjb
1362178479Sjb#if ! defined(__lock_lint)
1363178479Sjb		if (nv_slotp->nvslot_flags == NVSLOT_COMPLETE) {
1364178479Sjb			/*
1365178479Sjb			 * packet is complete
1366178479Sjb			 */
1367178479Sjb			return (SATA_TRAN_ACCEPTED);
1368178479Sjb		}
1369178479Sjb#endif
1370178479Sjb	}
1371178479Sjb	/*NOTREACHED*/
1372178479Sjb}
1373178479Sjb
1374178479Sjb
1375178479Sjb/*
1376178479Sjb * Called by sata module to abort outstanding packets.
1377178479Sjb */
1378178479Sjb/*ARGSUSED*/
1379178479Sjbstatic int
1380178479Sjbnv_sata_abort(dev_info_t *dip, sata_pkt_t *spkt, int flag)
1381178479Sjb{
1382178479Sjb	int cport = spkt->satapkt_device.satadev_addr.cport;
1383178479Sjb	nv_ctl_t *nvc = ddi_get_soft_state(nv_statep, ddi_get_instance(dip));
1384178479Sjb	nv_port_t *nvp = &(nvc->nvc_port[cport]);
1385178479Sjb	int c_a, ret;
1386178479Sjb
1387178479Sjb	ASSERT(cport < NV_MAX_PORTS(nvc));
1388178479Sjb	NVLOG((NVDBG_ENTRY, nvc, nvp, "nv_sata_abort %d %p", flag, spkt));
1389178479Sjb
1390178479Sjb	mutex_enter(&nvp->nvp_mutex);
1391178479Sjb
1392178479Sjb	if (nvp->nvp_state & NV_PORT_INACTIVE) {
1393178479Sjb		mutex_exit(&nvp->nvp_mutex);
1394178479Sjb		nv_cmn_err(CE_WARN, nvc, nvp,
1395178479Sjb		    "abort request failed: port inactive");
1396178479Sjb
1397178479Sjb		return (SATA_FAILURE);
1398178479Sjb	}
1399178479Sjb
1400178479Sjb	/*
1401178479Sjb	 * spkt == NULL then abort all commands
1402178479Sjb	 */
1403178479Sjb	c_a = nv_abort_active(nvp, spkt, SATA_PKT_ABORTED);
1404178479Sjb
1405178479Sjb	if (c_a) {
1406178479Sjb		NVLOG((NVDBG_ENTRY, nvc, nvp,
1407178479Sjb		    "packets aborted running=%d", c_a));
1408178479Sjb		ret = SATA_SUCCESS;
1409178479Sjb	} else {
1410178479Sjb		if (spkt == NULL) {
1411178479Sjb			NVLOG((NVDBG_ENTRY, nvc, nvp, "no spkts to abort"));
1412178479Sjb		} else {
1413178479Sjb			NVLOG((NVDBG_ENTRY, nvc, nvp,
1414178479Sjb			    "can't find spkt to abort"));
1415178479Sjb		}
1416178479Sjb		ret = SATA_FAILURE;
1417178479Sjb	}
1418178479Sjb
1419178479Sjb	mutex_exit(&nvp->nvp_mutex);
1420178479Sjb
1421178479Sjb	return (ret);
1422178479Sjb}
1423178479Sjb
1424178479Sjb
1425178479Sjb/*
1426178479Sjb * if spkt == NULL abort all pkts running, otherwise
1427178479Sjb * abort the requested packet.  must be called with nv_mutex
1428178479Sjb * held and returns with it held.  Not NCQ aware.
1429178479Sjb */
1430178479Sjbstatic int
1431178479Sjbnv_abort_active(nv_port_t *nvp, sata_pkt_t *spkt, int abort_reason)
1432178479Sjb{
1433178479Sjb	int aborted = 0, i, reset_once = B_FALSE;
1434178479Sjb	struct nv_slot *nv_slotp;
1435178479Sjb	sata_pkt_t *spkt_slot;
1436178479Sjb
1437178479Sjb	ASSERT(MUTEX_HELD(&nvp->nvp_mutex));
1438178479Sjb
1439178479Sjb	/*
1440178479Sjb	 * return if the port is not configured
1441178479Sjb	 */
1442178479Sjb	if (nvp->nvp_slot == NULL) {
1443178479Sjb		NVLOG((NVDBG_ENTRY, nvp->nvp_ctlp, nvp,
1444178479Sjb		    "nv_abort_active: not configured so returning"));
1445178479Sjb
1446178479Sjb		return (0);
1447178479Sjb	}
1448178479Sjb
1449178479Sjb	NVLOG((NVDBG_ENTRY, nvp->nvp_ctlp, nvp, "nv_abort_active"));
1450178479Sjb
1451178479Sjb	nvp->nvp_state |= NV_PORT_ABORTING;
1452178479Sjb
1453178479Sjb	for (i = 0; i < nvp->nvp_queue_depth; i++) {
1454178479Sjb
1455178479Sjb		nv_slotp = &(nvp->nvp_slot[i]);
1456178479Sjb		spkt_slot = nv_slotp->nvslot_spkt;
1457178479Sjb
1458178479Sjb		/*
1459178479Sjb		 * skip if not active command in slot
1460178479Sjb		 */
1461178479Sjb		if (spkt_slot == NULL) {
1462178479Sjb			continue;
1463178479Sjb		}
1464178479Sjb
1465178479Sjb		/*
1466178479Sjb		 * if a specific packet was requested, skip if
1467178479Sjb		 * this is not a match
1468178479Sjb		 */
1469178479Sjb		if ((spkt != NULL) && (spkt != spkt_slot)) {
1470178479Sjb			continue;
1471178479Sjb		}
1472178479Sjb
1473178479Sjb		/*
1474178479Sjb		 * stop the hardware.  This could need reworking
1475178479Sjb		 * when NCQ is enabled in the driver.
1476178479Sjb		 */
1477178479Sjb		if (reset_once == B_FALSE) {
1478178479Sjb			ddi_acc_handle_t bmhdl = nvp->nvp_bm_hdl;
1479178479Sjb
1480178479Sjb			/*
1481178479Sjb			 * stop DMA engine
1482178479Sjb			 */
1483178479Sjb			nv_put8(bmhdl, nvp->nvp_bmicx,  0);
1484178479Sjb
1485178479Sjb			nv_reset(nvp);
1486178479Sjb			reset_once = B_TRUE;
1487178479Sjb		}
1488178479Sjb
1489178479Sjb		spkt_slot->satapkt_reason = abort_reason;
1490178479Sjb		nv_complete_io(nvp, spkt_slot, i);
1491178479Sjb		aborted++;
1492178479Sjb	}
1493178479Sjb
1494178479Sjb	nvp->nvp_state &= ~NV_PORT_ABORTING;
1495178479Sjb
1496178479Sjb	return (aborted);
1497178479Sjb}
1498178479Sjb
1499178479Sjb
1500178479Sjb/*
1501178479Sjb * Called by sata module to reset a port, device, or the controller.
1502178479Sjb */
1503178479Sjbstatic int
1504178479Sjbnv_sata_reset(dev_info_t *dip, sata_device_t *sd)
1505178479Sjb{
1506178479Sjb	int cport = sd->satadev_addr.cport;
1507178479Sjb	nv_ctl_t *nvc = ddi_get_soft_state(nv_statep, ddi_get_instance(dip));
1508178479Sjb	nv_port_t *nvp = &(nvc->nvc_port[cport]);
1509178479Sjb	int ret = SATA_SUCCESS;
1510178479Sjb
1511178479Sjb	ASSERT(cport < NV_MAX_PORTS(nvc));
1512178479Sjb
1513178479Sjb	NVLOG((NVDBG_ENTRY, nvc, nvp, "nv_sata_reset"));
1514178479Sjb
1515178479Sjb	mutex_enter(&nvp->nvp_mutex);
1516178479Sjb
1517178479Sjb	switch (sd->satadev_addr.qual) {
1518178479Sjb
1519178479Sjb	case SATA_ADDR_CPORT:
1520178479Sjb		/*FALLTHROUGH*/
1521178479Sjb	case SATA_ADDR_DCPORT:
1522178479Sjb		nv_reset(nvp);
1523178479Sjb		(void) nv_abort_active(nvp, NULL, SATA_PKT_RESET);
1524211554Srpaulo
1525178479Sjb		break;
1526178479Sjb	case SATA_ADDR_CNTRL:
1527178479Sjb		NVLOG((NVDBG_ENTRY, nvc, nvp,
1528178479Sjb		    "nv_sata_reset: constroller reset not supported"));
1529178479Sjb
1530178479Sjb		break;
1531211554Srpaulo	case SATA_ADDR_PMPORT:
1532211554Srpaulo	case SATA_ADDR_DPMPORT:
1533211554Srpaulo		NVLOG((NVDBG_ENTRY, nvc, nvp,
1534211554Srpaulo		    "nv_sata_reset: port multipliers not supported"));
1535211554Srpaulo		/*FALLTHROUGH*/
1536211554Srpaulo	default:
1537211554Srpaulo		/*
1538211554Srpaulo		 * unsupported case
1539211554Srpaulo		 */
1540211554Srpaulo		ret = SATA_FAILURE;
1541211554Srpaulo		break;
1542211554Srpaulo	}
1543211554Srpaulo
1544211554Srpaulo	if (ret == SATA_SUCCESS) {
1545211554Srpaulo		/*
1546211554Srpaulo		 * If the port is inactive, do a quiet reset and don't attempt
1547178479Sjb		 * to wait for reset completion or do any post reset processing
1548178479Sjb		 */
1549178479Sjb		if (nvp->nvp_state & NV_PORT_INACTIVE) {
1550178479Sjb			nvp->nvp_state &= ~NV_PORT_RESET;
1551178479Sjb			nvp->nvp_reset_time = 0;
1552178479Sjb		}
1553178479Sjb
1554178479Sjb		/*
1555178479Sjb		 * clear the port failed flag
1556178479Sjb		 */
1557178479Sjb		nvp->nvp_state &= ~NV_PORT_FAILED;
1558211554Srpaulo	}
1559211554Srpaulo
1560211554Srpaulo	mutex_exit(&nvp->nvp_mutex);
1561178479Sjb
1562178479Sjb	return (ret);
1563178479Sjb}
1564178479Sjb
1565178479Sjb
1566178479Sjb/*
1567178479Sjb * Sata entry point to handle port activation.  cfgadm -c connect
1568178479Sjb */
1569178479Sjbstatic int
1570178479Sjbnv_sata_activate(dev_info_t *dip, sata_device_t *sd)
1571178479Sjb{
1572178479Sjb	int cport = sd->satadev_addr.cport;
1573178479Sjb	nv_ctl_t *nvc = ddi_get_soft_state(nv_statep, ddi_get_instance(dip));
1574211554Srpaulo	nv_port_t *nvp = &(nvc->nvc_port[cport]);
1575211554Srpaulo
1576211554Srpaulo	ASSERT(cport < NV_MAX_PORTS(nvc));
1577178479Sjb	NVLOG((NVDBG_ENTRY, nvc, nvp, "nv_sata_activate"));
1578178479Sjb
1579178479Sjb	mutex_enter(&nvp->nvp_mutex);
1580178479Sjb
1581178479Sjb	sd->satadev_state = SATA_STATE_READY;
1582178479Sjb
1583178479Sjb	nv_copy_registers(nvp, sd, NULL);
1584178479Sjb
1585178479Sjb	(*(nvc->nvc_set_intr))(nvp, NV_INTR_ENABLE);
1586178479Sjb
1587178479Sjb	nvp->nvp_state = 0;
1588178479Sjb
1589178479Sjb	mutex_exit(&nvp->nvp_mutex);
1590178479Sjb
1591178479Sjb	return (SATA_SUCCESS);
1592178479Sjb}
1593178479Sjb
1594178479Sjb
1595178573Sjb/*
1596178573Sjb * Sata entry point to handle port deactivation.  cfgadm -c disconnect
1597211554Srpaulo */
1598211554Srpaulostatic int
1599211554Srpaulonv_sata_deactivate(dev_info_t *dip, sata_device_t *sd)
1600211554Srpaulo{
1601211554Srpaulo	int cport = sd->satadev_addr.cport;
1602211554Srpaulo	nv_ctl_t *nvc = ddi_get_soft_state(nv_statep, ddi_get_instance(dip));
1603211554Srpaulo	nv_port_t *nvp = &(nvc->nvc_port[cport]);
1604211554Srpaulo
1605211554Srpaulo	ASSERT(cport < NV_MAX_PORTS(nvc));
1606211554Srpaulo	NVLOG((NVDBG_ENTRY, nvc, nvp, "nv_sata_deactivate"));
1607211554Srpaulo
1608211554Srpaulo	mutex_enter(&nvp->nvp_mutex);
1609211554Srpaulo
1610178573Sjb	(void) nv_abort_active(nvp, NULL, SATA_PKT_RESET);
1611178479Sjb
1612178479Sjb	/*
1613178479Sjb	 * mark the device as inaccessible
1614178479Sjb	 */
1615178479Sjb	nvp->nvp_state &= ~NV_PORT_INACTIVE;
1616178479Sjb
1617178479Sjb	/*
1618178573Sjb	 * disable the interrupts on port
1619178573Sjb	 */
1620178573Sjb	(*(nvc->nvc_set_intr))(nvp, NV_INTR_DISABLE);
1621178573Sjb
1622178573Sjb	nv_uninit_port(nvp);
1623178479Sjb
1624178479Sjb	sd->satadev_state = SATA_PSTATE_SHUTDOWN;
1625178479Sjb	nv_copy_registers(nvp, sd, NULL);
1626178479Sjb
1627178479Sjb	mutex_exit(&nvp->nvp_mutex);
1628178479Sjb
1629178479Sjb	return (SATA_SUCCESS);
1630178479Sjb}
1631178479Sjb
1632178479Sjb
1633178479Sjb/*
1634178479Sjb * find an empty slot in the driver's queue, increment counters,
1635178479Sjb * and then invoke the appropriate PIO or DMA start routine.
1636178479Sjb */
1637178479Sjbstatic int
1638178479Sjbnv_start_common(nv_port_t *nvp, sata_pkt_t *spkt)
1639178479Sjb{
1640178479Sjb	sata_cmd_t *sata_cmdp = &spkt->satapkt_cmd;
1641178479Sjb	int on_bit = 0x01, slot, sactive, ret, ncq = 0;
1642178479Sjb	uint8_t cmd = spkt->satapkt_cmd.satacmd_cmd_reg;
1643178479Sjb	int direction = sata_cmdp->satacmd_flags.sata_data_direction;
1644178479Sjb	nv_ctl_t *nvc = nvp->nvp_ctlp;
1645178479Sjb	nv_slot_t *nv_slotp;
1646178479Sjb	boolean_t dma_cmd;
1647178479Sjb
1648178479Sjb	NVLOG((NVDBG_DELIVER, nvc, nvp, "nv_start_common  entered: cmd: 0x%x",
1649178479Sjb	    sata_cmdp->satacmd_cmd_reg));
1650178479Sjb
1651178479Sjb	if ((cmd == SATAC_WRITE_FPDMA_QUEUED) ||
1652178479Sjb	    (cmd == SATAC_READ_FPDMA_QUEUED)) {
1653178479Sjb		nvp->nvp_ncq_run++;
1654178479Sjb		/*
1655178479Sjb		 * search for an empty NCQ slot.  by the time, it's already
1656178479Sjb		 * been determined by the caller that there is room on the
1657178479Sjb		 * queue.
1658178479Sjb		 */
1659178479Sjb		for (slot = 0; slot < nvp->nvp_queue_depth; slot++,
1660178479Sjb		    on_bit <<= 1) {
1661178479Sjb			if ((nvp->nvp_sactive_cache & on_bit) == 0) {
1662178479Sjb				break;
1663178479Sjb			}
1664178479Sjb		}
1665178479Sjb
1666178479Sjb		/*
1667178479Sjb		 * the first empty slot found, should not exceed the queue
1668178479Sjb		 * depth of the drive.  if it does it's an error.
1669178479Sjb		 */
1670178479Sjb		ASSERT(slot != nvp->nvp_queue_depth);
1671178479Sjb
1672178479Sjb		sactive = nv_get32(nvc->nvc_bar_hdl[5],
1673178479Sjb		    nvp->nvp_sactive);
1674178479Sjb		ASSERT((sactive & on_bit) == 0);
1675178479Sjb		nv_put32(nvc->nvc_bar_hdl[5], nvp->nvp_sactive, on_bit);
1676178479Sjb		NVLOG((NVDBG_INIT, nvc, nvp, "setting SACTIVE onbit: %X",
1677178479Sjb		    on_bit));
1678178479Sjb		nvp->nvp_sactive_cache |= on_bit;
1679178479Sjb
1680178479Sjb		ncq = NVSLOT_NCQ;
1681178479Sjb
1682178479Sjb	} else {
1683178479Sjb		nvp->nvp_non_ncq_run++;
1684178573Sjb		slot = 0;
1685178479Sjb	}
1686178479Sjb
1687178479Sjb	nv_slotp = (nv_slot_t *)&nvp->nvp_slot[slot];
1688178479Sjb
1689178479Sjb	ASSERT(nv_slotp->nvslot_spkt == NULL);
1690178479Sjb
1691178479Sjb	nv_slotp->nvslot_spkt = spkt;
1692178479Sjb	nv_slotp->nvslot_flags = ncq;
1693178479Sjb
1694178573Sjb	/*
1695178573Sjb	 * the sata module doesn't indicate which commands utilize the
1696178573Sjb	 * DMA engine, so find out using this switch table.
1697178573Sjb	 */
1698178573Sjb	switch (spkt->satapkt_cmd.satacmd_cmd_reg) {
1699178479Sjb	case SATAC_READ_DMA_EXT:
1700178479Sjb	case SATAC_WRITE_DMA_EXT:
1701178479Sjb	case SATAC_WRITE_DMA:
1702178479Sjb	case SATAC_READ_DMA:
1703178479Sjb	case SATAC_READ_DMA_QUEUED:
1704178479Sjb	case SATAC_READ_DMA_QUEUED_EXT:
1705178479Sjb	case SATAC_WRITE_DMA_QUEUED:
1706178479Sjb	case SATAC_WRITE_DMA_QUEUED_EXT:
1707178479Sjb	case SATAC_READ_FPDMA_QUEUED:
1708178479Sjb	case SATAC_WRITE_FPDMA_QUEUED:
1709178479Sjb		dma_cmd = B_TRUE;
1710178479Sjb		break;
1711178479Sjb	default:
1712178479Sjb		dma_cmd = B_FALSE;
1713178479Sjb	}
1714178479Sjb
1715178479Sjb	if (sata_cmdp->satacmd_num_dma_cookies != 0 && dma_cmd == B_TRUE) {
1716178479Sjb		NVLOG((NVDBG_DELIVER, nvc,  nvp, "DMA command"));
1717178479Sjb		nv_slotp->nvslot_start = nv_start_dma;
1718178479Sjb		nv_slotp->nvslot_intr = nv_intr_dma;
1719178479Sjb	} else if (spkt->satapkt_cmd.satacmd_cmd_reg == SATAC_PACKET) {
1720178479Sjb		NVLOG((NVDBG_DELIVER, nvc,  nvp, "packet command"));
1721178479Sjb		nv_slotp->nvslot_start = nv_start_pkt_pio;
1722178479Sjb		nv_slotp->nvslot_intr = nv_intr_pkt_pio;
1723178479Sjb		if ((direction == SATA_DIR_READ) ||
1724178479Sjb		    (direction == SATA_DIR_WRITE)) {
1725178479Sjb			nv_slotp->nvslot_byte_count =
1726178479Sjb			    spkt->satapkt_cmd.satacmd_bp->b_bcount;
1727178479Sjb			nv_slotp->nvslot_v_addr =
1728178573Sjb			    spkt->satapkt_cmd.satacmd_bp->b_un.b_addr;
1729178479Sjb			/*
1730178479Sjb			 * Freeing DMA resources allocated by the framework
1731178573Sjb			 * now to avoid buffer overwrite (dma sync) problems
1732178479Sjb			 * when the buffer is released at command completion.
1733211554Srpaulo			 * Primarily an issue on systems with more than
1734178479Sjb			 * 4GB of memory.
1735178479Sjb			 */
1736178479Sjb			sata_free_dma_resources(spkt);
1737178479Sjb		}
1738178479Sjb	} else if (direction == SATA_DIR_NODATA_XFER) {
1739178479Sjb		NVLOG((NVDBG_DELIVER, nvc, nvp, "non-data command"));
1740211554Srpaulo		nv_slotp->nvslot_start = nv_start_nodata;
1741211554Srpaulo		nv_slotp->nvslot_intr = nv_intr_nodata;
1742211554Srpaulo	} else if (direction == SATA_DIR_READ) {
1743211554Srpaulo		NVLOG((NVDBG_DELIVER, nvc, nvp, "pio in command"));
1744178479Sjb		nv_slotp->nvslot_start = nv_start_pio_in;
1745178479Sjb		nv_slotp->nvslot_intr = nv_intr_pio_in;
1746178479Sjb		nv_slotp->nvslot_byte_count =
1747178479Sjb		    spkt->satapkt_cmd.satacmd_bp->b_bcount;
1748178479Sjb		nv_slotp->nvslot_v_addr =
1749178573Sjb		    spkt->satapkt_cmd.satacmd_bp->b_un.b_addr;
1750178479Sjb		/*
1751178479Sjb		 * Freeing DMA resources allocated by the framework now to
1752178479Sjb		 * avoid buffer overwrite (dma sync) problems when the buffer
1753178479Sjb		 * is released at command completion.  This is not an issue
1754178479Sjb		 * for write because write does not update the buffer.
1755178479Sjb		 * Primarily an issue on systems with more than 4GB of memory.
1756178479Sjb		 */
1757178479Sjb		sata_free_dma_resources(spkt);
1758178479Sjb	} else if (direction == SATA_DIR_WRITE) {
1759178479Sjb		NVLOG((NVDBG_DELIVER, nvc, nvp, "pio out command"));
1760178479Sjb		nv_slotp->nvslot_start = nv_start_pio_out;
1761178479Sjb		nv_slotp->nvslot_intr = nv_intr_pio_out;
1762178479Sjb		nv_slotp->nvslot_byte_count =
1763178479Sjb		    spkt->satapkt_cmd.satacmd_bp->b_bcount;
1764178479Sjb		nv_slotp->nvslot_v_addr =
1765178479Sjb		    spkt->satapkt_cmd.satacmd_bp->b_un.b_addr;
1766178573Sjb	} else {
1767211554Srpaulo		nv_cmn_err(CE_WARN, nvc, nvp, "malformed command: direction"
1768178479Sjb		    " %d cookies %d cmd %x",
1769178573Sjb		    sata_cmdp->satacmd_flags.sata_data_direction,
1770178573Sjb		    sata_cmdp->satacmd_num_dma_cookies,  cmd);
1771178573Sjb		spkt->satapkt_reason = SATA_PKT_CMD_UNSUPPORTED;
1772178573Sjb		ret = SATA_TRAN_CMD_UNSUPPORTED;
1773178573Sjb
1774178573Sjb		goto fail;
1775178573Sjb	}
1776178573Sjb
1777178573Sjb	if ((ret = (*nv_slotp->nvslot_start)(nvp, slot)) ==
1778178573Sjb	    SATA_TRAN_ACCEPTED) {
1779178573Sjb		nv_slotp->nvslot_stime = ddi_get_lbolt();
1780178573Sjb
1781178573Sjb		/*
1782178573Sjb		 * start timer if it's not already running and this packet
1783178573Sjb		 * is not requesting polled mode.
1784187347Sjhb		 */
1785178573Sjb		if ((nvp->nvp_timeout_id == 0) &&
1786178573Sjb		    ((spkt->satapkt_op_mode & SATA_OPMODE_POLLING) == 0)) {
1787178573Sjb			nvp->nvp_timeout_id = timeout(nv_timeout, (void *)nvp,
1788178573Sjb			    drv_usectohz(NV_ONE_SEC));
1789211554Srpaulo		}
1790211554Srpaulo
1791211554Srpaulo		return (SATA_TRAN_ACCEPTED);
1792178573Sjb	}
1793178573Sjb
1794211554Srpaulo	fail:
1795211554Srpaulo
1796178573Sjb	spkt->satapkt_reason = SATA_TRAN_PORT_ERROR;
1797178479Sjb
1798178479Sjb	if (ncq == NVSLOT_NCQ) {
1799178479Sjb		nvp->nvp_ncq_run--;
1800178479Sjb		nvp->nvp_sactive_cache &= ~on_bit;
1801178479Sjb	} else {
1802178479Sjb		nvp->nvp_non_ncq_run--;
1803178479Sjb	}
1804178479Sjb	nv_slotp->nvslot_spkt = NULL;
1805178479Sjb	nv_slotp->nvslot_flags = 0;
1806178479Sjb
1807178479Sjb	return (ret);
1808178479Sjb}
1809178479Sjb
1810178479Sjb
1811178479Sjb/*
1812178479Sjb * Check if the signature is ready and if non-zero translate
1813178479Sjb * it into a solaris sata defined type.
1814178479Sjb */
1815178479Sjbstatic void
1816178479Sjbnv_read_signature(nv_port_t *nvp)
1817211554Srpaulo{
1818211554Srpaulo	ddi_acc_handle_t cmdhdl = nvp->nvp_cmd_hdl;
1819211554Srpaulo
1820211554Srpaulo	nvp->nvp_signature = nv_get8(cmdhdl, nvp->nvp_count);
1821211554Srpaulo	nvp->nvp_signature |= (nv_get8(cmdhdl, nvp->nvp_sect) << 8);
1822211554Srpaulo	nvp->nvp_signature |= (nv_get8(cmdhdl, nvp->nvp_lcyl) << 16);
1823211554Srpaulo	nvp->nvp_signature |= (nv_get8(cmdhdl, nvp->nvp_hcyl) << 24);
1824211554Srpaulo
1825211554Srpaulo	switch (nvp->nvp_signature) {
1826211554Srpaulo
1827211554Srpaulo	case NV_SIG_DISK:
1828211554Srpaulo		NVLOG((NVDBG_INIT, nvp->nvp_ctlp, nvp, "drive is a disk"));
1829211554Srpaulo		nvp->nvp_type = SATA_DTYPE_ATADISK;
1830211554Srpaulo		break;
1831211554Srpaulo	case NV_SIG_ATAPI:
1832211554Srpaulo		NVLOG((NVDBG_INIT, nvp->nvp_ctlp, nvp,
1833211554Srpaulo		    "drive is an optical device"));
1834211554Srpaulo		nvp->nvp_type = SATA_DTYPE_ATAPICD;
1835211554Srpaulo		break;
1836211554Srpaulo	case NV_SIG_PM:
1837211554Srpaulo		NVLOG((NVDBG_INIT, nvp->nvp_ctlp, nvp,
1838211554Srpaulo		    "device is a port multiplier"));
1839211554Srpaulo		nvp->nvp_type = SATA_DTYPE_PMULT;
1840211554Srpaulo		break;
1841211554Srpaulo	case NV_SIG_NOTREADY:
1842211554Srpaulo		NVLOG((NVDBG_INIT, nvp->nvp_ctlp, nvp,
1843211554Srpaulo		    "signature not ready"));
1844211554Srpaulo		nvp->nvp_type = SATA_DTYPE_UNKNOWN;
1845211554Srpaulo		break;
1846211554Srpaulo	default:
1847211554Srpaulo		nv_cmn_err(CE_WARN, nvp->nvp_ctlp, nvp, "signature %X not"
1848211554Srpaulo		    " recognized", nvp->nvp_signature);
1849211554Srpaulo		nvp->nvp_type = SATA_DTYPE_UNKNOWN;
1850211554Srpaulo		break;
1851211554Srpaulo	}
1852211554Srpaulo
1853211554Srpaulo	if (nvp->nvp_signature) {
1854211554Srpaulo		nvp->nvp_state &= ~(NV_PORT_RESET_PROBE|NV_PORT_RESET);
1855211554Srpaulo	}
1856211554Srpaulo}
1857211554Srpaulo
1858211554Srpaulo
1859211554Srpaulo/*
1860211554Srpaulo * Reset the port
1861211554Srpaulo */
1862211554Srpaulostatic void
1863211554Srpaulonv_reset(nv_port_t *nvp)
1864211554Srpaulo{
1865211554Srpaulo	ddi_acc_handle_t bar5_hdl = nvp->nvp_ctlp->nvc_bar_hdl[5];
1866211554Srpaulo	ddi_acc_handle_t cmdhdl = nvp->nvp_cmd_hdl;
1867211554Srpaulo	nv_ctl_t *nvc = nvp->nvp_ctlp;
1868211554Srpaulo	uint32_t sctrl;
1869211554Srpaulo
1870211554Srpaulo	NVLOG((NVDBG_ENTRY, nvc, nvp, "nv_reset()"));
1871211554Srpaulo
1872211554Srpaulo	ASSERT(mutex_owned(&nvp->nvp_mutex));
1873211554Srpaulo
1874211554Srpaulo	/*
1875211554Srpaulo	 * clear signature registers
1876211554Srpaulo	 */
1877211554Srpaulo	nv_put8(cmdhdl, nvp->nvp_sect, 0);
1878211554Srpaulo	nv_put8(cmdhdl, nvp->nvp_lcyl, 0);
1879211554Srpaulo	nv_put8(cmdhdl, nvp->nvp_hcyl, 0);
1880211554Srpaulo	nv_put8(cmdhdl, nvp->nvp_count, 0);
1881211554Srpaulo
1882211554Srpaulo	nvp->nvp_signature = 0;
1883211554Srpaulo	nvp->nvp_type = 0;
1884211554Srpaulo	nvp->nvp_state |= NV_PORT_RESET;
1885211554Srpaulo	nvp->nvp_reset_time = ddi_get_lbolt();
1886211554Srpaulo	nvp->nvp_link_lost_time = 0;
1887211554Srpaulo
1888211554Srpaulo	/*
1889211554Srpaulo	 * assert reset in PHY by writing a 1 to bit 0 scontrol
1890211554Srpaulo	 */
1891211554Srpaulo	sctrl = nv_get32(bar5_hdl, nvp->nvp_sctrl);
1892211554Srpaulo
1893211554Srpaulo	nv_put32(bar5_hdl, nvp->nvp_sctrl, sctrl | SCONTROL_DET_COMRESET);
1894211554Srpaulo
1895211554Srpaulo	/*
1896211554Srpaulo	 * wait 1ms
1897211554Srpaulo	 */
1898211554Srpaulo	drv_usecwait(1000);
1899211554Srpaulo
1900211554Srpaulo	/*
1901211554Srpaulo	 * de-assert reset in PHY
1902211554Srpaulo	 */
1903211554Srpaulo	nv_put32(bar5_hdl, nvp->nvp_sctrl, sctrl);
1904211554Srpaulo
1905211554Srpaulo	/*
1906211554Srpaulo	 * make sure timer is running
1907211554Srpaulo	 */
1908211554Srpaulo	if (nvp->nvp_timeout_id == 0) {
1909211554Srpaulo		nvp->nvp_timeout_id = timeout(nv_timeout, (void *)nvp,
1910211554Srpaulo		    drv_usectohz(NV_ONE_SEC));
1911211554Srpaulo	}
1912211554Srpaulo}
1913211554Srpaulo
1914211554Srpaulo
1915211554Srpaulo/*
1916211554Srpaulo * Initialize register handling specific to mcp55
1917211554Srpaulo */
1918211554Srpaulo/* ARGSUSED */
1919211554Srpaulostatic void
1920211554Srpaulomcp55_reg_init(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle)
1921211554Srpaulo{
1922211554Srpaulo	nv_port_t *nvp;
1923211554Srpaulo	uchar_t *bar5  = nvc->nvc_bar_addr[5];
1924211554Srpaulo	uint8_t off, port;
1925211554Srpaulo
1926211554Srpaulo	nvc->nvc_mcp55_ctl = (uint32_t *)(bar5 + MCP55_CTL);
1927211554Srpaulo	nvc->nvc_mcp55_ncq = (uint32_t *)(bar5 + MCP55_NCQ);
1928211554Srpaulo
1929211554Srpaulo	for (port = 0, off = 0; port < NV_MAX_PORTS(nvc); port++, off += 2) {
1930211554Srpaulo		nvp = &(nvc->nvc_port[port]);
1931211554Srpaulo		nvp->nvp_mcp55_int_status =
1932211554Srpaulo		    (uint16_t *)(bar5 + MCP55_INT_STATUS + off);
1933211554Srpaulo		nvp->nvp_mcp55_int_ctl =
1934211554Srpaulo		    (uint16_t *)(bar5 + MCP55_INT_CTL + off);
1935211554Srpaulo
1936211554Srpaulo		/*
1937211554Srpaulo		 * clear any previous interrupts asserted
1938211554Srpaulo		 */
1939211554Srpaulo		nv_put16(nvc->nvc_bar_hdl[5], nvp->nvp_mcp55_int_status,
1940211554Srpaulo		    MCP55_INT_CLEAR);
1941211554Srpaulo
1942211554Srpaulo		/*
1943211554Srpaulo		 * These are the interrupts to accept for now.  The spec
1944211554Srpaulo		 * says these are enable bits, but nvidia has indicated
1945211554Srpaulo		 * these are masking bits.  Even though they may be masked
1946211554Srpaulo		 * out to prevent asserting the main interrupt, they can
1947211554Srpaulo		 * still be asserted while reading the interrupt status
1948211554Srpaulo		 * register, so that needs to be considered in the interrupt
1949178479Sjb		 * handler.
1950178479Sjb		 */
1951178479Sjb		nv_put16(nvc->nvc_bar_hdl[5], nvp->nvp_mcp55_int_ctl,
1952178479Sjb		    ~(MCP55_INT_IGNORE));
1953178479Sjb	}
1954178479Sjb
1955178573Sjb	/*
1956178573Sjb	 * Allow the driver to program the BM on the first command instead
1957178573Sjb	 * of waiting for an interrupt.
1958178573Sjb	 */
1959178479Sjb#ifdef NCQ
1960178479Sjb	flags = MCP_SATA_AE_NCQ_PDEV_FIRST_CMD | MCP_SATA_AE_NCQ_SDEV_FIRST_CMD;
1961	nv_put32(nvc->nvc_bar_hdl[5], nvc->nvc_mcp55_ncq, flags);
1962	flags = MCP_SATA_AE_CTL_PRI_SWNCQ | MCP_SATA_AE_CTL_SEC_SWNCQ;
1963	nv_put32(nvc->nvc_bar_hdl[5], nvc->nvc_mcp55_ctl, flags);
1964#endif
1965
1966
1967#if 0
1968	/*
1969	 * This caused problems on some but not all mcp55 based systems.
1970	 * DMA writes would never complete.  This happens even on small
1971	 * mem systems, and only setting NV_40BIT_PRD below and not
1972	 * buffer_dma_attr.dma_attr_addr_hi, so it seems to be a hardware
1973	 * issue that needs further investigation.
1974	 */
1975
1976	/*
1977	 * mcp55 rev A03 and above supports 40-bit physical addressing.
1978	 * Enable DMA to take advantage of that.
1979	 *
1980	 */
1981	if (nvc->nvc_revid >= 0xa3) {
1982		uint32_t reg32;
1983		NVLOG((NVDBG_INIT, nvp->nvp_ctlp, nvp, "rev id is %X and"
1984		    " is capable of 40-bit addressing", nvc->nvc_revid));
1985		buffer_dma_attr.dma_attr_addr_hi = 0xffffffffffull;
1986		reg32 = pci_config_get32(pci_conf_handle, NV_SATA_CFG_20);
1987		pci_config_put32(pci_conf_handle, NV_SATA_CFG_20,
1988		    reg32 |NV_40BIT_PRD);
1989	} else {
1990		NVLOG((NVDBG_INIT, nvp->nvp_ctlp, nvp, "rev is %X and is "
1991		    "not capable of 40-bit addressing", nvc->nvc_revid));
1992	}
1993#endif
1994
1995}
1996
1997
1998/*
1999 * Initialize register handling specific to mcp04
2000 */
2001static void
2002mcp04_reg_init(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle)
2003{
2004	uchar_t *bar5  = nvc->nvc_bar_addr[5];
2005	uint32_t reg32;
2006	uint16_t reg16;
2007	nv_port_t *nvp;
2008	int j;
2009
2010	/*
2011	 * delay hotplug interrupts until PHYRDY.
2012	 */
2013	reg32 = pci_config_get32(pci_conf_handle, NV_SATA_CFG_42);
2014	pci_config_put32(pci_conf_handle, NV_SATA_CFG_42,
2015	    reg32 | MCP04_CFG_DELAY_HOTPLUG_INTR);
2016
2017	/*
2018	 * enable hot plug interrupts for channel x and y
2019	 */
2020	reg16 = nv_get16(nvc->nvc_bar_hdl[5],
2021	    (uint16_t *)(bar5 + NV_ADMACTL_X));
2022	nv_put16(nvc->nvc_bar_hdl[5], (uint16_t *)(bar5 + NV_ADMACTL_X),
2023	    NV_HIRQ_EN | reg16);
2024
2025
2026	reg16 = nv_get16(nvc->nvc_bar_hdl[5],
2027	    (uint16_t *)(bar5 + NV_ADMACTL_Y));
2028	nv_put16(nvc->nvc_bar_hdl[5], (uint16_t *)(bar5 + NV_ADMACTL_Y),
2029	    NV_HIRQ_EN | reg16);
2030
2031	nvc->nvc_mcp04_int_status = (uint8_t *)(bar5 + MCP04_SATA_INT_STATUS);
2032
2033	/*
2034	 * clear any existing interrupt pending then enable
2035	 */
2036	for (j = 0; j < NV_MAX_PORTS(nvc); j++) {
2037		nvp = &(nvc->nvc_port[j]);
2038		mutex_enter(&nvp->nvp_mutex);
2039		(*(nvp->nvp_ctlp->nvc_set_intr))(nvp,
2040		    NV_INTR_CLEAR_ALL|NV_INTR_ENABLE);
2041		mutex_exit(&nvp->nvp_mutex);
2042	}
2043}
2044
2045
2046/*
2047 * Initialize the controller and set up driver data structures.
2048 * determine if ck804 or mcp55 class.
2049 */
2050static int
2051nv_init_ctl(nv_ctl_t *nvc, ddi_acc_handle_t pci_conf_handle)
2052{
2053	struct sata_hba_tran stran;
2054	nv_port_t *nvp;
2055	int j, ck804 = B_TRUE;
2056	uchar_t *cmd_addr, *ctl_addr, *bm_addr;
2057	ddi_acc_handle_t bar5_hdl = nvc->nvc_bar_hdl[5];
2058	uchar_t *bar5  = nvc->nvc_bar_addr[5];
2059	uint32_t reg32;
2060	uint8_t reg8, reg8_save;
2061
2062	NVLOG((NVDBG_INIT, nvc, NULL, "nv_init_ctl entered"));
2063
2064	/*
2065	 * Need to set bit 2 to 1 at config offset 0x50
2066	 * to enable access to the bar5 registers.
2067	 */
2068	reg32 = pci_config_get32(pci_conf_handle, NV_SATA_CFG_20);
2069	pci_config_put32(pci_conf_handle, NV_SATA_CFG_20,
2070	    reg32 | NV_BAR5_SPACE_EN);
2071
2072	/*
2073	 * Determine if this is ck804 or mcp55.  ck804 will map in the
2074	 * task file registers into bar5 while mcp55 won't.  The offset of
2075	 * the task file registers in mcp55's space is unused, so it will
2076	 * return zero.  So check one of the task file registers to see if it is
2077	 * writable and reads back what was written.  If it's mcp55 it will
2078	 * return back 0xff whereas ck804 will return the value written.
2079	 */
2080	reg8_save = nv_get8(bar5_hdl,
2081	    (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X));
2082
2083
2084	for (j = 1; j < 3; j++) {
2085
2086		nv_put8(bar5_hdl, (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X), j);
2087		reg8 = nv_get8(bar5_hdl,
2088		    (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X));
2089
2090		if (reg8 != j) {
2091			ck804 = B_FALSE;
2092			break;
2093		}
2094	}
2095
2096	nv_put8(bar5_hdl, (uint8_t *)(bar5 + NV_BAR5_TRAN_LEN_CH_X), reg8_save);
2097
2098	if (ck804 == B_TRUE) {
2099		NVLOG((NVDBG_INIT, nvc, NULL, "controller is CK804"));
2100		nvc->nvc_interrupt = mcp04_intr;
2101		nvc->nvc_reg_init = mcp04_reg_init;
2102		nvc->nvc_set_intr = mcp04_set_intr;
2103	} else {
2104		NVLOG((NVDBG_INIT, nvc, NULL, "controller is MCP55"));
2105		nvc->nvc_interrupt = mcp55_intr;
2106		nvc->nvc_reg_init = mcp55_reg_init;
2107		nvc->nvc_set_intr = mcp55_set_intr;
2108	}
2109
2110
2111	stran.sata_tran_hba_rev = SATA_TRAN_HBA_REV_2;
2112	stran.sata_tran_hba_dip = nvc->nvc_dip;
2113	stran.sata_tran_hba_dma_attr = &buffer_dma_attr;
2114	stran.sata_tran_hba_num_cports = NV_NUM_CPORTS;
2115	stran.sata_tran_hba_features_support =
2116	    SATA_CTLF_HOTPLUG | SATA_CTLF_ASN | SATA_CTLF_ATAPI;
2117	stran.sata_tran_hba_qdepth = NV_QUEUE_SLOTS;
2118	stran.sata_tran_probe_port = nv_sata_probe;
2119	stran.sata_tran_start = nv_sata_start;
2120	stran.sata_tran_abort = nv_sata_abort;
2121	stran.sata_tran_reset_dport = nv_sata_reset;
2122	stran.sata_tran_selftest = NULL;
2123	stran.sata_tran_hotplug_ops = &nv_hotplug_ops;
2124	stran.sata_tran_pwrmgt_ops = NULL;
2125	stran.sata_tran_ioctl = NULL;
2126	nvc->nvc_sata_hba_tran = stran;
2127
2128	nvc->nvc_port = kmem_zalloc(sizeof (nv_port_t) * NV_MAX_PORTS(nvc),
2129	    KM_SLEEP);
2130
2131	/*
2132	 * initialize registers common to all chipsets
2133	 */
2134	nv_common_reg_init(nvc);
2135
2136	for (j = 0; j < NV_MAX_PORTS(nvc); j++) {
2137		nvp = &(nvc->nvc_port[j]);
2138
2139		cmd_addr = nvp->nvp_cmd_addr;
2140		ctl_addr = nvp->nvp_ctl_addr;
2141		bm_addr = nvp->nvp_bm_addr;
2142
2143		mutex_init(&nvp->nvp_mutex, NULL, MUTEX_DRIVER,
2144		    DDI_INTR_PRI(nvc->nvc_intr_pri));
2145
2146		cv_init(&nvp->nvp_poll_cv, NULL, CV_DRIVER, NULL);
2147
2148		nvp->nvp_data	= cmd_addr + NV_DATA;
2149		nvp->nvp_error	= cmd_addr + NV_ERROR;
2150		nvp->nvp_feature = cmd_addr + NV_FEATURE;
2151		nvp->nvp_count	= cmd_addr + NV_COUNT;
2152		nvp->nvp_sect	= cmd_addr + NV_SECT;
2153		nvp->nvp_lcyl	= cmd_addr + NV_LCYL;
2154		nvp->nvp_hcyl	= cmd_addr + NV_HCYL;
2155		nvp->nvp_drvhd	= cmd_addr + NV_DRVHD;
2156		nvp->nvp_status	= cmd_addr + NV_STATUS;
2157		nvp->nvp_cmd	= cmd_addr + NV_CMD;
2158		nvp->nvp_altstatus = ctl_addr + NV_ALTSTATUS;
2159		nvp->nvp_devctl	= ctl_addr + NV_DEVCTL;
2160
2161		nvp->nvp_bmicx	= bm_addr + BMICX_REG;
2162		nvp->nvp_bmisx	= bm_addr + BMISX_REG;
2163		nvp->nvp_bmidtpx = (uint32_t *)(bm_addr + BMIDTPX_REG);
2164
2165		nvp->nvp_state = 0;
2166	}
2167
2168	/*
2169	 * initialize register by calling chip specific reg initialization
2170	 */
2171	(*(nvc->nvc_reg_init))(nvc, pci_conf_handle);
2172
2173	return (NV_SUCCESS);
2174}
2175
2176
2177/*
2178 * Initialize data structures with enough slots to handle queuing, if
2179 * enabled.  NV_QUEUE_SLOTS will be set to 1 or 32, depending on whether
2180 * NCQ support is built into the driver and enabled.  It might have been
2181 * better to derive the true size from the drive itself, but the sata
2182 * module only sends down that information on the first NCQ command,
2183 * which means possibly re-sizing the structures on an interrupt stack,
2184 * making error handling more messy.  The easy way is to just allocate
2185 * all 32 slots, which is what most drives support anyway.
2186 */
2187static int
2188nv_init_port(nv_port_t *nvp)
2189{
2190	nv_ctl_t *nvc = nvp->nvp_ctlp;
2191	size_t	prd_size = sizeof (prde_t) * NV_DMA_NSEGS;
2192	dev_info_t *dip = nvc->nvc_dip;
2193	ddi_device_acc_attr_t dev_attr;
2194	size_t buf_size;
2195	ddi_dma_cookie_t cookie;
2196	uint_t count;
2197	int rc, i;
2198
2199	dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
2200	dev_attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC;
2201	dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
2202
2203	if (nvp->nvp_state & NV_PORT_INIT) {
2204		NVLOG((NVDBG_INIT, nvc, nvp,
2205		    "nv_init_port previously initialized"));
2206
2207		return (NV_SUCCESS);
2208	} else {
2209		NVLOG((NVDBG_INIT, nvc, nvp, "nv_init_port initializing"));
2210	}
2211
2212	nvp->nvp_sg_dma_hdl = kmem_zalloc(sizeof (ddi_dma_handle_t) *
2213	    NV_QUEUE_SLOTS, KM_SLEEP);
2214
2215	nvp->nvp_sg_acc_hdl = kmem_zalloc(sizeof (ddi_acc_handle_t) *
2216	    NV_QUEUE_SLOTS, KM_SLEEP);
2217
2218	nvp->nvp_sg_addr = kmem_zalloc(sizeof (caddr_t) *
2219	    NV_QUEUE_SLOTS, KM_SLEEP);
2220
2221	nvp->nvp_sg_paddr = kmem_zalloc(sizeof (uint32_t) *
2222	    NV_QUEUE_SLOTS, KM_SLEEP);
2223
2224	nvp->nvp_slot = kmem_zalloc(sizeof (nv_slot_t) * NV_QUEUE_SLOTS,
2225	    KM_SLEEP);
2226
2227	for (i = 0; i < NV_QUEUE_SLOTS; i++) {
2228
2229		rc = ddi_dma_alloc_handle(dip, &nv_prd_dma_attr,
2230		    DDI_DMA_SLEEP, NULL, &(nvp->nvp_sg_dma_hdl[i]));
2231
2232		if (rc != DDI_SUCCESS) {
2233			nv_uninit_port(nvp);
2234
2235			return (NV_FAILURE);
2236		}
2237
2238		rc = ddi_dma_mem_alloc(nvp->nvp_sg_dma_hdl[i], prd_size,
2239		    &dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
2240		    NULL, &(nvp->nvp_sg_addr[i]), &buf_size,
2241		    &(nvp->nvp_sg_acc_hdl[i]));
2242
2243		if (rc != DDI_SUCCESS) {
2244			nv_uninit_port(nvp);
2245
2246			return (NV_FAILURE);
2247		}
2248
2249		rc = ddi_dma_addr_bind_handle(nvp->nvp_sg_dma_hdl[i], NULL,
2250		    nvp->nvp_sg_addr[i], buf_size,
2251		    DDI_DMA_WRITE | DDI_DMA_CONSISTENT,
2252		    DDI_DMA_SLEEP, NULL, &cookie, &count);
2253
2254		if (rc != DDI_DMA_MAPPED) {
2255			nv_uninit_port(nvp);
2256
2257			return (NV_FAILURE);
2258		}
2259
2260		ASSERT(count == 1);
2261		ASSERT((cookie.dmac_address & (sizeof (int) - 1)) == 0);
2262
2263		ASSERT(cookie.dmac_laddress <= UINT32_MAX);
2264
2265		nvp->nvp_sg_paddr[i] = cookie.dmac_address;
2266	}
2267
2268	/*
2269	 * nvp_queue_depth represents the actual drive queue depth, not the
2270	 * number of slots allocated in the structures (which may be more).
2271	 * Actual queue depth is only learned after the first NCQ command, so
2272	 * initialize it to 1 for now.
2273	 */
2274	nvp->nvp_queue_depth = 1;
2275
2276	nvp->nvp_state |= NV_PORT_INIT;
2277
2278	return (NV_SUCCESS);
2279}
2280
2281
2282/*
2283 * Free dynamically allocated structures for port.
2284 */
2285static void
2286nv_uninit_port(nv_port_t *nvp)
2287{
2288	int i;
2289
2290	/*
2291	 * It is possible to reach here before a port has been initialized or
2292	 * after it has already been uninitialized.  Just return in that case.
2293	 */
2294	if (nvp->nvp_slot == NULL) {
2295
2296		return;
2297	}
2298
2299	NVLOG((NVDBG_INIT, nvp->nvp_ctlp, nvp,
2300	    "nv_uninit_port uninitializing"));
2301
2302	nvp->nvp_type = SATA_DTYPE_NONE;
2303
2304	for (i = 0; i < NV_QUEUE_SLOTS; i++) {
2305		if (nvp->nvp_sg_paddr[i]) {
2306			(void) ddi_dma_unbind_handle(nvp->nvp_sg_dma_hdl[i]);
2307		}
2308
2309		if (nvp->nvp_sg_acc_hdl[i] != NULL) {
2310			ddi_dma_mem_free(&(nvp->nvp_sg_acc_hdl[i]));
2311		}
2312
2313		if (nvp->nvp_sg_dma_hdl[i] != NULL) {
2314			ddi_dma_free_handle(&(nvp->nvp_sg_dma_hdl[i]));
2315		}
2316	}
2317
2318	kmem_free(nvp->nvp_slot, sizeof (nv_slot_t) * NV_QUEUE_SLOTS);
2319	nvp->nvp_slot = NULL;
2320
2321	kmem_free(nvp->nvp_sg_dma_hdl,
2322	    sizeof (ddi_dma_handle_t) * NV_QUEUE_SLOTS);
2323	nvp->nvp_sg_dma_hdl = NULL;
2324
2325	kmem_free(nvp->nvp_sg_acc_hdl,
2326	    sizeof (ddi_acc_handle_t) * NV_QUEUE_SLOTS);
2327	nvp->nvp_sg_acc_hdl = NULL;
2328
2329	kmem_free(nvp->nvp_sg_addr, sizeof (caddr_t) * NV_QUEUE_SLOTS);
2330	nvp->nvp_sg_addr = NULL;
2331
2332	kmem_free(nvp->nvp_sg_paddr, sizeof (uint32_t) * NV_QUEUE_SLOTS);
2333	nvp->nvp_sg_paddr = NULL;
2334
2335	nvp->nvp_state &= ~NV_PORT_INIT;
2336	nvp->nvp_signature = 0;
2337}
2338
2339
2340/*
2341 * Cache register offsets and access handles to frequently accessed registers
2342 * which are common to either chipset.
2343 */
2344static void
2345nv_common_reg_init(nv_ctl_t *nvc)
2346{
2347	uchar_t *bar5_addr = nvc->nvc_bar_addr[5];
2348	uchar_t *bm_addr_offset, *sreg_offset;
2349	uint8_t bar, port;
2350	nv_port_t *nvp;
2351
2352	for (port = 0; port < NV_MAX_PORTS(nvc); port++) {
2353		if (port == 0) {
2354			bar = NV_BAR_0;
2355			bm_addr_offset = 0;
2356			sreg_offset = (uchar_t *)(CH0_SREG_OFFSET + bar5_addr);
2357		} else {
2358			bar = NV_BAR_2;
2359			bm_addr_offset = (uchar_t *)8;
2360			sreg_offset = (uchar_t *)(CH1_SREG_OFFSET + bar5_addr);
2361		}
2362
2363		nvp = &(nvc->nvc_port[port]);
2364		nvp->nvp_ctlp = nvc;
2365		nvp->nvp_port_num = port;
2366		NVLOG((NVDBG_INIT, nvc, nvp, "setting up port mappings"));
2367
2368		nvp->nvp_cmd_hdl = nvc->nvc_bar_hdl[bar];
2369		nvp->nvp_cmd_addr = nvc->nvc_bar_addr[bar];
2370		nvp->nvp_ctl_hdl = nvc->nvc_bar_hdl[bar + 1];
2371		nvp->nvp_ctl_addr = nvc->nvc_bar_addr[bar + 1];
2372		nvp->nvp_bm_hdl = nvc->nvc_bar_hdl[NV_BAR_4];
2373		nvp->nvp_bm_addr = nvc->nvc_bar_addr[NV_BAR_4] +
2374		    (long)bm_addr_offset;
2375
2376		nvp->nvp_sstatus = (uint32_t *)(sreg_offset + NV_SSTATUS);
2377		nvp->nvp_serror = (uint32_t *)(sreg_offset + NV_SERROR);
2378		nvp->nvp_sactive = (uint32_t *)(sreg_offset + NV_SACTIVE);
2379		nvp->nvp_sctrl = (uint32_t *)(sreg_offset + NV_SCTRL);
2380	}
2381}
2382
2383
2384static void
2385nv_uninit_ctl(nv_ctl_t *nvc)
2386{
2387	int port;
2388	nv_port_t *nvp;
2389
2390	NVLOG((NVDBG_INIT, nvc, NULL, "nv_uninit_ctl entered"));
2391
2392	for (port = 0; port < NV_MAX_PORTS(nvc); port++) {
2393		nvp = &(nvc->nvc_port[port]);
2394		mutex_enter(&nvp->nvp_mutex);
2395		NVLOG((NVDBG_INIT, nvc, nvp, "uninitializing port"));
2396		nv_uninit_port(nvp);
2397		mutex_exit(&nvp->nvp_mutex);
2398		mutex_destroy(&nvp->nvp_mutex);
2399		cv_destroy(&nvp->nvp_poll_cv);
2400	}
2401
2402	kmem_free(nvc->nvc_port, NV_MAX_PORTS(nvc) * sizeof (nv_port_t));
2403	nvc->nvc_port = NULL;
2404}
2405
2406
2407/*
2408 * mcp04 interrupt.  This is a wrapper around mcp04_intr_process so
2409 * that interrupts from other devices can be disregarded while dtracing.
2410 */
2411/* ARGSUSED */
2412static uint_t
2413mcp04_intr(caddr_t arg1, caddr_t arg2)
2414{
2415	nv_ctl_t *nvc = (nv_ctl_t *)arg1;
2416	uint8_t intr_status;
2417	ddi_acc_handle_t bar5_hdl = nvc->nvc_bar_hdl[5];
2418
2419	intr_status = ddi_get8(bar5_hdl, nvc->nvc_mcp04_int_status);
2420
2421	if (intr_status == 0) {
2422
2423		return (DDI_INTR_UNCLAIMED);
2424	}
2425
2426	mcp04_intr_process(nvc, intr_status);
2427
2428	return (DDI_INTR_CLAIMED);
2429}
2430
2431
2432/*
2433 * Main interrupt handler for ck804.  handles normal device
2434 * interrupts as well as port hot plug and remove interrupts.
2435 *
2436 */
2437static void
2438mcp04_intr_process(nv_ctl_t *nvc, uint8_t intr_status)
2439{
2440
2441	int port, i;
2442	nv_port_t *nvp;
2443	nv_slot_t *nv_slotp;
2444	uchar_t	status;
2445	sata_pkt_t *spkt;
2446	uint8_t bmstatus, clear_bits;
2447	ddi_acc_handle_t bmhdl;
2448	int nvcleared = 0;
2449	ddi_acc_handle_t bar5_hdl = nvc->nvc_bar_hdl[5];
2450	uint32_t sstatus;
2451	int port_mask_hot[] = {
2452		MCP04_INT_PDEV_HOT, MCP04_INT_SDEV_HOT,
2453	};
2454	int port_mask_pm[] = {
2455		MCP04_INT_PDEV_PM, MCP04_INT_SDEV_PM,
2456	};
2457
2458	NVLOG((NVDBG_INTR, nvc, NULL,
2459	    "mcp04_intr_process entered intr_status=%x", intr_status));
2460
2461	/*
2462	 * For command completion interrupt, explicit clear is not required.
2463	 * however, for the error cases explicit clear is performed.
2464	 */
2465	for (port = 0; port < NV_MAX_PORTS(nvc); port++) {
2466
2467		int port_mask[] = {MCP04_INT_PDEV_INT, MCP04_INT_SDEV_INT};
2468
2469		if ((port_mask[port] & intr_status) == 0) {
2470			continue;
2471		}
2472
2473		NVLOG((NVDBG_INTR, nvc, NULL,
2474		    "mcp04_intr_process interrupt on port %d", port));
2475
2476		nvp = &(nvc->nvc_port[port]);
2477
2478		mutex_enter(&nvp->nvp_mutex);
2479
2480		/*
2481		 * there was a corner case found where an interrupt
2482		 * arrived before nvp_slot was set.  Should
2483		 * probably should track down why that happens and try
2484		 * to eliminate that source and then get rid of this
2485		 * check.
2486		 */
2487		if (nvp->nvp_slot == NULL) {
2488			status = nv_get8(nvp->nvp_ctl_hdl, nvp->nvp_status);
2489			NVLOG((NVDBG_ALWAYS, nvc, nvp, "spurious interrupt "
2490			    "received before initialization "
2491			    "completed status=%x", status));
2492			mutex_exit(&nvp->nvp_mutex);
2493
2494			/*
2495			 * clear interrupt bits
2496			 */
2497			nv_put8(bar5_hdl, nvc->nvc_mcp04_int_status,
2498			    port_mask[port]);
2499
2500			continue;
2501		}
2502
2503		if ((&(nvp->nvp_slot[0]))->nvslot_spkt == NULL)  {
2504			status = nv_get8(nvp->nvp_ctl_hdl, nvp->nvp_status);
2505			NVLOG((NVDBG_ALWAYS, nvc, nvp, "spurious interrupt "
2506			    " no command in progress status=%x", status));
2507			mutex_exit(&nvp->nvp_mutex);
2508
2509			/*
2510			 * clear interrupt bits
2511			 */
2512			nv_put8(bar5_hdl, nvc->nvc_mcp04_int_status,
2513			    port_mask[port]);
2514
2515			continue;
2516		}
2517
2518		bmhdl = nvp->nvp_bm_hdl;
2519		bmstatus = nv_get8(bmhdl, nvp->nvp_bmisx);
2520
2521		if (!(bmstatus & BMISX_IDEINTS)) {
2522			mutex_exit(&nvp->nvp_mutex);
2523
2524			continue;
2525		}
2526
2527		status = nv_get8(nvp->nvp_ctl_hdl, nvp->nvp_altstatus);
2528
2529		if (status & SATA_STATUS_BSY) {
2530			mutex_exit(&nvp->nvp_mutex);
2531
2532			continue;
2533		}
2534
2535		nv_slotp = &(nvp->nvp_slot[0]);
2536
2537		ASSERT(nv_slotp);
2538
2539		spkt = nv_slotp->nvslot_spkt;
2540
2541		if (spkt == NULL) {
2542			mutex_exit(&nvp->nvp_mutex);
2543
2544			continue;
2545		}
2546
2547		(*nv_slotp->nvslot_intr)(nvp, nv_slotp);
2548
2549		nv_copy_registers(nvp, &spkt->satapkt_device, spkt);
2550
2551		/*
2552		 * If there is no link cannot be certain about the completion
2553		 * of the packet, so abort it.
2554		 */
2555		if (nv_check_link((&spkt->satapkt_device)->
2556		    satadev_scr.sstatus) == B_FALSE) {
2557
2558			(void) nv_abort_active(nvp, NULL, SATA_PKT_PORT_ERROR);
2559
2560		} else if (nv_slotp->nvslot_flags == NVSLOT_COMPLETE) {
2561
2562			nv_complete_io(nvp, spkt, 0);
2563		}
2564
2565		mutex_exit(&nvp->nvp_mutex);
2566	}
2567
2568	/*
2569	 * mcp04 often doesn't correctly distinguish hot add/remove
2570	 * interrupts.  Frequently both the ADD and the REMOVE bits
2571	 * are asserted, whether it was a remove or add.  Use sstatus
2572	 * to distinguish hot add from hot remove.
2573	 */
2574
2575	for (port = 0; port < NV_MAX_PORTS(nvc); port++) {
2576		clear_bits = 0;
2577
2578		nvp = &(nvc->nvc_port[port]);
2579		mutex_enter(&nvp->nvp_mutex);
2580
2581		if ((port_mask_pm[port] & intr_status) != 0) {
2582			clear_bits = port_mask_pm[port];
2583			NVLOG((NVDBG_HOT, nvc, nvp,
2584			    "clearing PM interrupt bit: %x",
2585			    intr_status & port_mask_pm[port]));
2586		}
2587
2588		if ((port_mask_hot[port] & intr_status) == 0) {
2589			if (clear_bits != 0) {
2590				goto clear;
2591			} else {
2592				mutex_exit(&nvp->nvp_mutex);
2593				continue;
2594			}
2595		}
2596
2597		/*
2598		 * reaching here means there was a hot add or remove.
2599		 */
2600		clear_bits |= port_mask_hot[port];
2601
2602		ASSERT(nvc->nvc_port[port].nvp_sstatus);
2603
2604		sstatus = nv_get32(bar5_hdl,
2605		    nvc->nvc_port[port].nvp_sstatus);
2606
2607		if ((sstatus & SSTATUS_DET_DEVPRE_PHYCOM) ==
2608		    SSTATUS_DET_DEVPRE_PHYCOM) {
2609			nv_report_add_remove(nvp, 0);
2610		} else {
2611			nv_report_add_remove(nvp, NV_PORT_HOTREMOVED);
2612		}
2613	clear:
2614		/*
2615		 * clear interrupt bits.  explicit interrupt clear is
2616		 * required for hotplug interrupts.
2617		 */
2618		nv_put8(bar5_hdl, nvc->nvc_mcp04_int_status, clear_bits);
2619
2620		/*
2621		 * make sure it's flushed and cleared.  If not try
2622		 * again.  Sometimes it has been observed to not clear
2623		 * on the first try.
2624		 */
2625		intr_status = nv_get8(bar5_hdl, nvc->nvc_mcp04_int_status);
2626
2627		/*
2628		 * make 10 additional attempts to clear the interrupt
2629		 */
2630		for (i = 0; (intr_status & clear_bits) && (i < 10); i++) {
2631			NVLOG((NVDBG_ALWAYS, nvc, nvp, "inst_status=%x "
2632			    "still not clear try=%d", intr_status,
2633			    ++nvcleared));
2634			nv_put8(bar5_hdl, nvc->nvc_mcp04_int_status,
2635			    clear_bits);
2636			intr_status = nv_get8(bar5_hdl,
2637			    nvc->nvc_mcp04_int_status);
2638		}
2639
2640		/*
2641		 * if still not clear, log a message and disable the
2642		 * port. highly unlikely that this path is taken, but it
2643		 * gives protection against a wedged interrupt.
2644		 */
2645		if (intr_status & clear_bits) {
2646			(*(nvc->nvc_set_intr))(nvp, NV_INTR_DISABLE);
2647			nv_port_state_change(nvp, SATA_EVNT_PORT_FAILED,
2648			    SATA_ADDR_CPORT, SATA_PSTATE_FAILED);
2649			nvp->nvp_state |= NV_PORT_FAILED;
2650			(void) nv_abort_active(nvp, NULL, SATA_PKT_DEV_ERROR);
2651			nv_cmn_err(CE_WARN, nvc, nvp, "unable to clear "
2652			    "interrupt.  disabling port intr_status=%X",
2653			    intr_status);
2654		}
2655
2656		mutex_exit(&nvp->nvp_mutex);
2657	}
2658}
2659
2660
2661/*
2662 * Interrupt handler for mcp55.  It is invoked by the wrapper for each port
2663 * on the controller, to handle completion and hot plug and remove events.
2664 *
2665 */
2666static uint_t
2667mcp55_intr_port(nv_port_t *nvp)
2668{
2669	nv_ctl_t *nvc = nvp->nvp_ctlp;
2670	ddi_acc_handle_t bar5_hdl = nvc->nvc_bar_hdl[5];
2671	uint8_t clear = 0, intr_cycles = 0;
2672	int ret = DDI_INTR_UNCLAIMED;
2673	uint16_t int_status;
2674
2675	NVLOG((NVDBG_INTR, nvc, nvp, "mcp55_intr_port entered"));
2676
2677	for (;;) {
2678		/*
2679		 * read current interrupt status
2680		 */
2681		int_status = nv_get16(bar5_hdl, nvp->nvp_mcp55_int_status);
2682
2683		NVLOG((NVDBG_INTR, nvc, nvp, "int_status = %x", int_status));
2684
2685		/*
2686		 * MCP55_INT_IGNORE interrupts will show up in the status,
2687		 * but are masked out from causing an interrupt to be generated
2688		 * to the processor.  Ignore them here by masking them out.
2689		 */
2690		int_status &= ~(MCP55_INT_IGNORE);
2691
2692		/*
2693		 * exit the loop when no more interrupts to process
2694		 */
2695		if (int_status == 0) {
2696
2697			break;
2698		}
2699
2700		if (int_status & MCP55_INT_COMPLETE) {
2701			NVLOG((NVDBG_INTR, nvc, nvp,
2702			    "mcp55_packet_complete_intr"));
2703			/*
2704			 * since int_status was set, return DDI_INTR_CLAIMED
2705			 * from the DDI's perspective even though the packet
2706			 * completion may not have succeeded.  If it fails,
2707			 * need to manually clear the interrupt, otherwise
2708			 * clearing is implicit.
2709			 */
2710			ret = DDI_INTR_CLAIMED;
2711			if (mcp55_packet_complete_intr(nvc, nvp) ==
2712			    NV_FAILURE) {
2713				clear = MCP55_INT_COMPLETE;
2714			} else {
2715				intr_cycles = 0;
2716			}
2717		}
2718
2719		if (int_status & MCP55_INT_DMA_SETUP) {
2720			NVLOG((NVDBG_INTR, nvc, nvp, "mcp55_dma_setup_intr"));
2721
2722			/*
2723			 * Needs to be cleared before starting the BM, so do it
2724			 * now.  make sure this is still working.
2725			 */
2726			nv_put16(bar5_hdl, nvp->nvp_mcp55_int_status,
2727			    MCP55_INT_DMA_SETUP);
2728#ifdef NCQ
2729			ret = mcp55_dma_setup_intr(nvc, nvp);
2730#endif
2731		}
2732
2733		if (int_status & MCP55_INT_REM) {
2734			NVLOG((NVDBG_INTR, nvc, nvp, "mcp55 device removed"));
2735			clear = MCP55_INT_REM;
2736			ret = DDI_INTR_CLAIMED;
2737
2738			mutex_enter(&nvp->nvp_mutex);
2739			nv_report_add_remove(nvp, NV_PORT_HOTREMOVED);
2740			mutex_exit(&nvp->nvp_mutex);
2741
2742		} else if (int_status & MCP55_INT_ADD) {
2743			NVLOG((NVDBG_HOT, nvc, nvp, "mcp55 device added"));
2744			clear = MCP55_INT_ADD;
2745			ret = DDI_INTR_CLAIMED;
2746
2747			mutex_enter(&nvp->nvp_mutex);
2748			nv_report_add_remove(nvp, 0);
2749			mutex_exit(&nvp->nvp_mutex);
2750		}
2751
2752		if (clear) {
2753			nv_put16(bar5_hdl, nvp->nvp_mcp55_int_status, clear);
2754			clear = 0;
2755		}
2756
2757		if (intr_cycles++ == NV_MAX_INTR_LOOP) {
2758			nv_cmn_err(CE_WARN, nvc, nvp, "excessive interrupt "
2759			    "processing.  Disabling port int_status=%X"
2760			    " clear=%X", int_status, clear);
2761			mutex_enter(&nvp->nvp_mutex);
2762			(*(nvc->nvc_set_intr))(nvp, NV_INTR_DISABLE);
2763			nv_port_state_change(nvp, SATA_EVNT_PORT_FAILED,
2764			    SATA_ADDR_CPORT, SATA_PSTATE_FAILED);
2765			nvp->nvp_state |= NV_PORT_FAILED;
2766			(void) nv_abort_active(nvp, NULL, SATA_PKT_DEV_ERROR);
2767			mutex_exit(&nvp->nvp_mutex);
2768		}
2769	}
2770
2771	NVLOG((NVDBG_INTR, nvc, nvp, "mcp55_intr_port: finished ret=%d", ret));
2772
2773	return (ret);
2774}
2775
2776
2777/* ARGSUSED */
2778static uint_t
2779mcp55_intr(caddr_t arg1, caddr_t arg2)
2780{
2781	nv_ctl_t *nvc = (nv_ctl_t *)arg1;
2782	int ret;
2783
2784	ret = mcp55_intr_port(&(nvc->nvc_port[0]));
2785	ret |= mcp55_intr_port(&(nvc->nvc_port[1]));
2786
2787	return (ret);
2788}
2789
2790
2791#ifdef NCQ
2792/*
2793 * with software driven NCQ on mcp55, an interrupt occurs right
2794 * before the drive is ready to do a DMA transfer.  At this point,
2795 * the PRD table needs to be programmed and the DMA engine enabled
2796 * and ready to go.
2797 *
2798 * -- MCP_SATA_AE_INT_STATUS_SDEV_DMA_SETUP indicates the interrupt
2799 * -- MCP_SATA_AE_NCQ_PDEV_DMA_SETUP_TAG shows which command is ready
2800 * -- clear bit 0 of master command reg
2801 * -- program PRD
2802 * -- clear the interrupt status bit for the DMA Setup FIS
2803 * -- set bit 0 of the bus master command register
2804 */
2805static int
2806mcp55_dma_setup_intr(nv_ctl_t *nvc, nv_port_t *nvp)
2807{
2808	int slot;
2809	ddi_acc_handle_t bmhdl = nvp->nvp_bm_hdl;
2810	uint8_t bmicx;
2811	int port = nvp->nvp_port_num;
2812	uint8_t tag_shift[] = {MCP_SATA_AE_NCQ_PDEV_DMA_SETUP_TAG_SHIFT,
2813	    MCP_SATA_AE_NCQ_SDEV_DMA_SETUP_TAG_SHIFT};
2814
2815	nv_cmn_err(CE_PANIC, nvc, nvp,
2816	    "this is should not be executed at all until NCQ");
2817
2818	mutex_enter(&nvp->nvp_mutex);
2819
2820	slot = nv_get32(nvc->nvc_bar_hdl[5], nvc->nvc_mcp55_ncq);
2821
2822	slot = (slot >> tag_shift[port]) & MCP_SATA_AE_NCQ_DMA_SETUP_TAG_MASK;
2823
2824	NVLOG((NVDBG_INTR, nvc, nvp, "mcp55_dma_setup_intr slot %d"
2825	    " nvp_slot_sactive %X", slot, nvp->nvp_sactive_cache));
2826
2827	/*
2828	 * halt the DMA engine.  This step is necessary according to
2829	 * the mcp55 spec, probably since there may have been a "first" packet
2830	 * that already programmed the DMA engine, but may not turn out to
2831	 * be the first one processed.
2832	 */
2833	bmicx = nv_get8(bmhdl, nvp->nvp_bmicx);
2834
2835#if 0
2836	if (bmicx & BMICX_SSBM) {
2837		NVLOG((NVDBG_INTR, nvc, nvp, "BM was already enabled for "
2838		    "another packet.  Cancelling and reprogramming"));
2839		nv_put8(bmhdl, nvp->nvp_bmicx,  bmicx & ~BMICX_SSBM);
2840	}
2841#endif
2842	nv_put8(bmhdl, nvp->nvp_bmicx,  bmicx & ~BMICX_SSBM);
2843
2844	nv_start_dma_engine(nvp, slot);
2845
2846	mutex_exit(&nvp->nvp_mutex);
2847
2848	return (DDI_INTR_CLAIMED);
2849}
2850#endif /* NCQ */
2851
2852
2853/*
2854 * packet completion interrupt.  If the packet is complete, invoke
2855 * the packet completion callback.
2856 */
2857static int
2858mcp55_packet_complete_intr(nv_ctl_t *nvc, nv_port_t *nvp)
2859{
2860	uint8_t status, bmstatus;
2861	ddi_acc_handle_t bmhdl = nvp->nvp_bm_hdl;
2862	int sactive;
2863	int active_pkt_bit = 0, active_pkt = 0, ncq_command = B_FALSE;
2864	sata_pkt_t *spkt;
2865	nv_slot_t *nv_slotp;
2866
2867	mutex_enter(&nvp->nvp_mutex);
2868
2869	bmstatus = nv_get8(bmhdl, nvp->nvp_bmisx);
2870
2871	if (!(bmstatus & BMISX_IDEINTS)) {
2872		NVLOG((NVDBG_INTR, nvc, nvp, "BMISX_IDEINTS not set"));
2873		mutex_exit(&nvp->nvp_mutex);
2874
2875		return (NV_FAILURE);
2876	}
2877
2878	/*
2879	 * If the just completed item is a non-ncq command, the busy
2880	 * bit should not be set
2881	 */
2882	if (nvp->nvp_non_ncq_run) {
2883		status = nv_get8(nvp->nvp_ctl_hdl, nvp->nvp_altstatus);
2884		if (status & SATA_STATUS_BSY) {
2885			nv_cmn_err(CE_WARN, nvc, nvp,
2886			    "unexpected SATA_STATUS_BSY set");
2887			mutex_exit(&nvp->nvp_mutex);
2888			/*
2889			 * calling function will clear interrupt.  then
2890			 * the real interrupt will either arrive or the
2891			 * packet timeout handling will take over and
2892			 * reset.
2893			 */
2894			return (NV_FAILURE);
2895		}
2896
2897	} else {
2898		/*
2899		 * NCQ check for BSY here and wait if still bsy before
2900		 * continuing. Rather than wait for it to be cleared
2901		 * when starting a packet and wasting CPU time, the starting
2902		 * thread can exit immediate, but might have to spin here
2903		 * for a bit possibly.  Needs more work and experimentation.
2904		 */
2905		ASSERT(nvp->nvp_ncq_run);
2906	}
2907
2908
2909	if (nvp->nvp_ncq_run) {
2910		ncq_command = B_TRUE;
2911		ASSERT(nvp->nvp_non_ncq_run == 0);
2912	} else {
2913		ASSERT(nvp->nvp_non_ncq_run != 0);
2914	}
2915
2916	/*
2917	 * active_pkt_bit will represent the bitmap of the single completed
2918	 * packet.  Because of the nature of sw assisted NCQ, only one
2919	 * command will complete per interrupt.
2920	 */
2921
2922	if (ncq_command == B_FALSE) {
2923		active_pkt = 0;
2924	} else {
2925		/*
2926		 * NCQ: determine which command just completed, by examining
2927		 * which bit cleared in the register since last written.
2928		 */
2929		sactive = nv_get32(nvc->nvc_bar_hdl[5], nvp->nvp_sactive);
2930
2931		active_pkt_bit = ~sactive & nvp->nvp_sactive_cache;
2932
2933		ASSERT(active_pkt_bit);
2934
2935
2936		/*
2937		 * this failure path needs more work to handle the
2938		 * error condition and recovery.
2939		 */
2940		if (active_pkt_bit == 0) {
2941			ddi_acc_handle_t cmdhdl = nvp->nvp_cmd_hdl;
2942
2943			nv_cmn_err(CE_CONT, nvc, nvp, "ERROR sactive = %X  "
2944			    "nvp->nvp_sactive %X", sactive,
2945			    nvp->nvp_sactive_cache);
2946
2947			(void) nv_get8(cmdhdl, nvp->nvp_status);
2948
2949			mutex_exit(&nvp->nvp_mutex);
2950
2951			return (NV_FAILURE);
2952		}
2953
2954		for (active_pkt = 0; (active_pkt_bit & 0x1) != 0x1;
2955		    active_pkt++, active_pkt_bit >>= 1) {
2956		}
2957
2958		/*
2959		 * make sure only one bit is ever turned on
2960		 */
2961		ASSERT(active_pkt_bit == 1);
2962
2963		nvp->nvp_sactive_cache &= ~(0x01 << active_pkt);
2964	}
2965
2966	nv_slotp = &(nvp->nvp_slot[active_pkt]);
2967
2968	spkt = nv_slotp->nvslot_spkt;
2969
2970	ASSERT(spkt != NULL);
2971
2972	(*nv_slotp->nvslot_intr)(nvp, nv_slotp);
2973
2974	nv_copy_registers(nvp, &spkt->satapkt_device, spkt);
2975
2976	/*
2977	 * If there is no link cannot be certain about the completion
2978	 * of the packet, so abort it.
2979	 */
2980	if (nv_check_link((&spkt->satapkt_device)->
2981	    satadev_scr.sstatus) == B_FALSE) {
2982		(void) nv_abort_active(nvp, NULL, SATA_PKT_PORT_ERROR);
2983
2984	} else if (nv_slotp->nvslot_flags == NVSLOT_COMPLETE) {
2985
2986		nv_complete_io(nvp, spkt, active_pkt);
2987	}
2988
2989	mutex_exit(&nvp->nvp_mutex);
2990
2991	return (NV_SUCCESS);
2992}
2993
2994
2995static void
2996nv_complete_io(nv_port_t *nvp, sata_pkt_t *spkt, int slot)
2997{
2998
2999	ASSERT(MUTEX_HELD(&nvp->nvp_mutex));
3000
3001	if ((&(nvp->nvp_slot[slot]))->nvslot_flags & NVSLOT_NCQ) {
3002		nvp->nvp_ncq_run--;
3003	} else {
3004		nvp->nvp_non_ncq_run--;
3005	}
3006
3007	/*
3008	 * mark the packet slot idle so it can be reused.  Do this before
3009	 * calling satapkt_comp so the slot can be reused.
3010	 */
3011	(&(nvp->nvp_slot[slot]))->nvslot_spkt = NULL;
3012
3013	if (spkt->satapkt_op_mode & SATA_OPMODE_SYNCH) {
3014		/*
3015		 * If this is not timed polled mode cmd, which has an
3016		 * active thread monitoring for completion, then need
3017		 * to signal the sleeping thread that the cmd is complete.
3018		 */
3019		if ((spkt->satapkt_op_mode & SATA_OPMODE_POLLING) == 0) {
3020			cv_signal(&nvp->nvp_poll_cv);
3021		}
3022
3023		return;
3024	}
3025
3026	if (spkt->satapkt_comp != NULL) {
3027		mutex_exit(&nvp->nvp_mutex);
3028		(*spkt->satapkt_comp)(spkt);
3029		mutex_enter(&nvp->nvp_mutex);
3030	}
3031}
3032
3033
3034/*
3035 * check whether packet is ncq command or not.  for ncq command,
3036 * start it if there is still room on queue.  for non-ncq command only
3037 * start if no other command is running.
3038 */
3039static int
3040nv_start_async(nv_port_t *nvp, sata_pkt_t *spkt)
3041{
3042	uint8_t cmd, ncq;
3043
3044	NVLOG((NVDBG_ENTRY, nvp->nvp_ctlp, nvp, "nv_start_async: entry"));
3045
3046	cmd = spkt->satapkt_cmd.satacmd_cmd_reg;
3047
3048	ncq = ((cmd == SATAC_WRITE_FPDMA_QUEUED) ||
3049	    (cmd == SATAC_READ_FPDMA_QUEUED));
3050
3051	if (ncq == B_FALSE) {
3052
3053		if ((nvp->nvp_non_ncq_run == 1) ||
3054		    (nvp->nvp_ncq_run > 0)) {
3055			/*
3056			 * next command is non-ncq which can't run
3057			 * concurrently.  exit and return queue full.
3058			 */
3059			spkt->satapkt_reason = SATA_PKT_QUEUE_FULL;
3060
3061			return (SATA_TRAN_QUEUE_FULL);
3062		}
3063
3064		return (nv_start_common(nvp, spkt));
3065	}
3066
3067	/*
3068	 * ncq == B_TRUE
3069	 */
3070	if (nvp->nvp_non_ncq_run == 1) {
3071		/*
3072		 * cannot start any NCQ commands when there
3073		 * is a non-NCQ command running.
3074		 */
3075		spkt->satapkt_reason = SATA_PKT_QUEUE_FULL;
3076
3077		return (SATA_TRAN_QUEUE_FULL);
3078	}
3079
3080#ifdef NCQ
3081	/*
3082	 * this is not compiled for now as satapkt_device.satadev_qdepth
3083	 * is being pulled out until NCQ support is later addressed
3084	 *
3085	 * nvp_queue_depth is initialized by the first NCQ command
3086	 * received.
3087	 */
3088	if (nvp->nvp_queue_depth == 1) {
3089		nvp->nvp_queue_depth =
3090		    spkt->satapkt_device.satadev_qdepth;
3091
3092		ASSERT(nvp->nvp_queue_depth > 1);
3093
3094		NVLOG((NVDBG_ENTRY, nvp->nvp_ctlp, nvp,
3095		    "nv_process_queue: nvp_queue_depth set to %d",
3096		    nvp->nvp_queue_depth));
3097	}
3098#endif
3099
3100	if (nvp->nvp_ncq_run >= nvp->nvp_queue_depth) {
3101		/*
3102		 * max number of NCQ commands already active
3103		 */
3104		spkt->satapkt_reason = SATA_PKT_QUEUE_FULL;
3105
3106		return (SATA_TRAN_QUEUE_FULL);
3107	}
3108
3109	return (nv_start_common(nvp, spkt));
3110}
3111
3112
3113/*
3114 * configure INTx and legacy interrupts
3115 */
3116static int
3117nv_add_legacy_intrs(nv_ctl_t *nvc)
3118{
3119	dev_info_t	*devinfo = nvc->nvc_dip;
3120	int		actual, count = 0;
3121	int		x, y, rc, inum = 0;
3122
3123	NVLOG((NVDBG_ENTRY, nvc, NULL, "nv_add_legacy_intrs"));
3124
3125	/*
3126	 * get number of interrupts
3127	 */
3128	rc = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_FIXED, &count);
3129	if ((rc != DDI_SUCCESS) || (count == 0)) {
3130		NVLOG((NVDBG_INTR, nvc, NULL,
3131		    "ddi_intr_get_nintrs() failed, "
3132		    "rc %d count %d", rc, count));
3133
3134		return (DDI_FAILURE);
3135	}
3136
3137	/*
3138	 * allocate an array of interrupt handles
3139	 */
3140	nvc->nvc_intr_size = count * sizeof (ddi_intr_handle_t);
3141	nvc->nvc_htable = kmem_zalloc(nvc->nvc_intr_size, KM_SLEEP);
3142
3143	/*
3144	 * call ddi_intr_alloc()
3145	 */
3146	rc = ddi_intr_alloc(devinfo, nvc->nvc_htable, DDI_INTR_TYPE_FIXED,
3147	    inum, count, &actual, DDI_INTR_ALLOC_STRICT);
3148
3149	if ((rc != DDI_SUCCESS) || (actual == 0)) {
3150		nv_cmn_err(CE_WARN, nvc, NULL,
3151		    "ddi_intr_alloc() failed, rc %d", rc);
3152		kmem_free(nvc->nvc_htable, nvc->nvc_intr_size);
3153
3154		return (DDI_FAILURE);
3155	}
3156
3157	if (actual < count) {
3158		nv_cmn_err(CE_WARN, nvc, NULL,
3159		    "ddi_intr_alloc: requested: %d, received: %d",
3160		    count, actual);
3161
3162		goto failure;
3163	}
3164
3165	nvc->nvc_intr_cnt = actual;
3166
3167	/*
3168	 * get intr priority
3169	 */
3170	if (ddi_intr_get_pri(nvc->nvc_htable[0], &nvc->nvc_intr_pri) !=
3171	    DDI_SUCCESS) {
3172		nv_cmn_err(CE_WARN, nvc, NULL, "ddi_intr_get_pri() failed");
3173
3174		goto failure;
3175	}
3176
3177	/*
3178	 * Test for high level mutex
3179	 */
3180	if (nvc->nvc_intr_pri >= ddi_intr_get_hilevel_pri()) {
3181		nv_cmn_err(CE_WARN, nvc, NULL,
3182		    "nv_add_legacy_intrs: high level intr not supported");
3183
3184		goto failure;
3185	}
3186
3187	for (x = 0; x < actual; x++) {
3188		if (ddi_intr_add_handler(nvc->nvc_htable[x],
3189		    nvc->nvc_interrupt, (caddr_t)nvc, NULL) != DDI_SUCCESS) {
3190			nv_cmn_err(CE_WARN, nvc, NULL,
3191			    "ddi_intr_add_handler() failed");
3192
3193			goto failure;
3194		}
3195	}
3196
3197	/*
3198	 * call ddi_intr_enable() for legacy interrupts
3199	 */
3200	for (x = 0; x < nvc->nvc_intr_cnt; x++) {
3201		(void) ddi_intr_enable(nvc->nvc_htable[x]);
3202	}
3203
3204	return (DDI_SUCCESS);
3205
3206	failure:
3207	/*
3208	 * free allocated intr and nvc_htable
3209	 */
3210	for (y = 0; y < actual; y++) {
3211		(void) ddi_intr_free(nvc->nvc_htable[y]);
3212	}
3213
3214	kmem_free(nvc->nvc_htable, nvc->nvc_intr_size);
3215
3216	return (DDI_FAILURE);
3217}
3218
3219#ifdef	NV_MSI_SUPPORTED
3220/*
3221 * configure MSI interrupts
3222 */
3223static int
3224nv_add_msi_intrs(nv_ctl_t *nvc)
3225{
3226	dev_info_t	*devinfo = nvc->nvc_dip;
3227	int		count, avail, actual;
3228	int		x, y, rc, inum = 0;
3229
3230	NVLOG((NVDBG_ENTRY, nvc, NULL, "nv_add_msi_intrs"));
3231
3232	/*
3233	 * get number of interrupts
3234	 */
3235	rc = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_MSI, &count);
3236	if ((rc != DDI_SUCCESS) || (count == 0)) {
3237		nv_cmn_err(CE_WARN, nvc, NULL,
3238		    "ddi_intr_get_nintrs() failed, "
3239		    "rc %d count %d", rc, count);
3240
3241		return (DDI_FAILURE);
3242	}
3243
3244	/*
3245	 * get number of available interrupts
3246	 */
3247	rc = ddi_intr_get_navail(devinfo, DDI_INTR_TYPE_MSI, &avail);
3248	if ((rc != DDI_SUCCESS) || (avail == 0)) {
3249		nv_cmn_err(CE_WARN, nvc, NULL,
3250		    "ddi_intr_get_navail() failed, "
3251		    "rc %d avail %d", rc, avail);
3252
3253		return (DDI_FAILURE);
3254	}
3255
3256	if (avail < count) {
3257		nv_cmn_err(CE_WARN, nvc, NULL,
3258		    "ddi_intr_get_nvail returned %d ddi_intr_get_nintrs: %d",
3259		    avail, count);
3260	}
3261
3262	/*
3263	 * allocate an array of interrupt handles
3264	 */
3265	nvc->nvc_intr_size = count * sizeof (ddi_intr_handle_t);
3266	nvc->nvc_htable = kmem_alloc(nvc->nvc_intr_size, KM_SLEEP);
3267
3268	rc = ddi_intr_alloc(devinfo, nvc->nvc_htable, DDI_INTR_TYPE_MSI,
3269	    inum, count, &actual, DDI_INTR_ALLOC_NORMAL);
3270
3271	if ((rc != DDI_SUCCESS) || (actual == 0)) {
3272		nv_cmn_err(CE_WARN, nvc, NULL,
3273		    "ddi_intr_alloc() failed, rc %d", rc);
3274		kmem_free(nvc->nvc_htable, nvc->nvc_intr_size);
3275
3276		return (DDI_FAILURE);
3277	}
3278
3279	/*
3280	 * Use interrupt count returned or abort?
3281	 */
3282	if (actual < count) {
3283		NVLOG((NVDBG_INIT, nvc, NULL,
3284		    "Requested: %d, Received: %d", count, actual));
3285	}
3286
3287	nvc->nvc_intr_cnt = actual;
3288
3289	/*
3290	 * get priority for first msi, assume remaining are all the same
3291	 */
3292	if (ddi_intr_get_pri(nvc->nvc_htable[0], &nvc->nvc_intr_pri) !=
3293	    DDI_SUCCESS) {
3294		nv_cmn_err(CE_WARN, nvc, NULL, "ddi_intr_get_pri() failed");
3295
3296		goto failure;
3297	}
3298
3299	/*
3300	 * test for high level mutex
3301	 */
3302	if (nvc->nvc_intr_pri >= ddi_intr_get_hilevel_pri()) {
3303		nv_cmn_err(CE_WARN, nvc, NULL,
3304		    "nv_add_msi_intrs: high level intr not supported");
3305
3306		goto failure;
3307	}
3308
3309	/*
3310	 * Call ddi_intr_add_handler()
3311	 */
3312	for (x = 0; x < actual; x++) {
3313		if (ddi_intr_add_handler(nvc->nvc_htable[x],
3314		    nvc->nvc_interrupt, (caddr_t)nvc, NULL) != DDI_SUCCESS) {
3315			nv_cmn_err(CE_WARN, nvc, NULL,
3316			    "ddi_intr_add_handler() failed");
3317
3318			goto failure;
3319		}
3320	}
3321
3322	(void) ddi_intr_get_cap(nvc->nvc_htable[0], &nvc->nvc_intr_cap);
3323
3324	if (nvc->nvc_intr_cap & DDI_INTR_FLAG_BLOCK) {
3325		(void) ddi_intr_block_enable(nvc->nvc_htable,
3326		    nvc->nvc_intr_cnt);
3327	} else {
3328		/*
3329		 * Call ddi_intr_enable() for MSI non block enable
3330		 */
3331		for (x = 0; x < nvc->nvc_intr_cnt; x++) {
3332			(void) ddi_intr_enable(nvc->nvc_htable[x]);
3333		}
3334	}
3335
3336	return (DDI_SUCCESS);
3337
3338	failure:
3339	/*
3340	 * free allocated intr and nvc_htable
3341	 */
3342	for (y = 0; y < actual; y++) {
3343		(void) ddi_intr_free(nvc->nvc_htable[y]);
3344	}
3345
3346	kmem_free(nvc->nvc_htable, nvc->nvc_intr_size);
3347
3348	return (DDI_FAILURE);
3349}
3350#endif
3351
3352
3353static void
3354nv_rem_intrs(nv_ctl_t *nvc)
3355{
3356	int x, i;
3357	nv_port_t *nvp;
3358
3359	NVLOG((NVDBG_ENTRY, nvc, NULL, "nv_rem_intrs"));
3360
3361	/*
3362	 * prevent controller from generating interrupts by
3363	 * masking them out.  This is an extra precaution.
3364	 */
3365	for (i = 0; i < NV_MAX_PORTS(nvc); i++) {
3366		nvp = (&nvc->nvc_port[i]);
3367		mutex_enter(&nvp->nvp_mutex);
3368		(*(nvc->nvc_set_intr))(nvp, NV_INTR_DISABLE);
3369		mutex_exit(&nvp->nvp_mutex);
3370	}
3371
3372	/*
3373	 * disable all interrupts
3374	 */
3375	if ((nvc->nvc_intr_type == DDI_INTR_TYPE_MSI) &&
3376	    (nvc->nvc_intr_cap & DDI_INTR_FLAG_BLOCK)) {
3377		(void) ddi_intr_block_disable(nvc->nvc_htable,
3378		    nvc->nvc_intr_cnt);
3379	} else {
3380		for (x = 0; x < nvc->nvc_intr_cnt; x++) {
3381			(void) ddi_intr_disable(nvc->nvc_htable[x]);
3382		}
3383	}
3384
3385	for (x = 0; x < nvc->nvc_intr_cnt; x++) {
3386		(void) ddi_intr_remove_handler(nvc->nvc_htable[x]);
3387		(void) ddi_intr_free(nvc->nvc_htable[x]);
3388	}
3389
3390	kmem_free(nvc->nvc_htable, nvc->nvc_intr_size);
3391}
3392
3393
3394/*
3395 * variable argument wrapper for cmn_err.  prefixes the instance and port
3396 * number if possible
3397 */
3398static void
3399nv_vcmn_err(int ce, nv_ctl_t *nvc, nv_port_t *nvp, char *fmt, va_list ap)
3400{
3401	char port[NV_STRING_10];
3402	char inst[NV_STRING_10];
3403
3404	mutex_enter(&nv_log_mutex);
3405
3406	if (nvc) {
3407		(void) snprintf(inst, NV_STRING_10, "inst %d",
3408		    ddi_get_instance(nvc->nvc_dip));
3409	} else {
3410		inst[0] = '\0';
3411	}
3412
3413	if (nvp) {
3414		(void) sprintf(port, " port %d", nvp->nvp_port_num);
3415	} else {
3416		port[0] = '\0';
3417	}
3418
3419	(void) sprintf(nv_log_buf, "nv_sata %s%s%s", inst, port,
3420	    (inst[0]|port[0] ? ": " :""));
3421
3422	(void) vsnprintf(&nv_log_buf[strlen(nv_log_buf)],
3423	    NV_STRING_512 - strlen(nv_log_buf), fmt, ap);
3424
3425	/*
3426	 * normally set to log to console but in some debug situations it
3427	 * may be useful to log only to a file.
3428	 */
3429	if (nv_log_to_console) {
3430		if (nv_prom_print) {
3431			prom_printf("%s\n", nv_log_buf);
3432		} else {
3433			cmn_err(ce, "%s", nv_log_buf);
3434		}
3435
3436
3437	} else {
3438		cmn_err(ce, "!%s", nv_log_buf);
3439	}
3440
3441	mutex_exit(&nv_log_mutex);
3442}
3443
3444
3445/*
3446 * wrapper for cmn_err
3447 */
3448static void
3449nv_cmn_err(int ce, nv_ctl_t *nvc, nv_port_t *nvp, char *fmt, ...)
3450{
3451	va_list ap;
3452
3453	va_start(ap, fmt);
3454	nv_vcmn_err(ce, nvc, nvp, fmt, ap);
3455	va_end(ap);
3456}
3457
3458
3459#if defined(DEBUG)
3460/*
3461 * prefixes the instance and port number if possible to the debug message
3462 */
3463static void
3464nv_log(uint_t flag, nv_ctl_t *nvc, nv_port_t *nvp, char *fmt, ...)
3465{
3466	va_list ap;
3467
3468	if ((nv_debug_flags & flag) == 0) {
3469		return;
3470	}
3471
3472	va_start(ap, fmt);
3473	nv_vcmn_err(CE_NOTE, nvc, nvp, fmt, ap);
3474	va_end(ap);
3475
3476	/*
3477	 * useful for some debugging situations
3478	 */
3479	if (nv_log_delay) {
3480		drv_usecwait(nv_log_delay);
3481	}
3482
3483}
3484#endif /* DEBUG */
3485
3486
3487/*
3488 * program registers which are common to all commands
3489 */
3490static void
3491nv_program_taskfile_regs(nv_port_t *nvp, int slot)
3492{
3493	nv_slot_t *nv_slotp = &(nvp->nvp_slot[slot]);
3494	sata_pkt_t *spkt;
3495	sata_cmd_t *satacmd;
3496	ddi_acc_handle_t cmdhdl = nvp->nvp_cmd_hdl;
3497	uint8_t cmd, ncq = B_FALSE;
3498
3499	spkt = nv_slotp->nvslot_spkt;
3500	satacmd = &spkt->satapkt_cmd;
3501	cmd = satacmd->satacmd_cmd_reg;
3502
3503	ASSERT(nvp->nvp_slot);
3504
3505	if ((cmd == SATAC_WRITE_FPDMA_QUEUED) ||
3506	    (cmd == SATAC_READ_FPDMA_QUEUED)) {
3507		ncq = B_TRUE;
3508	}
3509
3510	/*
3511	 * select the drive
3512	 */
3513	nv_put8(cmdhdl, nvp->nvp_drvhd, satacmd->satacmd_device_reg);
3514
3515	/*
3516	 * make certain the drive selected
3517	 */
3518	if (nv_wait(nvp, SATA_STATUS_DRDY, SATA_STATUS_BSY,
3519	    NV_SEC2USEC(5), 0) == B_FALSE) {
3520
3521		return;
3522	}
3523
3524	switch (spkt->satapkt_cmd.satacmd_addr_type) {
3525
3526	case ATA_ADDR_LBA:
3527		NVLOG((NVDBG_DELIVER, nvp->nvp_ctlp, nvp, "ATA_ADDR_LBA mode"));
3528
3529		nv_put8(cmdhdl, nvp->nvp_count, satacmd->satacmd_sec_count_lsb);
3530		nv_put8(cmdhdl, nvp->nvp_hcyl, satacmd->satacmd_lba_high_lsb);
3531		nv_put8(cmdhdl, nvp->nvp_lcyl, satacmd->satacmd_lba_mid_lsb);
3532		nv_put8(cmdhdl, nvp->nvp_sect, satacmd->satacmd_lba_low_lsb);
3533
3534		break;
3535
3536	case ATA_ADDR_LBA28:
3537		NVLOG((NVDBG_DELIVER, nvp->nvp_ctlp, nvp,
3538		    "ATA_ADDR_LBA28 mode"));
3539		/*
3540		 * NCQ only uses 48-bit addressing
3541		 */
3542		ASSERT(ncq != B_TRUE);
3543
3544		nv_put8(cmdhdl, nvp->nvp_count, satacmd->satacmd_sec_count_lsb);
3545		nv_put8(cmdhdl, nvp->nvp_hcyl, satacmd->satacmd_lba_high_lsb);
3546		nv_put8(cmdhdl, nvp->nvp_lcyl, satacmd->satacmd_lba_mid_lsb);
3547		nv_put8(cmdhdl, nvp->nvp_sect, satacmd->satacmd_lba_low_lsb);
3548
3549		break;
3550
3551	case ATA_ADDR_LBA48:
3552		NVLOG((NVDBG_DELIVER, nvp->nvp_ctlp, nvp,
3553		    "ATA_ADDR_LBA48 mode"));
3554
3555		/*
3556		 * for NCQ, tag goes into count register and real sector count
3557		 * into features register.  The sata module does the translation
3558		 * in the satacmd.
3559		 */
3560		if (ncq == B_TRUE) {
3561			nv_put8(cmdhdl, nvp->nvp_count, slot << 3);
3562			nv_put8(cmdhdl, nvp->nvp_feature,
3563			    satacmd->satacmd_features_reg_ext);
3564			nv_put8(cmdhdl, nvp->nvp_feature,
3565			    satacmd->satacmd_features_reg);
3566		} else {
3567			nv_put8(cmdhdl, nvp->nvp_count,
3568			    satacmd->satacmd_sec_count_msb);
3569			nv_put8(cmdhdl, nvp->nvp_count,
3570			    satacmd->satacmd_sec_count_lsb);
3571		}
3572
3573		/*
3574		 * send the high-order half first
3575		 */
3576		nv_put8(cmdhdl, nvp->nvp_hcyl, satacmd->satacmd_lba_high_msb);
3577		nv_put8(cmdhdl, nvp->nvp_lcyl, satacmd->satacmd_lba_mid_msb);
3578		nv_put8(cmdhdl, nvp->nvp_sect, satacmd->satacmd_lba_low_msb);
3579		/*
3580		 * Send the low-order half
3581		 */
3582		nv_put8(cmdhdl, nvp->nvp_hcyl, satacmd->satacmd_lba_high_lsb);
3583		nv_put8(cmdhdl, nvp->nvp_lcyl, satacmd->satacmd_lba_mid_lsb);
3584		nv_put8(cmdhdl, nvp->nvp_sect, satacmd->satacmd_lba_low_lsb);
3585
3586		break;
3587
3588	case 0:
3589		/*
3590		 * non-media access commands such as identify and features
3591		 * take this path.
3592		 */
3593		nv_put8(cmdhdl, nvp->nvp_count, satacmd->satacmd_sec_count_lsb);
3594		nv_put8(cmdhdl, nvp->nvp_feature,
3595		    satacmd->satacmd_features_reg);
3596		nv_put8(cmdhdl, nvp->nvp_hcyl, satacmd->satacmd_lba_high_lsb);
3597		nv_put8(cmdhdl, nvp->nvp_lcyl, satacmd->satacmd_lba_mid_lsb);
3598		nv_put8(cmdhdl, nvp->nvp_sect, satacmd->satacmd_lba_low_lsb);
3599
3600		break;
3601
3602	default:
3603		break;
3604	}
3605
3606	ASSERT(nvp->nvp_slot);
3607}
3608
3609
3610/*
3611 * start a command that involves no media access
3612 */
3613static int
3614nv_start_nodata(nv_port_t *nvp, int slot)
3615{
3616	nv_slot_t *nv_slotp = &(nvp->nvp_slot[slot]);
3617	sata_pkt_t *spkt = nv_slotp->nvslot_spkt;
3618	sata_cmd_t *sata_cmdp = &spkt->satapkt_cmd;
3619	ddi_acc_handle_t cmdhdl = nvp->nvp_cmd_hdl;
3620
3621	nv_program_taskfile_regs(nvp, slot);
3622
3623	/*
3624	 * This next one sets the controller in motion
3625	 */
3626	nv_put8(cmdhdl, nvp->nvp_cmd, sata_cmdp->satacmd_cmd_reg);
3627
3628	return (SATA_TRAN_ACCEPTED);
3629}
3630
3631
3632int
3633nv_bm_status_clear(nv_port_t *nvp)
3634{
3635	ddi_acc_handle_t bmhdl = nvp->nvp_bm_hdl;
3636	uchar_t	status, ret;
3637
3638	/*
3639	 * Get the current BM status
3640	 */
3641	ret = status = nv_get8(bmhdl, nvp->nvp_bmisx);
3642
3643	status = (status & BMISX_MASK) | BMISX_IDERR | BMISX_IDEINTS;
3644
3645	/*
3646	 * Clear the latches (and preserve the other bits)
3647	 */
3648	nv_put8(bmhdl, nvp->nvp_bmisx, status);
3649
3650	return (ret);
3651}
3652
3653
3654/*
3655 * program the bus master DMA engine with the PRD address for
3656 * the active slot command, and start the DMA engine.
3657 */
3658static void
3659nv_start_dma_engine(nv_port_t *nvp, int slot)
3660{
3661	nv_slot_t *nv_slotp = &(nvp->nvp_slot[slot]);
3662	ddi_acc_handle_t bmhdl = nvp->nvp_bm_hdl;
3663	uchar_t direction;
3664
3665	ASSERT(nv_slotp->nvslot_spkt != NULL);
3666
3667	if (nv_slotp->nvslot_spkt->satapkt_cmd.satacmd_flags.sata_data_direction
3668	    == SATA_DIR_READ) {
3669		direction = BMICX_RWCON_WRITE_TO_MEMORY;
3670	} else {
3671		direction = BMICX_RWCON_READ_FROM_MEMORY;
3672	}
3673
3674	NVLOG((NVDBG_DELIVER, nvp->nvp_ctlp, nvp,
3675	    "nv_start_dma_engine entered"));
3676
3677	/*
3678	 * reset the controller's interrupt and error status bits
3679	 */
3680	(void) nv_bm_status_clear(nvp);
3681
3682	/*
3683	 * program the PRD table physical start address
3684	 */
3685	nv_put32(bmhdl, nvp->nvp_bmidtpx, nvp->nvp_sg_paddr[slot]);
3686
3687	/*
3688	 * set the direction control and start the DMA controller
3689	 */
3690	nv_put8(bmhdl, nvp->nvp_bmicx, direction | BMICX_SSBM);
3691}
3692
3693/*
3694 * start dma command, either in or out
3695 */
3696static int
3697nv_start_dma(nv_port_t *nvp, int slot)
3698{
3699	nv_slot_t *nv_slotp = &(nvp->nvp_slot[slot]);
3700	ddi_acc_handle_t cmdhdl = nvp->nvp_cmd_hdl;
3701	sata_pkt_t *spkt = nv_slotp->nvslot_spkt;
3702	sata_cmd_t *sata_cmdp = &spkt->satapkt_cmd;
3703	uint8_t cmd = sata_cmdp->satacmd_cmd_reg;
3704#ifdef NCQ
3705	uint8_t ncq = B_FALSE;
3706#endif
3707	ddi_acc_handle_t sghdl = nvp->nvp_sg_acc_hdl[slot];
3708	uint_t *dstp = (uint_t *)nvp->nvp_sg_addr[slot];
3709	int sg_count = sata_cmdp->satacmd_num_dma_cookies, idx;
3710	ddi_dma_cookie_t  *srcp = sata_cmdp->satacmd_dma_cookie_list;
3711
3712	ASSERT(sg_count != 0);
3713
3714	if (sata_cmdp->satacmd_num_dma_cookies > NV_DMA_NSEGS) {
3715		nv_cmn_err(CE_WARN, nvp->nvp_ctlp, nvp, "NV_DMA_NSEGS=%d <"
3716		    " satacmd_num_dma_cookies=%d", NV_DMA_NSEGS,
3717		    sata_cmdp->satacmd_num_dma_cookies);
3718
3719		return (NV_FAILURE);
3720	}
3721
3722	nv_program_taskfile_regs(nvp, slot);
3723
3724	/*
3725	 * start the drive in motion
3726	 */
3727	nv_put8(cmdhdl, nvp->nvp_cmd, cmd);
3728
3729	/*
3730	 * the drive starts processing the transaction when the cmd register
3731	 * is written.  This is done here before programming the DMA engine to
3732	 * parallelize and save some time.  In the event that the drive is ready
3733	 * before DMA, it will wait.
3734	 */
3735#ifdef NCQ
3736	if ((cmd == SATAC_WRITE_FPDMA_QUEUED) ||
3737	    (cmd == SATAC_READ_FPDMA_QUEUED)) {
3738		ncq = B_TRUE;
3739	}
3740#endif
3741
3742	/*
3743	 * copy the PRD list to PRD table in DMA accessible memory
3744	 * so that the controller can access it.
3745	 */
3746	for (idx = 0; idx < sg_count; idx++, srcp++) {
3747		uint32_t size;
3748
3749		ASSERT(srcp->dmac_size <= UINT16_MAX);
3750
3751		nv_put32(sghdl, dstp++, srcp->dmac_address);
3752
3753		size = srcp->dmac_size;
3754
3755		/*
3756		 * If this is a 40-bit address, copy bits 32-40 of the
3757		 * physical address to bits 16-24 of the PRD count.
3758		 */
3759		if (srcp->dmac_laddress > UINT32_MAX) {
3760			size |= ((srcp->dmac_laddress & 0xff00000000) >> 16);
3761		}
3762
3763		/*
3764		 * set the end of table flag for the last entry
3765		 */
3766		if (idx == (sg_count - 1)) {
3767			size |= PRDE_EOT;
3768		}
3769
3770		nv_put32(sghdl, dstp++, size);
3771	}
3772
3773	(void) ddi_dma_sync(nvp->nvp_sg_dma_hdl[slot], 0,
3774	    sizeof (prde_t) * NV_DMA_NSEGS, DDI_DMA_SYNC_FORDEV);
3775
3776	nv_start_dma_engine(nvp, slot);
3777
3778#ifdef NCQ
3779	/*
3780	 * optimization:  for SWNCQ, start DMA engine if this is the only
3781	 * command running.  Preliminary NCQ efforts indicated this needs
3782	 * more debugging.
3783	 *
3784	 * if (nvp->nvp_ncq_run <= 1)
3785	 */
3786
3787	if (ncq == B_FALSE) {
3788		NVLOG((NVDBG_DELIVER, nvp->nvp_ctlp, nvp,
3789		    "NOT NCQ so starting DMA NOW non_ncq_commands=%d"
3790		    " cmd = %X", non_ncq_commands++, cmd));
3791		nv_start_dma_engine(nvp, slot);
3792	} else {
3793		NVLOG((NVDBG_DELIVER, nvp->nvp_ctlp, nvp, "?NCQ, so program "
3794		    "DMA later ncq_commands=%d cmd = %X", ncq_commands++, cmd));
3795	}
3796#endif /* NCQ */
3797
3798	return (SATA_TRAN_ACCEPTED);
3799}
3800
3801
3802/*
3803 * start a PIO data-in ATA command
3804 */
3805static int
3806nv_start_pio_in(nv_port_t *nvp, int slot)
3807{
3808
3809	nv_slot_t *nv_slotp = &(nvp->nvp_slot[slot]);
3810	sata_pkt_t *spkt = nv_slotp->nvslot_spkt;
3811	ddi_acc_handle_t cmdhdl = nvp->nvp_cmd_hdl;
3812
3813	nv_program_taskfile_regs(nvp, slot);
3814
3815	/*
3816	 * This next one sets the drive in motion
3817	 */
3818	nv_put8(cmdhdl, nvp->nvp_cmd, spkt->satapkt_cmd.satacmd_cmd_reg);
3819
3820	return (SATA_TRAN_ACCEPTED);
3821}
3822
3823
3824/*
3825 * start a PIO data-out ATA command
3826 */
3827static int
3828nv_start_pio_out(nv_port_t *nvp, int slot)
3829{
3830	nv_slot_t *nv_slotp = &(nvp->nvp_slot[slot]);
3831	ddi_acc_handle_t cmdhdl = nvp->nvp_cmd_hdl;
3832	sata_pkt_t *spkt = nv_slotp->nvslot_spkt;
3833
3834	nv_program_taskfile_regs(nvp, slot);
3835
3836	/*
3837	 * this next one sets the drive in motion
3838	 */
3839	nv_put8(cmdhdl, nvp->nvp_cmd, spkt->satapkt_cmd.satacmd_cmd_reg);
3840
3841	/*
3842	 * wait for the busy bit to settle
3843	 */
3844	NV_DELAY_NSEC(400);
3845
3846	/*
3847	 * wait for the drive to assert DRQ to send the first chunk
3848	 * of data. Have to busy wait because there's no interrupt for
3849	 * the first chunk. This is bad... uses a lot of cycles if the
3850	 * drive responds too slowly or if the wait loop granularity
3851	 * is too large. It's even worse if the drive is defective and
3852	 * the loop times out.
3853	 */
3854	if (nv_wait3(nvp, SATA_STATUS_DRQ, SATA_STATUS_BSY, /* okay */
3855	    SATA_STATUS_ERR, SATA_STATUS_BSY, /* cmd failed */
3856	    SATA_STATUS_DF, SATA_STATUS_BSY, /* drive failed */
3857	    4000000, 0) == B_FALSE) {
3858		spkt->satapkt_reason = SATA_PKT_TIMEOUT;
3859
3860		goto error;
3861	}
3862
3863	/*
3864	 * send the first block.
3865	 */
3866	nv_intr_pio_out(nvp, nv_slotp);
3867
3868	/*
3869	 * If nvslot_flags is not set to COMPLETE yet, then processing
3870	 * is OK so far, so return.  Otherwise, fall into error handling
3871	 * below.
3872	 */
3873	if (nv_slotp->nvslot_flags != NVSLOT_COMPLETE) {
3874
3875		return (SATA_TRAN_ACCEPTED);
3876	}
3877
3878	error:
3879	/*
3880	 * there was an error so reset the device and complete the packet.
3881	 */
3882	nv_copy_registers(nvp, &spkt->satapkt_device, spkt);
3883	nv_complete_io(nvp, spkt, 0);
3884	nv_reset(nvp);
3885
3886	return (SATA_TRAN_PORT_ERROR);
3887}
3888
3889
3890/*
3891 * start a ATAPI Packet command (PIO data in or out)
3892 */
3893static int
3894nv_start_pkt_pio(nv_port_t *nvp, int slot)
3895{
3896	nv_slot_t *nv_slotp = &(nvp->nvp_slot[slot]);
3897	sata_pkt_t *spkt = nv_slotp->nvslot_spkt;
3898	ddi_acc_handle_t cmdhdl = nvp->nvp_cmd_hdl;
3899	sata_cmd_t *satacmd = &spkt->satapkt_cmd;
3900
3901	NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
3902	    "nv_start_pkt_pio: start"));
3903
3904	/*
3905	 * Write the PACKET command to the command register.  Normally
3906	 * this would be done through nv_program_taskfile_regs().  It
3907	 * is done here because some values need to be overridden.
3908	 */
3909
3910	/* select the drive */
3911	nv_put8(cmdhdl, nvp->nvp_drvhd, satacmd->satacmd_device_reg);
3912
3913	/* make certain the drive selected */
3914	if (nv_wait(nvp, SATA_STATUS_DRDY, SATA_STATUS_BSY,
3915	    NV_SEC2USEC(5), 0) == B_FALSE) {
3916		NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
3917		    "nv_start_pkt_pio: drive select failed"));
3918		return (SATA_TRAN_PORT_ERROR);
3919	}
3920
3921	/*
3922	 * The command is always sent via PIO, despite whatever the SATA
3923	 * framework sets in the command.  Overwrite the DMA bit to do this.
3924	 * Also, overwrite the overlay bit to be safe (it shouldn't be set).
3925	 */
3926	nv_put8(cmdhdl, nvp->nvp_feature, 0);	/* deassert DMA and OVL */
3927
3928	/* set appropriately by the sata framework */
3929	nv_put8(cmdhdl, nvp->nvp_hcyl, satacmd->satacmd_lba_high_lsb);
3930	nv_put8(cmdhdl, nvp->nvp_lcyl, satacmd->satacmd_lba_mid_lsb);
3931	nv_put8(cmdhdl, nvp->nvp_sect, satacmd->satacmd_lba_low_lsb);
3932	nv_put8(cmdhdl, nvp->nvp_count, satacmd->satacmd_sec_count_lsb);
3933
3934	/* initiate the command by writing the command register last */
3935	nv_put8(cmdhdl, nvp->nvp_cmd, spkt->satapkt_cmd.satacmd_cmd_reg);
3936
3937	/* Give the host controller time to do its thing */
3938	NV_DELAY_NSEC(400);
3939
3940	/*
3941	 * Wait for the device to indicate that it is ready for the command
3942	 * ATAPI protocol state - HP0: Check_Status_A
3943	 */
3944
3945	if (nv_wait3(nvp, SATA_STATUS_DRQ, SATA_STATUS_BSY, /* okay */
3946	    SATA_STATUS_ERR, SATA_STATUS_BSY, /* cmd failed */
3947	    SATA_STATUS_DF, SATA_STATUS_BSY, /* drive failed */
3948	    4000000, 0) == B_FALSE) {
3949		/*
3950		 * Either an error or device fault occurred or the wait
3951		 * timed out.  According to the ATAPI protocol, command
3952		 * completion is also possible.  Other implementations of
3953		 * this protocol don't handle this last case, so neither
3954		 * does this code.
3955		 */
3956
3957		if (nv_get8(cmdhdl, nvp->nvp_status) &
3958		    (SATA_STATUS_ERR | SATA_STATUS_DF)) {
3959			spkt->satapkt_reason = SATA_PKT_DEV_ERROR;
3960
3961			NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
3962			    "nv_start_pkt_pio: device error (HP0)"));
3963		} else {
3964			spkt->satapkt_reason = SATA_PKT_TIMEOUT;
3965
3966			NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
3967			    "nv_start_pkt_pio: timeout (HP0)"));
3968		}
3969
3970		nv_copy_registers(nvp, &spkt->satapkt_device, spkt);
3971		nv_complete_io(nvp, spkt, 0);
3972		nv_reset(nvp);
3973
3974		return (SATA_TRAN_PORT_ERROR);
3975	}
3976
3977	/*
3978	 * Put the ATAPI command in the data register
3979	 * ATAPI protocol state - HP1: Send_Packet
3980	 */
3981
3982	ddi_rep_put16(cmdhdl, (ushort_t *)spkt->satapkt_cmd.satacmd_acdb,
3983	    (ushort_t *)nvp->nvp_data,
3984	    (spkt->satapkt_cmd.satacmd_acdb_len >> 1), DDI_DEV_NO_AUTOINCR);
3985
3986	/*
3987	 * See you in nv_intr_pkt_pio.
3988	 * ATAPI protocol state - HP3: INTRQ_wait
3989	 */
3990
3991	NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
3992	    "nv_start_pkt_pio: exiting into HP3"));
3993
3994	return (SATA_TRAN_ACCEPTED);
3995}
3996
3997
3998/*
3999 * Interrupt processing for a non-data ATA command.
4000 */
4001static void
4002nv_intr_nodata(nv_port_t *nvp, nv_slot_t *nv_slotp)
4003{
4004	uchar_t status;
4005	sata_pkt_t *spkt = nv_slotp->nvslot_spkt;
4006	sata_cmd_t *sata_cmdp = &spkt->satapkt_cmd;
4007	ddi_acc_handle_t ctlhdl = nvp->nvp_ctl_hdl;
4008	ddi_acc_handle_t cmdhdl = nvp->nvp_cmd_hdl;
4009
4010	NVLOG((NVDBG_INTR, nvp->nvp_ctlp, nvp, "nv_intr_nodata entered"));
4011
4012	status = nv_get8(cmdhdl, nvp->nvp_status);
4013
4014	/*
4015	 * check for errors
4016	 */
4017	if (status & (SATA_STATUS_DF | SATA_STATUS_ERR)) {
4018		spkt->satapkt_reason = SATA_PKT_DEV_ERROR;
4019		sata_cmdp->satacmd_status_reg = nv_get8(ctlhdl,
4020		    nvp->nvp_altstatus);
4021		sata_cmdp->satacmd_error_reg = nv_get8(cmdhdl, nvp->nvp_error);
4022	} else {
4023		spkt->satapkt_reason = SATA_PKT_COMPLETED;
4024	}
4025
4026	nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4027}
4028
4029
4030/*
4031 * ATA command, PIO data in
4032 */
4033static void
4034nv_intr_pio_in(nv_port_t *nvp, nv_slot_t *nv_slotp)
4035{
4036	uchar_t	status;
4037	sata_pkt_t *spkt = nv_slotp->nvslot_spkt;
4038	sata_cmd_t *sata_cmdp = &spkt->satapkt_cmd;
4039	ddi_acc_handle_t ctlhdl = nvp->nvp_ctl_hdl;
4040	ddi_acc_handle_t cmdhdl = nvp->nvp_cmd_hdl;
4041	int count;
4042
4043	status = nv_get8(cmdhdl, nvp->nvp_status);
4044
4045	if (status & SATA_STATUS_BSY) {
4046		spkt->satapkt_reason = SATA_PKT_TIMEOUT;
4047		nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4048		sata_cmdp->satacmd_status_reg = nv_get8(ctlhdl,
4049		    nvp->nvp_altstatus);
4050		sata_cmdp->satacmd_error_reg = nv_get8(cmdhdl, nvp->nvp_error);
4051		nv_reset(nvp);
4052
4053		return;
4054	}
4055
4056	/*
4057	 * check for errors
4058	 */
4059	if ((status & (SATA_STATUS_DRQ | SATA_STATUS_DF |
4060	    SATA_STATUS_ERR)) != SATA_STATUS_DRQ) {
4061		nv_copy_registers(nvp, &spkt->satapkt_device, spkt);
4062		nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4063		spkt->satapkt_reason = SATA_PKT_DEV_ERROR;
4064
4065		return;
4066	}
4067
4068	/*
4069	 * read the next chunk of data (if any)
4070	 */
4071	count = min(nv_slotp->nvslot_byte_count, NV_BYTES_PER_SEC);
4072
4073	/*
4074	 * read count bytes
4075	 */
4076	ASSERT(count != 0);
4077
4078	ddi_rep_get16(cmdhdl, (ushort_t *)nv_slotp->nvslot_v_addr,
4079	    (ushort_t *)nvp->nvp_data, (count >> 1), DDI_DEV_NO_AUTOINCR);
4080
4081	nv_slotp->nvslot_v_addr += count;
4082	nv_slotp->nvslot_byte_count -= count;
4083
4084
4085	if (nv_slotp->nvslot_byte_count != 0) {
4086		/*
4087		 * more to transfer.  Wait for next interrupt.
4088		 */
4089		return;
4090	}
4091
4092	/*
4093	 * transfer is complete. wait for the busy bit to settle.
4094	 */
4095	NV_DELAY_NSEC(400);
4096
4097	spkt->satapkt_reason = SATA_PKT_COMPLETED;
4098	nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4099}
4100
4101
4102/*
4103 * ATA command PIO data out
4104 */
4105static void
4106nv_intr_pio_out(nv_port_t *nvp, nv_slot_t *nv_slotp)
4107{
4108	sata_pkt_t *spkt = nv_slotp->nvslot_spkt;
4109	sata_cmd_t *sata_cmdp = &spkt->satapkt_cmd;
4110	uchar_t status;
4111	ddi_acc_handle_t ctlhdl = nvp->nvp_ctl_hdl;
4112	ddi_acc_handle_t cmdhdl = nvp->nvp_cmd_hdl;
4113	int count;
4114
4115	/*
4116	 * clear the IRQ
4117	 */
4118	status = nv_get8(cmdhdl, nvp->nvp_status);
4119
4120	if (status & SATA_STATUS_BSY) {
4121		/*
4122		 * this should not happen
4123		 */
4124		spkt->satapkt_reason = SATA_PKT_TIMEOUT;
4125		nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4126		sata_cmdp->satacmd_status_reg = nv_get8(ctlhdl,
4127		    nvp->nvp_altstatus);
4128		sata_cmdp->satacmd_error_reg = nv_get8(cmdhdl, nvp->nvp_error);
4129
4130		return;
4131	}
4132
4133	/*
4134	 * check for errors
4135	 */
4136	if (status & (SATA_STATUS_DF | SATA_STATUS_ERR)) {
4137		nv_copy_registers(nvp,  &spkt->satapkt_device, spkt);
4138		nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4139		spkt->satapkt_reason = SATA_PKT_DEV_ERROR;
4140
4141		return;
4142	}
4143
4144	/*
4145	 * this is the condition which signals the drive is
4146	 * no longer ready to transfer.  Likely that the transfer
4147	 * completed successfully, but check that byte_count is
4148	 * zero.
4149	 */
4150	if ((status & SATA_STATUS_DRQ) == 0) {
4151
4152		if (nv_slotp->nvslot_byte_count == 0) {
4153			/*
4154			 * complete; successful transfer
4155			 */
4156			spkt->satapkt_reason = SATA_PKT_COMPLETED;
4157		} else {
4158			/*
4159			 * error condition, incomplete transfer
4160			 */
4161			nv_copy_registers(nvp, &spkt->satapkt_device, spkt);
4162			spkt->satapkt_reason = SATA_PKT_DEV_ERROR;
4163		}
4164		nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4165
4166		return;
4167	}
4168
4169	/*
4170	 * write the next chunk of data
4171	 */
4172	count = min(nv_slotp->nvslot_byte_count, NV_BYTES_PER_SEC);
4173
4174	/*
4175	 * read or write count bytes
4176	 */
4177
4178	ASSERT(count != 0);
4179
4180	ddi_rep_put16(cmdhdl, (ushort_t *)nv_slotp->nvslot_v_addr,
4181	    (ushort_t *)nvp->nvp_data, (count >> 1), DDI_DEV_NO_AUTOINCR);
4182
4183	nv_slotp->nvslot_v_addr += count;
4184	nv_slotp->nvslot_byte_count -= count;
4185}
4186
4187
4188/*
4189 * ATAPI PACKET command, PIO in/out interrupt
4190 *
4191 * Under normal circumstances, one of four different interrupt scenarios
4192 * will result in this function being called:
4193 *
4194 * 1. Packet command data transfer
4195 * 2. Packet command completion
4196 * 3. Request sense data transfer
4197 * 4. Request sense command completion
4198 */
4199static void
4200nv_intr_pkt_pio(nv_port_t *nvp, nv_slot_t *nv_slotp)
4201{
4202	uchar_t	status;
4203	sata_pkt_t *spkt = nv_slotp->nvslot_spkt;
4204	sata_cmd_t *sata_cmdp = &spkt->satapkt_cmd;
4205	int direction = sata_cmdp->satacmd_flags.sata_data_direction;
4206	ddi_acc_handle_t ctlhdl = nvp->nvp_ctl_hdl;
4207	ddi_acc_handle_t cmdhdl = nvp->nvp_cmd_hdl;
4208	uint16_t ctlr_count;
4209	int count;
4210
4211	/* ATAPI protocol state - HP2: Check_Status_B */
4212
4213	status = nv_get8(cmdhdl, nvp->nvp_status);
4214	NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
4215	    "nv_intr_pkt_pio: status 0x%x", status));
4216
4217	if (status & SATA_STATUS_BSY) {
4218		if ((nv_slotp->nvslot_flags & NVSLOT_RQSENSE) != 0) {
4219			nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4220			spkt->satapkt_reason = SATA_PKT_DEV_ERROR;
4221		} else {
4222			nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4223			spkt->satapkt_reason = SATA_PKT_TIMEOUT;
4224
4225			nv_reset(nvp);
4226		}
4227
4228		NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
4229		    "nv_intr_pkt_pio: busy - status 0x%x", status));
4230
4231		return;
4232	}
4233
4234	if ((status & SATA_STATUS_DF) != 0) {
4235		/*
4236		 * On device fault, just clean up and bail.  Request sense
4237		 * will just default to its NO SENSE initialized value.
4238		 */
4239
4240		if ((nv_slotp->nvslot_flags & NVSLOT_RQSENSE) == 0) {
4241			nv_copy_registers(nvp, &spkt->satapkt_device, spkt);
4242		}
4243
4244		nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4245		spkt->satapkt_reason = SATA_PKT_DEV_ERROR;
4246
4247		sata_cmdp->satacmd_status_reg = nv_get8(ctlhdl,
4248		    nvp->nvp_altstatus);
4249		sata_cmdp->satacmd_error_reg = nv_get8(cmdhdl,
4250		    nvp->nvp_error);
4251
4252		NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
4253		    "nv_intr_pkt_pio: device fault"));
4254
4255		return;
4256	}
4257
4258	if ((status & SATA_STATUS_ERR) != 0) {
4259		/*
4260		 * On command error, figure out whether we are processing a
4261		 * request sense.  If so, clean up and bail.  Otherwise,
4262		 * do a REQUEST SENSE.
4263		 */
4264
4265		if ((nv_slotp->nvslot_flags & NVSLOT_RQSENSE) == 0) {
4266			nv_slotp->nvslot_flags |= NVSLOT_RQSENSE;
4267			if (nv_start_rqsense_pio(nvp, nv_slotp) ==
4268			    NV_FAILURE) {
4269				nv_copy_registers(nvp, &spkt->satapkt_device,
4270				    spkt);
4271				nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4272				spkt->satapkt_reason = SATA_PKT_DEV_ERROR;
4273			}
4274
4275			sata_cmdp->satacmd_status_reg = nv_get8(ctlhdl,
4276			    nvp->nvp_altstatus);
4277			sata_cmdp->satacmd_error_reg = nv_get8(cmdhdl,
4278			    nvp->nvp_error);
4279		} else {
4280			nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4281			spkt->satapkt_reason = SATA_PKT_DEV_ERROR;
4282
4283			nv_copy_registers(nvp, &spkt->satapkt_device, spkt);
4284		}
4285
4286		NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
4287		    "nv_intr_pkt_pio: error (status 0x%x)", status));
4288
4289		return;
4290	}
4291
4292	if ((nv_slotp->nvslot_flags & NVSLOT_RQSENSE) != 0) {
4293		/*
4294		 * REQUEST SENSE command processing
4295		 */
4296
4297		if ((status & (SATA_STATUS_DRQ)) != 0) {
4298			/* ATAPI state - HP4: Transfer_Data */
4299
4300			/* read the byte count from the controller */
4301			ctlr_count =
4302			    (uint16_t)nv_get8(cmdhdl, nvp->nvp_hcyl) << 8;
4303			ctlr_count |= nv_get8(cmdhdl, nvp->nvp_lcyl);
4304
4305			NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
4306			    "nv_intr_pkt_pio: ctlr byte count - %d",
4307			    ctlr_count));
4308
4309			if (ctlr_count == 0) {
4310				/* no data to transfer - some devices do this */
4311
4312				spkt->satapkt_reason = SATA_PKT_DEV_ERROR;
4313				nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4314
4315				NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
4316				    "nv_intr_pkt_pio: done (no data)"));
4317
4318				return;
4319			}
4320
4321			count = min(ctlr_count, SATA_ATAPI_RQSENSE_LEN);
4322
4323			/* transfer the data */
4324			ddi_rep_get16(cmdhdl,
4325			    (ushort_t *)nv_slotp->nvslot_rqsense_buff,
4326			    (ushort_t *)nvp->nvp_data, (count >> 1),
4327			    DDI_DEV_NO_AUTOINCR);
4328
4329			/* consume residual bytes */
4330			ctlr_count -= count;
4331
4332			if (ctlr_count > 0) {
4333				for (; ctlr_count > 0; ctlr_count -= 2)
4334					(void) ddi_get16(cmdhdl,
4335					    (ushort_t *)nvp->nvp_data);
4336			}
4337
4338			NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
4339			    "nv_intr_pkt_pio: transition to HP2"));
4340		} else {
4341			/* still in ATAPI state - HP2 */
4342
4343			/*
4344			 * In order to avoid clobbering the rqsense data
4345			 * set by the SATA framework, the sense data read
4346			 * from the device is put in a separate buffer and
4347			 * copied into the packet after the request sense
4348			 * command successfully completes.
4349			 */
4350			bcopy(nv_slotp->nvslot_rqsense_buff,
4351			    spkt->satapkt_cmd.satacmd_rqsense,
4352			    SATA_ATAPI_RQSENSE_LEN);
4353
4354			nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4355			spkt->satapkt_reason = SATA_PKT_DEV_ERROR;
4356
4357			NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
4358			    "nv_intr_pkt_pio: request sense done"));
4359		}
4360
4361		return;
4362	}
4363
4364	/*
4365	 * Normal command processing
4366	 */
4367
4368	if ((status & (SATA_STATUS_DRQ)) != 0) {
4369		/* ATAPI protocol state - HP4: Transfer_Data */
4370
4371		/* read the byte count from the controller */
4372		ctlr_count = (uint16_t)nv_get8(cmdhdl, nvp->nvp_hcyl) << 8;
4373		ctlr_count |= nv_get8(cmdhdl, nvp->nvp_lcyl);
4374
4375		if (ctlr_count == 0) {
4376			/* no data to transfer - some devices do this */
4377
4378			spkt->satapkt_reason = SATA_PKT_COMPLETED;
4379			nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4380
4381			NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
4382			    "nv_intr_pkt_pio: done (no data)"));
4383
4384			return;
4385		}
4386
4387		count = min(ctlr_count, nv_slotp->nvslot_byte_count);
4388
4389		NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
4390		    "nv_intr_pkt_pio: drive_bytes 0x%x", ctlr_count));
4391
4392		NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
4393		    "nv_intr_pkt_pio: byte_count 0x%x",
4394		    nv_slotp->nvslot_byte_count));
4395
4396		/* transfer the data */
4397
4398		if (direction == SATA_DIR_READ) {
4399			ddi_rep_get16(cmdhdl,
4400			    (ushort_t *)nv_slotp->nvslot_v_addr,
4401			    (ushort_t *)nvp->nvp_data, (count >> 1),
4402			    DDI_DEV_NO_AUTOINCR);
4403
4404			ctlr_count -= count;
4405
4406			if (ctlr_count > 0) {
4407				/* consume remainding bytes */
4408
4409				for (; ctlr_count > 0;
4410				    ctlr_count -= 2)
4411					(void) ddi_get16(cmdhdl,
4412					    (ushort_t *)nvp->nvp_data);
4413
4414				NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
4415				    "nv_intr_pkt_pio: bytes remained"));
4416			}
4417		} else {
4418			ddi_rep_put16(cmdhdl,
4419			    (ushort_t *)nv_slotp->nvslot_v_addr,
4420			    (ushort_t *)nvp->nvp_data, (count >> 1),
4421			    DDI_DEV_NO_AUTOINCR);
4422		}
4423
4424		nv_slotp->nvslot_v_addr += count;
4425		nv_slotp->nvslot_byte_count -= count;
4426
4427		NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
4428		    "nv_intr_pkt_pio: transition to HP2"));
4429	} else {
4430		/* still in ATAPI state - HP2 */
4431
4432		spkt->satapkt_reason = SATA_PKT_COMPLETED;
4433		nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4434
4435		NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
4436		    "nv_intr_pkt_pio: done"));
4437	}
4438}
4439
4440
4441/*
4442 * ATA command, DMA data in/out
4443 */
4444static void
4445nv_intr_dma(nv_port_t *nvp, struct nv_slot *nv_slotp)
4446{
4447	uchar_t status;
4448	sata_pkt_t *spkt = nv_slotp->nvslot_spkt;
4449	sata_cmd_t *sata_cmdp = &spkt->satapkt_cmd;
4450	ddi_acc_handle_t ctlhdl = nvp->nvp_ctl_hdl;
4451	ddi_acc_handle_t cmdhdl = nvp->nvp_cmd_hdl;
4452	ddi_acc_handle_t bmhdl = nvp->nvp_bm_hdl;
4453	uchar_t	bmicx;
4454	uchar_t bm_status;
4455
4456	nv_slotp->nvslot_flags = NVSLOT_COMPLETE;
4457
4458	/*
4459	 * stop DMA engine.
4460	 */
4461	bmicx = nv_get8(bmhdl, nvp->nvp_bmicx);
4462	nv_put8(bmhdl, nvp->nvp_bmicx,  bmicx & ~BMICX_SSBM);
4463
4464	/*
4465	 * get the status and clear the IRQ, and check for DMA error
4466	 */
4467	status = nv_get8(cmdhdl, nvp->nvp_status);
4468
4469	/*
4470	 * check for drive errors
4471	 */
4472	if (status & (SATA_STATUS_DF | SATA_STATUS_ERR)) {
4473		nv_copy_registers(nvp, &spkt->satapkt_device, spkt);
4474		spkt->satapkt_reason = SATA_PKT_DEV_ERROR;
4475		(void) nv_bm_status_clear(nvp);
4476
4477		return;
4478	}
4479
4480	bm_status = nv_bm_status_clear(nvp);
4481
4482	/*
4483	 * check for bus master errors
4484	 */
4485	if (bm_status & BMISX_IDERR) {
4486		spkt->satapkt_reason = SATA_PKT_RESET;
4487		sata_cmdp->satacmd_status_reg = nv_get8(ctlhdl,
4488		    nvp->nvp_altstatus);
4489		sata_cmdp->satacmd_error_reg = nv_get8(cmdhdl, nvp->nvp_error);
4490		nv_reset(nvp);
4491
4492		return;
4493	}
4494
4495	spkt->satapkt_reason = SATA_PKT_COMPLETED;
4496}
4497
4498
4499/*
4500 * Wait for a register of a controller to achieve a specific state.
4501 * To return normally, all the bits in the first sub-mask must be ON,
4502 * all the bits in the second sub-mask must be OFF.
4503 * If timeout_usec microseconds pass without the controller achieving
4504 * the desired bit configuration, return TRUE, else FALSE.
4505 *
4506 * hybrid waiting algorithm: if not in interrupt context, busy looping will
4507 * occur for the first 250 us, then switch over to a sleeping wait.
4508 *
4509 */
4510int
4511nv_wait(nv_port_t *nvp, uchar_t onbits, uchar_t offbits, uint_t timeout_usec,
4512    int type_wait)
4513{
4514	ddi_acc_handle_t ctlhdl = nvp->nvp_ctl_hdl;
4515	hrtime_t end, cur, start_sleep, start;
4516	int first_time = B_TRUE;
4517	ushort_t val;
4518
4519	for (;;) {
4520		val = nv_get8(ctlhdl, nvp->nvp_altstatus);
4521
4522		if ((val & onbits) == onbits && (val & offbits) == 0) {
4523
4524			return (B_TRUE);
4525		}
4526
4527		cur = gethrtime();
4528
4529		/*
4530		 * store the start time and calculate the end
4531		 * time.  also calculate "start_sleep" which is
4532		 * the point after which the driver will stop busy
4533		 * waiting and change to sleep waiting.
4534		 */
4535		if (first_time) {
4536			first_time = B_FALSE;
4537			/*
4538			 * start and end are in nanoseconds
4539			 */
4540			start = cur;
4541			end = start + timeout_usec * 1000;
4542			/*
4543			 * add 1 ms to start
4544			 */
4545			start_sleep =  start + 250000;
4546
4547			if (servicing_interrupt()) {
4548				type_wait = NV_NOSLEEP;
4549			}
4550		}
4551
4552		if (cur > end) {
4553
4554			break;
4555		}
4556
4557		if ((type_wait != NV_NOSLEEP) && (cur > start_sleep)) {
4558#if ! defined(__lock_lint)
4559			delay(1);
4560#endif
4561		} else {
4562			drv_usecwait(nv_usec_delay);
4563		}
4564	}
4565
4566	return (B_FALSE);
4567}
4568
4569
4570/*
4571 * This is a slightly more complicated version that checks
4572 * for error conditions and bails-out rather than looping
4573 * until the timeout is exceeded.
4574 *
4575 * hybrid waiting algorithm: if not in interrupt context, busy looping will
4576 * occur for the first 250 us, then switch over to a sleeping wait.
4577 */
4578int
4579nv_wait3(
4580	nv_port_t	*nvp,
4581	uchar_t		onbits1,
4582	uchar_t		offbits1,
4583	uchar_t		failure_onbits2,
4584	uchar_t		failure_offbits2,
4585	uchar_t		failure_onbits3,
4586	uchar_t		failure_offbits3,
4587	uint_t		timeout_usec,
4588	int		type_wait)
4589{
4590	ddi_acc_handle_t ctlhdl = nvp->nvp_ctl_hdl;
4591	hrtime_t end, cur, start_sleep, start;
4592	int first_time = B_TRUE;
4593	ushort_t val;
4594
4595	for (;;) {
4596		val = nv_get8(ctlhdl, nvp->nvp_altstatus);
4597
4598		/*
4599		 * check for expected condition
4600		 */
4601		if ((val & onbits1) == onbits1 && (val & offbits1) == 0) {
4602
4603			return (B_TRUE);
4604		}
4605
4606		/*
4607		 * check for error conditions
4608		 */
4609		if ((val & failure_onbits2) == failure_onbits2 &&
4610		    (val & failure_offbits2) == 0) {
4611
4612			return (B_FALSE);
4613		}
4614
4615		if ((val & failure_onbits3) == failure_onbits3 &&
4616		    (val & failure_offbits3) == 0) {
4617
4618			return (B_FALSE);
4619		}
4620
4621		/*
4622		 * store the start time and calculate the end
4623		 * time.  also calculate "start_sleep" which is
4624		 * the point after which the driver will stop busy
4625		 * waiting and change to sleep waiting.
4626		 */
4627		if (first_time) {
4628			first_time = B_FALSE;
4629			/*
4630			 * start and end are in nanoseconds
4631			 */
4632			cur = start = gethrtime();
4633			end = start + timeout_usec * 1000;
4634			/*
4635			 * add 1 ms to start
4636			 */
4637			start_sleep =  start + 250000;
4638
4639			if (servicing_interrupt()) {
4640				type_wait = NV_NOSLEEP;
4641			}
4642		} else {
4643			cur = gethrtime();
4644		}
4645
4646		if (cur > end) {
4647
4648			break;
4649		}
4650
4651		if ((type_wait != NV_NOSLEEP) && (cur > start_sleep)) {
4652#if ! defined(__lock_lint)
4653			delay(1);
4654#endif
4655		} else {
4656			drv_usecwait(nv_usec_delay);
4657		}
4658	}
4659
4660	return (B_FALSE);
4661}
4662
4663
4664/*
4665 * nv_check_link() checks if a specified link is active device present
4666 * and communicating.
4667 */
4668static boolean_t
4669nv_check_link(uint32_t sstatus)
4670{
4671	uint8_t det;
4672
4673	det = (sstatus & SSTATUS_DET) >> SSTATUS_DET_SHIFT;
4674
4675	return (det == SSTATUS_DET_DEVPRE_PHYCOM);
4676}
4677
4678
4679/*
4680 * nv_port_state_change() reports the state of the port to the
4681 * sata module by calling sata_hba_event_notify().  This
4682 * function is called any time the state of the port is changed
4683 */
4684static void
4685nv_port_state_change(nv_port_t *nvp, int event, uint8_t addr_type, int state)
4686{
4687	sata_device_t sd;
4688
4689	bzero((void *)&sd, sizeof (sata_device_t));
4690	sd.satadev_rev = SATA_DEVICE_REV;
4691	nv_copy_registers(nvp, &sd, NULL);
4692
4693	/*
4694	 * When NCQ is implemented sactive and snotific field need to be
4695	 * updated.
4696	 */
4697	sd.satadev_addr.cport = nvp->nvp_port_num;
4698	sd.satadev_addr.qual = addr_type;
4699	sd.satadev_state = state;
4700
4701	sata_hba_event_notify(nvp->nvp_ctlp->nvc_dip, &sd, event);
4702}
4703
4704
4705/*
4706 * timeout processing:
4707 *
4708 * Check if any packets have crossed a timeout threshold.  If so, then
4709 * abort the packet.  This function is not NCQ aware.
4710 *
4711 * If reset was invoked in any other place than nv_sata_probe(), then
4712 * monitor for reset completion here.
4713 *
4714 */
4715static void
4716nv_timeout(void *arg)
4717{
4718	nv_port_t *nvp = arg;
4719	nv_slot_t *nv_slotp;
4720	int restart_timeout = B_FALSE;
4721
4722	mutex_enter(&nvp->nvp_mutex);
4723
4724	/*
4725	 * If the probe entry point is driving the reset and signature
4726	 * acquisition, just return.
4727	 */
4728	if (nvp->nvp_state & NV_PORT_RESET_PROBE) {
4729		goto finished;
4730	}
4731
4732	/*
4733	 * If the port is not in the init state, it likely
4734	 * means the link was lost while a timeout was active.
4735	 */
4736	if ((nvp->nvp_state & NV_PORT_INIT) == 0) {
4737		NVLOG((NVDBG_TIMEOUT, nvp->nvp_ctlp, nvp,
4738		    "nv_timeout: port uninitialized"));
4739
4740		goto finished;
4741	}
4742
4743	if (nvp->nvp_state & NV_PORT_RESET) {
4744		ddi_acc_handle_t bar5_hdl = nvp->nvp_ctlp->nvc_bar_hdl[5];
4745		uint32_t sstatus;
4746
4747		NVLOG((NVDBG_TIMEOUT, nvp->nvp_ctlp, nvp,
4748		    "nv_timeout(): port waiting for signature"));
4749
4750		sstatus = nv_get32(bar5_hdl, nvp->nvp_sstatus);
4751
4752		/*
4753		 * check for link presence.  If the link remains
4754		 * missing for more than 2 seconds, send a remove
4755		 * event and abort signature acquisition.
4756		 */
4757		if (nv_check_link(sstatus) == B_FALSE) {
4758			clock_t e_link_lost = ddi_get_lbolt();
4759
4760			if (nvp->nvp_link_lost_time == 0) {
4761				nvp->nvp_link_lost_time = e_link_lost;
4762			}
4763			if (TICK_TO_SEC(e_link_lost -
4764			    nvp->nvp_link_lost_time) < NV_LINK_LOST_OK) {
4765				NVLOG((NVDBG_TIMEOUT, nvp->nvp_ctlp, nvp,
4766				    "probe: intermittent link lost while"
4767				    " resetting"));
4768				restart_timeout = B_TRUE;
4769			} else {
4770				NVLOG((NVDBG_TIMEOUT, nvp->nvp_ctlp, nvp,
4771				    "link lost during signature acquisition."
4772				    "  Giving up"));
4773				nv_port_state_change(nvp,
4774				    SATA_EVNT_DEVICE_DETACHED|
4775				    SATA_EVNT_LINK_LOST,
4776				    SATA_ADDR_CPORT, 0);
4777				nvp->nvp_state |= NV_PORT_HOTREMOVED;
4778				nvp->nvp_state &= ~NV_PORT_RESET;
4779			}
4780
4781			goto finished;
4782		} else {
4783
4784			nvp->nvp_link_lost_time = 0;
4785		}
4786
4787		nv_read_signature(nvp);
4788
4789		if (nvp->nvp_signature != 0) {
4790			if ((nvp->nvp_type == SATA_DTYPE_ATADISK) ||
4791			    (nvp->nvp_type == SATA_DTYPE_ATAPICD)) {
4792				nvp->nvp_state |= NV_PORT_RESTORE;
4793				nv_port_state_change(nvp,
4794				    SATA_EVNT_DEVICE_RESET,
4795				    SATA_ADDR_DCPORT,
4796				    SATA_DSTATE_RESET|SATA_DSTATE_PWR_ACTIVE);
4797			}
4798
4799			goto finished;
4800		}
4801
4802		/*
4803		 * Reset if more than 5 seconds has passed without
4804		 * acquiring a signature.
4805		 */
4806		if (TICK_TO_SEC(ddi_get_lbolt() - nvp->nvp_reset_time) > 5) {
4807			nv_reset(nvp);
4808		}
4809
4810		restart_timeout = B_TRUE;
4811		goto finished;
4812	}
4813
4814
4815	/*
4816	 * not yet NCQ aware
4817	 */
4818	nv_slotp = &(nvp->nvp_slot[0]);
4819
4820	/*
4821	 * this happens early on before nv_slotp is set
4822	 * up OR when a device was unexpectedly removed and
4823	 * there was an active packet.
4824	 */
4825	if (nv_slotp == NULL) {
4826		NVLOG((NVDBG_TIMEOUT, nvp->nvp_ctlp, nvp,
4827		    "nv_timeout: nv_slotp == NULL"));
4828
4829		goto finished;
4830	}
4831
4832	/*
4833	 * perform timeout checking and processing only if there is an
4834	 * active packet on the port
4835	 */
4836	if (nv_slotp->nvslot_spkt != NULL)  {
4837		sata_pkt_t *spkt = nv_slotp->nvslot_spkt;
4838		sata_cmd_t *satacmd = &spkt->satapkt_cmd;
4839		uint8_t cmd = satacmd->satacmd_cmd_reg;
4840		uint64_t lba;
4841
4842#if ! defined(__lock_lint) && defined(DEBUG)
4843
4844		lba = (uint64_t)satacmd->satacmd_lba_low_lsb |
4845		    ((uint64_t)satacmd->satacmd_lba_mid_lsb << 8) |
4846		    ((uint64_t)satacmd->satacmd_lba_high_lsb << 16) |
4847		    ((uint64_t)satacmd->satacmd_lba_low_msb << 24) |
4848		    ((uint64_t)satacmd->satacmd_lba_mid_msb << 32) |
4849		    ((uint64_t)satacmd->satacmd_lba_high_msb << 40);
4850#endif
4851
4852		/*
4853		 * timeout not needed if there is a polling thread
4854		 */
4855		if (spkt->satapkt_op_mode & SATA_OPMODE_POLLING) {
4856
4857			goto finished;
4858		}
4859
4860		if (TICK_TO_SEC(ddi_get_lbolt() - nv_slotp->nvslot_stime) >
4861		    spkt->satapkt_time) {
4862			NVLOG((NVDBG_TIMEOUT, nvp->nvp_ctlp, nvp,
4863			    "abort timeout: "
4864			    "nvslot_stime: %ld max ticks till timeout: "
4865			    "%ld cur_time: %ld cmd=%x lba=%d",
4866			    nv_slotp->nvslot_stime, drv_usectohz(MICROSEC *
4867			    spkt->satapkt_time), ddi_get_lbolt(), cmd, lba));
4868
4869			(void) nv_abort_active(nvp, spkt, SATA_PKT_TIMEOUT);
4870
4871		} else {
4872			NVLOG((NVDBG_TIMEOUT, nvp->nvp_ctlp, nvp, "nv_timeout:"
4873			    " still in use so restarting timeout"));
4874		}
4875		restart_timeout = B_TRUE;
4876
4877	} else {
4878		/*
4879		 * there was no active packet, so do not re-enable timeout
4880		 */
4881		NVLOG((NVDBG_TIMEOUT, nvp->nvp_ctlp, nvp,
4882		    "nv_timeout: no active packet so not re-arming timeout"));
4883	}
4884
4885	finished:
4886
4887	if (restart_timeout == B_TRUE) {
4888		nvp->nvp_timeout_id = timeout(nv_timeout, (void *)nvp,
4889		    drv_usectohz(NV_ONE_SEC));
4890	} else {
4891		nvp->nvp_timeout_id = 0;
4892	}
4893	mutex_exit(&nvp->nvp_mutex);
4894}
4895
4896
4897/*
4898 * enable or disable the 3 interrupt types the driver is
4899 * interested in: completion, add and remove.
4900 */
4901static void
4902mcp04_set_intr(nv_port_t *nvp, int flag)
4903{
4904	nv_ctl_t *nvc = nvp->nvp_ctlp;
4905	ddi_acc_handle_t bar5_hdl = nvc->nvc_bar_hdl[5];
4906	uchar_t *bar5  = nvc->nvc_bar_addr[5];
4907	uint8_t intr_bits[] = { MCP04_INT_PDEV_HOT|MCP04_INT_PDEV_INT,
4908	    MCP04_INT_SDEV_HOT|MCP04_INT_SDEV_INT };
4909	uint8_t clear_all_bits[] = { MCP04_INT_PDEV_ALL, MCP04_INT_SDEV_ALL };
4910	uint8_t int_en, port = nvp->nvp_port_num, intr_status;
4911
4912	ASSERT(mutex_owned(&nvp->nvp_mutex));
4913
4914	/*
4915	 * controller level lock also required since access to an 8-bit
4916	 * interrupt register is shared between both channels.
4917	 */
4918	mutex_enter(&nvc->nvc_mutex);
4919
4920	if (flag & NV_INTR_CLEAR_ALL) {
4921		NVLOG((NVDBG_INTR, nvc, nvp,
4922		    "mcp04_set_intr: NV_INTR_CLEAR_ALL"));
4923
4924		intr_status = nv_get8(nvc->nvc_bar_hdl[5],
4925		    (uint8_t *)(nvc->nvc_mcp04_int_status));
4926
4927		if (intr_status & clear_all_bits[port]) {
4928
4929			nv_put8(nvc->nvc_bar_hdl[5],
4930			    (uint8_t *)(nvc->nvc_mcp04_int_status),
4931			    clear_all_bits[port]);
4932
4933			NVLOG((NVDBG_INTR, nvc, nvp,
4934			    "interrupt bits cleared %x",
4935			    intr_status & clear_all_bits[port]));
4936		}
4937	}
4938
4939	if (flag & NV_INTR_DISABLE) {
4940		NVLOG((NVDBG_INTR, nvc, nvp,
4941		    "mcp04_set_intr: NV_INTR_DISABLE"));
4942		int_en = nv_get8(bar5_hdl,
4943		    (uint8_t *)(bar5 + MCP04_SATA_INT_EN));
4944		int_en &= ~intr_bits[port];
4945		nv_put8(bar5_hdl, (uint8_t *)(bar5 + MCP04_SATA_INT_EN),
4946		    int_en);
4947	}
4948
4949	if (flag & NV_INTR_ENABLE) {
4950		NVLOG((NVDBG_INTR, nvc, nvp, "mcp04_set_intr: NV_INTR_ENABLE"));
4951		int_en = nv_get8(bar5_hdl,
4952		    (uint8_t *)(bar5 + MCP04_SATA_INT_EN));
4953		int_en |= intr_bits[port];
4954		nv_put8(bar5_hdl, (uint8_t *)(bar5 + MCP04_SATA_INT_EN),
4955		    int_en);
4956	}
4957
4958	mutex_exit(&nvc->nvc_mutex);
4959}
4960
4961
4962/*
4963 * enable or disable the 3 interrupts the driver is interested in:
4964 * completion interrupt, hot add, and hot remove interrupt.
4965 */
4966static void
4967mcp55_set_intr(nv_port_t *nvp, int flag)
4968{
4969	nv_ctl_t *nvc = nvp->nvp_ctlp;
4970	ddi_acc_handle_t bar5_hdl = nvc->nvc_bar_hdl[5];
4971	uint16_t intr_bits =
4972	    MCP55_INT_ADD|MCP55_INT_REM|MCP55_INT_COMPLETE;
4973	uint16_t int_en;
4974
4975	ASSERT(mutex_owned(&nvp->nvp_mutex));
4976
4977	NVLOG((NVDBG_HOT, nvc, nvp, "mcp055_set_intr: enter flag: %d", flag));
4978
4979	if (flag & NV_INTR_CLEAR_ALL) {
4980		NVLOG((NVDBG_INTR, nvc, nvp,
4981		    "mcp55_set_intr: NV_INTR_CLEAR_ALL"));
4982		nv_put16(bar5_hdl, nvp->nvp_mcp55_int_status, MCP55_INT_CLEAR);
4983	}
4984
4985	if (flag & NV_INTR_ENABLE) {
4986		NVLOG((NVDBG_INTR, nvc, nvp, "mcp55_set_intr: NV_INTR_ENABLE"));
4987		int_en = nv_get16(bar5_hdl, nvp->nvp_mcp55_int_ctl);
4988		int_en |= intr_bits;
4989		nv_put16(bar5_hdl, nvp->nvp_mcp55_int_ctl, int_en);
4990	}
4991
4992	if (flag & NV_INTR_DISABLE) {
4993		NVLOG((NVDBG_INTR, nvc, nvp,
4994		    "mcp55_set_intr: NV_INTR_DISABLE"));
4995		int_en = nv_get16(bar5_hdl, nvp->nvp_mcp55_int_ctl);
4996		int_en &= ~intr_bits;
4997		nv_put16(bar5_hdl, nvp->nvp_mcp55_int_ctl, int_en);
4998	}
4999}
5000
5001
5002/*
5003 * The PM functions for suspend and resume are incomplete and need additional
5004 * work.  It may or may not work in the current state.
5005 */
5006static void
5007nv_resume(nv_port_t *nvp)
5008{
5009	NVLOG((NVDBG_INIT, nvp->nvp_ctlp, nvp, "nv_resume()"));
5010
5011	mutex_enter(&nvp->nvp_mutex);
5012
5013	if (nvp->nvp_state & NV_PORT_INACTIVE) {
5014		mutex_exit(&nvp->nvp_mutex);
5015
5016		return;
5017	}
5018
5019	(*(nvp->nvp_ctlp->nvc_set_intr))(nvp, NV_INTR_CLEAR_ALL|NV_INTR_ENABLE);
5020
5021	/*
5022	 * power may have been removed to the port and the
5023	 * drive, and/or a drive may have been added or removed.
5024	 * Force a reset which will cause a probe and re-establish
5025	 * any state needed on the drive.
5026	 * nv_reset(nvp);
5027	 */
5028
5029	nv_reset(nvp);
5030
5031	mutex_exit(&nvp->nvp_mutex);
5032}
5033
5034/*
5035 * The PM functions for suspend and resume are incomplete and need additional
5036 * work.  It may or may not work in the current state.
5037 */
5038static void
5039nv_suspend(nv_port_t *nvp)
5040{
5041	NVLOG((NVDBG_INIT, nvp->nvp_ctlp, nvp, "nv_suspend()"));
5042
5043	mutex_enter(&nvp->nvp_mutex);
5044
5045	if (nvp->nvp_state & NV_PORT_INACTIVE) {
5046		mutex_exit(&nvp->nvp_mutex);
5047
5048		return;
5049	}
5050
5051	(*(nvp->nvp_ctlp->nvc_set_intr))(nvp, NV_INTR_DISABLE);
5052
5053	/*
5054	 * power may have been removed to the port and the
5055	 * drive, and/or a drive may have been added or removed.
5056	 * Force a reset which will cause a probe and re-establish
5057	 * any state needed on the drive.
5058	 * nv_reset(nvp);
5059	 */
5060
5061	mutex_exit(&nvp->nvp_mutex);
5062}
5063
5064
5065static void
5066nv_copy_registers(nv_port_t *nvp, sata_device_t *sd, sata_pkt_t *spkt)
5067{
5068	ddi_acc_handle_t bar5_hdl = nvp->nvp_ctlp->nvc_bar_hdl[5];
5069	sata_cmd_t *scmd = &spkt->satapkt_cmd;
5070	ddi_acc_handle_t ctlhdl = nvp->nvp_ctl_hdl;
5071	ddi_acc_handle_t cmdhdl = nvp->nvp_cmd_hdl;
5072	uchar_t status;
5073	struct sata_cmd_flags flags;
5074
5075	NVLOG((NVDBG_INIT, nvp->nvp_ctlp, nvp, "nv_copy_registers()"));
5076
5077	sd->satadev_scr.sstatus = nv_get32(bar5_hdl, nvp->nvp_sstatus);
5078	sd->satadev_scr.serror = nv_get32(bar5_hdl, nvp->nvp_serror);
5079	sd->satadev_scr.scontrol = nv_get32(bar5_hdl, nvp->nvp_sctrl);
5080
5081	if (spkt == NULL) {
5082
5083		return;
5084	}
5085
5086	/*
5087	 * in the error case, implicitly set the return of regs needed
5088	 * for error handling.
5089	 */
5090	status = scmd->satacmd_status_reg = nv_get8(ctlhdl,
5091	    nvp->nvp_altstatus);
5092
5093	flags = scmd->satacmd_flags;
5094
5095	if (status & SATA_STATUS_ERR) {
5096		flags.sata_copy_out_lba_low_msb = B_TRUE;
5097		flags.sata_copy_out_lba_mid_msb = B_TRUE;
5098		flags.sata_copy_out_lba_high_msb = B_TRUE;
5099		flags.sata_copy_out_lba_low_lsb = B_TRUE;
5100		flags.sata_copy_out_lba_mid_lsb = B_TRUE;
5101		flags.sata_copy_out_lba_high_lsb = B_TRUE;
5102		flags.sata_copy_out_error_reg = B_TRUE;
5103		flags.sata_copy_out_sec_count_msb = B_TRUE;
5104		flags.sata_copy_out_sec_count_lsb = B_TRUE;
5105		scmd->satacmd_status_reg = status;
5106	}
5107
5108	if (scmd->satacmd_addr_type & ATA_ADDR_LBA48) {
5109
5110		/*
5111		 * set HOB so that high byte will be read
5112		 */
5113		nv_put8(ctlhdl, nvp->nvp_devctl, ATDC_HOB|ATDC_D3);
5114
5115		/*
5116		 * get the requested high bytes
5117		 */
5118		if (flags.sata_copy_out_sec_count_msb) {
5119			scmd->satacmd_sec_count_msb =
5120			    nv_get8(cmdhdl, nvp->nvp_count);
5121		}
5122
5123		if (flags.sata_copy_out_lba_low_msb) {
5124			scmd->satacmd_lba_low_msb =
5125			    nv_get8(cmdhdl, nvp->nvp_sect);
5126		}
5127
5128		if (flags.sata_copy_out_lba_mid_msb) {
5129			scmd->satacmd_lba_mid_msb =
5130			    nv_get8(cmdhdl, nvp->nvp_lcyl);
5131		}
5132
5133		if (flags.sata_copy_out_lba_high_msb) {
5134			scmd->satacmd_lba_high_msb =
5135			    nv_get8(cmdhdl, nvp->nvp_hcyl);
5136		}
5137	}
5138
5139	/*
5140	 * disable HOB so that low byte is read
5141	 */
5142	nv_put8(ctlhdl, nvp->nvp_devctl, ATDC_D3);
5143
5144	/*
5145	 * get the requested low bytes
5146	 */
5147	if (flags.sata_copy_out_sec_count_lsb) {
5148		scmd->satacmd_sec_count_lsb = nv_get8(cmdhdl, nvp->nvp_count);
5149	}
5150
5151	if (flags.sata_copy_out_lba_low_lsb) {
5152		scmd->satacmd_lba_low_lsb = nv_get8(cmdhdl, nvp->nvp_sect);
5153	}
5154
5155	if (flags.sata_copy_out_lba_mid_lsb) {
5156		scmd->satacmd_lba_mid_lsb = nv_get8(cmdhdl, nvp->nvp_lcyl);
5157	}
5158
5159	if (flags.sata_copy_out_lba_high_lsb) {
5160		scmd->satacmd_lba_high_lsb = nv_get8(cmdhdl, nvp->nvp_hcyl);
5161	}
5162
5163	/*
5164	 * get the device register if requested
5165	 */
5166	if (flags.sata_copy_out_device_reg) {
5167		scmd->satacmd_device_reg =  nv_get8(cmdhdl, nvp->nvp_drvhd);
5168	}
5169
5170	/*
5171	 * get the error register if requested
5172	 */
5173	if (flags.sata_copy_out_error_reg) {
5174		scmd->satacmd_error_reg = nv_get8(cmdhdl, nvp->nvp_error);
5175	}
5176}
5177
5178
5179/*
5180 * Hot plug and remove interrupts can occur when the device is reset.  Just
5181 * masking the interrupt doesn't always work well because if a
5182 * different interrupt arrives on the other port, the driver can still
5183 * end up checking the state of the other port and discover the hot
5184 * interrupt flag is set even though it was masked.  Checking for recent
5185 * reset activity and then ignoring turns out to be the easiest way.
5186 */
5187static void
5188nv_report_add_remove(nv_port_t *nvp, int flags)
5189{
5190	ddi_acc_handle_t bar5_hdl = nvp->nvp_ctlp->nvc_bar_hdl[5];
5191	clock_t time_diff = ddi_get_lbolt() - nvp->nvp_reset_time;
5192	uint32_t sstatus;
5193	int i;
5194
5195	/*
5196	 * If reset within last 1 second ignore.  This should be
5197	 * reworked and improved instead of having this somewhat
5198	 * heavy handed clamping job.
5199	 */
5200	if (time_diff < drv_usectohz(NV_ONE_SEC)) {
5201		NVLOG((NVDBG_HOT, nvp->nvp_ctlp, nvp, "nv_report_add_remove()"
5202		    "ignoring plug interrupt was %dms ago",
5203		    TICK_TO_MSEC(time_diff)));
5204
5205		return;
5206	}
5207
5208	/*
5209	 * wait up to 1ms for sstatus to settle and reflect the true
5210	 * status of the port.  Failure to do so can create confusion
5211	 * in probe, where the incorrect sstatus value can still
5212	 * persist.
5213	 */
5214	for (i = 0; i < 1000; i++) {
5215		sstatus = nv_get32(bar5_hdl, nvp->nvp_sstatus);
5216
5217		if ((flags == NV_PORT_HOTREMOVED) &&
5218		    ((sstatus & SSTATUS_DET_DEVPRE_PHYCOM) !=
5219		    SSTATUS_DET_DEVPRE_PHYCOM)) {
5220			break;
5221		}
5222
5223		if ((flags != NV_PORT_HOTREMOVED) &&
5224		    ((sstatus & SSTATUS_DET_DEVPRE_PHYCOM) ==
5225		    SSTATUS_DET_DEVPRE_PHYCOM)) {
5226			break;
5227		}
5228		drv_usecwait(1);
5229	}
5230
5231	NVLOG((NVDBG_HOT, nvp->nvp_ctlp, nvp,
5232	    "sstatus took %i us for DEVPRE_PHYCOM to settle", i));
5233
5234	if (flags == NV_PORT_HOTREMOVED) {
5235		NVLOG((NVDBG_HOT, nvp->nvp_ctlp, nvp,
5236		    "nv_report_add_remove() hot removed"));
5237		nv_port_state_change(nvp,
5238		    SATA_EVNT_DEVICE_DETACHED,
5239		    SATA_ADDR_CPORT, 0);
5240
5241		nvp->nvp_state |= NV_PORT_HOTREMOVED;
5242	} else {
5243		NVLOG((NVDBG_HOT, nvp->nvp_ctlp, nvp,
5244		    "nv_report_add_remove() hot plugged"));
5245		nv_port_state_change(nvp, SATA_EVNT_DEVICE_ATTACHED,
5246		    SATA_ADDR_CPORT, 0);
5247	}
5248}
5249
5250
5251/*
5252 * Get request sense data and stuff it the command's sense buffer.
5253 * Start a request sense command in order to get sense data to insert
5254 * in the sata packet's rqsense buffer.  The command completion
5255 * processing is in nv_intr_pkt_pio.
5256 *
5257 * The sata framework provides a function to allocate and set-up a
5258 * request sense packet command. The reasons it is not being used here is:
5259 * a) it cannot be called in an interrupt context and this function is
5260 *    called in an interrupt context.
5261 * b) it allocates DMA resources that are not used here because this is
5262 *    implemented using PIO.
5263 *
5264 * If, in the future, this is changed to use DMA, the sata framework should
5265 * be used to allocate and set-up the error retrieval (request sense)
5266 * command.
5267 */
5268static int
5269nv_start_rqsense_pio(nv_port_t *nvp, nv_slot_t *nv_slotp)
5270{
5271	sata_pkt_t *spkt = nv_slotp->nvslot_spkt;
5272	sata_cmd_t *satacmd = &spkt->satapkt_cmd;
5273	ddi_acc_handle_t cmdhdl = nvp->nvp_cmd_hdl;
5274	int cdb_len = spkt->satapkt_cmd.satacmd_acdb_len;
5275
5276	NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
5277	    "nv_start_rqsense_pio: start"));
5278
5279	/* clear the local request sense buffer before starting the command */
5280	bzero(nv_slotp->nvslot_rqsense_buff, SATA_ATAPI_RQSENSE_LEN);
5281
5282	/* Write the request sense PACKET command */
5283
5284	/* select the drive */
5285	nv_put8(cmdhdl, nvp->nvp_drvhd, satacmd->satacmd_device_reg);
5286
5287	/* make certain the drive selected */
5288	if (nv_wait(nvp, SATA_STATUS_DRDY, SATA_STATUS_BSY,
5289	    NV_SEC2USEC(5), 0) == B_FALSE) {
5290		NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
5291		    "nv_start_rqsense_pio: drive select failed"));
5292		return (NV_FAILURE);
5293	}
5294
5295	/* set up the command */
5296	nv_put8(cmdhdl, nvp->nvp_feature, 0);	/* deassert DMA and OVL */
5297	nv_put8(cmdhdl, nvp->nvp_hcyl, SATA_ATAPI_MAX_BYTES_PER_DRQ >> 8);
5298	nv_put8(cmdhdl, nvp->nvp_lcyl, SATA_ATAPI_MAX_BYTES_PER_DRQ & 0xff);
5299	nv_put8(cmdhdl, nvp->nvp_sect, 0);
5300	nv_put8(cmdhdl, nvp->nvp_count, 0);	/* no tag */
5301
5302	/* initiate the command by writing the command register last */
5303	nv_put8(cmdhdl, nvp->nvp_cmd, SATAC_PACKET);
5304
5305	/* Give the host ctlr time to do its thing, according to ATA/ATAPI */
5306	NV_DELAY_NSEC(400);
5307
5308	/*
5309	 * Wait for the device to indicate that it is ready for the command
5310	 * ATAPI protocol state - HP0: Check_Status_A
5311	 */
5312
5313	if (nv_wait3(nvp, SATA_STATUS_DRQ, SATA_STATUS_BSY, /* okay */
5314	    SATA_STATUS_ERR, SATA_STATUS_BSY, /* cmd failed */
5315	    SATA_STATUS_DF, SATA_STATUS_BSY, /* drive failed */
5316	    4000000, 0) == B_FALSE) {
5317		if (nv_get8(cmdhdl, nvp->nvp_status) &
5318		    (SATA_STATUS_ERR | SATA_STATUS_DF)) {
5319			NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
5320			    "nv_start_rqsense_pio: rqsense dev error (HP0)"));
5321		} else {
5322			NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
5323			    "nv_start_rqsense_pio: rqsense timeout (HP0)"));
5324		}
5325
5326		nv_copy_registers(nvp, &spkt->satapkt_device, spkt);
5327		nv_complete_io(nvp, spkt, 0);
5328		nv_reset(nvp);
5329
5330		return (NV_FAILURE);
5331	}
5332
5333	/*
5334	 * Put the ATAPI command in the data register
5335	 * ATAPI protocol state - HP1: Send_Packet
5336	 */
5337
5338	ddi_rep_put16(cmdhdl, (ushort_t *)nv_rqsense_cdb,
5339	    (ushort_t *)nvp->nvp_data,
5340	    (cdb_len >> 1), DDI_DEV_NO_AUTOINCR);
5341
5342	NVLOG((NVDBG_ATAPI, nvp->nvp_ctlp, nvp,
5343	    "nv_start_rqsense_pio: exiting into HP3"));
5344
5345	return (NV_SUCCESS);
5346}
5347