1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26
27/*
28 * SiliconImage 3124/3132 sata controller driver
29 */
30
31/*
32 *
33 *
34 * 			Few Design notes
35 *
36 *
37 * I. General notes
38 *
39 * Even though the driver is named as si3124, it is actually meant to
40 * work with both 3124 and 3132 controllers.
41 *
42 * The current file si3124.c is the main driver code. The si3124reg.h
43 * holds the register definitions from SiI 3124/3132 data sheets. The
44 * si3124var.h holds the driver specific definitions which are not
45 * directly derived from data sheets.
46 *
47 *
48 * II. Data structures
49 *
50 * si_ctl_state_t: This holds the driver private information for each
51 * 	controller instance. Each of the sata ports within a single
52 *	controller are represented by si_port_state_t. The
53 *	sictl_global_acc_handle and sictl_global_address map the
54 *	controller-wide global register space and are derived from pci
55 *	BAR 0. The sictl_port_acc_handle and sictl_port_addr map the
56 *	per-port register space and are derived from pci BAR 1.
57 *
58 * si_port_state_t: This holds the per port information. The siport_mutex
59 *	holds the per port mutex. The siport_pending_tags is the bit mask of
60 * 	commands posted to controller. The siport_slot_pkts[] holds the
61 * 	pending sata packets. The siport_port_type holds the device type
62 *	connected directly to the port while the siport_portmult_state
63 * 	holds the similar information for the devices behind a port
64 *	multiplier.
65 *
66 * si_prb_t: This contains the PRB being posted to the controller.
67 *	The two SGE entries contained within si_prb_t itself are not
68 *	really used to hold any scatter gather entries. The scatter gather
69 *	list is maintained external to PRB and is linked from one
70 * 	of the contained SGEs inside the PRB. For atapi devices, the
71 *	first contained SGE holds the PACKET and second contained
72 *	SGE holds the link to an external SGT. For non-atapi devices,
73 *	the first contained SGE works as link to external SGT while
74 *	second SGE is blank.
75 *
76 * external SGT tables: The external SGT tables pointed to from
77 *	within si_prb_t are actually abstracted as si_sgblock_t. Each
78 *	si_sgblock_t contains si_dma_sg_number number of
79 *	SGT tables linked in a chain. Currently this default value of
80 *	SGT tables per block is at 85 as  which translates
81 *	to a maximum of 256 dma cookies per single dma transfer.
82 *	This value can be changed through the global var: si_dma_sg_number
83 *	in /etc/system, the maxium is at 21844 as which translates to 65535
84 *	dma cookies per single dma transfer.
85 *
86 *
87 * III. Driver operation
88 *
89 * Command Issuing: We use the "indirect method of command issuance". The
90 *	PRB contains the command [and atapi PACKET] and a link to the
91 *	external SGT chain. We write the physical address of the PRB into
92 *	command activation register. There are 31 command slots for
93 *	each port. After posting a command, we remember the posted slot &
94 *	the sata packet in siport_pending_tags & siport_slot_pkts[]
95 *	respectively.
96 *
97 * Command completion: On a successful completion, intr_command_complete()
98 * 	receives the control. The slot_status register holds the outstanding
99 *	commands. Any reading of slot_status register automatically clears
100 *	the interrupt. By comparing the slot_status register contents with
101 *	per port siport_pending_tags, we determine which of the previously
102 *	posted commands have finished.
103 *
104 * Timeout handling: Every 5 seconds, the watchdog handler scans thru the
105 * 	pending packets. The satapkt->satapkt_hba_driver_private field is
106 * 	overloaded with the count of watchdog cycles a packet has survived.
107 *	If a packet has not completed within satapkt->satapkt_time, it is
108 *	failed with error code of SATA_PKT_TIMEOUT. There is one watchdog
109 *	handler running for each instance of controller.
110 *
111 * Error handling: For 3124, whenever any single command has encountered
112 *	an error, the whole port execution completely stalls; there is no
113 *	way of canceling or aborting the particular failed command. If
114 * 	the port is connected to a port multiplier, we can however RESUME
115 *	other non-error devices connected to the port multiplier.
116 *	The only way to recover the failed commands is to either initialize
117 *	the port or reset the port/device. Both port initialize and reset
118 *	operations result in discarding any of pending commands on the port.
119 *	All such discarded commands are sent up to framework with PKT_RESET
120 *	satapkt_reason. The assumption is that framework [and sd] would
121 *	retry these commands again. The failed command itself however is
122 *	sent up with PKT_DEV_ERROR.
123 *
124 *	Here is the implementation strategy based on SiliconImage email
125 *	regarding how they handle the errors for their Windows driver:
126 *
127 *	  a) for DEVICEERROR:
128 *		If the port is connected to port multiplier, then
129 *		 1) Resume the port
130 *		 2) Wait for all the non-failed commands to complete
131 *		 3) Perform a Port Initialize
132 *
133 *		If the port is not connected to port multiplier, issue
134 *		a Port Initialize.
135 *
136 *	  b) for SDBERROR: [SDBERROR means failed command is an NCQ command]
137 * 		Handle exactly like DEVICEERROR handling.
138 *		After the Port Initialize done, do a Read Log Extended.
139 *
140 *	  c) for SENDFISERROR:
141 *		If the port is connected to port multiplier, then
142 *		 1) Resume the port
143 *		 2) Wait for all the non-failed commands to complete
144 *		 3) Perform a Port Initialize
145 *
146 *		If the port is not connected to port multiplier, issue
147 * 		a Device Reset.
148 *
149 *	  d) for DATAFISERROR:
150 *		If the port was executing an NCQ command, issue a Device
151 *		Reset.
152 *
153 *		Otherwise, follow the same error recovery as DEVICEERROR.
154 *
155 *	  e) for any other error, simply issue a Device Reset.
156 *
157 * 	To synchronize the interactions between various control flows (e.g.
158 *	error recovery, timeout handling, si_poll_timeout, incoming flow
159 *	from framework etc.), the following precautions are taken care of:
160 *		a) During mopping_in_progress, no more commands are
161 *		accepted from the framework.
162 *
163 *		b) While draining the port multiplier commands, we should
164 *		handle the possibility of any of the other waited commands
165 *		failing (possibly with a different error code)
166 *
167 * Atapi handling: For atapi devices, we use the first SGE within the PRB
168 * 	to fill the scsi cdb while the second SGE points to external SGT.
169 *
170 * Queuing: Queue management is achieved external to the driver inside sd.
171 *	Based on sata_hba_tran->qdepth and IDENTIFY data, the framework
172 *	enables or disables the queuing. The qdepth for si3124 is 31
173 *	commands.
174 *
175 * Port Multiplier: Enumeration of port multiplier is handled during the
176 *	controller initialization and also during the a hotplug operation.
177 *	Current logic takes care of situation where a port multiplier
178 *	is hotplugged into a port which had a cdisk connected previously
179 *	and vice versa.
180 *
181 * Register poll timeouts: Currently most of poll timeouts on register
182 *	reads is set to 0.5 seconds except for a value of 10 seconds
183 *	while reading the device signature. [Such a big timeout values
184 *	for device signature were found needed during cold reboots
185 *	for devices behind port multiplier].
186 *
187 *
188 * IV. Known Issues
189 *
190 * 1) Currently the atapi packet length is hard coded to 12 bytes
191 *	This is wrong. The framework should determine it just like they
192 * 	determine ad_cdb_len in legacy atapi.c. It should even reject
193 *	init_pkt() for greater CDB lengths. See atapi.c. Revisit this
194 *	in 2nd phase of framework project.
195 *
196 * 2) Do real REQUEST SENSE command instead of faking for ATAPI case.
197 *
198 */
199
200
201#include <sys/note.h>
202#include <sys/scsi/scsi.h>
203#include <sys/pci.h>
204#include <sys/sata/sata_hba.h>
205#include <sys/sata/adapters/si3124/si3124reg.h>
206#include <sys/sata/adapters/si3124/si3124var.h>
207#include <sys/sdt.h>
208
209/*
210 * FMA header files
211 */
212#include <sys/ddifm.h>
213#include <sys/fm/protocol.h>
214#include <sys/fm/util.h>
215#include <sys/fm/io/ddi.h>
216
217/*
218 * Function prototypes for driver entry points
219 */
220static	int si_attach(dev_info_t *, ddi_attach_cmd_t);
221static	int si_detach(dev_info_t *, ddi_detach_cmd_t);
222static	int si_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
223static	int si_power(dev_info_t *, int, int);
224static	int si_quiesce(dev_info_t *);
225/*
226 * Function prototypes for SATA Framework interfaces
227 */
228static	int si_register_sata_hba_tran(si_ctl_state_t *);
229static	int si_unregister_sata_hba_tran(si_ctl_state_t *);
230
231static	int si_tran_probe_port(dev_info_t *, sata_device_t *);
232static	int si_tran_start(dev_info_t *, sata_pkt_t *spkt);
233static	int si_tran_abort(dev_info_t *, sata_pkt_t *, int);
234static	int si_tran_reset_dport(dev_info_t *, sata_device_t *);
235static	int si_tran_hotplug_port_activate(dev_info_t *, sata_device_t *);
236static	int si_tran_hotplug_port_deactivate(dev_info_t *, sata_device_t *);
237
238/*
239 * Local function prototypes
240 */
241
242static	int si_alloc_port_state(si_ctl_state_t *, int);
243static	void si_dealloc_port_state(si_ctl_state_t *, int);
244static	int si_alloc_sgbpool(si_ctl_state_t *, int);
245static	void si_dealloc_sgbpool(si_ctl_state_t *, int);
246static	int si_alloc_prbpool(si_ctl_state_t *, int);
247static	void si_dealloc_prbpool(si_ctl_state_t *, int);
248
249static void si_find_dev_signature(si_ctl_state_t *, si_port_state_t *,
250						int, int);
251static void si_poll_cmd(si_ctl_state_t *, si_port_state_t *, int, int,
252						sata_pkt_t *);
253static	int si_claim_free_slot(si_ctl_state_t *, si_port_state_t *, int);
254static	int si_deliver_satapkt(si_ctl_state_t *, si_port_state_t *, int,
255						sata_pkt_t *);
256
257static	int si_initialize_controller(si_ctl_state_t *);
258static	void si_deinitialize_controller(si_ctl_state_t *);
259static void si_init_port(si_ctl_state_t *, int);
260static	int si_enumerate_port_multiplier(si_ctl_state_t *,
261						si_port_state_t *, int);
262static int si_read_portmult_reg(si_ctl_state_t *, si_port_state_t *,
263						int, int, int, uint32_t *);
264static int si_write_portmult_reg(si_ctl_state_t *, si_port_state_t *,
265						int, int, int, uint32_t);
266static void si_set_sense_data(sata_pkt_t *, int);
267
268static uint_t si_intr(caddr_t, caddr_t);
269static int si_intr_command_complete(si_ctl_state_t *,
270					si_port_state_t *, int);
271static void si_schedule_intr_command_error(si_ctl_state_t *,
272					si_port_state_t *, int);
273static void si_do_intr_command_error(void *);
274static int si_intr_command_error(si_ctl_state_t *,
275					si_port_state_t *, int);
276static void si_error_recovery_DEVICEERROR(si_ctl_state_t *,
277					si_port_state_t *, int);
278static void si_error_recovery_SDBERROR(si_ctl_state_t *,
279					si_port_state_t *, int);
280static void si_error_recovery_DATAFISERROR(si_ctl_state_t *,
281					si_port_state_t *, int);
282static void si_error_recovery_SENDFISERROR(si_ctl_state_t *,
283					si_port_state_t *, int);
284static void si_error_recovery_default(si_ctl_state_t *,
285					si_port_state_t *, int);
286static uint8_t si_read_log_ext(si_ctl_state_t *,
287					si_port_state_t *si_portp, int);
288static void si_log_error_message(si_ctl_state_t *, int, uint32_t);
289static int si_intr_port_ready(si_ctl_state_t *, si_port_state_t *, int);
290static int si_intr_pwr_change(si_ctl_state_t *, si_port_state_t *, int);
291static int si_intr_phy_ready_change(si_ctl_state_t *, si_port_state_t *, int);
292static int si_intr_comwake_rcvd(si_ctl_state_t *, si_port_state_t *, int);
293static int si_intr_unrecognised_fis(si_ctl_state_t *, si_port_state_t *, int);
294static int si_intr_dev_xchanged(si_ctl_state_t *, si_port_state_t *, int);
295static int si_intr_decode_err_threshold(si_ctl_state_t *,
296					si_port_state_t *, int);
297static int si_intr_crc_err_threshold(si_ctl_state_t *, si_port_state_t *, int);
298static int si_intr_handshake_err_threshold(si_ctl_state_t *,
299					si_port_state_t *, int);
300static int si_intr_set_devbits_notify(si_ctl_state_t *, si_port_state_t *, int);
301
302static	void si_enable_port_interrupts(si_ctl_state_t *, int);
303static	void si_enable_all_interrupts(si_ctl_state_t *);
304static	void si_disable_port_interrupts(si_ctl_state_t *, int);
305static	void si_disable_all_interrupts(si_ctl_state_t *);
306static 	void fill_dev_sregisters(si_ctl_state_t *, int, sata_device_t *);
307static 	int si_add_legacy_intrs(si_ctl_state_t *);
308static 	int si_add_msi_intrs(si_ctl_state_t *);
309static 	void si_rem_intrs(si_ctl_state_t *);
310
311static	int si_reset_dport_wait_till_ready(si_ctl_state_t *,
312				si_port_state_t *, int, int);
313static int si_clear_port(si_ctl_state_t *, int);
314static void si_schedule_port_initialize(si_ctl_state_t *,
315				si_port_state_t *, int);
316static void si_do_initialize_port(void *);
317static	int si_initialize_port_wait_till_ready(si_ctl_state_t *, int);
318
319static void si_timeout_pkts(si_ctl_state_t *, si_port_state_t *, int, uint32_t);
320static	void si_watchdog_handler(si_ctl_state_t *);
321
322/*
323 * FMA Prototypes
324 */
325static void si_fm_init(si_ctl_state_t *);
326static void si_fm_fini(si_ctl_state_t *);
327static int si_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *);
328static int si_check_acc_handle(ddi_acc_handle_t);
329static int si_check_dma_handle(ddi_dma_handle_t);
330static int si_check_ctl_handles(si_ctl_state_t *);
331static int si_check_port_handles(si_port_state_t *);
332static void si_fm_ereport(si_ctl_state_t *, char *, char *);
333
334static	void si_log(si_ctl_state_t *, si_port_state_t *, char *, ...);
335
336static void si_copy_out_regs(sata_cmd_t *, si_ctl_state_t *, uint8_t, uint8_t);
337
338/*
339 * DMA attributes for the data buffer
340 */
341
342static ddi_dma_attr_t buffer_dma_attr = {
343	DMA_ATTR_V0,		/* dma_attr_version */
344	0,			/* dma_attr_addr_lo: lowest bus address */
345	0xffffffffffffffffull,	/* dma_attr_addr_hi: highest bus address */
346	0xffffffffull,		/* dma_attr_count_max i.e. for one cookie */
347	1,			/* dma_attr_align: single byte aligned */
348	1,			/* dma_attr_burstsizes */
349	1,			/* dma_attr_minxfer */
350	0xffffffffull,		/* dma_attr_maxxfer i.e. includes all cookies */
351	0xffffffffull,		/* dma_attr_seg */
352	SI_DEFAULT_SGL_LENGTH,	/* dma_attr_sgllen */
353	512,			/* dma_attr_granular */
354	0,			/* dma_attr_flags */
355};
356
357/*
358 * DMA attributes for incore RPB and SGT pool
359 */
360static ddi_dma_attr_t prb_sgt_dma_attr = {
361	DMA_ATTR_V0,		/* dma_attr_version */
362	0,			/* dma_attr_addr_lo: lowest bus address */
363	0xffffffffffffffffull,	/* dma_attr_addr_hi: highest bus address */
364	0xffffffffull,		/* dma_attr_count_max i.e. for one cookie */
365	8,			/* dma_attr_align: quad word aligned */
366	1,			/* dma_attr_burstsizes */
367	1,			/* dma_attr_minxfer */
368	0xffffffffull,		/* dma_attr_maxxfer i.e. includes all cookies */
369	0xffffffffull,		/* dma_attr_seg */
370	1,			/* dma_attr_sgllen */
371	1,			/* dma_attr_granular */
372	0,			/* dma_attr_flags */
373};
374
375/* Device access attributes */
376static ddi_device_acc_attr_t accattr = {
377    DDI_DEVICE_ATTR_V1,
378    DDI_STRUCTURE_LE_ACC,
379    DDI_STRICTORDER_ACC,
380    DDI_DEFAULT_ACC
381};
382
383
384static struct dev_ops sictl_dev_ops = {
385	DEVO_REV,		/* devo_rev */
386	0,			/* refcnt  */
387	si_getinfo,		/* info */
388	nulldev,		/* identify */
389	nulldev,		/* probe */
390	si_attach,		/* attach */
391	si_detach,		/* detach */
392	nodev,			/* no reset */
393	(struct cb_ops *)0,	/* driver operations */
394	NULL,			/* bus operations */
395	si_power,		/* power */
396	si_quiesce,		/* devo_quiesce */
397};
398
399static sata_tran_hotplug_ops_t si_tran_hotplug_ops = {
400	SATA_TRAN_HOTPLUG_OPS_REV_1,
401	si_tran_hotplug_port_activate,
402	si_tran_hotplug_port_deactivate
403};
404
405
406static int si_watchdog_timeout = 5; /* 5 seconds */
407static int si_watchdog_tick;
408
409extern struct mod_ops mod_driverops;
410
411static  struct modldrv modldrv = {
412	&mod_driverops,	/* driverops */
413	"si3124 driver",
414	&sictl_dev_ops,	/* driver ops */
415};
416
417static  struct modlinkage modlinkage = {
418	MODREV_1,
419	&modldrv,
420	NULL
421};
422
423
424/* The following are needed for si_log() */
425static kmutex_t si_log_mutex;
426static char si_log_buf[SI_LOGBUF_LEN];
427uint32_t si_debug_flags =
428    SIDBG_ERRS|SIDBG_INIT|SIDBG_EVENT|SIDBG_TIMEOUT|SIDBG_RESET;
429
430static int is_msi_supported = 0;
431
432/*
433 * The below global variables are tunable via /etc/system
434 *
435 * si_dma_sg_number
436 */
437
438int si_dma_sg_number = SI_DEFAULT_SGT_TABLES_PER_PRB;
439
440/* Opaque state pointer to be initialized by ddi_soft_state_init() */
441static void *si_statep	= NULL;
442
443/*
444 *  si3124 module initialization.
445 *
446 */
447int
448_init(void)
449{
450	int	error;
451
452	error = ddi_soft_state_init(&si_statep, sizeof (si_ctl_state_t), 0);
453	if (error != 0) {
454		return (error);
455	}
456
457	mutex_init(&si_log_mutex, NULL, MUTEX_DRIVER, NULL);
458
459	if ((error = sata_hba_init(&modlinkage)) != 0) {
460		mutex_destroy(&si_log_mutex);
461		ddi_soft_state_fini(&si_statep);
462		return (error);
463	}
464
465	error = mod_install(&modlinkage);
466	if (error != 0) {
467		sata_hba_fini(&modlinkage);
468		mutex_destroy(&si_log_mutex);
469		ddi_soft_state_fini(&si_statep);
470		return (error);
471	}
472
473	si_watchdog_tick = drv_usectohz((clock_t)si_watchdog_timeout * 1000000);
474
475	return (error);
476}
477
478/*
479 * si3124 module uninitialize.
480 *
481 */
482int
483_fini(void)
484{
485	int	error;
486
487	error = mod_remove(&modlinkage);
488	if (error != 0) {
489		return (error);
490	}
491
492	/* Remove the resources allocated in _init(). */
493	sata_hba_fini(&modlinkage);
494	mutex_destroy(&si_log_mutex);
495	ddi_soft_state_fini(&si_statep);
496
497	return (error);
498}
499
500/*
501 * _info entry point
502 *
503 */
504int
505_info(struct modinfo *modinfop)
506{
507	return (mod_info(&modlinkage, modinfop));
508}
509
510
511/*
512 * The attach entry point for dev_ops.
513 *
514 * We initialize the controller, initialize the soft state, register
515 * the interrupt handlers and then register ourselves with sata framework.
516 */
517static int
518si_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
519{
520	si_ctl_state_t *si_ctlp;
521	int instance;
522	int status;
523	int attach_state;
524	int intr_types;
525	sata_device_t sdevice;
526
527	SIDBG(SIDBG_ENTRY, "si_attach enter", NULL);
528	instance = ddi_get_instance(dip);
529	attach_state = ATTACH_PROGRESS_NONE;
530
531	switch (cmd) {
532
533	case DDI_ATTACH:
534
535		/* Allocate si_softc. */
536		status = ddi_soft_state_zalloc(si_statep, instance);
537		if (status != DDI_SUCCESS) {
538			goto err_out;
539		}
540
541		si_ctlp = ddi_get_soft_state(si_statep, instance);
542		si_ctlp->sictl_devinfop = dip;
543
544		attach_state |= ATTACH_PROGRESS_STATEP_ALLOC;
545
546		/* Initialize FMA */
547		si_ctlp->fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, dip,
548		    DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
549		    DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
550		    DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
551
552		si_fm_init(si_ctlp);
553
554		attach_state |= ATTACH_PROGRESS_INIT_FMA;
555
556		/* Configure pci config space handle. */
557		status = pci_config_setup(dip, &si_ctlp->sictl_pci_conf_handle);
558		if (status != DDI_SUCCESS) {
559			goto err_out;
560		}
561
562		si_ctlp->sictl_devid =
563		    pci_config_get16(si_ctlp->sictl_pci_conf_handle,
564		    PCI_CONF_DEVID);
565		if (si_ctlp->sictl_devid == SI3132_DEV_ID) {
566			si_ctlp->sictl_num_ports = SI3132_MAX_PORTS;
567		} else {
568			si_ctlp->sictl_num_ports = SI3124_MAX_PORTS;
569		}
570
571		attach_state |= ATTACH_PROGRESS_CONF_HANDLE;
572
573		/* Now map the bar0; the bar0 contains the global registers. */
574		status = ddi_regs_map_setup(dip,
575		    PCI_BAR0,
576		    (caddr_t *)&si_ctlp->sictl_global_addr,
577		    0,
578		    0,
579		    &accattr,
580		    &si_ctlp->sictl_global_acc_handle);
581		if (status != DDI_SUCCESS) {
582			goto err_out;
583		}
584
585		attach_state |= ATTACH_PROGRESS_BAR0_MAP;
586
587		/* Now map bar1; the bar1 contains the port registers. */
588		status = ddi_regs_map_setup(dip,
589		    PCI_BAR1,
590		    (caddr_t *)&si_ctlp->sictl_port_addr,
591		    0,
592		    0,
593		    &accattr,
594		    &si_ctlp->sictl_port_acc_handle);
595		if (status != DDI_SUCCESS) {
596			goto err_out;
597		}
598
599		attach_state |= ATTACH_PROGRESS_BAR1_MAP;
600
601		/*
602		 * Disable all the interrupts before adding interrupt
603		 * handler(s). The interrupts shall be re-enabled selectively
604		 * out of si_init_port().
605		 */
606		si_disable_all_interrupts(si_ctlp);
607
608		/* Get supported interrupt types. */
609		if (ddi_intr_get_supported_types(dip, &intr_types)
610		    != DDI_SUCCESS) {
611			SIDBG_C(SIDBG_INIT, si_ctlp,
612			    "ddi_intr_get_supported_types failed", NULL);
613			goto err_out;
614		}
615
616		SIDBG_C(SIDBG_INIT, si_ctlp,
617		    "ddi_intr_get_supported_types() returned: 0x%x",
618		    intr_types);
619
620		if (is_msi_supported && (intr_types & DDI_INTR_TYPE_MSI)) {
621			SIDBG_C(SIDBG_INIT, si_ctlp,
622			    "Using MSI interrupt type", NULL);
623
624			/*
625			 * Try MSI first, but fall back to legacy if MSI
626			 * attach fails.
627			 */
628			if (si_add_msi_intrs(si_ctlp) == DDI_SUCCESS) {
629				si_ctlp->sictl_intr_type = DDI_INTR_TYPE_MSI;
630				attach_state |= ATTACH_PROGRESS_INTR_ADDED;
631				SIDBG_C(SIDBG_INIT, si_ctlp,
632				    "MSI interrupt setup done", NULL);
633			} else {
634				SIDBG_C(SIDBG_INIT, si_ctlp,
635				    "MSI registration failed "
636				    "will try Legacy interrupts", NULL);
637			}
638		}
639
640		if (!(attach_state & ATTACH_PROGRESS_INTR_ADDED) &&
641		    (intr_types & DDI_INTR_TYPE_FIXED)) {
642			/*
643			 * Either the MSI interrupt setup has failed or only
644			 * fixed interrupts are available on the system.
645			 */
646			SIDBG_C(SIDBG_INIT, si_ctlp,
647			    "Using Legacy interrupt type", NULL);
648
649			if (si_add_legacy_intrs(si_ctlp) == DDI_SUCCESS) {
650				si_ctlp->sictl_intr_type = DDI_INTR_TYPE_FIXED;
651				attach_state |= ATTACH_PROGRESS_INTR_ADDED;
652				SIDBG_C(SIDBG_INIT, si_ctlp,
653				    "Legacy interrupt setup done", NULL);
654			} else {
655				SIDBG_C(SIDBG_INIT, si_ctlp,
656				    "legacy interrupt setup failed", NULL);
657				goto err_out;
658			}
659		}
660
661		if (!(attach_state & ATTACH_PROGRESS_INTR_ADDED)) {
662			SIDBG_C(SIDBG_INIT, si_ctlp,
663			    "si3124: No interrupts registered", NULL);
664			goto err_out;
665		}
666
667
668		/* Initialize the mutex. */
669		mutex_init(&si_ctlp->sictl_mutex, NULL, MUTEX_DRIVER,
670		    (void *)(uintptr_t)si_ctlp->sictl_intr_pri);
671
672		attach_state |= ATTACH_PROGRESS_MUTEX_INIT;
673
674		/*
675		 * Initialize the controller and driver core.
676		 */
677		si_ctlp->sictl_flags |= SI_ATTACH;
678		status = si_initialize_controller(si_ctlp);
679		si_ctlp->sictl_flags &= ~SI_ATTACH;
680		if (status) {
681			goto err_out;
682		}
683
684		attach_state |= ATTACH_PROGRESS_HW_INIT;
685
686		if (si_register_sata_hba_tran(si_ctlp)) {
687			SIDBG_C(SIDBG_INIT, si_ctlp,
688			    "si3124: setting sata hba tran failed", NULL);
689			goto err_out;
690		}
691
692		si_ctlp->sictl_timeout_id = timeout(
693		    (void (*)(void *))si_watchdog_handler,
694		    (caddr_t)si_ctlp, si_watchdog_tick);
695
696		si_ctlp->sictl_power_level = PM_LEVEL_D0;
697
698		return (DDI_SUCCESS);
699
700	case DDI_RESUME:
701		si_ctlp = ddi_get_soft_state(si_statep, instance);
702
703		status = si_initialize_controller(si_ctlp);
704		if (status) {
705			return (DDI_FAILURE);
706		}
707
708		si_ctlp->sictl_timeout_id = timeout(
709		    (void (*)(void *))si_watchdog_handler,
710		    (caddr_t)si_ctlp, si_watchdog_tick);
711
712		(void) pm_power_has_changed(dip, 0, PM_LEVEL_D0);
713
714		/* Notify SATA framework about RESUME. */
715		if (sata_hba_attach(si_ctlp->sictl_devinfop,
716		    si_ctlp->sictl_sata_hba_tran,
717		    DDI_RESUME) != DDI_SUCCESS) {
718			return (DDI_FAILURE);
719		}
720
721		/*
722		 * Notify the "framework" that it should reprobe ports to see
723		 * if any device got changed while suspended.
724		 */
725		bzero((void *)&sdevice, sizeof (sata_device_t));
726		sata_hba_event_notify(dip, &sdevice,
727		    SATA_EVNT_PWR_LEVEL_CHANGED);
728		SIDBG_C(SIDBG_INIT|SIDBG_EVENT, si_ctlp,
729		    "sending event up: SATA_EVNT_PWR_LEVEL_CHANGED", NULL);
730
731		(void) pm_idle_component(si_ctlp->sictl_devinfop, 0);
732
733		si_ctlp->sictl_power_level = PM_LEVEL_D0;
734
735		return (DDI_SUCCESS);
736
737	default:
738		return (DDI_FAILURE);
739
740	}
741
742err_out:
743	if (attach_state & ATTACH_PROGRESS_HW_INIT) {
744		si_ctlp->sictl_flags |= SI_DETACH;
745		/* We want to set SI_DETACH to deallocate all memory */
746		si_deinitialize_controller(si_ctlp);
747		si_ctlp->sictl_flags &= ~SI_DETACH;
748	}
749
750	if (attach_state & ATTACH_PROGRESS_MUTEX_INIT) {
751		mutex_destroy(&si_ctlp->sictl_mutex);
752	}
753
754	if (attach_state & ATTACH_PROGRESS_INTR_ADDED) {
755		si_rem_intrs(si_ctlp);
756	}
757
758	if (attach_state & ATTACH_PROGRESS_BAR1_MAP) {
759		ddi_regs_map_free(&si_ctlp->sictl_port_acc_handle);
760	}
761
762	if (attach_state & ATTACH_PROGRESS_BAR0_MAP) {
763		ddi_regs_map_free(&si_ctlp->sictl_global_acc_handle);
764	}
765
766	if (attach_state & ATTACH_PROGRESS_CONF_HANDLE) {
767		pci_config_teardown(&si_ctlp->sictl_pci_conf_handle);
768	}
769
770	if (attach_state & ATTACH_PROGRESS_INIT_FMA) {
771		si_fm_fini(si_ctlp);
772	}
773
774	if (attach_state & ATTACH_PROGRESS_STATEP_ALLOC) {
775		ddi_soft_state_free(si_statep, instance);
776	}
777
778	return (DDI_FAILURE);
779}
780
781
782/*
783 * The detach entry point for dev_ops.
784 *
785 * We undo the things we did in si_attach().
786 */
787static int
788si_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
789{
790	si_ctl_state_t *si_ctlp;
791	int instance;
792
793	SIDBG(SIDBG_ENTRY, "si_detach enter", NULL);
794	instance = ddi_get_instance(dip);
795	si_ctlp = ddi_get_soft_state(si_statep, instance);
796
797	switch (cmd) {
798
799	case DDI_DETACH:
800
801		mutex_enter(&si_ctlp->sictl_mutex);
802
803		/* disable the interrupts for an uninterrupted detach */
804		si_disable_all_interrupts(si_ctlp);
805
806		mutex_exit(&si_ctlp->sictl_mutex);
807		/* unregister from the sata framework. */
808		if (si_unregister_sata_hba_tran(si_ctlp) != SI_SUCCESS) {
809			si_enable_all_interrupts(si_ctlp);
810			return (DDI_FAILURE);
811		}
812		mutex_enter(&si_ctlp->sictl_mutex);
813
814		/* now cancel the timeout handler. */
815		si_ctlp->sictl_flags |= SI_NO_TIMEOUTS;
816		(void) untimeout(si_ctlp->sictl_timeout_id);
817		si_ctlp->sictl_flags &= ~SI_NO_TIMEOUTS;
818
819		/* de-initialize the controller. */
820		si_ctlp->sictl_flags |= SI_DETACH;
821		si_deinitialize_controller(si_ctlp);
822		si_ctlp->sictl_flags &= ~SI_DETACH;
823
824		/* destroy any mutexes */
825		mutex_exit(&si_ctlp->sictl_mutex);
826		mutex_destroy(&si_ctlp->sictl_mutex);
827
828		/* remove the interrupts */
829		si_rem_intrs(si_ctlp);
830
831		/* remove the reg maps. */
832		ddi_regs_map_free(&si_ctlp->sictl_port_acc_handle);
833		ddi_regs_map_free(&si_ctlp->sictl_global_acc_handle);
834		pci_config_teardown(&si_ctlp->sictl_pci_conf_handle);
835
836		/* deinit FMA */
837		si_fm_fini(si_ctlp);
838
839		/* free the soft state. */
840		ddi_soft_state_free(si_statep, instance);
841
842		return (DDI_SUCCESS);
843
844	case DDI_SUSPEND:
845		/* Inform SATA framework */
846		if (sata_hba_detach(dip, cmd) != DDI_SUCCESS) {
847			return (DDI_FAILURE);
848		}
849
850		mutex_enter(&si_ctlp->sictl_mutex);
851
852		/*
853		 * Device needs to be at full power in case it is needed to
854		 * handle dump(9e) to save CPR state after DDI_SUSPEND
855		 * completes.  This is OK since presumably power will be
856		 * removed anyways.  No outstanding transactions should be
857		 * on the controller since the children are already quiesced.
858		 *
859		 * If any ioctls/cfgadm support is added that touches
860		 * hardware, those entry points will need to check for
861		 * suspend and then block or return errors until resume.
862		 *
863		 */
864		if (pm_busy_component(si_ctlp->sictl_devinfop, 0) ==
865		    DDI_SUCCESS) {
866			mutex_exit(&si_ctlp->sictl_mutex);
867			(void) pm_raise_power(si_ctlp->sictl_devinfop, 0,
868			    PM_LEVEL_D0);
869			mutex_enter(&si_ctlp->sictl_mutex);
870		}
871
872		si_deinitialize_controller(si_ctlp);
873
874		si_ctlp->sictl_flags |= SI_NO_TIMEOUTS;
875		(void) untimeout(si_ctlp->sictl_timeout_id);
876		si_ctlp->sictl_flags &= ~SI_NO_TIMEOUTS;
877
878		SIDBG_C(SIDBG_POWER, si_ctlp, "si3124%d: DDI_SUSPEND",
879		    instance);
880
881		mutex_exit(&si_ctlp->sictl_mutex);
882
883		return (DDI_SUCCESS);
884
885	default:
886		return (DDI_FAILURE);
887
888	}
889
890}
891
892static int
893si_power(dev_info_t *dip, int component, int level)
894{
895#ifndef __lock_lint
896	_NOTE(ARGUNUSED(component))
897#endif /* __lock_lint */
898
899	si_ctl_state_t *si_ctlp;
900	int instance = ddi_get_instance(dip);
901	int rval = DDI_SUCCESS;
902	int old_level;
903	sata_device_t sdevice;
904
905	si_ctlp = ddi_get_soft_state(si_statep, instance);
906
907	if (si_ctlp == NULL) {
908		return (DDI_FAILURE);
909	}
910
911	SIDBG_C(SIDBG_ENTRY, si_ctlp, "si_power enter", NULL);
912
913	mutex_enter(&si_ctlp->sictl_mutex);
914	old_level = si_ctlp->sictl_power_level;
915
916	switch (level) {
917	case PM_LEVEL_D0: /* fully on */
918		pci_config_put16(si_ctlp->sictl_pci_conf_handle,
919		    PM_CSR(si_ctlp->sictl_devid), PCI_PMCSR_D0);
920#ifndef __lock_lint
921		delay(drv_usectohz(10000));
922#endif  /* __lock_lint */
923		si_ctlp->sictl_power_level = PM_LEVEL_D0;
924		(void) pci_restore_config_regs(si_ctlp->sictl_devinfop);
925
926		SIDBG_C(SIDBG_POWER, si_ctlp,
927		    "si3124%d: turning power ON. old level %d",
928		    instance, old_level);
929		/*
930		 * If called from attach, just raise device power,
931		 * restore config registers (if they were saved
932		 * from a previous detach that lowered power),
933		 * and exit.
934		 */
935		if (si_ctlp->sictl_flags & SI_ATTACH)
936			break;
937
938		mutex_exit(&si_ctlp->sictl_mutex);
939		(void) si_initialize_controller(si_ctlp);
940		mutex_enter(&si_ctlp->sictl_mutex);
941
942		si_ctlp->sictl_timeout_id = timeout(
943		    (void (*)(void *))si_watchdog_handler,
944		    (caddr_t)si_ctlp, si_watchdog_tick);
945
946		bzero((void *)&sdevice, sizeof (sata_device_t));
947		sata_hba_event_notify(
948		    si_ctlp->sictl_sata_hba_tran->sata_tran_hba_dip,
949		    &sdevice, SATA_EVNT_PWR_LEVEL_CHANGED);
950		SIDBG_C(SIDBG_EVENT|SIDBG_POWER, si_ctlp,
951		    "sending event up: PWR_LEVEL_CHANGED", NULL);
952
953		break;
954
955	case PM_LEVEL_D3: /* fully off */
956		if (!(si_ctlp->sictl_flags & SI_DETACH)) {
957			si_ctlp->sictl_flags |= SI_NO_TIMEOUTS;
958			(void) untimeout(si_ctlp->sictl_timeout_id);
959			si_ctlp->sictl_flags &= ~SI_NO_TIMEOUTS;
960
961			si_deinitialize_controller(si_ctlp);
962
963			si_ctlp->sictl_power_level = PM_LEVEL_D3;
964		}
965
966		(void) pci_save_config_regs(si_ctlp->sictl_devinfop);
967
968		pci_config_put16(si_ctlp->sictl_pci_conf_handle,
969		    PM_CSR(si_ctlp->sictl_devid), PCI_PMCSR_D3HOT);
970
971		SIDBG_C(SIDBG_POWER, si_ctlp, "si3124%d: turning power OFF. "
972		    "old level %d", instance, old_level);
973
974		break;
975
976	default:
977		SIDBG_C(SIDBG_POWER, si_ctlp, "si3124%d: turning power OFF. "
978		    "old level %d", instance, old_level);
979		rval = DDI_FAILURE;
980		break;
981	}
982
983	mutex_exit(&si_ctlp->sictl_mutex);
984
985	return (rval);
986}
987
988
989/*
990 * The info entry point for dev_ops.
991 *
992 */
993static int
994si_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd,
995		void *arg,
996		void **result)
997{
998#ifndef __lock_lint
999	_NOTE(ARGUNUSED(dip))
1000#endif /* __lock_lint */
1001	si_ctl_state_t *si_ctlp;
1002	int instance;
1003	dev_t dev;
1004
1005	dev = (dev_t)arg;
1006	instance = getminor(dev);
1007
1008	switch (infocmd) {
1009		case DDI_INFO_DEVT2DEVINFO:
1010			si_ctlp = ddi_get_soft_state(si_statep,  instance);
1011			if (si_ctlp != NULL) {
1012				*result = si_ctlp->sictl_devinfop;
1013				return (DDI_SUCCESS);
1014			} else {
1015				*result = NULL;
1016				return (DDI_FAILURE);
1017			}
1018		case DDI_INFO_DEVT2INSTANCE:
1019			*(int *)result = instance;
1020			break;
1021		default:
1022			break;
1023	}
1024	return (DDI_SUCCESS);
1025}
1026
1027
1028
1029/*
1030 * Registers the si3124 with sata framework.
1031 */
1032static int
1033si_register_sata_hba_tran(si_ctl_state_t *si_ctlp)
1034{
1035	struct 	sata_hba_tran	*sata_hba_tran;
1036
1037	SIDBG_C(SIDBG_ENTRY, si_ctlp,
1038	    "si_register_sata_hba_tran entry", NULL);
1039
1040	mutex_enter(&si_ctlp->sictl_mutex);
1041
1042	/* Allocate memory for the sata_hba_tran  */
1043	sata_hba_tran = kmem_zalloc(sizeof (sata_hba_tran_t), KM_SLEEP);
1044
1045	sata_hba_tran->sata_tran_hba_rev = SATA_TRAN_HBA_REV;
1046	sata_hba_tran->sata_tran_hba_dip = si_ctlp->sictl_devinfop;
1047
1048	if (si_dma_sg_number > SI_MAX_SGT_TABLES_PER_PRB) {
1049		si_dma_sg_number = SI_MAX_SGT_TABLES_PER_PRB;
1050	} else if (si_dma_sg_number < SI_MIN_SGT_TABLES_PER_PRB) {
1051		si_dma_sg_number = SI_MIN_SGT_TABLES_PER_PRB;
1052	}
1053
1054	if (si_dma_sg_number != SI_DEFAULT_SGT_TABLES_PER_PRB) {
1055		buffer_dma_attr.dma_attr_sgllen = SGE_LENGTH(si_dma_sg_number);
1056	}
1057	sata_hba_tran->sata_tran_hba_dma_attr = &buffer_dma_attr;
1058
1059	sata_hba_tran->sata_tran_hba_num_cports = si_ctlp->sictl_num_ports;
1060	sata_hba_tran->sata_tran_hba_features_support = 0;
1061	sata_hba_tran->sata_tran_hba_qdepth = SI_NUM_SLOTS;
1062
1063	sata_hba_tran->sata_tran_probe_port = si_tran_probe_port;
1064	sata_hba_tran->sata_tran_start = si_tran_start;
1065	sata_hba_tran->sata_tran_abort = si_tran_abort;
1066	sata_hba_tran->sata_tran_reset_dport = si_tran_reset_dport;
1067	sata_hba_tran->sata_tran_selftest = NULL;
1068	sata_hba_tran->sata_tran_hotplug_ops = &si_tran_hotplug_ops;
1069	sata_hba_tran->sata_tran_pwrmgt_ops = NULL;
1070	sata_hba_tran->sata_tran_ioctl = NULL;
1071	mutex_exit(&si_ctlp->sictl_mutex);
1072
1073	/* Attach it to SATA framework */
1074	if (sata_hba_attach(si_ctlp->sictl_devinfop, sata_hba_tran, DDI_ATTACH)
1075	    != DDI_SUCCESS) {
1076		kmem_free((void *)sata_hba_tran, sizeof (sata_hba_tran_t));
1077		return (SI_FAILURE);
1078	}
1079
1080	mutex_enter(&si_ctlp->sictl_mutex);
1081	si_ctlp->sictl_sata_hba_tran = sata_hba_tran;
1082	mutex_exit(&si_ctlp->sictl_mutex);
1083
1084	return (SI_SUCCESS);
1085}
1086
1087
1088/*
1089 * Unregisters the si3124 with sata framework.
1090 */
1091static int
1092si_unregister_sata_hba_tran(si_ctl_state_t *si_ctlp)
1093{
1094
1095	/* Detach from the SATA framework. */
1096	if (sata_hba_detach(si_ctlp->sictl_devinfop, DDI_DETACH) !=
1097	    DDI_SUCCESS) {
1098		return (SI_FAILURE);
1099	}
1100
1101	/* Deallocate sata_hba_tran. */
1102	kmem_free((void *)si_ctlp->sictl_sata_hba_tran,
1103	    sizeof (sata_hba_tran_t));
1104
1105	si_ctlp->sictl_sata_hba_tran = NULL;
1106
1107	return (SI_SUCCESS);
1108}
1109
1110/*
1111 * Called by sata framework to probe a port. We return the
1112 * cached information from a previous hardware probe.
1113 *
1114 * The actual hardware probing itself was done either from within
1115 * si_initialize_controller() during the driver attach or
1116 * from a phy ready change interrupt handler.
1117 */
1118static int
1119si_tran_probe_port(dev_info_t *dip, sata_device_t *sd)
1120{
1121
1122	si_ctl_state_t	*si_ctlp;
1123	uint8_t cport = sd->satadev_addr.cport;
1124	uint8_t pmport = sd->satadev_addr.pmport;
1125	uint8_t qual = sd->satadev_addr.qual;
1126	uint8_t port_type;
1127	si_port_state_t *si_portp;
1128	si_portmult_state_t *si_portmultp;
1129
1130	si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1131
1132	SIDBG_C(SIDBG_ENTRY, si_ctlp,
1133	    "si_tran_probe_port: cport: 0x%x, pmport: 0x%x, qual: 0x%x",
1134	    cport, pmport, qual);
1135
1136	if (cport >= SI_MAX_PORTS) {
1137		sd->satadev_type = SATA_DTYPE_NONE;
1138		sd->satadev_state = SATA_STATE_UNKNOWN; /* invalid port */
1139		return (SATA_FAILURE);
1140	}
1141
1142	mutex_enter(&si_ctlp->sictl_mutex);
1143	si_portp = si_ctlp->sictl_ports[cport];
1144	mutex_exit(&si_ctlp->sictl_mutex);
1145	if (si_portp == NULL) {
1146		sd->satadev_type = SATA_DTYPE_NONE;
1147		sd->satadev_state = SATA_STATE_UNKNOWN;
1148		return (SATA_FAILURE);
1149	}
1150
1151	mutex_enter(&si_portp->siport_mutex);
1152
1153	if (qual == SATA_ADDR_PMPORT) {
1154		if (pmport >= si_portp->siport_portmult_state.sipm_num_ports) {
1155			sd->satadev_type = SATA_DTYPE_NONE;
1156			sd->satadev_state = SATA_STATE_UNKNOWN;
1157			mutex_exit(&si_portp->siport_mutex);
1158			return (SATA_FAILURE);
1159		} else {
1160			si_portmultp = 	&si_portp->siport_portmult_state;
1161			port_type = si_portmultp->sipm_port_type[pmport];
1162		}
1163	} else {
1164		port_type = si_portp->siport_port_type;
1165	}
1166
1167	switch (port_type) {
1168
1169	case PORT_TYPE_DISK:
1170		sd->satadev_type = SATA_DTYPE_ATADISK;
1171		break;
1172
1173	case PORT_TYPE_ATAPI:
1174		sd->satadev_type = SATA_DTYPE_ATAPICD;
1175		break;
1176
1177	case PORT_TYPE_MULTIPLIER:
1178		sd->satadev_type = SATA_DTYPE_PMULT;
1179		sd->satadev_add_info =
1180		    si_portp->siport_portmult_state.sipm_num_ports;
1181		break;
1182
1183	case PORT_TYPE_UNKNOWN:
1184		sd->satadev_type = SATA_DTYPE_UNKNOWN;
1185		break;
1186
1187	default:
1188		/* we don't support any other device types. */
1189		sd->satadev_type = SATA_DTYPE_NONE;
1190		break;
1191	}
1192	sd->satadev_state = SATA_STATE_READY;
1193
1194	if (qual == SATA_ADDR_PMPORT) {
1195		(void) si_read_portmult_reg(si_ctlp, si_portp, cport,
1196		    pmport, PSCR_REG0, &sd->satadev_scr.sstatus);
1197		(void) si_read_portmult_reg(si_ctlp, si_portp, cport,
1198		    pmport, PSCR_REG1, &sd->satadev_scr.serror);
1199		(void) si_read_portmult_reg(si_ctlp, si_portp, cport,
1200		    pmport, PSCR_REG2, &sd->satadev_scr.scontrol);
1201		(void) si_read_portmult_reg(si_ctlp, si_portp, cport,
1202		    pmport, PSCR_REG3, &sd->satadev_scr.sactive);
1203	} else {
1204		fill_dev_sregisters(si_ctlp, cport, sd);
1205		if (!(si_portp->siport_active)) {
1206			/*
1207			 * Since we are implementing the port deactivation
1208			 * in software only, we need to fake a valid value
1209			 * for sstatus when the device is in deactivated state.
1210			 */
1211			SSTATUS_SET_DET(sd->satadev_scr.sstatus,
1212			    SSTATUS_DET_PHYOFFLINE);
1213			SSTATUS_SET_IPM(sd->satadev_scr.sstatus,
1214			    SSTATUS_IPM_NODEV_NOPHY);
1215			sd->satadev_state = SATA_PSTATE_SHUTDOWN;
1216		}
1217	}
1218
1219	mutex_exit(&si_portp->siport_mutex);
1220	return (SATA_SUCCESS);
1221}
1222
1223/*
1224 * Called by sata framework to transport a sata packet down stream.
1225 *
1226 * The actual work of building the FIS & transporting it to the hardware
1227 * is done out of the subroutine si_deliver_satapkt().
1228 */
1229static int
1230si_tran_start(dev_info_t *dip, sata_pkt_t *spkt)
1231{
1232	si_ctl_state_t *si_ctlp;
1233	uint8_t	cport;
1234	si_port_state_t *si_portp;
1235	int slot;
1236
1237	cport = spkt->satapkt_device.satadev_addr.cport;
1238	si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1239	mutex_enter(&si_ctlp->sictl_mutex);
1240	si_portp = si_ctlp->sictl_ports[cport];
1241	mutex_exit(&si_ctlp->sictl_mutex);
1242
1243	SIDBG_P(SIDBG_ENTRY, si_portp,
1244	    "si_tran_start entry", NULL);
1245
1246	mutex_enter(&si_portp->siport_mutex);
1247
1248	if ((si_portp->siport_port_type == PORT_TYPE_NODEV) ||
1249	    !si_portp->siport_active) {
1250		/*
1251		 * si_intr_phy_ready_change() may have rendered it to
1252		 * PORT_TYPE_NODEV. cfgadm operation may have rendered
1253		 * it inactive.
1254		 */
1255		spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1256		fill_dev_sregisters(si_ctlp, cport, &spkt->satapkt_device);
1257		mutex_exit(&si_portp->siport_mutex);
1258		return (SATA_TRAN_PORT_ERROR);
1259	}
1260
1261	if (spkt->satapkt_cmd.satacmd_flags.sata_clear_dev_reset) {
1262		si_portp->siport_reset_in_progress = 0;
1263		SIDBG_P(SIDBG_RESET, si_portp,
1264		    "si_tran_start clearing the "
1265		    "reset_in_progress for port", NULL);
1266	}
1267
1268	if (si_portp->siport_reset_in_progress &&
1269	    ! spkt->satapkt_cmd.satacmd_flags.sata_ignore_dev_reset &&
1270	    ! ddi_in_panic()) {
1271
1272		spkt->satapkt_reason = SATA_PKT_BUSY;
1273		SIDBG_P(SIDBG_RESET, si_portp,
1274		    "si_tran_start returning BUSY while "
1275		    "reset in progress for port", NULL);
1276		mutex_exit(&si_portp->siport_mutex);
1277		return (SATA_TRAN_BUSY);
1278	}
1279
1280	if (si_portp->mopping_in_progress > 0) {
1281		spkt->satapkt_reason = SATA_PKT_BUSY;
1282		SIDBG_P(SIDBG_RESET, si_portp,
1283		    "si_tran_start returning BUSY while "
1284		    "mopping in progress for port", NULL);
1285		mutex_exit(&si_portp->siport_mutex);
1286		return (SATA_TRAN_BUSY);
1287	}
1288
1289	if ((slot = si_deliver_satapkt(si_ctlp, si_portp, cport, spkt))
1290	    == SI_FAILURE) {
1291		spkt->satapkt_reason = SATA_PKT_QUEUE_FULL;
1292		SIDBG_P(SIDBG_ERRS, si_portp,
1293		    "si_tran_start returning QUEUE_FULL",
1294		    NULL);
1295		mutex_exit(&si_portp->siport_mutex);
1296		return (SATA_TRAN_QUEUE_FULL);
1297	}
1298
1299	if (spkt->satapkt_op_mode & (SATA_OPMODE_POLLING|SATA_OPMODE_SYNCH)) {
1300		/* we need to poll now */
1301		si_poll_cmd(si_ctlp, si_portp, cport, slot, spkt);
1302		/*
1303		 * The command has completed, and spkt will be freed by the
1304		 * sata module, so don't keep a pointer to it lying around.
1305		 */
1306		si_portp->siport_slot_pkts[slot] = NULL;
1307	}
1308
1309	mutex_exit(&si_portp->siport_mutex);
1310	return (SATA_TRAN_ACCEPTED);
1311}
1312
1313#define	SENDUP_PACKET(si_portp, satapkt, reason)			\
1314	if (satapkt) {							\
1315		if ((satapkt->satapkt_cmd.satacmd_cmd_reg ==		\
1316					SATAC_WRITE_FPDMA_QUEUED) ||	\
1317		    (satapkt->satapkt_cmd.satacmd_cmd_reg ==		\
1318					SATAC_READ_FPDMA_QUEUED)) {	\
1319			si_portp->siport_pending_ncq_count--;		\
1320		}							\
1321		satapkt->satapkt_reason = reason;			\
1322		/*							\
1323		 * We set the satapkt_reason in both synch and		\
1324		 * non-synch cases.					\
1325		 */							\
1326		if (!(satapkt->satapkt_op_mode & SATA_OPMODE_SYNCH) &&	\
1327			satapkt->satapkt_comp) {			\
1328			mutex_exit(&si_portp->siport_mutex);		\
1329			(*satapkt->satapkt_comp)(satapkt);		\
1330			mutex_enter(&si_portp->siport_mutex);		\
1331		}							\
1332	}
1333
1334/*
1335 * Mopping is necessitated because of the si3124 hardware limitation.
1336 * The only way to recover from errors or to abort a command is to
1337 * reset the port/device but such a reset also results in throwing
1338 * away all the unfinished pending commands.
1339 *
1340 * A port or device is reset in four scenarios:
1341 *	a) some commands failed with errors
1342 *	b) or we need to timeout some commands
1343 *	c) or we need to abort some commands
1344 *	d) or we need reset the port at the request of sata framework
1345 *
1346 * In all these scenarios, we need to send any pending unfinished
1347 * commands up to sata framework.
1348 *
1349 * WARNING!!! siport_mutex should be acquired before the function is called.
1350 */
1351static void
1352si_mop_commands(si_ctl_state_t *si_ctlp,
1353		si_port_state_t *si_portp,
1354		uint8_t	port,
1355
1356		uint32_t slot_status,
1357		uint32_t failed_tags,
1358		uint32_t timedout_tags,
1359		uint32_t aborting_tags,
1360		uint32_t reset_tags)
1361{
1362	uint32_t finished_tags, unfinished_tags;
1363	int tmpslot;
1364	sata_pkt_t *satapkt;
1365	struct sata_cmd_flags *flagsp;
1366
1367	SIDBG_P(SIDBG_ERRS, si_portp,
1368	    "si_mop_commands entered: slot_status: 0x%x",
1369	    slot_status);
1370
1371	SIDBG_P(SIDBG_ERRS, si_portp,
1372	    "si_mop_commands: failed_tags: 0x%x, timedout_tags: 0x%x"
1373	    "aborting_tags: 0x%x, reset_tags: 0x%x",
1374	    failed_tags,
1375	    timedout_tags,
1376	    aborting_tags,
1377	    reset_tags);
1378
1379	/*
1380	 * We could be here for four reasons: abort, reset,
1381	 * timeout or error handling. Only one such mopping
1382	 * is allowed at a time.
1383	 */
1384
1385	finished_tags =  si_portp->siport_pending_tags &
1386	    ~slot_status & SI_SLOT_MASK;
1387
1388	unfinished_tags = slot_status & SI_SLOT_MASK &
1389	    ~failed_tags &
1390	    ~aborting_tags &
1391	    ~reset_tags &
1392	    ~timedout_tags;
1393
1394	/* Send up the finished_tags with SATA_PKT_COMPLETED. */
1395	while (finished_tags) {
1396		tmpslot = ddi_ffs(finished_tags) - 1;
1397		if (tmpslot == -1) {
1398			break;
1399		}
1400
1401		satapkt = si_portp->siport_slot_pkts[tmpslot];
1402
1403		if (satapkt != NULL &&
1404		    satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
1405			si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp,
1406			    port, tmpslot);
1407		}
1408
1409		SIDBG_P(SIDBG_ERRS, si_portp,
1410		    "si_mop_commands sending up completed satapkt: %x",
1411		    satapkt);
1412
1413		CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1414		CLEAR_BIT(finished_tags, tmpslot);
1415		SENDUP_PACKET(si_portp, satapkt, SATA_PKT_COMPLETED);
1416	}
1417
1418	ASSERT(finished_tags == 0);
1419
1420	/* Send up failed_tags with SATA_PKT_DEV_ERROR. */
1421	while (failed_tags) {
1422		tmpslot = ddi_ffs(failed_tags) - 1;
1423		if (tmpslot == -1) {
1424			break;
1425		}
1426		SIDBG_P(SIDBG_ERRS, si_portp, "si3124: si_mop_commands: "
1427		    "handling failed slot: 0x%x", tmpslot);
1428
1429		satapkt = si_portp->siport_slot_pkts[tmpslot];
1430
1431		if (satapkt != NULL) {
1432
1433			if (satapkt->satapkt_device.satadev_type ==
1434			    SATA_DTYPE_ATAPICD) {
1435				si_set_sense_data(satapkt, SATA_PKT_DEV_ERROR);
1436			}
1437
1438
1439			flagsp = &satapkt->satapkt_cmd.satacmd_flags;
1440
1441			flagsp->sata_copy_out_lba_low_msb = B_TRUE;
1442			flagsp->sata_copy_out_lba_mid_msb = B_TRUE;
1443			flagsp->sata_copy_out_lba_high_msb = B_TRUE;
1444			flagsp->sata_copy_out_lba_low_lsb = B_TRUE;
1445			flagsp->sata_copy_out_lba_mid_lsb = B_TRUE;
1446			flagsp->sata_copy_out_lba_high_lsb = B_TRUE;
1447			flagsp->sata_copy_out_error_reg = B_TRUE;
1448			flagsp->sata_copy_out_sec_count_msb = B_TRUE;
1449			flagsp->sata_copy_out_sec_count_lsb = B_TRUE;
1450			flagsp->sata_copy_out_device_reg = B_TRUE;
1451
1452			si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp,
1453			    port, tmpslot);
1454
1455			/*
1456			 * In the case of NCQ command failures, the error is
1457			 * overwritten by the one obtained from issuing of a
1458			 * READ LOG EXTENDED command.
1459			 */
1460			if (si_portp->siport_err_tags_SDBERROR &
1461			    (1 << tmpslot)) {
1462				satapkt->satapkt_cmd.satacmd_error_reg =
1463				    si_read_log_ext(si_ctlp, si_portp, port);
1464			}
1465		}
1466
1467		CLEAR_BIT(failed_tags, tmpslot);
1468		CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1469		SENDUP_PACKET(si_portp, satapkt, SATA_PKT_DEV_ERROR);
1470	}
1471
1472	ASSERT(failed_tags == 0);
1473
1474	/* Send up timedout_tags with SATA_PKT_TIMEOUT. */
1475	while (timedout_tags) {
1476		tmpslot = ddi_ffs(timedout_tags) - 1;
1477		if (tmpslot == -1) {
1478			break;
1479		}
1480
1481		satapkt = si_portp->siport_slot_pkts[tmpslot];
1482		SIDBG_P(SIDBG_ERRS, si_portp,
1483		    "si_mop_commands sending "
1484		    "spkt up with PKT_TIMEOUT: %x",
1485		    satapkt);
1486
1487		CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1488		CLEAR_BIT(timedout_tags, tmpslot);
1489		SENDUP_PACKET(si_portp, satapkt, SATA_PKT_TIMEOUT);
1490	}
1491
1492	ASSERT(timedout_tags == 0);
1493
1494	/* Send up aborting packets with SATA_PKT_ABORTED. */
1495	while (aborting_tags) {
1496		tmpslot = ddi_ffs(aborting_tags) - 1;
1497		if (tmpslot == -1) {
1498			break;
1499		}
1500
1501		satapkt = si_portp->siport_slot_pkts[tmpslot];
1502		SIDBG_P(SIDBG_ERRS, si_portp,
1503		    "si_mop_commands aborting spkt: %x",
1504		    satapkt);
1505		if (satapkt != NULL && satapkt->satapkt_device.satadev_type ==
1506		    SATA_DTYPE_ATAPICD) {
1507			si_set_sense_data(satapkt, SATA_PKT_ABORTED);
1508		}
1509
1510		CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1511		CLEAR_BIT(aborting_tags, tmpslot);
1512		SENDUP_PACKET(si_portp, satapkt, SATA_PKT_ABORTED);
1513
1514	}
1515
1516	ASSERT(aborting_tags == 0);
1517
1518	/* Reset tags are sent up to framework with SATA_PKT_RESET. */
1519	while (reset_tags) {
1520		tmpslot = ddi_ffs(reset_tags) - 1;
1521		if (tmpslot == -1) {
1522			break;
1523		}
1524		satapkt = si_portp->siport_slot_pkts[tmpslot];
1525		SIDBG_P(SIDBG_ERRS, si_portp,
1526		    "si_mop_commands sending PKT_RESET for "
1527		    "reset spkt: %x",
1528		    satapkt);
1529
1530		CLEAR_BIT(reset_tags, tmpslot);
1531		CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1532		SENDUP_PACKET(si_portp, satapkt, SATA_PKT_RESET);
1533	}
1534
1535	ASSERT(reset_tags == 0);
1536
1537	/* Send up the unfinished_tags with SATA_PKT_RESET. */
1538	while (unfinished_tags) {
1539		tmpslot = ddi_ffs(unfinished_tags) - 1;
1540		if (tmpslot == -1) {
1541			break;
1542		}
1543		satapkt = si_portp->siport_slot_pkts[tmpslot];
1544		SIDBG_P(SIDBG_ERRS, si_portp,
1545		    "si_mop_commands sending SATA_PKT_RESET for "
1546		    "retry spkt: %x",
1547		    satapkt);
1548
1549		CLEAR_BIT(unfinished_tags, tmpslot);
1550		CLEAR_BIT(si_portp->siport_pending_tags, tmpslot);
1551		SENDUP_PACKET(si_portp, satapkt, SATA_PKT_RESET);
1552	}
1553
1554	ASSERT(unfinished_tags == 0);
1555
1556	si_portp->mopping_in_progress--;
1557	ASSERT(si_portp->mopping_in_progress >= 0);
1558}
1559
1560/*
1561 * Called by the sata framework to abort the previously sent packet(s).
1562 *
1563 * We reset the device and mop the commands on the port.
1564 */
1565static int
1566si_tran_abort(dev_info_t *dip, sata_pkt_t *spkt, int flag)
1567{
1568	uint32_t slot_status;
1569	uint8_t	port;
1570	int tmpslot;
1571	uint32_t aborting_tags;
1572	uint32_t finished_tags;
1573	si_port_state_t *si_portp;
1574	si_ctl_state_t *si_ctlp;
1575
1576	port = spkt->satapkt_device.satadev_addr.cport;
1577	si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1578	mutex_enter(&si_ctlp->sictl_mutex);
1579	si_portp = si_ctlp->sictl_ports[port];
1580	mutex_exit(&si_ctlp->sictl_mutex);
1581
1582	SIDBG_P(SIDBG_ERRS, si_portp, "si_tran_abort on port: %x", port);
1583
1584	mutex_enter(&si_portp->siport_mutex);
1585
1586	/*
1587	 * If already mopping, then no need to abort anything.
1588	 */
1589	if (si_portp->mopping_in_progress > 0) {
1590		SIDBG_P(SIDBG_ERRS, si_portp,
1591		    "si_tran_abort: port %d mopping "
1592		    "in progress, so just return", port);
1593		mutex_exit(&si_portp->siport_mutex);
1594		return (SATA_SUCCESS);
1595	}
1596
1597	if ((si_portp->siport_port_type == PORT_TYPE_NODEV) ||
1598	    !si_portp->siport_active) {
1599		/*
1600		 * si_intr_phy_ready_change() may have rendered it to
1601		 * PORT_TYPE_NODEV. cfgadm operation may have rendered
1602		 * it inactive.
1603		 */
1604		spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1605		fill_dev_sregisters(si_ctlp, port, &spkt->satapkt_device);
1606		mutex_exit(&si_portp->siport_mutex);
1607		return (SATA_FAILURE);
1608	}
1609
1610	if (flag == SATA_ABORT_ALL_PACKETS) {
1611		aborting_tags = si_portp->siport_pending_tags;
1612	} else {
1613		/*
1614		 * Need to abort a single packet.
1615		 * Search our siport_slot_pkts[] list for matching spkt.
1616		 */
1617		aborting_tags = 0xffffffff; /* 0xffffffff is impossible tag */
1618		for (tmpslot = 0; tmpslot < SI_NUM_SLOTS; tmpslot++) {
1619			if (si_portp->siport_slot_pkts[tmpslot] == spkt) {
1620				aborting_tags = (0x1 << tmpslot);
1621				break;
1622			}
1623		}
1624
1625		if (aborting_tags == 0xffffffff) {
1626			/* requested packet is not on pending list. */
1627			fill_dev_sregisters(si_ctlp, port,
1628			    &spkt->satapkt_device);
1629			mutex_exit(&si_portp->siport_mutex);
1630			return (SATA_FAILURE);
1631		}
1632	}
1633
1634	si_portp->mopping_in_progress++;
1635
1636	slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
1637	    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
1638	(void) si_reset_dport_wait_till_ready(si_ctlp, si_portp,
1639	    port, SI_DEVICE_RESET);
1640
1641	/*
1642	 * Compute which have finished and which need to be retried.
1643	 *
1644	 * The finished tags are siport_pending_tags minus the slot_status.
1645	 * The aborting_tags have to be reduced by finished_tags since we
1646	 * can't possibly abort a tag which had finished already.
1647	 */
1648	finished_tags =  si_portp->siport_pending_tags &
1649	    ~slot_status & SI_SLOT_MASK;
1650	aborting_tags &= ~finished_tags;
1651
1652	si_mop_commands(si_ctlp,
1653	    si_portp,
1654	    port,
1655	    slot_status,
1656	    0, /* failed_tags */
1657	    0, /* timedout_tags */
1658	    aborting_tags,
1659	    0); /* reset_tags */
1660
1661	fill_dev_sregisters(si_ctlp, port, &spkt->satapkt_device);
1662	mutex_exit(&si_portp->siport_mutex);
1663	return (SATA_SUCCESS);
1664}
1665
1666
1667/*
1668 * Used to reject all the pending packets on a port during a reset
1669 * operation.
1670 *
1671 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
1672 * before calling us.
1673 */
1674static void
1675si_reject_all_reset_pkts(
1676	si_ctl_state_t *si_ctlp,
1677	si_port_state_t *si_portp,
1678	int port)
1679{
1680	uint32_t slot_status;
1681	uint32_t reset_tags;
1682
1683	_NOTE(ASSUMING_PROTECTED(si_portp))
1684
1685	SIDBG_P(SIDBG_RESET, si_portp,
1686	    "si_reject_all_reset_pkts on port: %x",
1687	    port);
1688
1689	slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
1690	    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
1691
1692	/* Compute which tags need to be sent up. */
1693	reset_tags = slot_status & SI_SLOT_MASK;
1694
1695	si_portp->mopping_in_progress++;
1696
1697	si_mop_commands(si_ctlp,
1698	    si_portp,
1699	    port,
1700	    slot_status,
1701	    0, /* failed_tags */
1702	    0, /* timedout_tags */
1703	    0, /* aborting_tags */
1704	    reset_tags);
1705}
1706
1707
1708/*
1709 * Called by sata framework to reset a port(s) or device.
1710 *
1711 */
1712static int
1713si_tran_reset_dport(dev_info_t *dip, sata_device_t *sd)
1714{
1715	si_ctl_state_t	*si_ctlp;
1716	uint8_t port = sd->satadev_addr.cport;
1717	int i;
1718	si_port_state_t *si_portp;
1719	int retval = SI_SUCCESS;
1720
1721	si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1722	SIDBG_C(SIDBG_RESET, si_ctlp,
1723	    "si_tran_reset_port entry: port: 0x%x",
1724	    port);
1725
1726	switch (sd->satadev_addr.qual) {
1727	case SATA_ADDR_CPORT:
1728		mutex_enter(&si_ctlp->sictl_mutex);
1729		si_portp = si_ctlp->sictl_ports[port];
1730		mutex_exit(&si_ctlp->sictl_mutex);
1731
1732		mutex_enter(&si_portp->siport_mutex);
1733
1734		/*
1735		 * If already mopping, then no need to reset or mop again.
1736		 */
1737		if (si_portp->mopping_in_progress > 0) {
1738			SIDBG_P(SIDBG_RESET, si_portp,
1739			    "si_tran_reset_dport: CPORT port %d mopping "
1740			    "in progress, so just return", port);
1741			mutex_exit(&si_portp->siport_mutex);
1742			retval = SI_SUCCESS;
1743			break;
1744		}
1745
1746		retval = si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
1747		    SI_PORT_RESET);
1748		si_reject_all_reset_pkts(si_ctlp,  si_portp, port);
1749		mutex_exit(&si_portp->siport_mutex);
1750
1751		break;
1752
1753	case SATA_ADDR_DCPORT:
1754		mutex_enter(&si_ctlp->sictl_mutex);
1755		si_portp = si_ctlp->sictl_ports[port];
1756		mutex_exit(&si_ctlp->sictl_mutex);
1757
1758		mutex_enter(&si_portp->siport_mutex);
1759
1760		if ((si_portp->siport_port_type == PORT_TYPE_NODEV) ||
1761		    !si_portp->siport_active) {
1762			mutex_exit(&si_portp->siport_mutex);
1763			retval = SI_FAILURE;
1764			break;
1765		}
1766
1767		/*
1768		 * If already mopping, then no need to reset or mop again.
1769		 */
1770		if (si_portp->mopping_in_progress > 0) {
1771			SIDBG_P(SIDBG_RESET, si_portp,
1772			    "si_tran_reset_dport: DCPORT port %d mopping "
1773			    "in progress, so just return", port);
1774			mutex_exit(&si_portp->siport_mutex);
1775			retval = SI_SUCCESS;
1776			break;
1777		}
1778
1779		retval = si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
1780		    SI_DEVICE_RESET);
1781		si_reject_all_reset_pkts(si_ctlp,  si_portp, port);
1782		mutex_exit(&si_portp->siport_mutex);
1783
1784		break;
1785
1786	case SATA_ADDR_CNTRL:
1787		for (i = 0; i < si_ctlp->sictl_num_ports; i++) {
1788			mutex_enter(&si_ctlp->sictl_mutex);
1789			si_portp = si_ctlp->sictl_ports[i];
1790			mutex_exit(&si_ctlp->sictl_mutex);
1791
1792			mutex_enter(&si_portp->siport_mutex);
1793
1794			/*
1795			 * If mopping, then all the pending commands are being
1796			 * mopped, therefore there is nothing else to do.
1797			 */
1798			if (si_portp->mopping_in_progress > 0) {
1799				SIDBG_P(SIDBG_RESET, si_portp,
1800				    "si_tran_reset_dport: CNTRL port %d mopping"
1801				    " in progress, so just return", i);
1802				mutex_exit(&si_portp->siport_mutex);
1803				retval = SI_SUCCESS;
1804				break;
1805			}
1806
1807			retval = si_reset_dport_wait_till_ready(si_ctlp,
1808			    si_portp, i, SI_PORT_RESET);
1809			if (retval) {
1810				mutex_exit(&si_portp->siport_mutex);
1811				break;
1812			}
1813			si_reject_all_reset_pkts(si_ctlp,  si_portp, i);
1814			mutex_exit(&si_portp->siport_mutex);
1815		}
1816		break;
1817
1818	case SATA_ADDR_PMPORT:
1819	case SATA_ADDR_DPMPORT:
1820		SIDBG_P(SIDBG_RESET, si_portp,
1821		    "port mult reset not implemented yet", NULL);
1822		/* FALLSTHROUGH */
1823
1824	default:
1825		retval = SI_FAILURE;
1826
1827	}
1828
1829	return (retval);
1830}
1831
1832
1833/*
1834 * Called by sata framework to activate a port as part of hotplug.
1835 *
1836 * Note: Not port-mult aware.
1837 */
1838static int
1839si_tran_hotplug_port_activate(dev_info_t *dip, sata_device_t *satadev)
1840{
1841	si_ctl_state_t *si_ctlp;
1842	si_port_state_t *si_portp;
1843	uint8_t	port;
1844
1845	si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1846	port = satadev->satadev_addr.cport;
1847	mutex_enter(&si_ctlp->sictl_mutex);
1848	si_portp = si_ctlp->sictl_ports[port];
1849	mutex_exit(&si_ctlp->sictl_mutex);
1850
1851	SIDBG_P(SIDBG_EVENT, si_portp, "si_tran_hotplug_port_activate entry",
1852	    NULL);
1853
1854	mutex_enter(&si_portp->siport_mutex);
1855	si_enable_port_interrupts(si_ctlp, port);
1856
1857	/*
1858	 * Reset the device so that a si_find_dev_signature() would trigger.
1859	 * But this reset is an internal operation; the sata framework does
1860	 * not need to know about it.
1861	 */
1862	(void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
1863	    SI_DEVICE_RESET|SI_RESET_NO_EVENTS_UP);
1864
1865	satadev->satadev_state = SATA_STATE_READY;
1866
1867	si_portp->siport_active = PORT_ACTIVE;
1868
1869	fill_dev_sregisters(si_ctlp, port, satadev);
1870
1871	mutex_exit(&si_portp->siport_mutex);
1872	return (SATA_SUCCESS);
1873}
1874
1875/*
1876 * Called by sata framework to deactivate a port as part of hotplug.
1877 *
1878 * Note: Not port-mult aware.
1879 */
1880static int
1881si_tran_hotplug_port_deactivate(dev_info_t *dip, sata_device_t *satadev)
1882{
1883	si_ctl_state_t *si_ctlp;
1884	si_port_state_t *si_portp;
1885	uint8_t	port;
1886
1887	si_ctlp = ddi_get_soft_state(si_statep, ddi_get_instance(dip));
1888	port = satadev->satadev_addr.cport;
1889	mutex_enter(&si_ctlp->sictl_mutex);
1890	si_portp = si_ctlp->sictl_ports[port];
1891	mutex_exit(&si_ctlp->sictl_mutex);
1892
1893	SIDBG(SIDBG_EVENT, "si_tran_hotplug_port_deactivate entry", NULL);
1894
1895	mutex_enter(&si_portp->siport_mutex);
1896	if (si_portp->siport_pending_tags & SI_SLOT_MASK) {
1897		/*
1898		 * There are pending commands on this port.
1899		 * Fail the deactivate request.
1900		 */
1901		satadev->satadev_state = SATA_STATE_READY;
1902		mutex_exit(&si_portp->siport_mutex);
1903		return (SATA_FAILURE);
1904	}
1905
1906	/* mark the device as not accessible any more. */
1907	si_portp->siport_active = PORT_INACTIVE;
1908
1909	/* disable the interrupts on the port. */
1910	si_disable_port_interrupts(si_ctlp, port);
1911
1912	satadev->satadev_state = SATA_PSTATE_SHUTDOWN;
1913
1914	fill_dev_sregisters(si_ctlp, port, satadev);
1915	/*
1916	 * Since we are implementing the port deactivation in software only,
1917	 * we need to fake a valid value for sstatus.
1918	 */
1919	SSTATUS_SET_DET(satadev->satadev_scr.sstatus, SSTATUS_DET_PHYOFFLINE);
1920	SSTATUS_SET_IPM(satadev->satadev_scr.sstatus, SSTATUS_IPM_NODEV_NOPHY);
1921
1922	mutex_exit(&si_portp->siport_mutex);
1923	return (SATA_SUCCESS);
1924}
1925
1926
1927/*
1928 * Allocates the si_port_state_t.
1929 */
1930static int
1931si_alloc_port_state(si_ctl_state_t *si_ctlp, int port)
1932{
1933	si_port_state_t *si_portp;
1934
1935	si_ctlp->sictl_ports[port] = (si_port_state_t *)kmem_zalloc(
1936	    sizeof (si_port_state_t), KM_SLEEP);
1937
1938	si_portp = si_ctlp->sictl_ports[port];
1939	mutex_init(&si_portp->siport_mutex, NULL, MUTEX_DRIVER,
1940	    (void *)(uintptr_t)si_ctlp->sictl_intr_pri);
1941	mutex_enter(&si_portp->siport_mutex);
1942
1943	/* allocate prb & sgt pkts for this port. */
1944	if (si_alloc_prbpool(si_ctlp, port)) {
1945		mutex_exit(&si_portp->siport_mutex);
1946		kmem_free(si_ctlp->sictl_ports[port], sizeof (si_port_state_t));
1947		return (SI_FAILURE);
1948	}
1949	if (si_alloc_sgbpool(si_ctlp, port)) {
1950		si_dealloc_prbpool(si_ctlp, port);
1951		mutex_exit(&si_portp->siport_mutex);
1952		kmem_free(si_ctlp->sictl_ports[port], sizeof (si_port_state_t));
1953		return (SI_FAILURE);
1954	}
1955
1956	/* Allocate the argument for the timeout */
1957	si_portp->siport_event_args =
1958	    kmem_zalloc(sizeof (si_event_arg_t), KM_SLEEP);
1959
1960	si_portp->siport_active = PORT_ACTIVE;
1961	mutex_exit(&si_portp->siport_mutex);
1962
1963	return (SI_SUCCESS);
1964
1965}
1966
1967/*
1968 * Deallocates the si_port_state_t.
1969 */
1970static void
1971si_dealloc_port_state(si_ctl_state_t *si_ctlp, int port)
1972{
1973	si_port_state_t *si_portp;
1974	si_portp = si_ctlp->sictl_ports[port];
1975
1976	mutex_enter(&si_portp->siport_mutex);
1977	kmem_free(si_portp->siport_event_args, sizeof (si_event_arg_t));
1978	si_dealloc_sgbpool(si_ctlp, port);
1979	si_dealloc_prbpool(si_ctlp, port);
1980	mutex_exit(&si_portp->siport_mutex);
1981
1982	mutex_destroy(&si_portp->siport_mutex);
1983
1984	kmem_free(si_ctlp->sictl_ports[port], sizeof (si_port_state_t));
1985
1986}
1987
1988/*
1989 * Allocates the SGB (Scatter Gather Block) incore buffer.
1990 */
1991static int
1992si_alloc_sgbpool(si_ctl_state_t *si_ctlp, int port)
1993{
1994	si_port_state_t *si_portp;
1995	uint_t cookie_count;
1996	size_t incore_sgbpool_size = SI_NUM_SLOTS * sizeof (si_sgblock_t)
1997	    * si_dma_sg_number;
1998	size_t ret_len;
1999	ddi_dma_cookie_t sgbpool_dma_cookie;
2000
2001	si_portp = si_ctlp->sictl_ports[port];
2002
2003	/* allocate sgbpool dma handle. */
2004	if (ddi_dma_alloc_handle(si_ctlp->sictl_devinfop,
2005	    &prb_sgt_dma_attr,
2006	    DDI_DMA_SLEEP,
2007	    NULL,
2008	    &si_portp->siport_sgbpool_dma_handle) !=
2009	    DDI_SUCCESS) {
2010
2011		return (SI_FAILURE);
2012	}
2013
2014	/* allocate the memory for sgbpool. */
2015	if (ddi_dma_mem_alloc(si_portp->siport_sgbpool_dma_handle,
2016	    incore_sgbpool_size,
2017	    &accattr,
2018	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2019	    DDI_DMA_SLEEP,
2020	    NULL,
2021	    (caddr_t *)&si_portp->siport_sgbpool,
2022	    &ret_len,
2023	    &si_portp->siport_sgbpool_acc_handle) != NULL) {
2024
2025		/*  error.. free the dma handle. */
2026		ddi_dma_free_handle(&si_portp->siport_sgbpool_dma_handle);
2027		return (SI_FAILURE);
2028	}
2029
2030	/* now bind it */
2031	if (ddi_dma_addr_bind_handle(si_portp->siport_sgbpool_dma_handle,
2032	    NULL,
2033	    (caddr_t)si_portp->siport_sgbpool,
2034	    incore_sgbpool_size,
2035	    DDI_DMA_CONSISTENT,
2036	    DDI_DMA_SLEEP,
2037	    NULL,
2038	    &sgbpool_dma_cookie,
2039	    &cookie_count) !=  DDI_DMA_MAPPED) {
2040		/*  error.. free the dma handle & free the memory. */
2041		ddi_dma_mem_free(&si_portp->siport_sgbpool_acc_handle);
2042		ddi_dma_free_handle(&si_portp->siport_sgbpool_dma_handle);
2043		return (SI_FAILURE);
2044	}
2045
2046	si_portp->siport_sgbpool_physaddr = sgbpool_dma_cookie.dmac_laddress;
2047	return (SI_SUCCESS);
2048}
2049
2050/*
2051 * Deallocates the SGB (Scatter Gather Block) incore buffer.
2052 */
2053static void
2054si_dealloc_sgbpool(si_ctl_state_t *si_ctlp, int port)
2055{
2056	si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
2057
2058	/* Unbind the dma handle first. */
2059	(void) ddi_dma_unbind_handle(si_portp->siport_sgbpool_dma_handle);
2060
2061	/* Then free the underlying memory. */
2062	ddi_dma_mem_free(&si_portp->siport_sgbpool_acc_handle);
2063
2064	/* Now free the handle itself. */
2065	ddi_dma_free_handle(&si_portp->siport_sgbpool_dma_handle);
2066
2067}
2068
2069/*
2070 * Allocates the PRB (Port Request Block) incore packets.
2071 */
2072static int
2073si_alloc_prbpool(si_ctl_state_t *si_ctlp, int port)
2074{
2075	si_port_state_t *si_portp;
2076	uint_t cookie_count;
2077	size_t incore_pkt_size = SI_NUM_SLOTS * sizeof (si_prb_t);
2078	size_t ret_len;
2079	ddi_dma_cookie_t prbpool_dma_cookie;
2080
2081	si_portp = si_ctlp->sictl_ports[port];
2082
2083	/* allocate prb pkts. */
2084	if (ddi_dma_alloc_handle(si_ctlp->sictl_devinfop,
2085	    &prb_sgt_dma_attr,
2086	    DDI_DMA_SLEEP,
2087	    NULL,
2088	    &si_portp->siport_prbpool_dma_handle) !=
2089	    DDI_SUCCESS) {
2090
2091		return (SI_FAILURE);
2092	}
2093
2094	if (ddi_dma_mem_alloc(si_portp->siport_prbpool_dma_handle,
2095	    incore_pkt_size,
2096	    &accattr,
2097	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2098	    DDI_DMA_SLEEP,
2099	    NULL,
2100	    (caddr_t *)&si_portp->siport_prbpool,
2101	    &ret_len,
2102	    &si_portp->siport_prbpool_acc_handle) != NULL) {
2103
2104		/* error.. free the dma handle. */
2105		ddi_dma_free_handle(&si_portp->siport_prbpool_dma_handle);
2106		return (SI_FAILURE);
2107	}
2108
2109	if (ddi_dma_addr_bind_handle(si_portp->siport_prbpool_dma_handle,
2110	    NULL,
2111	    (caddr_t)si_portp->siport_prbpool,
2112	    incore_pkt_size,
2113	    DDI_DMA_CONSISTENT,
2114	    DDI_DMA_SLEEP,
2115	    NULL,
2116	    &prbpool_dma_cookie,
2117	    &cookie_count) !=  DDI_DMA_MAPPED) {
2118		/*  error.. free the dma handle & free the memory. */
2119		ddi_dma_mem_free(&si_portp->siport_prbpool_acc_handle);
2120		ddi_dma_free_handle(&si_portp->siport_prbpool_dma_handle);
2121		return (SI_FAILURE);
2122	}
2123
2124	si_portp->siport_prbpool_physaddr =
2125	    prbpool_dma_cookie.dmac_laddress;
2126	return (SI_SUCCESS);
2127}
2128
2129/*
2130 * Deallocates the PRB (Port Request Block) incore packets.
2131 */
2132static void
2133si_dealloc_prbpool(si_ctl_state_t *si_ctlp, int port)
2134{
2135	si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
2136
2137	/* Unbind the prb dma handle first. */
2138	(void) ddi_dma_unbind_handle(si_portp->siport_prbpool_dma_handle);
2139
2140	/* Then free the underlying memory. */
2141	ddi_dma_mem_free(&si_portp->siport_prbpool_acc_handle);
2142
2143	/* Now free the handle itself. */
2144	ddi_dma_free_handle(&si_portp->siport_prbpool_dma_handle);
2145
2146}
2147
2148
2149
2150/*
2151 * Soft-reset the port to find the signature of the device connected to
2152 * the port.
2153 */
2154static void
2155si_find_dev_signature(
2156	si_ctl_state_t *si_ctlp,
2157	si_port_state_t *si_portp,
2158	int port,
2159	int pmp)
2160{
2161	si_prb_t *prb;
2162	uint32_t slot_status, signature;
2163	int slot, loop_count;
2164
2165	SIDBG_P(SIDBG_INIT, si_portp,
2166	    "si_find_dev_signature enter: port: %x, pmp: %x",
2167	    port, pmp);
2168
2169	/* Build a Soft Reset PRB in host memory. */
2170	mutex_enter(&si_portp->siport_mutex);
2171
2172	slot = si_claim_free_slot(si_ctlp, si_portp, port);
2173	if (slot == SI_FAILURE) {
2174		/* Empty slot could not be found. */
2175		if (pmp != PORTMULT_CONTROL_PORT) {
2176			/* We are behind port multiplier. */
2177			si_portp->siport_portmult_state.sipm_port_type[pmp] =
2178			    PORT_TYPE_NODEV;
2179		} else {
2180			si_portp->siport_port_type = PORT_TYPE_NODEV;
2181		}
2182
2183		mutex_exit(&si_portp->siport_mutex);
2184		return;
2185	}
2186	prb = &si_portp->siport_prbpool[slot];
2187	bzero((void *)prb, sizeof (si_prb_t));
2188
2189	SET_FIS_PMP(prb->prb_fis, pmp);
2190	SET_PRB_CONTROL_SOFT_RESET(prb);
2191
2192#if SI_DEBUG
2193	if (si_debug_flags & SIDBG_DUMP_PRB) {
2194		char *ptr;
2195		int j;
2196
2197		ptr = (char *)prb;
2198		cmn_err(CE_WARN, "si_find_dev_signature, prb: ");
2199		for (j = 0; j < (sizeof (si_prb_t)); j++) {
2200			if (j%4 == 0) {
2201				cmn_err(CE_WARN, "----");
2202			}
2203			cmn_err(CE_WARN, "%x ", ptr[j]);
2204		}
2205
2206	}
2207#endif /* SI_DEBUG */
2208
2209	/* deliver soft reset prb to empty slot. */
2210	POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
2211
2212	loop_count = 0;
2213	/* Loop till the soft reset is finished. */
2214	do {
2215		slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
2216		    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
2217
2218		if (loop_count++ > SI_POLLRATE_SOFT_RESET) {
2219			/* We are effectively timing out after 10 sec. */
2220			break;
2221		}
2222
2223		/* Wait for 10 millisec */
2224#ifndef __lock_lint
2225		delay(SI_10MS_TICKS);
2226#endif /* __lock_lint */
2227
2228	} while (slot_status & SI_SLOT_MASK & (0x1 << slot));
2229
2230	SIDBG_P(SIDBG_POLL_LOOP, si_portp,
2231	    "si_find_dev_signature: loop count: %d, slot_status: 0x%x",
2232	    loop_count, slot_status);
2233
2234	CLEAR_BIT(si_portp->siport_pending_tags, slot);
2235
2236	/* Read device signature from command slot. */
2237	signature = ddi_get32(si_ctlp->sictl_port_acc_handle,
2238	    (uint32_t *)(PORT_SIGNATURE_MSB(si_ctlp, port, slot)));
2239	signature <<= 8;
2240	signature |= (0xff & ddi_get32(si_ctlp->sictl_port_acc_handle,
2241	    (uint32_t *)(PORT_SIGNATURE_LSB(si_ctlp,
2242	    port, slot))));
2243
2244	SIDBG_P(SIDBG_INIT, si_portp, "Device signature: 0x%x", signature);
2245
2246	if (signature == SI_SIGNATURE_PORT_MULTIPLIER) {
2247
2248		SIDBG_P(SIDBG_INIT, si_portp,
2249		    "Found multiplier at cport: 0x%d, pmport: 0x%x",
2250		    port, pmp);
2251
2252		if (pmp != PORTMULT_CONTROL_PORT) {
2253			/*
2254			 * It is wrong to chain a port multiplier behind
2255			 * another port multiplier.
2256			 */
2257			si_portp->siport_portmult_state.sipm_port_type[pmp] =
2258			    PORT_TYPE_NODEV;
2259		} else {
2260			si_portp->siport_port_type = PORT_TYPE_MULTIPLIER;
2261			mutex_exit(&si_portp->siport_mutex);
2262			(void) si_enumerate_port_multiplier(si_ctlp,
2263			    si_portp, port);
2264			mutex_enter(&si_portp->siport_mutex);
2265		}
2266		si_init_port(si_ctlp, port);
2267
2268	} else if (signature == SI_SIGNATURE_ATAPI) {
2269		if (pmp != PORTMULT_CONTROL_PORT) {
2270			/* We are behind port multiplier. */
2271			si_portp->siport_portmult_state.sipm_port_type[pmp] =
2272			    PORT_TYPE_ATAPI;
2273		} else {
2274			si_portp->siport_port_type = PORT_TYPE_ATAPI;
2275			si_init_port(si_ctlp, port);
2276		}
2277		SIDBG_P(SIDBG_INIT, si_portp,
2278		    "Found atapi at : cport: %x, pmport: %x",
2279		    port, pmp);
2280
2281	} else if (signature == SI_SIGNATURE_DISK) {
2282
2283		if (pmp != PORTMULT_CONTROL_PORT) {
2284			/* We are behind port multiplier. */
2285			si_portp->siport_portmult_state.sipm_port_type[pmp] =
2286			    PORT_TYPE_DISK;
2287		} else {
2288			si_portp->siport_port_type = PORT_TYPE_DISK;
2289			si_init_port(si_ctlp, port);
2290		}
2291		SIDBG_P(SIDBG_INIT, si_portp,
2292		    "found disk at : cport: %x, pmport: %x",
2293		    port, pmp);
2294
2295	} else {
2296		if (pmp != PORTMULT_CONTROL_PORT) {
2297			/* We are behind port multiplier. */
2298			si_portp->siport_portmult_state.sipm_port_type[pmp] =
2299			    PORT_TYPE_UNKNOWN;
2300		} else {
2301			si_portp->siport_port_type = PORT_TYPE_UNKNOWN;
2302		}
2303		SIDBG_P(SIDBG_INIT, si_portp,
2304		    "Found unknown signature 0x%x at: port: %x, pmp: %x",
2305		    signature, port, pmp);
2306	}
2307
2308	mutex_exit(&si_portp->siport_mutex);
2309}
2310
2311
2312/*
2313 * Polls for the completion of the command. This is safe with both
2314 * interrupts enabled or disabled.
2315 */
2316static void
2317si_poll_cmd(
2318	si_ctl_state_t *si_ctlp,
2319	si_port_state_t *si_portp,
2320	int port,
2321	int slot,
2322	sata_pkt_t *satapkt)
2323{
2324	uint32_t slot_status;
2325	int pkt_timeout_ticks;
2326	uint32_t port_intr_status;
2327	int in_panic = ddi_in_panic();
2328
2329	SIDBG_P(SIDBG_ENTRY, si_portp, "si_poll_cmd entered: port: 0x%x", port);
2330
2331	pkt_timeout_ticks = drv_usectohz((clock_t)satapkt->satapkt_time *
2332	    1000000);
2333
2334
2335	/* we start out with SATA_PKT_COMPLETED as the satapkt_reason */
2336	satapkt->satapkt_reason = SATA_PKT_COMPLETED;
2337
2338	do {
2339		slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
2340		    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
2341
2342		if (slot_status & SI_SLOT_MASK & (0x1 << slot)) {
2343			if (in_panic) {
2344				/*
2345				 * If we are in panic, we can't rely on
2346				 * timers; so, busy wait instead of delay().
2347				 */
2348				mutex_exit(&si_portp->siport_mutex);
2349				drv_usecwait(SI_1MS_USECS);
2350				mutex_enter(&si_portp->siport_mutex);
2351			} else {
2352				mutex_exit(&si_portp->siport_mutex);
2353#ifndef __lock_lint
2354				delay(SI_1MS_TICKS);
2355#endif /* __lock_lint */
2356				mutex_enter(&si_portp->siport_mutex);
2357			}
2358		} else {
2359			break;
2360		}
2361
2362		pkt_timeout_ticks -= SI_1MS_TICKS;
2363
2364	} while (pkt_timeout_ticks > 0);
2365
2366	if (satapkt->satapkt_reason != SATA_PKT_COMPLETED) {
2367		/* The si_mop_command() got to our packet before us */
2368
2369		return;
2370	}
2371
2372	/*
2373	 * Interrupts and timers may not be working properly in a crash dump
2374	 * situation; we may need to handle all the three conditions here:
2375	 * successful completion, packet failure and packet timeout.
2376	 */
2377	if (IS_ATTENTION_RAISED(slot_status)) { /* error seen on port */
2378
2379		port_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
2380		    (uint32_t *)PORT_INTERRUPT_STATUS(si_ctlp, port));
2381
2382		SIDBG_P(SIDBG_VERBOSE, si_portp,
2383		    "si_poll_cmd: port_intr_status: 0x%x, port: %x",
2384		    port_intr_status, port);
2385
2386		if (port_intr_status & INTR_COMMAND_ERROR) {
2387			mutex_exit(&si_portp->siport_mutex);
2388			(void) si_intr_command_error(si_ctlp, si_portp, port);
2389			mutex_enter(&si_portp->siport_mutex);
2390
2391			return;
2392
2393			/*
2394			 * Why do we need to call si_intr_command_error() ?
2395			 *
2396			 * Answer: Even if the current packet is not the
2397			 * offending command, we need to restart the stalled
2398			 * port; (may be, the interrupts are not working well
2399			 * in panic condition). The call to routine
2400			 * si_intr_command_error() will achieve that.
2401			 *
2402			 * What if the interrupts are working fine and the
2403			 * si_intr_command_error() gets called once more from
2404			 * interrupt context ?
2405			 *
2406			 * Answer: The second instance of routine
2407			 * si_intr_command_error() will not mop anything
2408			 * since the first error handler has already blown
2409			 * away the hardware pending queues through reset.
2410			 *
2411			 * Will the si_intr_command_error() hurt current
2412			 * packet ?
2413			 *
2414			 * Answer: No.
2415			 */
2416		} else {
2417			/* Ignore any non-error interrupts at this stage */
2418			ddi_put32(si_ctlp->sictl_port_acc_handle,
2419			    (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp,
2420			    port)),
2421			    port_intr_status & INTR_MASK);
2422		}
2423
2424	} else if (slot_status & SI_SLOT_MASK & (0x1 << slot)) {
2425		satapkt->satapkt_reason = SATA_PKT_TIMEOUT;
2426
2427	} /* else: the command completed successfully */
2428
2429	if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
2430		si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp, port, slot);
2431	}
2432
2433	if ((satapkt->satapkt_cmd.satacmd_cmd_reg ==
2434	    SATAC_WRITE_FPDMA_QUEUED) ||
2435	    (satapkt->satapkt_cmd.satacmd_cmd_reg ==
2436	    SATAC_READ_FPDMA_QUEUED)) {
2437		si_portp->siport_pending_ncq_count--;
2438	}
2439
2440	CLEAR_BIT(si_portp->siport_pending_tags, slot);
2441
2442	/*
2443	 * tidbit: What is the interaction of abort with polling ?
2444	 * What happens if the current polled pkt is aborted in parallel ?
2445	 *
2446	 * Answer: Assuming that the si_mop_commands() completes ahead
2447	 * of polling, all it does is to set the satapkt_reason to
2448	 * SPKT_PKT_ABORTED. That would be fine with us.
2449	 *
2450	 * The same logic applies to reset interacting with polling.
2451	 */
2452}
2453
2454
2455/*
2456 * Searches for and claims a free slot.
2457 *
2458 * Returns: 	SI_FAILURE if no slots found
2459 *		claimed slot number if successful
2460 *
2461 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
2462 * before calling us.
2463 */
2464/*ARGSUSED*/
2465static int
2466si_claim_free_slot(si_ctl_state_t *si_ctlp, si_port_state_t *si_portp, int port)
2467{
2468	uint32_t free_slots;
2469	int slot;
2470
2471	_NOTE(ASSUMING_PROTECTED(si_portp))
2472
2473	SIDBG_P(SIDBG_ENTRY, si_portp,
2474	    "si_claim_free_slot entry: siport_pending_tags: %x",
2475	    si_portp->siport_pending_tags);
2476
2477	free_slots = (~si_portp->siport_pending_tags) & SI_SLOT_MASK;
2478	slot = ddi_ffs(free_slots) - 1;
2479	if (slot == -1) {
2480		SIDBG_P(SIDBG_VERBOSE, si_portp,
2481		    "si_claim_free_slot: no empty slots", NULL);
2482		return (SI_FAILURE);
2483	}
2484
2485	si_portp->siport_pending_tags |= (0x1 << slot);
2486	SIDBG_P(SIDBG_VERBOSE, si_portp, "si_claim_free_slot: found slot: 0x%x",
2487	    slot);
2488	return (slot);
2489}
2490
2491/*
2492 * Builds the PRB for the sata packet and delivers it to controller.
2493 *
2494 * Returns:
2495 *	slot number if we can obtain a slot successfully
2496 *	otherwise, return SI_FAILURE
2497 *
2498 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
2499 * before calling us.
2500 */
2501static int
2502si_deliver_satapkt(
2503	si_ctl_state_t *si_ctlp,
2504	si_port_state_t *si_portp,
2505	int port,
2506	sata_pkt_t *spkt)
2507{
2508	int slot;
2509	si_prb_t *prb;
2510	sata_cmd_t *cmd;
2511	si_sge_t *sgep; /* scatter gather entry pointer */
2512	si_sgt_t *sgtp; /* scatter gather table pointer */
2513	si_sgblock_t *sgbp; /* scatter gather block pointer */
2514	int i, j, cookie_index;
2515	int ncookies;
2516	int is_atapi = 0;
2517	ddi_dma_cookie_t cookie;
2518
2519	_NOTE(ASSUMING_PROTECTED(si_portp))
2520
2521	slot = si_claim_free_slot(si_ctlp, si_portp, port);
2522	if (slot == SI_FAILURE) {
2523		return (SI_FAILURE);
2524	}
2525
2526	if (spkt->satapkt_device.satadev_type == SATA_DTYPE_ATAPICD) {
2527		is_atapi = 1;
2528	}
2529
2530	if ((si_portp->siport_port_type == PORT_TYPE_NODEV) ||
2531	    !si_portp->siport_active) {
2532		/*
2533		 * si_intr_phy_ready_change() may have rendered it to
2534		 * PORT_TYPE_NODEV. cfgadm operation may have rendered
2535		 * it inactive.
2536		 */
2537		spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
2538		fill_dev_sregisters(si_ctlp, port, &spkt->satapkt_device);
2539		CLEAR_BIT(si_portp->siport_pending_tags, slot);
2540
2541		return (SI_FAILURE);
2542	}
2543
2544
2545	prb =  &(si_portp->siport_prbpool[slot]);
2546	bzero((void *)prb, sizeof (si_prb_t));
2547
2548	cmd = &spkt->satapkt_cmd;
2549
2550	SIDBG_P(SIDBG_ENTRY, si_portp,
2551	    "si_deliver_satpkt entry: cmd_reg: 0x%x, slot: 0x%x, \
2552		port: %x, satapkt: %x",
2553	    cmd->satacmd_cmd_reg, slot, port, (uint32_t)(intptr_t)spkt);
2554
2555	/* Now fill the prb. */
2556	if (is_atapi) {
2557		if (spkt->satapkt_cmd.satacmd_flags.sata_data_direction ==
2558		    SATA_DIR_READ) {
2559			SET_PRB_CONTROL_PKT_READ(prb);
2560		} else if (spkt->satapkt_cmd.satacmd_flags.sata_data_direction
2561		    == SATA_DIR_WRITE) {
2562			SET_PRB_CONTROL_PKT_WRITE(prb);
2563		}
2564	}
2565
2566	SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
2567	if ((spkt->satapkt_device.satadev_addr.qual == SATA_ADDR_PMPORT) ||
2568	    (spkt->satapkt_device.satadev_addr.qual == SATA_ADDR_DPMPORT)) {
2569		SET_FIS_PMP(prb->prb_fis,
2570		    spkt->satapkt_device.satadev_addr.pmport);
2571	}
2572	SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
2573	SET_FIS_COMMAND(prb->prb_fis, cmd->satacmd_cmd_reg);
2574	SET_FIS_FEATURES(prb->prb_fis, cmd->satacmd_features_reg);
2575	SET_FIS_SECTOR_COUNT(prb->prb_fis, cmd->satacmd_sec_count_lsb);
2576
2577	switch (cmd->satacmd_addr_type) {
2578
2579	case 0:
2580		/*
2581		 * satacmd_addr_type will be 0 for the commands below:
2582		 * 	SATAC_PACKET
2583		 * 	SATAC_IDLE_IM
2584		 * 	SATAC_STANDBY_IM
2585		 * 	SATAC_DOWNLOAD_MICROCODE
2586		 * 	SATAC_FLUSH_CACHE
2587		 * 	SATAC_SET_FEATURES
2588		 * 	SATAC_SMART
2589		 * 	SATAC_ID_PACKET_DEVICE
2590		 * 	SATAC_ID_DEVICE
2591		 * 	SATAC_READ_PORTMULT
2592		 * 	SATAC_WRITE_PORTMULT
2593		 */
2594		/* FALLTHRU */
2595
2596	case ATA_ADDR_LBA:
2597		/* FALLTHRU */
2598
2599	case ATA_ADDR_LBA28:
2600		/* LBA[7:0] */
2601		SET_FIS_SECTOR(prb->prb_fis, cmd->satacmd_lba_low_lsb);
2602
2603		/* LBA[15:8] */
2604		SET_FIS_CYL_LOW(prb->prb_fis, cmd->satacmd_lba_mid_lsb);
2605
2606		/* LBA[23:16] */
2607		SET_FIS_CYL_HI(prb->prb_fis, cmd->satacmd_lba_high_lsb);
2608
2609		/* LBA [27:24] (also called dev_head) */
2610		SET_FIS_DEV_HEAD(prb->prb_fis, cmd->satacmd_device_reg);
2611
2612		break;
2613
2614	case ATA_ADDR_LBA48:
2615		/* LBA[7:0] */
2616		SET_FIS_SECTOR(prb->prb_fis, cmd->satacmd_lba_low_lsb);
2617
2618		/* LBA[15:8] */
2619		SET_FIS_CYL_LOW(prb->prb_fis, cmd->satacmd_lba_mid_lsb);
2620
2621		/* LBA[23:16] */
2622		SET_FIS_CYL_HI(prb->prb_fis, cmd->satacmd_lba_high_lsb);
2623
2624		/* LBA [31:24] */
2625		SET_FIS_SECTOR_EXP(prb->prb_fis, cmd->satacmd_lba_low_msb);
2626
2627		/* LBA [39:32] */
2628		SET_FIS_CYL_LOW_EXP(prb->prb_fis, cmd->satacmd_lba_mid_msb);
2629
2630		/* LBA [47:40] */
2631		SET_FIS_CYL_HI_EXP(prb->prb_fis, cmd->satacmd_lba_high_msb);
2632
2633		/* Set dev_head */
2634		SET_FIS_DEV_HEAD(prb->prb_fis, cmd->satacmd_device_reg);
2635
2636		/* Set the extended sector count and features */
2637		SET_FIS_SECTOR_COUNT_EXP(prb->prb_fis,
2638		    cmd->satacmd_sec_count_msb);
2639		SET_FIS_FEATURES_EXP(prb->prb_fis,
2640		    cmd->satacmd_features_reg_ext);
2641
2642		break;
2643
2644	}
2645
2646	if (cmd->satacmd_flags.sata_queued) {
2647		/*
2648		 * For queued commands, the TAG for the sector count lsb is
2649		 * generated from current slot number.
2650		 */
2651		SET_FIS_SECTOR_COUNT(prb->prb_fis, slot << 3);
2652	}
2653
2654	if ((cmd->satacmd_cmd_reg == SATAC_WRITE_FPDMA_QUEUED) ||
2655	    (cmd->satacmd_cmd_reg == SATAC_READ_FPDMA_QUEUED)) {
2656		si_portp->siport_pending_ncq_count++;
2657	}
2658
2659	/* *** now fill the scatter gather list ******* */
2660
2661	if (is_atapi) { /* It is an ATAPI drive */
2662		/* atapi command goes into sge0 */
2663		bcopy(cmd->satacmd_acdb, &prb->prb_sge0, sizeof (si_sge_t));
2664
2665		/* Now fill sge1 with pointer to external SGT. */
2666		if (spkt->satapkt_cmd.satacmd_num_dma_cookies) {
2667			prb->prb_sge1.sge_addr =
2668			    si_portp->siport_sgbpool_physaddr +
2669			    slot * sizeof (si_sgblock_t) * si_dma_sg_number;
2670			SET_SGE_LNK(prb->prb_sge1);
2671		} else {
2672			SET_SGE_TRM(prb->prb_sge1);
2673		}
2674	} else {
2675		/* Fill the sge0 */
2676		if (spkt->satapkt_cmd.satacmd_num_dma_cookies) {
2677			prb->prb_sge0.sge_addr =
2678			    si_portp->siport_sgbpool_physaddr +
2679			    slot * sizeof (si_sgblock_t) * si_dma_sg_number;
2680			SET_SGE_LNK(prb->prb_sge0);
2681
2682		} else {
2683			SET_SGE_TRM(prb->prb_sge0);
2684		}
2685
2686		/* sge1 is left empty in non-ATAPI case */
2687	}
2688
2689	bzero(&si_portp->siport_sgbpool[slot * si_dma_sg_number],
2690	    sizeof (si_sgblock_t) * si_dma_sg_number);
2691
2692	ncookies = spkt->satapkt_cmd.satacmd_num_dma_cookies;
2693	ASSERT(ncookies <= (SGE_LENGTH(si_dma_sg_number)));
2694
2695	SIDBG_P(SIDBG_COOKIES, si_portp, "total ncookies: %d", ncookies);
2696	if (ncookies == 0) {
2697		sgbp = &si_portp->siport_sgbpool[slot * si_dma_sg_number];
2698		sgtp = &sgbp->sgb_sgt[0];
2699		sgep = &sgtp->sgt_sge[0];
2700
2701		/* No cookies. Terminate the chain. */
2702		SIDBG_P(SIDBG_COOKIES, si_portp, "empty cookies: terminating.",
2703		    NULL);
2704
2705		sgep->sge_addr_low = 0;
2706		sgep->sge_addr_high = 0;
2707		sgep->sge_data_count = 0;
2708		SET_SGE_TRM((*sgep));
2709
2710		goto sgl_fill_done;
2711	}
2712
2713	for (i = 0, cookie_index = 0,
2714	    sgbp = &si_portp->siport_sgbpool[slot * si_dma_sg_number];
2715	    i < si_dma_sg_number; i++) {
2716
2717		sgtp = &sgbp->sgb_sgt[0] + i;
2718
2719		/* Now fill the first 3 entries of SGT in the loop below. */
2720		for (j = 0, sgep = &sgtp->sgt_sge[0];
2721		    ((j < 3) && (cookie_index < ncookies-1));
2722		    j++, cookie_index++, sgep++)  {
2723			ASSERT(cookie_index < ncookies);
2724			SIDBG_P(SIDBG_COOKIES, si_portp,
2725			    "inner loop: cookie_index: %d, ncookies: %d",
2726			    cookie_index,
2727			    ncookies);
2728			cookie = spkt->satapkt_cmd.
2729			    satacmd_dma_cookie_list[cookie_index];
2730
2731			sgep->sge_addr_low = cookie._dmu._dmac_la[0];
2732			sgep->sge_addr_high = cookie._dmu._dmac_la[1];
2733			sgep->sge_data_count = (uint32_t)cookie.dmac_size;
2734		}
2735
2736		/*
2737		 * If this happens to be the last cookie, we terminate it here.
2738		 * Otherwise, we link to next SGT.
2739		 */
2740
2741		if (cookie_index == ncookies-1) {
2742			/* This is the last cookie. Terminate the chain. */
2743			SIDBG_P(SIDBG_COOKIES, si_portp,
2744			    "filling the last: cookie_index: %d, "
2745			    "ncookies: %d",
2746			    cookie_index,
2747			    ncookies);
2748			cookie = spkt->satapkt_cmd.
2749			    satacmd_dma_cookie_list[cookie_index];
2750
2751			sgep->sge_addr_low = cookie._dmu._dmac_la[0];
2752			sgep->sge_addr_high = cookie._dmu._dmac_la[1];
2753			sgep->sge_data_count = (uint32_t)cookie.dmac_size;
2754			SET_SGE_TRM((*sgep));
2755
2756			break; /* we break the loop */
2757
2758		} else {
2759			/* This is not the last one. So link it. */
2760			SIDBG_P(SIDBG_COOKIES, si_portp,
2761			    "linking SGT: cookie_index: %d, ncookies: %d",
2762			    cookie_index,
2763			    ncookies);
2764			sgep->sge_addr = si_portp->siport_sgbpool_physaddr +
2765			    slot * sizeof (si_sgblock_t) * si_dma_sg_number +
2766			    (i+1) * sizeof (si_sgt_t);
2767
2768			SET_SGE_LNK((*sgep));
2769		}
2770
2771	}
2772
2773	/* *** finished filling the scatter gather list ******* */
2774
2775sgl_fill_done:
2776	/* Now remember the sata packet in siport_slot_pkts[]. */
2777	si_portp->siport_slot_pkts[slot] = spkt;
2778
2779	/*
2780	 * We are overloading satapkt_hba_driver_private with
2781	 * watched_cycle count.
2782	 */
2783	spkt->satapkt_hba_driver_private = (void *)(intptr_t)0;
2784
2785	if (is_atapi) {
2786		/* program the packet_lenth if it is atapi device. */
2787
2788
2789#ifdef ATAPI_2nd_PHASE
2790		/*
2791		 * Framework needs to calculate the acdb_len based on
2792		 * identify packet data. This needs to be accomplished
2793		 * in second phase of the project.
2794		 */
2795		ASSERT((cmd->satacmd_acdb_len == 12) ||
2796		    (cmd->satacmd_acdb_len == 16));
2797		SIDBG_P(SIDBG_VERBOSE, si_portp, "deliver: acdb_len: %d",
2798		    cmd->satacmd_acdb_len);
2799
2800		if (cmd->satacmd_acdb_len == 16) {
2801			ddi_put32(si_ctlp->sictl_port_acc_handle,
2802			    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
2803			    PORT_CONTROL_SET_BITS_PACKET_LEN);
2804		} else {
2805			ddi_put32(si_ctlp->sictl_port_acc_handle,
2806			    (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
2807			    PORT_CONTROL_CLEAR_BITS_PACKET_LEN);
2808		}
2809
2810#else /* ATAPI_2nd_PHASE */
2811		/* hard coding for now to 12 bytes */
2812		ddi_put32(si_ctlp->sictl_port_acc_handle,
2813		    (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
2814		    PORT_CONTROL_CLEAR_BITS_PACKET_LEN);
2815#endif /* ATAPI_2nd_PHASE */
2816	}
2817
2818
2819#if SI_DEBUG
2820	if (si_debug_flags & SIDBG_DUMP_PRB) {
2821		if (!(is_atapi && (prb->prb_sge0.sge_addr_low == 0))) {
2822			/*
2823			 * Do not dump the atapi Test-Unit-Ready commands.
2824			 * The sd_media_watch spews too many of these.
2825			 */
2826			int *ptr;
2827			si_sge_t *tmpsgep;
2828			int j;
2829
2830			ptr = (int *)(void *)prb;
2831			cmn_err(CE_WARN, "si_deliver_satpkt prb: ");
2832			for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
2833				cmn_err(CE_WARN, "%x ", ptr[j]);
2834			}
2835
2836			cmn_err(CE_WARN,
2837			    "si_deliver_satpkt sgt: low, high, count link");
2838			for (j = 0,
2839			    tmpsgep = (si_sge_t *)
2840			    &si_portp->siport_sgbpool[slot * si_dma_sg_number];
2841			    j < (sizeof (si_sgblock_t)/ sizeof (si_sge_t))
2842			    *si_dma_sg_number;
2843			    j++, tmpsgep++) {
2844				ptr = (int *)(void *)tmpsgep;
2845				cmn_err(CE_WARN, "%x %x %x %x",
2846				    ptr[0],
2847				    ptr[1],
2848				    ptr[2],
2849				    ptr[3]);
2850				if (IS_SGE_TRM_SET((*tmpsgep))) {
2851					break;
2852				}
2853
2854			}
2855		}
2856
2857	}
2858#endif  /* SI_DEBUG */
2859
2860	/* Deliver PRB */
2861	POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
2862
2863	return (slot);
2864}
2865
2866/*
2867 * Initialize the controller and set up driver data structures.
2868 *
2869 * This routine can be called from three separate cases: DDI_ATTACH, PM_LEVEL_D0
2870 * and DDI_RESUME. The DDI_ATTACH case is different from other two cases; the
2871 * memory allocation & device signature probing are attempted only during
2872 * DDI_ATTACH case. In the case of PM_LEVEL_D0 & DDI_RESUME, we are starting
2873 * from a previously initialized state; so there is no need to allocate memory
2874 * or to attempt probing the device signatures.
2875 */
2876static int
2877si_initialize_controller(si_ctl_state_t *si_ctlp)
2878{
2879	uint32_t port_status;
2880	uint32_t SStatus;
2881	uint32_t SControl;
2882	uint8_t port;
2883	int loop_count = 0;
2884	si_port_state_t *si_portp;
2885
2886	SIDBG_C(SIDBG_INIT, si_ctlp,
2887	    "si3124: si_initialize_controller entered", NULL);
2888
2889	mutex_enter(&si_ctlp->sictl_mutex);
2890
2891	/* Remove the Global Reset. */
2892	ddi_put32(si_ctlp->sictl_global_acc_handle,
2893	    (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp),
2894	    GLOBAL_CONTROL_REG_BITS_CLEAR);
2895
2896	for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
2897
2898		if (si_ctlp->sictl_flags & SI_ATTACH) {
2899			/*
2900			 * We allocate the port state only during attach
2901			 * sequence. We don't want to do it during
2902			 * suspend/resume sequence.
2903			 */
2904			if (si_alloc_port_state(si_ctlp, port)) {
2905				mutex_exit(&si_ctlp->sictl_mutex);
2906				return (SI_FAILURE);
2907			}
2908		}
2909
2910		si_portp = si_ctlp->sictl_ports[port];
2911		mutex_enter(&si_portp->siport_mutex);
2912		si_portp->siport_ctlp = si_ctlp;
2913		si_portp->siport_port_num = port;
2914
2915		/* Clear Port Reset. */
2916		ddi_put32(si_ctlp->sictl_port_acc_handle,
2917		    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
2918		    PORT_CONTROL_SET_BITS_PORT_RESET);
2919		ddi_put32(si_ctlp->sictl_port_acc_handle,
2920		    (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
2921		    PORT_CONTROL_CLEAR_BITS_PORT_RESET);
2922
2923		/*
2924		 * Arm the interrupts for: Cmd completion, Cmd error,
2925		 * Port Ready, PM Change, PhyRdyChange, Commwake,
2926		 * UnrecFIS, Devxchanged, SDBNotify.
2927		 */
2928		ddi_put32(si_ctlp->sictl_port_acc_handle,
2929		    (uint32_t *)PORT_INTERRUPT_ENABLE_SET(si_ctlp, port),
2930		    (INTR_COMMAND_COMPLETE |
2931		    INTR_COMMAND_ERROR |
2932		    INTR_PORT_READY |
2933		    INTR_POWER_CHANGE |
2934		    INTR_PHYRDY_CHANGE |
2935		    INTR_COMWAKE_RECEIVED |
2936		    INTR_UNRECOG_FIS |
2937		    INTR_DEV_XCHANGED |
2938		    INTR_SETDEVBITS_NOTIFY));
2939
2940		/* Now enable the interrupts. */
2941		si_enable_port_interrupts(si_ctlp, port);
2942
2943		/*
2944		 * The following PHY initialization is redundant in
2945		 * in x86 since the BIOS anyway does this as part of
2946		 * device enumeration during the power up. But this
2947		 * is a required step in sparc since there is no BIOS.
2948		 *
2949		 * The way to initialize the PHY is to write a 1 and then
2950		 * a 0 to DET field of SControl register.
2951		 */
2952
2953		/*
2954		 * Fetch the current SControl before writing the
2955		 * DET part with 1
2956		 */
2957		SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
2958		    (uint32_t *)PORT_SCONTROL(si_ctlp, port));
2959		SCONTROL_SET_DET(SControl, SCONTROL_DET_COMRESET);
2960		ddi_put32(si_ctlp->sictl_port_acc_handle,
2961		    (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
2962		    SControl);
2963#ifndef __lock_lint
2964		delay(SI_10MS_TICKS); /* give time for COMRESET to percolate */
2965#endif /* __lock_lint */
2966
2967		/*
2968		 * Now fetch the SControl again and rewrite the
2969		 * DET part with 0
2970		 */
2971		SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
2972		    (uint32_t *)PORT_SCONTROL(si_ctlp, port));
2973		SCONTROL_SET_DET(SControl, SCONTROL_DET_NOACTION);
2974		ddi_put32(si_ctlp->sictl_port_acc_handle,
2975		    (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
2976		    SControl);
2977
2978		/*
2979		 * PHY may be initialized by now. Check the DET field of
2980		 * SStatus to determine if there is a device present.
2981		 *
2982		 * The DET field is valid only if IPM field indicates that
2983		 * the interface is in active state.
2984		 */
2985
2986		loop_count = 0;
2987		do {
2988			SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
2989			    (uint32_t *)PORT_SSTATUS(si_ctlp, port));
2990
2991			if (SSTATUS_GET_IPM(SStatus) !=
2992			    SSTATUS_IPM_INTERFACE_ACTIVE) {
2993				/*
2994				 * If the interface is not active, the DET field
2995				 * is considered not accurate. So we want to
2996				 * continue looping.
2997				 */
2998				SSTATUS_SET_DET(SStatus,
2999				    SSTATUS_DET_NODEV_NOPHY);
3000			}
3001
3002			if (loop_count++ > SI_POLLRATE_SSTATUS) {
3003				/*
3004				 * We are effectively timing out after 0.1 sec.
3005				 */
3006				break;
3007			}
3008
3009			/* Wait for 10 millisec */
3010#ifndef __lock_lint
3011			delay(SI_10MS_TICKS);
3012#endif /* __lock_lint */
3013
3014		} while (SSTATUS_GET_DET(SStatus) !=
3015		    SSTATUS_DET_DEVPRESENT_PHYONLINE);
3016
3017		SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3018		    "si_initialize_controller: 1st loop count: %d, "
3019		    "SStatus: 0x%x",
3020		    loop_count,
3021		    SStatus);
3022
3023		if ((SSTATUS_GET_IPM(SStatus) !=
3024		    SSTATUS_IPM_INTERFACE_ACTIVE) ||
3025		    (SSTATUS_GET_DET(SStatus) !=
3026		    SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
3027			/*
3028			 * Either the port is not active or there
3029			 * is no device present.
3030			 */
3031			si_ctlp->sictl_ports[port]->siport_port_type =
3032			    PORT_TYPE_NODEV;
3033			mutex_exit(&si_portp->siport_mutex);
3034			continue;
3035		}
3036
3037		/* Wait until Port Ready */
3038		loop_count = 0;
3039		do {
3040			port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3041			    (uint32_t *)PORT_STATUS(si_ctlp, port));
3042
3043			if (loop_count++ > SI_POLLRATE_PORTREADY) {
3044				/*
3045				 * We are effectively timing out after 0.5 sec.
3046				 */
3047				break;
3048			}
3049
3050			/* Wait for 10 millisec */
3051#ifndef __lock_lint
3052			delay(SI_10MS_TICKS);
3053#endif /* __lock_lint */
3054
3055		} while (!(port_status & PORT_STATUS_BITS_PORT_READY));
3056
3057		SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3058		    "si_initialize_controller: 2nd loop count: %d",
3059		    loop_count);
3060
3061		if (si_ctlp->sictl_flags & SI_ATTACH) {
3062			/*
3063			 * We want to probe for dev signature only during attach
3064			 * case. Don't do it during suspend/resume sequence.
3065			 */
3066			if (port_status & PORT_STATUS_BITS_PORT_READY) {
3067				mutex_exit(&si_portp->siport_mutex);
3068				si_find_dev_signature(si_ctlp, si_portp, port,
3069				    PORTMULT_CONTROL_PORT);
3070				mutex_enter(&si_portp->siport_mutex);
3071			} else {
3072				si_ctlp->sictl_ports[port]->siport_port_type =
3073				    PORT_TYPE_NODEV;
3074			}
3075		}
3076
3077		if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
3078		    si_check_port_handles(si_portp) != DDI_SUCCESS) {
3079			ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3080			    DDI_SERVICE_LOST);
3081			mutex_exit(&si_portp->siport_mutex);
3082			mutex_exit(&si_ctlp->sictl_mutex);
3083			return (SI_FAILURE);
3084		}
3085
3086		mutex_exit(&si_portp->siport_mutex);
3087	}
3088
3089	mutex_exit(&si_ctlp->sictl_mutex);
3090	return (SI_SUCCESS);
3091}
3092
3093/*
3094 * Reverse of si_initialize_controller().
3095 *
3096 * WARNING, WARNING: The caller is expected to obtain the sictl_mutex
3097 * before calling us.
3098 */
3099static void
3100si_deinitialize_controller(si_ctl_state_t *si_ctlp)
3101{
3102	int port;
3103
3104	_NOTE(ASSUMING_PROTECTED(si_ctlp))
3105
3106	SIDBG_C(SIDBG_INIT, si_ctlp,
3107	    "si3124: si_deinitialize_controller entered", NULL);
3108
3109	/* disable all the interrupts. */
3110	si_disable_all_interrupts(si_ctlp);
3111
3112	if (si_ctlp->sictl_flags & SI_DETACH) {
3113		/*
3114		 * We want to dealloc all the memory in detach case.
3115		 */
3116		for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
3117			si_dealloc_port_state(si_ctlp, port);
3118		}
3119	}
3120
3121}
3122
3123/*
3124 * Prepare the port ready for usage.
3125 *
3126 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
3127 * before calling us.
3128 */
3129static void
3130si_init_port(si_ctl_state_t *si_ctlp, int port)
3131{
3132
3133	SIDBG_C(SIDBG_INIT, si_ctlp,
3134	    "si_init_port entered: port: 0x%x",
3135	    port);
3136
3137	/* Initialize the port. */
3138	ddi_put32(si_ctlp->sictl_port_acc_handle,
3139	    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
3140	    PORT_CONTROL_SET_BITS_PORT_INITIALIZE);
3141
3142	/*
3143	 * Clear the InterruptNCOR (Interrupt No Clear on Read).
3144	 * This step ensures that a mere reading of slot_status will clear
3145	 * the interrupt; no explicit clearing of interrupt condition
3146	 * will be needed for successful completion of commands.
3147	 */
3148	ddi_put32(si_ctlp->sictl_port_acc_handle,
3149	    (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
3150	    PORT_CONTROL_CLEAR_BITS_INTR_NCoR);
3151
3152	/* clear any pending interrupts at this point */
3153	ddi_put32(si_ctlp->sictl_port_acc_handle,
3154	    (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp, port)),
3155	    INTR_MASK);
3156
3157}
3158
3159
3160/*
3161 * Enumerate the devices connected to the port multiplier.
3162 * Once a device is detected, we call si_find_dev_signature()
3163 * to find the type of device connected. Even though we are
3164 * called from within si_find_dev_signature(), there is no
3165 * recursion possible.
3166 */
3167static int
3168si_enumerate_port_multiplier(
3169	si_ctl_state_t *si_ctlp,
3170	si_port_state_t *si_portp,
3171	int port)
3172{
3173	uint32_t num_dev_ports = 0;
3174	int pmport;
3175	uint32_t SControl = 0;
3176	uint32_t SStatus = 0;
3177	uint32_t SError = 0;
3178	int loop_count = 0;
3179
3180	SIDBG_P(SIDBG_INIT, si_portp,
3181	    "si_enumerate_port_multiplier entered: port: %d",
3182	    port);
3183
3184	mutex_enter(&si_portp->siport_mutex);
3185
3186	/* Enable Port Multiplier context switching. */
3187	ddi_put32(si_ctlp->sictl_port_acc_handle,
3188	    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
3189	    PORT_CONTROL_SET_BITS_PM_ENABLE);
3190
3191	/*
3192	 * Read the num dev ports connected.
3193	 * GSCR[2] contains the number of device ports.
3194	 */
3195	if (si_read_portmult_reg(si_ctlp, si_portp, port, PORTMULT_CONTROL_PORT,
3196	    PSCR_REG2, &num_dev_ports)) {
3197		mutex_exit(&si_portp->siport_mutex);
3198		return (SI_FAILURE);
3199	}
3200	si_portp->siport_portmult_state.sipm_num_ports = num_dev_ports;
3201
3202	SIDBG_P(SIDBG_INIT, si_portp,
3203	    "si_enumerate_port_multiplier: ports found: %d",
3204	    num_dev_ports);
3205
3206	for (pmport = 0; pmport < num_dev_ports-1; pmport++) {
3207		/*
3208		 * Enable PHY by writing a 1, then a 0 to SControl
3209		 * (i.e. PSCR[2]) DET field.
3210		 */
3211		if (si_read_portmult_reg(si_ctlp, si_portp, port, pmport,
3212		    PSCR_REG2, &SControl)) {
3213			continue;
3214		}
3215
3216		/* First write a 1 to DET field of SControl. */
3217		SCONTROL_SET_DET(SControl, SCONTROL_DET_COMRESET);
3218		if (si_write_portmult_reg(si_ctlp, si_portp, port, pmport,
3219		    PSCR_REG2, SControl)) {
3220			continue;
3221		}
3222#ifndef __lock_lint
3223		delay(SI_10MS_TICKS); /* give time for COMRESET to percolate */
3224#endif /* __lock_lint */
3225
3226		/* Then write a 0 to the DET field of SControl. */
3227		SCONTROL_SET_DET(SControl, SCONTROL_DET_NOACTION);
3228		if (si_write_portmult_reg(si_ctlp, si_portp, port, pmport,
3229		    PSCR_REG2, SControl)) {
3230			continue;
3231		}
3232
3233		/* Wait for PHYRDY by polling SStatus (i.e. PSCR[0]). */
3234		loop_count = 0;
3235		do {
3236			if (si_read_portmult_reg(si_ctlp, si_portp, port,
3237			    pmport, PSCR_REG0, &SStatus)) {
3238				break;
3239			}
3240			SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3241			    "looping for PHYRDY: SStatus: %x",
3242			    SStatus);
3243
3244			if (SSTATUS_GET_IPM(SStatus) !=
3245			    SSTATUS_IPM_INTERFACE_ACTIVE) {
3246				/*
3247				 * If the interface is not active, the DET field
3248				 * is considered not accurate. So we want to
3249				 * continue looping.
3250				 */
3251				SSTATUS_SET_DET(SStatus,
3252				    SSTATUS_DET_NODEV_NOPHY);
3253			}
3254
3255			if (loop_count++ > SI_POLLRATE_SSTATUS) {
3256				/*
3257				 * We are effectively timing out after 0.1 sec.
3258				 */
3259				break;
3260			}
3261
3262			/* Wait for 10 millisec */
3263#ifndef __lock_lint
3264			delay(SI_10MS_TICKS);
3265#endif /* __lock_lint */
3266
3267		} while (SSTATUS_GET_DET(SStatus) !=
3268		    SSTATUS_DET_DEVPRESENT_PHYONLINE);
3269
3270		SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3271		    "si_enumerate_port_multiplier: "
3272		    "loop count: %d, SStatus: 0x%x",
3273		    loop_count,
3274		    SStatus);
3275
3276		if ((SSTATUS_GET_IPM(SStatus) ==
3277		    SSTATUS_IPM_INTERFACE_ACTIVE) &&
3278		    (SSTATUS_GET_DET(SStatus) ==
3279		    SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
3280			/* The interface is active and the device is present */
3281			SIDBG_P(SIDBG_INIT, si_portp,
3282			    "Status: %x, device exists",
3283			    SStatus);
3284			/*
3285			 * Clear error bits in SError register (i.e. PSCR[1]
3286			 * by writing back error bits.
3287			 */
3288			if (si_read_portmult_reg(si_ctlp, si_portp, port,
3289			    pmport, PSCR_REG1, &SError)) {
3290				continue;
3291			}
3292			SIDBG_P(SIDBG_INIT, si_portp,
3293			    "SError bits are: %x", SError);
3294			if (si_write_portmult_reg(si_ctlp, si_portp, port,
3295			    pmport, PSCR_REG1, SError)) {
3296				continue;
3297			}
3298
3299			/* There exists a device. */
3300			mutex_exit(&si_portp->siport_mutex);
3301			si_find_dev_signature(si_ctlp, si_portp, port, pmport);
3302			mutex_enter(&si_portp->siport_mutex);
3303		}
3304	}
3305
3306	mutex_exit(&si_portp->siport_mutex);
3307
3308	return (SI_SUCCESS);
3309}
3310
3311
3312/*
3313 * Read a port multiplier register.
3314 *
3315 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
3316 * before calling us.
3317 */
3318static int
3319si_read_portmult_reg(
3320	si_ctl_state_t *si_ctlp,
3321	si_port_state_t *si_portp,
3322	int port,
3323	int pmport,
3324	int regnum,
3325	uint32_t *regval)
3326{
3327	int slot;
3328	si_prb_t *prb;
3329	uint32_t *prb_word_ptr;
3330	int i;
3331	uint32_t slot_status;
3332	int loop_count = 0;
3333
3334	_NOTE(ASSUMING_PROTECTED(si_portp))
3335
3336	SIDBG_P(SIDBG_ENTRY, si_portp, "si_read_portmult_reg: port: %x,"
3337	    "pmport: %x, regnum: %x",
3338	    port, pmport, regnum);
3339
3340	slot = si_claim_free_slot(si_ctlp, si_portp, port);
3341	if (slot == SI_FAILURE) {
3342		return (SI_FAILURE);
3343	}
3344
3345	prb =  &(si_portp->siport_prbpool[slot]);
3346	bzero((void *)prb, sizeof (si_prb_t));
3347
3348	/* Now fill the prb. */
3349	SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
3350	SET_FIS_PMP(prb->prb_fis, PORTMULT_CONTROL_PORT);
3351	SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
3352	SET_FIS_COMMAND(prb->prb_fis, SATAC_READ_PM_REG);
3353
3354	SET_FIS_DEV_HEAD(prb->prb_fis, pmport);
3355	SET_FIS_FEATURES(prb->prb_fis, regnum);
3356
3357	/* no real data transfer is involved. */
3358	SET_SGE_TRM(prb->prb_sge0);
3359
3360#if SI_DEBUG
3361	if (si_debug_flags & SIDBG_DUMP_PRB) {
3362		int *ptr;
3363		int j;
3364
3365		ptr = (int *)(void *)prb;
3366		cmn_err(CE_WARN, "read_port_mult_reg, prb: ");
3367		for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
3368			cmn_err(CE_WARN, "%x ", ptr[j]);
3369		}
3370
3371	}
3372#endif /* SI_DEBUG */
3373
3374	/* Deliver PRB */
3375	POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
3376
3377	/* Loop till the command is finished. */
3378	do {
3379		slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3380		    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3381
3382		SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3383		    "looping read_pm slot_status: 0x%x",
3384		    slot_status);
3385
3386		if (loop_count++ > SI_POLLRATE_SLOTSTATUS) {
3387			/* We are effectively timing out after 0.5 sec. */
3388			break;
3389		}
3390
3391		/* Wait for 10 millisec */
3392#ifndef __lock_lint
3393		delay(SI_10MS_TICKS);
3394#endif /* __lock_lint */
3395
3396	} while (slot_status & SI_SLOT_MASK & (0x1 << slot));
3397
3398	SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3399	    "read_portmult_reg: loop count: %d",
3400	    loop_count);
3401
3402	CLEAR_BIT(si_portp->siport_pending_tags, slot);
3403
3404	/* Now inspect the port LRAM for the modified FIS. */
3405	prb_word_ptr = (uint32_t *)(void *)prb;
3406	for (i = 0; i < (sizeof (si_prb_t)/4); i++) {
3407		prb_word_ptr[i] = ddi_get32(si_ctlp->sictl_port_acc_handle,
3408		    (uint32_t *)(PORT_LRAM(si_ctlp, port, slot)+i*4));
3409	}
3410
3411	if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
3412	    si_check_port_handles(si_portp) != DDI_SUCCESS) {
3413		ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3414		    DDI_SERVICE_UNAFFECTED);
3415		return (SI_FAILURE);
3416	}
3417
3418	if (((GET_FIS_COMMAND(prb->prb_fis) & 0x1) != 0) ||
3419	    (GET_FIS_FEATURES(prb->prb_fis) != 0)) {
3420		/* command failed. */
3421		return (SI_FAILURE);
3422	}
3423
3424	/* command succeeded. */
3425	*regval = (GET_FIS_SECTOR_COUNT(prb->prb_fis) & 0xff) |
3426	    ((GET_FIS_SECTOR(prb->prb_fis) << 8)  & 0xff00) |
3427	    ((GET_FIS_CYL_LOW(prb->prb_fis) << 16)  & 0xff0000) |
3428	    ((GET_FIS_CYL_HI(prb->prb_fis) << 24)  & 0xff000000);
3429
3430	return (SI_SUCCESS);
3431}
3432
3433/*
3434 * Write a port multiplier register.
3435 *
3436 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
3437 * before calling us.
3438 */
3439static int
3440si_write_portmult_reg(
3441	si_ctl_state_t *si_ctlp,
3442	si_port_state_t *si_portp,
3443	int port,
3444	int pmport,
3445	int regnum,
3446	uint32_t regval)
3447{
3448	int slot;
3449	si_prb_t *prb;
3450	uint32_t *prb_word_ptr;
3451	uint32_t slot_status;
3452	int i;
3453	int loop_count = 0;
3454
3455	_NOTE(ASSUMING_PROTECTED(si_portp))
3456
3457	SIDBG_P(SIDBG_ENTRY, si_portp,
3458	    "si_write_portmult_reg: port: %x, pmport: %x,"
3459	    "regnum: %x, regval: %x",
3460	    port, pmport, regnum, regval);
3461
3462	slot = si_claim_free_slot(si_ctlp, si_portp, port);
3463	if (slot == SI_FAILURE) {
3464		return (SI_FAILURE);
3465	}
3466
3467	prb =  &(si_portp->siport_prbpool[slot]);
3468	bzero((void *)prb, sizeof (si_prb_t));
3469
3470	/* Now fill the prb. */
3471	SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
3472	SET_FIS_PMP(prb->prb_fis, PORTMULT_CONTROL_PORT);
3473	SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
3474
3475	SET_FIS_COMMAND(prb->prb_fis, SATAC_WRITE_PM_REG);
3476	SET_FIS_DEV_HEAD(prb->prb_fis, pmport);
3477	SET_FIS_FEATURES(prb->prb_fis, regnum);
3478
3479	SET_FIS_SECTOR_COUNT(prb->prb_fis, regval & 0xff);
3480	SET_FIS_SECTOR(prb->prb_fis, (regval >> 8) & 0xff);
3481	SET_FIS_CYL_LOW(prb->prb_fis, (regval >> 16) & 0xff);
3482	SET_FIS_CYL_HI(prb->prb_fis, (regval >> 24)  & 0xff);
3483
3484	/* no real data transfer is involved. */
3485	SET_SGE_TRM(prb->prb_sge0);
3486
3487#if SI_DEBUG
3488	if (si_debug_flags & SIDBG_DUMP_PRB) {
3489		int *ptr;
3490		int j;
3491
3492		ptr = (int *)(void *)prb;
3493		cmn_err(CE_WARN, "read_port_mult_reg, prb: ");
3494		for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
3495			cmn_err(CE_WARN, "%x ", ptr[j]);
3496		}
3497
3498	}
3499#endif /* SI_DEBUG */
3500
3501	/* Deliver PRB */
3502	POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
3503
3504	/* Loop till the command is finished. */
3505	do {
3506		slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3507		    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3508
3509		SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3510		    "looping write_pmp slot_status: 0x%x",
3511		    slot_status);
3512
3513		if (loop_count++ > SI_POLLRATE_SLOTSTATUS) {
3514			/* We are effectively timing out after 0.5 sec. */
3515			break;
3516		}
3517
3518		/* Wait for 10 millisec */
3519#ifndef __lock_lint
3520		delay(SI_10MS_TICKS);
3521#endif /* __lock_lint */
3522
3523	} while (slot_status & SI_SLOT_MASK & (0x1 << slot));
3524
3525	SIDBG_P(SIDBG_POLL_LOOP, si_portp,
3526	    "write_portmult_reg: loop count: %d",
3527	    loop_count);
3528
3529	CLEAR_BIT(si_portp->siport_pending_tags, slot);
3530
3531	/* Now inspect the port LRAM for the modified FIS. */
3532	prb_word_ptr = (uint32_t *)(void *)prb;
3533	for (i = 0; i < (sizeof (si_prb_t)/4); i++) {
3534		prb_word_ptr[i] = ddi_get32(si_ctlp->sictl_port_acc_handle,
3535		    (uint32_t *)(PORT_LRAM(si_ctlp, port, slot)+i*4));
3536	}
3537
3538	if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
3539	    si_check_port_handles(si_portp) != DDI_SUCCESS) {
3540		ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3541		    DDI_SERVICE_UNAFFECTED);
3542		return (SI_FAILURE);
3543	}
3544
3545	if (((GET_FIS_COMMAND(prb->prb_fis) & 0x1) != 0) ||
3546	    (GET_FIS_FEATURES(prb->prb_fis) != 0)) {
3547		/* command failed */
3548		return (SI_FAILURE);
3549	}
3550
3551	/* command succeeded */
3552	return (SI_SUCCESS);
3553}
3554
3555
3556/*
3557 * Set the auto sense data for ATAPI devices.
3558 *
3559 * Note: Currently the sense data is simulated; this code will be enhanced
3560 * in second phase to fetch the real sense data from the atapi device.
3561 */
3562static void
3563si_set_sense_data(sata_pkt_t *satapkt, int reason)
3564{
3565	struct scsi_extended_sense *sense;
3566
3567	sense = (struct scsi_extended_sense *)
3568	    satapkt->satapkt_cmd.satacmd_rqsense;
3569	bzero(sense, sizeof (struct scsi_extended_sense));
3570	sense->es_valid = 1;		/* Valid sense */
3571	sense->es_class = 7;		/* Response code 0x70 - current err */
3572	sense->es_key = 0;
3573	sense->es_info_1 = 0;
3574	sense->es_info_2 = 0;
3575	sense->es_info_3 = 0;
3576	sense->es_info_4 = 0;
3577	sense->es_add_len = 6;		/* Additional length */
3578	sense->es_cmd_info[0] = 0;
3579	sense->es_cmd_info[1] = 0;
3580	sense->es_cmd_info[2] = 0;
3581	sense->es_cmd_info[3] = 0;
3582	sense->es_add_code = 0;
3583	sense->es_qual_code = 0;
3584
3585	if ((reason == SATA_PKT_DEV_ERROR) || (reason == SATA_PKT_TIMEOUT)) {
3586		sense->es_key = KEY_HARDWARE_ERROR;
3587	}
3588}
3589
3590
3591/*
3592 * Interrupt service handler. We loop through each of the ports to find
3593 * if the interrupt belongs to any of them.
3594 *
3595 * Bulk of the interrupt handling is actually done out of subroutines
3596 * like si_intr_command_complete() etc.
3597 */
3598/*ARGSUSED*/
3599static uint_t
3600si_intr(caddr_t arg1, caddr_t arg2)
3601{
3602	si_ctl_state_t *si_ctlp = (si_ctl_state_t *)(void *)arg1;
3603	si_port_state_t *si_portp;
3604	uint32_t global_intr_status;
3605	uint32_t mask, port_intr_status;
3606	int port;
3607
3608	global_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
3609	    (uint32_t *)GLOBAL_INTERRUPT_STATUS(si_ctlp));
3610
3611	SIDBG_C(SIDBG_INTR, si_ctlp,
3612	    "si_intr: global_int_status: 0x%x",
3613	    global_intr_status);
3614
3615	if (si_check_acc_handle(si_ctlp->sictl_global_acc_handle) !=
3616	    DDI_SUCCESS) {
3617		ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3618		    DDI_SERVICE_UNAFFECTED);
3619		return (DDI_INTR_UNCLAIMED);
3620	}
3621
3622	if (!(global_intr_status & SI31xx_INTR_PORT_MASK)) {
3623		/* Sorry, the interrupt is not ours. */
3624		return (DDI_INTR_UNCLAIMED);
3625	}
3626
3627	/* Loop for all the ports. */
3628	for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
3629
3630		mask = 0x1 << port;
3631		if (!(global_intr_status & mask)) {
3632			continue;
3633		}
3634
3635		mutex_enter(&si_ctlp->sictl_mutex);
3636		si_portp = si_ctlp->sictl_ports[port];
3637		mutex_exit(&si_ctlp->sictl_mutex);
3638
3639		port_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
3640		    (uint32_t *)PORT_INTERRUPT_STATUS(si_ctlp, port));
3641
3642		SIDBG_P(SIDBG_VERBOSE, si_portp,
3643		    "s_intr: port_intr_status: 0x%x, port: %x",
3644		    port_intr_status,
3645		    port);
3646
3647		if (port_intr_status & INTR_COMMAND_COMPLETE) {
3648			(void) si_intr_command_complete(si_ctlp, si_portp,
3649			    port);
3650
3651			mutex_enter(&si_portp->siport_mutex);
3652			if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
3653			    si_check_port_handles(si_portp) != DDI_SUCCESS) {
3654				ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3655				    DDI_SERVICE_UNAFFECTED);
3656				si_schedule_port_initialize(si_ctlp, si_portp,
3657				    port);
3658			}
3659			mutex_exit(&si_portp->siport_mutex);
3660		} else {
3661			/* Clear the interrupts */
3662			ddi_put32(si_ctlp->sictl_port_acc_handle,
3663			    (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp, port)),
3664			    port_intr_status & INTR_MASK);
3665		}
3666
3667		/*
3668		 * Note that we did not clear the interrupt for command
3669		 * completion interrupt. Reading of slot_status takes care
3670		 * of clearing the interrupt for command completion case.
3671		 */
3672
3673		if (port_intr_status & INTR_COMMAND_ERROR) {
3674			si_schedule_intr_command_error(si_ctlp, si_portp, port);
3675		}
3676
3677		if (port_intr_status & INTR_PORT_READY) {
3678			(void) si_intr_port_ready(si_ctlp, si_portp, port);
3679		}
3680
3681		if (port_intr_status & INTR_POWER_CHANGE) {
3682			(void) si_intr_pwr_change(si_ctlp, si_portp, port);
3683		}
3684
3685		if (port_intr_status & INTR_PHYRDY_CHANGE) {
3686			(void) si_intr_phy_ready_change(si_ctlp, si_portp,
3687			    port);
3688		}
3689
3690		if (port_intr_status & INTR_COMWAKE_RECEIVED) {
3691			(void) si_intr_comwake_rcvd(si_ctlp, si_portp,
3692			    port);
3693		}
3694
3695		if (port_intr_status & INTR_UNRECOG_FIS) {
3696			(void) si_intr_unrecognised_fis(si_ctlp, si_portp,
3697			    port);
3698		}
3699
3700		if (port_intr_status & INTR_DEV_XCHANGED) {
3701			(void) si_intr_dev_xchanged(si_ctlp, si_portp, port);
3702		}
3703
3704		if (port_intr_status & INTR_8B10B_DECODE_ERROR) {
3705			(void) si_intr_decode_err_threshold(si_ctlp, si_portp,
3706			    port);
3707		}
3708
3709		if (port_intr_status & INTR_CRC_ERROR) {
3710			(void) si_intr_crc_err_threshold(si_ctlp, si_portp,
3711			    port);
3712		}
3713
3714		if (port_intr_status & INTR_HANDSHAKE_ERROR) {
3715			(void) si_intr_handshake_err_threshold(si_ctlp,
3716			    si_portp, port);
3717		}
3718
3719		if (port_intr_status & INTR_SETDEVBITS_NOTIFY) {
3720			(void) si_intr_set_devbits_notify(si_ctlp, si_portp,
3721			    port);
3722		}
3723	}
3724
3725	return (DDI_INTR_CLAIMED);
3726}
3727
3728/*
3729 * Interrupt which indicates that one or more commands have successfully
3730 * completed.
3731 *
3732 * Since we disabled W1C (write-one-to-clear) previously, mere reading
3733 * of slot_status register clears the interrupt. There is no need to
3734 * explicitly clear the interrupt.
3735 */
3736static int
3737si_intr_command_complete(
3738	si_ctl_state_t *si_ctlp,
3739	si_port_state_t *si_portp,
3740	int port)
3741{
3742
3743	uint32_t slot_status;
3744	uint32_t finished_tags;
3745	int finished_slot;
3746	sata_pkt_t *satapkt;
3747
3748	SIDBG_P(SIDBG_INTR, si_portp,
3749	    "si_intr_command_complete enter", NULL);
3750
3751	mutex_enter(&si_portp->siport_mutex);
3752
3753	slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3754	    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3755
3756	if (!si_portp->siport_pending_tags) {
3757		/*
3758		 * Spurious interrupt. Nothing to be done.
3759		 * The interrupt was cleared when slot_status was read.
3760		 */
3761		mutex_exit(&si_portp->siport_mutex);
3762		return (SI_SUCCESS);
3763	}
3764
3765	SIDBG_P(SIDBG_VERBOSE, si_portp, "si3124: si_intr_command_complete: "
3766	    "pending_tags: %x, slot_status: %x",
3767	    si_portp->siport_pending_tags,
3768	    slot_status);
3769
3770	finished_tags =  si_portp->siport_pending_tags &
3771	    ~slot_status & SI_SLOT_MASK;
3772	while (finished_tags) {
3773
3774		finished_slot = ddi_ffs(finished_tags) - 1;
3775		if (finished_slot == -1) {
3776			break;
3777		}
3778
3779		satapkt = si_portp->siport_slot_pkts[finished_slot];
3780
3781		if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
3782			si_copy_out_regs(&satapkt->satapkt_cmd, si_ctlp, port,
3783			    finished_slot);
3784		}
3785
3786		CLEAR_BIT(si_portp->siport_pending_tags, finished_slot);
3787		CLEAR_BIT(finished_tags, finished_slot);
3788		SENDUP_PACKET(si_portp, satapkt, SATA_PKT_COMPLETED);
3789	}
3790
3791	SIDBG_P(SIDBG_PKTCOMP, si_portp,
3792	    "command_complete done: pend_tags: 0x%x, slot_status: 0x%x",
3793	    si_portp->siport_pending_tags,
3794	    slot_status);
3795
3796	/*
3797	 * tidbit: no need to clear the interrupt since reading of
3798	 * slot_status automatically clears the interrupt in the case
3799	 * of a successful command completion.
3800	 */
3801
3802	mutex_exit(&si_portp->siport_mutex);
3803
3804	return (SI_SUCCESS);
3805}
3806
3807/*
3808 * Schedule a call to si_intr_command_error using a timeout to get it done
3809 * off the interrupt thread.
3810 */
3811static void
3812si_schedule_intr_command_error(
3813	si_ctl_state_t *si_ctlp,
3814	si_port_state_t *si_portp,
3815	int port)
3816{
3817	si_event_arg_t *args;
3818
3819	mutex_enter(&si_portp->siport_mutex);
3820
3821	args = si_portp->siport_event_args;
3822	if (args->siea_ctlp != NULL) {
3823		cmn_err(CE_WARN, "si_schedule_intr_command_error: "
3824		    "args->si_ctlp != NULL");
3825		mutex_exit(&si_portp->siport_mutex);
3826		return;
3827	}
3828
3829	args->siea_ctlp = si_ctlp;
3830	args->siea_port = port;
3831
3832	(void) timeout(si_do_intr_command_error, si_portp, 1);
3833
3834	mutex_exit(&si_portp->siport_mutex);
3835}
3836
3837/*
3838 * Called from timeout()
3839 * Unpack the arguments and call si_intr_command_error()
3840 */
3841static void
3842si_do_intr_command_error(void *arg)
3843{
3844	si_event_arg_t *args;
3845	si_ctl_state_t *si_ctlp;
3846	si_port_state_t *si_portp;
3847	int port;
3848
3849	si_portp = arg;
3850	mutex_enter(&si_portp->siport_mutex);
3851
3852	args = si_portp->siport_event_args;
3853	si_ctlp = args->siea_ctlp;
3854	port = args->siea_port;
3855	args->siea_ctlp = NULL;	/* mark siport_event_args as free */
3856
3857	mutex_exit(&si_portp->siport_mutex);
3858	(void) si_intr_command_error(si_ctlp, si_portp, port);
3859}
3860
3861/*
3862 * Interrupt which indicates that a command did not complete successfully.
3863 *
3864 * The port halts whenever a command error interrupt is received.
3865 * The only way to restart it is to reset or reinitialize the port
3866 * but such an operation throws away all the pending commands on
3867 * the port.
3868 *
3869 * We reset the device and mop the commands on the port.
3870 */
3871static int
3872si_intr_command_error(
3873	si_ctl_state_t *si_ctlp,
3874	si_port_state_t *si_portp,
3875	int port)
3876{
3877	uint32_t command_error, slot_status;
3878	uint32_t failed_tags;
3879
3880	command_error = ddi_get32(si_ctlp->sictl_port_acc_handle,
3881	    (uint32_t *)(PORT_COMMAND_ERROR(si_ctlp, port)));
3882
3883	SIDBG_P(SIDBG_ERRS, si_portp,
3884	    "si_intr_command_error: command_error: 0x%x",
3885	    command_error);
3886
3887	mutex_enter(&si_portp->siport_mutex);
3888
3889	/*
3890	 * Remember the slot_status since any of the recovery handler
3891	 * can blow it away with reset operation.
3892	 */
3893	slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
3894	    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
3895
3896	si_log_error_message(si_ctlp, port, command_error);
3897
3898	switch (command_error) {
3899
3900	case CMD_ERR_DEVICEERRROR:
3901		si_error_recovery_DEVICEERROR(si_ctlp, si_portp, port);
3902		break;
3903
3904	case CMD_ERR_SDBERROR:
3905		si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR, "SBD error");
3906		si_error_recovery_SDBERROR(si_ctlp, si_portp, port);
3907		ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3908		    DDI_SERVICE_UNAFFECTED);
3909		break;
3910
3911	case CMD_ERR_DATAFISERROR:
3912		si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR,
3913		    "Data FIS error");
3914		si_error_recovery_DATAFISERROR(si_ctlp, si_portp, port);
3915		ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3916		    DDI_SERVICE_UNAFFECTED);
3917		break;
3918
3919	case CMD_ERR_SENDFISERROR:
3920		si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR,
3921		    "Send FIS error");
3922		si_error_recovery_SENDFISERROR(si_ctlp, si_portp, port);
3923		ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3924		    DDI_SERVICE_UNAFFECTED);
3925		break;
3926
3927	default:
3928		si_fm_ereport(si_ctlp, DDI_FM_DEVICE_INTERN_CORR,
3929		    "Unknown error");
3930		si_error_recovery_default(si_ctlp, si_portp, port);
3931		ddi_fm_service_impact(si_ctlp->sictl_devinfop,
3932		    DDI_SERVICE_UNAFFECTED);
3933		break;
3934
3935	}
3936
3937	/*
3938	 * Compute the failed_tags by adding up the error tags.
3939	 *
3940	 * The siport_err_tags_SDBERROR and siport_err_tags_nonSDBERROR
3941	 * were filled in by the si_error_recovery_* routines.
3942	 */
3943	failed_tags = si_portp->siport_pending_tags &
3944	    (si_portp->siport_err_tags_SDBERROR |
3945	    si_portp->siport_err_tags_nonSDBERROR);
3946
3947	SIDBG_P(SIDBG_ERRS, si_portp, "si_intr_command_error: "
3948	    "err_tags_SDBERROR: 0x%x, "
3949	    "err_tags_nonSDBERRROR: 0x%x, "
3950	    "failed_tags: 0x%x",
3951	    si_portp->siport_err_tags_SDBERROR,
3952	    si_portp->siport_err_tags_nonSDBERROR,
3953	    failed_tags);
3954
3955	SIDBG_P(SIDBG_ERRS, si_portp,
3956	    "si3124: si_intr_command_error: "
3957	    "slot_status:0x%x, pending_tags: 0x%x",
3958	    slot_status,
3959	    si_portp->siport_pending_tags);
3960
3961	si_portp->mopping_in_progress++;
3962
3963	si_mop_commands(si_ctlp,
3964	    si_portp,
3965	    port,
3966	    slot_status,
3967	    failed_tags,
3968	    0, 	/* timedout_tags */
3969	    0, 	/* aborting_tags */
3970	    0); 	/* reset_tags */
3971
3972	ASSERT(si_portp->siport_pending_tags == 0);
3973
3974	si_portp->siport_err_tags_SDBERROR = 0;
3975	si_portp->siport_err_tags_nonSDBERROR = 0;
3976
3977	mutex_exit(&si_portp->siport_mutex);
3978
3979	return (SI_SUCCESS);
3980}
3981
3982/*
3983 * There is a subtle difference between errors on a normal port and
3984 * a port-mult port. When an error happens on a normal port, the port
3985 * is halted effectively until the port is reset or initialized.
3986 * However, in port-mult port errors, port does not get halted since
3987 * other non-error devices behind the port multiplier can still
3988 * continue to operate. So we wait till all the commands are drained
3989 * instead of resetting it right away.
3990 *
3991 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
3992 * before calling us.
3993 */
3994static void
3995si_recover_portmult_errors(
3996	si_ctl_state_t *si_ctlp,
3997	si_port_state_t *si_portp,
3998	int port)
3999{
4000	uint32_t command_error, slot_status, port_status;
4001	int failed_slot;
4002	int loop_count = 0;
4003
4004	_NOTE(ASSUMING_PROTECTED(si_portp))
4005
4006	SIDBG_P(SIDBG_ERRS, si_portp,
4007	    "si_recover_portmult_errors: port: 0x%x",
4008	    port);
4009
4010	/* Resume the port */
4011	ddi_put32(si_ctlp->sictl_port_acc_handle,
4012	    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
4013	    PORT_CONTROL_SET_BITS_RESUME);
4014
4015	port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4016	    (uint32_t *)PORT_STATUS(si_ctlp, port));
4017
4018	failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4019	command_error = ddi_get32(si_ctlp->sictl_port_acc_handle,
4020	    (uint32_t *)(PORT_COMMAND_ERROR(si_ctlp, port)));
4021
4022	if (command_error ==  CMD_ERR_SDBERROR) {
4023		si_portp->siport_err_tags_SDBERROR |= (0x1 << failed_slot);
4024	} else {
4025		si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4026	}
4027
4028	/* Now we drain the pending commands. */
4029	do {
4030		slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4031		    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
4032
4033		/*
4034		 * Since we have not yet returned DDI_INTR_CLAIMED,
4035		 * our interrupt handler is guaranteed not to be called again.
4036		 * So we need to check IS_ATTENTION_RAISED() for further
4037		 * decisions.
4038		 *
4039		 * This is a too big a delay for an interrupt context.
4040		 * But this is supposed to be a rare condition.
4041		 */
4042
4043		if (IS_ATTENTION_RAISED(slot_status)) {
4044			/* Resume again */
4045			ddi_put32(si_ctlp->sictl_port_acc_handle,
4046			    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
4047			    PORT_CONTROL_SET_BITS_RESUME);
4048
4049			port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4050			    (uint32_t *)PORT_STATUS(si_ctlp, port));
4051			failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4052			command_error = ddi_get32(
4053			    si_ctlp->sictl_port_acc_handle,
4054			    (uint32_t *)(PORT_COMMAND_ERROR(si_ctlp,
4055			    port)));
4056			if (command_error ==  CMD_ERR_SDBERROR) {
4057				si_portp->siport_err_tags_SDBERROR |=
4058				    (0x1 << failed_slot);
4059			} else {
4060				si_portp->siport_err_tags_nonSDBERROR |=
4061				    (0x1 << failed_slot);
4062			}
4063		}
4064
4065		if (loop_count++ > SI_POLLRATE_RECOVERPORTMULT) {
4066			/* We are effectively timing out after 10 sec. */
4067			break;
4068		}
4069
4070		/* Wait for 10 millisec */
4071#ifndef __lock_lint
4072		delay(SI_10MS_TICKS);
4073#endif /* __lock_lint */
4074
4075	} while (slot_status & SI_SLOT_MASK);
4076
4077	/*
4078	 * The above loop can be improved for 3132 since we could obtain the
4079	 * Port Multiplier Context of the device in error. Then we could
4080	 * do a better job in filtering out commands for the device in error.
4081	 * The loop could finish much earlier with such a logic.
4082	 */
4083
4084	/* Clear the RESUME bit. */
4085	ddi_put32(si_ctlp->sictl_port_acc_handle,
4086	    (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
4087	    PORT_CONTROL_CLEAR_BITS_RESUME);
4088
4089}
4090
4091/*
4092 * If we are connected to port multiplier, drain the non-failed devices.
4093 * Otherwise, we initialize the port (which effectively fails all the
4094 * pending commands in the hope that sd would retry them later).
4095 *
4096 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4097 * before calling us.
4098 */
4099static void
4100si_error_recovery_DEVICEERROR(
4101	si_ctl_state_t *si_ctlp,
4102	si_port_state_t *si_portp,
4103	int port)
4104{
4105	uint32_t port_status;
4106	int failed_slot;
4107
4108	_NOTE(ASSUMING_PROTECTED(si_portp))
4109
4110	SIDBG_P(SIDBG_ERRS, si_portp,
4111	    "si_error_recovery_DEVICEERROR: port: 0x%x",
4112	    port);
4113
4114	if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
4115		si_recover_portmult_errors(si_ctlp, si_portp, port);
4116	} else {
4117		port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4118		    (uint32_t *)PORT_STATUS(si_ctlp, port));
4119		failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4120		si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4121	}
4122
4123	/* In either case (port-mult or not), we reinitialize the port. */
4124	(void) si_initialize_port_wait_till_ready(si_ctlp, port);
4125}
4126
4127/*
4128 * Handle exactly like DEVICEERROR. Remember the tags with SDBERROR
4129 * to perform read_log_ext on them later. SDBERROR means that the
4130 * error was for an NCQ command.
4131 *
4132 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4133 * before calling us.
4134 */
4135static void
4136si_error_recovery_SDBERROR(
4137	si_ctl_state_t *si_ctlp,
4138	si_port_state_t *si_portp,
4139	int port)
4140{
4141	uint32_t port_status;
4142	int failed_slot;
4143
4144	_NOTE(ASSUMING_PROTECTED(si_portp))
4145
4146	SIDBG_P(SIDBG_ERRS, si_portp,
4147	    "si3124: si_error_recovery_SDBERROR: port: 0x%x",
4148	    port);
4149
4150	if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
4151		si_recover_portmult_errors(si_ctlp, si_portp, port);
4152	} else {
4153		port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4154		    (uint32_t *)PORT_STATUS(si_ctlp, port));
4155		failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4156		si_portp->siport_err_tags_SDBERROR |= (0x1 << failed_slot);
4157	}
4158
4159	/* In either case (port-mult or not), we reinitialize the port. */
4160	(void) si_initialize_port_wait_till_ready(si_ctlp, port);
4161}
4162
4163/*
4164 * Handle exactly like DEVICEERROR except resetting the port if there was
4165 * an NCQ command on the port.
4166 *
4167 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4168 * before calling us.
4169 */
4170static void
4171si_error_recovery_DATAFISERROR(
4172	si_ctl_state_t *si_ctlp,
4173	si_port_state_t *si_portp,
4174	int port)
4175{
4176	uint32_t port_status;
4177	int failed_slot;
4178
4179	_NOTE(ASSUMING_PROTECTED(si_portp))
4180
4181	SIDBG_P(SIDBG_ERRS, si_portp,
4182	    "si3124: si_error_recovery_DATAFISERROR: port: 0x%x",
4183	    port);
4184
4185	/* reset device if we were waiting for any ncq commands. */
4186	if (si_portp->siport_pending_ncq_count) {
4187		port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4188		    (uint32_t *)PORT_STATUS(si_ctlp, port));
4189		failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4190		si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4191		(void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
4192		    SI_DEVICE_RESET);
4193		return;
4194	}
4195
4196	/*
4197	 * If we don't have any ncq commands pending, the rest of
4198	 * the process is similar to the one for DEVICEERROR.
4199	 */
4200	si_error_recovery_DEVICEERROR(si_ctlp, si_portp, port);
4201}
4202
4203/*
4204 * We handle just like DEVICERROR except that we reset the device instead
4205 * of initializing the port.
4206 *
4207 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4208 * before calling us.
4209 */
4210static void
4211si_error_recovery_SENDFISERROR(
4212	si_ctl_state_t *si_ctlp,
4213	si_port_state_t *si_portp,
4214	int port)
4215{
4216	uint32_t port_status;
4217	int failed_slot;
4218
4219	_NOTE(ASSUMING_PROTECTED(si_portp))
4220
4221	SIDBG_P(SIDBG_ERRS, si_portp,
4222	    "si3124: si_error_recovery_SENDFISERROR: port: 0x%x",
4223	    port);
4224
4225	if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
4226		si_recover_portmult_errors(si_ctlp, si_portp, port);
4227	} else {
4228		port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4229		    (uint32_t *)PORT_STATUS(si_ctlp, port));
4230		failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4231		si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4232		(void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
4233		    SI_DEVICE_RESET);
4234	}
4235}
4236
4237/*
4238 * The default behavior for all other errors is to reset the device.
4239 *
4240 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4241 * before calling us.
4242 */
4243static void
4244si_error_recovery_default(
4245	si_ctl_state_t *si_ctlp,
4246	si_port_state_t *si_portp,
4247	int port)
4248{
4249	uint32_t port_status;
4250	int failed_slot;
4251
4252	_NOTE(ASSUMING_PROTECTED(si_portp))
4253
4254	SIDBG_P(SIDBG_ERRS, si_portp,
4255	    "si3124: si_error_recovery_default: port: 0x%x",
4256	    port);
4257
4258	port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4259	    (uint32_t *)PORT_STATUS(si_ctlp, port));
4260	failed_slot = (port_status >> 16) & SI_NUM_SLOTS;
4261	si_portp->siport_err_tags_nonSDBERROR |= (0x1 << failed_slot);
4262
4263	(void) si_reset_dport_wait_till_ready(si_ctlp, si_portp, port,
4264	    SI_DEVICE_RESET);
4265}
4266
4267/*
4268 * Read Log Ext with PAGE 10 to retrieve the error for an NCQ command.
4269 *
4270 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4271 * before calling us.
4272 */
4273static uint8_t
4274si_read_log_ext(si_ctl_state_t *si_ctlp, si_port_state_t *si_portp, int port)
4275{
4276	int slot;
4277	si_prb_t *prb;
4278	int i;
4279	uint32_t slot_status;
4280	int loop_count = 0;
4281	uint32_t *prb_word_ptr;
4282	uint8_t error;
4283
4284	_NOTE(ASSUMING_PROTECTED(si_portp))
4285
4286	SIDBG_P(SIDBG_ERRS, si_portp,
4287	    "si_read_log_ext: port: %x", port);
4288
4289	slot = si_claim_free_slot(si_ctlp, si_portp, port);
4290	if (slot == SI_FAILURE) {
4291		return (0);
4292	}
4293
4294	prb =  &(si_portp->siport_prbpool[slot]);
4295	bzero((void *)prb, sizeof (si_prb_t));
4296
4297	/* Now fill the prb */
4298	SET_FIS_TYPE(prb->prb_fis, REGISTER_FIS_H2D);
4299	SET_FIS_PMP(prb->prb_fis, PORTMULT_CONTROL_PORT);
4300	SET_FIS_CDMDEVCTL(prb->prb_fis, 1);
4301	SET_FIS_COMMAND(prb->prb_fis, SATAC_READ_LOG_EXT);
4302	SET_FIS_SECTOR(prb->prb_fis, SATA_LOG_PAGE_10);
4303
4304	/* no real data transfer is involved */
4305	SET_SGE_TRM(prb->prb_sge0);
4306
4307#if SI_DEBUG
4308	if (si_debug_flags & SIDBG_DUMP_PRB) {
4309		int *ptr;
4310		int j;
4311
4312		ptr = (int *)(void *)prb;
4313		cmn_err(CE_WARN, "read_port_mult_reg, prb: ");
4314		for (j = 0; j < (sizeof (si_prb_t)/4); j++) {
4315			cmn_err(CE_WARN, "%x ", ptr[j]);
4316		}
4317
4318	}
4319#endif /* SI_DEBUG */
4320
4321	/* Deliver PRB */
4322	POST_PRB_ADDR(si_ctlp, si_portp, port, slot);
4323
4324	/* Loop till the command is finished. */
4325	do {
4326		slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
4327		    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
4328
4329		SIDBG_P(SIDBG_POLL_LOOP, si_portp,
4330		    "looping read_log_ext slot_status: 0x%x",
4331		    slot_status);
4332
4333		if (loop_count++ > SI_POLLRATE_SLOTSTATUS) {
4334			/* We are effectively timing out after 0.5 sec. */
4335			break;
4336		}
4337
4338		/* Wait for 10 millisec */
4339#ifndef __lock_lint
4340		delay(SI_10MS_TICKS);
4341#endif /* __lock_lint */
4342
4343	} while (slot_status & SI_SLOT_MASK & (0x1 << slot));
4344
4345	if (slot_status & SI_SLOT_MASK & (0x1 << slot)) {
4346		/*
4347		 * If we fail with the READ LOG EXT command, we need to
4348		 * initialize the port to clear the slot_status register.
4349		 * We don't need to worry about any other valid commands
4350		 * being thrown away because we are already in recovery
4351		 * mode and READ LOG EXT is the only pending command.
4352		 */
4353		(void) si_initialize_port_wait_till_ready(si_ctlp, port);
4354	}
4355
4356	SIDBG_P(SIDBG_POLL_LOOP, si_portp,
4357	    "read_portmult_reg: loop count: %d",
4358	    loop_count);
4359
4360	/*
4361	 * The LRAM contains the the modified FIS.
4362	 * Read the modified FIS to obtain the Error.
4363	 */
4364	prb_word_ptr = (uint32_t *)(void *)prb;
4365	for (i = 0; i < (sizeof (si_prb_t)/4); i++) {
4366		prb_word_ptr[i] = ddi_get32(si_ctlp->sictl_port_acc_handle,
4367		    (uint32_t *)(PORT_LRAM(si_ctlp, port, slot)+i*4));
4368	}
4369
4370	if (si_check_ctl_handles(si_ctlp) != DDI_SUCCESS ||
4371	    si_check_port_handles(si_portp) != DDI_SUCCESS) {
4372		ddi_fm_service_impact(si_ctlp->sictl_devinfop,
4373		    DDI_SERVICE_UNAFFECTED);
4374	}
4375
4376	error = GET_FIS_FEATURES(prb->prb_fis);
4377
4378	CLEAR_BIT(si_portp->siport_pending_tags, slot);
4379
4380	return (error);
4381
4382}
4383
4384/*
4385 * Dump the error message to the log.
4386 */
4387static void
4388si_log_error_message(si_ctl_state_t *si_ctlp, int port, uint32_t command_error)
4389{
4390#if SI_DEBUG
4391#ifndef __lock_lint
4392	_NOTE(ARGUNUSED(si_ctlp))
4393        _NOTE(ARGUNUSED(port))
4394#endif  /* __lock_lint */
4395
4396	char *errstr;
4397	si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
4398
4399	switch (command_error) {
4400
4401	case CMD_ERR_DEVICEERRROR:
4402		errstr = "Standard Error: Error bit set in register - device"
4403		    " to host FIS";
4404		break;
4405
4406	case CMD_ERR_SDBERROR:
4407		errstr = "NCQ Error: Error bit set in register - device"
4408		    " to host FIS";
4409		break;
4410
4411	case CMD_ERR_DATAFISERROR:
4412		errstr = "Error in data FIS not detected by device";
4413		break;
4414
4415	case CMD_ERR_SENDFISERROR:
4416		errstr = "Initial command FIS transmission failed";
4417		break;
4418
4419	case CMD_ERR_INCONSISTENTSTATE:
4420		errstr = "Inconsistency in protocol";
4421		break;
4422
4423	case CMD_ERR_DIRECTIONERROR:
4424		errstr = "DMA direction flag does not match the command";
4425		break;
4426
4427	case CMD_ERR_UNDERRUNERROR:
4428		errstr = "Run out of scatter gather entries while writing data";
4429		break;
4430
4431	case CMD_ERR_OVERRUNERROR:
4432		errstr = "Run out of scatter gather entries while reading data";
4433		break;
4434
4435	case CMD_ERR_PACKETPROTOCOLERROR:
4436		errstr = "Packet protocol error";
4437		break;
4438
4439	case CMD_ERR_PLDSGTERRORBOUNDARY:
4440		errstr = "Scatter/gather table not on quadword boundary";
4441		break;
4442
4443	case CMD_ERR_PLDSGTERRORTARETABORT:
4444		errstr = "PCI(X) Target abort while fetching scatter/gather"
4445		    " table";
4446		break;
4447
4448	case CMD_ERR_PLDSGTERRORMASTERABORT:
4449		errstr = "PCI(X) Master abort while fetching scatter/gather"
4450		    " table";
4451		break;
4452
4453	case CMD_ERR_PLDSGTERRORPCIERR:
4454		errstr = "PCI(X) parity error while fetching scatter/gather"
4455		    " table";
4456		break;
4457
4458	case CMD_ERR_PLDCMDERRORBOUNDARY:
4459		errstr = "PRB not on quadword boundary";
4460		break;
4461
4462	case CMD_ERR_PLDCMDERRORTARGETABORT:
4463		errstr = "PCI(X) Target abort while fetching PRB";
4464		break;
4465
4466	case CMD_ERR_PLDCMDERRORMASTERABORT:
4467		errstr = "PCI(X) Master abort while fetching PRB";
4468		break;
4469
4470	case CMD_ERR_PLDCMDERORPCIERR:
4471		errstr = "PCI(X) parity error while fetching PRB";
4472		break;
4473
4474	case CMD_ERR_PSDERRORTARGETABORT:
4475		errstr = "PCI(X) Target abort during data transfer";
4476		break;
4477
4478	case CMD_ERR_PSDERRORMASTERABORT:
4479		errstr = "PCI(X) Master abort during data transfer";
4480		break;
4481
4482	case CMD_ERR_PSDERRORPCIERR:
4483		errstr = "PCI(X) parity error during data transfer";
4484		break;
4485
4486	case CMD_ERR_SENDSERVICEERROR:
4487		errstr = "FIS received while sending service FIS in"
4488		    " legacy queuing operation";
4489		break;
4490
4491	default:
4492		errstr = "Unknown Error";
4493		break;
4494
4495	}
4496
4497	SIDBG_P(SIDBG_ERRS, si_portp,
4498	    "command error: error: %s",
4499	    errstr);
4500#else
4501#ifndef __lock_lint
4502        _NOTE(ARGUNUSED(si_ctlp))
4503        _NOTE(ARGUNUSED(port))
4504        _NOTE(ARGUNUSED(command_error))
4505#endif  /* __lock_lint */
4506
4507#endif	/* SI_DEBUG */
4508}
4509
4510
4511/*
4512 * Interrupt which indicates that the Port Ready state has changed
4513 * from zero to one.
4514 *
4515 * We are not interested in this interrupt; we just log a debug message.
4516 */
4517/*ARGSUSED*/
4518static int
4519si_intr_port_ready(
4520	si_ctl_state_t *si_ctlp,
4521	si_port_state_t *si_portp,
4522	int port)
4523{
4524	SIDBG_P(SIDBG_INTR, si_portp, "si_intr_ready", NULL);
4525	return (SI_SUCCESS);
4526}
4527
4528/*
4529 * Interrupt which indicates that the port power management state
4530 * has been modified.
4531 *
4532 * We are not interested in this interrupt; we just log a debug message.
4533 */
4534/*ARGSUSED*/
4535static int
4536si_intr_pwr_change(
4537	si_ctl_state_t *si_ctlp,
4538	si_port_state_t *si_portp,
4539	int port)
4540{
4541	SIDBG_P(SIDBG_INTR, si_portp, "si_intr_pwr_change", NULL);
4542	return (SI_SUCCESS);
4543}
4544
4545/*
4546 * Interrupt which indicates that the PHY state has changed either from
4547 * Not-Ready to Ready or from Ready to Not-Ready.
4548 */
4549static int
4550si_intr_phy_ready_change(
4551	si_ctl_state_t *si_ctlp,
4552	si_port_state_t *si_portp,
4553	int port)
4554{
4555	sata_device_t sdevice;
4556	uint32_t SStatus = 0; /* No dev present & PHY not established. */
4557	int dev_exists_now = 0;
4558	int dev_existed_previously = 0;
4559
4560	SIDBG_P(SIDBG_INTR, si_portp,
4561	    "si_intr_phy_rdy_change", NULL);
4562
4563	mutex_enter(&si_ctlp->sictl_mutex);
4564	if ((si_ctlp->sictl_sata_hba_tran == NULL) || (si_portp == NULL)) {
4565		/* the whole controller setup is not yet done. */
4566		mutex_exit(&si_ctlp->sictl_mutex);
4567		return (SI_SUCCESS);
4568	}
4569
4570	mutex_exit(&si_ctlp->sictl_mutex);
4571
4572	mutex_enter(&si_portp->siport_mutex);
4573
4574	/* SStatus tells the presence of device. */
4575	SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
4576	    (uint32_t *)PORT_SSTATUS(si_ctlp, port));
4577	dev_exists_now =
4578	    (SSTATUS_GET_DET(SStatus) == SSTATUS_DET_DEVPRESENT_PHYONLINE);
4579
4580	if (si_portp->siport_port_type != PORT_TYPE_NODEV) {
4581		dev_existed_previously = 1;
4582	}
4583
4584	bzero((void *)&sdevice, sizeof (sata_device_t));
4585
4586	sdevice.satadev_addr.cport = (uint8_t)port;
4587	sdevice.satadev_addr.pmport = PORTMULT_CONTROL_PORT;
4588
4589	/* we don't have a way of determining the exact port-mult port. */
4590	if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
4591		sdevice.satadev_addr.qual = SATA_ADDR_PMPORT;
4592	} else {
4593		sdevice.satadev_addr.qual = SATA_ADDR_CPORT;
4594	}
4595
4596	sdevice.satadev_state = SATA_STATE_READY; /* port state */
4597
4598	if (dev_exists_now) {
4599		if (dev_existed_previously) {
4600
4601			/* Things are fine now. The loss was temporary. */
4602			SIDBG_P(SIDBG_INTR, si_portp,
4603			    "phyrdy: doing BOTH EVENTS TOGETHER", NULL);
4604			if (si_portp->siport_active) {
4605				SIDBG_P(SIDBG_EVENT, si_portp,
4606				    "sending event: LINK_LOST & "
4607				    "LINK_ESTABLISHED", NULL);
4608
4609				sata_hba_event_notify(
4610				    si_ctlp->sictl_sata_hba_tran->\
4611				    sata_tran_hba_dip,
4612				    &sdevice,
4613				    SATA_EVNT_LINK_LOST|
4614				    SATA_EVNT_LINK_ESTABLISHED);
4615			}
4616
4617		} else {
4618
4619			/* A new device has been detected. */
4620			mutex_exit(&si_portp->siport_mutex);
4621			si_find_dev_signature(si_ctlp, si_portp, port,
4622			    PORTMULT_CONTROL_PORT);
4623			mutex_enter(&si_portp->siport_mutex);
4624			SIDBG_P(SIDBG_INTR, si_portp,
4625			    "phyrdy: doing ATTACH event", NULL);
4626			if (si_portp->siport_active) {
4627				SIDBG_P(SIDBG_EVENT, si_portp,
4628				    "sending event up: LINK_ESTABLISHED", NULL);
4629
4630				sata_hba_event_notify(
4631				    si_ctlp->sictl_sata_hba_tran->\
4632				    sata_tran_hba_dip,
4633				    &sdevice,
4634				    SATA_EVNT_LINK_ESTABLISHED);
4635			}
4636
4637		}
4638	} else { /* No device exists now */
4639
4640		if (dev_existed_previously) {
4641
4642			/* An existing device is lost. */
4643			if (si_portp->siport_active) {
4644				SIDBG_P(SIDBG_EVENT, si_portp,
4645				    "sending event up: LINK_LOST", NULL);
4646
4647				sata_hba_event_notify(
4648				    si_ctlp->sictl_sata_hba_tran->
4649				    sata_tran_hba_dip,
4650				    &sdevice,
4651				    SATA_EVNT_LINK_LOST);
4652			}
4653			si_portp->siport_port_type = PORT_TYPE_NODEV;
4654
4655		} else {
4656
4657			/* spurious interrupt */
4658			SIDBG_P(SIDBG_INTR, si_portp,
4659			    "spurious phy ready interrupt", NULL);
4660		}
4661	}
4662
4663	mutex_exit(&si_portp->siport_mutex);
4664	return (SI_SUCCESS);
4665}
4666
4667
4668/*
4669 * Interrupt which indicates that a COMWAKE OOB signal has been decoded
4670 * on the receiver.
4671 *
4672 * We are not interested in this interrupt; we just log a debug message.
4673 */
4674/*ARGSUSED*/
4675static int
4676si_intr_comwake_rcvd(
4677	si_ctl_state_t *si_ctlp,
4678	si_port_state_t *si_portp,
4679	int port)
4680{
4681	SIDBG_P(SIDBG_INTR, si_portp,
4682	    "si_intr_commwake_rcvd", NULL);
4683	return (SI_SUCCESS);
4684}
4685
4686/*
4687 * Interrupt which indicates that the F-bit has been set in SError
4688 * Diag field.
4689 *
4690 * We are not interested in this interrupt; we just log a debug message.
4691 */
4692/*ARGSUSED*/
4693static int
4694si_intr_unrecognised_fis(
4695	si_ctl_state_t *si_ctlp,
4696	si_port_state_t *si_portp,
4697	int port)
4698{
4699	SIDBG_P(SIDBG_INTR, si_portp,
4700	    "si_intr_unrecognised_fis", NULL);
4701	return (SI_SUCCESS);
4702}
4703
4704/*
4705 * Interrupt which indicates that the X-bit has been set in SError
4706 * Diag field.
4707 *
4708 * We are not interested in this interrupt; we just log a debug message.
4709 */
4710/*ARGSUSED*/
4711static int
4712si_intr_dev_xchanged(
4713	si_ctl_state_t *si_ctlp,
4714	si_port_state_t *si_portp,
4715	int port)
4716{
4717
4718	SIDBG_P(SIDBG_INTR, si_portp,
4719	    "si_intr_dev_xchanged", NULL);
4720	return (SI_SUCCESS);
4721}
4722
4723/*
4724 * Interrupt which indicates that the 8b/10b Decode Error counter has
4725 * exceeded the programmed non-zero threshold value.
4726 *
4727 * We are not interested in this interrupt; we just log a debug message.
4728 */
4729/*ARGSUSED*/
4730static int
4731si_intr_decode_err_threshold(
4732	si_ctl_state_t *si_ctlp,
4733	si_port_state_t *si_portp,
4734	int port)
4735{
4736	SIDBG_P(SIDBG_INTR, si_portp,
4737	    "si_intr_err_threshold", NULL);
4738	return (SI_SUCCESS);
4739}
4740
4741/*
4742 * Interrupt which indicates that the CRC Error counter has exceeded the
4743 * programmed non-zero threshold value.
4744 *
4745 * We are not interested in this interrupt; we just log a debug message.
4746 */
4747/*ARGSUSED*/
4748static int
4749si_intr_crc_err_threshold(
4750	si_ctl_state_t *si_ctlp,
4751	si_port_state_t *si_portp,
4752	int port)
4753{
4754	SIDBG_P(SIDBG_INTR, si_portp,
4755	    "si_intr_crc_threshold", NULL);
4756	return (SI_SUCCESS);
4757}
4758
4759/*
4760 * Interrupt which indicates that the Handshake Error counter has
4761 * exceeded the programmed non-zero threshold value.
4762 *
4763 * We are not interested in this interrupt; we just log a debug message.
4764 */
4765/*ARGSUSED*/
4766static int
4767si_intr_handshake_err_threshold(
4768	si_ctl_state_t *si_ctlp,
4769	si_port_state_t *si_portp,
4770	int port)
4771{
4772	SIDBG_P(SIDBG_INTR, si_portp,
4773	    "si_intr_handshake_err_threshold", NULL);
4774	return (SI_SUCCESS);
4775}
4776
4777/*
4778 * Interrupt which indicates that a "Set Device Bits" FIS has been
4779 * received with N-bit set in the control field.
4780 *
4781 * We are not interested in this interrupt; we just log a debug message.
4782 */
4783/*ARGSUSED*/
4784static int
4785si_intr_set_devbits_notify(
4786	si_ctl_state_t *si_ctlp,
4787	si_port_state_t *si_portp,
4788	int port)
4789{
4790	SIDBG_P(SIDBG_INTR, si_portp,
4791	    "si_intr_set_devbits_notify", NULL);
4792	return (SI_SUCCESS);
4793}
4794
4795
4796/*
4797 * Enable the interrupts for a particular port.
4798 *
4799 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4800 * before calling us.
4801 */
4802static void
4803si_enable_port_interrupts(si_ctl_state_t *si_ctlp, int port)
4804{
4805	uint32_t mask;
4806	si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
4807
4808	/* get the current settings first. */
4809	mask = ddi_get32(si_ctlp->sictl_global_acc_handle,
4810	    (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp));
4811
4812	SIDBG_P(SIDBG_INIT, si_portp,
4813	    "si_enable_port_interrupts: current mask: 0x%x",
4814	    mask);
4815
4816	/* enable the bit for current port. */
4817	SET_BIT(mask, port);
4818
4819	/* now use this mask to enable the interrupt. */
4820	ddi_put32(si_ctlp->sictl_global_acc_handle,
4821	    (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp),
4822	    mask);
4823}
4824
4825/*
4826 * Enable interrupts for all the ports.
4827 */
4828static void
4829si_enable_all_interrupts(si_ctl_state_t *si_ctlp)
4830{
4831	int port;
4832
4833	for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
4834		si_enable_port_interrupts(si_ctlp, port);
4835	}
4836}
4837
4838/*
4839 * Disable interrupts for a particular port.
4840 *
4841 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
4842 * before calling us.
4843 */
4844static void
4845si_disable_port_interrupts(si_ctl_state_t *si_ctlp, int port)
4846{
4847	uint32_t mask;
4848
4849	/* get the current settings first. */
4850	mask = ddi_get32(si_ctlp->sictl_global_acc_handle,
4851	    (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp));
4852
4853	/* clear the bit for current port. */
4854	CLEAR_BIT(mask, port);
4855
4856	/* now use this mask to disable the interrupt. */
4857	ddi_put32(si_ctlp->sictl_global_acc_handle,
4858	    (uint32_t *)GLOBAL_CONTROL_REG(si_ctlp),
4859	    mask);
4860
4861}
4862
4863/*
4864 * Disable interrupts for all the ports.
4865 */
4866static void
4867si_disable_all_interrupts(si_ctl_state_t *si_ctlp)
4868{
4869	int port;
4870
4871	for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
4872		si_disable_port_interrupts(si_ctlp, port);
4873	}
4874}
4875
4876/*
4877 * Fetches the latest sstatus, scontrol, serror, sactive registers
4878 * and stuffs them into sata_device_t structure.
4879 */
4880static void
4881fill_dev_sregisters(si_ctl_state_t *si_ctlp, int port, sata_device_t *satadev)
4882{
4883	satadev->satadev_scr.sstatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
4884	    (uint32_t *)(PORT_SSTATUS(si_ctlp, port)));
4885	satadev->satadev_scr.serror = ddi_get32(si_ctlp->sictl_port_acc_handle,
4886	    (uint32_t *)(PORT_SERROR(si_ctlp, port)));
4887	satadev->satadev_scr.sactive = ddi_get32(si_ctlp->sictl_port_acc_handle,
4888	    (uint32_t *)(PORT_SACTIVE(si_ctlp, port)));
4889	satadev->satadev_scr.scontrol =
4890	    ddi_get32(si_ctlp->sictl_port_acc_handle,
4891	    (uint32_t *)(PORT_SCONTROL(si_ctlp, port)));
4892
4893}
4894
4895/*
4896 * si_add_legacy_intrs() handles INTx and legacy interrupts.
4897 */
4898static int
4899si_add_legacy_intrs(si_ctl_state_t *si_ctlp)
4900{
4901	dev_info_t	*devinfo = si_ctlp->sictl_devinfop;
4902	int		actual, count = 0;
4903	int		x, y, rc, inum = 0;
4904
4905	SIDBG_C(SIDBG_INIT, si_ctlp, "si_add_legacy_intrs", NULL);
4906
4907	/* get number of interrupts. */
4908	rc = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_FIXED, &count);
4909	if ((rc != DDI_SUCCESS) || (count == 0)) {
4910		SIDBG_C(SIDBG_ERRS, si_ctlp,
4911		    "ddi_intr_get_nintrs() failed, "
4912		    "rc %d count %d\n", rc, count);
4913		return (DDI_FAILURE);
4914	}
4915
4916	/* Allocate an array of interrupt handles. */
4917	si_ctlp->sictl_intr_size = count * sizeof (ddi_intr_handle_t);
4918	si_ctlp->sictl_htable = kmem_zalloc(si_ctlp->sictl_intr_size, KM_SLEEP);
4919
4920	/* call ddi_intr_alloc(). */
4921	rc = ddi_intr_alloc(devinfo, si_ctlp->sictl_htable, DDI_INTR_TYPE_FIXED,
4922	    inum, count, &actual, DDI_INTR_ALLOC_STRICT);
4923
4924	if ((rc != DDI_SUCCESS) || (actual == 0)) {
4925		SIDBG_C(SIDBG_ERRS, si_ctlp,
4926		    "ddi_intr_alloc() failed, rc %d\n", rc);
4927		kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
4928		return (DDI_FAILURE);
4929	}
4930
4931	if (actual < count) {
4932		SIDBG_C(SIDBG_ERRS, si_ctlp,
4933		    "Requested: %d, Received: %d", count, actual);
4934
4935		for (x = 0; x < actual; x++) {
4936			(void) ddi_intr_free(si_ctlp->sictl_htable[x]);
4937		}
4938
4939		kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
4940		return (DDI_FAILURE);
4941	}
4942
4943	si_ctlp->sictl_intr_cnt = actual;
4944
4945	/* Get intr priority. */
4946	if (ddi_intr_get_pri(si_ctlp->sictl_htable[0],
4947	    &si_ctlp->sictl_intr_pri) != DDI_SUCCESS) {
4948		SIDBG_C(SIDBG_ERRS, si_ctlp,
4949		    "ddi_intr_get_pri() failed", NULL);
4950
4951		for (x = 0; x < actual; x++) {
4952			(void) ddi_intr_free(si_ctlp->sictl_htable[x]);
4953		}
4954
4955		kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
4956		return (DDI_FAILURE);
4957	}
4958
4959	/* Test for high level mutex. */
4960	if (si_ctlp->sictl_intr_pri >= ddi_intr_get_hilevel_pri()) {
4961		SIDBG_C(SIDBG_ERRS, si_ctlp,
4962		    "si_add_legacy_intrs: Hi level intr not supported", NULL);
4963
4964		for (x = 0; x < actual; x++) {
4965			(void) ddi_intr_free(si_ctlp->sictl_htable[x]);
4966		}
4967
4968		kmem_free(si_ctlp->sictl_htable, sizeof (ddi_intr_handle_t));
4969
4970		return (DDI_FAILURE);
4971	}
4972
4973	/* Call ddi_intr_add_handler(). */
4974	for (x = 0; x < actual; x++) {
4975		if (ddi_intr_add_handler(si_ctlp->sictl_htable[x], si_intr,
4976		    (caddr_t)si_ctlp, NULL) != DDI_SUCCESS) {
4977			SIDBG_C(SIDBG_ERRS, si_ctlp,
4978			    "ddi_intr_add_handler() failed", NULL);
4979
4980			for (y = 0; y < actual; y++) {
4981				(void) ddi_intr_free(si_ctlp->sictl_htable[y]);
4982			}
4983
4984			kmem_free(si_ctlp->sictl_htable,
4985			    si_ctlp->sictl_intr_size);
4986			return (DDI_FAILURE);
4987		}
4988	}
4989
4990	/* Call ddi_intr_enable() for legacy interrupts. */
4991	for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
4992		(void) ddi_intr_enable(si_ctlp->sictl_htable[x]);
4993	}
4994
4995	return (DDI_SUCCESS);
4996}
4997
4998/*
4999 * si_add_msictl_intrs() handles MSI interrupts.
5000 */
5001static int
5002si_add_msi_intrs(si_ctl_state_t *si_ctlp)
5003{
5004	dev_info_t	*devinfo = si_ctlp->sictl_devinfop;
5005	int		count, avail, actual;
5006	int		x, y, rc, inum = 0;
5007
5008	SIDBG_C(SIDBG_INIT, si_ctlp, "si_add_msi_intrs", NULL);
5009
5010	/* get number of interrupts. */
5011	rc = ddi_intr_get_nintrs(devinfo, DDI_INTR_TYPE_MSI, &count);
5012	if ((rc != DDI_SUCCESS) || (count == 0)) {
5013		SIDBG_C(SIDBG_ERRS, si_ctlp,
5014		    "ddi_intr_get_nintrs() failed, "
5015		    "rc %d count %d\n", rc, count);
5016		return (DDI_FAILURE);
5017	}
5018
5019	/* get number of available interrupts. */
5020	rc = ddi_intr_get_navail(devinfo, DDI_INTR_TYPE_MSI, &avail);
5021	if ((rc != DDI_SUCCESS) || (avail == 0)) {
5022		SIDBG_C(SIDBG_ERRS, si_ctlp,
5023		    "ddi_intr_get_navail() failed, "
5024		    "rc %d avail %d\n", rc, avail);
5025		return (DDI_FAILURE);
5026	}
5027
5028	if (avail < count) {
5029		SIDBG_C(SIDBG_INIT, si_ctlp,
5030		    "ddi_intr_get_nvail returned %d, navail() returned %d",
5031		    count, avail);
5032	}
5033
5034	/* Allocate an array of interrupt handles. */
5035	si_ctlp->sictl_intr_size = count * sizeof (ddi_intr_handle_t);
5036	si_ctlp->sictl_htable = kmem_alloc(si_ctlp->sictl_intr_size, KM_SLEEP);
5037
5038	/* call ddi_intr_alloc(). */
5039	rc = ddi_intr_alloc(devinfo, si_ctlp->sictl_htable, DDI_INTR_TYPE_MSI,
5040	    inum, count, &actual, DDI_INTR_ALLOC_NORMAL);
5041
5042	if ((rc != DDI_SUCCESS) || (actual == 0)) {
5043		SIDBG_C(SIDBG_ERRS, si_ctlp,
5044		    "ddi_intr_alloc() failed, rc %d\n", rc);
5045		kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
5046		return (DDI_FAILURE);
5047	}
5048
5049	/* use interrupt count returned */
5050	if (actual < count) {
5051		SIDBG_C(SIDBG_INIT, si_ctlp,
5052		    "Requested: %d, Received: %d", count, actual);
5053	}
5054
5055	si_ctlp->sictl_intr_cnt = actual;
5056
5057	/*
5058	 * Get priority for first msi, assume remaining are all the same.
5059	 */
5060	if (ddi_intr_get_pri(si_ctlp->sictl_htable[0],
5061	    &si_ctlp->sictl_intr_pri) != DDI_SUCCESS) {
5062		SIDBG_C(SIDBG_ERRS, si_ctlp, "ddi_intr_get_pri() failed", NULL);
5063
5064		/* Free already allocated intr. */
5065		for (y = 0; y < actual; y++) {
5066			(void) ddi_intr_free(si_ctlp->sictl_htable[y]);
5067		}
5068
5069		kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
5070		return (DDI_FAILURE);
5071	}
5072
5073	/* Test for high level mutex. */
5074	if (si_ctlp->sictl_intr_pri >= ddi_intr_get_hilevel_pri()) {
5075		SIDBG_C(SIDBG_ERRS, si_ctlp,
5076		    "si_add_msi_intrs: Hi level intr not supported", NULL);
5077
5078		/* Free already allocated intr. */
5079		for (y = 0; y < actual; y++) {
5080			(void) ddi_intr_free(si_ctlp->sictl_htable[y]);
5081		}
5082
5083		kmem_free(si_ctlp->sictl_htable, sizeof (ddi_intr_handle_t));
5084
5085		return (DDI_FAILURE);
5086	}
5087
5088	/* Call ddi_intr_add_handler(). */
5089	for (x = 0; x < actual; x++) {
5090		if (ddi_intr_add_handler(si_ctlp->sictl_htable[x], si_intr,
5091		    (caddr_t)si_ctlp, NULL) != DDI_SUCCESS) {
5092			SIDBG_C(SIDBG_ERRS, si_ctlp,
5093			    "ddi_intr_add_handler() failed", NULL);
5094
5095			/* Free already allocated intr. */
5096			for (y = 0; y < actual; y++) {
5097				(void) ddi_intr_free(si_ctlp->sictl_htable[y]);
5098			}
5099
5100			kmem_free(si_ctlp->sictl_htable,
5101			    si_ctlp->sictl_intr_size);
5102			return (DDI_FAILURE);
5103		}
5104	}
5105
5106	(void) ddi_intr_get_cap(si_ctlp->sictl_htable[0],
5107	    &si_ctlp->sictl_intr_cap);
5108
5109	if (si_ctlp->sictl_intr_cap & DDI_INTR_FLAG_BLOCK) {
5110		/* Call ddi_intr_block_enable() for MSI. */
5111		(void) ddi_intr_block_enable(si_ctlp->sictl_htable,
5112		    si_ctlp->sictl_intr_cnt);
5113	} else {
5114		/* Call ddi_intr_enable() for MSI non block enable. */
5115		for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
5116			(void) ddi_intr_enable(si_ctlp->sictl_htable[x]);
5117		}
5118	}
5119
5120	return (DDI_SUCCESS);
5121}
5122
5123/*
5124 * Removes the registered interrupts irrespective of whether they
5125 * were legacy or MSI.
5126 */
5127static void
5128si_rem_intrs(si_ctl_state_t *si_ctlp)
5129{
5130	int x;
5131
5132	SIDBG_C(SIDBG_INIT, si_ctlp, "si_rem_intrs entered", NULL);
5133
5134	/* Disable all interrupts. */
5135	if ((si_ctlp->sictl_intr_type == DDI_INTR_TYPE_MSI) &&
5136	    (si_ctlp->sictl_intr_cap & DDI_INTR_FLAG_BLOCK)) {
5137		/* Call ddi_intr_block_disable(). */
5138		(void) ddi_intr_block_disable(si_ctlp->sictl_htable,
5139		    si_ctlp->sictl_intr_cnt);
5140	} else {
5141		for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
5142			(void) ddi_intr_disable(si_ctlp->sictl_htable[x]);
5143		}
5144	}
5145
5146	/* Call ddi_intr_remove_handler(). */
5147	for (x = 0; x < si_ctlp->sictl_intr_cnt; x++) {
5148		(void) ddi_intr_remove_handler(si_ctlp->sictl_htable[x]);
5149		(void) ddi_intr_free(si_ctlp->sictl_htable[x]);
5150	}
5151
5152	kmem_free(si_ctlp->sictl_htable, si_ctlp->sictl_intr_size);
5153}
5154
5155/*
5156 * Resets either the port or the device connected to the port based on
5157 * the flag variable.
5158 *
5159 * The reset effectively throws away all the pending commands. So, the caller
5160 * has to make provision to handle the pending commands.
5161 *
5162 * After the reset, we wait till the port is ready again.
5163 *
5164 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
5165 * before calling us.
5166 *
5167 * Note: Not port-mult aware.
5168 */
5169static int
5170si_reset_dport_wait_till_ready(
5171	si_ctl_state_t *si_ctlp,
5172	si_port_state_t *si_portp,
5173	int port,
5174	int flag)
5175{
5176	uint32_t port_status;
5177	int loop_count = 0;
5178	sata_device_t sdevice;
5179	uint32_t SStatus;
5180	uint32_t SControl;
5181	uint32_t port_intr_status;
5182
5183	_NOTE(ASSUMING_PROTECTED(si_portp))
5184
5185	if (flag == SI_PORT_RESET) {
5186		ddi_put32(si_ctlp->sictl_port_acc_handle,
5187		    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
5188		    PORT_CONTROL_SET_BITS_PORT_RESET);
5189
5190		/* Port reset is not self clearing. So clear it now. */
5191		ddi_put32(si_ctlp->sictl_port_acc_handle,
5192		    (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
5193		    PORT_CONTROL_CLEAR_BITS_PORT_RESET);
5194	} else {
5195		/* Reset the device. */
5196		ddi_put32(si_ctlp->sictl_port_acc_handle,
5197		    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
5198		    PORT_CONTROL_SET_BITS_DEV_RESET);
5199
5200		/*
5201		 * tidbit: this bit is self clearing; so there is no need
5202		 * for manual clear as we did for port reset.
5203		 */
5204	}
5205
5206	/* Set the reset in progress flag */
5207	if (!(flag & SI_RESET_NO_EVENTS_UP)) {
5208		si_portp->siport_reset_in_progress = 1;
5209	}
5210
5211
5212	/*
5213	 * Every reset needs a PHY initialization.
5214	 *
5215	 * The way to initialize the PHY is to write a 1 and then
5216	 * a 0 to DET field of SControl register.
5217	 */
5218
5219	/* Fetch the current SControl before writing the DET part with 1. */
5220	SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
5221	    (uint32_t *)PORT_SCONTROL(si_ctlp, port));
5222	SCONTROL_SET_DET(SControl, SCONTROL_DET_COMRESET);
5223	ddi_put32(si_ctlp->sictl_port_acc_handle,
5224	    (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
5225	    SControl);
5226#ifndef __lock_lint
5227	delay(SI_10MS_TICKS); /* give time for COMRESET to percolate */
5228#endif /* __lock_lint */
5229
5230	/* Now fetch the SControl again and rewrite the DET part with 0 */
5231	SControl = ddi_get32(si_ctlp->sictl_port_acc_handle,
5232	    (uint32_t *)PORT_SCONTROL(si_ctlp, port));
5233	SCONTROL_SET_DET(SControl, SCONTROL_DET_NOACTION);
5234	ddi_put32(si_ctlp->sictl_port_acc_handle,
5235	    (uint32_t *)(PORT_SCONTROL(si_ctlp, port)),
5236	    SControl);
5237
5238	/*
5239	 * PHY may be initialized by now. Check the DET field of SStatus
5240	 * to determine if there is a device present.
5241	 *
5242	 * The DET field is valid only if IPM field indicates that
5243	 * the interface is in active state.
5244	 */
5245
5246	loop_count = 0;
5247	do {
5248		SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
5249		    (uint32_t *)PORT_SSTATUS(si_ctlp, port));
5250
5251		if (SSTATUS_GET_IPM(SStatus) !=
5252		    SSTATUS_IPM_INTERFACE_ACTIVE) {
5253			/*
5254			 * If the interface is not active, the DET field
5255			 * is considered not accurate. So we want to
5256			 * continue looping.
5257			 */
5258			SSTATUS_SET_DET(SStatus, SSTATUS_DET_NODEV_NOPHY);
5259		}
5260
5261		if (loop_count++ > SI_POLLRATE_SSTATUS) {
5262			/* We are effectively timing out after 0.1 sec. */
5263			break;
5264		}
5265
5266		/* Wait for 10 millisec */
5267#ifndef __lock_lint
5268		delay(SI_10MS_TICKS);
5269#endif /* __lock_lint */
5270
5271	} while (SSTATUS_GET_DET(SStatus) != SSTATUS_DET_DEVPRESENT_PHYONLINE);
5272
5273	SIDBG_P(SIDBG_POLL_LOOP, si_portp,
5274	    "si_reset_dport_wait_till_ready: loop count: %d, \
5275		SStatus: 0x%x",
5276	    loop_count,
5277	    SStatus);
5278
5279	/* Now check for port readiness. */
5280	loop_count = 0;
5281	do {
5282		port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
5283		    (uint32_t *)PORT_STATUS(si_ctlp, port));
5284
5285		if (loop_count++ > SI_POLLRATE_PORTREADY) {
5286			/* We are effectively timing out after 0.5 sec. */
5287			break;
5288		}
5289
5290		/* Wait for 10 millisec */
5291#ifndef __lock_lint
5292		delay(SI_10MS_TICKS);
5293#endif /* __lock_lint */
5294
5295	} while (!(port_status & PORT_STATUS_BITS_PORT_READY));
5296
5297	SIDBG_P(SIDBG_POLL_LOOP, si_portp,
5298	    "si_reset_dport_wait_till_ready: loop count: %d, \
5299		port_status: 0x%x, SStatus: 0x%x",
5300	    loop_count,
5301	    port_status,
5302	    SStatus);
5303
5304	/* Indicate to the framework that a reset has happened. */
5305	if (!(flag & SI_RESET_NO_EVENTS_UP)) {
5306
5307		bzero((void *)&sdevice, sizeof (sata_device_t));
5308
5309		sdevice.satadev_addr.cport = (uint8_t)port;
5310		sdevice.satadev_addr.pmport = PORTMULT_CONTROL_PORT;
5311
5312		if (si_portp->siport_port_type == PORT_TYPE_MULTIPLIER) {
5313			sdevice.satadev_addr.qual = SATA_ADDR_DPMPORT;
5314		} else {
5315			sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
5316		}
5317		sdevice.satadev_state = SATA_DSTATE_RESET |
5318		    SATA_DSTATE_PWR_ACTIVE;
5319		if (si_ctlp->sictl_sata_hba_tran) {
5320			sata_hba_event_notify(
5321			    si_ctlp->sictl_sata_hba_tran->sata_tran_hba_dip,
5322			    &sdevice,
5323			    SATA_EVNT_DEVICE_RESET);
5324		}
5325
5326		SIDBG_P(SIDBG_EVENT, si_portp,
5327		    "sending event up: SATA_EVNT_RESET", NULL);
5328	}
5329
5330	if ((SSTATUS_GET_IPM(SStatus) == SSTATUS_IPM_INTERFACE_ACTIVE) &&
5331	    (SSTATUS_GET_DET(SStatus) ==
5332	    SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
5333		/* The interface is active and the device is present */
5334		if (!(port_status & PORT_STATUS_BITS_PORT_READY)) {
5335			/* But the port is is not ready for some reason */
5336			SIDBG_P(SIDBG_POLL_LOOP, si_portp,
5337			    "si_reset_dport_wait_till_ready failed", NULL);
5338			return (SI_FAILURE);
5339		}
5340	}
5341
5342
5343	/*
5344	 * For some reason, we are losing the interrupt enablement after
5345	 * any reset condition. So restore them back now.
5346	 */
5347
5348	SIDBG_P(SIDBG_INIT, si_portp,
5349	    "current interrupt enable set: 0x%x",
5350	    ddi_get32(si_ctlp->sictl_port_acc_handle,
5351	    (uint32_t *)PORT_INTERRUPT_ENABLE_SET(si_ctlp, port)));
5352
5353	ddi_put32(si_ctlp->sictl_port_acc_handle,
5354	    (uint32_t *)PORT_INTERRUPT_ENABLE_SET(si_ctlp, port),
5355	    (INTR_COMMAND_COMPLETE |
5356	    INTR_COMMAND_ERROR |
5357	    INTR_PORT_READY |
5358	    INTR_POWER_CHANGE |
5359	    INTR_PHYRDY_CHANGE |
5360	    INTR_COMWAKE_RECEIVED |
5361	    INTR_UNRECOG_FIS |
5362	    INTR_DEV_XCHANGED |
5363	    INTR_SETDEVBITS_NOTIFY));
5364
5365	si_enable_port_interrupts(si_ctlp, port);
5366
5367	/*
5368	 * make sure interrupts are cleared
5369	 */
5370	port_intr_status = ddi_get32(si_ctlp->sictl_global_acc_handle,
5371	    (uint32_t *)PORT_INTERRUPT_STATUS(si_ctlp, port));
5372
5373	ddi_put32(si_ctlp->sictl_port_acc_handle,
5374	    (uint32_t *)(PORT_INTERRUPT_STATUS(si_ctlp,
5375	    port)),
5376	    port_intr_status & INTR_MASK);
5377
5378
5379	SIDBG_P(SIDBG_POLL_LOOP, si_portp,
5380	    "si_reset_dport_wait_till_ready returning success", NULL);
5381
5382	return (SI_SUCCESS);
5383}
5384
5385/*
5386 * Schedule an initialization of the port using a timeout to get it done
5387 * off an interrupt thread.
5388 *
5389 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
5390 * before calling us.
5391 */
5392static void
5393si_schedule_port_initialize(
5394	si_ctl_state_t *si_ctlp,
5395	si_port_state_t *si_portp,
5396	int port)
5397{
5398	si_event_arg_t *args;
5399
5400	ASSERT(mutex_owned(&si_portp->siport_mutex));
5401
5402	args = si_portp->siport_event_args;
5403	if (args->siea_ctlp != NULL) {
5404		cmn_err(CE_WARN, "si_schedule_port_initialize: "
5405		    "args->si_ctlp != NULL");
5406		return;
5407	}
5408
5409	args->siea_ctlp = si_ctlp;
5410	args->siea_port = port;
5411
5412	(void) timeout(si_do_initialize_port, si_portp, 1);
5413}
5414
5415/*
5416 * Called from timeout()
5417 * Unpack the arguments and call si_initialize_port_wait_till_ready()
5418 */
5419static void
5420si_do_initialize_port(void *arg)
5421{
5422	si_event_arg_t *args;
5423	si_ctl_state_t *si_ctlp;
5424	si_port_state_t *si_portp;
5425	int port;
5426
5427	si_portp = arg;
5428	mutex_enter(&si_portp->siport_mutex);
5429
5430	args = si_portp->siport_event_args;
5431	si_ctlp = args->siea_ctlp;
5432	port = args->siea_port;
5433	args->siea_ctlp = NULL;	/* mark siport_event_args as free */
5434	(void) si_initialize_port_wait_till_ready(si_ctlp, port);
5435
5436	mutex_exit(&si_portp->siport_mutex);
5437}
5438
5439
5440/*
5441 * Initializes the port.
5442 *
5443 * Initialization effectively throws away all the pending commands on
5444 * the port. So, the caller  has to make provision to handle the pending
5445 * commands.
5446 *
5447 * After the port initialization, we wait till the port is ready again.
5448 *
5449 * WARNING, WARNING: The caller is expected to obtain the siport_mutex
5450 * before calling us.
5451 */
5452static int
5453si_initialize_port_wait_till_ready(si_ctl_state_t *si_ctlp, int port)
5454{
5455	uint32_t port_status;
5456	int loop_count = 0;
5457	uint32_t SStatus;
5458	si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
5459
5460	/* Initialize the port. */
5461	ddi_put32(si_ctlp->sictl_port_acc_handle,
5462	    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
5463	    PORT_CONTROL_SET_BITS_PORT_INITIALIZE);
5464
5465	/* Wait until Port Ready */
5466	loop_count = 0;
5467	do {
5468		port_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
5469		    (uint32_t *)PORT_STATUS(si_ctlp, port));
5470
5471		if (loop_count++ > SI_POLLRATE_PORTREADY) {
5472			SIDBG_P(SIDBG_INTR, si_portp,
5473			    "si_initialize_port_wait is timing out: "
5474			    "port_status: %x",
5475			    port_status);
5476			/* We are effectively timing out after 0.5 sec. */
5477			break;
5478		}
5479
5480		/* Wait for 10 millisec */
5481#ifndef __lock_lint
5482		delay(SI_10MS_TICKS);
5483#endif /* __lock_lint */
5484
5485	} while (!(port_status & PORT_STATUS_BITS_PORT_READY));
5486
5487	SIDBG_P(SIDBG_POLL_LOOP, si_portp,
5488	    "si_initialize_port_wait_till_ready: loop count: %d",
5489	    loop_count);
5490
5491	SStatus = ddi_get32(si_ctlp->sictl_port_acc_handle,
5492	    (uint32_t *)PORT_SSTATUS(si_ctlp, port));
5493
5494	if ((SSTATUS_GET_IPM(SStatus) == SSTATUS_IPM_INTERFACE_ACTIVE) &&
5495	    (SSTATUS_GET_DET(SStatus) ==
5496	    SSTATUS_DET_DEVPRESENT_PHYONLINE)) {
5497		/* The interface is active and the device is present */
5498		if (!(port_status & PORT_STATUS_BITS_PORT_READY)) {
5499			/* But the port is is not ready for some reason */
5500			return (SI_FAILURE);
5501		}
5502	}
5503
5504	return (SI_SUCCESS);
5505}
5506
5507
5508/*
5509 * si_watchdog_handler() calls us if it detects that there are some
5510 * commands which timed out. We recalculate the timed out commands once
5511 * again since some of them may have finished recently.
5512 */
5513static void
5514si_timeout_pkts(
5515	si_ctl_state_t *si_ctlp,
5516	si_port_state_t *si_portp,
5517	int port,
5518	uint32_t timedout_tags)
5519{
5520	uint32_t slot_status;
5521	uint32_t finished_tags;
5522
5523	SIDBG_P(SIDBG_TIMEOUT, si_portp,
5524	    "si_timeout_pkts entry", NULL);
5525
5526	mutex_enter(&si_portp->siport_mutex);
5527	slot_status = ddi_get32(si_ctlp->sictl_port_acc_handle,
5528	    (uint32_t *)(PORT_SLOT_STATUS(si_ctlp, port)));
5529
5530	si_portp->mopping_in_progress++;
5531
5532	/*
5533	 * Initialize the controller. The only way to timeout the commands
5534	 * is to reset or initialize the controller. We mop commands after
5535	 * the initialization.
5536	 */
5537	(void) si_initialize_port_wait_till_ready(si_ctlp, port);
5538
5539	/*
5540	 * Recompute the timedout tags since some of them may have finished
5541	 * meanwhile.
5542	 */
5543	finished_tags =  si_portp->siport_pending_tags &
5544	    ~slot_status & SI_SLOT_MASK;
5545	timedout_tags &= ~finished_tags;
5546
5547	SIDBG_P(SIDBG_TIMEOUT, si_portp,
5548	    "si_timeout_pkts: finished: %x, timeout: %x",
5549	    finished_tags,
5550	    timedout_tags);
5551
5552	si_mop_commands(si_ctlp,
5553	    si_portp,
5554	    port,
5555	    slot_status,
5556	    0, /* failed_tags */
5557	    timedout_tags,
5558	    0, /* aborting_tags */
5559	    0);  /* reset_tags */
5560
5561	mutex_exit(&si_portp->siport_mutex);
5562}
5563
5564
5565
5566/*
5567 * Watchdog handler kicks in every 5 seconds to timeout any commands pending
5568 * for long time.
5569 */
5570static void
5571si_watchdog_handler(si_ctl_state_t *si_ctlp)
5572{
5573	uint32_t pending_tags = 0;
5574	uint32_t timedout_tags = 0;
5575	si_port_state_t *si_portp;
5576	int port;
5577	int tmpslot;
5578	sata_pkt_t *satapkt;
5579
5580	/* max number of cycles this packet should survive */
5581	int max_life_cycles;
5582
5583	/* how many cycles this packet survived so far */
5584	int watched_cycles;
5585
5586	mutex_enter(&si_ctlp->sictl_mutex);
5587	SIDBG_C(SIDBG_ENTRY, si_ctlp,
5588	    "si_watchdog_handler entered", NULL);
5589
5590	for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
5591
5592		si_portp = si_ctlp->sictl_ports[port];
5593		if (si_portp == NULL) {
5594			continue;
5595		}
5596
5597		mutex_enter(&si_portp->siport_mutex);
5598
5599		if (si_portp->siport_port_type == PORT_TYPE_NODEV) {
5600			mutex_exit(&si_portp->siport_mutex);
5601			continue;
5602		}
5603
5604		/* Skip the check for those ports in error recovery */
5605		if (si_portp->mopping_in_progress > 0) {
5606			SIDBG_P(SIDBG_INFO, si_portp,
5607			    "si_watchdog_handler: port %d mopping "
5608			    "in progress, so just return", port);
5609			mutex_exit(&si_portp->siport_mutex);
5610			continue;
5611		}
5612
5613		pending_tags =  si_portp->siport_pending_tags;
5614		timedout_tags = 0;
5615		while (pending_tags) {
5616			tmpslot = ddi_ffs(pending_tags) - 1;
5617			if (tmpslot == -1) {
5618				break;
5619			}
5620			satapkt = si_portp->siport_slot_pkts[tmpslot];
5621
5622			if ((satapkt != NULL) && satapkt->satapkt_time) {
5623
5624				/*
5625				 * We are overloading satapkt_hba_driver_private
5626				 * with watched_cycle count.
5627				 *
5628				 * If a packet has survived for more than it's
5629				 * max life cycles, it is a candidate for time
5630				 * out.
5631				 */
5632				watched_cycles = (int)(intptr_t)
5633				    satapkt->satapkt_hba_driver_private;
5634				watched_cycles++;
5635				max_life_cycles = (satapkt->satapkt_time +
5636				    si_watchdog_timeout - 1) /
5637				    si_watchdog_timeout;
5638				if (watched_cycles > max_life_cycles) {
5639					timedout_tags |= (0x1 << tmpslot);
5640					SIDBG_P(SIDBG_TIMEOUT,
5641					    si_portp,
5642					    "watchdog: timedout_tags: 0x%x",
5643					    timedout_tags);
5644				}
5645				satapkt->satapkt_hba_driver_private =
5646				    (void *)(intptr_t)watched_cycles;
5647			}
5648
5649			CLEAR_BIT(pending_tags, tmpslot);
5650		}
5651
5652		if (timedout_tags) {
5653			mutex_exit(&si_portp->siport_mutex);
5654			mutex_exit(&si_ctlp->sictl_mutex);
5655			si_timeout_pkts(si_ctlp, si_portp, port, timedout_tags);
5656			mutex_enter(&si_ctlp->sictl_mutex);
5657			mutex_enter(&si_portp->siport_mutex);
5658		}
5659
5660		mutex_exit(&si_portp->siport_mutex);
5661	}
5662
5663	/* Reinstall the watchdog timeout handler. */
5664	if (!(si_ctlp->sictl_flags & SI_NO_TIMEOUTS)) {
5665		si_ctlp->sictl_timeout_id =
5666		    timeout((void (*)(void *))si_watchdog_handler,
5667		    (caddr_t)si_ctlp, si_watchdog_tick);
5668	}
5669	mutex_exit(&si_ctlp->sictl_mutex);
5670}
5671
5672/*
5673 * FMA Functions
5674 */
5675
5676/*
5677 * The IO fault service error handling callback function
5678 */
5679/*ARGSUSED*/
5680static int
5681si_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
5682{
5683	/*
5684	 * as the driver can always deal with an error in any dma or
5685	 * access handle, we can just return the fme_status value.
5686	 */
5687	pci_ereport_post(dip, err, NULL);
5688	return (err->fme_status);
5689}
5690
5691/*
5692 * si_fm_init - initialize fma capabilities and register with IO
5693 *              fault services.
5694 */
5695static void
5696si_fm_init(si_ctl_state_t *si_ctlp)
5697{
5698	/*
5699	 * Need to change iblock to priority for new MSI intr
5700	 */
5701	ddi_iblock_cookie_t fm_ibc;
5702
5703	/* Only register with IO Fault Services if we have some capability */
5704	if (si_ctlp->fm_capabilities) {
5705		/* Adjust access and dma attributes for FMA */
5706		accattr.devacc_attr_access = DDI_FLAGERR_ACC;
5707		prb_sgt_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
5708		buffer_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
5709
5710		/*
5711		 * Register capabilities with IO Fault Services.
5712		 * fm_capabilities will be updated to indicate
5713		 * capabilities actually supported (not requested.)
5714		 */
5715		ddi_fm_init(si_ctlp->sictl_devinfop, &si_ctlp->fm_capabilities,
5716		    &fm_ibc);
5717
5718		if (si_ctlp->fm_capabilities == DDI_FM_NOT_CAPABLE)
5719			cmn_err(CE_WARN, "si_fm_init: ddi_fm_init fail");
5720
5721		/*
5722		 * Initialize pci ereport capabilities if ereport
5723		 * capable (should always be.)
5724		 */
5725		if (DDI_FM_EREPORT_CAP(si_ctlp->fm_capabilities) ||
5726		    DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
5727			pci_ereport_setup(si_ctlp->sictl_devinfop);
5728		}
5729
5730		/*
5731		 * Register error callback if error callback capable.
5732		 */
5733		if (DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
5734			ddi_fm_handler_register(si_ctlp->sictl_devinfop,
5735			    si_fm_error_cb, (void *) si_ctlp);
5736		}
5737	}
5738}
5739
5740/*
5741 * si_fm_fini - Releases fma capabilities and un-registers with IO
5742 *              fault services.
5743 */
5744static void
5745si_fm_fini(si_ctl_state_t *si_ctlp)
5746{
5747	/* Only unregister FMA capabilities if registered */
5748	if (si_ctlp->fm_capabilities) {
5749		/*
5750		 * Un-register error callback if error callback capable.
5751		 */
5752		if (DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
5753			ddi_fm_handler_unregister(si_ctlp->sictl_devinfop);
5754		}
5755
5756		/*
5757		 * Release any resources allocated by pci_ereport_setup()
5758		 */
5759		if (DDI_FM_EREPORT_CAP(si_ctlp->fm_capabilities) ||
5760		    DDI_FM_ERRCB_CAP(si_ctlp->fm_capabilities)) {
5761			pci_ereport_teardown(si_ctlp->sictl_devinfop);
5762		}
5763
5764		/* Unregister from IO Fault Services */
5765		ddi_fm_fini(si_ctlp->sictl_devinfop);
5766
5767		/* Adjust access and dma attributes for FMA */
5768		accattr.devacc_attr_access = DDI_DEFAULT_ACC;
5769		prb_sgt_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
5770		buffer_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
5771	}
5772}
5773
5774static int
5775si_check_acc_handle(ddi_acc_handle_t handle)
5776{
5777	ddi_fm_error_t de;
5778
5779	ASSERT(handle != NULL);
5780	ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
5781	return (de.fme_status);
5782}
5783
5784static int
5785si_check_dma_handle(ddi_dma_handle_t handle)
5786{
5787	ddi_fm_error_t de;
5788
5789	ASSERT(handle != NULL);
5790	ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
5791	return (de.fme_status);
5792}
5793
5794static int
5795si_check_ctl_handles(si_ctl_state_t *si_ctlp)
5796{
5797	if ((si_check_acc_handle(si_ctlp->sictl_pci_conf_handle)
5798	    != DDI_SUCCESS) ||
5799	    (si_check_acc_handle(si_ctlp->sictl_global_acc_handle)
5800	    != DDI_SUCCESS) ||
5801	    (si_check_acc_handle(si_ctlp->sictl_port_acc_handle)
5802	    != DDI_SUCCESS)) {
5803		return (DDI_FAILURE);
5804	}
5805
5806	return (DDI_SUCCESS);
5807}
5808
5809/*
5810 * WARNING: The caller is expected to obtain the siport_mutex
5811 * before calling us.
5812 */
5813static int
5814si_check_port_handles(si_port_state_t *si_portp)
5815{
5816	if ((si_check_dma_handle(si_portp->siport_prbpool_dma_handle)
5817	    != DDI_SUCCESS) ||
5818	    (si_check_acc_handle(si_portp->siport_prbpool_acc_handle)
5819	    != DDI_SUCCESS) ||
5820	    (si_check_dma_handle(si_portp->siport_sgbpool_dma_handle)
5821	    != DDI_SUCCESS) ||
5822	    (si_check_acc_handle(si_portp->siport_sgbpool_acc_handle)
5823	    != DDI_SUCCESS)) {
5824		return (DDI_FAILURE);
5825	}
5826
5827	return (DDI_SUCCESS);
5828}
5829
5830static void
5831si_fm_ereport(si_ctl_state_t *si_ctlp, char *detail, char *payload)
5832{
5833	uint64_t ena;
5834	char buf[FM_MAX_CLASS];
5835
5836	(void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
5837	ena = fm_ena_generate(0, FM_ENA_FMT1);
5838
5839	if (DDI_FM_EREPORT_CAP(si_ctlp->fm_capabilities)) {
5840		ddi_fm_ereport_post(si_ctlp->sictl_devinfop, buf, ena,
5841		    DDI_NOSLEEP,
5842		    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERSION,
5843		    "detailed_err_type", DATA_TYPE_STRING, payload,
5844		    NULL);
5845	}
5846}
5847
5848/*
5849 * Logs the message.
5850 */
5851static void
5852si_log(si_ctl_state_t *si_ctlp, si_port_state_t *si_portp, char *fmt, ...)
5853{
5854	va_list ap;
5855
5856	mutex_enter(&si_log_mutex);
5857
5858	va_start(ap, fmt);
5859
5860	if (si_portp == NULL && si_ctlp == NULL) {
5861		sata_vtrace_debug(NULL, fmt, ap);
5862		va_end(ap);
5863		mutex_exit(&si_log_mutex);
5864		return;
5865	}
5866
5867	if (si_portp == NULL && si_ctlp != NULL) {
5868		sata_vtrace_debug(si_ctlp->sictl_devinfop, fmt, ap);
5869		va_end(ap);
5870		mutex_exit(&si_log_mutex);
5871		return;
5872	}
5873
5874	/*
5875	 * si_portp is not NULL, but si_ctlp might be.
5876	 * Reference si_portp for both port and dip.
5877	 */
5878	(void) snprintf(si_log_buf, SI_LOGBUF_LEN, "port%d: %s",
5879	    si_portp->siport_port_num, fmt);
5880
5881	if (si_portp->siport_ctlp == NULL) {
5882		sata_vtrace_debug(NULL, si_log_buf, ap);
5883		va_end(ap);
5884		mutex_exit(&si_log_mutex);
5885		return;
5886	}
5887
5888	sata_vtrace_debug(si_portp->siport_ctlp->sictl_devinfop,
5889	    si_log_buf, ap);
5890
5891	va_end(ap);
5892
5893	mutex_exit(&si_log_mutex);
5894
5895}
5896
5897static void
5898si_copy_out_regs(sata_cmd_t *scmd, si_ctl_state_t *si_ctlp, uint8_t port,
5899	uint8_t slot)
5900{
5901	uint32_t *fis_word_ptr;
5902	si_prb_t *prb;
5903	int i;
5904	si_port_state_t *si_portp = si_ctlp->sictl_ports[port];
5905
5906	/*
5907	 * The LRAM contains the the modified FIS after command completion, so
5908	 * first copy it back to the in-core PRB pool.  To save read cycles,
5909	 * just copy over the FIS portion of the PRB pool.
5910	 */
5911	prb =  &si_ctlp->sictl_ports[port]->siport_prbpool[slot];
5912
5913	fis_word_ptr = (uint32_t *)(void *)(&prb->prb_fis);
5914
5915	for (i = 0; i < (sizeof (fis_reg_h2d_t)/4); i++) {
5916		fis_word_ptr[i] = ddi_get32(
5917		    si_ctlp->sictl_port_acc_handle,
5918		    (uint32_t *)(PORT_LRAM(si_ctlp, port,
5919		    slot) + i * 4 + 0x08));
5920	}
5921
5922	/*
5923	 * always get the status register
5924	 */
5925	scmd->satacmd_status_reg = GET_FIS_COMMAND(prb->prb_fis);
5926
5927	DTRACE_PROBE1(satacmd_status_reg, int, scmd->satacmd_status_reg);
5928
5929	if (scmd->satacmd_flags.sata_copy_out_sec_count_msb) {
5930		scmd->satacmd_sec_count_msb =
5931		    GET_FIS_SECTOR_COUNT_EXP(prb->prb_fis);
5932		SIDBG_P(SIDBG_VERBOSE, si_portp,
5933		    "copyout satacmd_sec_count_msb %x\n",
5934		    scmd->satacmd_sec_count_msb);
5935	}
5936
5937	if (scmd->satacmd_flags.sata_copy_out_lba_low_msb) {
5938		scmd->satacmd_lba_low_msb = GET_FIS_SECTOR_EXP(prb->prb_fis);
5939		SIDBG_P(SIDBG_VERBOSE, si_portp,
5940		    "copyout satacmd_lba_low_msb %x\n",
5941		    scmd->satacmd_lba_low_msb);
5942	}
5943
5944	if (scmd->satacmd_flags.sata_copy_out_lba_mid_msb) {
5945		scmd->satacmd_lba_mid_msb = GET_FIS_CYL_LOW_EXP(prb->prb_fis);
5946		SIDBG_P(SIDBG_VERBOSE, si_portp,
5947		    "copyout satacmd_lba_mid_msb %x\n",
5948		    scmd->satacmd_lba_mid_msb);
5949	}
5950
5951	if (scmd->satacmd_flags.sata_copy_out_lba_high_msb) {
5952		scmd->satacmd_lba_high_msb = GET_FIS_CYL_HI_EXP(prb->prb_fis);
5953		SIDBG_P(SIDBG_VERBOSE, si_portp,
5954		    "copyout satacmd_lba_high_msb %x\n",
5955		    scmd->satacmd_lba_high_msb);
5956	}
5957
5958	if (scmd->satacmd_flags.sata_copy_out_sec_count_lsb) {
5959		scmd->satacmd_sec_count_lsb =
5960		    GET_FIS_SECTOR_COUNT(prb->prb_fis);
5961		SIDBG_P(SIDBG_VERBOSE, si_portp,
5962		    "copyout satacmd_sec_count_lsb %x\n",
5963		    scmd->satacmd_sec_count_lsb);
5964	}
5965
5966	if (scmd->satacmd_flags.sata_copy_out_lba_low_lsb) {
5967		scmd->satacmd_lba_low_lsb = GET_FIS_SECTOR(prb->prb_fis);
5968		SIDBG_P(SIDBG_VERBOSE, si_portp,
5969		    "copyout satacmd_lba_low_lsb %x\n",
5970		    scmd->satacmd_lba_low_lsb);
5971	}
5972
5973	if (scmd->satacmd_flags.sata_copy_out_lba_mid_lsb) {
5974		scmd->satacmd_lba_mid_lsb = GET_FIS_CYL_LOW(prb->prb_fis);
5975		SIDBG_P(SIDBG_VERBOSE, si_portp,
5976		    "copyout satacmd_lba_mid_lsb %x\n",
5977		    scmd->satacmd_lba_mid_lsb);
5978	}
5979
5980	if (scmd->satacmd_flags.sata_copy_out_lba_high_lsb) {
5981		scmd->satacmd_lba_high_lsb = GET_FIS_CYL_HI(prb->prb_fis);
5982		SIDBG_P(SIDBG_VERBOSE, si_portp,
5983		    "copyout satacmd_lba_high_lsb %x\n",
5984		    scmd->satacmd_lba_high_lsb);
5985	}
5986
5987	if (scmd->satacmd_flags.sata_copy_out_device_reg) {
5988		scmd->satacmd_device_reg = GET_FIS_DEV_HEAD(prb->prb_fis);
5989		SIDBG_P(SIDBG_VERBOSE, si_portp,
5990		    "copyout satacmd_device_reg %x\n",
5991		    scmd->satacmd_device_reg);
5992	}
5993
5994	if (scmd->satacmd_flags.sata_copy_out_error_reg) {
5995		scmd->satacmd_error_reg = GET_FIS_FEATURES(prb->prb_fis);
5996		SIDBG_P(SIDBG_VERBOSE, si_portp,
5997		    "copyout satacmd_error_reg %x\n",
5998		    scmd->satacmd_error_reg);
5999	}
6000}
6001
6002/*
6003 * This function clear the special port by send the PORT RESET
6004 * After reset was sent, all commands running on the port
6005 * is aborted
6006 */
6007static int
6008si_clear_port(si_ctl_state_t *si_ctlp, int port)
6009{
6010
6011	if (si_ctlp == NULL)
6012		return (SI_FAILURE);
6013	/*
6014	 * reset this port so that all existing command
6015	 * is clear
6016	 */
6017	ddi_put32(si_ctlp->sictl_port_acc_handle,
6018	    (uint32_t *)PORT_CONTROL_SET(si_ctlp, port),
6019	    PORT_CONTROL_SET_BITS_PORT_RESET);
6020
6021	/* Port reset is not self clearing. So clear it now. */
6022	ddi_put32(si_ctlp->sictl_port_acc_handle,
6023	    (uint32_t *)PORT_CONTROL_CLEAR(si_ctlp, port),
6024	    PORT_CONTROL_CLEAR_BITS_PORT_RESET);
6025	return (SI_SUCCESS);
6026}
6027
6028/*
6029 * quiesce(9E) entry point.
6030 * This function is called when the system is single-threaded at high
6031 * PIL with preemption disabled. Therefore, this function must not be
6032 * blocked.
6033 *
6034 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
6035 * DDI_FAILURE indicates an error condition and should almost never happen.
6036 */
6037static int
6038si_quiesce(dev_info_t *dip)
6039{
6040	si_ctl_state_t *si_ctlp;
6041	int instance;
6042	int port;
6043
6044	instance = ddi_get_instance(dip);
6045	si_ctlp = ddi_get_soft_state(si_statep, instance);
6046	if (si_ctlp == NULL)
6047		return (DDI_FAILURE);
6048
6049	SIDBG_C(SIDBG_ENTRY, si_ctlp, "si_quiesce enter", NULL);
6050	/*
6051	 * Disable all the interrupts before quiesce
6052	 */
6053
6054	for (port = 0; port < si_ctlp->sictl_num_ports; port++) {
6055		si_disable_port_interrupts(si_ctlp, port);
6056		(void) si_clear_port(si_ctlp, port);
6057	}
6058
6059	return (DDI_SUCCESS);
6060}
6061